[Opal-commits] opal/samples/src PhysicalCamera.h,NONE,1.1 PhysicalEntity.h,NONE,1.1 BaseOpalApp.h,1.
Status: Inactive
Brought to you by:
tylerstreeter
|
From: tylerstreeter <tyl...@us...> - 2005-04-03 00:11:52
|
Update of /cvsroot/opal/opal/samples/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12604/samples/src Modified Files: BaseOpalApp.h ExampleApplication.h TemplateApp.cpp Added Files: PhysicalCamera.h PhysicalEntity.h Log Message: minor changes to opal src; added more to playpen sample app --- NEW FILE: PhysicalCamera.h --- #ifndef OPAL_SAMPLES_PHYSICAL_CAMERA_H #define OPAL_SAMPLES_PHYSICAL_CAMERA_H #include <opal/opal.h> namespace opalSamples { //const opal::real graspDistanceScalar = (opal::real)5; //const opal::real maxReachScalar = (opal::real)8; /// Define how object grasping is handled. enum GraspMode { /// Grasped objects stay the same distance from the camera as /// when they were initially grasped. LONG_RANGE_GRASP_MODE, /// Grasped objects are pulled close to the camera. Better for /// first-person perspective. SHORT_RANGE_GRASP_MODE }; /// A camera class that enables an Ogre Camera to be physical by /// using an OPAL Solid. The physical aspect can also be disabled, /// allowing the camera to move freely through objects and not be /// affected by gravity. When the physics option is used, the /// physical shape of the camera is a stack of two sphere, like a /// snowman. class PhysicalCamera { public: /// Note: eye height and Solid radius are only used when the /// physics option is enabled. PhysicalCamera(opal::Simulator* sim, Ogre::Camera* cam, bool isPhysical, opal::real eyeHeight=2) { mIsPhysical = isPhysical; mGraspMode = LONG_RANGE_GRASP_MODE; mSimulator = sim; mSolid = NULL; mOgreCamera = cam; mGraspingMotor = sim->createSpringMotor(); mGraspingSensor = sim->createRaycastSensor(); mGraspedObject = NULL; mGraspPos.set(0, 0, -5); mMaxReach = 8; mEyeHeight = eyeHeight; //mGraspOffset.makeIdentity(); // Setup OPAL Solid, if necessary. if (isPhysical) { mSolid = sim->createSolid(); mSolid->setPosition(0, eyeHeight, 0); // Keep the camera Solid from falling asleep. mSolid->setSleepiness(0); // Make the spheres' radii 1/4 * eye height. opal::real radius = eyeHeight * (opal::real)0.25; // Add a sphere at the eye/Solid position. opal::SphereShapeData sphereData; sphereData.radius = radius; mSolid->addShape(sphereData); // Add another sphere down below. sphereData.offset.translate(0, -3 * radius, 0); mSolid->addShape(sphereData); // Attach the ray Sensor to the Solid. opal::RaycastSensorData raySensorData; raySensorData.solid = mSolid; mGraspingSensor->init(raySensorData); } } ~PhysicalCamera() { if (mIsPhysical) { assert(mSimulator && mGraspingMotor); mSimulator->destroySolid(mSolid); } mSimulator->destroyMotor(mGraspingMotor); mSimulator->destroySensor(mGraspingSensor); } /// Gives the camera a chance to update things regularly. void update(opal::real dt) { if (!mIsPhysical && !mGraspedObject) { return; } // Keep solid upright by resetting its orientation. Thus the // camera Solid's orientation is always the same. opal::Point3r p = mSolid->getPosition(); opal::Matrix44r m; m.translate(p[0], p[1], p[2]); mSolid->setTransform(m); // Set the Ogre camera's position. It must be at the same position // as the OPAL Solid. mOgreCamera->setPosition((Ogre::Real)p[0], (Ogre::Real)p[1], (Ogre::Real)p[2]); // Update the ray casting Sensor's ray. Ogre::Vector3 camForward = mOgreCamera->getDirection(); if (0 != camForward.squaredLength()) { camForward.normalise(); } opal::Vec3r rayDir(camForward[0], camForward[1], camForward[2]); if (mIsPhysical) { // The ray's origin will be updated automatically since it is // attached to the camera's Solid. Its direction should be set // manually here because we constantly reset the camera's // orientation. opal::Rayr r(opal::Point3r(), rayDir); mGraspingSensor->setRay(r); } else { // The ray should start at the camera's position and fire // straight forward into the scene. opal::Rayr r(p, rayDir); mGraspingSensor->setRay(r); } // Handle the grasped object if one exists. if (mGraspedObject) { // Keep the object awake. mGraspedObject->setSleeping(false); // TODO: use 3 vecs for motor, not transform // Get the camera's transform. opal::Matrix44r camTransform; getOpalMatFromOgreCam(camTransform); // Set the desired transform for the grasped object. //mGraspingMotor->setDesiredTransform(camTransform * mGraspOffset); mGraspingMotor->setDesiredTransform(camTransform); // Since the Ogre camera's matrix doesn't include position, now // set the desired position. if (SHORT_RANGE_GRASP_MODE == mGraspMode) { // mGraspPos is a local offset from the camera. mGraspingMotor->setDesiredPosition(camTransform * mGraspPos); } else if (LONG_RANGE_GRASP_MODE == mGraspMode) { // mGraspPos is the global desired pos. mGraspingMotor->setDesiredPosition(mGraspPos); } // Drop object if it gets too far away. if (opal::distance(getPosition(), mGraspedObject->getPosition()) > mMaxReach) { release(); } } } /// Returns a pointer to the Ogre Camera. Ogre::Camera* getOgreCamera()const { return mOgreCamera; } /// Sets the position of the camera in global coordinates. This /// refers to the camera's eye position. void setPosition(const opal::Point3r& pos) { if (mIsPhysical) { assert(mSolid); mSolid->setPosition(pos); } else { mOgreCamera->setPosition(pos[0], pos[1], pos[2]); } } /// Returns the position of the camera in global coordinates. This /// refers to the camera's eye position. opal::Point3r getPosition()const { Ogre::Vector3 ogreCamPos = mOgreCamera->getPosition(); return opal::Point3r(ogreCamPos[0], ogreCamPos[1], ogreCamPos[2]); } /// Orients the camera look at the given point. void lookAt(opal::Point3r point) { mOgreCamera->lookAt(point[0], point[1], point[2]); } /// Moves the camera according to the given direction vector /// relative to its current transform. This works differently /// depending on whether the camera is physical. void moveRelative(const opal::Vec3r& dir) { if (mIsPhysical) { assert(mSolid); // TODO... //// don't let the camera fly ////if (mSolid->getPosition()[1] > mEyeHeight + 0.0001) ////{ //// dir = DONT_MOVE; ////} //Ogre::Vector3 vec; //switch(dir) //{ // case DONT_MOVE: // vec = Ogre::Vector3::ZERO; // break; // case MOVE_LEFT: // vec = -(mOgreCamera->getRight()); // break; // case MOVE_RIGHT: // vec = mOgreCamera->getRight(); // break; // case MOVE_FORWARD: // vec = mOgreCamera->getDirection(); // break; // case MOVE_BACK: // vec = -(mOgreCamera->getDirection()); // break; //} //// Don't let the camera fly. //if (vec[1] > 0) //{ // vec[1] = 0; //} //vec.normalise(); //opal::Vec3r v(vec[0], vec[1], vec[2]); //v *= 3; //mSolid->setGlobalLinearVel(v); } else { Ogre::Vector3 ogreVec(dir[0], dir[1], dir[2]); mOgreCamera->moveRelative(ogreVec); } } /// Attempts to grasp an object by firing a ray into the scene /// directly in front of the camera and choosing the closest /// intersected object, if any. void grasp() { if (!mGraspedObject) { // Fire a ray into the scene to find an object to grasp. If // an object is found, attach it to the grasping Motor and, // if using long range grasping mode, store the intersection // position relative to the camera as the grasp offset. opal::RaycastResult result = mGraspingSensor->fireRay(mMaxReach); if (result.solid && !result.solid->isStatic()) { // Store the grasped object. mGraspedObject = result.solid; // Initialize the grasping Motor with the new data. opal::SpringMotorData data; data.solid = result.solid; data.mode = opal::LINEAR_AND_ANGULAR_MODE; data.linearKd = 15; data.linearKs = 250; data.angularKd = 1; data.angularKs = 5; // Desired position/orientation will be updated in the // "update" function. mGraspingMotor->init(data); mGraspingMotor->setGlobalAttachPoint(result.intersection); if (LONG_RANGE_GRASP_MODE == mGraspMode) { mGraspPos = result.intersection; } // TODO: try just passing in the matrix and let OPAL calc these three vecs //Ogre::Vector3 f = mOgreCamera->getDirection(); //Ogre::Vector3 u = mOgreCamera->getUp(); //Ogre::Vector3 r = mOgreCamera->getRight(); //opal::Vec3r forward(f[0], f[1], f[2]); //opal::Vec3r up(u[0], u[1], u[2]); //opal::Vec3r right(r[0], r[1], r[2]); //mGraspingMotor->setDesiredOrientation( forward, up, right ); //Ogre::Matrix4 ogreMat = mOgreCamera->getViewMatrix(); ////ogreMat.setScale(Ogre::Vector3(1,1,1)); //opal::Matrix44r camTransform(ogreMat[0][0], ogreMat[1][0], ogreMat[2][0], ogreMat[3][0], // ogreMat[0][1], ogreMat[1][1], ogreMat[2][1], ogreMat[3][1], // ogreMat[0][2], ogreMat[1][2], ogreMat[2][2], ogreMat[3][2], // ogreMat[0][3], ogreMat[1][3], ogreMat[2][3], ogreMat[3][3]); //// setup grasp offset transform //camTransform.fastInvert(); //mGraspOffset = mGraspedObject->getTransform() * camTransform; // //// set desired transform //mGraspingMotor->setDesiredTransform(mGraspedObject->getTransform()); //// since the previous matrix doesn't include position, now set the desired position //mGraspingMotor->setDesiredPos(calcGraspPos()); } } } /// Releases any grasped objects. void release() { if (mGraspedObject) { // Make sure the object is awake before releasing it so it // doesn't float in midair. mGraspedObject->setSleeping(false); mGraspedObject = NULL; mGraspingMotor->setEnabled(false); } } /// Adjust the camera's pitch by adding an angle to its yaw /// relative to its current yaw. void yawRelative(opal::real degrees) { // Update the Ogre camera. mOgreCamera->yaw(Ogre::Radian(Ogre::Degree(degrees))); } /// Adjust the camera's pitch by adding an angle to its pitch /// relative to its current pitch. void pitchRelative(opal::real degrees) { // Update the Ogre camera. mOgreCamera->pitch(Ogre::Radian(Ogre::Degree(degrees))); } /// Returns true if the camera uses physics. bool isPhysical()const { return mIsPhysical; } /// Sets how object grasping is handled. void setGraspMode(GraspMode mode) { mGraspMode = mode; } /// Returns the grasp mode being used. GraspMode getGraspMode()const { return mGraspMode; } /// Sets the desired position for grasped objects, represented as a /// local offset from the camera's transform. This only applies /// in the short-range grasp mode. void setGraspOffset(const opal::Point3r& offset) { if (SHORT_RANGE_GRASP_MODE == mGraspMode) { mGraspPos = offset; } } /// Returns the desired position for grasped objects. In short /// range mode this is a local offset from the camera's transform. /// In long range mode this is the global desired position. const opal::Point3r& getGraspPos()const { return mGraspPos; } /// Sets the maximum reach distance used for grasping. void setMaxReach(opal::real r) { mMaxReach = r; } /// Returns the maximum reach distance used for grasping. opal::real getMaxReach()const { return mMaxReach; } private: // Old stuff... //opal::Point3r calcGraspPos(); //opal::Matrix44r mGraspOffset; void getOpalMatFromOgreCam(opal::Matrix44r& mat) { // Make an OPAL matrix copy of the Ogre camera's transform. Ogre::Matrix4 ogreMat = mOgreCamera->getViewMatrix(); mat.set( ogreMat[0][0], ogreMat[1][0], ogreMat[2][0], ogreMat[3][0], ogreMat[0][1], ogreMat[1][1], ogreMat[2][1], ogreMat[3][1], ogreMat[0][2], ogreMat[1][2], ogreMat[2][2], ogreMat[3][2], ogreMat[0][3], ogreMat[1][3], ogreMat[2][3], ogreMat[3][3]); } /// True if the camera uses physics. bool mIsPhysical; /// Determines how object grasping is handled. GraspMode mGraspMode; /// Pointer to the OPAL Simulator. opal::Simulator* mSimulator; /// Pointer to the OPAL Solid. opal::Solid* mSolid; /// Pointer to the Ogre camera. Ogre::Camera* mOgreCamera; /// The OPAL ray casting Sensor used to find objects to grasp. opal::RaycastSensor* mGraspingSensor; /// The OPAL Motor used to hold grasped objects in a desired /// position and orientation. opal::SpringMotor* mGraspingMotor; /// Pointer to the currently grasped object, if one exists. opal::Solid* mGraspedObject; /// The desired position for grasped objects. Has different /// meanings depending on the grasp mode. opal::Point3r mGraspPos; /// When the camera attempts to grasp an object by casting a ray, /// this is the length of the ray. It determines how far away /// objects can be and still be grasped. opal::real mMaxReach; /// The distance between the ground and the camera viewpoint. opal::real mEyeHeight; }; } #endif Index: TemplateApp.cpp =================================================================== RCS file: /cvsroot/opal/opal/samples/src/TemplateApp.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** TemplateApp.cpp 1 Apr 2005 23:13:50 -0000 1.3 --- TemplateApp.cpp 3 Apr 2005 00:11:42 -0000 1.4 *************** *** 58,64 **** // Setup the initial camera position. ! ExampleApplication::mCamera->setPosition( ! Ogre::Vector3(0, 30, 50)); ! ExampleApplication::mCamera->lookAt(0, 0, 0); // Load models, create physical objects, etc. here. --- 58,63 ---- // Setup the initial camera position. ! mPhysicalCamera->setPosition(Ogre::Vector3(0, 30, 50)); ! mPhysicalCamera->lookAt(0, 0, 0); // Load models, create physical objects, etc. here. *************** *** 92,96 **** // The following code updates the camera's position. ! Ogre::Vector3 cameraDir = Ogre::Vector3::ZERO; bool cameraMoved = false; --- 91,95 ---- // The following code updates the camera's position. ! opal::Vec3r cameraDir; bool cameraMoved = false; *************** *** 99,103 **** { // Move camera left. ! cameraDir.x -= (dt * 5); cameraMoved = true; } --- 98,102 ---- { // Move camera left. ! cameraDir[0] -= (dt * mMoveSpeed); cameraMoved = true; } *************** *** 107,111 **** { // Move camera right. ! cameraDir.x += (dt * 5); cameraMoved = true; } --- 106,110 ---- { // Move camera right. ! cameraDir[0] += (dt * mMoveSpeed); cameraMoved = true; } *************** *** 115,119 **** { // Move camera forward. ! cameraDir.z -= (dt * 5); cameraMoved = true; } --- 114,118 ---- { // Move camera forward. ! cameraDir[2] -= (dt * mMoveSpeed); cameraMoved = true; } *************** *** 123,127 **** { // Move camera backward. ! cameraDir.z += (dt * 5); cameraMoved = true; } --- 122,126 ---- { // Move camera backward. ! cameraDir[2] += (dt * mMoveSpeed); cameraMoved = true; } *************** *** 133,137 **** // Use the camera dir vector to translate the camera. ! ExampleApplication::mCamera->moveRelative(cameraDir); // Toggle shadows. --- 132,136 ---- // Use the camera dir vector to translate the camera. ! mPhysicalCamera->moveRelative(cameraDir); // Toggle shadows. *************** *** 153,158 **** } ! // Toggle HUD. ! if (mInputDevice->isKeyDown(KC_H) && mTimeUntilNextToggle <= 0) { mStatsOn = !mStatsOn; --- 152,157 ---- } ! // Toggle GUI. ! if (mInputDevice->isKeyDown(KC_G) && mTimeUntilNextToggle <= 0) { mStatsOn = !mStatsOn; *************** *** 184,189 **** // the last poll. This data can be used to rotate the camera // around its X and Y axes (pitch and yaw, respectively). ! Ogre::Radian rotX(-mInputDevice->getMouseRelativeX() * mRotateSpeed); ! Ogre::Radian rotY(-mInputDevice->getMouseRelativeY() * mRotateSpeed); // The following code checks the mouse button state. --- 183,192 ---- // the last poll. This data can be used to rotate the camera // around its X and Y axes (pitch and yaw, respectively). ! Ogre::Degree rotY = -mInputDevice->getMouseRelativeX() * mRotateSpeed; ! Ogre::Degree rotX = -mInputDevice->getMouseRelativeY() * mRotateSpeed; ! ! // Use the relative mouse motion to rotate the camera. ! mPhysicalCamera->yawRelative(rotY.valueDegrees()); ! mPhysicalCamera->yawRelative(rotX.valueDegrees()); // The following code checks the mouse button state. *************** *** 191,198 **** { // The right mouse button is down. - - // Use the relative mouse motion to rotate the camera. - ExampleApplication::mCamera->yaw(rotY); - ExampleApplication::mCamera->pitch(rotX); } else --- 194,197 ---- Index: ExampleApplication.h =================================================================== RCS file: /cvsroot/opal/opal/samples/src/ExampleApplication.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ExampleApplication.h 31 Mar 2005 08:47:02 -0000 1.2 --- ExampleApplication.h 3 Apr 2005 00:11:42 -0000 1.3 *************** *** 27,31 **** ! using namespace Ogre; /** Base class which manages the standard startup of an Ogre application. --- 27,31 ---- ! //using namespace Ogre; /** Base class which manages the standard startup of an Ogre application. --- NEW FILE: PhysicalEntity.h --- #ifndef OPAL_SAMPLES_PHYSICAL_ENTITY_H #define OPAL_SAMPLES_PHYSICAL_ENTITY_H #include <opal/opal.h> namespace opalSamples { class PhysicalEntity { public: /// PhysicalEntities should not be instantiated directly. Instead, /// use the BaseOpalApp function for creating PhysicalEntities. PhysicalEntity(const std::string& name, Ogre::SceneNode* node, opal::Solid* s) { mName = name; mSceneNode = node; mSolid = s; } virtual ~PhysicalEntity() { // The OPAL Solid and Ogre SceneNode should be destroyed // externally, not here. } /// Updates the Ogre SceneNode transform from the OPAL /// Solid's transform. virtual void update(opal::real dt) { if (NULL == mSolid || NULL == mSceneNode) { return; } opal::Point3r pos = mSolid->getPosition(); opal::Quaternion quat = mSolid->getQuaternion(); mSceneNode->setPosition((Ogre::Real)pos[0], (Ogre::Real)pos[1], (Ogre::Real)pos[2]); quat.normalize(); mSceneNode->setOrientation((Ogre::Real)quat[0], (Ogre::Real)quat[1], (Ogre::Real)quat[2], (Ogre::Real)quat[3]); } /// Returns the PhysicalEntity's name. const std::string& getName()const { return mName; } /// Returns a pointer to the Ogre SceneNode. Ogre::SceneNode* getSceneNode()const { return mSceneNode; } /// Returns a pointer to the OPAL Solid. opal::Solid* getSolid()const { return mSolid; } protected: /// The PhysicalEntity's name. std::string mName; /// Pointer to the OPAL Solid. opal::Solid* mSolid; /// Pointer to the Ogre SceneNode. Ogre::SceneNode* mSceneNode; private: }; } #endif Index: BaseOpalApp.h =================================================================== RCS file: /cvsroot/opal/opal/samples/src/BaseOpalApp.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** BaseOpalApp.h 1 Apr 2005 23:13:50 -0000 1.3 --- BaseOpalApp.h 3 Apr 2005 00:11:42 -0000 1.4 *************** *** 5,8 **** --- 5,9 ---- #include "ExampleFrameListener.h" #include "PhysicalEntity.h" + #include "PhysicalCamera.h" #include <opal/opal.h> *************** *** 17,20 **** --- 18,23 ---- mSimulator = opal::createSimulator(); mSimulator->setGravity(opal::Vec3r(0, (opal::real)-9.81, 0)); + // Create the physical camera later after the ExampleApplication + // has created its Ogre camera. mPaused = false; mNamelessObjectCount = 0; *************** *** 23,26 **** --- 26,31 ---- ~BaseOpalApp() { + delete mPhysicalCamera; + while (!mPhysicalEntityList.empty()) { *************** *** 41,44 **** --- 46,53 ---- virtual void createFrameListener() { + // TODO: move this somewhere else... + mPhysicalCamera = new PhysicalCamera(mSimulator, + ExampleApplication::mCamera, false); + ExampleFrameListener::init(ExampleApplication::mWindow, ExampleApplication::mCamera); *************** *** 315,318 **** --- 324,330 ---- opal::Simulator* mSimulator; + /// Pointer to the PhysicalCamera. + PhysicalCamera* mPhysicalCamera; + /// True when the physics simulation is paused. bool mPaused; |