00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00035 #include "SO3Scene.h"
00036 #include "SO3Entity.h"
00037 #include "SO3Skeleton.h"
00038 #include "../SO3Animation/SO3VertexAnimation.h"
00039 #include "../SO3Animation/SO3PoseAnimation.h"
00040 #include "../SO3Material/SO3Material.h"
00041
00042 namespace SO3
00043 {
00044
00045 SEntity::SEntity(SScene* parent, std::string groupName, std::string entityName, std::string meshName) : SNode(parent, entityName, SNode::ENTITY_TYPE_ID)
00046 {
00047 entitySKL = 0;
00048 mGroupName = groupName;
00049 mReleaseResource = false;
00050 mResourceName = meshName;
00051
00052
00053 mMesh = Ogre::MeshManager::getSingleton().getByName(meshName, mGroupName);
00054 if(mMesh.isNull())
00055 {
00056 mMesh = Ogre::MeshManager::getSingleton().load(meshName, mGroupName);
00057 if(mMesh->hasSkeleton())
00058 {
00059 mMesh->setSkeletonName("");
00060 }
00061 }
00062
00063 if(mMesh->isLodManual())
00064 {
00065 Ogre::MeshManager::getSingleton().unload(mMesh->getHandle());
00066 OGRE_EXCEPT(Ogre::Exception::ERR_INTERNAL_ERROR, "Cannot load a mesh with manual LOD!", "SEntity::SEntity");
00067 }
00068
00069
00070 if(mMesh->getPoseCount() > 0)
00071 {
00072 Ogre::ushort cptPose = 0;
00073 Ogre::Mesh::PoseIterator iPoseList = mMesh->getPoseIterator();
00074 while(iPoseList.hasMoreElements())
00075 {
00076 Ogre::Pose* pose = iPoseList.getNext();
00077 Ogre::Animation* ogreAnimation = 0;
00078
00079
00080 std::string animationName = pose->getName();
00081 std::string poseTargetAsString = boost::lexical_cast<std::string, Ogre::ushort> (pose->getTarget());
00082 if(animationName.substr(animationName.length()-poseTargetAsString.length(), poseTargetAsString.length()) == poseTargetAsString)
00083 animationName = animationName.substr(0, animationName.length()-poseTargetAsString.length());
00084
00085 if(!mMesh->hasAnimation(animationName))
00086 {
00087
00088 Ogre::LogManager::getSingleton().logMessage("No animation was found for mesh pose \""+ animationName +"\", SO3Engine will generate automatically an animation for it, but it'll be cleaner to create this animation in your modeler!");
00089
00090
00091 ogreAnimation = mMesh->createAnimation(animationName, 0);
00092
00093
00094 Ogre::VertexPoseKeyFrame* ogreKeyFrame = ogreAnimation->createVertexTrack(pose->getTarget(), Ogre::VAT_POSE)->createVertexPoseKeyFrame(0);
00095
00096
00097 ogreKeyFrame->addPoseReference(cptPose, 0.0f);
00098
00099
00100 }
00101
00102
00103 poseHandleList.insert(PoseHandleList::value_type(animationName, cptPose));
00104
00105
00106 cptPose++;
00107 }
00108 }
00109
00110 O3Entity = currentScene->GetOgreScenePointer()->createEntity(entityName, meshName, groupName);
00111 CommonConstructorsSequence();
00112 }
00113
00114 SEntity::SEntity(SScene* parent, std::string entityName, EntityPrefabType prefabType) : SNode(parent, entityName, SNode::ENTITY_TYPE_ID)
00115 {
00116 entitySKL = 0;
00117 mGroupName = "General";
00118 mReleaseResource = false;
00119 mResourceName = "";
00120 mMesh.setNull();
00121
00122 switch (prefabType)
00123 {
00124 case SO3_PREFAB_PLANE:
00125 O3Entity = currentScene->GetOgreScenePointer()->createEntity(entityName, Ogre::SceneManager::PT_PLANE);
00126 break;
00127 case SO3_PREFAB_CUBE:
00128 O3Entity = currentScene->GetOgreScenePointer()->createEntity(entityName, Ogre::SceneManager::PT_CUBE);
00129 break;
00130 case SO3_PREFAB_SPHERE:
00131 O3Entity = currentScene->GetOgreScenePointer()->createEntity(entityName, Ogre::SceneManager::PT_SPHERE);
00132 break;
00133 default:
00134 OGRE_EXCEPT(Ogre::Exception::ERR_NOT_IMPLEMENTED, "Unknow prefab type!", "SEntity::SEntity");
00135 }
00136 CommonConstructorsSequence();
00137 }
00138
00139
00140 SEntity::SEntity(SScene* parent, std::string groupName, std::string entityName, SPointFloat sizev, SPointInt seg, SPointFloat uv) : SNode(parent, entityName, SNode::ENTITY_TYPE_ID)
00141 {
00142 entitySKL = 0;
00143 mGroupName = groupName;
00144 mReleaseResource = true;
00145 mResourceName = groupName + entityName + ".PlaneRes";
00146
00147 Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0);
00148 mMesh = Ogre::MeshManager::getSingleton().createPlane(mResourceName, mGroupName, plane, sizev.x, sizev.y, seg.x, seg.y, true, 1, uv.x, uv.y, Ogre::Vector3::UNIT_Z);
00149 O3Entity = currentScene->GetOgreScenePointer()->createEntity(entityName, mResourceName, groupName);
00150 CommonConstructorsSequence();
00151 }
00152
00153 SEntity::SEntity() : SNode(0, "", SNode::ENTITY_TYPE_ID)
00154 {
00155
00156 }
00157
00158 void SEntity::CommonConstructorsSequence()
00159 {
00160 assert(O3Entity != 0);
00161 ogreMovableObject = O3Entity;
00162
00163
00164 if(!mMesh->isEdgeListBuilt())
00165 {
00166 mMesh->freeEdgeList();
00167 mMesh->buildEdgeList();
00168 }
00169 O3SceneNode->attachObject(O3Entity);
00170
00171
00172 if(O3Entity->hasVertexAnimation())
00173 {
00174
00175 int numAnimations = mMesh->getNumAnimations();
00176 for(int i=0; i<numAnimations; i++)
00177 {
00178 Ogre::Animation* ogreAnimation = mMesh->getAnimation(i);
00179
00180
00181
00182 SAnim* animation = 0;
00183 PoseHandleList::iterator iPoseAnim = poseHandleList.find(ogreAnimation->getName());
00184 if(iPoseAnim != poseHandleList.end())
00185 animation = new SPoseAnimation(GetParentScene(), ogreAnimation->getName(), this, i, iPoseAnim->second);
00186 else
00187 animation = new SVertexAnimation(GetParentScene(), ogreAnimation->getName(), this, i);
00188
00189 AddAnimation(animation);
00190 }
00191 }
00192
00193
00194 int numSubEntities = O3Entity->getNumSubEntities();
00195
00196 for (int iSubEntities = 0; iSubEntities < numSubEntities; iSubEntities++)
00197 {
00198 Ogre::SubEntity* sEnt = O3Entity->getSubEntity(iSubEntities);
00199
00200 #if OGRE_VERSION < ((1 << 16) | (7 << 8) | 0)
00201 static_cast <Ogre::Renderable*> (sEnt)->setUserAny(Ogre::Any(this));
00202 #else
00203 sEnt->getUserObjectBindings().setUserAny("SEntity", Ogre::Any(this));
00204 #endif
00205 SMaterial* sMat = GetParentScene()->GetMaterial(mGroupName, sEnt->getMaterialName());
00206 if (sMat == 0)
00207 sMat = GetParentScene()->CreateMaterial(mGroupName, sEnt->getMaterialName());
00208
00209 sEnt->setMaterial(sMat->getOgreMaterialPointer());
00210 }
00211 }
00212
00213 SEntity::~SEntity()
00214 {
00215
00216 DetachFromParent();
00217
00218 if(entitySKL)
00219 {
00220 currentScene->DeleteSkeleton(entitySKL);
00221 entitySKL = 0;
00222 }
00223
00224 O3SceneNode->detachObject(O3Entity);
00225 currentScene->GetOgreScenePointer()->destroyEntity(O3Entity);
00226
00227 if (mReleaseResource && !mMesh.isNull())
00228 {
00229 Ogre::MeshManager::getSingleton().remove(mMesh->getHandle());
00230 mMesh.setNull();
00231 }
00232
00233 O3Entity = 0;
00234 ogreMovableObject = 0;
00235 }
00236
00237 Ogre::Entity* SEntity::getOgreEntityPointer()
00238 {
00239 return O3Entity;
00240 }
00241
00242 SSkeleton* SEntity::GetSkeleton()
00243 {
00244 return entitySKL;
00245 }
00246
00247 std::string SEntity::GetGroupName()
00248 {
00249 return mGroupName;
00250 }
00251
00252 void SEntity::getSubMeshVertices(std::vector<Ogre::Vector3>* vertices,unsigned int index, Ogre::MeshPtr curMesh)
00253 {
00254 if(this != NULL)
00255 {
00256 Ogre::VertexData* vertex_data = curMesh->getSubMesh(index)->useSharedVertices ? curMesh->sharedVertexData : curMesh->getSubMesh(index)->vertexData;
00257 const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
00258 Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
00259 unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
00260 float* pReal;
00261 vertices->resize(vertex_data->vertexCount);
00262
00263 for (size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
00264 {
00265 posElem->baseVertexPointerToElement(vertex, &pReal);
00266 (*vertices)[j] = Ogre::Vector3(pReal[0],pReal[1],pReal[2]);
00267 }
00268 vbuf->unlock();
00269 }
00270 }
00271
00272 void SEntity::SetCastShadows(bool castShadows)
00273 {
00274 O3Entity->setCastShadows(castShadows);
00275 }
00276
00277 bool SEntity::GetCastShadows()
00278 {
00279 return O3Entity->getCastShadows();
00280 }
00281
00282 void SEntity::SetRenderingDistance(float distance)
00283 {
00284 return O3Entity->setRenderingDistance(distance);
00285 }
00286
00287 float SEntity::GetRenderingDistance()
00288 {
00289 return O3Entity->getRenderingDistance();
00290 }
00291
00292 Ogre::Vector3 SEntity::GetBoundingBoxSize(bool childs)
00293 {
00294 if (childs)
00295 return GetSonsBoundingBox();
00296
00297 Ogre::Vector3 scale = O3SceneNode->_getDerivedScale();
00298 return (O3Entity->getBoundingBox().getSize() * scale);
00299 }
00300
00301 Ogre::Vector3 SEntity::GetBoundingBoxCenter(bool childs)
00302 {
00303 Ogre::Vector3 scale = O3SceneNode->_getDerivedScale();
00304 return (O3Entity->getBoundingBox().getCenter() * scale);
00305 }
00306
00307 unsigned int SEntity::GetPolygonCount()
00308 {
00309 return O3Entity->getEdgeList()->triangles.size();
00310 }
00311
00312 void SEntity::SetRenderQueue(Ogre::RenderQueueGroupID groupId)
00313 {
00314 O3Entity->setRenderQueueGroup(groupId);
00315 }
00316
00317 unsigned int SEntity::GetNumSubEntities()
00318 {
00319 return O3Entity->getNumSubEntities();
00320 }
00321
00324 void SEntity::SetVisibilityFlags(Ogre::uint32 flags)
00325 {
00326 O3Entity->setVisibilityFlags(flags);
00327 }
00328
00331 Ogre::uint32 SEntity::GetVisibilityFlags()
00332 {
00333 return O3Entity->getVisibilityFlags();
00334 }
00335
00336 void SEntity::_SetSkeleton(SSkeleton* newSkeleton)
00337 {
00338 entitySKL = newSkeleton;
00339 }
00340
00341
00342
00343 void SEntity::Reload()
00344 {
00345
00346 int numSubEntities = O3Entity->getNumSubEntities();
00347
00348 for (int iSubEntities = 0; iSubEntities < numSubEntities; iSubEntities++)
00349 {
00350 Ogre::SubEntity* sEnt = O3Entity->getSubEntity(iSubEntities);
00351
00352 #if OGRE_VERSION < ((1 << 16) | (7 << 8) | 0)
00353 static_cast <Ogre::Renderable*> (sEnt)->setUserAny(Ogre::Any(this));
00354 #else
00355 sEnt->getUserObjectBindings().setUserAny("SEntity", Ogre::Any(this));
00356 #endif
00357 SMaterial* sMat = GetParentScene()->GetMaterial(mGroupName, sEnt->getMaterialName());
00358 if (sMat == 0)
00359 sMat = GetParentScene()->CreateMaterial(mGroupName, sEnt->getMaterialName());
00360
00361 sEnt->setMaterial(sMat->getOgreMaterialPointer());
00362 }
00363 }
00364
00365 }