Skyscraper 2.0
wall.cpp
Go to the documentation of this file.
1/*
2 Scalable Building Simulator - Wall Object
3 The Skyscraper Project - Version 2.0
4 Copyright (C)2004-2024 Ryan Thoryk
5 https://www.skyscrapersim.net
6 https://sourceforge.net/projects/skyscraper/
7 Contact - ryan@skyscrapersim.net
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22*/
23
24#include "globals.h"
25#include "sbs.h"
26#include "mesh.h"
27#include "polygon.h"
28#include "polymesh.h"
29#include "triangle.h"
30#include "texture.h"
31#include "profiler.h"
32#include "utility.h"
33#include "wall.h"
34
35namespace SBS {
36
37Wall::Wall(MeshObject* wrapper) : Object(wrapper)
38{
39 //wall object constructor
40 meshwrapper = wrapper;
41 parent_array = 0;
42
43 sbs->WallCount++;
44}
45
47{
48 //wall object destructor
49
50 if (sbs->FastDelete == false && parent_array && parent_deleting == false)
51 {
52 for (size_t i = 0; i < parent_array->size(); i++)
53 {
54 if (parent_array->at(i) == this)
55 {
56 parent_array->erase(parent_array->begin() + i);
57 break;
58 }
59 }
60 }
61
62 sbs->WallCount--;
63
64 //delete polygons
66}
67
68Polygon* Wall::AddQuad(const std::string &name, const std::string &texture, const Vector3 &v1, const Vector3 &v2, const Vector3 &v3, const Vector3 &v4, Real tw, Real th, bool autosize)
69{
70 //add a quad
71
72 PolyArray vertices;
73 vertices.reserve(4);
74 vertices.emplace_back(v1);
75 vertices.emplace_back(v2);
76 vertices.emplace_back(v3);
77 vertices.emplace_back(v4);
78
79 return AddPolygon(name, texture, vertices, tw, th, autosize);
80}
81
82Polygon* Wall::AddPolygon(const std::string &name, const std::string &texture, PolyArray &vertices, Real tw, Real th, bool autosize)
83{
84 //create a generic polygon
85
86 Matrix3 tm;
87 Vector3 tv;
88 std::vector<Extents> index_extents;
89 std::vector<std::vector<Polygon::Geometry> > geometry;
90 std::vector<Triangle> triangles;
91 PolygonSet converted_vertices;
92 if (!meshwrapper->GetPolyMesh()->CreateMesh(name, texture, vertices, tw, th, autosize, tm, tv, geometry, triangles, converted_vertices))
93 {
94 ReportError("Error creating wall '" + name + "'");
95 return 0;
96 }
97
98 if (triangles.size() == 0)
99 return 0;
100
101 bool result;
102 std::string material = sbs->GetTextureManager()->GetTextureMaterial(texture, result, true, name);
103
104 //compute plane
105 Plane plane = sbs->GetUtility()->ComputePlane(converted_vertices[0]);
106
107 Polygon* poly = new Polygon(this, name, meshwrapper, geometry, triangles, tm, tv, material, plane);
108 polygons.emplace_back(poly);
109 return poly;
110}
111
112Polygon* Wall::AddPolygonSet(const std::string &name, const std::string &material, PolygonSet &vertices, Matrix3 &tex_matrix, Vector3 &tex_vector)
113{
114 //create a set of polygons, providing the original material and texture mapping
115
116 std::vector<std::vector<Polygon::Geometry> > geometry;
117 std::vector<Triangle> triangles;
118 PolygonSet converted_vertices;
119 if (!meshwrapper->GetPolyMesh()->CreateMesh(name, material, vertices, tex_matrix, tex_vector, geometry, triangles, converted_vertices, 0, 0))
120 {
121 ReportError("Error creating wall '" + name + "'");
122 return 0;
123 }
124
125 if (triangles.size() == 0)
126 return 0;
127
128 //compute plane
129 Plane plane = sbs->GetUtility()->ComputePlane(converted_vertices[0]);
130
131 Polygon* poly = new Polygon(this, name, meshwrapper, geometry, triangles, tex_matrix, tex_vector, material, plane);
132 polygons.emplace_back(poly);
133
134 return poly;
135}
136
137void Wall::DeletePolygons(bool recreate_collider)
138{
139 //delete polygons
140
141 for (size_t i = polygons.size() - 1; i < polygons.size(); --i)
142 {
143 delete polygons[i];
144 }
145 polygons.clear();
146
147 //recreate colliders
148 if (recreate_collider == true)
149 {
150 //prepare mesh
152
155 }
156}
157
158void Wall::DeletePolygon(int index, bool recreate_colliders)
159{
160 //delete a single polygon
161
162 if (index > -1 && index < (int)polygons.size())
163 {
164 //delete polygon
165 delete polygons[index];
166 polygons.erase(polygons.begin() + index);
167
168 //recreate colliders if specified
169 if (recreate_colliders == true)
170 {
174 }
175 }
176}
177
179{
180 return (int)polygons.size();
181}
182
184{
185 if (index > -1 && index < (int)polygons.size())
186 return polygons[index];
187 return 0;
188}
189
190int Wall::FindPolygon(const std::string &name)
191{
192 //find a polygon object by name
193
194 SBS_PROFILE("Wall::FindPolygon");
195
196 for (size_t i = 0; i < polygons.size(); i++)
197 {
198 if (name == polygons[i]->GetName())
199 return (int)i;
200 }
201 return -1;
202}
203
204bool Wall::IntersectsWall(Vector3 start, Vector3 end, Vector3 &isect, bool convert)
205{
206 //check through polygons to see if the specified line intersects with this wall object
207
208 SBS_PROFILE("Wall::IntersectsWall");
209 Real pr, best_pr = 2000000000.;
210 int best_i = -1;
211 Vector3 cur_isect, normal;
212
213 if (convert == true)
214 {
215 start = sbs->ToRemote(start);
216 end = sbs->ToRemote(end);
217 }
218
219 for (size_t i = 0; i < polygons.size(); i++)
220 {
221 if (polygons[i]->IntersectSegment(start, end, cur_isect, &pr, normal))
222 {
223 if (pr < best_pr)
224 {
225 best_pr = pr;
226 best_i = (int)i;
227 isect = cur_isect;
228 }
229 }
230 }
231
232 if (best_i > -1)
233 return true;
234
235 return false;
236}
237
238void Wall::Move(const Vector3 &vector, Real speed)
239{
240 //move a wall object
241
242 //move base object
243 Object::Move(vector, speed);
244
245 //move polygons
246 for (size_t i = 0; i < polygons.size(); i++)
247 {
248 polygons[i]->Move(vector, speed);
249 }
250
251 //prepare mesh
252 if (meshwrapper->UsingDynamicBuffers() == false)
253 meshwrapper->Prepare(true);
256}
257
259{
260 return meshwrapper;
261}
262
263void Wall::SetParentArray(std::vector<Wall*> &array)
264{
265 parent_array = &array;
266}
267
268Vector3 Wall::GetPoint(const Vector3 &start, const Vector3 &end)
269{
270 //do a line intersection with this wall, and return the intersection point
271
272 Vector3 isect;
273 Real distance = 2000000000.;
274 Vector3 normal = Vector3::ZERO;
275
276 Wall *result = meshwrapper->GetPolyMesh()->FindWallIntersect(sbs->ToRemote(start), sbs->ToRemote(end), isect, distance, normal, this);
277
278 if (result)
279 return sbs->ToLocal(isect);
280
281 return Vector3(0, 0, 0);
282}
283
284Vector3 Wall::GetWallExtents(Real altitude, bool get_max)
285{
286 //return the X and Z extents of this wall object at a specific altitude, by doing a double plane cut
287
288 for (int i = 0; i < GetPolygonCount(); i++)
289 {
290 PolyArray poly, tmp1, tmp2;
291 for (size_t j = 0; j < polygons[i]->geometry[0].size(); j++)
292 {
293 poly.emplace_back(sbs->ToLocal(polygons[i]->geometry[0][j].vertex));
294 }
295
296 //if given altitude is outside of polygon's range, return 0
297 Vector2 yextents = sbs->GetUtility()->GetExtents(poly, 2);
298 Real tmpaltitude = altitude;
299 if (tmpaltitude < yextents.x || tmpaltitude > yextents.y)
300 return Vector3(0, 0, 0);
301
302 //get upper
303 sbs->GetUtility()->SplitWithPlane(1, poly, tmp1, tmp2, tmpaltitude - 0.001);
304
305 //get lower part of upper
306 sbs->GetUtility()->SplitWithPlane(1, tmp2, poly, tmp1, tmpaltitude + 0.001);
307
308 Vector3 result;
309 if (get_max == false)
310 {
311 //get minimum extents
312 result.x = sbs->GetUtility()->GetExtents(poly, 1).x;
313 result.z = sbs->GetUtility()->GetExtents(poly, 3).x;
314 }
315 else
316 {
317 //get maximum extents
318 result.x = sbs->GetUtility()->GetExtents(poly, 1).y;
319 result.z = sbs->GetUtility()->GetExtents(poly, 3).y;
320 }
321 result.y = altitude;
322 return result; //only check the first polygon for now
323 }
324
325 return Vector3(0, 0, 0);
326}
327
329{
330 //change height of a wall object
331
332 for (size_t i = 0; i < polygons.size(); i++)
333 {
334 polygons[i]->ChangeHeight(newheight);
335 }
336
337 //prepare mesh
338 if (meshwrapper->UsingDynamicBuffers() == false)
339 meshwrapper->Prepare(true);
342}
343
345{
346 unsigned int total = 0;
347 for (size_t i = 0; i < polygons.size(); i++)
348 {
349 total += polygons[i]->vertex_count;
350 }
351 return total;
352}
353
355{
356 unsigned int total = 0;
357 for (size_t i = 0; i < polygons.size(); i++)
358 {
359 total += polygons[i]->triangles.size();
360 }
361 return total;
362}
363
364bool Wall::ReplaceTexture(const std::string &oldtexture, const std::string &newtexture)
365{
366 bool found = false;
367
368 for (int i = 0; i < GetPolygonCount(); i++)
369 {
370 Polygon *poly = GetPolygon(i);
371 bool result = poly->ReplaceTexture(oldtexture, newtexture);
372 if (result == true)
373 found = true;
374 }
375 return found;
376}
377
378bool Wall::ChangeTexture(const std::string &texture, bool matcheck)
379{
380 bool found = false;
381
382 for (int i = 0; i < GetPolygonCount(); i++)
383 {
384 Polygon *poly = GetPolygon(i);
385 bool result = poly->ChangeTexture(texture, matcheck);
386 if (result == true)
387 found = true;
388 }
389 return found;
390}
391
392}
PolyMesh * GetPolyMesh()
Definition mesh.cpp:676
void CreateCollider()
Definition mesh.cpp:802
void Prepare(bool force=false)
Definition mesh.cpp:241
void DeleteCollider()
Definition mesh.cpp:914
bool UsingDynamicBuffers()
Definition mesh.cpp:649
const std::string & GetName()
Definition object.cpp:53
virtual bool ReportError(const std::string &message)
Definition object.cpp:84
bool parent_deleting
Definition object.h:64
virtual void Move(const Vector3 &vector, Real speed=1.0)
Definition object.cpp:253
Wall * FindWallIntersect(const Vector3 &start, const Vector3 &end, Vector3 &isect, Real &distance, Vector3 &normal, Wall *wall=0)
Definition polymesh.cpp:44
bool CreateMesh(const std::string &name, const std::string &texture, PolyArray &vertices, Real tw, Real th, bool autosize, Matrix3 &tex_matrix, Vector3 &tex_vector, std::vector< std::vector< Polygon::Geometry > > &geometry, std::vector< Triangle > &triangles, PolygonSet &converted_vertices)
Definition polymesh.cpp:102
bool ChangeTexture(const std::string &texture, bool matcheck=true)
Definition polygon.cpp:178
bool ReplaceTexture(const std::string &oldtexture, const std::string &newtexture)
Definition polygon.cpp:151
Utility * GetUtility()
Definition sbs.cpp:4611
bool FastDelete
Definition sbs.h:188
TextureManager * GetTextureManager()
Definition sbs.cpp:4558
int WallCount
Definition sbs.h:191
Real ToLocal(Real remote_value)
Definition sbs.cpp:2367
Real ToRemote(Real local_value)
Definition sbs.cpp:2407
std::string GetTextureMaterial(const std::string &name, bool &result, bool report=true, const std::string &polygon_name="")
Definition texture.cpp:906
Vector2 GetExtents(PolyArray &varray, int coord, bool flip_z=false)
Definition utility.cpp:49
void SplitWithPlane(int axis, PolyArray &orig, PolyArray &poly1, PolyArray &poly2, Real value)
Definition texmap.cpp:240
Plane ComputePlane(PolyArray &vertices, bool flip_normal=true)
Definition utility.cpp:504
std::vector< Wall * > * parent_array
Definition wall.h:73
void DeletePolygon(int index, bool recreate_colliders)
Definition wall.cpp:158
int FindPolygon(const std::string &name)
Definition wall.cpp:190
Wall(MeshObject *wrapper)
Definition wall.cpp:37
bool ChangeTexture(const std::string &texture, bool matcheck=true)
Definition wall.cpp:378
Vector3 GetWallExtents(Real altitude, bool get_max)
Definition wall.cpp:284
void DeletePolygons(bool recreate_collider=true)
Definition wall.cpp:137
void SetParentArray(std::vector< Wall * > &array)
Definition wall.cpp:263
std::vector< Polygon * > polygons
Definition wall.h:70
bool IntersectsWall(Vector3 start, Vector3 end, Vector3 &isect, bool convert=true)
Definition wall.cpp:204
unsigned int GetTriangleCount()
Definition wall.cpp:354
void Move(const Vector3 &vector, Real speed=1.0)
Definition wall.cpp:238
void ChangeHeight(Real newheight)
Definition wall.cpp:328
bool ReplaceTexture(const std::string &oldtexture, const std::string &newtexture)
Definition wall.cpp:364
MeshObject * GetMesh()
Definition wall.cpp:258
MeshObject * meshwrapper
Definition wall.h:67
Polygon * GetPolygon(int index)
Definition wall.cpp:183
int GetPolygonCount()
Definition wall.cpp:178
~Wall()
Definition wall.cpp:46
unsigned int GetVertexCount()
Definition wall.cpp:344
Polygon * AddPolygonSet(const std::string &name, const std::string &material, PolygonSet &vertices, Matrix3 &tex_matrix, Vector3 &tex_vector)
Definition wall.cpp:112
Vector3 GetPoint(const Vector3 &start, const Vector3 &end)
Definition wall.cpp:268
Polygon * AddQuad(const std::string &name, const std::string &texture, const Vector3 &v1, const Vector3 &v2, const Vector3 &v3, const Vector3 &v4, Real tw, Real th, bool autosize)
Definition wall.cpp:68
Polygon * AddPolygon(const std::string &name, const std::string &texture, PolyArray &vertices, Real tw, Real th, bool autosize)
Definition wall.cpp:82
Ogre::Matrix3 Matrix3
Definition globals.h:64
Ogre::Vector3 Vector3
Definition globals.h:58
Ogre::Real Real
Definition globals.h:57
Ogre::Plane Plane
Definition globals.h:65
Ogre::Vector2 Vector2
Definition globals.h:59
std::vector< Vector3 > PolyArray
Definition sbs.h:118
std::vector< PolyArray > PolygonSet
Definition sbs.h:119
#define SBS_PROFILE(name)
Definition profiler.h:131