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();
215 Walls.emplace_back(wall);
225 for (
size_t i = 0; i <
Walls.size(); i++)
247 if (
prepared ==
true && force ==
false)
254 for (
size_t i = 0; i <
Walls.size(); i++)
259 for (
size_t j = 0; j <
Walls[i]->polygons.size(); j++)
265 for (
size_t k = 0; k < poly->
geometry.size(); k++)
267 for (
size_t l = 0; l < poly->
geometry[k].size(); l++)
303 OgreBulletCollisions::TriangleMeshCollisionShape* shape =
new OgreBulletCollisions::TriangleMeshCollisionShape(vertex_count, index_count);
306 for (
int i = 0; i < index_count; i += 3)
308 shape->AddTriangle(vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]]);
323 catch (Ogre::Exception &e)
325 ReportError(
"Error creating model collider for '" +
name +
"'\n" + e.getDescription());
348 if (
Bounds->isNull() ==
true)
352 OgreBulletCollisions::BoxCollisionShape* shape =
new OgreBulletCollisions::BoxCollisionShape(bounds);
366 catch (Ogre::Exception &e)
368 ReportError(
"Error creating box collider for '" +
name +
"'\n" + e.getDescription());
376 for (
size_t i = 0; i <
Walls.size(); i++)
395 for (
size_t i = 0; i <
Walls.size(); i++)
443 mBody->updateTransform(
true,
false,
false);
459 mBody->updateTransform(
false,
true,
false);
480 if (
Bounds->isNull() ==
true)
486 Ogre::AxisAlignedBox global_box (pos + min, pos + max);
488 return camera->isVisible(global_box);
502 if (
Bounds->isNull() ==
true)
503 return Vector3::ZERO;
515 for (
size_t i = 0; i <
Walls.size(); i++)
526 Real limit = 1000000;
528 Vector3 left_min (-limit, -limit, -limit);
529 Vector3 left_max (start.x, limit, limit);
530 Vector3 right_min (end.x, -limit, -limit);
531 Vector3 right_max (limit, limit, limit);
532 Vector3 front_min (-limit, -limit, -limit);
533 Vector3 front_max (limit, limit, start.z);
534 Vector3 back_min (-limit, -limit, end.z);
535 Vector3 back_max (limit, limit, limit);
537 Cut(left_min, left_max, cutwalls, cutfloors);
538 Cut(right_min, right_max, cutwalls, cutfloors);
539 Cut(front_min, front_max, cutwalls, cutfloors);
540 Cut(back_min, back_max, cutwalls, cutfloors);
547 std::string filename1 =
"data/";
548 filename1.append(filename);
556 matname = filename2.substr(0, filename2.length() - 5) +
".material";
558 Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(matname2, path);
559 Report(
"Loading material script " + matname2);
560 Ogre::MaterialManager::getSingleton().parseScript(stream, path);
565 while(!stream->eof())
567 std::string line = stream->getLine();
569 if (
StartsWith(line,
"material",
true) ==
true)
571 std::vector<std::string> vec = Ogre::StringUtil::split(line,
" \t:");
572 for (std::vector<std::string>::iterator it = vec.begin(); it < vec.end(); ++it)
574 std::string match = (*it);
578 Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().getByName(match, path);
581 Report(
"Loading material " + match);
586 materialPtr->setLightingEnabled(
false);
589 materialPtr->setLightingEnabled(
true);
600 catch (Ogre::Exception &e)
602 ReportError(
"Error loading material file " + matname +
"\n" + e.getDescription());
619 std::string filename1 =
"data/";
627 std::string colname2;
631 std::string colname = filename2.substr(0, filename2.length() - 5) +
".collider.mesh";
633 collidermesh = Ogre::MeshManager::getSingleton().load(colname2, path);
635 catch (Ogre::Exception &e)
637 return ReportError(
"No collider model for " + colname2 +
"\n" + e.getDescription());
660 for (
size_t i = 0; i <
Walls.size(); i++)
665 Walls[i]->ChangeHeight(newheight);
697 for (
size_t i = 0; i <
Walls.size(); i++)
702 bool result =
Walls[i]->ReplaceTexture(oldtexture, newtexture);
716 for (
size_t i = 0; i <
Walls.size(); i++)
721 bool result =
Walls[i]->ChangeTexture(texture, matcheck);
733 for (
size_t i = 0; i <
Walls.size(); i++)
738 for (
size_t j = 0; j <
Walls[i]->GetPolygonCount(); j++)
745 for (
size_t k = 0; k < poly->
geometry.size(); k++)
747 for (
size_t l = 0; l < poly->
geometry[k].size(); l++)
771 for (
size_t i = 0; i <
Walls.size(); i++)
776 for (
size_t j = 0; j <
Walls[i]->GetPolygonCount(); j++)
783 for (
size_t k = 0; k < poly->
triangles.size(); k++)
790 std::pair<bool, Real> result = Ogre::Math::intersects(ray, tri_a, tri_b, tri_c);
791 if (result.first ==
true)
819 if (
Walls.size() == 0)
828 OgreBulletCollisions::TriangleMeshCollisionShape* shape =
new OgreBulletCollisions::TriangleMeshCollisionShape(vcount, tricount * 3);
835 for (
size_t i = 0; i <
Walls.size(); i++)
840 for (
size_t j = 0; j <
Walls[i]->GetPolygonCount(); j++)
849 for (
size_t k = 0; k < poly->
geometry.size(); k++)
851 for (
size_t l = 0; l < poly->
geometry[k].size(); l++)
852 polyarray.emplace_back(poly->
geometry[k][l].vertex);
855 for (
size_t k = 0; k < poly->
triangles.size(); k++)
870 shape->AddTriangle(a, b, c);
908 catch (Ogre::Exception &e)
910 ReportError(
"Error creating collider for '" +
name +
"'\n" + e.getDescription());
925 mBody->removeFromWorld();
944 if (coord < 1 || coord > 3)
947 for (
size_t i = 0; i <
Walls.size(); i++)
952 for (
size_t j = 0; j <
Walls[i]->GetPolygonCount(); j++)
959 for (
size_t k = 0; k < poly->
geometry.size(); k++)
961 for (
size_t l = 0; l < poly->
geometry[k].size(); l++)
963 Ogre::Vector3 vertex = poly->
geometry[k][l].vertex;
966 tempnum = poly->
geometry[k][l].vertex.x;
968 tempnum = poly->
geometry[k][l].vertex.y;
972 tempnum = poly->
geometry[k][l].vertex.z;
974 tempnum = -poly->
geometry[k][l].vertex.z;
984 if (tempnum < esmall)
1002 for (
size_t i = 0; i <
Walls.size(); i++)
1024 if (
Bounds->isNull() ==
true)
1030 if (position.x >= min.x && position.x <= max.x && position.z >= min.z && position.z <= max.z)
1032 if (check_y ==
false)
1036 if (position.y >= min.y && position.y <= max.y)
1052 bool added_shared =
false;
1053 size_t current_offset = 0;
1054 size_t shared_offset = 0;
1055 size_t next_offset = 0;
1056 size_t index_offset = 0;
1058 vertex_count = index_count = 0;
1061 for (
unsigned short i = 0; i < mesh->getNumSubMeshes(); i++)
1063 Ogre::SubMesh* submesh = mesh->getSubMesh(i);
1066 if (submesh->useSharedVertices)
1070 vertex_count += (int)mesh->sharedVertexData->vertexCount;
1071 added_shared =
true;
1076 vertex_count += (int)submesh->vertexData->vertexCount;
1080 index_count += (int)submesh->indexData->indexCount;
1084 if (index_count < 3)
1088 vertices =
new Vector3[vertex_count];
1089 indices =
new unsigned long[index_count];
1091 added_shared =
false;
1094 for (
unsigned short i = 0; i < mesh->getNumSubMeshes(); i++)
1096 Ogre::SubMesh* submesh = mesh->getSubMesh(i);
1097 Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
1099 if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared))
1101 if(submesh->useSharedVertices)
1103 added_shared =
true;
1104 shared_offset = current_offset;
1107 const Ogre::VertexElement* posElem =
1108 vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
1110 Ogre::HardwareVertexBufferSharedPtr vbuf =
1111 vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
1113 unsigned char* vertex =
1114 static_cast<unsigned char*
>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
1118 for (
size_t j = 0; j < vertex_data->vertexCount; j++, vertex += vbuf->getVertexSize())
1120 posElem->baseVertexPointerToElement(vertex, &pReal);
1121 Vector3 pt(pReal[0], pReal[1], pReal[2]);
1124 extents.merge(vertices[current_offset + j]);
1128 next_offset += vertex_data->vertexCount;
1131 Ogre::IndexData* index_data = submesh->indexData;
1132 size_t numTris = index_data->indexCount / 3;
1133 Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
1135 bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
1137 unsigned long* pLong =
static_cast<unsigned long*
>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
1138 unsigned short* pShort =
reinterpret_cast<unsigned short*
>(pLong);
1140 size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset;
1142 if (use32bitindexes)
1144 for (
size_t k = 0; k < numTris * 3; k++)
1146 indices[index_offset++] = pLong[k] +
static_cast<unsigned long>(offset);
1151 for (
size_t k = 0; k < numTris * 3; k++)
1153 indices[index_offset++] =
static_cast<unsigned long>(pShort[k]) +
static_cast<unsigned long>(offset);
1158 current_offset = next_offset;
1164 unsigned int total = 0;
1166 for (
size_t i = 0; i <
Walls.size(); i++)
1169 total +=
Walls[i]->GetVertexCount();
1177 unsigned int tris = 0;
1179 for (
size_t i = 0; i <
Walls.size(); i++)
1183 for (
int j = 0; j <
Walls[i]->GetPolygonCount(); j++)
1189 if (poly->
material == material || (material ==
"" && total ==
true))
1228 int vertex_count, index_count;
1230 long unsigned int* indices;
1231 Ogre::AxisAlignedBox box;
1236 Ogre::MeshManager::getSingleton().remove(
collidermesh->getHandle());
1254 for (
size_t i = 0; i <
Walls.size(); i++)
1259 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)
void SetParentArray(std::vector< Wall * > &array)
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)