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, const std::string &name) : Object(wrapper)
38{
39 //wall object constructor
40
41 SetValues("Wall", name, false, true);
42 meshwrapper = wrapper;
43 parent_array = 0;
44
45 if (!meshwrapper)
46 return;
47
49
50 sbs->WallCount++;
51}
52
54{
55 //wall object destructor
56
57 if (sbs->FastDelete == false && parent_array && parent_deleting == false)
58 {
59 for (size_t i = 0; i < parent_array->size(); i++)
60 {
61 if (parent_array->at(i) == this)
62 {
63 parent_array->erase(parent_array->begin() + i);
64 break;
65 }
66 }
67 }
68
69 sbs->WallCount--;
70
71 //delete polygons
73}
74
75Polygon* 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)
76{
77 //add a quad
78
79 PolyArray vertices;
80 vertices.reserve(4);
81 vertices.emplace_back(v1);
82 vertices.emplace_back(v2);
83 vertices.emplace_back(v3);
84 vertices.emplace_back(v4);
85
86 return AddPolygon(name, texture, vertices, tw, th, autosize);
87}
88
89Polygon* Wall::AddPolygon(const std::string &name, const std::string &texture, PolyArray &vertices, Real tw, Real th, bool autosize)
90{
91 //create a generic polygon
92
93 Matrix3 tm;
94 Vector3 tv;
95 std::vector<Extents> index_extents;
96 std::vector<std::vector<Polygon::Geometry> > geometry;
97 std::vector<Triangle> triangles;
98 PolygonSet converted_vertices;
99 if (!meshwrapper->GetPolyMesh()->CreateMesh(name, texture, vertices, tw, th, autosize, tm, tv, geometry, triangles, converted_vertices))
100 {
101 ReportError("Error creating wall '" + name + "'");
102 return 0;
103 }
104
105 if (triangles.size() == 0)
106 return 0;
107
108 bool result;
109 std::string material = sbs->GetTextureManager()->GetTextureMaterial(texture, result, true, name);
110
111 //compute plane
112 Plane plane = sbs->GetUtility()->ComputePlane(converted_vertices[0]);
113
114 Polygon* poly = new Polygon(this, name, meshwrapper, geometry, triangles, tm, tv, material, plane);
115 polygons.emplace_back(poly);
116 return poly;
117}
118
119Polygon* Wall::AddPolygonSet(const std::string &name, const std::string &material, PolygonSet &vertices, Matrix3 &tex_matrix, Vector3 &tex_vector)
120{
121 //create a set of polygons, providing the original material and texture mapping
122
123 std::vector<std::vector<Polygon::Geometry> > geometry;
124 std::vector<Triangle> triangles;
125 PolygonSet converted_vertices;
126 if (!meshwrapper->GetPolyMesh()->CreateMesh(name, material, vertices, tex_matrix, tex_vector, geometry, triangles, converted_vertices, 0, 0))
127 {
128 ReportError("Error creating wall '" + name + "'");
129 return 0;
130 }
131
132 if (triangles.size() == 0)
133 return 0;
134
135 //compute plane
136 Plane plane = sbs->GetUtility()->ComputePlane(converted_vertices[0]);
137
138 Polygon* poly = new Polygon(this, name, meshwrapper, geometry, triangles, tex_matrix, tex_vector, material, plane);
139 polygons.emplace_back(poly);
140
141 return poly;
142}
143
144void Wall::DeletePolygons(bool recreate_collider)
145{
146 //delete polygons
147
148 if (!meshwrapper)
149 return;
150
151 for (size_t i = polygons.size() - 1; i < polygons.size(); --i)
152 {
153 delete polygons[i];
154 }
155 polygons.clear();
156
157 //recreate colliders
158 if (recreate_collider == true)
159 {
160 //prepare mesh
162
165 }
166}
167
168void Wall::DeletePolygon(int index, bool recreate_colliders)
169{
170 //delete a single polygon
171
172 if (!meshwrapper)
173 return;
174
175 if (index > -1 && index < (int)polygons.size())
176 {
177 //delete polygon
178 delete polygons[index];
179 polygons.erase(polygons.begin() + index);
180
181 //recreate colliders if specified
182 if (recreate_colliders == true)
183 {
187 }
188 }
189}
190
192{
193 return (int)polygons.size();
194}
195
197{
198 if (index > -1 && index < (int)polygons.size())
199 {
200 if (polygons[index])
201 return polygons[index];
202 }
203 return 0;
204}
205
206int Wall::FindPolygon(const std::string &name)
207{
208 //find a polygon object by name
209
210 SBS_PROFILE("Wall::FindPolygon");
211
212 for (size_t i = 0; i < polygons.size(); i++)
213 {
214 if (!polygons[i])
215 continue;
216
217 if (name == polygons[i]->GetName())
218 return (int)i;
219 }
220 return -1;
221}
222
223bool Wall::IntersectsWall(Vector3 start, Vector3 end, Vector3 &isect, bool convert)
224{
225 //check through polygons to see if the specified line intersects with this wall object
226
227 SBS_PROFILE("Wall::IntersectsWall");
228 Real pr, best_pr = 2000000000.;
229 int best_i = -1;
230 Vector3 cur_isect, normal;
231
232 if (convert == true)
233 {
234 start = sbs->ToRemote(start);
235 end = sbs->ToRemote(end);
236 }
237
238 for (size_t i = 0; i < polygons.size(); i++)
239 {
240 if (!polygons[i])
241 continue;
242
243 if (polygons[i]->IntersectSegment(start, end, cur_isect, &pr, normal))
244 {
245 if (pr < best_pr)
246 {
247 best_pr = pr;
248 best_i = (int)i;
249 isect = cur_isect;
250 }
251 }
252 }
253
254 if (best_i > -1)
255 return true;
256
257 return false;
258}
259
260void Wall::Move(const Vector3 &vector, Real speed)
261{
262 //move a wall object
263
264 if (!meshwrapper)
265 return;
266
267 //move base object
268 Object::Move(vector, speed);
269
270 //move polygons
271 for (size_t i = 0; i < polygons.size(); i++)
272 {
273 if (polygons[i])
274 polygons[i]->Move(vector, speed);
275 }
276
277 //prepare mesh
278 if (meshwrapper->UsingDynamicBuffers() == false)
279 meshwrapper->Prepare(true);
282}
283
285{
286 return meshwrapper;
287}
288
289void Wall::SetParentArray(std::vector<Wall*> &array)
290{
291 parent_array = &array;
292}
293
294Vector3 Wall::GetPoint(const Vector3 &start, const Vector3 &end)
295{
296 //do a line intersection with this wall, and return the intersection point
297
298 Vector3 isect;
299 Real distance = 2000000000.;
300 Vector3 normal = Vector3::ZERO;
301
302 Wall *result = meshwrapper->GetPolyMesh()->FindWallIntersect(sbs->ToRemote(start), sbs->ToRemote(end), isect, distance, normal, this);
303
304 if (result)
305 return sbs->ToLocal(isect);
306
307 return Vector3(0, 0, 0);
308}
309
310Vector3 Wall::GetWallExtents(Real altitude, bool get_max)
311{
312 //return the X and Z extents of this wall object at a specific altitude, by doing a double plane cut
313
314 Utility* utility = sbs->GetUtility();
315
316 for (int i = 0; i < GetPolygonCount(); i++)
317 {
318 if (!polygons[i])
319 continue;
320
321 PolyArray poly, tmp1, tmp2;
322 for (size_t j = 0; j < polygons[i]->geometry[0].size(); j++)
323 {
324 poly.emplace_back(sbs->ToLocal(polygons[i]->geometry[0][j].vertex));
325 }
326
327 //if given altitude is outside of polygon's range, return 0
328 Vector2 yextents = utility->GetExtents(poly, 2);
329 Real tmpaltitude = altitude;
330 if (tmpaltitude < yextents.x || tmpaltitude > yextents.y)
331 return Vector3(0, 0, 0);
332
333 //get upper
334 utility->SplitWithPlane(1, poly, tmp1, tmp2, tmpaltitude - 0.001);
335
336 //get lower part of upper
337 utility->SplitWithPlane(1, tmp2, poly, tmp1, tmpaltitude + 0.001);
338
339 Vector3 result;
340 if (get_max == false)
341 {
342 //get minimum extents
343 result.x = utility->GetExtents(poly, 1).x;
344 result.z = utility->GetExtents(poly, 3).x;
345 }
346 else
347 {
348 //get maximum extents
349 result.x = utility->GetExtents(poly, 1).y;
350 result.z = utility->GetExtents(poly, 3).y;
351 }
352 result.y = altitude;
353 return result; //only check the first polygon for now
354 }
355
356 return Vector3(0, 0, 0);
357}
358
360{
361 //change height of a wall object
362
363 if (!meshwrapper)
364 return;
365
366 for (size_t i = 0; i < polygons.size(); i++)
367 {
368 if (polygons[i])
369 polygons[i]->ChangeHeight(newheight);
370 }
371
372 //prepare mesh
373 if (meshwrapper->UsingDynamicBuffers() == false)
374 meshwrapper->Prepare(true);
377}
378
380{
381 unsigned int total = 0;
382 for (size_t i = 0; i < polygons.size(); i++)
383 {
384 if (polygons[i])
385 total += polygons[i]->vertex_count;
386 }
387 return total;
388}
389
391{
392 unsigned int total = 0;
393 for (size_t i = 0; i < polygons.size(); i++)
394 {
395 if (polygons[i])
396 total += polygons[i]->triangles.size();
397 }
398 return total;
399}
400
401bool Wall::ReplaceTexture(const std::string &oldtexture, const std::string &newtexture)
402{
403 bool found = false;
404
405 for (int i = 0; i < GetPolygonCount(); i++)
406 {
407 Polygon *poly = GetPolygon(i);
408 if (!poly)
409 continue;
410
411 bool result = poly->ReplaceTexture(oldtexture, newtexture);
412 if (result == true)
413 found = true;
414 }
415 return found;
416}
417
418bool Wall::ChangeTexture(const std::string &texture, bool matcheck)
419{
420 bool found = false;
421
422 for (int i = 0; i < GetPolygonCount(); i++)
423 {
424 Polygon *poly = GetPolygon(i);
425 if (!poly)
426 continue;
427
428 bool result = poly->ChangeTexture(texture, matcheck);
429 if (result == true)
430 found = true;
431 }
432 return found;
433}
434
435}
PolyMesh * GetPolyMesh()
Definition mesh.cpp:674
void CreateCollider()
Definition mesh.cpp:800
std::vector< Wall * > Walls
Definition mesh.h:99
void Prepare(bool force=false)
Definition mesh.cpp:239
void DeleteCollider()
Definition mesh.cpp:912
bool UsingDynamicBuffers()
Definition mesh.cpp:647
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
void SetValues(const std::string &type, const std::string &name, bool is_permanent, bool is_movable=true)
Definition object.cpp:144
virtual void Move(const Vector3 &vector, Real speed=1.0, bool force=false)
Definition object.cpp:259
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:4641
bool FastDelete
Definition sbs.h:188
TextureManager * GetTextureManager()
Definition sbs.cpp:4588
int WallCount
Definition sbs.h:191
Real ToLocal(Real remote_value)
Definition sbs.cpp:2397
Real ToRemote(Real local_value)
Definition sbs.cpp:2437
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:72
void DeletePolygon(int index, bool recreate_colliders)
Definition wall.cpp:168
int FindPolygon(const std::string &name)
Definition wall.cpp:206
bool ChangeTexture(const std::string &texture, bool matcheck=true)
Definition wall.cpp:418
Vector3 GetWallExtents(Real altitude, bool get_max)
Definition wall.cpp:310
void DeletePolygons(bool recreate_collider=true)
Definition wall.cpp:144
Wall(MeshObject *wrapper, const std::string &name)
Definition wall.cpp:37
void SetParentArray(std::vector< Wall * > &array)
Definition wall.cpp:289
std::vector< Polygon * > polygons
Definition wall.h:69
bool IntersectsWall(Vector3 start, Vector3 end, Vector3 &isect, bool convert=true)
Definition wall.cpp:223
unsigned int GetTriangleCount()
Definition wall.cpp:390
void Move(const Vector3 &vector, Real speed=1.0)
Definition wall.cpp:260
void ChangeHeight(Real newheight)
Definition wall.cpp:359
bool ReplaceTexture(const std::string &oldtexture, const std::string &newtexture)
Definition wall.cpp:401
MeshObject * GetMesh()
Definition wall.cpp:284
MeshObject * meshwrapper
Definition wall.h:66
Polygon * GetPolygon(int index)
Definition wall.cpp:196
int GetPolygonCount()
Definition wall.cpp:191
~Wall()
Definition wall.cpp:53
unsigned int GetVertexCount()
Definition wall.cpp:379
Polygon * AddPolygonSet(const std::string &name, const std::string &material, PolygonSet &vertices, Matrix3 &tex_matrix, Vector3 &tex_vector)
Definition wall.cpp:119
Vector3 GetPoint(const Vector3 &start, const Vector3 &end)
Definition wall.cpp:294
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:75
Polygon * AddPolygon(const std::string &name, const std::string &texture, PolyArray &vertices, Real tw, Real th, bool autosize)
Definition wall.cpp:89
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