Initial work on progressive mesh generation. Currently based on Stan Melax's PolyChop.

This commit is contained in:
David Williams
2009-10-20 22:02:58 +00:00
parent 5eb538e925
commit c695a7bc86
16 changed files with 1006 additions and 26 deletions

View File

@ -34,6 +34,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
namespace PolyVox
{
class LodRecord
{
public:
int beginIndex;
int endIndex; //Let's put it just past the end STL style
};
class POLYVOXCORE_API IndexedSurfacePatch
{
public:
@ -62,13 +69,22 @@ namespace PolyVox
//Vector3DInt32 m_v3dRegionPosition; //FIXME - remove this?
/*void growMaterialBoundary(void);
int countMaterialBoundary(void);*/
void makeProgressiveMesh(void);
Region m_Region;
int32_t m_iTimeStamp;
int32_t m_iNoOfLod0Tris;
public:
std::vector<uint32_t> m_vecTriangleIndices;
std::vector<SurfaceVertex> m_vecVertices;
std::vector<LodRecord> m_vecLodRecords;
};
}

View File

@ -0,0 +1,128 @@
/*
* A generic template list class.
* Fairly typical of the list example you would
* find in any c++ book.
*/
#ifndef GENERIC_LIST_H
#define GENERIC_LIST_H
#include <assert.h>
#include <stdio.h>
template <class Type> class List {
public:
List(int s=0);
~List();
void allocate(int s);
void SetSize(int s);
void Pack();
void Add(Type);
void AddUnique(Type);
int Contains(Type);
void Remove(Type);
void DelIndex(int i);
Type * element;
int num;
int array_size;
Type &operator[](int i){assert(i>=0 && i<num); return element[i];}
};
template <class Type>
List<Type>::List(int s){
num=0;
array_size = 0;
element = NULL;
if(s) {
allocate(s);
}
}
template <class Type>
List<Type>::~List<Type>(){
delete element;
}
template <class Type>
void List<Type>::allocate(int s){
assert(s>0);
assert(s>=num);
Type *old = element;
array_size =s;
element = new Type[array_size];
assert(element);
for(int i=0;i<num;i++){
element[i]=old[i];
}
if(old) delete old;
}
template <class Type>
void List<Type>::SetSize(int s){
if(s==0) { if(element) delete element;}
else { allocate(s); }
num=s;
}
template <class Type>
void List<Type>::Pack(){
allocate(num);
}
template <class Type>
void List<Type>::Add(Type t){
assert(num<=array_size);
if(num==array_size) {
allocate((array_size)?array_size *2:16);
}
//int i;
//for(i=0;i<num;i++) {
// dissallow duplicates
// assert(element[i] != t);
//}
element[num++] = t;
}
template <class Type>
int List<Type>::Contains(Type t){
int i;
int count=0;
for(i=0;i<num;i++) {
if(element[i] == t) count++;
}
return count;
}
template <class Type>
void List<Type>::AddUnique(Type t){
if(!Contains(t)) Add(t);
}
template <class Type>
void List<Type>::DelIndex(int i){
assert(i<num);
num--;
while(i<num){
element[i] = element[i+1];
i++;
}
}
template <class Type>
void List<Type>::Remove(Type t){
int i;
for(i=0;i<num;i++) {
if(element[i] == t) {
break;
}
}
DelIndex(i);
for(i=0;i<num;i++) {
assert(element[i] != t);
}
}
#endif

View File

@ -0,0 +1,35 @@
/*
* Progressive Mesh type Polygon Reduction Algorithm
* by Stan Melax (c) 1998
*
* The function ProgressiveMesh() takes a model in an "indexed face
* set" sort of way. i.e. list of vertices and list of triangles.
* The function then does the polygon reduction algorithm
* internally and reduces the model all the way down to 0
* vertices and then returns the order in which the
* vertices are collapsed and to which neighbor each vertex
* is collapsed to. More specifically the returned "permutation"
* indicates how to reorder your vertices so you can render
* an object by using the first n vertices (for the n
* vertex version). After permuting your vertices, the
* map list indicates to which vertex each vertex is collapsed to.
*/
#ifndef PROGRESSIVE_MESH_H
#define PROGRESSIVE_MESH_H
#include "PolyVoxImpl/TypeDef.h"
#include "vector_melax.h"
#include "list.h"
class tridata {
public:
int v[3]; // indices to vertex list
// texture and vertex normal info removed for this demo
};
void POLYVOXCORE_API ProgressiveMesh(List<VectorM> &vert, List<tridata> &tri,
List<int> &map, List<int> &permutation );
#endif

View File

@ -0,0 +1,68 @@
//
// This module contains a bunch of well understood functions
// I apologise if the conventions used here are slightly
// different than what you are used to.
//
#ifndef GENERIC_VECTOR_H
#define GENERIC_VECTOR_H
#include <stdio.h>
#include <math.h>
class VectorM {
public:
float x,y,z;
VectorM(float _x=0.0,float _y=0.0,float _z=0.0){x=_x;y=_y;z=_z;};
operator float *() { return &x;};
float fBoundaryCost;
};
float magnitude(VectorM v);
VectorM normalize(VectorM v);
VectorM operator+(VectorM v1,VectorM v2);
VectorM operator-(VectorM v);
VectorM operator-(VectorM v1,VectorM v2);
VectorM operator*(VectorM v1,float s) ;
VectorM operator*(float s,VectorM v1) ;
VectorM operator/(VectorM v1,float s) ;
float operator^(VectorM v1,VectorM v2); // DOT product
VectorM operator*(VectorM v1,VectorM v2); // CROSS product
VectorM planelineintersection(VectorM n,float d,VectorM p1,VectorM p2);
class matrix{
public:
VectorM x,y,z;
matrix(){x=VectorM(1.0f,0.0f,0.0f);
y=VectorM(0.0f,1.0f,0.0f);
z=VectorM(0.0f,0.0f,1.0f);};
matrix(VectorM _x,VectorM _y,VectorM _z){x=_x;y=_y;z=_z;};
};
matrix transpose(matrix m);
VectorM operator*(matrix m,VectorM v);
matrix operator*(matrix m1,matrix m2);
class Quaternion{
public:
float r,x,y,z;
Quaternion(){x=y=z=0.0f;r=1.0f;};
Quaternion(VectorM v,float t){v=normalize(v);r=(float)cos(t/2.0);v=v*(float)sin(t/2.0);x=v.x;y=v.y;z=v.z;};
Quaternion(float _r,float _x,float _y,float _z){r=_r;x=_x;y=_y;z=_z;};
float angle(){return (float)(acos(r)*2.0);}
VectorM axis(){VectorM a(x,y,z); return a*(float)(1/sin(angle()/2.0));}
VectorM xdir(){return VectorM(1-2*(y*y+z*z), 2*(x*y+r*z), 2*(x*z-r*y));}
VectorM ydir(){return VectorM( 2*(x*y-r*z),1-2*(x*x+z*z), 2*(y*z+r*x));}
VectorM zdir(){return VectorM( 2*(x*z+r*y), 2*(y*z-r*x),1-2*(x*x+y*y));}
matrix getmatrix(){return matrix(xdir(),ydir(),zdir());}
//operator matrix(){return getmatrix();}
};
Quaternion operator-(Quaternion q);
Quaternion operator*(Quaternion a,Quaternion b);
VectorM operator*(Quaternion q,VectorM v);
VectorM operator*(VectorM v,Quaternion q);
Quaternion slerp(Quaternion a,Quaternion b,float interp);
#endif