root/trunk/src/shared/vmap/SubModel.cpp @ 102

Revision 102, 8.8 kB (checked in by yumileroy, 17 years ago)

[svn] Fixed copyright notices to comply with GPL.

Original author: w12x
Date: 2008-10-23 03:29:52-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "SubModel.h"
22
23#ifdef _ASSEMBLER_DEBUG
24extern FILE *::g_df;
25#endif
26
27using namespace G3D;
28
29namespace VMAP
30{
31
32    //==========================================================
33    /**
34    Functions to use ModelContainer with a AABSPTree
35    */
36    unsigned int hashCode(const SubModel& pSm)
37    {
38        return pSm.getNTriangles();
39    }
40
41    void getBounds(const SubModel& pSm, G3D::AABox& pAABox)
42    {
43        ShortBox box = pSm.getReletiveBounds();
44        pAABox.set(box.getLo().getVector3()+pSm.getBasePosition(), box.getHi().getVector3()+pSm.getBasePosition());
45    }
46
47    void getBounds(const SubModel* pSm, G3D::AABox& pAABox)
48    {
49        ShortBox box = pSm->getReletiveBounds();
50        pAABox.set(box.getLo().getVector3()+pSm->getBasePosition(), box.getHi().getVector3()+pSm->getBasePosition());
51    }
52
53    //==========================================================
54    //==========================================================
55    //==========================================================
56    //==========================================================
57    SubModel::SubModel(unsigned int pNTriangles, TriangleBox *pTriangles, unsigned int pTrianglesPos, unsigned int pNNodes, TreeNode *pTreeNodes, unsigned int pNodesPos) :
58    BaseModel(pNNodes, pTreeNodes, pNTriangles, pTriangles)
59    {
60        iTrianglesPos = pTrianglesPos;
61        iNodesPos = pNodesPos;
62        iHasInternalMemAlloc = false;
63    }
64
65    //==========================================================
66
67    SubModel::~SubModel(void)
68    {
69        if(iHasInternalMemAlloc)
70        {
71            free();
72        }
73    }
74
75    //==========================================================
76
77    bool SubModel::operator==(const SubModel& pSm2) const
78    {
79        bool result = false;
80
81        if(getNNodes() == pSm2.getNNodes() &&
82            getNTriangles() == pSm2.getNTriangles() &&
83            getBasePosition() == pSm2.getBasePosition() &&
84            getNodesPos() == pSm2.getNodesPos() &&
85            getTrianglesPos() == pSm2.getTrianglesPos())
86        {
87            result = true;
88        }
89        return result;
90    }
91    //==========================================================
92
93    enum BIN_POSITIONS
94    {
95        BP_iNTriangles=8,
96        BP_iNNodes=12,
97        BP_iBasePosition=16,
98        BP_iNodesPos=28,
99        BP_iTrianglesPos=32,
100        BP_iHasInternalMemAlloc=36,
101        BP_iBox=38,
102    };
103    /**
104    This is ugly, but due to compatibility and 64 bit support we have to do that ... sorry
105    */
106    void SubModel::initFromBinBlock(void *pBinBlock)
107    {
108        iNTriangles =  *((unsigned int *)(((char *) pBinBlock) + BP_iNTriangles));
109        iNNodes =  *((unsigned int *) (((char *) pBinBlock) + BP_iNNodes));
110        iBasePosition =  *((Vector3 *) (((char *) pBinBlock) + BP_iBasePosition));
111        iNodesPos =  *((unsigned int *) (((char *) pBinBlock) + BP_iNodesPos));
112        iTrianglesPos =  *((unsigned int *) (((char *) pBinBlock) + BP_iTrianglesPos));
113        iHasInternalMemAlloc = *((bool *) (((char *) pBinBlock) + BP_iHasInternalMemAlloc));
114        iBox =  *((ShortBox *) (((char *) pBinBlock) + BP_iBox));
115    }
116
117    //==========================================================
118
119    void SubModel::countNodesAndTriangles(AABSPTree<Triangle>::Node& pNode, int &pNNodes, int &pNTriabgles)
120    {
121        ++pNNodes;
122        pNTriabgles += pNode.valueArray.size();
123
124        #ifdef _ASSEMBLER_DEBUG
125        fprintf(::g_df, "Nodes: %d, Tris: %d\n",pNNodes, pNTriabgles);
126        #endif
127
128        if(pNode.child[0] != 0)
129        {
130            countNodesAndTriangles(*pNode.child[0], pNNodes, pNTriabgles);
131        }
132        if(pNode.child[1] != 0)
133        {
134            countNodesAndTriangles(*pNode.child[1], pNNodes, pNTriabgles);
135        }
136    }
137
138    //==========================================================
139
140    void SubModel::fillContainer(const AABSPTree<Triangle>::Node& pNode, int &pTreeNodePos, int &pTrianglePos, Vector3& pLo, Vector3& pHi)
141    {
142        TreeNode treeNode = TreeNode(pNode.valueArray.size(), pTrianglePos);
143        treeNode.setSplitAxis(pNode.splitAxis);
144        treeNode.setSplitLocation(pNode.splitLocation);
145
146        int currentTreeNodePos = pTreeNodePos++;
147
148        Vector3 lo = Vector3(inf(),inf(),inf());
149        Vector3 hi = Vector3(-inf(),-inf(),-inf());
150
151        for(int i=0;i<pNode.valueArray.size(); i++)
152        {
153            G3D::_AABSPTree::Handle<Triangle>* h= pNode.valueArray[i];
154            Triangle t = h->value;
155            TriangleBox triangleBox = TriangleBox(t.vertex(0),t.vertex(1), t.vertex(2));
156            lo = lo.min(triangleBox.getBounds().getLo().getVector3());
157            hi = hi.max(triangleBox.getBounds().getHi().getVector3());
158
159            getTriangles()[pTrianglePos++] = triangleBox;
160        }
161
162        if(pNode.child[0] != 0)
163        {
164            treeNode.setChildPos(0, pTreeNodePos);
165            fillContainer(*pNode.child[0], pTreeNodePos, pTrianglePos, lo, hi);
166        }
167        if(pNode.child[1] != 0)
168        {
169            treeNode.setChildPos(1, pTreeNodePos);
170            fillContainer(*pNode.child[1], pTreeNodePos, pTrianglePos, lo, hi);
171        }
172
173        treeNode.setBounds(lo,hi);
174
175        // get absolute bounds
176        pLo = pLo.min(lo);
177        pHi = pHi.max(hi);
178
179        getTreeNodes()[currentTreeNodePos] = treeNode;
180    }
181
182    //==========================================================
183
184    SubModel::SubModel(AABSPTree<Triangle> *pTree)
185    {
186        int nNodes, nTriangles;
187        nNodes = nTriangles = 0;
188        countNodesAndTriangles(*pTree->root, nNodes, nTriangles);
189
190        init(nNodes, nTriangles);
191
192        iTrianglesPos = 0;                                  // this is the global array
193        iNodesPos = 0;                                      // this is the global array
194        iHasInternalMemAlloc = true;
195        int treeNodePos, trianglePos;
196        treeNodePos = trianglePos = 0;
197
198        Vector3 lo = Vector3(inf(),inf(),inf());
199        Vector3 hi = Vector3(-inf(),-inf(),-inf());
200
201        fillContainer(*pTree->root, treeNodePos, trianglePos, lo, hi);
202        setReletiveBounds(lo, hi);
203    }
204
205    //==========================================================
206#ifdef _DEBUG_VMAPS
207#ifndef gBoxArray
208    extern Vector3 p1,p2,p3,p4,p5,p6,p7;
209    extern Array<AABox>gBoxArray;
210    extern Array<G3D::Triangle>gTriArray;
211    extern int gCount1, gCount2, gCount3, gCount4;
212    extern bool myfound;
213#endif
214#endif
215
216    //==========================================================
217    void SubModel::intersect(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit, G3D::Vector3& /*pOutLocation*/, G3D::Vector3& /*pOutNormal*/) const
218    {
219            NodeValueAccess<TreeNode, TriangleBox> vna = NodeValueAccess<TreeNode, TriangleBox>(getTreeNodes(), getTriangles());
220            IntersectionCallBack<TriangleBox> intersectCallback;
221            Ray relativeRay = Ray::fromOriginAndDirection(pRay.origin - getBasePosition(), pRay.direction);
222#ifdef _DEBUG_VMAPS
223            //p6=getBasePosition();
224            //gBoxArray.push_back(getAABoxBounds());
225#endif
226            getTreeNode(0).intersectRay(relativeRay, intersectCallback, pMaxDist, vna, pStopAtFirstHit, false);
227    }
228
229    //==========================================================
230
231    bool SubModel::intersect(const G3D::Ray& pRay, float& pMaxDist) const
232    {
233        return BaseModel::intersect(getAABoxBounds(), pRay, pMaxDist);
234    }
235
236    //==========================================================
237
238    template<typename RayCallback>
239    void SubModel::intersectRay(const Ray& pRay, RayCallback& pIntersectCallback, float& pMaxDist, bool pStopAtFirstHit, bool intersectCallbackIsFast)
240    {
241        if(intersect(pRay, pMaxDist))
242        {
243            NodeValueAccess<TreeNode, TriangleBox> vna = NodeValueAccess<TreeNode, TriangleBox>(getTreeNodes(), getTriangles());
244            IntersectionCallBack<TriangleBox> intersectCallback;
245             getTreeNode(0).intersectRay(pRay, intersectCallback, pMaxDist, vna, pStopAtFirstHit, false);
246        }
247    }
248    //==========================================================
249
250}
Note: See TracBrowser for help on using the browser.