float psLinearMovement::GetYRotation () const { // user will get a warning and a nothing if theres no mesh if (!mesh) return 0.0; const csMatrix3& transf = mesh->GetMovable () ->GetTransform ().GetT2O (); return Matrix2YRot (transf); }
void psWorld::GetPosition(iMeshWrapper* pcmesh, csVector3 &pos, float* yrot,iSector* §or) { pos = pcmesh->GetMovable()->GetPosition(); // rotation if(yrot) { csMatrix3 transf = pcmesh->GetMovable()->GetTransform().GetT2O(); *yrot = Matrix2YRot(transf); } // Sector if(pcmesh->GetMovable()->GetSectors()->GetCount()) { sector = pcmesh->GetMovable()->GetSectors()->Get(0); } else { sector = NULL; } }
int psLinearMovement::MoveSprite (float delta) { int ret = PS_MOVE_SUCCEED; csReversibleTransform fulltransf = mesh->GetMovable () ->GetFullTransform (); const csMatrix3& transf = fulltransf.GetT2O (); float yrot = Matrix2YRot (transf); // Calculate the total velocity (body and world) in OBJECT space. csVector3 bodyVel (fulltransf.Other2ThisRelative (velWorld) + velBody); float local_max_interval = MIN (MIN ( (bodyVel.y==0.0f) ? MAX_CD_INTERVAL : ABS (intervalSize.y/bodyVel.y), (bodyVel.x==0.0f) ? MAX_CD_INTERVAL : ABS (intervalSize.x/bodyVel.x) ),(bodyVel.z==0.0f) ? MAX_CD_INTERVAL : ABS (intervalSize.z/bodyVel.z) ); // Compensate for speed local_max_interval /= speed; // Err on the side of safety (95% error margin) local_max_interval *= 0.95f; //printf("local_max_interval=%f, bodyVel is %1.2f, %1.2f, %1.2f\n",local_max_interval, bodyVel.x, bodyVel.y, bodyVel.z); //printf("velWorld is %1.2f, %1.2f, %1.2f\n", velWorld.x, velWorld.y, velWorld.z); //printf("velBody is %1.2f, %1.2f, %1.2f\n", velBody.x, velBody.y, velBody.z); // Sanity check on time interval here. Something is messing it up. -KWF //local_max_interval = MAX(local_max_interval,0.1F); if (colldet) { while (delta > local_max_interval) { csVector3 oldpos(mesh->GetMovable ()->GetFullTransform ().GetOrigin()); // Perform brutal optimisation here for falling with no obstacles if(velWorld.y < -20.0f && mesh->GetMovable()->GetSectors()->GetCount() > 0) { csVector3 worldVel (fulltransf.This2OtherRelative (velBody) + velWorld); bool hit = false; // We check for other meshes at the start and end of the box with radius * 2 to be on the safe side { csRef<iMeshWrapperIterator> objectIter = engine->GetNearbyMeshes(mesh->GetMovable()->GetSectors()->Get(0), oldpos + boundingBox.GetCenter(), boundingBox.GetSize().Norm() * 2); if(objectIter->HasNext()) hit = true; } if(!hit) { csRef<iMeshWrapperIterator> objectIter = engine->GetNearbyMeshes(mesh->GetMovable()->GetSectors()->Get(0), oldpos + worldVel * delta + boundingBox.GetCenter(), boundingBox.GetSize().Norm() * 2); if(objectIter->HasNext()) hit = true; } if(!hit) { csOrthoTransform transform_newpos(csMatrix3(), oldpos + worldVel * delta); csBox3 fullBox(fulltransf.This2OtherRelative(boundingBox.Min()), fulltransf.This2OtherRelative(boundingBox.Max())); csBox3 newBox( transform_newpos.This2OtherRelative(boundingBox.Min()), transform_newpos.This2OtherRelative(boundingBox.Max())); fullBox.AddBoundingBox(newBox); csRef<iMeshWrapperIterator> objectIter = engine->GetNearbyMeshes(mesh->GetMovable()->GetSectors()->Get(0), fullBox); if(objectIter->HasNext()) hit = true; } if(!hit) local_max_interval = delta; } ret = MoveV (local_max_interval); csVector3 displacement(fulltransf.GetOrigin() - oldpos); displacement = fulltransf.Other2ThisRelative(displacement); // Check the invariants still hold otherwise we may jump walls if(!(fabs(displacement.x) <= intervalSize.x)) { printf("X (%g) out of bounds when performing CD > %g!\n", fabs(displacement.x), intervalSize.x); CS_ASSERT(false); } if(!(fabs(displacement.z) <= intervalSize.z)) { printf("Z (%g) out of bounds when performing CD > %g!\n", fabs(displacement.y), intervalSize.y); CS_ASSERT(false); } if(!(fabs(displacement.y) <= intervalSize.y)) { printf("Y (%g) out of bounds when performing CD > %g!\n", fabs(displacement.z), intervalSize.z); CS_ASSERT(false); } RotateV (local_max_interval); yrot = Matrix2YRot (transf); // We must update the transform after every rotation! fulltransf = mesh->GetMovable ()->GetFullTransform (); if (ret == PS_MOVE_FAIL) return ret; // The velocity may have changed by now bodyVel = fulltransf.Other2ThisRelative(velWorld) + velBody; delta -= local_max_interval; local_max_interval = MIN (MIN ((bodyVel.y==0.0f) ? MAX_CD_INTERVAL : ABS (intervalSize.y/bodyVel.y), (bodyVel.x==0.0f) ? MAX_CD_INTERVAL : ABS (intervalSize.x/bodyVel.x)), (bodyVel.z==0.0f) ? MAX_CD_INTERVAL : ABS (intervalSize.z/bodyVel.z)); // Compensate for speed local_max_interval /= speed; // Err on the side of safety (95% error margin) local_max_interval *= 0.95f; // Sanity check on time interval here. Something is messing it up. -KWF // local_max_interval = MAX(local_max_interval,0.1F); } } if (!colldet || delta) { ret = MoveV (delta); RotateV(delta); } return ret; }