| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 |
- /*
- * PolyMesh.cpp
- * Poly
- *
- * Created by Ivan Safrin on 3/18/08.
- * Copyright 2008 __MyCompanyName__. All rights reserved.
- *
- */
- #include "PolyMesh.h"
- namespace Polycode {
- Mesh::Mesh(String fileName) {
-
- for(int i=0; i < 16; i++) {
- arrayDirtyMap[i] = false;
- renderDataArrays[i] = NULL;
- }
-
- meshType = TRI_MESH;
- numUVs = 1;
- meshHasVertexBuffer = false;
- loadMesh(fileName);
- vertexBuffer = NULL;
- useVertexColors = false;
- }
-
- Mesh::Mesh(int meshType) {
- for(int i=0; i < 16; i++) {
- arrayDirtyMap[i] = false;
- renderDataArrays[i] = NULL;
- }
- this->meshType = meshType;
- meshHasVertexBuffer = false;
- numUVs = 1;
- vertexBuffer = NULL;
- useVertexColors = false;
- }
-
-
- Mesh::~Mesh() {
- for(int i=0; i < vertices.size(); i++) {
- delete vertices[i];
- }
- vertices.clear();
- for(int i=0; i < polygons.size(); i++) {
- delete polygons[i];
- }
- polygons.clear();
- if(vertexBuffer)
- delete vertexBuffer;
-
- for(int i=0; i < 16; i++) {
- if(renderDataArrays[i]) {
- free(renderDataArrays[i]->arrayPtr);
- delete renderDataArrays[i];
- }
- }
- }
-
- VertexBuffer *Mesh::getVertexBuffer() {
- return vertexBuffer;
- }
- void Mesh::setVertexBuffer(VertexBuffer *buffer) {
- vertexBuffer = buffer;
- meshHasVertexBuffer = true;
- }
-
- Number Mesh::getRadius() {
- Number hRad = 0;
- Number len;
- for(int i=0; i < vertices.size(); i++) {
- len = vertices[i]->length();
- if(len > hRad)
- hRad = len;
- }
- return hRad;
- }
-
- void Mesh::saveToFile(OSFILE *outFile) {
- unsigned int numFaces = polygons.size();
- OSBasics::write(&meshType, sizeof(unsigned int), 1, outFile);
- OSBasics::write(&numFaces, sizeof(unsigned int), 1, outFile);
- for(int i=0; i < polygons.size(); i++) {
-
- Vector3_struct pos;
- Vector3_struct nor;
- Vector4_struct col;
- Vector2_struct tex;
-
- for(int j=0; j < polygons[i]->getVertexCount(); j++) {
-
- pos.x = polygons[i]->getVertex(j)->x;
- pos.y = polygons[i]->getVertex(j)->y;
- pos.z = polygons[i]->getVertex(j)->z;
- nor.x = polygons[i]->getVertex(j)->normal.x;
- nor.y = polygons[i]->getVertex(j)->normal.y;
- nor.z = polygons[i]->getVertex(j)->normal.z;
- col.x = polygons[i]->getVertex(j)->vertexColor.r;
- col.y = polygons[i]->getVertex(j)->vertexColor.g;
- col.z = polygons[i]->getVertex(j)->vertexColor.b;
- col.w = polygons[i]->getVertex(j)->vertexColor.a;
-
- tex.x = polygons[i]->getVertex(j)->getTexCoord().x;
- tex.y = polygons[i]->getVertex(j)->getTexCoord().y;
-
- OSBasics::write(&pos, sizeof(Vector3_struct), 1, outFile);
- OSBasics::write(&nor, sizeof(Vector3_struct), 1, outFile);
- OSBasics::write(&col, sizeof(Vector4_struct), 1, outFile);
- OSBasics::write(&tex, sizeof(Vector2_struct), 1, outFile);
-
- unsigned int numBoneWeights = polygons[i]->getVertex(j)->getNumBoneAssignments();
- OSBasics::write(&numBoneWeights, sizeof(unsigned int), 1, outFile);
- for(int b=0; b < numBoneWeights; b++) {
- BoneAssignment *a = polygons[i]->getVertex(j)->getBoneAssignment(b);
- unsigned int boneID = a->boneID;
- float weight = a->weight;
- OSBasics::write(&boneID, sizeof(unsigned int), 1, outFile);
- OSBasics::write(&weight, sizeof(float), 1, outFile);
- }
- }
-
- }
- }
- int Mesh::getVertexIndex(Vertex *vertex) {
- for(int i=0; i < vertices.size(); i++) {
- if(vertex == vertices[i])
- return i;
- }
- return 0;
- }
-
- void Mesh::loadFromFile(OSFILE *inFile) {
- unsigned int meshType;
- OSBasics::read(&meshType, sizeof(unsigned int), 1, inFile);
- setMeshType(meshType);
-
- int verticesPerFace;
- switch(meshType) {
- case TRI_MESH:
- verticesPerFace = 3;
- break;
- case QUAD_MESH:
- verticesPerFace = 4;
- break;
- default:
- verticesPerFace = 1;
- break;
- }
-
- unsigned int numFaces;
- OSBasics::read(&numFaces, sizeof(unsigned int), 1, inFile);
-
- Vector3_struct pos;
- Vector3_struct nor;
- Vector4_struct col;
- Vector2_struct tex;
-
- for(int i=0; i < numFaces; i++) {
- Polygon *poly = new Polygon();
-
- for(int j=0; j < verticesPerFace; j++) {
- OSBasics::read(&pos, sizeof(Vector3_struct), 1, inFile);
- OSBasics::read(&nor, sizeof(Vector3_struct), 1, inFile);
- OSBasics::read(&col, sizeof(Vector4_struct), 1, inFile);
- OSBasics::read(&tex, sizeof(Vector2_struct), 1, inFile);
-
- Vertex *vertex = new Vertex(pos.x, pos.y, pos.z);
- vertex->setNormal(nor.x,nor.y, nor.z);
- vertex->restNormal.set(nor.x,nor.y, nor.z);
- vertex->vertexColor.setColor(col.x,col.y, col.z, col.w);
- vertex->setTexCoord(tex.x, tex.y);
-
- unsigned int numBoneWeights;
- OSBasics::read(&numBoneWeights, sizeof(unsigned int), 1, inFile);
- for(int b=0; b < numBoneWeights; b++) {
- float weight;
- unsigned int boneID;
- OSBasics::read(&boneID, sizeof(unsigned int), 1, inFile);
- OSBasics::read(&weight, sizeof(float), 1, inFile);
- vertex->addBoneAssignment(boneID, weight);
- }
-
-
-
- poly->addVertex(vertex);
- }
- addPolygon(poly);
- }
-
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
-
-
- // int i;
- //
- // Vertex *newVertex;
- // Polygon *polygon;
- // unsigned int numVertices, numFaces, hasWeights, numWeights, numUVs;
- //
- // unsigned int boneID;
- // Number boneWeight;
- //
- // OSBasics::read(&numUVs, sizeof(unsigned int), 1, inFile);
- // OSBasics::read(&numVertices, sizeof(unsigned int), 1, inFile);
- // Vector3_struct pos;
- // Vector3_struct nor;
- // Face_struct face;
- //
- // for(i=0; i<numVertices; i++) {
- // OSBasics::read(&pos, sizeof(Vector3_struct), 1, inFile);
- // OSBasics::read(&nor, sizeof(Vector3_struct), 1, inFile);
- //
- // newVertex = new Vertex(pos.x, pos.y, pos.z, nor.x, nor.y,nor.z);
- //
- // OSBasics::read(&hasWeights, sizeof(unsigned int), 1, inFile);
- // if(hasWeights == 1) {
- // OSBasics::read(&numWeights, sizeof(unsigned int), 1, inFile);
- // for(int j=0; j < numWeights; j++) {
- // OSBasics::read(&boneID, sizeof(unsigned int), 1, inFile);
- // OSBasics::read(&boneWeight, sizeof(Number), 1, inFile);
- // newVertex->addBoneAssignment(boneID, boneWeight);
- // }
- // newVertex->normalizeWeights();
- // }
- // vertices.push_back(newVertex);
- // }
- //
- // OSBasics::read(&numFaces, sizeof(unsigned int), 1, inFile);
- //
- // for(i=0; i<numFaces; i++) {
- // OSBasics::read(&face, sizeof(Face_struct), 1, inFile);
- // polygon = new Polygon();
- // polygon->setNormal(Vector3(face.nx,face.ny,face.nz));
- //
- // vertices[face.v1]->setTexCoord(face.uvs[0].x,face.uvs[0].y);
- // vertices[face.v2]->setTexCoord(face.uvs[1].x,face.uvs[1].y);
- // vertices[face.v3]->setTexCoord(face.uvs[2].x,face.uvs[2].y);
- //
- // polygon->addTexCoord(face.uvs[0].x,face.uvs[0].y);
- // polygon->addTexCoord(face.uvs[1].x,face.uvs[1].y);
- // polygon->addTexCoord(face.uvs[2].x,face.uvs[2].y);
- // polygon->setUseFaceUV(true);
- //
- // if(numUVs == 2) {
- // Vector2_struct uv2s[3];
- // OSBasics::read(uv2s, sizeof(Vector2_struct), 3, inFile);
- // polygon->addTexCoord2(uv2s[0].x,uv2s[0].y);
- // polygon->addTexCoord2(uv2s[1].x,uv2s[1].y);
- // polygon->addTexCoord2(uv2s[2].x,uv2s[2].y);
- // }
- //
- // polygons.push_back(polygon);
- // }
- // this->numUVs = numUVs;
- }
-
- void Mesh::loadMesh(String fileName) {
- OSFILE *inFile = OSBasics::open(fileName.c_str(), "rb");
- if(!inFile) {
- Logger::log("Error opening mesh file %s", fileName.c_str());
- }
- loadFromFile(inFile);
- OSBasics::close(inFile);
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
-
- }
-
- void Mesh::createPlane(Number w, Number h) {
- Polygon *imagePolygon = new Polygon();
- imagePolygon->addVertex(0,0,0,0,1);
- imagePolygon->addVertex(w,0,0, 1, 1);
- imagePolygon->addVertex(w,h,0, 1, 0);
- imagePolygon->addVertex(0,h,0,0,0);
- addPolygon(imagePolygon);
-
- for(int i=0; i < polygons.size(); i++) {
- for(int j=0; j < polygons[i]->getVertexCount(); j++) {
- polygons[i]->getVertex(j)->x = polygons[i]->getVertex(j)->x - (w/2.0f);
- polygons[i]->getVertex(j)->y = polygons[i]->getVertex(j)->y - (h/2.0f);
- }
- }
- calculateNormals();
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
-
- }
-
- void Mesh::addVertex(Vertex* vertex) {
- vertices.push_back(vertex);
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- }
-
- unsigned int Mesh::getNumVertices() {
- return vertices.size();
- }
-
- Vertex *Mesh::getVertex(unsigned int index) {
- return vertices[index];
- }
-
- Vector3 Mesh::recenterMesh() {
- Vector3 positiveOffset;
- Vector3 negativeOffset;
-
- for(int i=0; i < polygons.size(); i++) {
- for(int j=0; j < polygons[i]->getVertexCount(); j++) {
- positiveOffset.x = max(positiveOffset.x,polygons[i]->getVertex(j)->x);
- positiveOffset.y = max(positiveOffset.y,polygons[i]->getVertex(j)->y);
- positiveOffset.z = max(positiveOffset.z,polygons[i]->getVertex(j)->z);
-
- }
- }
-
- for(int i=0; i < polygons.size(); i++) {
- for(int j=0; j < polygons[i]->getVertexCount(); j++) {
- negativeOffset.x = min(negativeOffset.x,polygons[i]->getVertex(j)->x);
- negativeOffset.y = min(negativeOffset.y,polygons[i]->getVertex(j)->y);
- negativeOffset.z = min(negativeOffset.z,polygons[i]->getVertex(j)->z);
-
- }
- }
-
- Vector3 finalOffset;
-
- finalOffset.x = (positiveOffset.x + negativeOffset.x)/2.0f;
- finalOffset.y = (positiveOffset.y + negativeOffset.y)/2.0f;
- finalOffset.z = (positiveOffset.z + negativeOffset.z)/2.0f;
-
- vector<Vertex*> done;
- for(int i=0; i < polygons.size(); i++) {
- for(int j=0; j < polygons[i]->getVertexCount(); j++) {
-
- bool alreadyDone = false;
- for(int k=0; k < done.size(); k++) {
- if(done[k] == polygons[i]->getVertex(j))
- alreadyDone = true;
- }
-
- if(!alreadyDone) {
- polygons[i]->getVertex(j)->x = polygons[i]->getVertex(j)->x - finalOffset.x;
- polygons[i]->getVertex(j)->y = polygons[i]->getVertex(j)->y - finalOffset.y;
- polygons[i]->getVertex(j)->z = polygons[i]->getVertex(j)->z - finalOffset.z;
- done.push_back(polygons[i]->getVertex(j));
- }
- }
- }
-
-
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
-
- return finalOffset;
- }
-
- Vector3 Mesh::calculateBBox() {
- Vector3 retVec;
-
- for(int i=0; i < polygons.size(); i++) {
- for(int j=0; j < polygons[i]->getVertexCount(); j++) {
- retVec.x = max(retVec.x,fabs(polygons[i]->getVertex(j)->x));
- retVec.y = max(retVec.y,fabs(polygons[i]->getVertex(j)->y));
- retVec.z = max(retVec.z,fabs(polygons[i]->getVertex(j)->z));
-
- }
- }
-
- return retVec*2;
- }
-
- void Mesh::createSphere(Number radius, Number numRings, Number numSegments) {
- Number fDeltaRingAngle = (PI / numRings);
- Number fDeltaSegAngle = (2 * PI / numSegments);
-
- for(int i=0; i < numRings; i++) {
- Number r0 = radius * sinf (i * fDeltaRingAngle);
- Number y0 = radius * cosf (i * fDeltaRingAngle);
- for(int j=0; j < numSegments; j++) {
- Number x0 = r0 * sinf(j * fDeltaSegAngle);
- Number z0 = r0 * cosf(j * fDeltaSegAngle);
-
- Number tx0 = (Number) j / (Number) numSegments;
- Number tx1 = (Number) i / (Number) numRings;
-
- Vector3 nor = Vector3(x0, y0, z0);
- nor.Normalize();
-
-
- }
- }
-
- useVertexNormals(true);
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
-
- }
- void Mesh::createBox(Number w, Number d, Number h) {
- Polygon *polygon = new Polygon();
- polygon->addVertex(w,0,h, 1, 1);
- polygon->addVertex(0,0,h, 1, 0);
- polygon->addVertex(0,0,0,0,0);
- polygon->addVertex(w,0,0,0,1);
- addPolygon(polygon);
- polygon = new Polygon();
- polygon->addVertex(w,d,h, 1, 1);
- polygon->addVertex(w,d,0, 1, 0);
- polygon->addVertex(0,d,0,0,0);
- polygon->addVertex(0,d,h,0,1);
- addPolygon(polygon);
- polygon = new Polygon();
- polygon->addVertex(0,d,0,0,1);
- polygon->addVertex(w,d,0, 1, 1);
- polygon->addVertex(w,0,0, 1, 0);
- polygon->addVertex(0,0,0,0,0);
- addPolygon(polygon);
- polygon = new Polygon();
- polygon->addVertex(0,0,h,0,0);
- polygon->addVertex(w,0,h, 1, 0);
- polygon->addVertex(w,d,h, 1, 1);
- polygon->addVertex(0,d,h,0,1);
- addPolygon(polygon);
- polygon = new Polygon();
- polygon->addVertex(0,0,h,0,1);
- polygon->addVertex(0,d,h, 1, 1);
- polygon->addVertex(0,d,0, 1, 0);
- polygon->addVertex(0,0,0,0,0);
- addPolygon(polygon);
- polygon = new Polygon();
- polygon->addVertex(w,0,h,0,1);
- polygon->addVertex(w,0,0, 1, 1);
- polygon->addVertex(w,d,0, 1, 0);
- polygon->addVertex(w,d,h,0,0);
- addPolygon(polygon);
- for(int i=0; i < polygons.size(); i++) {
- for(int j=0; j < polygons[i]->getVertexCount(); j++) {
- polygons[i]->getVertex(j)->x = polygons[i]->getVertex(j)->x - (w/2.0f);
- polygons[i]->getVertex(j)->y = polygons[i]->getVertex(j)->y - (d/2.0f);
- polygons[i]->getVertex(j)->z = polygons[i]->getVertex(j)->z - (h/2.0f);
- }
- }
- calculateNormals();
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- }
-
- void Mesh::useVertexNormals(bool val) {
- for(int i =0; i < polygons.size(); i++) {
- polygons[i]->useVertexNormals = val;
- }
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- }
-
- void Mesh::calculateNormals() {
- for(int i =0; i < polygons.size(); i++) {
- polygons[i]->calculateNormal();
- }
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- }
-
- int Mesh::getMeshType() {
- return meshType;
- }
-
- void Mesh::setMeshType(int newType) {
- meshType = newType;
- }
-
- void Mesh::addPolygon(Polygon *newPolygon) {
- polygons.push_back(newPolygon);
- arrayDirtyMap[RenderDataArray::VERTEX_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::COLOR_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
- arrayDirtyMap[RenderDataArray::NORMAL_DATA_ARRAY] = true;
- }
-
-
- unsigned int Mesh::getPolygonCount() {
- return polygons.size();
- }
-
- Polygon *Mesh::getPolygon(unsigned int index) {
- return polygons[index];
- }
- }
|