[Opal-commits] opal/samples/src OgreLine.h,NONE,1.1 BaseOpalApp.h,1.6,1.7 PhysicalCamera.h,1.3,1.4 T
Status: Inactive
Brought to you by:
tylerstreeter
|
From: tylerstreeter <tyl...@us...> - 2005-04-06 04:49:24
|
Update of /cvsroot/opal/opal/samples/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1764/samples/src Modified Files: BaseOpalApp.h PhysicalCamera.h TemplateApp.cpp Added Files: OgreLine.h Log Message: minor changes; added stuff to sample app Index: PhysicalCamera.h =================================================================== RCS file: /cvsroot/opal/opal/samples/src/PhysicalCamera.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** PhysicalCamera.h 5 Apr 2005 05:18:53 -0000 1.3 --- PhysicalCamera.h 6 Apr 2005 04:48:44 -0000 1.4 *************** *** 114,117 **** --- 114,126 ---- mGraspedObject->setSleeping(false); + //// Set the Motor's global desired orientaiton for the Solid. + //Ogre::Vector3 camForward = mOgreCamera->getDirection(); + //Ogre::Vector3 camUp = mOgreCamera->getUp(); + //Ogre::Vector3 camRight = mOgreCamera->getRight(); + //opal::Vec3r f(camForward[0], camForward[1], camForward[2]); + //opal::Vec3r u(camUp[0], camUp[1], camUp[2]); + //opal::Vec3r r(camRight[0], camRight[1], camRight[2]); + //mGraspingMotor->setDesiredOrientation(f, u, r); + // Set the Motor's global desired position for the Solid // (at its attach position). *************** *** 133,136 **** --- 142,151 ---- } + /// Returns a pointer to the Ogre Camera's parent SceneNode. + Ogre::SceneNode* getOgreSceneNode()const + { + return mOgreCamera->getParentSceneNode(); + } + /// Sets the position of the camera in global coordinates. This /// refers to the camera's eye position. *************** *** 281,286 **** --- 296,304 ---- data.solid = result.solid; data.mode = opal::LINEAR_MODE; + //data.mode = opal::LINEAR_AND_ANGULAR_MODE; data.linearKd = 3; data.linearKs = 50; + //data.angularKd = 0.3; + //data.angularKs = 5; // Desired position/orientation will be updated in the // "update" function. Index: TemplateApp.cpp =================================================================== RCS file: /cvsroot/opal/opal/samples/src/TemplateApp.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** TemplateApp.cpp 4 Apr 2005 13:09:10 -0000 1.5 --- TemplateApp.cpp 6 Apr 2005 04:48:44 -0000 1.6 *************** *** 31,35 **** } ! ~MyApp::MyApp() { } --- 31,35 ---- } ! MyApp::~MyApp() { } *************** *** 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. --- 58,63 ---- // Setup the initial camera position. ! mPhysicalCamera->setPosition(opal::Point3r(0, 30, 50)); ! mPhysicalCamera->lookAt(opal::Point3r(0, 0, 0)); // Load models, create physical objects, etc. here. *************** *** 66,70 **** bool MyApp::appFrameStarted(opal::real dt) { ! // Do per-frame application specific things here. // Return true to continue looping. --- 66,70 ---- bool MyApp::appFrameStarted(opal::real dt) { ! // Do per-frame application-specific things here. // Return true to continue looping. Index: BaseOpalApp.h =================================================================== RCS file: /cvsroot/opal/opal/samples/src/BaseOpalApp.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** BaseOpalApp.h 5 Apr 2005 05:18:53 -0000 1.6 --- BaseOpalApp.h 6 Apr 2005 04:48:44 -0000 1.7 *************** *** 22,26 **** mPhysicalCamera = NULL; mPaused = false; - mNamelessObjectCount = 0; } --- 22,25 ---- *************** *** 102,110 **** /// Creates and returns a pointer to a PhysicalEntity. Takes ! /// the name of the new PhysicalEntity, the Ogre Entity, and a ! /// pointer to an OPAL Solid. The name must be unique; unique ! /// names will be automatically generated for empty name strings. PhysicalEntity* createPhysicalEntity(const std::string& name, ! Ogre::Entity* e, opal::Solid* s) { if (!s) --- 101,110 ---- /// Creates and returns a pointer to a PhysicalEntity. Takes ! /// the name of the new PhysicalEntity, the associated Ogre ! /// SceneNode, and a pointer to an OPAL Solid. If the name string ! /// is empty, a unique name will be automatically generated; ! /// otherwise, the given name must be unique. PhysicalEntity* createPhysicalEntity(const std::string& name, ! Ogre::SceneNode* sn, opal::Solid* s) { if (!s) *************** *** 116,133 **** if (nameStr.empty()) { ! // Make a unique name. ! char newName[20]; ! sprintf(newName, "object%d", mNamelessObjectCount); ! mNamelessObjectCount++; ! nameStr = newName; } - // Create an Ogre SceneNode. - Ogre::SceneNode* sn = mSceneMgr->getRootSceneNode()-> - createChildSceneNode(nameStr); - - // Attach the Entity to the SceneNode. - sn->attachObject(e); - // Create a new Physical Entity. PhysicalEntity* pe = new PhysicalEntity(nameStr, sn, s); --- 116,122 ---- if (nameStr.empty()) { ! nameStr = generateUniqueName(); } // Create a new Physical Entity. PhysicalEntity* pe = new PhysicalEntity(nameStr, sn, s); *************** *** 148,154 **** /// Creates a PhysicalEntity drawn as a box. The OPAL Solid can /// be any shape, however. This is useful for prototyping scenes ! /// when you don't have a specific visual mesh to use. The name ! /// must be unique; unique names will be automatically generated ! /// for empty name strings. PhysicalEntity* createPhysicalEntityBox(const std::string& name, const std::string& materialName, Ogre::Vector3 dimensions, --- 137,143 ---- /// Creates a PhysicalEntity drawn as a box. The OPAL Solid can /// be any shape, however. This is useful for prototyping scenes ! /// when you don't have a specific visual mesh to use. If the name ! /// string is empty, a unique name will be automatically generated; ! /// otherwise, the given name must be unique. PhysicalEntity* createPhysicalEntityBox(const std::string& name, const std::string& materialName, Ogre::Vector3 dimensions, *************** *** 160,178 **** if (nameStr.empty()) { ! // Make a unique name. ! char newName[20]; ! sprintf(newName, "object%d", mNamelessObjectCount); ! mNamelessObjectCount++; ! nameStr = newName; } ! // This mesh must be stored as a box with dimensions 1x1x1. Entity* e = mSceneMgr->createEntity(nameStr, "cube.mesh"); e->setMaterialName(materialName); - pe = createPhysicalEntity(nameStr, e, s); ! // Scale the mesh according to the given dimensions. ! e->getParentSceneNode()->scale(dimensions[0], dimensions[1], ! dimensions[2]); return pe; --- 149,172 ---- if (nameStr.empty()) { ! nameStr = generateUniqueName(); } ! // Create an Ogre SceneNode for the Entity. ! Ogre::SceneNode* sn = mSceneMgr->getRootSceneNode()-> ! createChildSceneNode(nameStr); ! ! // Scale the object according to the given dimensions. ! sn->scale(dimensions[0], dimensions[1], ! dimensions[2]); ! ! // Create an Ogre Entity using a cube mesh. This mesh must be ! // stored as a box with dimensions 1x1x1. Entity* e = mSceneMgr->createEntity(nameStr, "cube.mesh"); e->setMaterialName(materialName); ! // Attach the Entity to the SceneNode. ! sn->attachObject(e); ! ! pe = createPhysicalEntity(nameStr, sn, s); return pe; *************** *** 181,187 **** /// Creates a PhysicalEntity drawn as a sphere. The OPAL Solid can /// be any shape, however. This is useful for prototyping scenes ! /// when you don't have a specific visual mesh to use. The name ! /// must be unique; unique names will be automatically generated ! /// for empty name strings. PhysicalEntity* createPhysicalEntitySphere(const std::string& name, const std::string& materialName, Ogre::Real radius, --- 175,181 ---- /// Creates a PhysicalEntity drawn as a sphere. The OPAL Solid can /// be any shape, however. This is useful for prototyping scenes ! /// when you don't have a specific visual mesh to use. If the name ! /// string is empty, a unique name will be automatically generated; ! /// otherwise, the given name must be unique. PhysicalEntity* createPhysicalEntitySphere(const std::string& name, const std::string& materialName, Ogre::Real radius, *************** *** 193,210 **** if (nameStr.empty()) { ! // Make a unique name. ! char newName[20]; ! sprintf(newName, "object%d", mNamelessObjectCount); ! mNamelessObjectCount++; ! nameStr = newName; } ! // This mesh must be stored as a sphere with radius 1. Entity* e = mSceneMgr->createEntity(nameStr, "sphere.mesh"); e->setMaterialName(materialName); - pe = createPhysicalEntity(nameStr, e, s); ! // Scale the mesh according to the given dimensions. ! e->getParentSceneNode()->scale(radius, radius, radius); return pe; --- 187,274 ---- if (nameStr.empty()) { ! nameStr = generateUniqueName(); } ! // Create an Ogre SceneNode for the Entity. ! Ogre::SceneNode* sn = mSceneMgr->getRootSceneNode()-> ! createChildSceneNode(nameStr); ! ! // Scale the object according to the given dimensions. ! sn->scale(radius, radius, radius); ! ! // Create an Ogre Entity using a sphere mesh. This mesh must be ! // stored as a sphere with radius 1. Entity* e = mSceneMgr->createEntity(nameStr, "sphere.mesh"); e->setMaterialName(materialName); ! // Attach the Entity to the SceneNode. ! sn->attachObject(e); ! ! pe = createPhysicalEntity(nameStr, sn, s); ! ! return pe; ! } ! ! /// Creates a PhysicalEntity drawn as a capsule. The OPAL Solid can ! /// be any shape, however. This is useful for prototyping scenes ! /// when you don't have a specific visual mesh to use. If the name ! /// string is empty, a unique name will be automatically generated; ! /// otherwise, the given name must be unique. ! PhysicalEntity* createPhysicalEntityCapsule(const std::string& name, ! const std::string& materialName, Ogre::Real radius, ! Ogre::Real length, opal::Solid* s) ! { ! PhysicalEntity* pe = NULL; ! ! std::string nameStr = name; ! if (nameStr.empty()) ! { ! nameStr = generateUniqueName(); ! } ! ! // Create Ogre Entities using cylinder and sphere meshes. ! ! // Create an Ogre SceneNode for the cylinder Entity. ! std::string subObjectName = "cylinder" + nameStr; ! Ogre::SceneNode* cylinderNode = mSceneMgr->getRootSceneNode()-> ! createChildSceneNode(subObjectName); ! ! // Scale the object according to the given dimensions. This ! // will also scale the transforms for the child nodes, but ! // we disable the "inherit scale" option for child nodes ! // here so the shapes themselves don't get scaled. ! cylinderNode->scale(radius, radius, length); ! ! // This mesh must be stored as a cylinder with length 1 and ! // radius 1. ! Entity* e = mSceneMgr->createEntity(subObjectName, ! "cylinder.mesh"); ! e->setMaterialName(materialName); ! cylinderNode->attachObject(e); ! ! // The spheres must use separate scene nodes that are offset ! // from the cylinder's scene node. ! ! // This mesh must be stored as a sphere with radius 1. ! subObjectName = "sphere0" + nameStr; ! Ogre::SceneNode* sn = ! cylinderNode->createChildSceneNode(subObjectName); ! sn->setInheritScale(false); ! sn->translate(0, 0, -0.5); ! sn->scale(radius, radius, radius); ! e = mSceneMgr->createEntity(subObjectName, "sphere.mesh"); ! e->setMaterialName(materialName); ! sn->attachObject(e); ! ! subObjectName = "sphere1" + nameStr; ! sn = cylinderNode->createChildSceneNode(subObjectName); ! sn->setInheritScale(false); ! sn->translate(0, 0, 0.5); ! sn->scale(radius, radius, radius); ! e = mSceneMgr->createEntity(subObjectName, "sphere.mesh"); ! e->setMaterialName(materialName); ! sn->attachObject(e); ! ! pe = createPhysicalEntity(nameStr, cylinderNode, s); return pe; *************** *** 259,263 **** // in this case, there should only be a single entity // (which is why we can safely call 'removeEntity' ! // here). while(sn->numAttachedObjects() > 0) { --- 323,330 ---- // in this case, there should only be a single entity // (which is why we can safely call 'removeEntity' ! // here). TODO: We should also check child nodes and ! // destroy their Entities here; this isn't a huge ! // issue since Ogre will destroy all the Entities ! // when the app exits. while(sn->numAttachedObjects() > 0) { *************** *** 339,342 **** --- 406,424 ---- virtual bool processUnbufferedMouseInput(Ogre::Real dt) = 0; + /// Returns a unique name string. Useful when creating lots of + /// anonymous objects. + std::string generateUniqueName() + { + static unsigned int namelessObjectCount = 0; + + // Make a unique name. + char newName[20]; + sprintf(newName, "object%d", namelessObjectCount); + std::string nameStr = newName; + ++namelessObjectCount; + + return nameStr; + } + /// Pointer to the OPAL Simulator. opal::Simulator* mSimulator; *************** *** 348,354 **** bool mPaused; - /// A counter used to generate unique object names. - unsigned int mNamelessObjectCount; - /// Map of named PhysicalEntities. This is just used to find a /// PhysicalEntity by name. --- 430,433 ---- --- NEW FILE: OgreLine.h --- #ifndef OPAL_SAMPLES_OGRE_LINE_H #define OPAL_SAMPLES_OGRE_LINE_H /// Adapted from the Dynamic Growing Buffers and the Dynamic Line Drawing /// examples on the Ogre3d wiki site (April 3, 2005). Special thanks to /// DWORD and baxissimo! /// http://grotsnik.ogre3d.org/wiki/index.php/DynamicGrowingBuffers /// http://grotsnik.ogre3d.org/wiki/index.php/DynamicLineDrawing // Here's an example of how to use it. // In initialization somewhere, create the initial lines object: // // OgreLine* line = new OgreLine(RenderOperation::OT_LINE_STRIP); // // Assume 'somePoints' is a collection of Ogre::Vector3s. // for (int i=0; i<somePoints.size(); i++) // { // line->addPoint(somePoints[i]); // } // line->update(); // SceneNode* lineNode = // mScene->getRootSceneNode()->createChildSceneNode("myLine"); // lineNode->attachObject(line); // // Then later on when you want to update the lines: // // SceneNode* lnode = dynamic_cast<SceneNode*>( // mScene->getRootSceneNode()->getChild("myLine")); // OgreLine* line = // dynamic_cast<OgreLine*>(lnode->getAttachedObject(0)); // // if (line->getNumPoints() != myPoints.size()) // { // // The number of points changed. Just recreate the list from // // scratch. // line->clear(); // for (int i=0; i<myPoints.size(); ++i) // { // line->addPoint(myPoints[i]); // } // } // else // { // // Just values have changed, use 'setPoint' instead of 'addPoint'. // for (int i=0; i<myPoints.size(); ++i) // { // line->setPoint(i, myPoints[i]); // } // } // line->update(); #include <Ogre/OgreSimpleRenderable.h> #include <Ogre/OgreHardwareBufferManager.h> #include <vector> namespace opalSamples { enum { POSITION_BINDING, TEXCOORD_BINDING }; class OgreLine : public Ogre::SimpleRenderable { public: /// Constructor - see setOperationType() for description of argument. OgreLine(Ogre::RenderOperation::OperationType opType=Ogre::RenderOperation::OT_LINE_STRIP) { initialize(opType,false); setMaterial("BaseWhiteNoLighting"); mDirty = true; } virtual ~OgreLine() { delete mRenderOp.vertexData; delete mRenderOp.indexData; } /// Add a point to the point list void addPoint(const Ogre::Vector3 &p) { mPoints.push_back(p); mDirty = true; } /// Add a point to the point list void addPoint(Real x, Real y, Real z) { mPoints.push_back(Ogre::Vector3(x,y,z)); mDirty = true; } /// Change the location of an existing point in the point list void setPoint(unsigned short index, const Ogre::Vector3 &value) { assert(index < mPoints.size() && "Point index is out of bounds!!"); mPoints[index] = value; mDirty = true; } /// Return the location of an existing point in the point list const Ogre::Vector3& getPoint(unsigned short index) const { assert(index < mPoints.size() && "Point index is out of bounds!!"); return mPoints[index]; } /// Return the total number of points in the point list unsigned short getNumPoints(void) const { return (unsigned short)mPoints.size(); } /// Remove all points from the point list void clear() { mPoints.clear(); mDirty = true; } /// Call this to update the hardware buffer after making changes. void update() { if (mDirty) { fillHardwareBuffers(); } } /** Set the type of operation to draw with. * @param opType Can be one of * - RenderOperation::OT_LINE_STRIP * - RenderOperation::OT_LINE_LIST * - RenderOperation::OT_POINT_LIST * - RenderOperation::OT_TRIANGLE_LIST * - RenderOperation::OT_TRIANGLE_STRIP * - RenderOperation::OT_TRIANGLE_FAN * The default is OT_LINE_STRIP. */ void setOperationType(Ogre::RenderOperation::OperationType opType) { mRenderOp.operationType = opType; } Ogre::RenderOperation::OperationType getOperationType()const { return mRenderOp.operationType; } /// Implementation of Ogre::SimpleRenderable virtual Ogre::Real getBoundingRadius()const { return Math::Sqrt(std::max(mBox.getMaximum().squaredLength(), mBox.getMinimum().squaredLength())); } /// Implementation of Ogre::SimpleRenderable virtual Ogre::Real getSquaredViewDepth(const Ogre::Camera* cam)const { Vector3 vMin, vMax, vMid, vDist; vMin = mBox.getMinimum(); vMax = mBox.getMaximum(); vMid = ((vMin - vMax) * 0.5) + vMin; vDist = cam->getDerivedPosition() - vMid; return vDist.squaredLength(); } protected: /** Initializes the dynamic renderable. @remarks This function should only be called once. It initializes the render operation, and calls the abstract function createVertexDeclaration(). @param operationType The type of render operation to perform. @param useIndices Specifies whether to use indices to determine the vertices to use as input. */ void initialize(Ogre::RenderOperation::OperationType operationType, bool useIndices) { // Initialize render operation mRenderOp.operationType = operationType; mRenderOp.useIndexes = useIndices; mRenderOp.vertexData = new VertexData; if (mRenderOp.useIndexes) mRenderOp.indexData = new IndexData; // Reset buffer capacities mVertexBufferCapacity = 0; mIndexBufferCapacity = 0; // Create vertex declaration createVertexDeclaration(); } /** Creates the vertex declaration. @remarks Override and set mRenderOp.vertexData->vertexDeclaration here. mRenderOp.vertexData will be created for you before this method is called. */ virtual void createVertexDeclaration() { VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); } /** Prepares the hardware buffers for the requested vertex and index counts. @remarks This function must be called before locking the buffers in fillHardwareBuffers(). It guarantees that the hardware buffers are large enough to hold at least the requested number of vertices and indices (if using indices). The buffers are possibly reallocated to achieve this. @par The vertex and index count in the render operation are set to the values of vertexCount and indexCount respectively. @param vertexCount The number of vertices the buffer must hold. @param indexCount The number of indices the buffer must hold. This parameter is ignored if not using indices. */ void prepareHardwareBuffers(size_t vertexCount, size_t indexCount) { // Prepare vertex buffer size_t newVertCapacity = mVertexBufferCapacity; if ((vertexCount > mVertexBufferCapacity) || (!mVertexBufferCapacity)) { // vertexCount exceeds current capacity! // It is necessary to reallocate the buffer. // Check if this is the first call if (!newVertCapacity) { newVertCapacity = 1; } // Make capacity the next power of two while (newVertCapacity < vertexCount) { newVertCapacity <<= 1; } } else if (vertexCount < mVertexBufferCapacity>>1) { // Make capacity the previous power of two while (vertexCount < newVertCapacity>>1) { newVertCapacity >>= 1; } } if (newVertCapacity != mVertexBufferCapacity) { mVertexBufferCapacity = newVertCapacity; // Create new vertex buffer HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( mRenderOp.vertexData->vertexDeclaration->getVertexSize(0), mVertexBufferCapacity, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // Bind buffer mRenderOp.vertexData->vertexBufferBinding->setBinding(0, vbuf); } // Update vertex count in the render operation mRenderOp.vertexData->vertexCount = vertexCount; if (mRenderOp.useIndexes) { OgreAssert(indexCount <= std::numeric_limits<unsigned short>::max(), "indexCount exceeds 16 bit"); size_t newIndexCapacity = mIndexBufferCapacity; // Prepare index buffer if ((indexCount > newIndexCapacity) || (!newIndexCapacity)) { // indexCount exceeds current capacity! // It is necessary to reallocate the buffer. // Check if this is the first call if (!newIndexCapacity) { newIndexCapacity = 1; } // Make capacity the next power of two while (newIndexCapacity < indexCount) { newIndexCapacity <<= 1; } } else if (indexCount < newIndexCapacity>>1) { // Make capacity the previous power of two while (indexCount < newIndexCapacity>>1) newIndexCapacity >>= 1; } if (newIndexCapacity != mIndexBufferCapacity) { mIndexBufferCapacity = newIndexCapacity; // Create new index buffer mRenderOp.indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, mIndexBufferCapacity, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); } // Update index count in the render operation mRenderOp.indexData->indexCount = indexCount; } } /** Fills the hardware vertex and index buffers with data. @remarks This function must call prepareHardwareBuffers() before locking the buffers to ensure the they are large enough for the data to be written. Afterwards the vertex and index buffers (if using indices) can be locked, and data can be written to them. */ virtual void fillHardwareBuffers() { size_t size = mPoints.size(); prepareHardwareBuffers(size,0); if (!size) { mBox.setExtents(Vector3::ZERO,Vector3::ZERO); mDirty=false; return; } Vector3 vaabMin = mPoints[0]; Vector3 vaabMax = mPoints[0]; HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(0); Real *prPos = static_cast<Real*>(vbuf->lock( HardwareBuffer::HBL_DISCARD)); { for(size_t i = 0; i < size; i++) { *prPos++ = mPoints[i].x; *prPos++ = mPoints[i].y; *prPos++ = mPoints[i].z; if(mPoints[i].x < vaabMin.x) vaabMin.x = mPoints[i].x; if(mPoints[i].y < vaabMin.y) vaabMin.y = mPoints[i].y; if(mPoints[i].z < vaabMin.z) vaabMin.z = mPoints[i].z; if(mPoints[i].x > vaabMax.x) vaabMax.x = mPoints[i].x; if(mPoints[i].y > vaabMax.y) vaabMax.y = mPoints[i].y; if(mPoints[i].z > vaabMax.z) vaabMax.z = mPoints[i].z; } } vbuf->unlock(); mBox.setExtents(vaabMin, vaabMax); mDirty = false; } private: std::vector<Vector3> mPoints; bool mDirty; /// Maximum capacity of the currently allocated vertex buffer. size_t mVertexBufferCapacity; /// Maximum capacity of the currently allocated index buffer. size_t mIndexBufferCapacity; }; } #endif |