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 Vector2 *table = GetTexels(tex_matrix, tex_vector, converted_vertices, tw, th);
181
182 //triangulate mesh
183 TriangleIndices *trimesh = new TriangleIndices[converted_vertices.size()];
184 size_t trimesh_size = converted_vertices.size();
185
186 for (size_t i = 0; i < trimesh_size; i++)
187 {
188 //do a (very) simple triangulation
189 //this method also somewhat works with non-planar polygons
190 trimesh[i].triangles.reserve(converted_vertices[i].size() - 2);
191 for (size_t j = 2; j < converted_vertices[i].size(); j++)
192 trimesh[i].triangles.emplace_back(Triangle(0, j - 1, j));
193 }
194
195 //initialize geometry arrays
196 size_t size = 0;
197 geometry.resize(trimesh_size);
198
199 for (size_t i = 0; i < trimesh_size; i++)
200 {
201 geometry[i].resize(converted_vertices[i].size());
202 }
203
204 //populate vertices, normals, and texels for mesh data
205 unsigned int k = 0;
206
207 for (size_t i = 0; i < trimesh_size; i++)
208 {
209 for (size_t j = 0; j < converted_vertices[i].size(); j++)
210 {
211 //calculate normal
212 Vector3 normal = sbs->GetUtility()->ComputePlane(converted_vertices[i], false).normal;
213
214 geometry[i][j].vertex = converted_vertices[i][j];
215 geometry[i][j].normal = normal;
216 geometry[i][j].texel = table[k];
217 k++;
218 }
219 }
220
221 //delete texel array
222 if (table)
223 delete [] table;
224 table = 0;
225
226 //add triangles to single array, to be passed to the submesh
227 size_t location = 0;
228 for (size_t i = 0; i < trimesh_size; i++)
229 {
230 if (triangles.capacity() < trimesh[i].triangles.size())
231 triangles.reserve(trimesh[i].triangles.size());
232 for (size_t j = 0; j < trimesh[i].triangles.size(); j++)
233 {
234 Triangle tri = trimesh[i].triangles[j];
235 tri += location;
236 triangles.emplace_back(tri);
237 }
238 location += converted_vertices[i].size();
239 }
240
241 //delete trimesh array
242 delete [] trimesh;
243 trimesh = 0;
244
245 //recreate colliders if specified
246 if (sbs->DeleteColliders == true)
248
249 return true;
250}
251
252Vector2* PolyMesh::GetTexels(Matrix3 &tex_matrix, Vector3 &tex_vector, PolygonSet &vertices, Real tw, Real th)
253{
254 //return texel array for specified texture transformation matrix and vector
255
256 if (sbs->TexelOverride == false)
257 {
258 //create array for texel map
259 size_t texel_count = 0;
260 for (size_t i = 0; i < vertices.size(); i++)
261 texel_count += vertices[i].size();
262 Vector2 *texels = new Vector2[texel_count];
263
264 //transform matrix into texel map
265 size_t index = 0;
266 Vector3 texel_temp;
267 for (size_t i = 0; i < vertices.size(); i++)
268 {
269 for (size_t j = 0; j < vertices[i].size(); j++)
270 {
271 texel_temp = tex_matrix * (vertices[i][j] - tex_vector);
272 texels[index].x = texel_temp.x;
273 texels[index].y = texel_temp.y;
274 index++;
275 }
276 }
277 return texels;
278 }
279 else
280 {
281 Vector2 *texels = new Vector2[4];
282 texels[0].x = 0;
283 texels[0].y = 0;
284 texels[1].x = tw;
285 texels[1].y = 0;
286 texels[2].x = tw;
287 texels[2].y = th;
288 texels[3].x = 0;
289 texels[3].y = th;
290 return texels;
291 }
292 return 0;
293}
294
295}
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:914
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)
Definition polymesh.cpp:252
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:427
Utility * GetUtility()
Definition sbs.cpp:4611
TextureManager * GetTextureManager()
Definition sbs.cpp:4558
Camera * camera
Definition sbs.h:160
Real ToLocal(Real remote_value)
Definition sbs.cpp:2367
Real ToRemote(Real local_value)
Definition sbs.cpp:2407
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