//--------------------------------------------------------------------------- #include #include //#include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "GLBaseClasses" #pragma link "GLCadencer" #pragma link "GLCoordinates" #pragma link "GLMaterial" #pragma link "GLObjects" #pragma link "GLScene" #pragma link "GLSimpleNavigation" #pragma link "GLWin32Viewer" #pragma link "GLCrossPlatform" #pragma resource "*.dfm" TForm1 *Form1; const cBOX_SIZE = 14.2; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { int i; Randomize; Octree = new TOctreeSpacePartition; Octree->SetSize(AffineVectorMake(-15, -15, -15), AffineVectorMake(15, 15, 15)); Octree->MaxTreeDepth = 6; Octree->LeafThreshold = 10; TrackBar_LeafThresholdChange(NULL); for (i = 0; i < 300; i ++) CreateBox(); VerifySpacialMisc(); } // class TGLSpacePartitionLeaf __fastcall TGLSpacePartitionLeaf::CreateGLOwned(TBaseSpacePartition *SpacePartition, TGLBaseSceneObject *aGLBaseSceneObject) { GLBaseSceneObject = aGLBaseSceneObject; // Set them all off in the same direction Direction.X = rand(); Direction.Y = rand(); Direction.Z = rand(); NormalizeVector(Direction); // inherited CreateOwned(SpacePartition); } void __fastcall TGLSpacePartitionLeaf::UpdateCachedAABBAndBSphere() { FCachedAABB = GLBaseSceneObject->AxisAlignedBoundingBox(); FCachedAABB.Min = GLBaseSceneObject->LocalToAbsolute(FCachedAABB.Min); FCachedAABB.Max = GLBaseSceneObject->LocalToAbsolute(FCachedAABB.Max); FCachedBSphere.Radius = GLBaseSceneObject->BoundingSphereRadius(); FCachedBSphere.Center = GLBaseSceneObject->Position->AsAffineVector; } //--------------------------------------------------------------------------- TAffineVector RandomPos() { int c1 = 10; TAffineVector result; //MakeVector(result, rand()*c1-c1/2, rand()*c1-c1/2, rand()*c1-c1/2); MakeVector(result, rand(), rand(), rand()); return result; }; float RandomSize() { return 0.1+rand()*0.5; }; void __fastcall TForm1::CreateBox() { TGLCube *GLCube; TGLSpacePartitionLeaf * GLSpacePartitionLeaf; GLCube = (TGLCube *)GLScene1->Objects->AddNewChild(__classid(TGLCube)); GLCube->Position->AsAffineVector = RandomPos(); GLCube->CubeWidth = RandomSize(); GLCube->CubeHeight = RandomSize(); GLCube->CubeDepth = RandomSize(); GLSpacePartitionLeaf = new TGLSpacePartitionLeaf; GLSpacePartitionLeaf->CreateGLOwned(Octree, GLCube); //C++ } //--------------------------------------------------------------------------- void __fastcall TForm1::TrackBar_LeafThresholdChange(TObject *Sender) { Label3->Caption = Format("Leaf Threshold : %d", ARRAYOFCONST ((TrackBar_LeafThreshold->Position))); Octree->LeafThreshold = TrackBar_LeafThreshold->Position; } //--------------------------------------------------------------------------- float TestMove(float pos, float dir, const double deltaTime) { const cSPEED = 2; { if (abs(pos+dir*deltaTime*cSPEED)>=cBOX_SIZE) dir = -dir; return (pos + dir * deltaTime*cSPEED); } } void __fastcall TForm1::RenderAABB(TAABB* AABB, float w, float r, float g, float b) { /* rci.GLStates->LineWidth = w; glColor3f(r,g,b); glBegin(GL_LINE_STRIP); glVertex3f(AABB.min.X,AABB.min.Y, AABB.min.Z); glVertex3f(AABB.min.X,AABB.max.Y, AABB.min.Z); glVertex3f(AABB.max.X,AABB.max.Y, AABB.min.Z); glVertex3f(AABB.max.X,AABB.min.Y, AABB.min.Z); glVertex3f(AABB.min.X,AABB.min.Y, AABB.min.Z); glVertex3f(AABB.min.X,AABB.min.Y, AABB.max.Z); glVertex3f(AABB.min.X,AABB.max.Y, AABB.max.Z); glVertex3f(AABB.max.X,AABB.max.Y, AABB.max.Z); glVertex3f(AABB.max.X,AABB.min.Y, AABB.max.Z); glVertex3f(AABB.min.X,AABB.min.Y, AABB.max.Z); glEnd(); glBegin(GL_LINES); glVertex3f(AABB.min.X,AABB.max.Y, AABB.min.Z); glVertex3f(AABB.min.X,AABB.max.Y, AABB.max.Z); glVertex3f(AABB.max.X,AABB.max.Y, AABB.min.Z); glVertex3f(AABB.max.X,AABB.max.Y, AABB.max.Z); glVertex3f(AABB.max.X,AABB.min.Y, AABB.min.Z); glVertex3f(AABB.max.X,AABB.min.Y, AABB.max.Z); glEnd(); */ } //--------------------------------------------------------------------------- void __fastcall TForm1::RenderOctreeNode(TSectorNode* Node) { int i; TAABB* AABB; if (Node->NoChildren) { AABB = new TAABB; // AABB = Node->AABB; if (Node->RecursiveLeafCount > 0) RenderAABB(AABB, 1, 0, 0, 0); else RenderAABB(AABB, 1, 0.8, 0.8, 0.8); } else { for (i = 0; i < Node->ChildCount-1; i++) RenderOctreeNode(Node->Children[i]); } } //--------------------------------------------------------------------------- void __fastcall TForm1::GLDirectOpenGL1Render(TObject *Sender, TGLRenderContextInfo &rci) { TAABB* AABB; rci.GLStates->Disable(stLighting); rci.GLStates->Enable(stColorMaterial); MakeVector(AABB->Min, -cBOX_SIZE, -cBOX_SIZE, -cBOX_SIZE); MakeVector(AABB->Max, cBOX_SIZE, cBOX_SIZE, cBOX_SIZE); RenderAABB(AABB,2, 0,0,0); RenderOctreeNode(Octree->RootNode); } //--------------------------------------------------------------------------- void __fastcall TForm1::GLCadencer1Progress(TObject *Sender, const double deltaTime, const double newTime) { const cSPEED = 2; TAABB* AABB; TBSphere* BSphere; TGLSpacePartitionLeaf* Leaf; TGLSpacePartitionLeaf* TestLeaf; TGLCube* Cube; int i, j, CollidingLeafCount; for (i = 0; i < Octree->Leaves->Count-1; i++) { Leaf = (TGLSpacePartitionLeaf*)(Octree->Leaves->Items[i]); Cube = (TGLCube*)(Leaf->GLBaseSceneObject); Cube->Position->X = TestMove(Cube->Position->X, Leaf->GLBaseSceneObject->Direction->X, deltaTime); Cube->Position->Y = TestMove(Cube->Position->Y, Leaf->GLBaseSceneObject->Direction->Y, deltaTime); Cube->Position->Z = TestMove(Cube->Position->Z, Leaf->GLBaseSceneObject->Direction->Z, deltaTime); Leaf->Changed(); } for (i = 0; i < Octree->Leaves->Count-1; i++) { Leaf = (TGLSpacePartitionLeaf*)(Octree->Leaves->Items[i]); Cube = (TGLCube*)(Leaf->GLBaseSceneObject); Cube->Material->FrontProperties->Emission->Red = 0; Cube->Material->FrontProperties->Emission->Green = 0; Cube->Material->FrontProperties->Emission->Blue = 0; } // AABB collision AABB = new TAABB(); /* AABB = GLCube1->AxisAlignedBoundingBox; AABB->Max = GLCube1->LocalToAbsolute(AABB->Min); AABB->Max = GLCube1->LocalToAbsolute(AABB->Max); Octree->QueryAABB(AABB); */ } //--------------------------------------------------------------------------- void __fastcall TForm1::VerifySpacialMisc() { TAABB* AABBmajor; TAABB* AABBfull; TAABB* AABBoff; TAABB* AABBpartial; AABBmajor = new TAABB; MakeVector(AABBmajor->Min, 0, 0, 0); MakeVector(AABBmajor->Max, 5, 5, 5); /* MakeVector(AABBpartial->Min, 4, 4, 4); MakeVector(AABBpartial->Max, 6, 6, 6); MakeVector(AABBfull->Min, 1, 1, 1); MakeVector(AABBfull->Max, 2, 2, 2); MakeVector(AABBoff->Min, 7, 7, 7); MakeVector(AABBoff->Max, 8, 8, 8); */ } //--------------------------------------------------------------------------- void __fastcall TForm1::Button_ResetOctreeSizeClick(TObject *Sender) { Octree->GrowMethod = gmBestFit; Octree->UpdateStructureSize(0.05); Octree->GrowMethod = gmIncreaseToFitAll; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormDestroy(TObject *Sender) { Octree->Free(); } //---------------------------------------------------------------------------