Removed Stan Melax's stuff. PolyVox should compile on Linux again now.

This commit is contained in:
David Williams 2010-02-19 21:24:35 +00:00
parent d3ad3d985b
commit 9aee0d26d2
13 changed files with 1 additions and 960 deletions

View File

@ -28,7 +28,6 @@ freely, subject to the following restrictions:
#include "GradientEstimators.h"
#include "SurfaceExtractor.h"
#include "RenderDynamicMesh.h"
#include "Mesh.h"
//Some namespaces we need

View File

@ -112,7 +112,6 @@ int main(int argc, char *argv[])
//createCubeInVolume(volData, Vector3DUint16(1, 1, 1), Vector3DUint16(maxPos-1, maxPos-1, midPos/4), 255);
volData.calculateSizeInChars();
cout << "Tidying memory...";
volData.tidyUpMemory(0);
cout << "done." << endl;

View File

@ -11,11 +11,9 @@ SET(CORE_SRC_FILES
source/MeshEdge.cpp
source/MeshFace.cpp
source/MeshVertex.cpp
source/progmesh.cpp
source/Region.cpp
source/SurfaceExtractor.cpp
source/SurfaceVertex.cpp
source/vector.cpp
source/VoxelFilters.cpp
)
@ -23,19 +21,16 @@ SET(CORE_SRC_FILES
SET(CORE_INC_FILES
include/GradientEstimators.inl
include/IndexedSurfacePatch.h
include/list.h
include/Log.h
include/Mesh.h
include/MeshEdge.h
include/MeshFace.h
include/MeshVertex.h
include/PolyVoxForwardDeclarations.h
include/progmesh.h
include/Region.h
include/SurfaceExtractor.h
include/SurfaceVertex.h
include/Vector.h
include/vector_melax.h
include/Vector.inl
include/Volume.h
include/Volume.inl

View File

@ -85,8 +85,6 @@ namespace PolyVox
int noOfDegenerateTris(void);
void removeDegenerateTris(void);
void makeProgressiveMesh(void);
Region m_Region;
int32_t m_iTimeStamp;

View File

@ -140,8 +140,6 @@ namespace PolyVox
void setVoxelAt(const Vector3DUint16& v3dPos, VoxelType tValue);
void tidyUpMemory(uint32_t uNoOfBlocksToProcess = (std::numeric_limits<uint32_t>::max)());
///Calculates roughly how much memory is used by the volume.
uint32_t calculateSizeInChars(void);
private:
POLYVOX_SHARED_PTR< Block<VoxelType> > getHomogenousBlock(VoxelType tHomogenousValue);

View File

@ -357,47 +357,6 @@ namespace PolyVox
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// The returned value is not precise because it is hard to say how much memory
/// STL vectors and maps take iternally, but it accounts for all the block data
/// which is by far the most significant contributer. The returned value is in
/// multiples of the basic type 'char', which is equal to a byte on most systems.
/// Important Note: The value returned by this function is only correct if there
/// is only one volume in memory. This is because blocks are shared between volumes
/// without any one volume being the real owner.
/// \return The amount of memory used by the volume.
////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType>
uint32_t Volume<VoxelType>::calculateSizeInChars(void)
{
//The easy part
uint32_t uSize = sizeof(Volume<VoxelType>);
//Now determine the size of the non homogenous data.
for(uint32_t ct = 0; ct < m_pBlocks.size(); ct++)
{
if(m_pBlocks[ct].unique()) //Check for non-homogenity
{
uSize += sizeof(POLYVOX_SHARED_PTR< Block<VoxelType> >); //The pointer
uSize += m_pBlocks[ct]->sizeInChars(); //The data it points to.
}
}
//The size of the m_vecBlockIsPotentiallyHomogenous vector
uSize += m_vecBlockIsPotentiallyHomogenous.size() * sizeof(bool);
//Now determine the size of the homogenous data.
//We could just get the number of blocks in the map and multiply
//by the block size, but it feels safer to do it 'properly'.
for(std::map<VoxelType, POLYVOX_SHARED_PTR< Block<VoxelType> > >::const_iterator iter = m_pHomogenousBlock.begin(); iter != m_pHomogenousBlock.end(); iter++)
{
uSize += sizeof(POLYVOX_SHARED_PTR< Block<VoxelType> >); //The pointer
uSize += iter->second->sizeInChars(); //The data it points to.
}
return uSize;
}
#pragma endregion
#pragma region Private Implementation

View File

@ -1,128 +0,0 @@
/*
* 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

@ -1,35 +0,0 @@
/*
* 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

@ -1,68 +0,0 @@
//
// 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

View File

@ -25,8 +25,6 @@ freely, subject to the following restrictions:
#include "IndexedSurfacePatch.h"
#include "progmesh.h"
#include <cstdlib>
#include <list>
@ -825,233 +823,4 @@ namespace PolyVox
m_vecTriangleIndices.resize(noOfNonDegenerate * 3);
}
void IndexedSurfacePatch::makeProgressiveMesh(void)
{
//Build the mesh using Stan Melax's code
List<VectorM> vecList;
for(int vertCt = 0; vertCt < m_vecVertices.size(); vertCt++)
{
VectorM vec;
vec.x = m_vecVertices[vertCt].getPosition().getX();
vec.y = m_vecVertices[vertCt].getPosition().getY();
vec.z = m_vecVertices[vertCt].getPosition().getZ();
if(m_vecVertices[vertCt].isOnEdge())
{
vec.fBoundaryCost = 1.0f;
}
else
{
vec.fBoundaryCost = 0.0f;
}
vecList.Add(vec);
}
List<tridata> triList;
for(int triCt = 0; triCt < m_vecTriangleIndices.size(); )
{
tridata tri;
tri.v[0] = m_vecTriangleIndices[triCt];
triCt++;
tri.v[1] = m_vecTriangleIndices[triCt];
triCt++;
tri.v[2] = m_vecTriangleIndices[triCt];
triCt++;
triList.Add(tri);
}
List<int> map;
List<int> permutation;
ProgressiveMesh(vecList, triList, map, permutation);
//Apply the permutation to our vertices
std::vector<SurfaceVertex> vecNewVertices(m_vecVertices.size());
for(int vertCt = 0; vertCt < m_vecVertices.size(); vertCt++)
{
vecNewVertices[permutation[vertCt]]= m_vecVertices[vertCt];
}
std::vector<uint32_t> vecNewTriangleIndices(m_vecTriangleIndices.size());
for(int triCt = 0; triCt < m_vecTriangleIndices.size(); triCt++)
{
vecNewTriangleIndices[triCt] = permutation[m_vecTriangleIndices[triCt]];
}
m_vecVertices = vecNewVertices;
m_vecTriangleIndices = vecNewTriangleIndices;
////////////////////////////////////////////////////////////////////////////////
//Check for unused vertices?
//int usedVertices = 0;
//int unusedVertices = 0;
/*usedVertices = 0;
unusedVertices = 0;
for(int vertCt = 0; vertCt < isp->m_vecVertices.size(); vertCt++)
{
bool found = false;
for(int triCt = 0; triCt < isp->m_vecTriangleIndices.size(); triCt++)
{
if(vertCt == isp->m_vecTriangleIndices[triCt])
{
found = true;
break;
}
}
if(found)
{
usedVertices++;
}
else
{
unusedVertices++;
}
}
std::cout << "Used = " << usedVertices << std::endl;
std::cout << "Unused = " << unusedVertices << std::endl;*/
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//switch triangle order?
/*int noOfTriIndices = isp->m_vecTriangleIndices.size();
for(int triCt = 0; triCt < noOfTriIndices; triCt++)
{
vecNewTriangleIndices[(noOfTriIndices - 1) - triCt] = isp->m_vecTriangleIndices[triCt];
}
isp->m_vecTriangleIndices = vecNewTriangleIndices;*/
//Now build the new index buffers
std::vector<uint32_t> vecNewTriangles;
std::vector<uint32_t> vecUnaffectedTriangles;
std::vector<uint32_t> vecCollapsedTriangles;
vector<bool> vecCanCollapse(m_vecVertices.size());
for(int ct = 0; ct < vecCanCollapse.size(); ct++)
{
vecCanCollapse[ct] = true;
}
vector<bool> vecTriangleRemoved(m_vecTriangleIndices.size() / 3);
for(int ct = 0; ct < vecTriangleRemoved.size(); ct++)
{
vecTriangleRemoved[ct] = false;
}
int noOfCollapsed = 0;
m_vecLodRecords.clear();
for(int vertToCollapse = m_vecVertices.size() - 1; vertToCollapse > 0; vertToCollapse--)
//int vertToCollapse = isp->m_vecVertices.size() - 1;
{
int vertCollapseTarget = map[vertToCollapse];
if((vecCanCollapse[vertToCollapse]) && (vecCanCollapse[vertCollapseTarget]))
{
int noOfNew = 0;
for(int triCt = 0; triCt < m_vecTriangleIndices.size();)
{
int v0 = m_vecTriangleIndices[triCt];
triCt++;
int v1 = m_vecTriangleIndices[triCt];
triCt++;
int v2 = m_vecTriangleIndices[triCt];
triCt++;
if(vecTriangleRemoved[(triCt - 3) / 3] == false)
{
if( (v0 == vertToCollapse) || (v1 == vertToCollapse) || (v2 == vertToCollapse) )
{
vecCollapsedTriangles.push_back(v0);
vecCollapsedTriangles.push_back(v1);
vecCollapsedTriangles.push_back(v2);
vecCanCollapse[v0] = false;
vecCanCollapse[v1] = false;
vecCanCollapse[v2] = false;
noOfCollapsed++;
int targetV0 = v0;
int targetV1 = v1;
int targetV2 = v2;
if(targetV0 == vertToCollapse) targetV0 = vertCollapseTarget;
if(targetV1 == vertToCollapse) targetV1 = vertCollapseTarget;
if(targetV2 == vertToCollapse) targetV2 = vertCollapseTarget;
if((targetV0 != targetV1) && (targetV1 != targetV2) && (targetV2 != targetV0))
{
vecNewTriangles.push_back(targetV0);
vecNewTriangles.push_back(targetV1);
vecNewTriangles.push_back(targetV2);
noOfNew++;
vecCanCollapse[targetV0] = false;
vecCanCollapse[targetV1] = false;
vecCanCollapse[targetV2] = false;
}
vecTriangleRemoved[(triCt - 3) / 3] = true;
}
}
}
LodRecord lodRecord;
lodRecord.beginIndex = vecNewTriangles.size() - (3 * noOfNew);
lodRecord.endIndex = vecCollapsedTriangles.size();
m_vecLodRecords.push_back(lodRecord);
}
}
//Copy triangles into unaffected list
for(int triCt = 0; triCt < m_vecTriangleIndices.size();)
{
int v0 = m_vecTriangleIndices[triCt];
triCt++;
int v1 = m_vecTriangleIndices[triCt];
triCt++;
int v2 = m_vecTriangleIndices[triCt];
triCt++;
if(vecTriangleRemoved[(triCt - 3) / 3] == false)
{
vecUnaffectedTriangles.push_back(v0);
vecUnaffectedTriangles.push_back(v1);
vecUnaffectedTriangles.push_back(v2);
}
}
//Now copy the three lists of triangles back
m_vecTriangleIndices.clear();
for(int ct = 0; ct < vecNewTriangles.size(); ct++)
{
m_vecTriangleIndices.push_back(vecNewTriangles[ct]);
}
for(int ct = 0; ct < vecUnaffectedTriangles.size(); ct++)
{
m_vecTriangleIndices.push_back(vecUnaffectedTriangles[ct]);
}
for(int ct = 0; ct < vecCollapsedTriangles.size(); ct++)
{
m_vecTriangleIndices.push_back(vecCollapsedTriangles[ct]);
}
//Adjust the lod records
for(int ct = 0; ct < m_vecLodRecords.size(); ct++)
{
m_vecLodRecords[ct].endIndex += (vecNewTriangles.size() + vecUnaffectedTriangles.size());
}
}
}

