25#include <OgreResourceGroupManager.h>
26#include <OgreMaterialManager.h>
27#include <OgreBulletDynamicsRigidBody.h>
29#include <OgreAxisAlignedBox.h>
30#include <Shapes/OgreBulletCollisionsTrimeshShape.h>
31#include <Shapes/OgreBulletCollisionsBoxShape.h>
71 Bounds =
new Ogre::AxisAlignedBox();
98 else if (meshname !=
"")
191 if (
mBody->isInWorld() ==
false)
195 mBody->enableCollisions(value);
201 mBody->removeFromWorld();
213 Walls.emplace_back(wall);
223 for (
size_t i = 0; i <
Walls.size(); i++)
245 if (
prepared ==
true && force ==
false)
252 for (
size_t i = 0; i <
Walls.size(); i++)
257 for (
size_t j = 0; j <
Walls[i]->polygons.size(); j++)
263 for (
size_t k = 0; k < poly->
geometry.size(); k++)
265 for (
size_t l = 0; l < poly->
geometry[k].size(); l++)
301 OgreBulletCollisions::TriangleMeshCollisionShape* shape =
new OgreBulletCollisions::TriangleMeshCollisionShape(vertex_count, index_count);
304 for (
int i = 0; i < index_count; i += 3)
306 shape->AddTriangle(vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]]);
321 catch (Ogre::Exception &e)
323 ReportError(
"Error creating model collider for '" +
name +
"'\n" + e.getDescription());
346 if (
Bounds->isNull() ==
true)
350 OgreBulletCollisions::BoxCollisionShape* shape =
new OgreBulletCollisions::BoxCollisionShape(bounds);
364 catch (Ogre::Exception &e)
366 ReportError(
"Error creating box collider for '" +
name +
"'\n" + e.getDescription());
374 for (
size_t i = 0; i <
Walls.size(); i++)
393 for (
size_t i = 0; i <
Walls.size(); i++)
441 mBody->updateTransform(
true,
false,
false);
457 mBody->updateTransform(
false,
true,
false);
478 if (
Bounds->isNull() ==
true)
484 Ogre::AxisAlignedBox global_box (pos + min, pos + max);
486 return camera->isVisible(global_box);
500 if (
Bounds->isNull() ==
true)
501 return Vector3::ZERO;
513 for (
size_t i = 0; i <
Walls.size(); i++)
524 Real limit = 1000000;
526 Vector3 left_min (-limit, -limit, -limit);
527 Vector3 left_max (start.x, limit, limit);
528 Vector3 right_min (end.x, -limit, -limit);
529 Vector3 right_max (limit, limit, limit);
530 Vector3 front_min (-limit, -limit, -limit);
531 Vector3 front_max (limit, limit, start.z);
532 Vector3 back_min (-limit, -limit, end.z);
533 Vector3 back_max (limit, limit, limit);
535 Cut(left_min, left_max, cutwalls, cutfloors);
536 Cut(right_min, right_max, cutwalls, cutfloors);
537 Cut(front_min, front_max, cutwalls, cutfloors);
538 Cut(back_min, back_max, cutwalls, cutfloors);
545 std::string filename1 =
"data/";
546 filename1.append(filename);
554 matname = filename2.substr(0, filename2.length() - 5) +
".material";
556 Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(matname2, path);
557 Report(
"Loading material script " + matname2);
558 Ogre::MaterialManager::getSingleton().parseScript(stream, path);
563 while(!stream->eof())
565 std::string line = stream->getLine();
567 if (
StartsWith(line,
"material",
true) ==
true)
569 std::vector<std::string> vec = Ogre::StringUtil::split(line,
" \t:");
570 for (std::vector<std::string>::iterator it = vec.begin(); it < vec.end(); ++it)
572 std::string match = (*it);
576 Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().getByName(match, path);
579 Report(
"Loading material " + match);
584 materialPtr->setLightingEnabled(
false);
587 materialPtr->setLightingEnabled(
true);
598 catch (Ogre::Exception &e)
600 ReportError(
"Error loading material file " + matname +
"\n" + e.getDescription());
617 std::string filename1 =
"data/";
625 std::string colname2;
629 std::string colname = filename2.substr(0, filename2.length() - 5) +
".collider.mesh";
631 collidermesh = Ogre::MeshManager::getSingleton().load(colname2, path);
633 catch (Ogre::Exception &e)
635 return ReportError(
"No collider model for " + colname2 +
"\n" + e.getDescription());
658 for (
size_t i = 0; i <
Walls.size(); i++)
663 Walls[i]->ChangeHeight(newheight);
695 for (
size_t i = 0; i <
Walls.size(); i++)
700 bool result =
Walls[i]->ReplaceTexture(oldtexture, newtexture);
714 for (
size_t i = 0; i <
Walls.size(); i++)
719 bool result =
Walls[i]->ChangeTexture(texture, matcheck);
731 for (
size_t i = 0; i <
Walls.size(); i++)
736 for (
size_t j = 0; j <
Walls[i]->GetPolygonCount(); j++)
743 for (
size_t k = 0; k < poly->
geometry.size(); k++)
745 for (
size_t l = 0; l < poly->
geometry[k].size(); l++)
769 for (
size_t i = 0; i <
Walls.size(); i++)
774 for (
size_t j = 0; j <
Walls[i]->GetPolygonCount(); j++)
781 for (
size_t k = 0; k < poly->
triangles.size(); k++)
788 std::pair<bool, Real> result = Ogre::Math::intersects(ray, tri_a, tri_b, tri_c);
789 if (result.first ==
true)
817 if (
Walls.size() == 0)
826 OgreBulletCollisions::TriangleMeshCollisionShape* shape =
new OgreBulletCollisions::TriangleMeshCollisionShape(vcount, tricount * 3);
833 for (
size_t i = 0; i <
Walls.size(); i++)
838 for (
size_t j = 0; j <
Walls[i]->GetPolygonCount(); j++)
847 for (
size_t k = 0; k < poly->
geometry.size(); k++)
849 for (
size_t l = 0; l < poly->
geometry[k].size(); l++)
850 polyarray.emplace_back(poly->
geometry[k][l].vertex);
853 for (
size_t k = 0; k < poly->
triangles.size(); k++)
868 shape->AddTriangle(a, b, c);
906 catch (Ogre::Exception &e)
908 ReportError(
"Error creating collider for '" +
name +
"'\n" + e.getDescription());
923 mBody->removeFromWorld();
942 if (coord < 1 || coord > 3)
945 for (
size_t i = 0; i <
Walls.size(); i++)
950 for (
size_t j = 0; j <
Walls[i]->GetPolygonCount(); j++)
957 for (
size_t k = 0; k < poly->
geometry.size(); k++)
959 for (
size_t l = 0; l < poly->
geometry[k].size(); l++)
961 Ogre::Vector3 vertex = poly->
geometry[k][l].vertex;
964 tempnum = poly->
geometry[k][l].vertex.x;
966 tempnum = poly->
geometry[k][l].vertex.y;
970 tempnum = poly->
geometry[k][l].vertex.z;
972 tempnum = -poly->
geometry[k][l].vertex.z;
982 if (tempnum < esmall)
1000 for (
size_t i = 0; i <
Walls.size(); i++)
1022 if (
Bounds->isNull() ==
true)
1028 if (position.x >= min.x && position.x <= max.x && position.z >= min.z && position.z <= max.z)
1030 if (check_y ==
false)
1034 if (position.y >= min.y && position.y <= max.y)
1050 bool added_shared =
false;
1051 size_t current_offset = 0;
1052 size_t shared_offset = 0;
1053 size_t next_offset = 0;
1054 size_t index_offset = 0;
1056 vertex_count = index_count = 0;
1059 for (
unsigned short i = 0; i < mesh->getNumSubMeshes(); i++)
1061 Ogre::SubMesh* submesh = mesh->getSubMesh(i);
1064 if (submesh->useSharedVertices)
1068 vertex_count += (int)mesh->sharedVertexData->vertexCount;
1069 added_shared =
true;
1074 vertex_count += (int)submesh->vertexData->vertexCount;
1078 index_count += (int)submesh->indexData->indexCount;
1082 if (index_count < 3)
1086 vertices =
new Vector3[vertex_count];
1087 indices =
new unsigned long[index_count];
1089 added_shared =
false;
1092 for (
unsigned short i = 0; i < mesh->getNumSubMeshes(); i++)
1094 Ogre::SubMesh* submesh = mesh->getSubMesh(i);
1095 Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
1097 if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared))
1099 if(submesh->useSharedVertices)
1101 added_shared =
true;
1102 shared_offset = current_offset;
1105 const Ogre::VertexElement* posElem =
1106 vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
1108 Ogre::HardwareVertexBufferSharedPtr vbuf =
1109 vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
1111 unsigned char* vertex =
1112 static_cast<unsigned char*
>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
1116 for (
size_t j = 0; j < vertex_data->vertexCount; j++, vertex += vbuf->getVertexSize())
1118 posElem->baseVertexPointerToElement(vertex, &pReal);
1119 Vector3 pt(pReal[0], pReal[1], pReal[2]);
1122 extents.merge(vertices[current_offset + j]);
1126 next_offset += vertex_data->vertexCount;
1129 Ogre::IndexData* index_data = submesh->indexData;
1130 size_t numTris = index_data->indexCount / 3;
1131 Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
1133 bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
1135 unsigned long* pLong =
static_cast<unsigned long*
>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
1136 unsigned short* pShort =
reinterpret_cast<unsigned short*
>(pLong);
1138 size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset;
1140 if (use32bitindexes)
1142 for (
size_t k = 0; k < numTris * 3; k++)
1144 indices[index_offset++] = pLong[k] +
static_cast<unsigned long>(offset);
1149 for (
size_t k = 0; k < numTris * 3; k++)
1151 indices[index_offset++] =
static_cast<unsigned long>(pShort[k]) +
static_cast<unsigned long>(offset);
1156 current_offset = next_offset;
1162 unsigned int total = 0;
1164 for (
size_t i = 0; i <
Walls.size(); i++)
1167 total +=
Walls[i]->GetVertexCount();
1175 unsigned int tris = 0;
1177 for (
size_t i = 0; i <
Walls.size(); i++)
1181 for (
int j = 0; j <
Walls[i]->GetPolygonCount(); j++)
1187 if (poly->
material == material || (material ==
"" && total ==
true))
1226 int vertex_count, index_count;
1228 long unsigned int* indices;
1229 Ogre::AxisAlignedBox box;
1234 Ogre::MeshManager::getSingleton().remove(
collidermesh->getHandle());
1252 for (
size_t i = 0; i <
Walls.size(); i++)
1257 for (
size_t j = 0; j <
Walls[i]->GetPolygonCount(); j++)
void UpdateVertices(MeshObject *client, const std::string &material="", Polygon *polygon=0, bool single=false)
void NeedsUpdate(MeshObject *client=0)
void EnableDebugView(bool value, MeshObject *client=0)
void SetMaterial(const std::string &material)
void RemoveClient(MeshObject *mesh)
void AddClient(MeshObject *mesh)
void DetachClient(MeshObject *client)
bool LoadFromMesh(const std::string &meshname)
void EnableShadows(bool value)
Ogre::AxisAlignedBox GetBounds(MeshObject *client=0)
bool IsVisible(MeshObject *client=0)
void Enabled(bool value, MeshObject *client=0)
bool LoadFromFile(const std::string &filename, const std::string &path)
OgreBulletCollisions::CollisionShape * mShape
void EnableShadows(bool value)
bool LoadFromMesh(const std::string &meshname)
Vector3 GetWallExtents(const std::string &name, Real altitude, bool get_max)
std::vector< Wall * > Walls
Wall * GetWallByName(std::string name)
void EnableDebugView(bool value)
bool InBoundingBox(const Vector3 &pos, bool check_y)
void OnRotate(bool parent)
void Cut(Vector3 start, Vector3 end, bool cutwalls, bool cutfloors, int checkwallnumber=0, bool reset_check=true)
bool LoadColliderModel(Ogre::MeshPtr &collidermesh)
Vector2 GetExtents(int coord, bool flip_z=false)
Real HitBeam(const Vector3 &origin, const Vector3 &direction, Real max_distance)
unsigned int GetVertexCount()
void GetMeshInformation(const Ogre::Mesh *const mesh, int &vertex_count, Vector3 *&vertices, int &index_count, unsigned long *&indices, Ogre::AxisAlignedBox &extents)
bool ChangeTexture(const std::string &texture, bool matcheck=true)
void SetMaterial(const std::string &material)
void Prepare(bool force=false)
Ogre::MeshPtr collidermesh
void EnableCollider(bool value)
void ChangeHeight(Real newheight)
Wall * FindPolygon(const std::string &name, int &index)
unsigned int GetTriangleCount(const std::string &material, bool total)
Vector3 GetPoint(const std::string &wallname, const Vector3 &start, const Vector3 &end)
void CutOutsideBounds(Vector3 start, Vector3 end, bool cutwalls, bool cutfloors)
bool LoadFromFile(const std::string &filename)
bool ReplaceTexture(const std::string &oldtexture, const std::string &newtexture)
bool UsingDynamicBuffers()
OgreBulletDynamics::RigidBody * mBody
Ogre::AxisAlignedBox * Bounds
void CreateColliderFromModel(int &vertex_count, Vector3 *&vertices, int &index_count, unsigned long *&indices)
DynamicMesh * MeshWrapper
Wall * CreateWallObject(const std::string &name)
SceneNode * collider_node
void EnablePhysics(bool value, Real restitution=0, Real friction=0, Real mass=0)
DynamicMesh * GetDynamicMesh()
MeshObject(Object *parent, const std::string &name, DynamicMesh *wrapper=0, const std::string &filename="", const std::string &meshname="", Real max_render_distance=0, Real scale_multiplier=1, bool create_collider=true, bool dynamic_buffers=false)
bool IsVisible(Ogre::Camera *camera)
const std::string & GetName()
virtual bool ReportError(const std::string &message)
virtual void Report(const std::string &message)
virtual Vector3 GetPosition(bool relative=false)
SceneNode * GetSceneNode()
void SetValues(const std::string &type, const std::string &name, bool is_permanent, bool is_movable=true)
std::vector< Triangle > triangles
Vector3 GetVertex(int index)
void DeleteMeshHandle(MeshObject *handle)
void AddMeshHandle(MeshObject *handle)
std::string GetMountPath(std::string filename, std::string &newfilename)
OgreBulletDynamics::DynamicsWorld * mWorld
Real ToLocal(Real remote_value)
bool GetConfigBool(const std::string &key, bool default_value)
Real ToRemote(Real local_value)
std::string VerifyFile(const std::string &filename)
Ogre::SceneNode * GetRawSceneNode()
SceneNode * CreateChild(std::string name, const Vector3 &offset=Vector3::ZERO)
void SetScale(Real scale)
std::string GetFullName()
void Cut(Wall *wall, Vector3 start, Vector3 end, bool cutwalls, bool cutfloors, int checkwallnumber=0, bool reset_check=true)
int FindPolygon(const std::string &name)
Vector3 GetWallExtents(Real altitude, bool get_max)
void DeletePolygons(bool recreate_collider=true)
Vector3 GetPoint(const Vector3 &start, const Vector3 &end)
std::vector< Vector3 > PolyArray
void SetCase(std::string &string, bool uppercase)
std::string SetCaseCopy(std::string string, bool uppercase)
bool StartsWith(const std::string &string, const std::string &check_string, bool ignore_case)
void TrimString(std::string &string)
#define SBS_PROFILE(name)