1 /***************************************************************************
2 Shape3D.cpp - description
3 -------------------
4 begin : Wed Jan 26 2000
5 copyright : (C) 2000 by Henrik Enqvist
6 email : henqvist@excite.com
7 ***************************************************************************/
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12
13 #include "Private.h"
14 #include "Shape3D.h"
15 #include "Polygon.h"
16
Shape3D(int v,int p)17 Shape3D::Shape3D(int v, int p) {
18 m_iProperties = 0;
19 p_Parent = NULL;
20 m_vPolygon.reserve(p);
21
22 m_vVtxSrc.reserve(v);
23 m_vVtxTrans.reserve(v);
24 m_vVtxAlign.reserve(v);
25
26 m_vNmlSrc.reserve(v);
27 m_vNmlTrans.reserve(v);
28 m_vNmlAlign.reserve(v);
29
30 m_vLight.reserve(v);
31 m_vSpecular.reserve(v);
32
33 m_vColor.reserve(v);
34 m_vLitColor.reserve(v);
35 m_vTexCoord.reserve(v);
36
37 m_Texture = NULL;
38 }
39
~Shape3D()40 Shape3D::~Shape3D() {
41 vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
42 vector<Polygon3D*>::iterator end = m_vPolygon.end();
43 for ( ; iter != end; iter++) {
44 delete (*iter);
45 }
46 m_vPolygon.clear();
47 }
48
setPolygonProperty(int p)49 void Shape3D::setPolygonProperty(int p) {
50 vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
51 vector<Polygon3D*>::iterator end = m_vPolygon.end();
52 for ( ; iter != end; iter++) {
53 (*iter)->setProperty(p);
54 }
55 }
56
unsetPolygonProperty(int p)57 void Shape3D::unsetPolygonProperty(int p) {
58 vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
59 vector<Polygon3D*>::iterator end = m_vPolygon.end();
60 for ( ; iter != end; iter++) {
61 (*iter)->unsetProperty(p);
62 }
63 }
64
setProperty(int p)65 void Shape3D::setProperty(int p) {
66 m_iProperties |= p;
67 }
68
unsetProperty(int p)69 void Shape3D::unsetProperty(int p) {
70 m_iProperties -= (m_iProperties & p);
71 }
72
setParent(Group * p)73 void Shape3D::setParent(Group* p) {
74 p_Parent = p;
75 }
76
setTexture(EmTexture * tex)77 void Shape3D::setTexture(EmTexture* tex) {
78 m_Texture = tex;
79 }
80
81 /*
82 * Adds a vertex to this shape. The index of the vertices will be the
83 * same as the order they are added.
84 */
add(float x,float y,float z)85 int Shape3D::add(float x, float y, float z) {
86 this->add(x, y, z, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f);
87 return m_vVtxSrc.size() - 1;
88 }
89
add(float x,float y,float z,float r,float g,float b,float a,float u,float v)90 int Shape3D::add(float x, float y, float z, float r, float g, float b, float a, float u, float v) {
91 EM_COUT("Shape3D::add() "<< x <<" "<< y <<" "<< z, 0);
92
93 Vertex3D vtx;
94 vtx.x = x;
95 vtx.y = y;
96 vtx.z = z;
97 m_vVtxSrc.push_back(vtx);
98 // Add dummy values to trans and align, i.e. allocate space
99 m_vVtxTrans.push_back(vtx);
100 m_vVtxAlign.push_back(vtx);
101 // Add dummy values to normals, i.e. allocate space
102 m_vNmlSrc.push_back(vtx);
103 m_vNmlTrans.push_back(vtx);
104 m_vNmlAlign.push_back(vtx);
105
106 Color color = {1.0f, 1.0f, 1.0f, 1.0f};
107 m_vLight.push_back(color);
108 m_vSpecular.push_back(color);
109
110 color.r = r;
111 color.g = g;
112 color.b = b;
113 color.a = a;
114 m_vColor.push_back(color);
115 m_vLitColor.push_back(color);
116 TexCoord texcoord;
117 texcoord.u = u;
118 texcoord.v = v;
119 m_vTexCoord.push_back(texcoord);
120
121 return m_vVtxSrc.size() - 1;
122 }
123
addAt(int index,float x,float y,float z,float r,float g,float b,float a,float u,float v)124 int Shape3D::addAt(int index, float x, float y, float z,
125 float r, float g, float b, float a, float u, float v) {
126 if (index < 0 || index >= (signed)m_vVtxSrc.size()) {
127 return this->add(x, y, z, r, g, b, a, u, v);
128 }
129
130 Vertex3D vtx;
131 vtx.x = x;
132 vtx.y = y;
133 vtx.z = z;
134 m_vVtxSrc.insert(m_vVtxSrc.begin()+index, vtx);
135 // Add dummy values to trans and align, i.e. allocate space
136 m_vVtxTrans.insert(m_vVtxTrans.begin()+index, vtx);
137 m_vVtxAlign.insert(m_vVtxAlign.begin()+index, vtx);
138 // Add dummy values to normals, i.e. allocate space
139 m_vNmlSrc.insert(m_vNmlSrc.begin()+index, vtx);
140 m_vNmlTrans.insert(m_vNmlTrans.begin()+index, vtx);
141 m_vNmlAlign.insert(m_vNmlAlign.begin()+index, vtx);
142
143 Color color = {1.0f, 1.0f, 1.0f, 1.0f};
144 m_vLight.insert(m_vLight.begin()+index, color);
145 m_vSpecular.insert(m_vSpecular.begin()+index, color);
146
147 color.r = r;
148 color.g = g;
149 color.b = b;
150 color.a = a;
151 m_vColor.insert(m_vColor.begin()+index, color);
152 m_vLitColor.insert(m_vLitColor.begin()+index, color);
153 TexCoord texcoord;
154 texcoord.u = u;
155 texcoord.v = v;
156 m_vTexCoord.insert(m_vTexCoord.begin()+index, texcoord);
157
158 return index;
159 }
160
161
162
getVertex3D(int index)163 Vertex3D * Shape3D::getVertex3D(int index) {
164 if ( index < 0 || index >= (signed)m_vVtxSrc.size() ) {
165 return NULL;
166 }
167 return &(m_vVtxSrc[index]);
168 }
169
getVertex3DSize()170 int Shape3D::getVertex3DSize() {
171 return m_vVtxSrc.size();
172 }
173
getVertex3DIndex(Vertex3D * vtx)174 int Shape3D::getVertex3DIndex(Vertex3D * vtx) {
175 if (vtx == NULL) return -1;
176 vector<Vertex3D>::iterator iter = m_vVtxSrc.begin();
177 vector<Vertex3D>::iterator end = m_vVtxSrc.end();
178 for (int a=0; iter != end; iter++, a++) {
179 if (&(*iter) == vtx) return a;
180 }
181 return -1;
182 }
183
getVertex3DIndex(TexCoord * tex)184 int Shape3D::getVertex3DIndex(TexCoord * tex) {
185 if (tex == NULL) return -1;
186 vector<TexCoord>::iterator iter = m_vTexCoord.begin();
187 vector<TexCoord>::iterator end = m_vTexCoord.end();
188 for (int a=0; iter != end; iter++, a++) {
189 if (&(*iter) == tex) return a;
190 }
191 return -1;
192 }
193
getColor(int index)194 Color * Shape3D::getColor(int index) {
195 if (index < 0 || index >= (signed)m_vColor.size()) {
196 return NULL;
197 }
198 return &(m_vColor[index]);
199 }
200
setColor(int index,float r,float g,float b,float a)201 void Shape3D::setColor(int index, float r, float g, float b, float a) {
202 if (index < 0 || index >= (signed)m_vColor.size()) {
203 return;
204 }
205 m_vColor[index].r = EM_MAX(EM_MIN(r, 1.0f), 0.0f);
206 m_vColor[index].g = EM_MAX(EM_MIN(g, 1.0f), 0.0f);
207 m_vColor[index].b = EM_MAX(EM_MIN(b, 1.0f), 0.0f);
208 m_vColor[index].a = EM_MAX(EM_MIN(a, 1.0f), 0.0f);
209 }
210
getTexCoord(int index)211 TexCoord * Shape3D::getTexCoord(int index) {
212 if (index < 0 || index >= (signed)m_vTexCoord.size()) {
213 return NULL;
214 }
215 return &(m_vTexCoord[index]);
216 }
217
setTexCoord(int index,float u,float v)218 void Shape3D::setTexCoord(int index, float u, float v) {
219 if (index < 0 || index >= (signed)m_vTexCoord.size()) {
220 return;
221 }
222 m_vTexCoord[index].u = u;
223 m_vTexCoord[index].v = v;
224 }
225
removeLooseVertex3D(int vtxindex)226 bool Shape3D::removeLooseVertex3D(int vtxindex) {
227 if (vtxindex < 0 || vtxindex >= (signed)m_vVtxSrc.size()) return false;
228 // check that the vertex is not included in any polygon
229 vector<Polygon3D*>::iterator polyiter = m_vPolygon.begin();
230 vector<Polygon3D*>::iterator polyend = m_vPolygon.end();
231 for (; polyiter != polyend; ++polyiter) {
232 if ((*polyiter)->includes(vtxindex) >= 0) return false;
233 }
234
235 m_vVtxSrc.erase(m_vVtxSrc.begin()+vtxindex);
236 m_vVtxTrans.erase(m_vVtxTrans.begin()+vtxindex);
237 m_vVtxAlign.erase(m_vVtxAlign.begin()+vtxindex);
238 m_vNmlSrc.erase(m_vNmlSrc.begin()+vtxindex);
239 m_vNmlTrans.erase(m_vNmlTrans.begin()+vtxindex);
240 m_vNmlAlign.erase(m_vNmlAlign.begin()+vtxindex);
241
242 // decrement each index above vtxindex
243 polyiter = m_vPolygon.begin();
244 polyend = m_vPolygon.end();
245 for (; polyiter != polyend; ++polyiter) {
246 (*polyiter)->decrement(vtxindex);
247 }
248 return true;
249 }
250
getPolygon(int index)251 Polygon3D * Shape3D::getPolygon(int index) {
252 if ( index < 0 || index >= (signed)m_vPolygon.size() ) {
253 return NULL;
254 }
255 return m_vPolygon[index];
256 }
257
getPolygonSize()258 int Shape3D::getPolygonSize() {
259 return m_vPolygon.size();
260 }
261
getPolygonIndex(Polygon3D * poly)262 int Shape3D::getPolygonIndex(Polygon3D * poly) {
263 if (poly == NULL) return -1;
264 vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
265 vector<Polygon3D*>::iterator end = m_vPolygon.end();
266 for (int a=0; iter != end; iter++, a++) {
267 if ((*iter) == poly) return a;
268 }
269 return -1;
270 }
271
removePolygon(Polygon3D * poly)272 void Shape3D::removePolygon(Polygon3D * poly) {
273 if (poly == NULL) return;
274 vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
275 vector<Polygon3D*>::iterator end = m_vPolygon.end();
276 for (; iter != end; iter++) {
277 if ((*iter) == poly) {
278 m_vPolygon.erase(iter);
279 return;
280 }
281 }
282 }
283
find(float x,float y,float z,float diff)284 int Shape3D::find(float x, float y, float z, float diff) {
285 vector<Vertex3D>::iterator iter = m_vVtxSrc.begin();
286 vector<Vertex3D>::iterator end = m_vVtxSrc.end();
287 for (int a=0; iter != end; iter++, a++) {
288 if ((*iter).x < x+diff && (*iter).x > x-diff &&
289 (*iter).y < y+diff && (*iter).y > y-diff &&
290 (*iter).z < z+diff && (*iter).z > z-diff)
291 return a;
292 }
293 return -1;
294 }
295
add(Polygon3D * p)296 void Shape3D::add(Polygon3D* p) {
297 if (p == NULL) return;
298 m_vPolygon.push_back(p);
299 }
300
301 /* Sets all polygons to color c. */
setColor(float r,float g,float b,float a)302 void Shape3D::setColor(float r, float g, float b, float a) {
303 vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
304 vector<Polygon3D*>::iterator end = m_vPolygon.end();
305
306 for ( ; iter != end; iter++) {
307 (*iter)->setColor(r,g,b,a);
308 }
309 }
310
311 /* Counts normals for all vertices in Shape3D. */
countNormals()312 void Shape3D::countNormals() {
313 vector<Vertex3D>::iterator nmlIter = m_vNmlSrc.begin();
314 vector<Vertex3D>::iterator nmlEnd = m_vNmlSrc.end();
315 for (int a=0; nmlIter != nmlEnd; nmlIter++, a++) {
316 (*nmlIter).x = 0;
317 (*nmlIter).y = 0;
318 (*nmlIter).z = 0;
319 // Get the avrage of all normals in which the vertex resides.
320 vector<Polygon3D*>::iterator polyIter = m_vPolygon.begin();
321 vector<Polygon3D*>::iterator polyEnd = m_vPolygon.end();
322 for (; polyIter != polyEnd; polyIter++) {
323 if ((*polyIter)->includes(a) >= 0) {
324 (*nmlIter).x += (*polyIter)->m_nmlSrc.x;
325 (*nmlIter).y += (*polyIter)->m_nmlSrc.y;
326 (*nmlIter).z += (*polyIter)->m_nmlSrc.z;
327 }
328 }
329 if ( EM_ZERO((*nmlIter).x) &&
330 EM_ZERO((*nmlIter).y) &&
331 EM_ZERO((*nmlIter).z) ) {
332 (*nmlIter).y = 1;
333 }
334
335 EMath::normalizeVector((*nmlIter));
336 }
337 }
338
getCollisionSize()339 float Shape3D::getCollisionSize() {
340 float size = 0;
341
342 vector<Vertex3D>::iterator iter = m_vVtxSrc.begin();
343 vector<Vertex3D>::iterator end = m_vVtxSrc.end();
344 for ( ; iter != end; iter++) {
345 if (EM_ABS((*iter).x) > size) size = EM_ABS((*iter).x);
346 if (EM_ABS((*iter).y) > size) size = EM_ABS((*iter).y);
347 if (EM_ABS((*iter).z) > size) size = EM_ABS((*iter).z);
348 }
349
350 return size;
351 }
352