//--------------------------------------------------------------------------------- void MeshAndBspLoadContext::readBspNode(BspNode* _bspNode) { readBspNodeBase(_bspNode); // Read flags BspNodeFlags flags; mDataStream->readData(flags); // Read separation plane used in BSP technology mDataStream->readData(_bspNode->separationPlane); _bspNode->lod = 0; if(mBspVersion == 0x0002) { mDataStream->readData(_bspNode->lod); } // Recursively read front BSP nodes if(flags.frontExist) { if(flags.frontIsLeaf) { mBspLeaves.push_back(BspLeaf()); BspLeaf* newBspLeaf = &mBspLeaves.back(); _bspNode->front = newBspLeaf; readBspLeaf(newBspLeaf); } else { mBspNodes.push_back(BspNode()); BspNode* newBspNode = &mBspNodes.back(); _bspNode->front = newBspNode; readBspNode(newBspNode); } } // Recursively read back BSP nodes if(flags.backExist) { if(flags.backIsLeaf) { mBspLeaves.push_back(BspLeaf()); BspLeaf* newBspLeaf = &mBspLeaves.back(); _bspNode->back = newBspLeaf; readBspLeaf(newBspLeaf); } else { mBspNodes.push_back(BspNode()); BspNode* newBspNode = &mBspNodes.back(); _bspNode->back = newBspNode; readBspNode(newBspNode); } } }
//--------------------------------------------------------------------------------- void MeshAndBspLoadContext::readBspNodes(Chunk& _chunk) { // Read all BSP nodes uint32 numBspNodesAndLeaves, numBspNodes, numBspLeaves; mDataStream->readData(numBspNodesAndLeaves); mDataStream->readData(numBspLeaves); numBspNodes = numBspNodesAndLeaves - numBspLeaves; mBspNodes.reserve(numBspNodes); mBspLeaves.reserve(numBspLeaves); mBspNodes.push_back(BspNode()); mRootBspNode = &mBspNodes.back(); readBspNode(mRootBspNode); }
void BspTree::BspNode::AddTriangle( const BspTriangle& in ) { if( m_bIsLeaf ) { // reinitialize ourselves as a node *this = BspNode( in ); } else { // test the BspTriangle against this node. PointListLoc res = this->m_plane.TestPoly( in ); BspTriangle front, back; // used in plistSPLIT switch( res ) { case plistFront: // drop down the front m_pFront->AddTriangle( in ); break; case plistBack: // drop down the back m_pBack->AddTriangle( in ); break; case plistSplit: { std::vector<BspTriangle> vFront; std::vector<BspTriangle> vBack; // split the BspTriangle, drop the halves down. m_plane.Split( in, vFront, vBack); for (unsigned int i=0; i<vFront.size(); i++) m_pFront->AddTriangle( vFront[i] ); for (unsigned int i=0; i<vBack.size(); i++) m_pBack->AddTriangle( vBack[i] ); break; } case plistCoplanar: // add the BspTriangle to this node's list m_coplanarList.push_back( in ); break; } } }
//---------------------------------------------------------------------------- BspNode* BspNodes::CreateNode (const Vector2f& v0, const Vector2f& v1, VertexColor3Effect* effect, const Float3& color) { // Create the model-space separating plane. Vector2f dir = v1 - v0; AVector normal(dir[1], -dir[0], 0.0f); normal.Normalize(); float constant = normal[0]*v0[0] + normal[1]*v0[1]; HPlane modelPlane(normal, constant); // Create the BSP node. BspNode* bsp = new0 BspNode(modelPlane); VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0); // Create the rectangle representation of the model plane and set the // vertex colors to the specified color. float xExtent = 0.5f*dir.Length(); float yExtent = 0.125f; TriMesh* rect = StandardMesh(vformat).Rectangle(2, 2, xExtent, yExtent); VertexBufferAccessor vba(rect); for (int i = 0; i < 4; ++i) { vba.Color<Float3>(0, i) = color; } rect->SetEffectInstance(effect->CreateInstance()); // Set the position and orientation for the world-space plane. APoint trn(0.5f*(v0[0] + v1[0]), 0.5f*(v0[1] + v1[1]), yExtent + 0.001f); HMatrix zRotate(AVector::UNIT_Z, Mathf::ATan2(dir.Y(),dir.X())); HMatrix xRotate(AVector::UNIT_X, Mathf::HALF_PI); HMatrix rotate = zRotate*xRotate; rect->LocalTransform.SetTranslate(trn); rect->LocalTransform.SetRotate(rotate); bsp->AttachCoplanarChild(rect); return bsp; }