PuzzleSDK
Physics3DTest.cpp
浏览该文件的文档.
1/****************************************************************************
2 Copyright (c) 2012 cocos2d-x.org
3 Copyright (c) 2015-2016 Chukong Technologies Inc.
4 Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
5
6 http://www.cocos2d-x.org
7
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 THE SOFTWARE.
25 ****************************************************************************/
26
27#include "Physics3DTest.h"
28
29#include "3d/CCTerrain.h"
30#include "3d/CCBundle3D.h"
31#include "physics3d/CCPhysics3D.h"
32#include "extensions/Particle3D/PU/CCPUParticleSystem3D.h"
35
36enum
37{
38 IDC_NEXT = 100,
41};
42
43#define START_POS_X -0.5
44#define START_POS_Y -2.5
45#define START_POS_Z -0.5
46
47#define ARRAY_SIZE_X 4
48#define ARRAY_SIZE_Y 3
49#define ARRAY_SIZE_Z 4
50
51static cocos2d::Scene *physicsScene = nullptr;
52
53Physics3DTests::Physics3DTests()
54{
55#if CC_USE_3D_PHYSICS == 0
57#else
58 ADD_TEST_CASE(BasicPhysics3DDemo);
59 ADD_TEST_CASE(Physics3DConstraintDemo);
60 ADD_TEST_CASE(Physics3DKinematicDemo);
61 ADD_TEST_CASE(Physics3DCollisionCallbackDemo);
62 ADD_TEST_CASE(Physics3DColliderDemo);
63 ADD_TEST_CASE(Physics3DTerrainDemo);
64#endif
65};
66
67#if CC_USE_3D_PHYSICS == 0
69{
70 TTFConfig ttfConfig("fonts/arial.ttf", 16);
71 auto label = Label::createWithTTF(ttfConfig, "Should define CC_USE_3D_PHYSICS\n to run this test case");
72
73 auto size = Director::getInstance()->getWinSize();
74 label->setPosition(Vec2(size.width / 2, size.height / 2));
75
76 addChild(label);
77
79}
80#else
81std::string Physics3DTestDemo::title() const
82{
83 return "Physics3D Test";
84}
85
86std::string Physics3DTestDemo::subtitle() const
87{
88 return "";
89}
90
91bool Physics3DTestDemo::init()
92{
93 if (!TestCase::init()) return false;
94
95 if (initWithPhysics())
96 {
97 getPhysics3DWorld()->setDebugDrawEnable(false);
98
99 physicsScene = this;
100 Size size = Director::getInstance()->getWinSize();
101 _camera = Camera::createPerspective(30.0f, size.width / size.height, 1.0f, 1000.0f);
102 _camera->setPosition3D(Vec3(0.0f, 50.0f, 100.0f));
103 _camera->lookAt(Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 1.0f, 0.0f));
104 _camera->setCameraFlag(CameraFlag::USER1);
105 this->addChild(_camera);
106
107 auto listener = EventListenerTouchAllAtOnce::create();
108 listener->onTouchesBegan = CC_CALLBACK_2(Physics3DTestDemo::onTouchesBegan, this);
109 listener->onTouchesMoved = CC_CALLBACK_2(Physics3DTestDemo::onTouchesMoved, this);
110 listener->onTouchesEnded = CC_CALLBACK_2(Physics3DTestDemo::onTouchesEnded, this);
111 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
112
113 TTFConfig ttfConfig("fonts/arial.ttf", 10);
114 auto label = Label::createWithTTF(ttfConfig,"DebugDraw OFF");
115 auto menuItem = MenuItemLabel::create(label, [=](Ref* /*ref*/){
116 if (getPhysics3DWorld()->isDebugDrawEnabled()){
117 getPhysics3DWorld()->setDebugDrawEnable(false);
118 label->setString("DebugDraw OFF");
119 }else{
120 getPhysics3DWorld()->setDebugDrawEnable(true);
121 label->setString("DebugDraw ON");
122 }
123 });
124
125 auto menu = Menu::create(menuItem, nullptr);
126 menu->setPosition(Vec2::ZERO);
127 menuItem->setAnchorPoint(Vec2::ANCHOR_TOP_LEFT);
128 menuItem->setPosition( Vec2(VisibleRect::left().x, VisibleRect::top().y-50) );
129 this->addChild(menu);
130
131 _angle = 0.0f;
132 return true;
133 }
134 physicsScene = nullptr;
135 return false;
136}
137
138void Physics3DTestDemo::onTouchesBegan(const std::vector<Touch*>& touches, cocos2d::Event *event)
139{
140 _needShootBox = true;
141 event->stopPropagation();
142}
143
144void Physics3DTestDemo::onTouchesMoved(const std::vector<Touch*>& touches, cocos2d::Event *event)
145{
146 if (touches.size() && _camera)
147 {
148 auto touch = touches[0];
149 auto delta = touch->getDelta();
150
151 _angle -= CC_DEGREES_TO_RADIANS(delta.x);
152 _camera->setPosition3D(Vec3(100.0f * sinf(_angle), 50.0f, 100.0f * cosf(_angle)));
153 _camera->lookAt(Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 1.0f, 0.0f));
154
155 if (delta.lengthSquared() > 16)
156 {
157 _needShootBox = false;
158 }
159 event->stopPropagation();
160 }
161}
162
163void Physics3DTestDemo::onTouchesEnded(const std::vector<Touch*>& touches, cocos2d::Event *event)
164{
165 if (!_needShootBox) return;
166 if (!touches.empty())
167 {
168 auto location = touches[0]->getLocationInView();
169
170 Vec3 nearP(location.x, location.y, -1.0f), farP(location.x, location.y, 1.0f);
171 nearP = _camera->unproject(nearP);
172 farP = _camera->unproject(farP);
173 Vec3 dir(farP - nearP);
174 shootBox(_camera->getPosition3D() + dir * 10.0f);
175 event->stopPropagation();
176 }
177}
178
179Physics3DTestDemo::Physics3DTestDemo()
180{
181
182}
183
184void Physics3DTestDemo::update( float /*delta*/ )
185{
186
187}
188
189Physics3DTestDemo::~Physics3DTestDemo()
190{
191
192}
193
194void Physics3DTestDemo::shootBox( const cocos2d::Vec3 &des )
195{
196 Physics3DRigidBodyDes rbDes;
197 Vec3 linearVel = des - _camera->getPosition3D();
198 linearVel.normalize();
199 linearVel *= 100.0f;
200 rbDes.originalTransform.translate(_camera->getPosition3D());
201 rbDes.mass = 1.f;
202 rbDes.shape = Physics3DShape::createBox(Vec3(0.5f, 0.5f, 0.5f));
203 auto sprite = PhysicsSprite3D::create("Sprite3DTest/box.c3t", &rbDes);
204 sprite->setTexture("Images/Icon.png");
205
206 auto rigidBody = static_cast<Physics3DRigidBody*>(sprite->getPhysicsObj());
207 rigidBody->setLinearFactor(Vec3::ONE);
208 rigidBody->setLinearVelocity(linearVel);
209 rigidBody->setAngularVelocity(Vec3::ZERO);
210 rigidBody->setCcdMotionThreshold(0.5f);
211 rigidBody->setCcdSweptSphereRadius(0.4f);
212
213 this->addChild(sprite);
214 sprite->setPosition3D(_camera->getPosition3D());
215 sprite->setScale(0.5f);
216 sprite->syncNodeToPhysics();
217
218 //optimize, only sync node to physics
219 sprite->setSyncFlag(Physics3DComponent::PhysicsSyncFlag::PHYSICS_TO_NODE); //sync node to physics
220
221 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
222}
223
224std::string BasicPhysics3DDemo::subtitle() const
225{
226 return "Basic Physics3D";
227}
228
229bool BasicPhysics3DDemo::init()
230{
231 if (!Physics3DTestDemo::init())
232 return false;
233
234 //create floor
235 Physics3DRigidBodyDes rbDes;
236 rbDes.mass = 0.0f;
237 rbDes.shape = Physics3DShape::createBox(Vec3(60.0f, 1.0f, 60.0f));
238
239 auto floor = PhysicsSprite3D::create("Sprite3DTest/box.c3t", &rbDes);
240 floor->setTexture("Sprite3DTest/plane.png");
241 floor->setScaleX(60);
242 floor->setScaleZ(60);
243 this->addChild(floor);
244 floor->setCameraMask((unsigned short)CameraFlag::USER1);
245 floor->syncNodeToPhysics();
246 //static object sync is not needed
247 floor->setSyncFlag(Physics3DComponent::PhysicsSyncFlag::NONE);
248
249 //create several boxes using PhysicsSprite3D
250 rbDes.mass = 1.f;
251 rbDes.shape = Physics3DShape::createBox(Vec3(0.8f, 0.8f, 0.8f));
252 float start_x = START_POS_X - ARRAY_SIZE_X/2;
253 float start_y = START_POS_Y;
254 float start_z = START_POS_Z - ARRAY_SIZE_Z/2;
255
256 for (int k=0;k<ARRAY_SIZE_Y;k++)
257 {
258 for (int i=0;i<ARRAY_SIZE_X;i++)
259 {
260 for(int j = 0;j<ARRAY_SIZE_Z;j++)
261 {
262 float x = 1.0*i + start_x;
263 float y = 5.0+1.0*k + start_y;
264 float z = 1.0*j + start_z;
265
266 auto sprite = PhysicsSprite3D::create("Sprite3DTest/box.c3t", &rbDes);
267 sprite->setTexture("Images/CyanSquare.png");
268 sprite->setPosition3D(Vec3(x, y, z));
269 sprite->syncNodeToPhysics();
270 sprite->setSyncFlag(Physics3DComponent::PhysicsSyncFlag::PHYSICS_TO_NODE);
271 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
272 sprite->setScale(0.8f);
273 this->addChild(sprite);
274 }
275 }
276 }
277
278 physicsScene->setPhysics3DDebugCamera(_camera);
279
280 return true;
281}
282
283std::string Physics3DConstraintDemo::subtitle() const
284{
285 return "Physics3D Constraint";
286}
287
288std::string Physics3DKinematicDemo::subtitle() const
289{
290 return "Physics3D Kinematic";
291}
292
293bool Physics3DKinematicDemo::init()
294{
295 if (!Physics3DTestDemo::init())
296 return false;
297
298 //create floor
299 Physics3DRigidBodyDes rbDes;
300 rbDes.mass = 0.0f;
301 rbDes.shape = Physics3DShape::createBox(Vec3(60.0f, 1.0f, 60.0f));
302 auto floor = PhysicsSprite3D::create("Sprite3DTest/box.c3t", &rbDes);
303 floor->setTexture("Sprite3DTest/plane.png");
304 floor->setScaleX(60);
305 floor->setScaleZ(60);
306 floor->setPosition3D(Vec3(0.f, -1.f, 0.f));
307 this->addChild(floor);
308 floor->setCameraMask((unsigned short)CameraFlag::USER1);
309 floor->syncNodeToPhysics();
310 //static object sync is not needed
311 floor->setSyncFlag(Physics3DComponent::PhysicsSyncFlag::NONE);
312
313 //create Kinematics
314 for (unsigned int i = 0; i < 3; ++i)
315 {
316 rbDes.mass = 0.f; //kinematic objects. zero mass so that it can not be affected by other dynamic objects
317 rbDes.shape = Physics3DShape::createBox(Vec3(2.0f, 2.0f, 2.0f));
318
319 auto sprite = PhysicsSprite3D::create("Sprite3DTest/box.c3t", &rbDes);
320 sprite->setTexture("Images/CyanSquare.png");
321 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
322 auto rigidBody = static_cast<Physics3DRigidBody*>(sprite->getPhysicsObj());
323 rigidBody->setKinematic(true);
324
325 this->addChild(sprite);
326
327 sprite->setScale(2.0f);
328 sprite->setPosition3D(Vec3(-15.0f, 0.0f, 15.0f - 15.0f * i));
329 auto moveby = MoveBy::create(2.0f + i, Vec3(30.0f, 0.0f, 0.0f));
330 sprite->runAction(RepeatForever::create(Sequence::create(moveby, moveby->reverse(), nullptr)));
331 }
332
333 //create Dynamic
334 {
335 //create several spheres
336 rbDes.mass = 1.f;
337 rbDes.shape = Physics3DShape::createSphere(0.5f);
338 float start_x = START_POS_X - ARRAY_SIZE_X/2;
339 float start_y = START_POS_Y + 5.0f;
340 float start_z = START_POS_Z - ARRAY_SIZE_Z/2;
341
342 for (int k=0;k<ARRAY_SIZE_Y;k++)
343 {
344 for (int i=0;i<ARRAY_SIZE_X;i++)
345 {
346 for(int j = 0;j<ARRAY_SIZE_Z;j++)
347 {
348 float x = 1.0*i + start_x;
349 float y = 5.0+1.0*k + start_y;
350 float z = 1.0*j + start_z;
351 rbDes.originalTransform.setIdentity();
352 rbDes.originalTransform.translate(x, y, z);
353
354 auto sprite = PhysicsSprite3D::create("Sprite3DTest/sphere.c3b", &rbDes);
355 sprite->setTexture("Sprite3DTest/plane.png");
356 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
357 sprite->setScale(1.0f / sprite->getContentSize().width);
358 this->addChild(sprite);
359 sprite->setPosition3D(Vec3(x, y, z));
360 sprite->syncNodeToPhysics();
361
362 sprite->setSyncFlag(Physics3DComponent::PhysicsSyncFlag::PHYSICS_TO_NODE);
363 }
364 }
365 }
366 }
367
368
369 physicsScene->setPhysics3DDebugCamera(_camera);
370 return true;
371}
372
373
374bool Physics3DConstraintDemo::init()
375{
376 if (!Physics3DTestDemo::init())
377 return false;
378
379 //PhysicsSprite3D = Sprite3D + Physics3DComponent
380 Physics3DRigidBodyDes rbDes;
381 rbDes.disableSleep = true;
382 //create box
383 auto sprite = Sprite3D::create("Sprite3DTest/orc.c3b");
384 rbDes.mass = 10.f;
385 rbDes.shape = Physics3DShape::createBox(Vec3(5.0f, 5.0f, 5.0f));
386 auto rigidBody = Physics3DRigidBody::create(&rbDes);
387 Quaternion quat;
388 Quaternion::createFromAxisAngle(Vec3(0.f, 1.f, 0.f), CC_DEGREES_TO_RADIANS(180), &quat);
389 auto component = Physics3DComponent::create(rigidBody, Vec3(0.f, -3.f, 0.f), quat);
390
391 sprite->addComponent(component);
392 addChild(sprite);
393 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
394 sprite->setScale(0.4f);
395 sprite->setPosition3D(Vec3(-20.f, 5.f, 0.f));
396 //sync node position to physics
397 component->syncNodeToPhysics();
398 //physics controlled, we will not set position for it, so we can skip sync node position to physics
399 component->setSyncFlag(Physics3DComponent::PhysicsSyncFlag::PHYSICS_TO_NODE);
400
401 physicsScene->setPhysics3DDebugCamera(_camera);
402
403 //create point to point constraint
404 Physics3DConstraint* constraint = Physics3DPointToPointConstraint::create(rigidBody, Vec3(2.5f, 2.5f, 2.5f));
405 physicsScene->getPhysics3DWorld()->addPhysics3DConstraint(constraint);
406
407 //create hinge constraint
408 rbDes.mass = 1.0f;
409 rbDes.shape = Physics3DShape::createBox(Vec3(8.0f, 8.0f, 1.f));
410 rigidBody = Physics3DRigidBody::create(&rbDes);
411 component = Physics3DComponent::create(rigidBody);
412 sprite = Sprite3D::create("Sprite3DTest/box.c3t");
413 sprite->setTexture("Sprite3DTest/plane.png");
414 sprite->setScaleX(8.f);
415 sprite->setScaleY(8.f);
416 sprite->setPosition3D(Vec3(5.f, 0.f, 0.f));
417 sprite->addComponent(component);
418 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
419 this->addChild(sprite);
420 component->syncNodeToPhysics();
421 rigidBody->setAngularVelocity(Vec3(0,3,0));
422 constraint = Physics3DHingeConstraint::create(rigidBody, Vec3(4.f, 4.f, 0.5f), Vec3(0.f, 1.f, 0.f));
423 physicsScene->getPhysics3DWorld()->addPhysics3DConstraint(constraint);
424
425
426 //create slider constraint
427 rbDes.mass = 1.0f;
428 rbDes.shape = Physics3DShape::createBox(Vec3(3.0f, 2.0f, 3.f));
429 rigidBody = Physics3DRigidBody::create(&rbDes);
430 component = Physics3DComponent::create(rigidBody);
431 sprite = Sprite3D::create("Sprite3DTest/box.c3t");
432 sprite->setTexture("Sprite3DTest/plane.png");
433 sprite->setScaleX(3.f);
434 sprite->setScaleZ(3.f);
435 sprite->setPosition3D(Vec3(30.f, 15.f, 0.f));
436 sprite->addComponent(component);
437 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
438 this->addChild(sprite);
439 component->syncNodeToPhysics();
440 rigidBody->setLinearVelocity(Vec3(0,3,0));
441
442 rbDes.mass = 0.0f;
443 rbDes.shape = Physics3DShape::createBox(Vec3(3.0f, 3.0f, 3.f));
444 auto rigidBodyB = Physics3DRigidBody::create(&rbDes);
445 component = Physics3DComponent::create(rigidBodyB);
446 sprite = Sprite3D::create("Sprite3DTest/box.c3t");
447 sprite->setTexture("Sprite3DTest/plane.png");
448 sprite->setScale(3.f);
449 sprite->setPosition3D(Vec3(30.f, 5.f, 0.f));
450 sprite->addComponent(component);
451 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
452 this->addChild(sprite);
453 component->syncNodeToPhysics();
454
455 Mat4 frameInA, frameInB;
456 Mat4::createRotationZ(CC_DEGREES_TO_RADIANS(90), &frameInA);
457 frameInB = frameInA;
458 frameInA.m[13] = -5.f;
459 frameInB.m[13] = 5.f;
460 constraint = Physics3DSliderConstraint::create(rigidBody, rigidBodyB, frameInA, frameInB, false);
461 physicsScene->getPhysics3DWorld()->addPhysics3DConstraint(constraint);
462 ((Physics3DSliderConstraint*)constraint)->setLowerLinLimit(-5.f);
463 ((Physics3DSliderConstraint*)constraint)->setUpperLinLimit(5.f);
464
465 //create ConeTwist constraint
466 rbDes.mass = 1.f;
467 rbDes.shape = Physics3DShape::createBox(Vec3(3.f, 3.f, 3.f));
468 rigidBody = Physics3DRigidBody::create(&rbDes);
469 component = Physics3DComponent::create(rigidBody);
470 sprite = Sprite3D::create("Sprite3DTest/box.c3t");
471 sprite->setTexture("Sprite3DTest/plane.png");
472 sprite->setScale(3.f);
473 sprite->setPosition3D(Vec3(-10.f, 5.f, 0.f));
474 sprite->addComponent(component);
475 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
476 this->addChild(sprite);
477 component->syncNodeToPhysics();
478
479 Mat4::createRotationZ(CC_DEGREES_TO_RADIANS(90), &frameInA);
480 frameInA.m[12] = 0.f;
481 frameInA.m[13] = -10.f;
482 frameInA.m[14] = 0.f;
483 constraint = Physics3DConeTwistConstraint::create(rigidBody, frameInA);
484 physicsScene->getPhysics3DWorld()->addPhysics3DConstraint(constraint, true);
485 ((Physics3DConeTwistConstraint*)constraint)->setLimit(CC_DEGREES_TO_RADIANS(10), CC_DEGREES_TO_RADIANS(10), CC_DEGREES_TO_RADIANS(40));
486
487 //create 6 dof constraint
488 rbDes.mass = 1.0f;
489 rbDes.shape = Physics3DShape::createBox(Vec3(3.0f, 3.0f, 3.f));
490 rigidBody = Physics3DRigidBody::create(&rbDes);
491 component = Physics3DComponent::create(rigidBody);
492 sprite = Sprite3D::create("Sprite3DTest/box.c3t");
493 sprite->setTexture("Sprite3DTest/plane.png");
494 sprite->setScale(3.f);
495 sprite->setPosition3D(Vec3(30.f, -5.f, 0.f));
496 sprite->addComponent(component);
497 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
498 this->addChild(sprite);
499 component->syncNodeToPhysics();
500 frameInA.setIdentity();
501 constraint = Physics3D6DofConstraint::create(rigidBody, frameInA, false);
502 physicsScene->getPhysics3DWorld()->addPhysics3DConstraint(constraint);
503 ((Physics3D6DofConstraint*)constraint)->setAngularLowerLimit(Vec3(0,0,0));
504 ((Physics3D6DofConstraint*)constraint)->setAngularUpperLimit(Vec3(0,0,0));
505 ((Physics3D6DofConstraint*)constraint)->setLinearLowerLimit(Vec3(-10,0,0));
506 ((Physics3D6DofConstraint*)constraint)->setLinearUpperLimit(Vec3(10,0,0));
507
508 return true;
509}
510
511void Physics3DConstraintDemo::onTouchesBegan(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event *event)
512{
513 //ray trace
514 if(_camera)
515 {
516 auto touch = touches[0];
517 auto location = touch->getLocationInView();
518 Vec3 nearP(location.x, location.y, 0.0f), farP(location.x, location.y, 1.0f);
519
520 auto size = Director::getInstance()->getWinSize();
521 _camera->unproject(size, &nearP, &nearP);
522 _camera->unproject(size, &farP, &farP);
523
524 Physics3DWorld::HitResult result;
525 bool ret = physicsScene->getPhysics3DWorld()->rayCast(nearP, farP, &result);
526 if (ret && result.hitObj->getObjType() == Physics3DObject::PhysicsObjType::RIGID_BODY)
527 {
528 auto mat = result.hitObj->getWorldTransform().getInversed();
529 Vec3 position;
530 mat.transformPoint(result.hitPosition, &position);
531
532 _constraint = Physics3DPointToPointConstraint::create(static_cast<Physics3DRigidBody*>(result.hitObj), position);
533 physicsScene->getPhysics3DWorld()->addPhysics3DConstraint(_constraint, true);
534 _pickingDistance = (result.hitPosition - nearP).length();
535 event->stopPropagation();
536 return;
537 }
538 }
539 Physics3DTestDemo::onTouchesBegan(touches, event);
540 _needShootBox = false;
541}
542void Physics3DConstraintDemo::onTouchesMoved(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event *event)
543{
544 if (_constraint)
545 {
546 auto p2pConstraint = ((Physics3DPointToPointConstraint*)_constraint);
547
548 auto touch = touches[0];
549 auto location = touch->getLocationInView();
550 Vec3 nearP(location.x, location.y, 0.0f), farP(location.x, location.y, 1.0f);
551
552 auto size = Director::getInstance()->getWinSize();
553 _camera->unproject(size, &nearP, &nearP);
554 _camera->unproject(size, &farP, &farP);
555 auto dir = (farP - nearP).getNormalized();
556 p2pConstraint->setPivotPointInB(nearP + dir * _pickingDistance);
557 event->stopPropagation();
558 return;
559 }
560 Physics3DTestDemo::onTouchesMoved(touches, event);
561}
562void Physics3DConstraintDemo::onTouchesEnded(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event *event)
563{
564 if (_constraint)
565 {
566 physicsScene->getPhysics3DWorld()->removePhysics3DConstraint(_constraint);
567 _constraint = nullptr;
568 event->stopPropagation();
569 return;
570 }
571 Physics3DTestDemo::onTouchesEnded(touches, event);
572}
573
574bool Physics3DTerrainDemo::init()
575{
576 if (!Physics3DTestDemo::init())
577 return false;
578
579 Terrain::DetailMap r("TerrainTest/dirt.jpg"),g("TerrainTest/Grass2.jpg",10),b("TerrainTest/road.jpg"),a("TerrainTest/GreenSkin.jpg",20);
580
581 Terrain::TerrainData data("TerrainTest/heightmap129.jpg","TerrainTest/alphamap.png",r,g,b,a,Size(32,32), 20.0f, 1.0f);
582 auto terrain = Terrain::create(data,Terrain::CrackFixedType::SKIRT);
583 terrain->setMaxDetailMapAmount(4);
584 terrain->setCameraMask(2);
585 terrain->setDrawWire(false);
586
587 terrain->setSkirtHeightRatio(3);
588 terrain->setLODDistance(64,128,192);
589 terrain->setCameraMask((unsigned short)CameraFlag::USER1);
590
591 //create terrain
592 std::vector<float> heidata = terrain->getHeightData();
593 auto size = terrain->getTerrainSize();
594 Physics3DColliderDes colliderDes;
595 colliderDes.shape = Physics3DShape::createHeightfield(size.width, size.height, &heidata[0], 1.0f, terrain->getMinHeight(), terrain->getMaxHeight(), true, false, true);
596 auto collider = Physics3DCollider::create(&colliderDes);
597 auto component = Physics3DComponent::create(collider);
598 terrain->addComponent(component);
599 this->addChild(terrain);
600 component->syncNodeToPhysics();
601 component->setSyncFlag(Physics3DComponent::PhysicsSyncFlag::NONE);
602
603
604 //create several spheres
605 Physics3DRigidBodyDes rbDes;
606 rbDes.mass = 1.f;
607 rbDes.shape = Physics3DShape::createSphere(0.5f);
608 float start_x = START_POS_X - ARRAY_SIZE_X/2 + 5.0f;
609 float start_y = START_POS_Y + 20.0f;
610 float start_z = START_POS_Z - ARRAY_SIZE_Z/2;
611
612 for (int k=0;k<ARRAY_SIZE_Y;k++)
613 {
614 for (int i=0;i<ARRAY_SIZE_X;i++)
615 {
616 for(int j = 0;j<ARRAY_SIZE_Z;j++)
617 {
618 float x = 1.0*i + start_x;
619 float y = 5.0+1.0*k + start_y;
620 float z = 1.0*j + start_z;
621
622 auto sprite = PhysicsSprite3D::create("Sprite3DTest/sphere.c3b", &rbDes);
623 sprite->setTexture("Sprite3DTest/plane.png");
624 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
625 sprite->setScale(1.0f / sprite->getContentSize().width);
626 sprite->setPosition3D(Vec3(x, y, z));
627 this->addChild(sprite);
628 sprite->syncNodeToPhysics();
629 sprite->setSyncFlag(Physics3DComponent::PhysicsSyncFlag::PHYSICS_TO_NODE);
630 }
631 }
632 }
633
634 //create mesh
635 std::vector<Vec3> trianglesList = Bundle3D::getTrianglesList("Sprite3DTest/boss.c3b");
636
637 colliderDes.shape = Physics3DShape::createMesh(&trianglesList[0], (int)trianglesList.size() / 3);
638
639 auto sprite = PhysicsSprite3D::createWithCollider("Sprite3DTest/boss.c3b", &colliderDes);
640 sprite->setRotation3D(Vec3(-90.0f, 0.0f, 0.0f));
641 sprite->setPosition3D(Vec3(0.0f, 15.0f, 0.0f));
642 sprite->setCameraMask(2);
643 this->addChild(sprite);
644 sprite->syncNodeToPhysics();
645 sprite->setSyncFlag(Physics3DComponent::PhysicsSyncFlag::NONE);
646
647 std::vector<std::pair<Physics3DShape*, Mat4> > shapeList;
648 {
649 Mat4 localTrans;
650 auto bodyshape = Physics3DShape::createBox(Vec3(2.0f, 4.0f, 2.0f));
651 Mat4::createTranslation(0.0f, 2.0f, 0.0f, &localTrans);
652 shapeList.push_back(std::make_pair(bodyshape, localTrans));
653 auto headshape = Physics3DShape::createSphere(1.5f);
654 Mat4::createTranslation(0.6f, 5.0f, -1.5f, &localTrans);
655 shapeList.push_back(std::make_pair(headshape, localTrans));
656 auto lhandshape = Physics3DShape::createBox(Vec3(1.0f, 3.0f, 1.0f));
657 Mat4::createRotation(Vec3(1.0f, 0.0f, 0.0f), CC_DEGREES_TO_RADIANS(15.0f), &localTrans);
658 localTrans.m[12] = -1.5f; localTrans.m[13] = 2.5f; localTrans.m[14] = -2.5f;
659 shapeList.push_back(std::make_pair(lhandshape, localTrans));
660 auto rhandshape = Physics3DShape::createBox(Vec3(1.0f, 3.0f, 1.0f));
661 Mat4::createRotation(Vec3(1.0f, 0.0f, 0.0f), CC_DEGREES_TO_RADIANS(-15.0f), &localTrans);
662 localTrans.m[12] = 2.0f; localTrans.m[13] = 2.5f; localTrans.m[14] = 1.f;
663 shapeList.push_back(std::make_pair(rhandshape, localTrans));
664
665 rbDes.mass = 10.0f;
666 rbDes.shape = Physics3DShape::createCompoundShape(shapeList);
667 auto rigidBody = Physics3DRigidBody::create(&rbDes);
668 component = Physics3DComponent::create(rigidBody);
669 auto sprite = Sprite3D::create("Sprite3DTest/orc.c3b");
670 sprite->addComponent(component);
671 sprite->setRotation3D(Vec3(0.0f, 180.0f, 0.0f));
672 sprite->setPosition3D(Vec3(-5.0f, 20.0f, 0.0f));
673 sprite->setScale(0.4f);
674 sprite->setCameraMask(2);
675 this->addChild(sprite);
676 }
677
678
679 physicsScene->setPhysics3DDebugCamera(_camera);
680 return true;
681}
682
683std::string Physics3DTerrainDemo::subtitle() const
684{
685 return "Physics3D Terrain";
686}
687
688std::string Physics3DCollisionCallbackDemo::subtitle() const
689{
690 return "Physics3D CollisionCallback";
691}
692
693bool Physics3DCollisionCallbackDemo::init()
694{
695 if (!Physics3DTestDemo::init())
696 return false;
697
698 {
699 Physics3DRigidBodyDes rbDes;
700
701 float scale = 2.0f;
702 std::vector<Vec3> trianglesList = Bundle3D::getTrianglesList("Sprite3DTest/boss.c3b");
703 for (auto& it : trianglesList) {
704 it *= scale;
705 }
706
707 rbDes.mass = 0.0f;
708 rbDes.shape = Physics3DShape::createMesh(&trianglesList[0], (int)trianglesList.size() / 3);
709 auto rigidBody = Physics3DRigidBody::create(&rbDes);
710 auto component = Physics3DComponent::create(rigidBody);
711 auto sprite = Sprite3D::create("Sprite3DTest/boss.c3b");
712 sprite->addComponent(component);
713 sprite->setRotation3D(Vec3(-90.0f, 0.0f, 0.0f));
714 sprite->setScale(scale);
715 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
716 this->addChild(sprite);
717 //preload
718 //
719 rigidBody->setCollisionCallback([=](const Physics3DCollisionInfo &ci){
720 if (!ci.collisionPointList.empty()){
721 if (ci.objA->getMask() != 0){
722 auto ps = PUParticleSystem3D::create("Particle3D/scripts/mp_hit_04.pu");
723 ps->setPosition3D(ci.collisionPointList[0].worldPositionOnB);
724 ps->setScale(0.05f);
725 ps->startParticleSystem();
726 ps->setCameraMask(2);
727 this->addChild(ps);
728 ps->runAction(Sequence::create(DelayTime::create(1.0f), CallFunc::create([=](){
729 ps->removeFromParent();
730 }), nullptr));
731 ci.objA->setMask(0);
732 }
733 }
734 //CCLOG("------------BoxB Collision Info------------");
735 //CCLOG("Collision Point Num: %d", ci.collisionPointList.size());
736 //for (auto &iter : ci.collisionPointList){
737 // CCLOG("Collision Position On A: (%.2f, %.2f, %.2f)", iter.worldPositionOnA.x, iter.worldPositionOnA.y, iter.worldPositionOnA.z);
738 // CCLOG("Collision Position On B: (%.2f, %.2f, %.2f)", iter.worldPositionOnB.x, iter.worldPositionOnB.y, iter.worldPositionOnB.z);
739 // CCLOG("Collision Normal On B: (%.2f, %.2f, %.2f)", iter.worldNormalOnB.x, iter.worldNormalOnB.y, iter.worldNormalOnB.z);
740 //}
741 //CCLOG("------------BoxB Collision Info------------");
742 });
743 }
744
745 physicsScene->setPhysics3DDebugCamera(_camera);
746 return true;
747}
748
749std::string Physics3DColliderDemo::subtitle() const
750{
751 return "Physics3D Trigger";
752}
753
754bool Physics3DColliderDemo::init()
755{
756 if (!Physics3DTestDemo::init())
757 return false;
758
759 Physics3DRigidBodyDes rbDes;
760 rbDes.mass = 1.0f;
761 rbDes.shape = Physics3DShape::createBox(Vec3(3.0f, 3.0f, 3.f));
762 auto playerBody = Physics3DRigidBody::create(&rbDes);
763 auto component = Physics3DComponent::create(playerBody);
764 playerBody->setKinematic(true);
765 auto sprite = Sprite3D::create("Sprite3DTest/box.c3t");
766 sprite->setTexture("Sprite3DTest/plane.png");
767 sprite->setScale(3.f);
768 sprite->setPosition3D(Vec3(0.0f, 0.f, 30.f));
769 sprite->addComponent(component);
770 sprite->setCameraMask((unsigned short)CameraFlag::USER1);
771 auto moveby = MoveBy::create(5.0f, Vec3(0.0f, 0.0f, -60.0f));
772 sprite->runAction(RepeatForever::create(Sequence::create(moveby, moveby->reverse(), nullptr)));
773 this->addChild(sprite);
774
775 {
776 Physics3DColliderDes colliderDes;
777 colliderDes.shape = Physics3DShape::createSphere(10.0f);
778 colliderDes.isTrigger = true;
779 auto collider = Physics3DCollider::create(&colliderDes);
780 auto component = Physics3DComponent::create(collider);
781 auto node = Node::create();
782 node->addComponent(component);
783 node->setCameraMask((unsigned short)CameraFlag::USER1);
784 this->addChild(node);
785
786 Physics3DRigidBodyDes rbDes;
787 rbDes.mass = 1.0f;
788 rbDes.shape = Physics3DShape::createBox(Vec3(10.0f, 10.0f, 1.f));
789 auto rigidBody = Physics3DRigidBody::create(&rbDes);
790 component = Physics3DComponent::create(rigidBody);
791 rigidBody->setKinematic(true);
792 auto doorLeft = Sprite3D::create("Sprite3DTest/box.c3t");
793 doorLeft->setTexture("Sprite3DTest/plane.png");
794 doorLeft->setScaleX(10.0f);
795 doorLeft->setScaleY(10.0f);
796 doorLeft->setScaleZ(1.0f);
797 doorLeft->setPosition3D(Vec3(-5.0f, 0.0f, 0.0f));
798 doorLeft->addComponent(component);
799 doorLeft->setCameraMask((unsigned short)CameraFlag::USER1);
800 node->addChild(doorLeft);
801
802 rbDes.mass = 1.0f;
803 rbDes.shape = Physics3DShape::createBox(Vec3(10.0f, 10.0f, 1.f));
804 rigidBody = Physics3DRigidBody::create(&rbDes);
805 component = Physics3DComponent::create(rigidBody);
806 rigidBody->setKinematic(true);
807 auto doorRight = Sprite3D::create("Sprite3DTest/box.c3t");
808 doorRight->setTexture("Sprite3DTest/plane.png");
809 doorRight->setScaleX(10.0f);
810 doorRight->setScaleY(10.0f);
811 doorRight->setScaleZ(1.0f);
812 doorRight->setPosition3D(Vec3(5.0f, 0.0f, 0.0f));
813 doorRight->addComponent(component);
814 doorRight->setCameraMask((unsigned short)CameraFlag::USER1);
815 node->addChild(doorRight);
816
817
818 collider->onTriggerEnter = [=](Physics3DObject *otherObject){
819 if (otherObject == playerBody){
820 auto moveby = MoveBy::create(1.0f, Vec3(-5.0f, 0.0f, 0.0f));
821 doorLeft->runAction(moveby);
822 doorRight->runAction(moveby->reverse());
823 }
824 };
825
826 collider->onTriggerExit = [=](Physics3DObject *otherObject){
827 if (otherObject == playerBody){
828 auto moveby = MoveBy::create(1.0f, Vec3(5.0f, 0.0f, 0.0f));
829 doorLeft->runAction(moveby);
830 doorRight->runAction(moveby->reverse());
831 }
832 };
833 }
834
835 physicsScene->setPhysics3DDebugCamera(_camera);
836 return true;
837}
838
839#endif
#define ADD_TEST_CASE(__className__)
Definition: BaseTest.h:211
#define ARRAY_SIZE_X
#define START_POS_Z
#define ARRAY_SIZE_Z
#define ARRAY_SIZE_Y
USING_NS_CC_EXT
#define START_POS_Y
static cocos2d::Scene * physicsScene
USING_NS_CC
#define START_POS_X
@ IDC_RESTART
@ IDC_NEXT
@ IDC_BACK
virtual void onEnter() override
virtual void onEnter() override
Definition: BaseTest.cpp:430
static cocos2d::Vec2 top()
Definition: VisibleRect.cpp:57
static cocos2d::Vec2 left()
Definition: VisibleRect.cpp:45