View File

@ -1,314 +0,0 @@
/*
* Progressive Mesh type Polygon Reduction Algorithm
* by Stan Melax (c) 1998
* Permission to use any of this code wherever you want is granted..
* Although, please do acknowledge authorship if appropriate.
*
* See the header file progmesh.h for a description of this module
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <windows.h>
#include <iostream>
#include "vector_melax.h"
#include "list.h"
#include "progmesh.h"
/*
* For the polygon reduction algorithm we use data structures
* that contain a little bit more information than the usual
* indexed face set type of data structure.
* From a vertex we wish to be able to quickly get the
* neighboring faces and vertices.
*/
class Triangle;
class Vertex;
class Triangle {
public:
Vertex * vertex[3]; // the 3 points that make this tri
VectorM normal; // unit vector othogonal to this face
Triangle(Vertex *v0,Vertex *v1,Vertex *v2);
~Triangle();
void ComputeNormal();
void ReplaceVertex(Vertex *vold,Vertex *vnew);
int HasVertex(Vertex *v);
};
class Vertex {
public:
VectorM position; // location of point in euclidean space
int id; // place of vertex in original list
List<Vertex *> neighbor; // adjacent vertices
List<Triangle *> face; // adjacent triangles
float objdist; // cached cost of collapsing edge
Vertex * collapse; // candidate vertex for collapse
Vertex(VectorM v,int _id);
~Vertex();
void RemoveIfNonNeighbor(Vertex *n);
};
List<Vertex *> vertices;
List<Triangle *> triangles;
Triangle::Triangle(Vertex *v0,Vertex *v1,Vertex *v2){
assert(v0!=v1 && v1!=v2 && v2!=v0);
vertex[0]=v0;
vertex[1]=v1;
vertex[2]=v2;
ComputeNormal();
triangles.Add(this);
for(int i=0;i<3;i++) {
vertex[i]->face.Add(this);
for(int j=0;j<3;j++) if(i!=j) {
vertex[i]->neighbor.AddUnique(vertex[j]);
}
}
}
Triangle::~Triangle(){
int i;
triangles.Remove(this);
for(i=0;i<3;i++) {
if(vertex[i]) vertex[i]->face.Remove(this);
}
for(i=0;i<3;i++) {
int i2 = (i+1)%3;
if(!vertex[i] || !vertex[i2]) continue;
vertex[i ]->RemoveIfNonNeighbor(vertex[i2]);
vertex[i2]->RemoveIfNonNeighbor(vertex[i ]);
}
}
int Triangle::HasVertex(Vertex *v) {
return (v==vertex[0] ||v==vertex[1] || v==vertex[2]);
}
void Triangle::ComputeNormal(){
VectorM v0=vertex[0]->position;
VectorM v1=vertex[1]->position;
VectorM v2=vertex[2]->position;
normal = (v1-v0)*(v2-v1);
if(magnitude(normal)==0)return;
normal = normalize(normal);
}
void Triangle::ReplaceVertex(Vertex *vold,Vertex *vnew) {
assert(vold && vnew);
assert(vold==vertex[0] || vold==vertex[1] || vold==vertex[2]);
assert(vnew!=vertex[0] && vnew!=vertex[1] && vnew!=vertex[2]);
if(vold==vertex[0]){
vertex[0]=vnew;
}
else if(vold==vertex[1]){
vertex[1]=vnew;
}
else {
assert(vold==vertex[2]);
vertex[2]=vnew;
}
int i;
vold->face.Remove(this);
assert(!vnew->face.Contains(this));
vnew->face.Add(this);
for(i=0;i<3;i++) {
vold->RemoveIfNonNeighbor(vertex[i]);
vertex[i]->RemoveIfNonNeighbor(vold);
}
for(i=0;i<3;i++) {
assert(vertex[i]->face.Contains(this)==1);
for(int j=0;j<3;j++) if(i!=j) {
vertex[i]->neighbor.AddUnique(vertex[j]);
}
}
ComputeNormal();
}
Vertex::Vertex(VectorM v,int _id) {
position =v;
id=_id;
vertices.Add(this);
}
Vertex::~Vertex(){
assert(face.num==0);
while(neighbor.num) {
neighbor[0]->neighbor.Remove(this);
neighbor.Remove(neighbor[0]);
}
vertices.Remove(this);
}
void Vertex::RemoveIfNonNeighbor(Vertex *n) {
// removes n from neighbor list if n isn't a neighbor.
if(!neighbor.Contains(n)) return;
for(int i=0;i<face.num;i++) {
if(face[i]->HasVertex(n)) return;
}
neighbor.Remove(n);
}
float ComputeEdgeCollapseCost(Vertex *u,Vertex *v) {
// if we collapse edge uv by moving u to v then how
// much different will the model change, i.e. how much "error".
// Texture, vertex normal, and border vertex code was removed
// to keep this demo as simple as possible.
// The method of determining cost was designed in order
// to exploit small and coplanar regions for
// effective polygon reduction.
// Is is possible to add some checks here to see if "folds"
// would be generated. i.e. normal of a remaining face gets
// flipped. I never seemed to run into this problem and
// therefore never added code to detect this case.
int i;
float edgelength = magnitude(v->position - u->position);
float curvature=0;
// find the "sides" triangles that are on the edge uv
List<Triangle *> sides;
for(i=0;i<u->face.num;i++) {
if(u->face[i]->HasVertex(v)){
sides.Add(u->face[i]);
}
}
// use the triangle facing most away from the sides
// to determine our curvature term
for(i=0;i<u->face.num;i++) {
float mincurv=1; // curve for face i and closer side to it
for(int j=0;j<sides.num;j++) {
// use dot product of face normals. '^' defined in vector
float dotprod = u->face[i]->normal ^ sides[j]->normal;
mincurv = min(mincurv,(1-dotprod)/2.0f);
}
curvature = max(curvature,mincurv);
}
float boundaryCost = u->position.fBoundaryCost + v->position.fBoundaryCost;
// the more coplanar the lower the curvature term
return edgelength * curvature + boundaryCost;
}
void ComputeEdgeCostAtVertex(Vertex *v) {
// compute the edge collapse cost for all edges that start
// from vertex v. Since we are only interested in reducing
// the object by selecting the min cost edge at each step, we
// only cache the cost of the least cost edge at this vertex
// (in member variable collapse) as well as the value of the
// cost (in member variable objdist).
if(v->neighbor.num==0) {
// v doesn't have neighbors so it costs nothing to collapse
v->collapse=NULL;
v->objdist=-0.01f;
return;
}
v->objdist = 1000000;
v->collapse=NULL;
// search all neighboring edges for "least cost" edge
for(int i=0;i<v->neighbor.num;i++) {
float dist;
dist = ComputeEdgeCollapseCost(v,v->neighbor[i]);
//std::cout << "Cost: " << dist << std::endl;
if(dist<v->objdist) {
v->collapse=v->neighbor[i]; // candidate for edge collapse
v->objdist=dist; // cost of the collapse
}
}
}
void ComputeAllEdgeCollapseCosts() {
// For all the edges, compute the difference it would make
// to the model if it was collapsed. The least of these
// per vertex is cached in each vertex object.
for(int i=0;i<vertices.num;i++) {
ComputeEdgeCostAtVertex(vertices[i]);
}
}
void Collapse(Vertex *u,Vertex *v){
// Collapse the edge uv by moving vertex u onto v
// Actually remove tris on uv, then update tris that
// have u to have v, and then remove u.
if(!v) {
// u is a vertex all by itself so just delete it
delete u;
return;
}
int i;
List<Vertex *>tmp;
// make tmp a list of all the neighbors of u
for(i=0;i<u->neighbor.num;i++) {
tmp.Add(u->neighbor[i]);
}
// delete triangles on edge uv:
for(i=u->face.num-1;i>=0;i--) {
if(u->face[i]->HasVertex(v)) {
delete(u->face[i]);
}
}
// update remaining triangles to have v instead of u
for(i=u->face.num-1;i>=0;i--) {
u->face[i]->ReplaceVertex(u,v);
}
delete u;
// recompute the edge collapse costs for neighboring vertices
for(i=0;i<tmp.num;i++) {
ComputeEdgeCostAtVertex(tmp[i]);
}
}
void AddVertex(List<VectorM> &vert){
for(int i=0;i<vert.num;i++) {
Vertex *v = new Vertex(vert[i],i);
}
}
void AddFaces(List<tridata> &tri){
for(int i=0;i<tri.num;i++) {
Triangle *t=new Triangle(
vertices[tri[i].v[0]],
vertices[tri[i].v[1]],
vertices[tri[i].v[2]] );
}
}
Vertex *MinimumCostEdge(){
// Find the edge that when collapsed will affect model the least.
// This funtion actually returns a Vertex, the second vertex
// of the edge (collapse candidate) is stored in the vertex data.
// Serious optimization opportunity here: this function currently
// does a sequential search through an unsorted list :-(
// Our algorithm could be O(n*lg(n)) instead of O(n*n)
Vertex *mn=vertices[0];
for(int i=0;i<vertices.num;i++) {
if(vertices[i]->objdist < mn->objdist) {
mn = vertices[i];
}
}
return mn;
}
void ProgressiveMesh(List<VectorM> &vert, List<tridata> &tri,
List<int> &map, List<int> &permutation)
{
AddVertex(vert); // put input data into our data structures
AddFaces(tri);
ComputeAllEdgeCollapseCosts(); // cache all edge collapse costs
permutation.SetSize(vertices.num); // allocate space
map.SetSize(vertices.num); // allocate space
// reduce the object down to nothing:
while(vertices.num > 0) {
// get the next vertex to collapse
Vertex *mn = MinimumCostEdge();
// keep track of this vertex, i.e. the collapse ordering
permutation[mn->id]=vertices.num-1;
// keep track of vertex to which we collapse to
map[vertices.num-1] = (mn->collapse)?mn->collapse->id:-1;
// Collapse this edge
Collapse(mn,mn->collapse);
}
// reorder the map list based on the collapse ordering
for(int i=0;i<map.num;i++) {
map[i] = (map[i]==-1)?0:permutation[map[i]];
}
// The caller of this function should reorder their vertices
// according to the returned "permutation".
}

