source: trunk/test/btphystest.cpp @ 2838

Last change on this file since 2838 was 2838, checked in by sam, 6 years ago

test: port the btphystest and meshviewer tests to the new input API.

  • Property svn:eol-style set to LF
File size: 15.3 KB
Line 
1//
2// BtPhysTest
3//
4// Copyright: (c) 2009-2013 Benjamin "Touky" Huet <huet.benjamin@gmail.com>
5//            (c) 2012-2013 Sam Hocevar <sam@hocevar.net>
6//
7
8#if defined HAVE_CONFIG_H
9#   include "config.h"
10#endif
11
12#include "core.h"
13#include "loldebug.h"
14
15using namespace lol;
16
17#ifndef HAVE_PHYS_USE_BULLET
18#define HAVE_PHYS_USE_BULLET
19#endif /* HAVE_PHYS_USE_BULLET */
20
21#include "physics/lolphysics.h"
22#include "physics/easyphysics.h"
23#include "physicobject.h"
24#include "btphystest.h"
25
26using namespace lol::phys;
27
28#define CUBE_HALF_EXTENTS .5f
29#define EXTRA_HEIGHT 1.f
30
31int gNumObjects = 64;
32
33#define USE_WALL        1
34#define USE_PLATFORM    1
35#define USE_ROPE        0
36#define USE_BODIES      1
37#define USE_ROTATION    0
38#define USE_CHARACTER   1
39#define USE_STAIRS      1
40
41BtPhysTest::BtPhysTest(bool editor)
42{
43    m_loop_value = .0f;
44
45    /* Register an input controller for the keyboard */
46    m_controller = new Controller(KEY_MAX, 0);
47    m_controller->GetKey(KEY_MOVE_FORWARD).Bind("Keyboard", "Up");
48    m_controller->GetKey(KEY_MOVE_BACK).Bind("Keyboard", "Down");
49    m_controller->GetKey(KEY_MOVE_LEFT).Bind("Keyboard", "Left");
50    m_controller->GetKey(KEY_MOVE_RIGHT).Bind("Keyboard", "Right");
51    m_controller->GetKey(KEY_MOVE_JUMP).Bind("Keyboard", "Space");
52    m_controller->GetKey(KEY_MOVE_UP).Bind("Keyboard", "PageUp");
53    m_controller->GetKey(KEY_MOVE_DOWN).Bind("Keyboard", "PageDown");
54    m_controller->GetKey(KEY_QUIT).Bind("Keyboard", "Escape");
55
56    /* Create a camera that matches the settings of XNA BtPhysTest */
57    m_camera = new Camera();
58    m_camera->SetView(vec3(50.f, 50.f, 0.f),
59                      vec3(0.f, 0.f, 0.f),
60                      vec3(0, 1, 0));
61    m_camera->SetProjection(mat4::perspective(45.f, 1280.f, 960.f, .1f, 1000.f));
62    g_scene->PushCamera(m_camera);
63
64    m_ready = false;
65
66    m_simulation = new Simulation();
67    m_simulation->SetWorldLimit(vec3(-1000.0f, -1000.0f, -1000.0f), vec3(1000.0f, 1000.0f, 1000.0f));
68    m_simulation->Init();
69    vec3 NewGravity = vec3(.0f, -10.0f, .0f);
70    m_simulation->SetGravity(NewGravity);
71    m_simulation->SetContinuousDetection(true);
72    m_simulation->SetTimestep(1.f / 120.f);
73    Ticker::Ref(m_simulation);
74
75    /* Add a white directional light */
76    m_light1 = new Light();
77    m_light1->SetPosition(vec4(0.2f, 0.2f, 0.f, 0.f));
78    m_light1->SetColor(vec4(0.5f, 0.5f, 0.5f, 1.f));
79    Ticker::Ref(m_light1);
80
81    /* Add an orangeish point light */
82    m_light2 = new Light();
83    m_light2->SetPosition(vec4(-15.f, 15.f, 15.f, 1.f));
84    m_light2->SetColor(vec4(0.4f, 0.3f, 0.2f, 1.f));
85    Ticker::Ref(m_light2);
86
87    float offset = 29.5f;
88    vec3 pos_offset = vec3(.0f, 30.f, .0f);
89    if (USE_STAIRS)
90    {
91        vec3 new_offset = vec3(1.0f, .125f, .0f);
92        quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
93        vec3 NewPosition = pos_offset + vec3(5.0f, -29.f, 15.0f);
94        {
95            NewRotation = quat::fromeuler_xyz(0.f, 0.f, 30.f);
96            NewPosition += vec3(4.0f, .0f, -4.0f);
97
98            PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
99            Ticker::Ref(NewPhyobj);
100            m_stairs_list << NewPhyobj;
101        }
102        {
103            NewRotation = quat::fromeuler_xyz(0.f, 0.f, 40.f);
104            NewPosition += vec3(4.0f, .0f, -4.0f);
105
106            PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
107            Ticker::Ref(NewPhyobj);
108            m_stairs_list << NewPhyobj;
109        }
110        NewPosition = pos_offset + vec3(5.0f, -29.5f, 15.0f);
111        NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
112        for (int i=0; i < 15; i++)
113        {
114            NewPosition += new_offset;
115
116            PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
117            Ticker::Ref(NewPhyobj);
118            m_stairs_list << NewPhyobj;
119        }
120    }
121
122    if (USE_WALL)
123    {
124        for (int i=0; i < 6; i++)
125        {
126            vec3 NewPosition = vec3(.0f);
127            quat NewRotation = quat(1.f);
128
129            PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation);
130
131            int idx = i/2;
132            NewPosition = pos_offset;
133            NewPosition[idx] += offset;
134            offset *= -1.f;
135
136            if (idx != 1)
137            {
138                vec3 NewAxis = vec3(.0f);
139                NewAxis[2 - idx] = 1;
140                NewRotation = quat::rotate(90.f, NewAxis);
141            }
142
143            NewPhyobj->SetTransform(NewPosition, NewRotation);
144            Ticker::Ref(NewPhyobj);
145            m_ground_list << NewPhyobj;
146        }
147    }
148
149    PhysicsObject* BasePhyobj = NULL;
150    if (USE_PLATFORM)
151    {
152        quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
153        vec3 NewPosition = pos_offset + vec3(5.0f, -25.0f, -15.0f);
154
155        PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
156
157        m_platform_list << NewPhyobj;
158        Ticker::Ref(NewPhyobj);
159
160        NewPosition = pos_offset + vec3(-15.0f, -25.0f, 5.0f);
161
162        NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
163        BasePhyobj = NewPhyobj;
164
165        m_platform_list << NewPhyobj;
166        Ticker::Ref(NewPhyobj);
167
168        NewRotation = quat::fromeuler_xyz(0.f, 0.f, 90.f);
169        NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f);
170
171        NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
172
173        NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, true);
174        m_platform_list << NewPhyobj;
175        Ticker::Ref(NewPhyobj);
176
177        //NewPosition += vec3(-0.0f, .0f, .0f);
178        //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
179
180        //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, false);
181        //m_platform_list << NewPhyobj;
182        //Ticker::Ref(NewPhyobj);
183
184        //NewPosition += vec3(-2.0f, .0f, .0f);
185        //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
186
187        //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), false, false);
188        //m_platform_list << NewPhyobj;
189        //Ticker::Ref(NewPhyobj);
190    }
191
192    if (USE_CHARACTER)
193    {
194        quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
195        vec3 NewPosition = pos_offset + vec3(-5.0f, -10.0f, 15.0f);
196
197        PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2);
198
199        m_character_list << NewPhyobj;
200        Ticker::Ref(NewPhyobj);
201
202        //NewPhyobj->GetCharacter()->AttachTo(BasePhyobj->GetPhysic(), true, true);
203    }
204
205    if (USE_BODIES)
206    {
207        for (int x=0; x < 6; x++)
208        {
209            for (int y=0; y < 6; y++)
210            {
211                for (int z=0; z < 5; z++)
212                {
213                    PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
214                        vec3(-20.f, 15.f, -20.f) +
215                        vec3(8.f * (float)x, 8.f * (float)y, 8.f * (float)z));
216                    m_physobj_list << new_physobj;
217                    Ticker::Ref(new_physobj);
218                }
219            }
220        }
221    }
222
223    if (USE_ROPE)
224    {
225        Array<PhysicsObject*> RopeElements;
226        for (int i = 0; i < 14; i++)
227        {
228            PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
229                vec3(0.f, 15.f, -20.f) +
230                vec3(0.f, 0.f, 2.f * (float)i), 1);
231            RopeElements << new_physobj;
232            m_physobj_list << new_physobj;
233            Ticker::Ref(new_physobj);
234            if (RopeElements.Count() > 1)
235            {
236                EasyConstraint* new_constraint = new EasyConstraint();
237
238                vec3 A2B = .5f * (RopeElements[i]->GetPhysic()->GetTransform().v3.xyz -
239                            RopeElements[i - 1]->GetPhysic()->GetTransform().v3.xyz);
240                new_constraint->SetPhysObjA(RopeElements[i - 1]->GetPhysic(), lol::mat4::translate(A2B));
241                new_constraint->SetPhysObjB(RopeElements[i]->GetPhysic(), lol::mat4::translate(-A2B));
242                new_constraint->InitConstraintToPoint2Point();
243                new_constraint->DisableCollisionBetweenObjs(true);
244                new_constraint->AddToSimulation(m_simulation);
245                m_constraint_list << new_constraint;
246            }
247        }
248    }
249}
250
251void BtPhysTest::TickGame(float seconds)
252{
253    WorldEntity::TickGame(seconds);
254
255    if (m_controller->GetKey(KEY_QUIT).IsReleased())
256        Ticker::Shutdown();
257
258    m_loop_value += seconds;
259    if (m_loop_value > F_PI * 2.0f)
260        m_loop_value -= F_PI * 2.0f;
261
262    vec3 GroundBarycenter = vec3(.0f);
263    vec3 PhysObjBarycenter = vec3(.0f);
264    float factor = .0f;
265
266    if (USE_WALL)
267    {
268        for (int i = 0; i < m_ground_list.Count(); i++)
269        {
270            PhysicsObject* PhysObj = m_ground_list[i];
271            mat4 GroundMat = PhysObj->GetTransform();
272
273            GroundBarycenter += GroundMat.v3.xyz;
274            factor += 1.f;
275        }
276
277        GroundBarycenter /= factor;
278
279        for (int i = 0; i < m_ground_list.Count(); i++)
280        {
281            PhysicsObject* PhysObj = m_ground_list[i];
282
283            mat4 GroundMat = PhysObj->GetTransform();
284            vec3 CenterToGround = GroundMat.v3.xyz - GroundBarycenter;
285            vec3 CenterToCam = m_camera->GetPosition() - GroundBarycenter;
286
287            if (dot(normalize(CenterToCam - CenterToGround),
288                    normalize(CenterToGround)) > 0.f)
289                PhysObj->SetRender(false);
290            else
291                PhysObj->SetRender(true);
292        }
293    }
294
295    if (USE_ROTATION)
296    {
297        for (int i = 0; i < m_ground_list.Count(); i++)
298        {
299            PhysicsObject* PhysObj = m_ground_list[i];
300
301            mat4 GroundMat = PhysObj->GetTransform();
302            mat4 CenterMx = mat4::translate(GroundBarycenter);
303            GroundMat = inverse(CenterMx) * GroundMat;
304            GroundMat = CenterMx *
305                        mat4(quat::fromeuler_xyz(vec3(.0f, 20.f, 20.0f) * seconds))
306                        * GroundMat;
307            PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
308        }
309    }
310
311    if (USE_PLATFORM)
312    {
313        for (int i = 0; i < m_platform_list.Count(); i++)
314        {
315            PhysicsObject* PhysObj = m_platform_list[i];
316
317            mat4 GroundMat = PhysObj->GetTransform();
318            if (i == 0)
319            {
320                GroundMat = GroundMat * mat4(quat::fromeuler_xyz(vec3(20.f, .0f, .0f) * seconds));
321                PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
322            }
323            else if (i == 1)
324            {
325                GroundMat =
326                    mat4::translate(vec3(-15.0f, 5.0f, lol::cos(m_loop_value) * 8.f)) *
327                    mat4(quat::fromeuler_xyz(vec3(.0f, lol::cos(m_loop_value) * 20.f, .0f)));
328                PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
329            }
330        }
331    }
332
333    if (USE_CHARACTER)
334    {
335        for (int i = 0; i < m_character_list.Count(); i++)
336        {
337            PhysicsObject* PhysObj = m_character_list[i];
338            EasyCharacterController* Character = (EasyCharacterController*)PhysObj->GetCharacter();
339            mat4 CtlrMx = Character->GetTransform();
340
341            vec3 movement(0.f);
342            movement.z = (m_controller->GetKey(KEY_MOVE_RIGHT).IsDown() ? 1.f : 0.f)
343                       - (m_controller->GetKey(KEY_MOVE_LEFT).IsDown() ? 1.f : 0.f);
344            movement.x = (m_controller->GetKey(KEY_MOVE_FORWARD).IsDown() ? 1.f : 0.f)
345                       - (m_controller->GetKey(KEY_MOVE_BACK).IsDown() ? 1.f : 0.f);
346            movement.y = (m_controller->GetKey(KEY_MOVE_UP).IsDown() ? 1.f : 0.f)
347                       - (m_controller->GetKey(KEY_MOVE_DOWN).IsDown() ? 1.f : 0.f);
348            vec3 CharMove = movement * seconds * vec3(4.f, 10.f, 4.f);
349
350            if (m_controller->GetKey(KEY_MOVE_JUMP).IsReleased())
351                Character->Jump();
352            Character->SetMovementForFrame(CharMove);
353
354            RayCastResult HitResult;
355            if (m_simulation->RayHits(HitResult, ERT_Closest, Character->GetTransform().v3.xyz, (Character->GetTransform().v3.xyz + vec3(.0f, -1.f, .0f)), Character))
356                Character->AttachTo(HitResult.m_collider_list[0], true, true);
357            else
358                Character->AttachTo(NULL);
359        }
360    }
361
362    if (USE_CHARACTER)
363    {
364        PhysObjBarycenter = vec3(.0f);
365        factor = .0f;
366
367        for (int i = 0; i < m_character_list.Count(); i++)
368        {
369            PhysicsObject* PhysObj = m_character_list[i];
370            mat4 GroundMat = PhysObj->GetTransform();
371
372            PhysObjBarycenter += GroundMat.v3.xyz;
373            factor += 1.f;
374        }
375
376        PhysObjBarycenter /= factor;
377
378#if 0
379        m_camera->SetTarget(m_camera->GetTarget() + (seconds / (seconds + 0.18f)) * (PhysObjBarycenter - m_camera->GetTarget()));
380        vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 5.0f, .0f);
381        m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 20.0f);
382#endif
383    }
384    else
385    {
386        PhysObjBarycenter = vec3(.0f);
387        for (int i = 0; i < m_physobj_list.Count(); i++)
388        {
389            PhysicsObject* PhysObj = m_physobj_list[i];
390            mat4 GroundMat = PhysObj->GetTransform();
391
392            PhysObjBarycenter += GroundMat.v3.xyz;
393            factor += 1.f;
394        }
395
396        PhysObjBarycenter /= factor;
397
398#if 0
399        m_camera->SetTarget(PhysObjBarycenter);
400        m_camera->SetPosition(GroundBarycenter + normalize(GroundBarycenter - PhysObjBarycenter) * 60.0f);
401#endif
402    }
403
404}
405
406void BtPhysTest::TickDraw(float seconds)
407{
408    WorldEntity::TickDraw(seconds);
409
410    if (!m_ready)
411    {
412        /* FIXME: this object never cleans up */
413        m_ready = true;
414    }
415
416    //Video::SetClearColor(vec4(0.0f, 0.0f, 0.12f, 1.0f));
417
418}
419
420BtPhysTest::~BtPhysTest()
421{
422    g_scene->PopCamera(m_camera);
423    Ticker::Unref(m_light1);
424    Ticker::Unref(m_light2);
425
426    while (m_constraint_list.Count())
427    {
428        EasyConstraint* CurPop = m_constraint_list.Last();
429        m_constraint_list.Pop();
430        CurPop->RemoveFromSimulation(m_simulation);
431        delete CurPop;
432    }
433    while (m_ground_list.Count())
434    {
435        PhysicsObject* CurPop = m_ground_list.Last();
436        m_ground_list.Pop();
437        CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
438        Ticker::Unref(CurPop);
439    }
440    while (m_stairs_list.Count())
441    {
442        PhysicsObject* CurPop = m_stairs_list.Last();
443        m_stairs_list.Pop();
444        CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
445        Ticker::Unref(CurPop);
446    }
447    while (m_character_list.Count())
448    {
449        PhysicsObject* CurPop = m_character_list.Last();
450        m_character_list.Pop();
451        CurPop->GetCharacter()->RemoveFromSimulation(m_simulation);
452        Ticker::Unref(CurPop);
453    }
454    while (m_platform_list.Count())
455    {
456        PhysicsObject* CurPop = m_platform_list.Last();
457        m_platform_list.Pop();
458        CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
459        Ticker::Unref(CurPop);
460    }
461    while (m_physobj_list.Count())
462    {
463        PhysicsObject* CurPop = m_physobj_list.Last();
464        m_physobj_list.Pop();
465        CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
466        Ticker::Unref(CurPop);
467    }
468    Ticker::Unref(m_simulation);
469
470}
471
472int main(int argc, char **argv)
473{
474    System::Init(argc, argv);
475
476    Application app("BtPhysTest", ivec2(1280, 720), 60.0f);
477
478    new BtPhysTest(argc > 1);
479    app.ShowPointer(false);
480
481    app.Run();
482
483    return EXIT_SUCCESS;
484}
485
Note: See TracBrowser for help on using the repository browser.