void Convexcast::go(const OgreNewt::World* world, const OgreNewt::ConvexCollisionPtr& col, const Ogre::Vector3& startpt, const Ogre::Quaternion &colori, const Ogre::Vector3& endpt, int maxcontactscount, int threadIndex) { if( world->getDebugger().isRaycastRecording() ) { world->getDebugger().addConvexRay(col, startpt, colori, endpt); } // reserve memory if( mReturnInfoListSize < maxcontactscount ) { mReturnInfoListSize = 0; if( mReturnInfoList ) delete[] mReturnInfoList; mReturnInfoList = new NewtonWorldConvexCastReturnInfo[maxcontactscount]; mReturnInfoListSize = maxcontactscount; } memset(mReturnInfoList, 0, sizeof(mReturnInfoList[0])*mReturnInfoListSize); // perform the cast float matrix[16]; OgreNewt::Converters::QuatPosToMatrix(colori, startpt, &matrix[0] ); mFirstContactDistance = -1; mReturnInfoListLength = NewtonWorldConvexCast( world->getNewtonWorld(), &matrix[0], (float*)&endpt, col->getNewtonCollision(), &mFirstContactDistance, this, OgreNewt::Convexcast::newtonConvexcastPreFilter, mReturnInfoList, mReturnInfoListSize, threadIndex); if( world->getDebugger().isRaycastRecording() && world->getDebugger().isRaycastRecordingHitBodies() ) { Body* body; for(int i = 0; i < mReturnInfoListLength; i++) { body = (OgreNewt::Body*) NewtonBodyGetUserData(mReturnInfoList[i].m_hitBody); world->getDebugger().addHitBody(body); } } }
PhysicsRagDoll::RagBone::RagBone(PhysicsRagDoll* creator, OgreNewt::World* world, PhysicsRagDoll::RagBone* parent, Ogre::Bone* ogreBone, Ogre::MeshPtr mesh, Ogre::Vector3 dir, PhysicsRagDoll::RagBone::BoneShape shape, Ogre::Vector3 size, Ogre::Real mass, Actor* parentActor) { mDoll = creator; mParent = parent; mOgreBone = ogreBone; OgreNewt::ConvexCollisionPtr col; // in the case of the cylindrical primitives, they need to be rotated to align the main axis with the direction vector. Ogre::Quaternion orient = Ogre::Quaternion::IDENTITY; Ogre::Vector3 pos = Ogre::Vector3::ZERO; Ogre::Matrix3 rot; if (dir == Ogre::Vector3::UNIT_Y) { rot.FromEulerAnglesXYZ(Ogre::Degree(0), Ogre::Degree(0), Ogre::Degree(90)); orient.FromRotationMatrix(rot); } if (dir == Ogre::Vector3::UNIT_Z) { rot.FromEulerAnglesXYZ(Ogre::Degree(0), Ogre::Degree(90), Ogre::Degree(0)); orient.FromRotationMatrix(rot); } // make the rigid body. switch (shape) { case PhysicsRagDoll::RagBone::BS_BOX: col = OgreNewt::ConvexCollisionPtr(new OgreNewt::CollisionPrimitives::Box(world, size, 0)); break; case PhysicsRagDoll::RagBone::BS_CAPSULE: col = OgreNewt::ConvexCollisionPtr(new OgreNewt::CollisionPrimitives::Capsule(world, size.y, size.x, 0, orient, pos)); break; case PhysicsRagDoll::RagBone::BS_CONE: col = OgreNewt::ConvexCollisionPtr(new OgreNewt::CollisionPrimitives::Cone(world, size.y, size.x, 0, orient, pos)); break; case PhysicsRagDoll::RagBone::BS_CYLINDER: col = OgreNewt::ConvexCollisionPtr(new OgreNewt::CollisionPrimitives::Cylinder(world, size.y, size.x, 0, orient, pos)); break; case PhysicsRagDoll::RagBone::BS_ELLIPSOID: col = OgreNewt::ConvexCollisionPtr(new OgreNewt::CollisionPrimitives::Ellipsoid(world, size, 0)); break; case PhysicsRagDoll::RagBone::BS_CONVEXHULL: col = _makeConvexHull(world, mesh, size.x); break; default: col = OgreNewt::ConvexCollisionPtr(new OgreNewt::CollisionPrimitives::Box(world, size, 0)); break; } if (col) { if (col->getNewtonCollision() == NULL) { col.reset(); } } if (!col) { LOG_WARNING(Logger::CORE, " error creating collision for '" + ogreBone->getName() + "', still continuing."); mBody = NULL; } else { mBody = new OgreNewt::Body(world, col); mBody->setUserData(Ogre::Any(parentActor)); mBody->setStandardForceCallback(); const OgreNewt::MaterialID* ragdollMat = PhysicsManager::getSingleton().createMaterialID("default"); mBody->setMaterialGroupID(ragdollMat); Ogre::Vector3 inertia; Ogre::Vector3 com; col->calculateInertialMatrix(inertia, com); mBody->setMassMatrix(mass, inertia * mass); mBody->setCenterOfMass(com); mBody->setCustomTransformCallback(PhysicsRagDoll::_placementCallback); mOgreBone->setManuallyControlled(true); } }