View File

@ -1,131 +0,0 @@
/*******************************************************************************
Copyright (c) 2005-2009 David Williams
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*******************************************************************************/
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include "vector_melax.h"
float sqr(float a) {return a*a;}
// vector (floating point) implementation
float magnitude(VectorM v) {
return (float)sqrt(sqr(v.x) + sqr( v.y)+ sqr(v.z));
}
VectorM normalize(VectorM v) {
float d=magnitude(v);
if (d==0) {
printf("Cant normalize ZERO vector\n");
assert(0);
d=0.1f;
}
v.x/=d;
v.y/=d;
v.z/=d;
return v;
}
VectorM operator+(VectorM v1,VectorM v2) {return VectorM(v1.x+v2.x,v1.y+v2.y,v1.z+v2.z);}
VectorM operator-(VectorM v1,VectorM v2) {return VectorM(v1.x-v2.x,v1.y-v2.y,v1.z-v2.z);}
VectorM operator-(VectorM v) {return VectorM(-v.x,-v.y,-v.z);}
VectorM operator*(VectorM v1,float s) {return VectorM(v1.x*s,v1.y*s,v1.z*s);}
VectorM operator*(float s, VectorM v1) {return VectorM(v1.x*s,v1.y*s,v1.z*s);}
VectorM operator/(VectorM v1,float s) {return v1*(1.0f/s);}
float operator^(VectorM v1,VectorM v2) {return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;}
VectorM operator*(VectorM v1,VectorM v2) {
return VectorM(
v1.y * v2.z - v1.z*v2.y,
v1.z * v2.x - v1.x*v2.z,
v1.x * v2.y - v1.y*v2.x);
}
VectorM planelineintersection(VectorM n,float d,VectorM p1,VectorM p2){
// returns the point where the line p1-p2 intersects the plane n&d
VectorM dif = p2-p1;
float dn= n^dif;
float t = -(d+(n^p1) )/dn;
return p1 + (dif*t);
}
int concurrent(VectorM a,VectorM b) {
return(a.x==b.x && a.y==b.y && a.z==b.z);
}
// Matrix Implementation
matrix transpose(matrix m) {
return matrix( VectorM(m.x.x,m.y.x,m.z.x),
VectorM(m.x.y,m.y.y,m.z.y),
VectorM(m.x.z,m.y.z,m.z.z));
}
VectorM operator*(matrix m,VectorM v){
m=transpose(m); // since column ordered
return VectorM(m.x^v,m.y^v,m.z^v);
}
matrix operator*(matrix m1,matrix m2){
m1=transpose(m1);
return matrix(m1*m2.x,m1*m2.y,m1*m2.z);
}
//Quaternion Implementation
Quaternion operator*(Quaternion a,Quaternion b) {
Quaternion c;
c.r = a.r*b.r - a.x*b.x - a.y*b.y - a.z*b.z;
c.x = a.r*b.x + a.x*b.r + a.y*b.z - a.z*b.y;
c.y = a.r*b.y - a.x*b.z + a.y*b.r + a.z*b.x;
c.z = a.r*b.z + a.x*b.y - a.y*b.x + a.z*b.r;
return c;
}
Quaternion operator-(Quaternion q) {
return Quaternion(q.r*-1,q.x,q.y,q.z);
}
Quaternion operator*(Quaternion a,float b) {
return Quaternion(a.r*b, a.x*b, a.y*b, a.z*b);
}
VectorM operator*(Quaternion q,VectorM v) {
return q.getmatrix() * v;
}
VectorM operator*(VectorM v,Quaternion q){
assert(0); // must multiply with the quat on the left
return VectorM(0.0f,0.0f,0.0f);
}
Quaternion operator+(Quaternion a,Quaternion b) {
return Quaternion(a.r+b.r, a.x+b.x, a.y+b.y, a.z+b.z);
}
float operator^(Quaternion a,Quaternion b) {
return (a.r*b.r + a.x*b.x + a.y*b.y + a.z*b.z);
}
Quaternion slerp(Quaternion a,Quaternion b,float interp){
if((a^b) <0.0) {
a.r=-a.r;
a.x=-a.x;
a.y=-a.y;
a.z=-a.z;
}
float theta = (float)acos(a^b);
if(theta==0.0f) { return(a);}
return a*(float)(sin(theta-interp*theta)/sin(theta)) + b*(float)(sin(interp*theta)/sin(theta));
}

View File

@ -57,7 +57,7 @@ namespace PolyVox
void unlockRegion(void);
//void markRegionChanged(uint16_t firstX, uint16_t firstY, uint16_t firstZ, uint16_t lastX, uint16_t lastY, uint16_t lastZ);
private:
public:
void incrementCurrentTime(void);
bool m_bIsLocked;
Region m_regLastLocked;