From 9b1c0e006f20091f28f3f468cfcab1feb51286bd Mon Sep 17 00:00:00 2001 From: Neo2003 Date: Thu, 2 Oct 2008 16:23:55 -0500 Subject: [svn] * Proper SVN structure --HG-- branch : trunk --- src/shared/vmap/SubModel.cpp | 248 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 src/shared/vmap/SubModel.cpp (limited to 'src/shared/vmap/SubModel.cpp') diff --git a/src/shared/vmap/SubModel.cpp b/src/shared/vmap/SubModel.cpp new file mode 100644 index 00000000000..2a46b3c6a1f --- /dev/null +++ b/src/shared/vmap/SubModel.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "SubModel.h" + +#ifdef _ASSEMBLER_DEBUG +extern FILE *::g_df; +#endif + +using namespace G3D; + +namespace VMAP +{ + + //========================================================== + /** + Functions to use ModelContainer with a AABSPTree + */ + unsigned int hashCode(const SubModel& pSm) + { + return pSm.getNTriangles(); + } + + void getBounds(const SubModel& pSm, G3D::AABox& pAABox) + { + ShortBox box = pSm.getReletiveBounds(); + pAABox.set(box.getLo().getVector3()+pSm.getBasePosition(), box.getHi().getVector3()+pSm.getBasePosition()); + } + + void getBounds(const SubModel* pSm, G3D::AABox& pAABox) + { + ShortBox box = pSm->getReletiveBounds(); + pAABox.set(box.getLo().getVector3()+pSm->getBasePosition(), box.getHi().getVector3()+pSm->getBasePosition()); + } + + //========================================================== + //========================================================== + //========================================================== + //========================================================== + SubModel::SubModel(unsigned int pNTriangles, TriangleBox *pTriangles, unsigned int pTrianglesPos, unsigned int pNNodes, TreeNode *pTreeNodes, unsigned int pNodesPos) : + BaseModel(pNNodes, pTreeNodes, pNTriangles, pTriangles) + { + iTrianglesPos = pTrianglesPos; + iNodesPos = pNodesPos; + iHasInternalMemAlloc = false; + } + + //========================================================== + + SubModel::~SubModel(void) + { + if(iHasInternalMemAlloc) + { + free(); + } + } + + //========================================================== + + bool SubModel::operator==(const SubModel& pSm2) const + { + bool result = false; + + if(getNNodes() == pSm2.getNNodes() && + getNTriangles() == pSm2.getNTriangles() && + getBasePosition() == pSm2.getBasePosition() && + getNodesPos() == pSm2.getNodesPos() && + getTrianglesPos() == pSm2.getTrianglesPos()) + { + result = true; + } + return result; + } + //========================================================== + + enum BIN_POSITIONS + { + BP_iNTriangles=8, + BP_iNNodes=12, + BP_iBasePosition=16, + BP_iNodesPos=28, + BP_iTrianglesPos=32, + BP_iHasInternalMemAlloc=36, + BP_iBox=38, + }; + /** + This is ugly, but due to compatibility and 64 bit support we have to do that ... sorry + */ + void SubModel::initFromBinBlock(void *pBinBlock) + { + iNTriangles = *((unsigned int *)(((char *) pBinBlock) + BP_iNTriangles)); + iNNodes = *((unsigned int *) (((char *) pBinBlock) + BP_iNNodes)); + iBasePosition = *((Vector3 *) (((char *) pBinBlock) + BP_iBasePosition)); + iNodesPos = *((unsigned int *) (((char *) pBinBlock) + BP_iNodesPos)); + iTrianglesPos = *((unsigned int *) (((char *) pBinBlock) + BP_iTrianglesPos)); + iHasInternalMemAlloc = *((bool *) (((char *) pBinBlock) + BP_iHasInternalMemAlloc)); + iBox = *((ShortBox *) (((char *) pBinBlock) + BP_iBox)); + } + + //========================================================== + + void SubModel::countNodesAndTriangles(AABSPTree::Node& pNode, int &pNNodes, int &pNTriabgles) + { + ++pNNodes; + pNTriabgles += pNode.valueArray.size(); + + #ifdef _ASSEMBLER_DEBUG + fprintf(::g_df, "Nodes: %d, Tris: %d\n",pNNodes, pNTriabgles); + #endif + + if(pNode.child[0] != 0) + { + countNodesAndTriangles(*pNode.child[0], pNNodes, pNTriabgles); + } + if(pNode.child[1] != 0) + { + countNodesAndTriangles(*pNode.child[1], pNNodes, pNTriabgles); + } + } + + //========================================================== + + void SubModel::fillContainer(const AABSPTree::Node& pNode, int &pTreeNodePos, int &pTrianglePos, Vector3& pLo, Vector3& pHi) + { + TreeNode treeNode = TreeNode(pNode.valueArray.size(), pTrianglePos); + treeNode.setSplitAxis(pNode.splitAxis); + treeNode.setSplitLocation(pNode.splitLocation); + + int currentTreeNodePos = pTreeNodePos++; + + Vector3 lo = Vector3(inf(),inf(),inf()); + Vector3 hi = Vector3(-inf(),-inf(),-inf()); + + for(int i=0;i* h= pNode.valueArray[i]; + Triangle t = h->value; + TriangleBox triangleBox = TriangleBox(t.vertex(0),t.vertex(1), t.vertex(2)); + lo = lo.min(triangleBox.getBounds().getLo().getVector3()); + hi = hi.max(triangleBox.getBounds().getHi().getVector3()); + + getTriangles()[pTrianglePos++] = triangleBox; + } + + if(pNode.child[0] != 0) + { + treeNode.setChildPos(0, pTreeNodePos); + fillContainer(*pNode.child[0], pTreeNodePos, pTrianglePos, lo, hi); + } + if(pNode.child[1] != 0) + { + treeNode.setChildPos(1, pTreeNodePos); + fillContainer(*pNode.child[1], pTreeNodePos, pTrianglePos, lo, hi); + } + + treeNode.setBounds(lo,hi); + + // get absolute bounds + pLo = pLo.min(lo); + pHi = pHi.max(hi); + + getTreeNodes()[currentTreeNodePos] = treeNode; + } + + //========================================================== + + SubModel::SubModel(AABSPTree *pTree) + { + int nNodes, nTriangles; + nNodes = nTriangles = 0; + countNodesAndTriangles(*pTree->root, nNodes, nTriangles); + + init(nNodes, nTriangles); + + iTrianglesPos = 0; // this is the global array + iNodesPos = 0; // this is the global array + iHasInternalMemAlloc = true; + int treeNodePos, trianglePos; + treeNodePos = trianglePos = 0; + + Vector3 lo = Vector3(inf(),inf(),inf()); + Vector3 hi = Vector3(-inf(),-inf(),-inf()); + + fillContainer(*pTree->root, treeNodePos, trianglePos, lo, hi); + setReletiveBounds(lo, hi); + } + + //========================================================== +#ifdef _DEBUG_VMAPS +#ifndef gBoxArray + extern Vector3 p1,p2,p3,p4,p5,p6,p7; + extern ArraygBoxArray; + extern ArraygTriArray; + extern int gCount1, gCount2, gCount3, gCount4; + extern bool myfound; +#endif +#endif + + //========================================================== + void SubModel::intersect(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit, G3D::Vector3& /*pOutLocation*/, G3D::Vector3& /*pOutNormal*/) const + { + NodeValueAccess vna = NodeValueAccess(getTreeNodes(), getTriangles()); + IntersectionCallBack intersectCallback; + Ray relativeRay = Ray::fromOriginAndDirection(pRay.origin - getBasePosition(), pRay.direction); +#ifdef _DEBUG_VMAPS + //p6=getBasePosition(); + //gBoxArray.push_back(getAABoxBounds()); +#endif + getTreeNode(0).intersectRay(relativeRay, intersectCallback, pMaxDist, vna, pStopAtFirstHit, false); + } + + //========================================================== + + bool SubModel::intersect(const G3D::Ray& pRay, float& pMaxDist) const + { + return BaseModel::intersect(getAABoxBounds(), pRay, pMaxDist); + } + + //========================================================== + + template + void SubModel::intersectRay(const Ray& pRay, RayCallback& pIntersectCallback, float& pMaxDist, bool pStopAtFirstHit, bool intersectCallbackIsFast) + { + if(intersect(pRay, pMaxDist)) + { + NodeValueAccess vna = NodeValueAccess(getTreeNodes(), getTriangles()); + IntersectionCallBack intersectCallback; + getTreeNode(0).intersectRay(pRay, intersectCallback, pMaxDist, vna, pStopAtFirstHit, false); + } + } + //========================================================== + +} -- cgit v1.2.3