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

Revision 2, 8.7 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

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