//! Basic Mesh class for the "sju" physics engine /*! * The mesh base class implements a non-movable mesh intended mainly for * terrains and other scenery structures. Its functionality will probably be * extended in the near future. */ /* Copyright (C) 2008-2010 Alejandro Valenzuela Roca, * * This file is part of MotorJ, a free framework for videogame creation. * * * MotorJ is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MotorJ is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with MotorJ. If not, see . */ #include "pmesh-class.h" pMesh::pMesh() { cGeometry = CG_MESH; cGeometryData = NULL; collStatuses = NULL; objectInteractionEffect = PE_C_IMMOVABLE; triangleCount = 0; v3_0(&v); v3_0(&a); v3_0(&rotv); v3_0(&rota); hasCollision = true; hasGravitation = false; hasGravity = false; hasCharge = false; } pMesh::~pMesh() { } vector3** pMesh::CreateTriangleArray(float width, int HowManyPoints) { triangle ** trArray; // The resulting triangle array will be stored here int t, tx, tz; float xzorigin = -width/2.0; // Origin in GL units float x, z; float dxz = width/(float)HowManyPoints; x = z = xzorigin; // Create a grid of vectors; min value for howmanypoints is 2 vector3 ** veclist = new vector3 * [HowManyPoints]; for (tx = 0; tx < HowManyPoints; tx++) { veclist[tx] = new vector3 [HowManyPoints]; x = xzorigin; for (tz = 0; tz < HowManyPoints; tz++) { veclist[tx][tz].x = x; veclist[tx][tz].y = 0; veclist[tx][tz].z = z; x += dxz; } z += dxz; } // Create the corresponding triangle structure trArray = new triangle * [2*(HowManyPoints-1)*(HowManyPoints-1)]; t = 0; for (tz = 0; tz < HowManyPoints-1; tz++) { for (tx = 0; tx < HowManyPoints-1; tx++) { trArray[t] = new triangle; trArray[t]->v0 = &veclist[tx][tz]; trArray[t]->v1 = &veclist[tx+1][tz]; trArray[t]->v2 = &veclist[tx][tz+1]; trArray[t]->n = new vector3; calc_normal(*trArray[t], trArray[t]->n); t++; trArray[t] = new triangle; trArray[t]->v0 = &veclist[tx+1][tz+1]; trArray[t]->v1 = &veclist[tx][tz+1]; trArray[t]->v2 = &veclist[tx+1][tz]; trArray[t]->n = new vector3; calc_normal(*trArray[t], trArray[t]->n); t++; } } trArray[t] = NULL; // NULL-terminate the array SetMesh(trArray); return veclist; } void pMesh::ApplyEffect(vector3 effect, vector3 &pointOfAction, sjuPETypes effectType, IPhysicalObject* interactionObject) { // This is a static, immovable mesh. No response is performed on collision. } void pMesh::Update(float t_elapsed) { // This is a static, immovable mesh. No response is performed on collision. } void pMesh::SetMesh(triangle ** mesh) { unsigned ctriangle = 0; while (mesh[ctriangle]) { if (mesh[ctriangle]->n == NULL) { mesh[ctriangle]->n = new vector3; calc_normal(* mesh[ctriangle], mesh[ctriangle]->n); //printf("Normal[%d]: %f, %f, %f \n",ctriangle, mesh[ctriangle]->n->x, //mesh[ctriangle]->n->y, mesh[ctriangle]->n->z); } ctriangle++; } triangleCount = ctriangle; collStatuses = new char * [triangleCount]; for (ctriangle = 0; ctriangle < triangleCount; ctriangle++) { collStatuses[ctriangle] = new char [1]; // Create space for "itself" collStatuses[ctriangle][0] = COLR_NOCOLLISION; } cGeometryData = (void *) mesh; } void pMesh::OnNewObjectAdded(std::list& objects) { int i; int t; char * oldCollStatuses; if (collStatuses) { for (t = 0; t < triangleCount; t++) { oldCollStatuses = collStatuses[t]; // Conserve current collStatus data collStatuses[t] = new char [objects.size()]; // Make room for new object data // Copy over collStatus data for (i = 0; i < objects.size()-1; i++) { collStatuses[t][i] = oldCollStatuses[i]; } //printf("collStatuses[%d][%d]: %d\n",t,i, cMesh->collStatuses[t][i]); delete [] oldCollStatuses; } } for (t = 0; t < triangleCount; t++) { collStatuses[t][objects.size()-1] = COLR_NOCOLLISION; } } void pMesh::OnObjectDeleted(unsigned posInList, std::list& objects) { int i; int t; int j = 0; char * oldCollStatuses; for (t = 0; t < triangleCount; t++) { oldCollStatuses = collStatuses[t]; // Conserve current collStatus data collStatuses[t] = new char [objects.size()-1]; // Make room for rearranged object data // Copy over collStatus data for (i = 0; i < objects.size(); i++) { // Step around the object being deleted.. if (i != posInList) { collStatuses[t][i] = oldCollStatuses[j]; j++; } } //printf("collStatuses[%d][%d]: %d\n",t,i, cMesh->collStatuses[t][i]); delete [] oldCollStatuses; } } void * pMesh::GetRelevantCollisionData(vector3 pos) { return cGeometryData; } void pMesh::RecalcNormals() { // Recalculate the collision data's normals triangle ** mesh = (triangle**) cGeometryData; int t = 0; while (mesh[t] != NULL) { calc_normal(*mesh[t], mesh[t]->n); t++; } }