41#include "OgreMeshLodGenerator.h"
42#include "OgrePixelCountLodStrategy.h"
43#include "OgreLodData.h"
44#include "OgreLodConfig.h"
45#include "OgreLodCollapser.h"
54 SEntity::SEntity(
SScene* parent,
const std::string& groupName,
const std::string& entityName,
const std::string& meshName,
bool loadInBackground) :
SNode(parent, entityName,
SNode::ENTITY_TYPE_ID)
57 mGroupName = groupName;
58 mReleaseResource =
false;
59 mResourceName = meshName;
61 mLoading = loadInBackground;
68 mMesh = Ogre::MeshManager::getSingleton().getByName(meshName, mGroupName);
76 mMesh = Ogre::MeshManager::getSingletonPtr()->create(meshName, mGroupName);
78 catch (Ogre::Exception &e)
83 if (e.getFullDescription().find(
".skeleton") == std::string::npos)
85 Ogre::LogManager::getSingletonPtr()->logMessage(e.getFullDescription(), Ogre::LML_CRITICAL,
true);
94 mMesh = Ogre::MeshManager::getSingletonPtr()->load(meshName, mGroupName);
96 catch (Ogre::Exception &e)
101 if (e.getFullDescription().find(
".skeleton") == std::string::npos)
103 Ogre::LogManager::getSingletonPtr()->logMessage(e.getFullDescription(), Ogre::LML_CRITICAL,
true);
112 if (mMesh->isLoaded() && !loadInBackground)
115 mMesh->setAutoBuildEdgeLists(
false);
116 if (mMesh->hasSkeleton())
119 mMesh->setSkeletonName(
"");
122 Ogre::PoseList plist = mMesh->getPoseList();
125 if (plist.size() > 0)
127 for (
unsigned int p = 0; p < plist.size(); p++)
129 Ogre::Pose* pose = plist[p];
130 std::string animationName = pose->getName();
133 Ogre::Animation* ogreAnimation = 0;
134 if (mMesh->hasAnimation(animationName) ==
false)
137 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!");
139 ogreAnimation = mMesh->createAnimation(animationName, 0);
143 poseHandleList.insert(PoseHandleList::value_type(animationName, p));
147 ogreAnimation = mMesh->getAnimation(animationName);
150 Ogre::ushort targetSubMesh = pose->getTarget();
151 if (!ogreAnimation->hasVertexTrack(targetSubMesh))
153 Ogre::VertexAnimationTrack* vt = ogreAnimation->createVertexTrack(targetSubMesh, Ogre::VAT_POSE);
154 vt->createVertexPoseKeyFrame(0)->addPoseReference(p, 0.0f);
160 if (mMesh->getLodStrategy() != Ogre::ScreenRatioPixelCountLodStrategy::getSingletonPtr())
161 mMesh->setLodStrategy(Ogre::ScreenRatioPixelCountLodStrategy::getSingletonPtr());
165 CommonConstructorsSequence();
172 if (mMesh->isLoading())
174 mMesh->addListener(
this);
176 else if (!mMesh->isLoaded())
181 mMesh->addListener(
this);
182 Ogre::ResourceBackgroundQueue::getSingleton().load(mMesh);
184 catch (Ogre::Exception &e)
189 if (e.getFullDescription().find(
".skeleton") == std::string::npos)
191 Ogre::LogManager::getSingletonPtr()->logMessage(e.getFullDescription(), Ogre::LML_CRITICAL,
true);
198 if (mMesh->isLoaded())
208 mMesh->setAutoBuildEdgeLists(
false);
210 if (mMesh->hasSkeleton())
213 mMesh->setSkeletonName(
"");
226 Ogre::PoseList poseList = mMesh->getPoseList();
227 if (poseList.size() > 0)
229 for (
unsigned int p = 0; p < poseList.size(); p++)
231 Ogre::Pose* pose = poseList[p];
232 std::string animationName = pose->getName();
235 Ogre::Animation* ogreAnimation = 0;
236 if (mMesh->hasAnimation(animationName) ==
false)
239 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!");
241 ogreAnimation = mMesh->createAnimation(animationName, 0);
245 poseHandleList.insert(PoseHandleList::value_type(animationName, p));
249 ogreAnimation = mMesh->getAnimation(animationName);
252 Ogre::ushort targetSubMesh = pose->getTarget();
253 if (!ogreAnimation->hasVertexTrack(targetSubMesh))
255 Ogre::VertexAnimationTrack* vt = ogreAnimation->createVertexTrack(targetSubMesh, Ogre::VAT_POSE);
256 vt->createVertexPoseKeyFrame(0)->addPoseReference(p, 0.0f);
262 CommonConstructorsSequence();
264 if (mNumLodLevel > 0)
278 SEntity::SEntity(
SScene* parent,
const std::string& entityName,
const std::string& groupName, Ogre::MeshPtr meshPointer) :
SNode(parent, entityName,
SNode::ENTITY_TYPE_ID)
281 mGroupName = groupName;
282 mReleaseResource =
false;
283 mResourceName = entityName;
288 assert(tmpRoot != 0);
301 catch (Ogre::Exception &e)
306 if (e.getFullDescription().find(
".skeleton") == std::string::npos)
308 Ogre::LogManager::getSingletonPtr()->logMessage(e.getFullDescription(), Ogre::LML_CRITICAL,
true);
315 if (mMesh->hasSkeleton())
318 mMesh->setSkeletonName(
"");
326 Ogre::PoseList poseList = mMesh->getPoseList();
327 if (poseList.size() > 0)
329 for (
unsigned int p = 0; p < poseList.size(); p++)
331 Ogre::Pose* pose = poseList[p];
332 std::string animationName = pose->getName();
335 Ogre::Animation* ogreAnimation = 0;
336 if (mMesh->hasAnimation(animationName) ==
false)
339 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!");
341 ogreAnimation = mMesh->createAnimation(animationName, 0);
345 poseHandleList.insert(PoseHandleList::value_type(animationName, p));
349 ogreAnimation = mMesh->getAnimation(animationName);
352 Ogre::ushort targetSubMesh = pose->getTarget();
353 if (!ogreAnimation->hasVertexTrack(targetSubMesh))
355 Ogre::VertexAnimationTrack* vt = ogreAnimation->createVertexTrack(targetSubMesh, Ogre::VAT_POSE);
356 vt->createVertexPoseKeyFrame(0)->addPoseReference(p, 0.0f);
362 CommonConstructorsSequence();
368 mGroupName = Ogre::RGN_DEFAULT;
369 mReleaseResource =
false;
387 OGRE_EXCEPT(Ogre::Exception::ERR_NOT_IMPLEMENTED,
"Unknow prefab type!",
"SEntity::SEntity");
389 CommonConstructorsSequence();
396 mGroupName = groupName;
397 mReleaseResource =
true;
398 mResourceName = groupName + entityName +
".PlaneRes";
402 Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0);
403 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);
405 CommonConstructorsSequence();
409 SEntity::SEntity(
SScene* parent,
const std::string& groupName,
const std::string& entityName,
const float& radius,
const int& rings,
const int& segments) :
SNode(parent, entityName,
SNode::ENTITY_TYPE_ID)
412 mGroupName = groupName;
413 mReleaseResource =
true;
414 mResourceName = groupName + entityName +
".SphereRes";
420 CommonConstructorsSequence();
424 SEntity::SEntity(
SScene* parent,
const std::string& groupName,
const std::string& entityName,
const float& radius,
const float& height,
const int& segments) :
SNode(parent, entityName,
SNode::ENTITY_TYPE_ID)
427 mGroupName = groupName;
428 mReleaseResource =
true;
429 mResourceName = groupName + entityName +
".SphereRes";
435 CommonConstructorsSequence();
439 SEntity::SEntity(
SScene* parent,
const std::string& groupName,
const std::string& entityName,
const float& base,
const float& bottom,
const float& dist) :
SNode(parent, entityName,
SNode::ENTITY_TYPE_ID)
442 mGroupName = groupName;
443 mReleaseResource =
true;
444 mResourceName = groupName + entityName +
".SphereRes";
450 CommonConstructorsSequence();
458 void SEntity::BuildMissingComponents()
461 if (mMesh->getSubMesh(0) && mMesh->getSubMesh(0)->vertexData)
465 for (
unsigned int i = 0; i < mMesh->getNumSubMeshes(); i++)
467 Ogre::SubMesh* smesh = mMesh->getSubMesh(i);
468 Ogre::VertexData* vdata = smesh->vertexData;
469 if (vdata && !vdata->vertexDeclaration->findElementBySemantic(Ogre::VertexElementSemantic::VES_TEXTURE_COORDINATES))
471 unsigned short src = vdata->vertexDeclaration->getMaxSource();
472 Ogre::HardwareVertexBufferSharedPtr origBuffer = vdata->vertexBufferBinding->getBuffer(src);
473 unsigned int vcnt = origBuffer->getVertexSize();
476 Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
477 vdata->vertexDeclaration->addElement(src, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
479 auto tvbuf = mMesh->getHardwareBufferManager()->createVertexBuffer(vcnt + 2 *
sizeof(
float), vdata->vertexCount, origBuffer->getUsage(), origBuffer->hasShadowBuffer());
482 Ogre::VertexBufferBinding* vBind = vdata->vertexBufferBinding;
483 vBind->setBinding(src, tvbuf);
486 Ogre::HardwareVertexBufferSharedPtr vbuf = vdata->vertexBufferBinding->getBuffer(src);
487 Ogre::HardwareBufferLockGuard vbufLock(vbuf, Ogre::HardwareBuffer::HBL_DISCARD);
488 float* pFloat =
static_cast<float*
>(vbufLock.pData);
490 if (smesh->operationType == Ogre::RenderOperation::OT_TRIANGLE_LIST)
492 for (
unsigned int i = 0; i < (vcnt / 3); i++)
504 for (
unsigned int i = 0; i < vcnt; i++)
514 const Ogre::VertexElement* hasTangent = mMesh->getSubMesh(0)->vertexData->vertexDeclaration->findElementBySemantic(Ogre::VertexElementSemantic::VES_TANGENT);
522 if (mMesh->suggestTangentVectorBuildParams(src))
524 mMesh->buildTangentVectors(src);
529 catch (Ogre::Exception &e)
531 Ogre::LogManager::getSingletonPtr()->logMessage(e.getFullDescription(), Ogre::LML_CRITICAL,
true);
536 void SEntity::CommonConstructorsSequence()
542 BuildMissingComponents();
587 while (visible && parent != NULL)
589 visible = parent->GetVisible();
590 parent = parent->GetParentSceneNode();
600 int numAnimations = mMesh->getNumAnimations();
601 for (
int i = 0; i < numAnimations; i++)
603 Ogre::Animation* ogreAnimation = mMesh->getAnimation(i);
607 SAnim* animation = 0;
608 PoseHandleList::iterator iPoseAnim = poseHandleList.find(ogreAnimation->getName());
609 if (iPoseAnim != poseHandleList.end())
619 int numSubEntities =
O3Entity->getNumSubEntities();
621 for (
int iSubEntities = 0; iSubEntities < numSubEntities; iSubEntities++)
623 Ogre::SubEntity* sEnt =
O3Entity->getSubEntity(iSubEntities);
625#if OGRE_VERSION < ((1 << 16) | (7 << 8) | 0)
626 static_cast <Ogre::Renderable*
> (sEnt)->setUserAny(Ogre::Any(
this));
628 sEnt->getUserObjectBindings().setUserAny(
"SEntity", Ogre::Any(
this));
635 sEnt->setMaterial(sMat->getOgreMaterialPointer());
639 MMechostr(MSKDEBUG,
">>>> Error on Material entity : %s\n", sEnt->getMaterialName().c_str());
650 mMesh->removeListener(
this);
666 if (mMesh && ((mMesh.use_count() <= 4) || mReleaseResource))
668 if (mMesh->isLoaded())
671 Ogre::MeshManager::getSingleton().remove(mMesh->getHandle());
681 mReleaseResource = state;
702 O3Entity->setCastShadows(castShadows);
716 O3Entity->setRenderingDistance(distance);
722 return O3Entity->getRenderingDistance();
735 return (
O3Entity->getBoundingBox().getSize() * scale);
737 return Ogre::Vector3(1.0f, 1.0f, 1.0f) * scale;
744 return (
O3Entity->getBoundingBox().getCenter() * scale);
746 return Ogre::Vector3(0.0f, 0.0f, 0.0f);
757 return O3Entity->getWorldBoundingBox(
true).getSize();
759 return Ogre::Vector3(1.0f, 1.0f, 1.0f) * scale;
765 return O3Entity->getWorldBoundingBox(
true).getCenter();
767 return Ogre::Vector3(0.0f, 0.0f, 0.0f);
772 unsigned int count = 0;
773 if (mMesh && mMesh->isLoaded())
775 for (
unsigned short i = 0; i < mMesh->getNumSubMeshes(); ++i)
777 Ogre::SubMesh* submesh = mMesh->getSubMesh(i);
778 count += submesh->indexData->indexCount;
787 unsigned int count = 0;
788 if (mMesh && mMesh->isLoaded())
790 for (
unsigned short i = 0; i < mMesh->getNumSubMeshes(); ++i)
792 Ogre::SubMesh* submesh = mMesh->getSubMesh(i);
794 if (submesh->useSharedVertices)
796 count += mMesh->sharedVertexData->vertexCount;
801 count += submesh->vertexData->vertexCount;
812 O3Entity->setRenderQueueGroup(groupId);
818 return O3Entity->getNumSubEntities();
832 return O3Entity->getVisibilityFlags();
841 assert((flagIndex > 0) && (flagIndex < 32));
842 Ogre::uint32 flag = 1 << flagIndex;
846 O3Entity->removeVisibilityFlags(flag);
854 assert((flagIndex > 0) && (flagIndex < 32));
856 Ogre::uint32 flag = 1 << flagIndex;
857 if ((flag &
O3Entity->getVisibilityFlags()) > 0)
873 mNumLodLevel = nbLevels;
876 int curLevels =
O3Entity->getMesh()->getNumLodLevels();
877 if ((curLevels == nbLevels) || (curLevels == 1 && nbLevels == 0))
880 if ((nbLevels == 0) && (curLevels != nbLevels))
882 O3Entity->getMesh()->removeLodLevels();
887 O3Entity->getMesh()->removeLodLevels();
888 Ogre::LodConfig lodConfig;
889 lodConfig.levels.clear();
890 lodConfig.mesh =
O3Entity->getMesh();
891 lodConfig.strategy = Ogre::ScreenRatioPixelCountLodStrategy::getSingletonPtr();
892 lodConfig.advanced.useCompression =
true;
893 lodConfig.advanced.useVertexNormals =
true;
894 lodConfig.advanced.useBackgroundQueue = mLoading;
898 int nbl = nbLevels + 2;
899 Ogre::Real reduction = 0.7f / nbLevels;
900 for (
int i = 2; i < nbl; i++)
902 Ogre::Real i4 = (Ogre::Real)(i * i * i * i);
903 lodConfig.createGeneratedLodLevel(2.0 / i4, reduction * i, Ogre::LodLevel::VRM_PROPORTIONAL);
906 Ogre::MeshLodGenerator::getSingleton().generateLodLevels(lodConfig);
917 int numSubEntities =
O3Entity->getNumSubEntities();
919 for (
int iSubEntities = 0; iSubEntities < numSubEntities; iSubEntities++)
921 Ogre::SubEntity* sEnt =
O3Entity->getSubEntity(iSubEntities);
923#if OGRE_VERSION < ((1 << 16) | (7 << 8) | 0)
924 static_cast <Ogre::Renderable*
> (sEnt)->setUserAny(Ogre::Any(
this));
926 sEnt->getUserObjectBindings().setUserAny(
"SEntity", Ogre::Any(
this));
953 else if (subindex < (
int)
O3Entity->getNumSubEntities())
960 catch (Ogre::Exception &)
974 O3Entity->setRenderingMinPixelSize(minsize);
982 return O3Entity->getRenderingMinPixelSize();
MMechostr(MSKDEBUG, " > Start loading Plugin SO3Engine dll\n")
std::string GetName() const
unsigned int GetVerticesCount()
SSkeleton * GetSkeleton()
void _SetSkeleton(SSkeleton *newSkeleton)
unsigned int GetPolygonCount()
virtual void SetCastShadows(const bool &castShadows)
virtual void SetRenderingDistance(const float &distance)
bool SetMaterial(SMaterial *mat, int subindex)
void SetVisibilityFlags(const Ogre::uint32 &flags)
void GenerateLOD(int nbLevels)
std::string GetGroupName()
virtual Ogre::Vector3 GetWorldBoundingBoxCenter(const bool &childs=false)
void SetFreeResource(bool state)
void SetRenderQueue(const Ogre::RenderQueueGroupID &groupId)
virtual Ogre::Vector3 GetBoundingBoxCenter(const bool &childs=false)
void SetMinPixelSize(const float &minsize)
virtual Ogre::Vector3 GetBoundingBoxSize(const bool &childs=false)
virtual bool GetCastShadows()
virtual Ogre::Vector3 GetWorldBoundingBoxSize(const bool &childs=false)
Ogre::uint32 GetVisibilityFlags()
Ogre::Entity * getOgreEntityPointer()
virtual float GetRenderingDistance()
void SetVisibilityFlagIndexEnable(const Ogre::uint32 &flagIndex, bool enable)
bool GetVisibilityFlagIndexEnable(const Ogre::uint32 &flagIndex)
virtual void loadingComplete(Ogre::Resource *res)
unsigned int GetNumSubEntities()
Base class for SO3 custom exception.
Ogre::MaterialPtr getOgreMaterialPointer()
std::string GetGroupName()
void AddAnimation(SAnim *existingAnimation)
Ogre::Vector3 GetSonsWorldBoundingBox()
Ogre::SceneNode * O3SceneNode
SScene * GetParentScene()
unsigned short animationCounter
virtual Ogre::Vector3 GetGlobalScale()
Ogre::MovableObject * ogreMovableObject
void SetVisible(const bool &visible, const bool &cascade=true)
SNode * GetParentSceneNode()
SNode(SScene *parent, const std::string &nodeName, const bool &isRootNode=false)
Ogre::Vector3 GetSonsBoundingBox()
void SetLogEnable(const bool &state)
static SRoot & getSingleton()
static SRoot * getSingletonPtr()
Ogre::SkeletonManager * O3SkeletonManager
SMaterial * GetMaterial(const std::string &groupName, const std::string &materialName, bool searchOtherGroups=true)
SMaterial * CreateMaterial(const std::string &groupname, const std::string &matname, const bool &loadedFromScript=false)
Ogre::SceneManager * GetOgreScenePointer()
void DeleteSkeleton(SSkeleton *existingSkeleton)
STBI_EXTERN unsigned long flags