Changeset 1764


Ignore:
Timestamp:
Aug 16, 2012, 7:14:07 PM (8 years ago)
Author:
touky
Message:

Added Base/Attachment Logic, works with Kinematic & Ghost.

Location:
trunk/test
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/BtPhysTest.cpp

    r1749 r1764  
    110110        if (USE_PLATFORM)
    111111        {
    112                 quat NewRotation = quat::fromeuler_xyz(5.f, 0.f, 0.f);
     112                quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
    113113                vec3 NewPosition = pos_offset + vec3(5.0f, -25.0f, -15.0f);
    114114
     
    121121
    122122                NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
     123                PhysicsObject* BasePhyobj = NewPhyobj;
    123124
    124125                m_platform_list << NewPhyobj;
    125126                Ticker::Ref(NewPhyobj);
     127
     128                NewRotation = quat::fromeuler_xyz(0.f, 0.f, 90.f);
     129                NewPosition = pos_offset + vec3(-25.0f, -25.0f, 5.0f);
     130
     131                NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
     132
     133                NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, true);
     134                m_platform_list << NewPhyobj;
     135                Ticker::Ref(NewPhyobj);
     136
     137                NewPosition += vec3(-0.0f, .0f, .0f);
     138                NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
     139
     140                NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, false);
     141                m_platform_list << NewPhyobj;
     142                Ticker::Ref(NewPhyobj);
     143
     144                NewPosition += vec3(-2.0f, .0f, .0f);
     145                NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
     146
     147                NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), false, false);
     148                m_platform_list << NewPhyobj;
     149                Ticker::Ref(NewPhyobj);
    126150        }
    127151
     
    129153        {
    130154                quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
    131                 vec3 NewPosition = pos_offset + vec3(.0f, 20.0f, .0f);
     155                vec3 NewPosition = pos_offset + vec3(-15.0f, 20.0f, .0f);
    132156
    133157                PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2);
     
    181205                }
    182206        }
    183 
    184 #if 0
    185         //init Physics
    186         {
    187                 m_bt_ccd_mode = USE_CCD;
    188 
    189                 //collision configuration contains default setup for memory, collision setup
    190                 m_bt_collision_config = new btDefaultCollisionConfiguration();
    191 
    192                 //use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
    193                 m_bt_dispatcher = new btCollisionDispatcher(m_bt_collision_config);
    194                 m_bt_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,
    195                                                                                                         BOX_SHAPE_PROXYTYPE,
    196                                                                                                         m_bt_collision_config->getCollisionAlgorithmCreateFunc(CONVEX_SHAPE_PROXYTYPE,
    197                                                                                                                                                                                                                         CONVEX_SHAPE_PROXYTYPE));
    198 
    199                 m_bt_broadphase = new btDbvtBroadphase();
    200 
    201                 ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
    202                 m_bt_solver = new btSequentialImpulseConstraintSolver;
    203 
    204                 m_bt_world = new btDiscreteDynamicsWorld(m_bt_dispatcher, m_bt_broadphase, m_bt_solver, m_bt_collision_config);
    205                 //m_bt_world->setDebugDrawer(&sDebugDrawer);
    206                 m_bt_world->getSolverInfo().m_splitImpulse = true;
    207                 m_bt_world->getSolverInfo().m_numIterations = 20;
    208 
    209                 m_bt_world->getDispatchInfo().m_useContinuous = (m_bt_ccd_mode == USE_CCD);
    210                 m_bt_world->setGravity(btVector3(0,-10,0));
    211 
    212                 ///create a few basic rigid bodies
    213                 btBoxShape* box = new btBoxShape(btVector3(btScalar(110.),btScalar(1.),btScalar(110.)));
    214                 btCollisionShape* groundShape = box;
    215                 m_bt_collision_shapes << groundShape;
    216         m_ground_mesh.Compile("[sc#ddd afcb220 2 220 -1]");
    217 
    218                 //m_bt_collision_shapes << new btCylinderShape(btVector3(.5f,.5f,.5f));
    219 
    220                 btTransform groundTransform;
    221                 groundTransform.setIdentity();
    222 
    223                 //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
    224                 {
    225                         btScalar mass(0.);
    226 
    227                         //rigidbody is dynamic if and only if mass is non zero, otherwise static
    228                         bool isDynamic = (mass != 0.f);
    229 
    230                         btVector3 localInertia(0,0,0);
    231                         if (isDynamic)
    232                                 groundShape->calculateLocalInertia(mass,localInertia);
    233 
    234                         //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
    235                         btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
    236                         btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
    237                         btRigidBody* body = new btRigidBody(rbInfo);
    238 
    239                         //add the body to the dynamics world
    240                         m_bt_world->addRigidBody(body);
    241                 }
    242 
    243                 //Adding Shapes
    244                 {
    245                         //create a few dynamic rigidbodies
    246                         // Re-using the same collision is better for memory usage and performance
    247                         btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1));
    248                         m_rigid_mesh[0].Compile("[sc#add afcb2 2 2 -.1]");
    249                         m_rigid_mesh[1].Compile("[sc#dad afcb2 2 2 -.1]");
    250                         m_rigid_mesh[2].Compile("[sc#dda afcb2 2 2 -.1]");
    251                         m_rigid_mesh[3].Compile("[sc#daa afcb2 2 2 -.1]");
    252                         m_rigid_mesh[4].Compile("[sc#ada afcb2 2 2 -.1]");
    253                         m_rigid_mesh[5].Compile("[sc#aad afcb2 2 2 -.1]");
    254 
    255                         m_bt_collision_shapes << colShape;
    256                         m_bt_dynamic_shapes << colShape;
    257 
    258                         /// Create Dynamic Objects
    259                         btTransform startTransform;
    260                         startTransform.setIdentity();
    261                         btScalar mass(1.f);
    262 
    263                         //rigidbody is dynamic if and only if mass is non zero, otherwise static
    264                         bool isDynamic = (mass != 0.f);
    265 
    266                         btVector3 localInertia(0,0,0);
    267                         if (isDynamic)
    268                                 colShape->calculateLocalInertia(mass,localInertia);
    269 
    270                         int i;
    271                         for (i=0;i<gNumObjects;i++)
    272                         {
    273                                 btCollisionShape* shape = colShape;
    274                                 btTransform trans;
    275                                 trans.setIdentity();
    276 
    277                                 //stack them
    278                                 int colsize = 10;
    279                                 int row = int(((float)i*CUBE_HALF_EXTENTS*2.0f)/((float)colsize*2.0f*CUBE_HALF_EXTENTS));
    280                                 int row2 = row;
    281                                 int col = (i)%(colsize)-colsize/2;
    282 
    283                                 if (col>3)
    284                                 {
    285                                         col=11;
    286                                         row2 |=1;
    287                                 }
    288 
    289                                 btVector3 pos(((row+col+row2) % 4)*CUBE_HALF_EXTENTS,
    290                                               20.0f + row*8*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT,
    291                                               col*8*CUBE_HALF_EXTENTS + 2 * (row2%2)*CUBE_HALF_EXTENTS);
    292 
    293                                 trans.setOrigin(pos);
    294        
    295                                 float mass = 1.f;
    296 
    297 
    298                                 btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
    299 
    300                                 //rigidbody is dynamic if and only if mass is non zero, otherwise static
    301                                 bool isDynamic = (mass != 0.f);
    302 
    303                                 btVector3 localInertia(0,0,0);
    304                                 if (isDynamic)
    305                                         shape->calculateLocalInertia(mass,localInertia);
    306 
    307                                 //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
    308 
    309                                 btDefaultMotionState* myMotionState = new btDefaultMotionState(trans);
    310 
    311                                 btRigidBody::btRigidBodyConstructionInfo cInfo(mass,myMotionState,shape,localInertia);
    312 
    313                                 btRigidBody* body = new btRigidBody(cInfo);
    314                                 body->setContactProcessingThreshold(BT_LARGE_FLOAT);
    315 
    316                                 m_bt_world->addRigidBody(body);
    317 
    318                                 ///when using m_ccdMode
    319                                 if (m_bt_ccd_mode == USE_CCD)
    320                                 {
    321                                         body->setCcdMotionThreshold(CUBE_HALF_EXTENTS);
    322                                         body->setCcdSweptSphereRadius(0.9*CUBE_HALF_EXTENTS);
    323                                 }
    324                         }
    325                 }
    326         }
    327 #endif
    328207}
    329208
     
    334213    if (Input::GetButtonState(27 /*SDLK_ESCAPE*/))
    335214        Ticker::Shutdown();
     215
     216        m_loop_value += seconds;
     217        if (m_loop_value > M_PI * 2.0f)
     218                m_loop_value -= M_PI * 2.0f;
    336219
    337220        vec3 GroundBarycenter = vec3(.0f);
     
    396279                                PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
    397280                        }
    398                         else
     281                        else if (i == 1)
    399282                        {
    400                                 GroundMat = GroundMat * mat4::translate(vec3(.0f, .0f, 10.0f) * seconds);
    401                                 if (GroundMat.v3.z > 40.0f)
    402                                         GroundMat = GroundMat * mat4::translate(vec3(.0f, .0f, -80.0f));
     283                                GroundMat = mat4::translate(vec3(-15.0f, 5.0f, lol::cos(m_loop_value) * 8.f)) *
     284                                                        mat4(quat::fromeuler_xyz(vec3(.0f, lol::cos(m_loop_value) * 20.f, .0f)));
    403285                                PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
    404286                        }
     
    459341        }
    460342
    461 #if 0
    462         ///step the simulation
    463         if (m_bt_world)
    464         {
    465                 //int steps = (int)(seconds / 0.005f);
    466                 //for (int i = 0; i < steps; i++)
    467                         m_bt_world->stepSimulation(seconds /*/ steps*/);
    468                 //optional but useful: debug drawing
    469                 //m_bt_world->debugDrawWorld();
    470         }
    471 #endif
    472343}
    473344
     
    478349    if (!m_ready)
    479350    {
    480 #if 0
    481                 m_ground_mesh.MeshConvert();
    482                 m_rigid_mesh[0].MeshConvert();
    483                 m_rigid_mesh[1].MeshConvert();
    484                 m_rigid_mesh[2].MeshConvert();
    485                 m_rigid_mesh[3].MeshConvert();
    486                 m_rigid_mesh[4].MeshConvert();
    487                 m_rigid_mesh[5].MeshConvert();
    488 #endif
    489351        /* FIXME: this object never cleans up */
    490352        m_ready = true;
     
    493355    //Video::SetClearColor(vec4(0.0f, 0.0f, 0.12f, 1.0f));
    494356
    495 #if 0
    496         vec3 BarycenterLocation = vec3(.0f);
    497         float BarycenterFactor = 0.0f;
    498         for(int i=0;i<gNumObjects;i++)
    499         {
    500                 mat4 m(1.0f);
    501                 btMatrix3x3     rot; rot.setIdentity();
    502                 btCollisionObject*      colObj = m_bt_world->getCollisionObjectArray()[i];
    503                 btRigidBody*            body = btRigidBody::upcast(colObj);
    504                 if(body && body->getMotionState())
    505                 {
    506                         btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState();
    507                         myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(&m[0][0]);
    508                         rot = myMotionState->m_graphicsWorldTrans.getBasis();
    509                 }
    510                 else
    511                 {
    512                         colObj->getWorldTransform().getOpenGLMatrix(&m[0][0]);
    513                         rot = colObj->getWorldTransform().getBasis();
    514                 }
    515                 if (i > 0)
    516                 {
    517                         BarycenterLocation += m.v3.xyz;
    518                         BarycenterFactor += 1.0f;
    519                 }
    520                 if (i == 0)
    521                         m_ground_mesh.Render(m);
    522                 else
    523                         m_rigid_mesh[i % 6].Render(m);
    524         }
    525         if (BarycenterFactor > .0f)
    526         {
    527                 BarycenterLocation /= BarycenterFactor;
    528 
    529                 m_camera->SetTarget(BarycenterLocation);
    530                 m_camera->SetPosition(BarycenterLocation + vec3(-20.0f, 8.0f, .0f));
    531         }
    532 #endif
    533357}
    534358
     
    574398    Ticker::Unref(m_simulation);
    575399
    576 #if 0
    577         //Exit Physics
    578         {
    579                 //cleanup in the reverse order of creation/initialization
    580                 //remove the rigidbodies from the dynamics world and delete them
    581                 for (int i = m_bt_world->getNumCollisionObjects() - 1; i >= 0 ;i--)
    582                 {
    583                         btCollisionObject* obj = m_bt_world->getCollisionObjectArray()[i];
    584                         btRigidBody* body = btRigidBody::upcast(obj);
    585                         if (body && body->getMotionState())
    586                                 delete body->getMotionState();
    587 
    588                         m_bt_world->removeCollisionObject(obj);
    589                         delete obj;
    590                 }
    591 
    592                 //delete collision shapes
    593                 for (int j = 0; j < m_bt_collision_shapes.Count(); j++)
    594                 {
    595                         btCollisionShape* shape = m_bt_collision_shapes[j];
    596                         delete shape;
    597                 }
    598                 m_bt_collision_shapes.Empty();
    599 
    600                 delete m_bt_world;
    601                 delete m_bt_solver;
    602                 delete m_bt_broadphase;
    603                 delete m_bt_dispatcher;
    604                 delete m_bt_collision_config;
    605         }
    606 #endif
    607400}
    608401
  • trunk/test/BtPhysTest.h

    r1722 r1764  
    3232        Array<PhysicsObject*>                           m_character_list;
    3333
    34 #if 0
    35         EasyMesh                                                        m_ground_mesh;
    36         EasyMesh                                                        m_rigid_mesh[6];
    37 
    38         //Bullet Physics Datas
    39         enum
    40         {
    41                 USE_CCD=1,
    42                 USE_NO_CCD
    43         };
    44         int                                                                     m_bt_ccd_mode;
    45         btDefaultCollisionConfiguration*                m_bt_collision_config;
    46         btCollisionDispatcher*                                  m_bt_dispatcher;
    47         btDbvtBroadphase*                                               m_bt_broadphase;
    48         btSequentialImpulseConstraintSolver*    m_bt_solver;
    49         btDiscreteDynamicsWorld*                                m_bt_world;
    50         Array<btCollisionShape*>                                m_bt_collision_shapes;
    51         Array<btCollisionShape*>                                m_bt_dynamic_shapes;
    52 #endif
     34        float                                                           m_loop_value;
    5335};
    5436
  • trunk/test/PhysicObject.h

    r1747 r1764  
    2727                : m_ready(false), m_should_render(true), m_is_character(false)
    2828        {
     29                m_physics = new EasyPhysic(this);
     30
    2931                m_mesh.Compile("[sc#ddd afcb60 1 60 -.1]");
    3032                vec3 BoxSize = vec3(60.f, 1.f, 60.f);
    31                 m_physics.SetCollisionChannel(0, 0xFF);
    32                 m_physics.SetShapeToBox(BoxSize);
    33                 m_physics.SetMass(.0f);
    34                 m_physics.SetTransform(base_location, base_rotation);
    35                 m_physics.InitBodyToRigid(true);
    36                 m_physics.AddToSimulation(new_sim);
     33                m_physics->SetCollisionChannel(0, 0xFF);
     34                m_physics->SetShapeToBox(BoxSize);
     35                m_physics->SetMass(.0f);
     36                m_physics->SetTransform(base_location, base_rotation);
     37                m_physics->InitBodyToRigid(true);
     38                m_physics->AddToSimulation(new_sim);
    3739        }
    3840
     
    4042                : m_ready(false), m_should_render(true), m_is_character(false)
    4143        {
    42                 if (dummy == 1) //for Rope purpose
    43                 {
     44                if (dummy == 1) //for platform purpose
     45                {
     46                        m_physics = new EasyPhysic(this);
     47
    4448                        m_mesh.Compile("[sc#ddd afcb20 1 20 -.1]");
    4549                        vec3 BoxSize = vec3(20.f, 1.f, 20.f);
    46                         m_physics.SetCollisionChannel(0, 0xFF);
    47                         m_physics.SetShapeToBox(BoxSize);
    48                         m_physics.SetMass(.0f);
    49                         m_physics.SetTransform(base_location, base_rotation);
    50                         m_physics.InitBodyToRigid(true);
    51                         m_physics.AddToSimulation(new_sim);
     50                        m_physics->SetCollisionChannel(0, 0xFF);
     51                        m_physics->SetShapeToBox(BoxSize);
     52                        m_physics->SetMass(.0f);
     53                        m_physics->SetTransform(base_location, base_rotation);
     54                        m_physics->InitBodyToRigid(true);
     55                        m_physics->AddToSimulation(new_sim);
    5256                }
    5357                else if (dummy == 2) //for character purpose
    5458                {
     59                        m_character = new EasyCharacterController(this);
    5560                        m_is_character = true;
    5661                        //m_mesh.Compile("[sc#f00 afcb10 10 10 -.1]");
     
    7883                                );
    7984                        vec3 BoxSize = vec3(.5f, 2.f, .5f);
    80                         m_character.SetCollisionChannel(0, 0xFF);
    81                         m_character.SetShapeToCapsule(BoxSize.x, BoxSize.y);
    82                         m_character.SetMass(.0f);
    83                         m_character.SetTransform(base_location, base_rotation);
    84                         m_character.InitBodyToGhost();
    85                         m_character.AddToSimulation(new_sim);
     85                        m_character->SetCollisionChannel(0, 0xFF);
     86                        m_character->SetShapeToCapsule(BoxSize.x, BoxSize.y);
     87                        m_character->SetMass(.0f);
     88                        m_character->SetTransform(base_location, base_rotation);
     89                        m_character->InitBodyToGhost();
     90                        m_character->AddToSimulation(new_sim);
    8691                }
    8792        }
     
    168173                }
    169174
     175                m_physics = new EasyPhysic(this);
     176
    170177                m_mesh.Compile(MeshRand[RandValue]);
    171178                vec3 BoxSize = vec3(2.0f);
     
    173180                if (RandValue < SphereLimit)
    174181                {
    175                         m_physics.SetShapeToBox(BoxSize);
     182                        m_physics->SetShapeToBox(BoxSize);
    176183                        ColGroup += 0;
    177184                }
    178185                else if (RandValue < ConeLimit)
    179186                {
    180                         m_physics.SetShapeToSphere(BoxSize.x * 2.f);
     187                        m_physics->SetShapeToSphere(BoxSize.x * 2.f);
    181188                        ColGroup += 1;
    182189                }
    183190                else if (RandValue < CylLimit)
    184191                {
    185                         m_physics.SetShapeToCone(BoxSize.x, BoxSize.y);
     192                        m_physics->SetShapeToCone(BoxSize.x, BoxSize.y);
    186193                        ColGroup += 2;
    187194                }
    188195                else if (RandValue < CapsLimit)
    189196                {
    190                         m_physics.SetShapeToCylinder(BoxSize);
     197                        m_physics->SetShapeToCylinder(BoxSize);
    191198                        ColGroup += 3;
    192199                }
    193200                else
    194201                {
    195                         m_physics.SetShapeToCapsule(BoxSize.x, BoxSize.y);
     202                        m_physics->SetShapeToCapsule(BoxSize.x, BoxSize.y);
    196203                        ColGroup += 4;
    197204                }
    198205
    199                 m_physics.SetCollisionChannel(0, 0xFF);
    200                 //m_physics.SetCollisionChannel(ColGroup, (1<<ColGroup)|(1));
    201                 m_physics.SetMass(base_mass);
    202                 m_physics.SetTransform(base_location);
    203                 m_physics.InitBodyToRigid();
    204                 m_physics.AddToSimulation(new_sim);
     206                m_physics->SetCollisionChannel(0, 0xFF);
     207                //m_physics->SetCollisionChannel(ColGroup, (1<<ColGroup)|(1));
     208                m_physics->SetMass(base_mass);
     209                m_physics->SetTransform(base_location);
     210                m_physics->InitBodyToRigid();
     211                m_physics->AddToSimulation(new_sim);
    205212        }
    206213
     
    208215        {
    209216                if (m_is_character)
    210                         m_character.SetTransform(base_location, base_rotation);
     217                        m_character->SetTransform(base_location, base_rotation);
    211218                else
    212                         m_physics.SetTransform(base_location, base_rotation);
     219                        m_physics->SetTransform(base_location, base_rotation);
     220        }
     221
     222        void SetLinearVelocity(const lol::vec3& NewVelocity, bool bIsLocal=false)
     223        {
     224                //if (m_is_character)
     225                //      m_character->SetLinearVelocity(NewVelocity);
     226                //else
     227                //      m_physics->SetLinearVelocity(NewVelocity);
    213228        }
    214229
     
    216231        {
    217232                if (m_is_character)
    218                         return m_character.GetTransform();
     233                        return m_character->GetTransform();
    219234                else
    220                         return m_physics.GetTransform();
     235                        return m_physics->GetTransform();
    221236        }
    222237
     
    227242
    228243        EasyMesh *GetMesh() { return &m_mesh; }
    229         EasyPhysic *GetPhysic() { return &m_physics; }
    230         EasyPhysic *GetCharacter() { return &m_character; }
     244        EasyPhysic *GetPhysic() { return m_physics; }
     245        EasyPhysic *GetCharacter() { return m_character; }
    231246
    232247        ~PhysicsObject()
     
    255270                {
    256271                        if (m_is_character)
    257                                 m_mesh.Render(m_character.GetTransform());
     272                                m_mesh.Render(m_character->GetTransform());
    258273                        else
    259                                 m_mesh.Render(m_physics.GetTransform());
     274                                m_mesh.Render(m_physics->GetTransform());
    260275                }
    261276        }
     
    263278private:
    264279        //Base datas
    265         EasyMesh                                m_mesh;
    266         EasyPhysic                              m_physics;
    267         EasyCharacterController m_character;
    268 
    269         bool                    m_ready;
    270         bool                    m_should_render;
    271         bool                    m_is_character;
     280        EasyMesh                                        m_mesh;
     281        EasyPhysic*                                     m_physics;
     282        EasyCharacterController*        m_character;
     283
     284        bool                                            m_ready;
     285        bool                                            m_should_render;
     286        bool                                            m_is_character;
    272287};
    273288
  • trunk/test/Physics/Include/EasyCharacterController.h

    r1749 r1764  
    3636
    3737public:
    38         EasyCharacterController() :
    39                 EasyPhysic(),
     38        EasyCharacterController(WorldEntity* NewOwnerEntity) :
     39                EasyPhysic(NewOwnerEntity),
    4040                m_character(NULL)
    4141        {
  • trunk/test/Physics/Include/EasyPhysics.h

    r1749 r1764  
    3939
    4040public:
    41         EasyPhysic();
     41        EasyPhysic(WorldEntity* NewOwnerEntity);
    4242        ~EasyPhysic();
    4343
     
    5050        virtual bool CanChangeCollisionChannel() { return (m_rigid_body == NULL); }
    5151        virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f)));
     52private:
     53        virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix);
     54public:
    5255        virtual void SetMass(float mass);
    5356        virtual void InitBodyToRigid(bool ZeroMassIsKinematic=false);
     
    7780
    7881public:
    79         EasyPhysic() { }
     82        EasyPhysic(WorldEntity* NewOwnerEntity) { m_owner_entity = NewOwnerEntity; }
    8083
    8184        virtual void SetShapeToBox(lol::vec3& BoxSize) { }
     
    8790        virtual bool CanChangeCollisionChannel() { return true; }
    8891        virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f))) { }
     92private:
     93        virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix) { }
     94public:
    8995        virtual void SetMass(float mass) { }
    9096        virtual void InitBodyToRigid() { }
     
    114120        int GetCollisionMask()  { return m_collision_mask; }
    115121
     122        //Base/Attachment logic
     123        virtual void AttachTo(EasyPhysic* NewBase, bool NewBaseLockLocation = true, bool NewBaseLockRotation = true)
     124        {
     125                if (NewBase == this || NewBase->m_base_physic == this)
     126                        return;
     127
     128                if (NewBase)
     129                {
     130                        bool bAlreadyExists = false;
     131                        for (int i = 0; i < NewBase->m_based_physic_list.Count(); ++i)
     132                                if (NewBase->m_based_physic_list[i] == this)
     133                                        bAlreadyExists = true;
     134                        if (!bAlreadyExists)
     135                                NewBase->m_based_physic_list << this;
     136                        m_base_physic = NewBase;
     137                        m_base_lock_location = NewBaseLockLocation;
     138                        m_base_lock_rotation = NewBaseLockRotation;
     139                }
     140                else
     141                {
     142                        for (int i = 0; i < NewBase->m_based_physic_list.Count(); ++i)
     143                                if (NewBase->m_based_physic_list[i] == this)
     144                                        NewBase->m_based_physic_list.Remove(i--);
     145                        m_base_physic = NULL;
     146                }
     147        }
     148
    116149protected:
    117150        lol::mat4                                                                       m_local_to_world;
     
    119152        int                                                                                     m_collision_group;
    120153        int                                                                                     m_collision_mask;
     154        WorldEntity*                                                            m_owner_entity;
     155
     156        //Base/Attachment logic
     157        Array<EasyPhysic*>                                                      m_based_physic_list;    //List of objects based on this : this object moves, its based object move with it.
     158        EasyPhysic*                                                                     m_base_physic;                  //Base for this object : The base moves, the object moves with it.
     159        bool                                                                            m_base_lock_location;   //when this is TRUE, location moves with rotation change.
     160        bool                                                                            m_base_lock_rotation;   //when this is TRUE, rotation moves with rotation change.
     161
     162        //Touch logic
     163        Array<EasyPhysic*>                                                      m_touching_physic;              //Maintained by ghost objects
    121164};
    122165
  • trunk/test/Physics/Src/EasyPhysics.cpp

    r1756 r1764  
    3030//--
    3131
    32 EasyPhysic::EasyPhysic() :
     32EasyPhysic::EasyPhysic(WorldEntity* NewOwnerEntity) :
    3333        m_collision_object(NULL),
    3434        m_ghost_object(NULL),
     
    4040        m_mass(.0f),
    4141        m_collision_group(1),
    42         m_collision_mask(1)
     42        m_collision_mask(1),
     43        m_owner_entity(NewOwnerEntity)
    4344{
    4445}
     
    114115void EasyPhysic::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation)
    115116{
    116         m_local_to_world = lol::mat4::translate(base_location) * mat4(base_rotation);
     117        lol::mat4 PreviousMatrix = m_local_to_world;
     118        m_local_to_world = lol::mat4::translate(base_location) * lol::mat4(base_rotation);
    117119
    118120        if (m_ghost_object)
     
    124126                else
    125127                        m_motion_state = new btDefaultMotionState(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT)));
     128        }
     129
     130        for (int i = 0; i < m_based_physic_list.Count(); i++)
     131                if (m_based_physic_list[i])
     132                        m_based_physic_list[i]->BaseTransformChanged(PreviousMatrix, m_local_to_world);
     133                else
     134                        m_based_physic_list.Remove(i--);
     135}
     136
     137//Internal callback when Base transform has changed.
     138void EasyPhysic::BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix)
     139{
     140        mat4 PreviousMatrixLoc = ((m_base_lock_location)?(PreviousMatrix):(lol::mat4::translate(PreviousMatrix.v3.xyz)));
     141        mat4 PreviousMatrixRot = ((m_base_lock_rotation)?(lol::mat4(lol::quat(PreviousMatrix))):(lol::mat4(1.f)));
     142        mat4 NewMatrixLoc = ((m_base_lock_location)?(NewMatrix):(lol::mat4::translate(NewMatrix.v3.xyz)));
     143        mat4 NewMatrixRot = ((m_base_lock_rotation)?(lol::mat4(lol::quat(NewMatrix))):(lol::mat4(1.f)));
     144       
     145        if (m_ghost_object || (m_rigid_body->getCollisionFlags() & btCollisionObject::CF_KINEMATIC_OBJECT))
     146        {
     147                mat4 ThisMatrixLoc = NewMatrixLoc * inverse(PreviousMatrixLoc) * lol::mat4::translate(m_local_to_world.v3.xyz);
     148                mat4 ThisMatrixRot = NewMatrixRot * inverse(PreviousMatrixRot) * lol::mat4(lol::quat(m_local_to_world));
     149                SetTransform(ThisMatrixLoc.v3.xyz, lol::mat4(lol::quat(ThisMatrixRot)));
    126150        }
    127151}
Note: See TracChangeset for help on using the changeset viewer.