123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- /***************************************************************************
- Shape3D.cpp - description
- -------------------
- begin : Wed Jan 26 2000
- copyright : (C) 2000 by Henrik Enqvist
- email : henqvist@excite.com
- ***************************************************************************/
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "Private.h"
- #include "Shape3D.h"
- #include "Polygon.h"
- Shape3D::Shape3D(int v, int p) {
- m_iProperties = 0;
- p_Parent = NULL;
- m_vPolygon.reserve(p);
- m_vVtxSrc.reserve(v);
- m_vVtxTrans.reserve(v);
- m_vVtxAlign.reserve(v);
- m_vNmlSrc.reserve(v);
- m_vNmlTrans.reserve(v);
- m_vNmlAlign.reserve(v);
- m_vLight.reserve(v);
- m_vSpecular.reserve(v);
- m_vColor.reserve(v);
- m_vLitColor.reserve(v);
- m_vTexCoord.reserve(v);
- m_Texture = NULL;
- }
- Shape3D::~Shape3D() {
- vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
- vector<Polygon3D*>::iterator end = m_vPolygon.end();
- for ( ; iter != end; iter++) {
- delete (*iter);
- }
- m_vPolygon.clear();
- }
- void Shape3D::setPolygonProperty(int p) {
- vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
- vector<Polygon3D*>::iterator end = m_vPolygon.end();
- for ( ; iter != end; iter++) {
- (*iter)->setProperty(p);
- }
- }
- void Shape3D::unsetPolygonProperty(int p) {
- vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
- vector<Polygon3D*>::iterator end = m_vPolygon.end();
- for ( ; iter != end; iter++) {
- (*iter)->unsetProperty(p);
- }
- }
- void Shape3D::setProperty(int p) {
- m_iProperties |= p;
- }
- void Shape3D::unsetProperty(int p) {
- m_iProperties -= (m_iProperties & p);
- }
- void Shape3D::setParent(Group* p) {
- p_Parent = p;
- }
- void Shape3D::setTexture(EmTexture* tex) {
- m_Texture = tex;
- }
- /*
- * Adds a vertex to this shape. The index of the vertices will be the
- * same as the order they are added.
- */
- int Shape3D::add(float x, float y, float z) {
- this->add(x, y, z, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f);
- return m_vVtxSrc.size() - 1;
- }
- int Shape3D::add(float x, float y, float z, float r, float g, float b, float a, float u, float v) {
- EM_COUT("Shape3D::add() "<< x <<" "<< y <<" "<< z, 0);
- Vertex3D vtx;
- vtx.x = x;
- vtx.y = y;
- vtx.z = z;
- m_vVtxSrc.push_back(vtx);
- // Add dummy values to trans and align, i.e. allocate space
- m_vVtxTrans.push_back(vtx);
- m_vVtxAlign.push_back(vtx);
- // Add dummy values to normals, i.e. allocate space
- m_vNmlSrc.push_back(vtx);
- m_vNmlTrans.push_back(vtx);
- m_vNmlAlign.push_back(vtx);
- Color color = {1.0f, 1.0f, 1.0f, 1.0f};
- m_vLight.push_back(color);
- m_vSpecular.push_back(color);
- color.r = r;
- color.g = g;
- color.b = b;
- color.a = a;
- m_vColor.push_back(color);
- m_vLitColor.push_back(color);
- TexCoord texcoord;
- texcoord.u = u;
- texcoord.v = v;
- m_vTexCoord.push_back(texcoord);
- return m_vVtxSrc.size() - 1;
- }
- int Shape3D::addAt(int index, float x, float y, float z,
- float r, float g, float b, float a, float u, float v) {
- if (index < 0 || index >= (signed)m_vVtxSrc.size()) {
- return this->add(x, y, z, r, g, b, a, u, v);
- }
- Vertex3D vtx;
- vtx.x = x;
- vtx.y = y;
- vtx.z = z;
- m_vVtxSrc.insert(m_vVtxSrc.begin()+index, vtx);
- // Add dummy values to trans and align, i.e. allocate space
- m_vVtxTrans.insert(m_vVtxTrans.begin()+index, vtx);
- m_vVtxAlign.insert(m_vVtxAlign.begin()+index, vtx);
- // Add dummy values to normals, i.e. allocate space
- m_vNmlSrc.insert(m_vNmlSrc.begin()+index, vtx);
- m_vNmlTrans.insert(m_vNmlTrans.begin()+index, vtx);
- m_vNmlAlign.insert(m_vNmlAlign.begin()+index, vtx);
- Color color = {1.0f, 1.0f, 1.0f, 1.0f};
- m_vLight.insert(m_vLight.begin()+index, color);
- m_vSpecular.insert(m_vSpecular.begin()+index, color);
- color.r = r;
- color.g = g;
- color.b = b;
- color.a = a;
- m_vColor.insert(m_vColor.begin()+index, color);
- m_vLitColor.insert(m_vLitColor.begin()+index, color);
- TexCoord texcoord;
- texcoord.u = u;
- texcoord.v = v;
- m_vTexCoord.insert(m_vTexCoord.begin()+index, texcoord);
- return index;
- }
- Vertex3D * Shape3D::getVertex3D(int index) {
- if ( index < 0 || index >= (signed)m_vVtxSrc.size() ) {
- return NULL;
- }
- return &(m_vVtxSrc[index]);
- }
- int Shape3D::getVertex3DSize() {
- return m_vVtxSrc.size();
- }
- int Shape3D::getVertex3DIndex(Vertex3D * vtx) {
- if (vtx == NULL) return -1;
- vector<Vertex3D>::iterator iter = m_vVtxSrc.begin();
- vector<Vertex3D>::iterator end = m_vVtxSrc.end();
- for (int a=0; iter != end; iter++, a++) {
- if (&(*iter) == vtx) return a;
- }
- return -1;
- }
- int Shape3D::getVertex3DIndex(TexCoord * tex) {
- if (tex == NULL) return -1;
- vector<TexCoord>::iterator iter = m_vTexCoord.begin();
- vector<TexCoord>::iterator end = m_vTexCoord.end();
- for (int a=0; iter != end; iter++, a++) {
- if (&(*iter) == tex) return a;
- }
- return -1;
- }
- Color * Shape3D::getColor(int index) {
- if (index < 0 || index >= (signed)m_vColor.size()) {
- return NULL;
- }
- return &(m_vColor[index]);
- }
- void Shape3D::setColor(int index, float r, float g, float b, float a) {
- if (index < 0 || index >= (signed)m_vColor.size()) {
- return;
- }
- m_vColor[index].r = EM_MAX(EM_MIN(r, 1.0f), 0.0f);
- m_vColor[index].g = EM_MAX(EM_MIN(g, 1.0f), 0.0f);
- m_vColor[index].b = EM_MAX(EM_MIN(b, 1.0f), 0.0f);
- m_vColor[index].a = EM_MAX(EM_MIN(a, 1.0f), 0.0f);
- }
- TexCoord * Shape3D::getTexCoord(int index) {
- if (index < 0 || index >= (signed)m_vTexCoord.size()) {
- return NULL;
- }
- return &(m_vTexCoord[index]);
- }
- void Shape3D::setTexCoord(int index, float u, float v) {
- if (index < 0 || index >= (signed)m_vTexCoord.size()) {
- return;
- }
- m_vTexCoord[index].u = u;
- m_vTexCoord[index].v = v;
- }
- bool Shape3D::removeLooseVertex3D(int vtxindex) {
- if (vtxindex < 0 || vtxindex >= (signed)m_vVtxSrc.size()) return false;
- // check that the vertex is not included in any polygon
- vector<Polygon3D*>::iterator polyiter = m_vPolygon.begin();
- vector<Polygon3D*>::iterator polyend = m_vPolygon.end();
- for (; polyiter != polyend; ++polyiter) {
- if ((*polyiter)->includes(vtxindex) >= 0) return false;
- }
- m_vVtxSrc.erase(m_vVtxSrc.begin()+vtxindex);
- m_vVtxTrans.erase(m_vVtxTrans.begin()+vtxindex);
- m_vVtxAlign.erase(m_vVtxAlign.begin()+vtxindex);
- m_vNmlSrc.erase(m_vNmlSrc.begin()+vtxindex);
- m_vNmlTrans.erase(m_vNmlTrans.begin()+vtxindex);
- m_vNmlAlign.erase(m_vNmlAlign.begin()+vtxindex);
-
- // decrement each index above vtxindex
- polyiter = m_vPolygon.begin();
- polyend = m_vPolygon.end();
- for (; polyiter != polyend; ++polyiter) {
- (*polyiter)->decrement(vtxindex);
- }
- return true;
- }
- Polygon3D * Shape3D::getPolygon(int index) {
- if ( index < 0 || index >= (signed)m_vPolygon.size() ) {
- return NULL;
- }
- return m_vPolygon[index];
- }
- int Shape3D::getPolygonSize() {
- return m_vPolygon.size();
- }
- int Shape3D::getPolygonIndex(Polygon3D * poly) {
- if (poly == NULL) return -1;
- vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
- vector<Polygon3D*>::iterator end = m_vPolygon.end();
- for (int a=0; iter != end; iter++, a++) {
- if ((*iter) == poly) return a;
- }
- return -1;
- }
- void Shape3D::removePolygon(Polygon3D * poly) {
- if (poly == NULL) return;
- vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
- vector<Polygon3D*>::iterator end = m_vPolygon.end();
- for (; iter != end; iter++) {
- if ((*iter) == poly) {
- m_vPolygon.erase(iter);
- return;
- }
- }
- }
- int Shape3D::find(float x, float y, float z, float diff) {
- vector<Vertex3D>::iterator iter = m_vVtxSrc.begin();
- vector<Vertex3D>::iterator end = m_vVtxSrc.end();
- for (int a=0; iter != end; iter++, a++) {
- if ((*iter).x < x+diff && (*iter).x > x-diff &&
- (*iter).y < y+diff && (*iter).y > y-diff &&
- (*iter).z < z+diff && (*iter).z > z-diff)
- return a;
- }
- return -1;
- }
- void Shape3D::add(Polygon3D* p) {
- if (p == NULL) return;
- m_vPolygon.push_back(p);
- }
- /* Sets all polygons to color c. */
- void Shape3D::setColor(float r, float g, float b, float a) {
- vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
- vector<Polygon3D*>::iterator end = m_vPolygon.end();
-
- for ( ; iter != end; iter++) {
- (*iter)->setColor(r,g,b,a);
- }
- }
- /* Counts normals for all vertices in Shape3D. */
- void Shape3D::countNormals() {
- vector<Vertex3D>::iterator nmlIter = m_vNmlSrc.begin();
- vector<Vertex3D>::iterator nmlEnd = m_vNmlSrc.end();
- for (int a=0; nmlIter != nmlEnd; nmlIter++, a++) {
- (*nmlIter).x = 0;
- (*nmlIter).y = 0;
- (*nmlIter).z = 0;
- // Get the avrage of all normals in which the vertex resides.
- vector<Polygon3D*>::iterator polyIter = m_vPolygon.begin();
- vector<Polygon3D*>::iterator polyEnd = m_vPolygon.end();
- for (; polyIter != polyEnd; polyIter++) {
- if ((*polyIter)->includes(a) >= 0) {
- (*nmlIter).x += (*polyIter)->m_nmlSrc.x;
- (*nmlIter).y += (*polyIter)->m_nmlSrc.y;
- (*nmlIter).z += (*polyIter)->m_nmlSrc.z;
- }
- }
- if ( EM_ZERO((*nmlIter).x) &&
- EM_ZERO((*nmlIter).y) &&
- EM_ZERO((*nmlIter).z) ) {
- (*nmlIter).y = 1;
- }
-
- EMath::normalizeVector((*nmlIter));
- }
- }
- float Shape3D::getCollisionSize() {
- float size = 0;
- vector<Vertex3D>::iterator iter = m_vVtxSrc.begin();
- vector<Vertex3D>::iterator end = m_vVtxSrc.end();
- for ( ; iter != end; iter++) {
- if (EM_ABS((*iter).x) > size) size = EM_ABS((*iter).x);
- if (EM_ABS((*iter).y) > size) size = EM_ABS((*iter).y);
- if (EM_ABS((*iter).z) > size) size = EM_ABS((*iter).z);
- }
- return size;
- }
|