Skyscraper 2.0
polymesh.cpp
Go to the documentation of this file.
1/*
2 Scalable Building Simulator - PolyMesh Geometry Processor
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 "camera.h"
27#include "wall.h"
28#include "texture.h"
29#include "profiler.h"
30#include "utility.h"
31#include "polymesh.h"
32
33namespace SBS {
34
36{
37 this->mesh = mesh;
38}
39
43
44Wall* PolyMesh::FindWallIntersect(const Vector3 &start, const Vector3 &end, Vector3 &isect, Real &distance, Vector3 &normal, Wall *wall)
45{
46 //find a wall from a 3D point
47 //positions need to be in remote (Ogre) positioning
48 //if wall_number is 0 or greater, this will only check that specified wall
49
50 SBS_PROFILE("PolyMesh::FindWallIntersect");
51
52 Real pr, best_pr = 2000000000.;
53 Real dist, best_dist = 2000000000.;
54 int best_i = -1;
55 Vector3 cur_isect;
56 Vector3 tmpnormal;
57
58 for (size_t i = 0; i < mesh->Walls.size(); i++)
59 {
60 if (!mesh->Walls[i])
61 continue;
62
63 if (wall && mesh->Walls[i] != wall)
64 continue;
65
66 for (int j = 0; j < mesh->Walls[i]->GetPolygonCount(); j++)
67 {
68 Polygon *poly = mesh->Walls[i]->GetPolygon(j);
69 if (!poly)
70 continue;
71
72 if (poly->IntersectSegment(start, end, cur_isect, &pr, tmpnormal) == true)
73 {
74 if (pr < best_pr)
75 {
76 //currently test against previous camera intersection test to fix some weird issues
77 Vector3 orig_start = sbs->ToRemote(sbs->camera->HitPosition);
78 dist = orig_start.distance(cur_isect);
79
80 if (dist < best_dist)
81 {
82 //calculate distance to intersection
83 distance = start.distance(cur_isect);
84
85 best_dist = dist;
86 best_pr = pr;
87 best_i = (int)i;
88 isect = cur_isect;
89 normal = tmpnormal;
90 }
91 }
92 }
93 }
94 }
95
96 if (best_i >= 0)
97 return mesh->Walls[best_i];
98 else
99 return 0;
100}
101
102bool PolyMesh::CreateMesh(const std::string &name, const std::string &texture, PolyArray &vertices, Real tw, Real th, bool autosize, Matrix3 &t_matrix, Vector3 &t_vector, std::vector<std::vector<Polygon::Geometry> > &geometry, std::vector<Triangle> &triangles, PolygonSet &converted_vertices)
103{
104 //create custom mesh geometry, apply a texture map and material, and return the created submesh
105
106 //exit if this mesh is a loaded file
107 if (mesh->Filename != "")
108 return ReportError("PolyMesh: Cannot create geometry in a file-loaded mesh");
109
110 //get texture material
111 std::string texname = texture;
112 bool result;
113 std::string material = sbs->GetTextureManager()->GetTextureMaterial(texture, result, true, name);
114 if (!result)
115 texname = "Default";
116
117 //convert to remote positioning
118 converted_vertices.resize(1);
119
120 converted_vertices[0].reserve(vertices.size());
121 for (size_t i = 0; i < vertices.size(); i++)
122 converted_vertices[0].emplace_back(sbs->ToRemote(vertices[i]));
123
124 //texture mapping
125 Vector3 v1, v2, v3;
126 int direction;
127
128 //get texture mapping coordinates
129 if (!sbs->GetTextureManager()->GetTextureMapping(converted_vertices[0], v1, v2, v3, direction))
130 return ReportError("PolyMesh: Texture mapping error");
131
132 if (tw == 0)
133 tw = 1;
134 if (th == 0)
135 th = 1;
136
137 //get autosize information
138 Vector2 sizing (tw, th);
139
140 if (autosize == true)
141 sizing = sbs->GetTextureManager()->CalculateSizing(texname, sbs->ToLocal(v1), sbs->ToLocal(v2), sbs->ToLocal(v3), direction, tw, th);
142
143 //get texture tiling information
144 Real tw2 = sizing.x, th2 = sizing.y;
145 Real mw, mh;
146 if (sbs->GetTextureManager()->GetTextureTiling(texname, mw, mh))
147 {
148 //multiply the tiling parameters (tw and th) by
149 //the stored multipliers for that texture
150 tw2 = sizing.x * mw;
151 th2 = sizing.y * mh;
152 }
153
154 if (!sbs->GetTextureManager()->ComputeTextureMap(t_matrix, t_vector, converted_vertices[0], v1, v2, v3, tw2, th2))
155 return false;
156
157 return CreateMesh(name, material, converted_vertices, t_matrix, t_vector, geometry, triangles, converted_vertices, tw2, th2, false);
158}
159
160bool PolyMesh::CreateMesh(const std::string &name, const std::string &material, PolygonSet &vertices, Matrix3 &tex_matrix, Vector3 &tex_vector, std::vector<std::vector<Polygon::Geometry> > &geometry, std::vector<Triangle> &triangles, PolygonSet &converted_vertices, Real tw, Real th, bool convert_vertices)
161{
162 //create custom geometry, apply a texture map and material, and return the created submesh
163 //tw and th are only used when overriding texel map
164
165 //convert to remote positioning
166 if (convert_vertices == true)
167 {
168 converted_vertices.resize(vertices.size());
169 for (size_t i = 0; i < vertices.size(); i++)
170 {
171 converted_vertices[i].reserve(vertices[i].size());
172 for (size_t j = 0; j < vertices[i].size(); j++)
173 converted_vertices[i].emplace_back(sbs->ToRemote(vertices[i][j]));
174 }
175 }
176 else
177 converted_vertices = vertices;
178
179 //texture mapping
180 size_t texel_count;
181 Vector2 *table = GetTexels(tex_matrix, tex_vector, converted_vertices, tw, th, texel_count);
182
183 //triangulate mesh
184 TriangleIndices *trimesh = new TriangleIndices[converted_vertices.size()];
185 size_t trimesh_size = converted_vertices.size();
186
187 for (size_t i = 0; i < trimesh_size; i++)
188 {
189 //do a (very) simple triangulation
190 //this method also somewhat works with non-planar polygons
191 trimesh[i].triangles.reserve(converted_vertices[i].size() - 2);
192 for (size_t j = 2; j < converted_vertices[i].size(); j++)
193 trimesh[i].triangles.emplace_back(Triangle(0, j - 1, j));
194 }
195
196 //initialize geometry arrays
197 size_t size = 0;
198 geometry.resize(trimesh_size);
199
200 for (size_t i = 0; i < trimesh_size; i++)
201 {
202 geometry[i].resize(converted_vertices[i].size());
203 }
204
205 //populate vertices, normals, and texels for mesh data
206 unsigned int k = 0;
207
208 for (size_t i = 0; i < trimesh_size; i++)
209 {
210 for (size_t j = 0; j < converted_vertices[i].size(); j++)
211 {
212 //calculate normal
213 Vector3 normal = sbs->GetUtility()->ComputePlane(converted_vertices[i], false).normal;
214
215 geometry[i][j].vertex = converted_vertices[i][j];
216 geometry[i][j].normal = normal;
217
218 if (k >= texel_count)
219 return ReportError("PolyMesh: invalid texel index");
220 geometry[i][j].texel = table[k];
221 k++;
222 }
223 }
224
225 //delete texel array
226 if (table)
227 delete [] table;
228 table = 0;
229
230 //add triangles to single array, to be passed to the submesh
231 size_t location = 0;
232 for (size_t i = 0; i < trimesh_size; i++)
233 {
234 if (triangles.capacity() < trimesh[i].triangles.size())
235 triangles.reserve(trimesh[i].triangles.size());
236 for (size_t j = 0; j < trimesh[i].triangles.size(); j++)
237 {
238 Triangle tri = trimesh[i].triangles[j];
239 tri += location;
240 triangles.emplace_back(tri);
241 }
242 location += converted_vertices[i].size();
243 }
244
245 //delete trimesh array
246 delete [] trimesh;
247 trimesh = 0;
248
249 //recreate colliders if specified
250 if (sbs->DeleteColliders == true)
252
253 return true;
254}
255
256Vector2* PolyMesh::GetTexels(Matrix3 &tex_matrix, Vector3 &tex_vector, PolygonSet &vertices, Real tw, Real th, size_t &texel_count)
257{
258 //return texel array for specified texture transformation matrix and vector
259
260 texel_count = 0;
261
262 if (sbs->TexelOverride == false)
263 {
264 //create array for texel map
265 for (size_t i = 0; i < vertices.size(); i++)
266 texel_count += vertices[i].size();
267 Vector2 *texels = new Vector2[texel_count];
268
269 //transform matrix into texel map
270 size_t index = 0;
271 Vector3 texel;
272 for (size_t i = 0; i < vertices.size(); i++)
273 {
274 for (size_t j = 0; j < vertices[i].size(); j++)
275 {
276 texel = tex_matrix * (vertices[i][j] - tex_vector);
277 texels[index].x = texel.x;
278 texels[index].y = texel.y;
279 index++;
280 }
281 }
282 return texels;
283 }
284 else
285 {
286 texel_count = 4;
287 Vector2 *texels = new Vector2[4];
288 texels[0].x = 0;
289 texels[0].y = 0;
290 texels[1].x = tw;
291 texels[1].y = 0;
292 texels[2].x = tw;
293 texels[2].y = th;
294 texels[3].x = 0;
295 texels[3].y = th;
296 return texels;
297 }
298 return 0;
299}
300
301}
Vector3 HitPosition
Definition camera.h:89
std::string Filename
Definition mesh.h:107
std::vector< Wall * > Walls
Definition mesh.h:99
void DeleteCollider()
Definition mesh.cpp:912
virtual bool ReportError(const std::string &message)
Definition object.cpp:84
MeshObject * mesh
Definition polymesh.h:56
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
Vector2 * GetTexels(Matrix3 &tex_matrix, Vector3 &tex_vector, PolygonSet &vertices, Real tw, Real th, size_t &texel_count)
Definition polymesh.cpp:256
PolyMesh(MeshObject *mesh)
Definition polymesh.cpp:35
bool IntersectSegment(const Vector3 &start, const Vector3 &end, Vector3 &isect, Real *pr, Vector3 &normal)
Definition texmap.cpp:440
bool TexelOverride
Definition sbs.h:429
Utility * GetUtility()
Definition sbs.cpp:4641
TextureManager * GetTextureManager()
Definition sbs.cpp:4588
Camera * camera
Definition sbs.h:160
Real ToLocal(Real remote_value)
Definition sbs.cpp:2397
Real ToRemote(Real local_value)
Definition sbs.cpp:2437
bool DeleteColliders
Definition sbs.h:184
bool ComputeTextureMap(Matrix3 &t_matrix, Vector3 &t_vector, PolyArray &vertices, const Vector3 &p1, const Vector3 &p2, const Vector3 &p3, Real tw, Real th)
Definition texmap.cpp:36
bool GetTextureMapping(PolyArray &vertices, Vector3 &v1, Vector3 &v2, Vector3 &v3, int &direction)
Definition texture.cpp:1109
Vector2 CalculateSizing(const std::string &texture, const Vector3 &v1, const Vector3 &v2, const Vector3 &v3, int direction, Real tw, Real th)
Definition texture.cpp:1089
std::string GetTextureMaterial(const std::string &name, bool &result, bool report=true, const std::string &polygon_name="")
Definition texture.cpp:906
bool GetTextureTiling(const std::string &texture, Real &tw, Real &th)
Definition texture.cpp:1002
Plane ComputePlane(PolyArray &vertices, bool flip_normal=true)
Definition utility.cpp:504
Ogre::Matrix3 Matrix3
Definition globals.h:64
Ogre::Vector3 Vector3
Definition globals.h:58
Ogre::Real Real
Definition globals.h:57
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
std::vector< Triangle > triangles
Definition polymesh.h:41