//--------------------------------------------------------------------------- #include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "GLS.Scene" #pragma link "GLS.File3DS" #pragma link "GLS.FileMD2" #pragma link "GLS.ProxyObjects" #pragma link "GLS.BaseClasses" #pragma link "GLS.BitmapFont" #pragma link "GLS.Cadencer" #pragma link "GLS.Coordinates" #pragma link "GLS.HeightData" #pragma link "GLS.HUDObjects" #pragma link "GLS.Material" #pragma link "GLS.Objects" #pragma link "GLS.TerrainRenderer" #pragma link "GLS.VectorFileObjects" #pragma link "GLS.SceneViewer" #pragma link "GLS.WindowsFont" #pragma resource "*.dfm" TForm1 *Form1; const float cForce = 250.0; const int cSpread = 200; const int cNbMushrooms = 20; float random(void) { return (float)(rand() & 0x1FFF) / (float)0x1FFF; } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void TForm1::Load() { SetGLSceneMediaDir(); //Load Materials GLMatLib->AddTextureMaterial("Terrain", "snow512.jpg"); GLMatLib->AddTextureMaterial("Actor", "waste.jpg"); //Load Terrain GLBitmapHDS1->MaxPoolSize = 8 * 1024 * 1024; GLBitmapHDS1->Picture->LoadFromFile("terrain.bmp"); Terrain->Direction->SetVector(0.0, 1.0, 0.0); Terrain->Material->LibMaterialName = "Terrain"; Terrain->TilesPerTexture = 256 / Terrain->TileSize; Terrain->Scale->SetVector(1.0, 1.0, 0.02); Ground->Material->LibMaterialName = "Terrain"; // Load mushroom mesh //Always use AutoScaling property or you may get some problems moMushroom->AutoScaling->SetPoint(0.1, 0.1, 0.1); moMushroom->LoadFromFile("Mushroom.3ds"); moMushroom->Direction->SetVector(0.0, 1.0, 0.0); moMushroom->BuildOctree(); //Load player Player->Position->SetPoint(0.0, 3.0, 0.0); //Actor GLActor1->LoadFromFile("Waste.md2"); GLActor1->Direction->SetVector(0.0, 1.0, 0.0); GLActor1->Up->SetVector(1.0, 0.0, 0.0); GLActor1->Scale->SetVector(0.05, 0.05, 0.05); GLActor1->Material->LibMaterialName = "Actor"; GLActor1->Animations->LoadFromFile("Quake2Animations.aaf"); // Define animation properties GLActor1->AnimationMode = aamLoop; GLActor1->SwitchToAnimation("stand"); GLActor1->FrameInterpolation = afpLinear; //DCE Behaviour GLSphere1->Scale->Assign(GetOrCreateDCEDynamic(Player)->Size); // GetOrCreateDCEDynamic(Player)->OnCollision = PlayerBehaviours0Collision; } //--------------------------------------------------------------------------- void TForm1::AddBall() { TGLSphere *Ball; float S; float pX,pY,pZ; float cR,cG,cB; Ball = (TGLSphere *)(Balls->AddNewChild(__classid(TGLSphere))); //with Ball do Ball->Tag = 1; //set the identifier of a ball Ball->Radius = 1.0; S = (float)(100.0 + random(900.0))/ 500.0; Ball->Scale->SetVector(S, S, S); pX = random(40.0) - random(40.0); pY = 4.0 + random(10.0); pZ = random(40.0) - random(40.0); Ball->Position->SetPoint(pX, pY, pZ); cR = (float)(100.0 + random(900.0))/1000; cG = (float)(100.0 + random(900.0))/1000; cB = (float)(100.0 + random(900.0))/1000; Ball->Material->FrontProperties->Diffuse->SetColor(cR, cG, cB); GetOrCreateDCEDynamic(Ball)->Manager = GLDCEManager1; GetOrCreateDCEDynamic(Ball)->BounceFactor = 0.75; GetOrCreateDCEDynamic(Ball)->Friction = 0.1; GetOrCreateDCEDynamic(Ball)->SlideOrBounce = csbBounce; GetOrCreateDCEDynamic(Ball)->Size->Assign(Ball->Scale); } //--------------------------------------------------------------------------- void TForm1::AddMushrooms() { int i; TGLFreeFormProxy *Proxy; TVector4f s; float f; // spawn some more mushrooms using proxy objects for (i = 0; i < cNbMushrooms - 1; i++) { // create a new Proxy and set its MasterObject property Proxy = (TGLFreeFormProxy *)(Mushrooms->AddNewChild(__classid(TGLFreeFormProxy))); Proxy->ProxyOptions = Proxy->ProxyOptions << pooObjects; Proxy->MasterObject = moMushroom; // retrieve reference attitude Proxy->Direction = moMushroom->Direction; Proxy->Up = moMushroom->Up; // randomize scale s = moMushroom->Scale->AsVector; f = 2.0 * random() + 1.0; ScaleVector(s, f); Proxy->Scale->AsVector = s; // randomize position Proxy->Position->SetPoint( (random(cSpread) - (float)(cSpread / 2.0)), (moMushroom->Position->Z + 1.5 * f), (random(cSpread) - (float)(cSpread / 2.0))); // randomize orientation Proxy->RollAngle = random(360.0); Proxy->TransformationChanged(); GetOrCreateDCEStatic(Proxy)->Manager = GLDCEManager1; GetOrCreateDCEStatic(Proxy)->BounceFactor = 0.75; GetOrCreateDCEStatic(Proxy)->Friction = 10.0; GetOrCreateDCEStatic(Proxy)->Shape = csFreeform; } } //--------------------------------------------------------------------------- void TForm1::HandleAnimation() { String anim; if (VectorNorm(GetOrCreateDCEDynamic(Player)->Speed) > 0.1) anim = "run"; else anim = "stand"; if (Jumped==true) { if (!GetOrCreateDCEDynamic(Player)->InGround) anim = "jump"; else Jumped = false; } if (anim == "jump") GLActor1->Interval = 500; else GLActor1->Interval = 100; if (GLActor1->CurrentAnimation() != anim) GLActor1->SwitchToAnimation(anim); } //--------------------------------------------------------------------------- void TForm1::HandleKeys() { TAffineVector Force; Force = NullVector; if (IsKeyDown(VK_ESCAPE)) Close(); if (IsKeyDown('w') || IsKeyDown('W') || IsKeyDown(VK_UP)) Force.Z = cForce; if (IsKeyDown('s') || IsKeyDown('S') || IsKeyDown(VK_DOWN)) Force.Z = -cForce; if (IsKeyDown('a') || IsKeyDown('A') || IsKeyDown(VK_LEFT)) Force.X = cForce; if (IsKeyDown('d') || IsKeyDown('D') || IsKeyDown(VK_RIGHT)) Force.X = -cForce; GetOrCreateDCEDynamic(Player)->ApplyAccel(Force); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { int i; if (Key == VK_F1) AddBall(); if (Key == VK_F2) for (i = 1; i <= 10; i++) AddBall(); if (Key == VK_F3) AddMushrooms(); if (Key == VK_SPACE) { GetOrCreateDCEDynamic(Player)->Jump(1.0, 20.0); Jumped = true; } if (Key == VK_F4) { Terrain->Visible = false; Ground->Visible = true; GetOrCreateDCEStatic(Terrain)->Active = false; GetOrCreateDCEStatic(Ground)->Active = true; } if (Key == VK_F5) GLDCEManager1->ManualStep = !GLDCEManager1->ManualStep; if (Key = VK_RETURN) { Player->Position->SetPoint(0.0, 3.0, 0.0); Balls->DeleteChildren(); Mushrooms->DeleteChildren(); Help->ModulateColor->Alpha = 1.0; Terrain->Visible = true; Ground->Visible = false; GetOrCreateDCEStatic(Terrain)->Active = true; GetOrCreateDCEStatic(Ground)->Active = false; } } //--------------------------------------------------------------------------- void __fastcall TForm1::GLSceneViewer1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { //Mouse look if (Shift.Contains(ssLeft)) { GLCamera1->MoveAroundTarget((my - Y), 0); Player->Turn(-(mx - X)); } mx = X; my = Y; } //--------------------------------------------------------------------------- void __fastcall TForm1::GLCadencer1Progress(TObject *Sender, const double deltaTime, const double newTime) { HandleKeys(); HandleAnimation(); //This shows the manual progress, don't need this if you use the automatic mode if (GLDCEManager1->ManualStep) GLDCEManager1->Step(deltaTime); Help->ModulateColor->Alpha = Help->ModulateColor->Alpha - (deltaTime * 0.05); if (Help->ModulateColor->Alpha < 0.25) Help->ModulateColor->Alpha = 0.25; HelpShadow->ModulateColor->Alpha = Help->ModulateColor->Alpha; HelpShadow->Text = Help->Text; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormShow(TObject *Sender) { Load(); GLCadencer1->Enabled = true; Help->Text = "Mouse Drag - Look\n\r\ A,W,S,D - movement\n\r\ SPACE - Jump\n\r\ F1 - Add one ball\n\r\ F2 - Add 10 balls\n\r\ F3 - Add 20 mushrooms\n\r\ F4 - Change ground to box\n\r\ F5 - Toggle step mode\n\r\ RETURN - Reset"; } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { String s; if (GLDCEManager1->ManualStep) s = "Manual"; else s = "Automatic"; GLHUDText1->Text = Format("FPS: %.1f - Dynamics: %d - Statics: %d - Step mode: %s", ARRAYOFCONST((GLSceneViewer1->FramesPerSecond(),GLDCEManager1->DynamicCount,GLDCEManager1->StaticCount,s))); GLSceneViewer1->ResetPerformanceMonitor(); } //--------------------------------------------------------------------------- void __fastcall TForm1::PlayerBehaviours0Collision(TObject *Sender, TGLBaseSceneObject *ObjectCollided, TDCECollision &CollisionInfo) { //Use some kind of identifier to know what object you are colliding //You can use the Tag, TagFloat, Name, Class TAffineVector v; if (ObjectCollided->Tag == 1) { v = AffineVectorMake(VectorSubtract(ObjectCollided->AbsolutePosition, Player->AbsolutePosition)); NormalizeVector(v); ScaleVector(v, 400.0); GetOrCreateDCEDynamic(ObjectCollided)->StopAbsAccel(); GetOrCreateDCEDynamic(ObjectCollided)->ApplyAbsAccel(v); } } //--------------------------------------------------------------------------- void __fastcall TForm1::GLDirectOpenGL1Render(TObject *Sender, TGLRenderContextInfo &rci) { int i; TAffineVector p, n; //To use this you will need to enable the debug define in the //GLEllipseCollision.pas, if you do, don't forget to clear the //triangle list! -> SetLength(Debug_Tri,0); rci.GLStates->PointSize = 5.0; glColor3f(0.0, 1.0, 0.0); for (i = 0; i < Debug_Tri.High; i++) { glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_STRIP); glVertex3f(Debug_Tri[i].p1.X, Debug_Tri[i].p1.Y, Debug_Tri[i].p1.Z); glVertex3f(Debug_Tri[i].p2.X, Debug_Tri[i].p2.Y, Debug_Tri[i].p2.Z); glVertex3f(Debug_Tri[i].p3.X, Debug_Tri[i].p3.Y, Debug_Tri[i].p3.Z); glEnd; CalcPlaneNormal(Debug_Tri[i].p1, Debug_Tri[i].p2, Debug_Tri[i].p3, n); ScaleVector(n, 0.25); p.X = (Debug_Tri[i].p1.X + Debug_Tri[i].p2.X + Debug_Tri[i].p3.X) / 3.0; p.Y = (Debug_Tri[i].p1.Y + Debug_Tri[i].p2.Y + Debug_Tri[i].p3.Y) / 3.0; p.Z = (Debug_Tri[i].p1.Z + Debug_Tri[i].p2.Z + Debug_Tri[i].p3.Z) / 3.0; glColor3f(0.0, 0.0, 1.0); glBegin(GL_LINE_STRIP); glVertex3f(p.X, p.Y, p.Z); glVertex3f(p.X + n.X, p.Y + n.Y, p.Z + n.Z); glEnd; glBegin(GL_POINTS); glVertex3f(p.X + n.X, p.Y + n.Y, p.Z + n.Z); glEnd; } Debug_Tri.Length = 0.0; } //---------------------------------------------------------------------------