mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Revert "STYLE: surfaceCoarsen: remove orhpaned files"
This reverts commit 98f269edaf.
This commit is contained in:
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
Polygon Reduction Demo
|
||||||
|
By Stan Melax (c) 1998
|
||||||
|
mailto:melax@cs.ualberta.ca
|
||||||
|
http://www.cs.ualberta.ca/~melax
|
||||||
|
|
||||||
|
The PC executable bunnylod.exe should run
|
||||||
|
on a standard PC.
|
||||||
|
Just run it and enjoy.
|
||||||
|
Mouse dragging spins the rabbit.
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,282 @@
|
|||||||
|
/*
|
||||||
|
* Polygon Reduction Demo by Stan Melax (c) 1998
|
||||||
|
* Permission to use any of this code wherever you want is granted..
|
||||||
|
* Although, please do acknowledge authorship if appropriate.
|
||||||
|
*
|
||||||
|
* This module initializes the bunny model data and calls
|
||||||
|
* the polygon reduction routine. At each frame the RenderModel()
|
||||||
|
* routine is called to draw the model. This module also
|
||||||
|
* animates the parameters (such as number of vertices to
|
||||||
|
* use) to show the model at various levels of detail.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
#include "font.h"
|
||||||
|
#include "progmesh.h"
|
||||||
|
#include "rabdata.h"
|
||||||
|
|
||||||
|
extern float DeltaT; // change in time since last frame
|
||||||
|
int render_num; // number of vertices to draw with
|
||||||
|
float lodbase=0.5f; // the fraction of vertices used to morph toward
|
||||||
|
float morph=1.0f; // where to render between 2 levels of detail
|
||||||
|
List<Vector> vert; // global list of vertices
|
||||||
|
List<tridata> tri; // global list of triangles
|
||||||
|
List<int> collapse_map; // to which neighbor each vertex collapses
|
||||||
|
int renderpolycount=0; // polygons rendered in the current frame
|
||||||
|
Vector model_position; // position of bunny
|
||||||
|
Quaternion model_orientation; // orientation of bunny
|
||||||
|
|
||||||
|
// Note that the use of the Map() function and the collapse_map
|
||||||
|
// list isn't part of the polygon reduction algorithm.
|
||||||
|
// We just set up this system here in this module
|
||||||
|
// so that we could retrieve the model at any desired vertex count.
|
||||||
|
// Therefore if this part of the program confuses you, then
|
||||||
|
// dont worry about it. It might help to look over the progmesh.cpp
|
||||||
|
// module first.
|
||||||
|
|
||||||
|
// Map()
|
||||||
|
//
|
||||||
|
// When the model is rendered using a maximum of mx vertices
|
||||||
|
// then it is vertices 0 through mx-1 that are used.
|
||||||
|
// We are able to do this because the vertex list
|
||||||
|
// gets sorted according to the collapse order.
|
||||||
|
// The Map() routine takes a vertex number 'a' and the
|
||||||
|
// maximum number of vertices 'mx' and returns the
|
||||||
|
// appropriate vertex in the range 0 to mx-1.
|
||||||
|
// When 'a' is greater than 'mx' the Map() routine
|
||||||
|
// follows the chain of edge collapses until a vertex
|
||||||
|
// within the limit is reached.
|
||||||
|
// An example to make this clear: assume there is
|
||||||
|
// a triangle with vertices 1, 3 and 12. But when
|
||||||
|
// rendering the model we limit ourselves to 10 vertices.
|
||||||
|
// In that case we find out how vertex 12 was removed
|
||||||
|
// by the polygon reduction algorithm. i.e. which
|
||||||
|
// edge was collapsed. Lets say that vertex 12 was collapsed
|
||||||
|
// to vertex number 7. This number would have been stored
|
||||||
|
// in the collapse_map array (i.e. collapse_map[12]==7).
|
||||||
|
// Since vertex 7 is in range (less than max of 10) we
|
||||||
|
// will want to render the triangle 1,3,7.
|
||||||
|
// Pretend now that we want to limit ourselves to 5 vertices.
|
||||||
|
// and vertex 7 was collapsed to vertex 3
|
||||||
|
// (i.e. collapse_map[7]==3). Then triangle 1,3,12 would now be
|
||||||
|
// triangle 1,3,3. i.e. this polygon was removed by the
|
||||||
|
// progressive mesh polygon reduction algorithm by the time
|
||||||
|
// it had gotten down to 5 vertices.
|
||||||
|
// No need to draw a one dimensional polygon. :-)
|
||||||
|
int Map(int a,int mx) {
|
||||||
|
if(mx<=0) return 0;
|
||||||
|
while(a>=mx) {
|
||||||
|
a=collapse_map[a];
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawModelTriangles() {
|
||||||
|
assert(collapse_map.num);
|
||||||
|
renderpolycount=0;
|
||||||
|
int i=0;
|
||||||
|
for(i=0;i<tri.num;i++) {
|
||||||
|
int p0= Map(tri[i].v[0],render_num);
|
||||||
|
int p1= Map(tri[i].v[1],render_num);
|
||||||
|
int p2= Map(tri[i].v[2],render_num);
|
||||||
|
// note: serious optimization opportunity here,
|
||||||
|
// by sorting the triangles the following "continue"
|
||||||
|
// could have been made into a "break" statement.
|
||||||
|
if(p0==p1 || p1==p2 || p2==p0) continue;
|
||||||
|
renderpolycount++;
|
||||||
|
// if we are not currenly morphing between 2 levels of detail
|
||||||
|
// (i.e. if morph=1.0) then q0,q1, and q2 are not necessary.
|
||||||
|
int q0= Map(p0,(int)(render_num*lodbase));
|
||||||
|
int q1= Map(p1,(int)(render_num*lodbase));
|
||||||
|
int q2= Map(p2,(int)(render_num*lodbase));
|
||||||
|
Vector v0,v1,v2;
|
||||||
|
v0 = vert[p0]*morph + vert[q0]*(1-morph);
|
||||||
|
v1 = vert[p1]*morph + vert[q1]*(1-morph);
|
||||||
|
v2 = vert[p2]*morph + vert[q2]*(1-morph);
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
// the purpose of the demo is to show polygons
|
||||||
|
// therefore just use 1 face normal (flat shading)
|
||||||
|
Vector nrml = (v1-v0) * (v2-v1); // cross product
|
||||||
|
if(0<magnitude(nrml)) {
|
||||||
|
glNormal3fv(normalize(nrml));
|
||||||
|
}
|
||||||
|
glVertex3fv(v0);
|
||||||
|
glVertex3fv(v1);
|
||||||
|
glVertex3fv(v2);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PermuteVertices(List<int> &permutation) {
|
||||||
|
// rearrange the vertex list
|
||||||
|
List<Vector> temp_list;
|
||||||
|
int i;
|
||||||
|
assert(permutation.num==vert.num);
|
||||||
|
for(i=0;i<vert.num;i++) {
|
||||||
|
temp_list.Add(vert[i]);
|
||||||
|
}
|
||||||
|
for(i=0;i<vert.num;i++) {
|
||||||
|
vert[permutation[i]]=temp_list[i];
|
||||||
|
}
|
||||||
|
// update the changes in the entries in the triangle list
|
||||||
|
for(i=0;i<tri.num;i++) {
|
||||||
|
for(int j=0;j<3;j++) {
|
||||||
|
tri[i].v[j] = permutation[tri[i].v[j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetRabbitData(){
|
||||||
|
// Copy the geometry from the arrays of data in rabdata.cpp into
|
||||||
|
// the vert and tri lists which we send to the reduction routine
|
||||||
|
int i;
|
||||||
|
for(i=0;i<RABBIT_VERTEX_NUM;i++) {
|
||||||
|
float *vp=rabbit_vertices[i];
|
||||||
|
vert.Add(Vector(vp[0],vp[1],vp[2]));
|
||||||
|
}
|
||||||
|
for(i=0;i<RABBIT_TRIANGLE_NUM;i++) {
|
||||||
|
tridata td;
|
||||||
|
td.v[0]=rabbit_triangles[i][0];
|
||||||
|
td.v[1]=rabbit_triangles[i][1];
|
||||||
|
td.v[2]=rabbit_triangles[i][2];
|
||||||
|
tri.Add(td);
|
||||||
|
}
|
||||||
|
render_num=vert.num; // by default lets use all the model to render
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InitModel() {
|
||||||
|
List<int> permutation;
|
||||||
|
GetRabbitData();
|
||||||
|
ProgressiveMesh(vert,tri,collapse_map,permutation);
|
||||||
|
PermuteVertices(permutation);
|
||||||
|
model_position = Vector(0,0,-3);
|
||||||
|
Quaternion yaw(Vector(0,1,0),-3.14f/4); // 45 degrees
|
||||||
|
Quaternion pitch(Vector(1,0,0),3.14f/12); // 15 degrees
|
||||||
|
model_orientation = pitch*yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusDraw() {
|
||||||
|
// Draw a slider type widget looking thing
|
||||||
|
// to show portion of vertices being used
|
||||||
|
float b = (float)render_num/(float)vert.num;
|
||||||
|
float a = b*(lodbase );
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
glMatrixMode( GL_PROJECTION );
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
glOrtho(-0.15,15,-0.1,1.1,-0.1,100);
|
||||||
|
glMatrixMode( GL_MODELVIEW );
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
glColor3f(1,0,0);
|
||||||
|
glVertex2f(0,0);
|
||||||
|
glVertex2f(1,0);
|
||||||
|
glVertex2f(1,a);
|
||||||
|
glVertex2f(0,a);
|
||||||
|
glEnd();
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
glColor3f(1,0,0);
|
||||||
|
glVertex2f(0,a);
|
||||||
|
glVertex2f(morph,a);
|
||||||
|
glVertex2f(morph,b);
|
||||||
|
glVertex2f(0,b);
|
||||||
|
glEnd();
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
glColor3f(0,0,1);
|
||||||
|
glVertex2f(morph,a);
|
||||||
|
glVertex2f(1,a);
|
||||||
|
glVertex2f(1,b);
|
||||||
|
glVertex2f(morph,b);
|
||||||
|
glEnd();
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
glColor3f(0,0,1);
|
||||||
|
glVertex2f(0,b);
|
||||||
|
glVertex2f(1,b);
|
||||||
|
glVertex2f(1,1);
|
||||||
|
glVertex2f(0,1);
|
||||||
|
glEnd();
|
||||||
|
glPopMatrix();
|
||||||
|
glMatrixMode( GL_PROJECTION );
|
||||||
|
glPopMatrix();
|
||||||
|
glMatrixMode( GL_MODELVIEW );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following is just a quick hack to animate
|
||||||
|
* the object through various polygon reduced versions.
|
||||||
|
*/
|
||||||
|
struct keyframethings {
|
||||||
|
float t; // timestamp
|
||||||
|
float n; // portion of vertices used to start
|
||||||
|
float dn; // rate of change in "n"
|
||||||
|
float m; // morph value
|
||||||
|
float dm; // rate of change in "m"
|
||||||
|
} keys[]={
|
||||||
|
{0 ,1 ,0 ,1, 0},
|
||||||
|
{2 ,1 ,-1,1, 0},
|
||||||
|
{10,0 ,1 ,1, 0},
|
||||||
|
{18,1 ,0 ,1, 0},
|
||||||
|
{20,1 ,0 ,1,-1},
|
||||||
|
{24,0.5 ,0 ,1, 0},
|
||||||
|
{26,0.5 ,0 ,1,-1},
|
||||||
|
{30,0.25,0 ,1, 0},
|
||||||
|
{32,0.25,0 ,1,-1},
|
||||||
|
{36,0.125,0,1, 0},
|
||||||
|
{38,0.25,0 ,0, 1},
|
||||||
|
{42,0.5 ,0 ,0, 1},
|
||||||
|
{46,1 ,0 ,0, 1},
|
||||||
|
{50,1 ,0 ,1, 0},
|
||||||
|
};
|
||||||
|
void AnimateParameters() {
|
||||||
|
static float time=0; // global time - used for animation
|
||||||
|
time+=DeltaT;
|
||||||
|
if(time>=50) time=0; // repeat cycle every so many seconds
|
||||||
|
int k=0;
|
||||||
|
while(time>keys[k+1].t) {
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
float interp = (time-keys[k].t)/(keys[k+1].t-keys[k].t);
|
||||||
|
render_num = vert.num*(keys[k].n + interp*keys[k].dn);
|
||||||
|
morph = keys[k].m + interp*keys[k].dm;
|
||||||
|
morph = (morph>1.0f) ? 1.0f : morph; // clamp value
|
||||||
|
if(render_num>vert.num) render_num=vert.num;
|
||||||
|
if(render_num<0 ) render_num=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderModel() {
|
||||||
|
AnimateParameters();
|
||||||
|
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
glEnable(GL_LIGHT0);
|
||||||
|
glColor3f(1,1,1);
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(model_position.x,model_position.y,model_position.z);
|
||||||
|
// Rotate by quaternion: model_orientation
|
||||||
|
Vector axis=model_orientation.axis();
|
||||||
|
float angle=model_orientation.angle()*180.0f/3.14f;
|
||||||
|
glRotatef(angle,axis.x,axis.y,axis.z);
|
||||||
|
DrawModelTriangles();
|
||||||
|
StatusDraw();
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
char buf[256];
|
||||||
|
sprintf(buf,"Polys: %d Vertices: %d ",renderpolycount,render_num);
|
||||||
|
if(morph<1.0) {
|
||||||
|
sprintf(buf+strlen(buf),"<-> %d morph: %4.2f ",
|
||||||
|
(int)(lodbase *render_num),morph);
|
||||||
|
}
|
||||||
|
PostString(buf,0,-2,5);
|
||||||
|
}
|
||||||
@ -0,0 +1,114 @@
|
|||||||
|
# Microsoft Developer Studio Project File - Name="bunnylod" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 5.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||||
|
|
||||||
|
CFG=bunnylod - Win32 Debug
|
||||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
|
!MESSAGE use the Export Makefile command and run
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "bunnylod.mak".
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "bunnylod.mak" CFG="bunnylod - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "bunnylod - Win32 Release" (based on "Win32 (x86) Application")
|
||||||
|
!MESSAGE "bunnylod - Win32 Debug" (based on "Win32 (x86) Application")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
MTL=midl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "bunnylod - Win32 Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "Release"
|
||||||
|
# PROP BASE Intermediate_Dir "Release"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "Release"
|
||||||
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||||
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
|
||||||
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
|
||||||
|
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
|
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||||
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib winmm.lib /nologo /subsystem:windows /machine:I386
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "bunnylod - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "Debug"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "Debug"
|
||||||
|
# PROP Intermediate_Dir "Debug"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
|
||||||
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
|
||||||
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
|
||||||
|
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||||
|
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||||
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "bunnylod - Win32 Release"
|
||||||
|
# Name "bunnylod - Win32 Debug"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\bunnygut.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\font.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\progmesh.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\rabdata.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\vector.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\winmain.cpp
|
||||||
|
# End Source File
|
||||||
|
# End Target
|
||||||
|
# End Project
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
Microsoft Developer Studio Workspace File, Format Version 5.00
|
||||||
|
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "bunnylod"=.\bunnylod.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Global:
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<3>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef FONT_H
|
||||||
|
#define FONT_H
|
||||||
|
|
||||||
|
void PrintString(char *s,int x=0,int y=-1);
|
||||||
|
void PostString(char *_s,int _x,int _y,float _life=5.0);
|
||||||
|
void RenderStrings();
|
||||||
|
|
||||||
|
#endif
|
||||||
130
applications/utilities/surface/surfaceCoarsen/bunnylod/list.h
Normal file
130
applications/utilities/surface/surfaceCoarsen/bunnylod/list.h
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* 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(){
|
||||||
|
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
|
||||||
@ -0,0 +1,315 @@
|
|||||||
|
/*
|
||||||
|
* 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 "vector.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "progmesh.h"
|
||||||
|
|
||||||
|
#define min(x,y) (((x) <= (y)) ? (x) : (y))
|
||||||
|
#define max(x,y) (((x) >= (y)) ? (x) : (y))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
Vector 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:
|
||||||
|
Vector 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(Vector 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(){
|
||||||
|
Vector v0=vertex[0]->position;
|
||||||
|
Vector v1=vertex[1]->position;
|
||||||
|
Vector 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(Vector 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);
|
||||||
|
}
|
||||||
|
// the more coplanar the lower the curvature term
|
||||||
|
return edgelength * curvature;
|
||||||
|
}
|
||||||
|
|
||||||
|
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]);
|
||||||
|
if(dist<v->objdist) {
|
||||||
|
// candidate for edge collapse
|
||||||
|
v->collapse=v->neighbor[i];
|
||||||
|
// cost of the collapse
|
||||||
|
v->objdist=dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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<Vector> &vert){
|
||||||
|
for(int i=0;i<vert.num;i++) {
|
||||||
|
new Vertex(vert[i],i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void AddFaces(List<tridata> &tri){
|
||||||
|
for(int i=0;i<tri.num;i++) {
|
||||||
|
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<Vector> &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".
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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 "vector.h"
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
class tridata {
|
||||||
|
public:
|
||||||
|
int v[3]; // indices to vertex list
|
||||||
|
// texture and vertex normal info removed for this demo
|
||||||
|
};
|
||||||
|
|
||||||
|
void ProgressiveMesh(List<Vector> &vert, List<tridata> &tri,
|
||||||
|
List<int> &map, List<int> &permutation );
|
||||||
|
|
||||||
|
#endif
|
||||||
1383
applications/utilities/surface/surfaceCoarsen/bunnylod/rabdata.C
Normal file
1383
applications/utilities/surface/surfaceCoarsen/bunnylod/rabdata.C
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,32 @@
|
|||||||
|
/* Copyright 1996, Viewpoint Datalabs Int'l, www.viewpoint.com, 1-800-DATASET */
|
||||||
|
/*
|
||||||
|
# Usage Rights: You (the user) may use this model to help build
|
||||||
|
# cool personal vrml worlds, but please give us credit when you do
|
||||||
|
# ("3D model provided by Viewpoint Datalabs, www,viewpoint.com").
|
||||||
|
# Please don't sell it or use it to make money indirectly. Don't
|
||||||
|
# redistribute it or put it on a web site except as a part of your
|
||||||
|
# personal, non-commerical vrml world. If you want to do a
|
||||||
|
# commercial project, give us a call at 1-800-DATASET or visit
|
||||||
|
# www.viewpoint.com and we'll help you obtain the rights to do so.
|
||||||
|
# */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that this data was put directly into the program
|
||||||
|
* to provide a demo program on the net that people could
|
||||||
|
* just run without having to fetch datafiles.
|
||||||
|
* i.e. more convienent for the user this way
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef RABBIT_DATA_H
|
||||||
|
#define RABBIT_DATA_H
|
||||||
|
|
||||||
|
#define RABBIT_VERTEX_NUM (453)
|
||||||
|
#define RABBIT_TRIANGLE_NUM (902)
|
||||||
|
|
||||||
|
extern float rabbit_vertices[RABBIT_VERTEX_NUM][3];
|
||||||
|
extern int rabbit_triangles[RABBIT_TRIANGLE_NUM][3];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
117
applications/utilities/surface/surfaceCoarsen/bunnylod/vector.C
Normal file
117
applications/utilities/surface/surfaceCoarsen/bunnylod/vector.C
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
float sqr(float a) {return a*a;}
|
||||||
|
|
||||||
|
// vector (floating point) implementation
|
||||||
|
|
||||||
|
float magnitude(Vector v) {
|
||||||
|
return float(sqrt(sqr(v.x) + sqr( v.y)+ sqr(v.z)));
|
||||||
|
}
|
||||||
|
Vector normalize(Vector 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector operator+(Vector v1,Vector v2)
|
||||||
|
{
|
||||||
|
return Vector(v1.x+v2.x,v1.y+v2.y,v1.z+v2.z);
|
||||||
|
}
|
||||||
|
Vector operator-(Vector v1,Vector v2)
|
||||||
|
{
|
||||||
|
return Vector(v1.x-v2.x,v1.y-v2.y,v1.z-v2.z);
|
||||||
|
}
|
||||||
|
Vector operator-(Vector v) {return Vector(-v.x,-v.y,-v.z);}
|
||||||
|
Vector operator*(Vector v1,float s) {return Vector(v1.x*s,v1.y*s,v1.z*s);}
|
||||||
|
Vector operator*(float s, Vector v1) {return Vector(v1.x*s,v1.y*s,v1.z*s);}
|
||||||
|
Vector operator/(Vector v1,float s) {return v1*(1.0f/s);}
|
||||||
|
float operator^(Vector v1,Vector v2)
|
||||||
|
{
|
||||||
|
return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
|
||||||
|
}
|
||||||
|
Vector operator*(Vector v1,Vector v2) {
|
||||||
|
return Vector(
|
||||||
|
v1.y * v2.z - v1.z*v2.y,
|
||||||
|
v1.z * v2.x - v1.x*v2.z,
|
||||||
|
v1.x * v2.y - v1.y*v2.x);
|
||||||
|
}
|
||||||
|
Vector planelineintersection(Vector n,float d,Vector p1,Vector p2){
|
||||||
|
// returns the point where the line p1-p2 intersects the plane n&d
|
||||||
|
Vector dif = p2-p1;
|
||||||
|
float dn= n^dif;
|
||||||
|
float t = -(d+(n^p1) )/dn;
|
||||||
|
return p1 + (dif*t);
|
||||||
|
}
|
||||||
|
int concurrent(Vector a,Vector b) {
|
||||||
|
return(a.x==b.x && a.y==b.y && a.z==b.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Matrix Implementation
|
||||||
|
matrix transpose(matrix m) {
|
||||||
|
return matrix( Vector(m.x.x,m.y.x,m.z.x),
|
||||||
|
Vector(m.x.y,m.y.y,m.z.y),
|
||||||
|
Vector(m.x.z,m.y.z,m.z.z));
|
||||||
|
}
|
||||||
|
Vector operator*(matrix m,Vector v){
|
||||||
|
m=transpose(m); // since column ordered
|
||||||
|
return Vector(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);
|
||||||
|
}
|
||||||
|
Vector operator*(Quaternion q,Vector v) {
|
||||||
|
return q.getmatrix() * v;
|
||||||
|
}
|
||||||
|
Vector operator*(Vector v,Quaternion q){
|
||||||
|
assert(0); // must multiply with the quat on the left
|
||||||
|
return Vector(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));
|
||||||
|
}
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
//
|
||||||
|
// 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 Vector {
|
||||||
|
public:
|
||||||
|
float x,y,z;
|
||||||
|
Vector(float _x=0.0,float _y=0.0,float _z=0.0){x=_x;y=_y;z=_z;};
|
||||||
|
operator float *() { return &x;};
|
||||||
|
};
|
||||||
|
|
||||||
|
float magnitude(Vector v);
|
||||||
|
Vector normalize(Vector v);
|
||||||
|
|
||||||
|
Vector operator+(Vector v1,Vector v2);
|
||||||
|
Vector operator-(Vector v);
|
||||||
|
Vector operator-(Vector v1,Vector v2);
|
||||||
|
Vector operator*(Vector v1,float s) ;
|
||||||
|
Vector operator*(float s,Vector v1) ;
|
||||||
|
Vector operator/(Vector v1,float s) ;
|
||||||
|
float operator^(Vector v1,Vector v2); // DOT product
|
||||||
|
Vector operator*(Vector v1,Vector v2); // CROSS product
|
||||||
|
Vector planelineintersection(Vector n,float d,Vector p1,Vector p2);
|
||||||
|
|
||||||
|
class matrix{
|
||||||
|
public:
|
||||||
|
Vector x,y,z;
|
||||||
|
matrix(){x=Vector(1.0f,0.0f,0.0f);
|
||||||
|
y=Vector(0.0f,1.0f,0.0f);
|
||||||
|
z=Vector(0.0f,0.0f,1.0f);};
|
||||||
|
matrix(Vector _x,Vector _y,Vector _z){x=_x;y=_y;z=_z;};
|
||||||
|
};
|
||||||
|
matrix transpose(matrix m);
|
||||||
|
Vector operator*(matrix m,Vector 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(Vector 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);}
|
||||||
|
Vector axis(){Vector a(x,y,z); return a*float(1/sin(angle()/2.0));}
|
||||||
|
Vector xdir(){
|
||||||
|
return Vector(1-2*(y*y+z*z), 2*(x*y+r*z), 2*(x*z-r*y));
|
||||||
|
}
|
||||||
|
Vector ydir(){
|
||||||
|
return Vector( 2*(x*y-r*z),1-2*(x*x+z*z), 2*(y*z+r*x));
|
||||||
|
}
|
||||||
|
Vector zdir(){
|
||||||
|
return Vector( 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);
|
||||||
|
Vector operator*(Quaternion q,Vector v);
|
||||||
|
Vector operator*(Vector v,Quaternion q);
|
||||||
|
Quaternion slerp(Quaternion a,Quaternion b,float interp);
|
||||||
|
|
||||||
|
#endif
|
||||||
453
applications/utilities/surface/surfaceCoarsen/bunnylod/winmain.C
Normal file
453
applications/utilities/surface/surfaceCoarsen/bunnylod/winmain.C
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
/*
|
||||||
|
* Polygon Reduction Demo by Stan Melax (c) 1998
|
||||||
|
* Permission to use any of this code wherever you want is granted..
|
||||||
|
* Although, please do acknowledge authorship if appropriate.
|
||||||
|
*
|
||||||
|
* This module contains the window setup code, mouse input, timing
|
||||||
|
* routines, and that sort of stuff. The interesting modules
|
||||||
|
* to see are bunnygut.cpp and progmesh.cpp.
|
||||||
|
*
|
||||||
|
* The windows 95 specific code for this application was taken from
|
||||||
|
* an example of processing mouse events in an OpenGL program using
|
||||||
|
* the Win32 API from the www.opengl.org web site.
|
||||||
|
*
|
||||||
|
* Under Project->Settings, Link Options, General Category
|
||||||
|
* Add:
|
||||||
|
* Opengl32.lib glu32.lib winmm.lib
|
||||||
|
* to the Object/Library Modules
|
||||||
|
*
|
||||||
|
* You will need have OpenGL libs and include files to compile this
|
||||||
|
* Go to the www.opengl.org web site if you need help with this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <windows.h> /* must include this before GL/gl.h */
|
||||||
|
#include <GL/gl.h> /* OpenGL header file */
|
||||||
|
#include <GL/glu.h> /* OpenGL utilities header file */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/timeb.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
#include "font.h"
|
||||||
|
|
||||||
|
// Functions and Variables from bunny module
|
||||||
|
extern void InitModel();
|
||||||
|
extern void RenderModel();
|
||||||
|
extern Vector model_position; // position of bunny
|
||||||
|
extern Quaternion model_orientation; // orientation of bunny
|
||||||
|
|
||||||
|
// Global Variables
|
||||||
|
float DeltaT = 0.1f;
|
||||||
|
float FPS;
|
||||||
|
int Width = 512;
|
||||||
|
int Height = 512;
|
||||||
|
int MouseX = 0;
|
||||||
|
int MouseY = 0;
|
||||||
|
Vector MouseVector; // 3D direction mouse points
|
||||||
|
Vector OldMouseVector;
|
||||||
|
int MouseState=0; // true iff left button down
|
||||||
|
float ViewAngle=45.0f;
|
||||||
|
|
||||||
|
HDC hDC; /* device context */
|
||||||
|
HPALETTE hPalette = 0; /* custom palette (if needed) */
|
||||||
|
|
||||||
|
|
||||||
|
void CalcFPSDeltaT(){
|
||||||
|
static int timeinit=0;
|
||||||
|
static int start,start2,current,last;
|
||||||
|
static int frame=0, frame2=0;
|
||||||
|
if(!timeinit){
|
||||||
|
frame=0;
|
||||||
|
start=timeGetTime();
|
||||||
|
timeinit=1;
|
||||||
|
}
|
||||||
|
frame++;
|
||||||
|
frame2++;
|
||||||
|
current=timeGetTime(); // found in winmm.lib
|
||||||
|
double dif=(double)(current-start)/CLOCKS_PER_SEC;
|
||||||
|
double rv = (dif)? (double)frame/(double)dif:-1.0;
|
||||||
|
if(dif>2.0 && frame >10) {
|
||||||
|
start = start2;
|
||||||
|
frame = frame2;
|
||||||
|
start2 = timeGetTime();
|
||||||
|
frame2 = 0;
|
||||||
|
}
|
||||||
|
DeltaT = (float)(current-last)/CLOCKS_PER_SEC;
|
||||||
|
if(current==last) {
|
||||||
|
DeltaT = 0.1f/CLOCKS_PER_SEC; // it just cant be 0
|
||||||
|
}
|
||||||
|
// if(DeltaT>1.0) DeltaT=1.0;
|
||||||
|
FPS = (float)rv;
|
||||||
|
last = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ComputeMouseVector(){
|
||||||
|
OldMouseVector=MouseVector;
|
||||||
|
float spread = (float)tan(ViewAngle/2*3.14/180);
|
||||||
|
float y = spread * ((Height-MouseY)-Height/2.0f) /(Height/2.0f);
|
||||||
|
float x = spread * (MouseX-Width/2.0f) /(Height/2.0f);
|
||||||
|
Vector v(x ,y,-1);
|
||||||
|
// v=UserOrientation *v;
|
||||||
|
v=normalize(v);
|
||||||
|
MouseVector = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion VirtualTrackBall(Vector cop,Vector cor,Vector dir1,Vector dir2) {
|
||||||
|
// Implement track ball functionality to spin stuf on the screen
|
||||||
|
// cop center of projection
|
||||||
|
// cor center of rotation
|
||||||
|
// dir1 old mouse direction
|
||||||
|
// dir2 new mouse direction
|
||||||
|
// pretend there is a sphere around cor. Then find the points
|
||||||
|
// where dir1 and dir2 intersect that sphere. Find the
|
||||||
|
// rotation that takes the first point to the second.
|
||||||
|
float m;
|
||||||
|
// compute plane
|
||||||
|
Vector nrml = cor - cop;
|
||||||
|
// since trackball proportional to distance from cop
|
||||||
|
float fudgefactor = 1.0f/(magnitude(nrml) * 0.25f);
|
||||||
|
nrml = normalize(nrml);
|
||||||
|
float dist = -(nrml^cor);
|
||||||
|
Vector u= planelineintersection(nrml,dist,cop,cop+dir1);
|
||||||
|
u=u-cor;
|
||||||
|
u=u*fudgefactor;
|
||||||
|
m= magnitude(u);
|
||||||
|
if(m>1) {u=u*1.0f/m;}
|
||||||
|
else {
|
||||||
|
u=u - (nrml * (float)sqrt(1-m*m));
|
||||||
|
}
|
||||||
|
Vector v= planelineintersection(nrml,dist,cop,cop+dir2);
|
||||||
|
v=v-cor;
|
||||||
|
v=v*fudgefactor;
|
||||||
|
m= magnitude(v);
|
||||||
|
if(m>1) {v=v*1.0f/m;}
|
||||||
|
else {
|
||||||
|
v=v - (nrml * (float)sqrt(1-m*m));
|
||||||
|
}
|
||||||
|
Vector axis = u*v;
|
||||||
|
float angle;
|
||||||
|
m=magnitude(axis);
|
||||||
|
if(m>1)m=1; // avoid potential floating point error
|
||||||
|
Quaternion q(Vector(1.0f,0.0f,0.0f),0.0f);
|
||||||
|
if(m>0 && (angle=(float)asin(m))>3.14/180) {
|
||||||
|
axis = normalize(axis);
|
||||||
|
q=Quaternion(axis,angle);
|
||||||
|
}
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpinIt(){
|
||||||
|
// Change the orientation of the bunny according to mouse drag
|
||||||
|
Quaternion q=VirtualTrackBall(Vector(0,0,0),model_position,
|
||||||
|
OldMouseVector,MouseVector);
|
||||||
|
model_orientation=q*model_orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reshape(int width, int height){
|
||||||
|
// called initially and when the window changes size
|
||||||
|
Width=width;
|
||||||
|
Height=height;
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
gluPerspective(ViewAngle, (float)width/height, 0.1, 50.0);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintStats(){
|
||||||
|
char buf[1024];buf[0]='\0';
|
||||||
|
sprintf(buf,"FPS: %5.2f ",FPS);
|
||||||
|
PostString(buf,0,-1,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display(){
|
||||||
|
// main drawing routine - called every frame
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
// camera at default (zero) position and orientation
|
||||||
|
RenderModel();
|
||||||
|
PrintStats();
|
||||||
|
glLoadIdentity();
|
||||||
|
RenderStrings();
|
||||||
|
glPopMatrix();
|
||||||
|
glFlush();
|
||||||
|
SwapBuffers(hDC); /* nop if singlebuffered */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
static PAINTSTRUCT ps;
|
||||||
|
static GLboolean left = GL_FALSE; /* left button currently down? */
|
||||||
|
static GLboolean right = GL_FALSE; /* right button currently down? */
|
||||||
|
static int omx, omy, mx, my;
|
||||||
|
|
||||||
|
switch(uMsg) {
|
||||||
|
case WM_PAINT:
|
||||||
|
BeginPaint(hWnd, &ps);
|
||||||
|
EndPaint(hWnd, &ps);
|
||||||
|
return 0;
|
||||||
|
case WM_SIZE:
|
||||||
|
Reshape(LOWORD(lParam), HIWORD(lParam));
|
||||||
|
PostMessage(hWnd, WM_PAINT, 0, 0);
|
||||||
|
return 0;
|
||||||
|
case WM_CHAR:
|
||||||
|
switch (wParam) {
|
||||||
|
case 27: /* ESC key */
|
||||||
|
PostQuitMessage(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_LBUTTONDOWN:
|
||||||
|
/* if we don't set the capture we won't get mouse move
|
||||||
|
messages when the mouse moves outside the window. */
|
||||||
|
SetCapture(hWnd);
|
||||||
|
MouseX = LOWORD(lParam);
|
||||||
|
MouseY = HIWORD(lParam);
|
||||||
|
ComputeMouseVector();
|
||||||
|
MouseState = 1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_LBUTTONUP:
|
||||||
|
MouseX = LOWORD(lParam);
|
||||||
|
MouseY = HIWORD(lParam);
|
||||||
|
if(MouseX & 1 << 15) MouseX -= (1 << 16);
|
||||||
|
if(MouseY & 1 << 15) MouseY -= (1 << 16);
|
||||||
|
ComputeMouseVector();
|
||||||
|
if(MouseState) SpinIt();
|
||||||
|
MouseState=0;
|
||||||
|
/* remember to release the capture when we are finished. */
|
||||||
|
ReleaseCapture();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
|
MouseX = LOWORD(lParam);
|
||||||
|
MouseY = HIWORD(lParam);
|
||||||
|
/* Win32 is pretty braindead about the x, y position that
|
||||||
|
it returns when the mouse is off the left or top edge
|
||||||
|
of the window (due to them being unsigned). therefore,
|
||||||
|
roll the Win32's 0..2^16 pointer co-ord range to the
|
||||||
|
more amenable (and useful) 0..+/-2^15. */
|
||||||
|
if(MouseX & 1 << 15) MouseX -= (1 << 16);
|
||||||
|
if(MouseY & 1 << 15) MouseY -= (1 << 16);
|
||||||
|
ComputeMouseVector();
|
||||||
|
if(MouseState) SpinIt();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_PALETTECHANGED:
|
||||||
|
if (hWnd == (HWND)wParam) break;
|
||||||
|
/* fall through to WM_QUERYNEWPALETTE */
|
||||||
|
case WM_QUERYNEWPALETTE:
|
||||||
|
if (hPalette) {
|
||||||
|
UnrealizeObject(hPalette);
|
||||||
|
SelectPalette(hDC, hPalette, FALSE);
|
||||||
|
RealizePalette(hDC);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
case WM_CLOSE:
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND CreateOpenGLWindow(char* title)
|
||||||
|
{
|
||||||
|
// make a double-buffered, rgba, opengl window
|
||||||
|
int n, pf;
|
||||||
|
HWND hWnd;
|
||||||
|
WNDCLASS wc;
|
||||||
|
LOGPALETTE* lpPal;
|
||||||
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
static HINSTANCE hInstance = 0;
|
||||||
|
|
||||||
|
/* only register the window class once - use hInstance as a flag. */
|
||||||
|
if (!hInstance) {
|
||||||
|
hInstance = GetModuleHandle(NULL);
|
||||||
|
wc.style = CS_OWNDC;
|
||||||
|
wc.lpfnWndProc = (WNDPROC)WindowProc;
|
||||||
|
wc.cbClsExtra = 0;
|
||||||
|
wc.cbWndExtra = 0;
|
||||||
|
wc.hInstance = hInstance;
|
||||||
|
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
|
||||||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
wc.hbrBackground = NULL;
|
||||||
|
wc.lpszMenuName = NULL;
|
||||||
|
wc.lpszClassName = "OpenGL";
|
||||||
|
|
||||||
|
if (!RegisterClass(&wc)) {
|
||||||
|
MessageBox(NULL, "RegisterClass() failed: "
|
||||||
|
"Cannot register window class.",
|
||||||
|
"Error", MB_OK);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hWnd = CreateWindow("OpenGL", title, WS_OVERLAPPEDWINDOW |
|
||||||
|
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
||||||
|
0,0,Width,Height, NULL, NULL, hInstance, NULL);
|
||||||
|
|
||||||
|
if (hWnd == NULL) {
|
||||||
|
MessageBox(NULL,
|
||||||
|
"CreateWindow() failed: Cannot create a window.",
|
||||||
|
"Error", MB_OK);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
hDC = GetDC(hWnd);
|
||||||
|
|
||||||
|
/* there is no guarantee that the contents of the stack that become
|
||||||
|
the pfd are zeroed, therefore _make sure_ to clear these bits. */
|
||||||
|
memset(&pfd, 0, sizeof(pfd));
|
||||||
|
pfd.nSize = sizeof(pfd);
|
||||||
|
pfd.nVersion = 1;
|
||||||
|
pfd.dwFlags = PFD_DRAW_TO_WINDOW
|
||||||
|
| PFD_SUPPORT_OPENGL
|
||||||
|
| PFD_DOUBLEBUFFER;
|
||||||
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||||
|
pfd.cDepthBits = 32;
|
||||||
|
pfd.cColorBits = 32;
|
||||||
|
|
||||||
|
pf = ChoosePixelFormat(hDC, &pfd);
|
||||||
|
if (pf == 0) {
|
||||||
|
MessageBox(NULL, "ChoosePixelFormat() failed: "
|
||||||
|
"Cannot find a suitable pixel format.",
|
||||||
|
"Error", MB_OK);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
|
||||||
|
MessageBox(NULL, "SetPixelFormat() failed: "
|
||||||
|
"Cannot set format specified.", "Error", MB_OK);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
|
||||||
|
|
||||||
|
if (pfd.dwFlags & PFD_NEED_PALETTE ||
|
||||||
|
pfd.iPixelType == PFD_TYPE_COLORINDEX) {
|
||||||
|
|
||||||
|
n = 1 << pfd.cColorBits;
|
||||||
|
if (n > 256) n = 256;
|
||||||
|
|
||||||
|
lpPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +
|
||||||
|
sizeof(PALETTEENTRY) * n);
|
||||||
|
memset(lpPal, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n);
|
||||||
|
lpPal->palVersion = 0x300;
|
||||||
|
lpPal->palNumEntries = n;
|
||||||
|
|
||||||
|
GetSystemPaletteEntries(hDC, 0, n, &lpPal->palPalEntry[0]);
|
||||||
|
|
||||||
|
/* if the pixel type is RGBA, then we want to make an RGB ramp,
|
||||||
|
otherwise (color index) set individual colors. */
|
||||||
|
if (pfd.iPixelType == PFD_TYPE_RGBA) {
|
||||||
|
int redMask = (1 << pfd.cRedBits) - 1;
|
||||||
|
int greenMask = (1 << pfd.cGreenBits) - 1;
|
||||||
|
int blueMask = (1 << pfd.cBlueBits) - 1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* fill in the entries with an RGB color ramp. */
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
lpPal->palPalEntry[i].peRed =
|
||||||
|
(((i >> pfd.cRedShift) & redMask) * 255)
|
||||||
|
/redMask;
|
||||||
|
lpPal->palPalEntry[i].peGreen =
|
||||||
|
(((i >> pfd.cGreenShift) & greenMask) * 255)
|
||||||
|
/greenMask;
|
||||||
|
lpPal->palPalEntry[i].peBlue =
|
||||||
|
(((i >> pfd.cBlueShift) & blueMask) * 255)
|
||||||
|
/blueMask;
|
||||||
|
lpPal->palPalEntry[i].peFlags = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lpPal->palPalEntry[0].peRed = 0;
|
||||||
|
lpPal->palPalEntry[0].peGreen = 0;
|
||||||
|
lpPal->palPalEntry[0].peBlue = 0;
|
||||||
|
lpPal->palPalEntry[0].peFlags = PC_NOCOLLAPSE;
|
||||||
|
lpPal->palPalEntry[1].peRed = 255;
|
||||||
|
lpPal->palPalEntry[1].peGreen = 0;
|
||||||
|
lpPal->palPalEntry[1].peBlue = 0;
|
||||||
|
lpPal->palPalEntry[1].peFlags = PC_NOCOLLAPSE;
|
||||||
|
lpPal->palPalEntry[2].peRed = 0;
|
||||||
|
lpPal->palPalEntry[2].peGreen = 255;
|
||||||
|
lpPal->palPalEntry[2].peBlue = 0;
|
||||||
|
lpPal->palPalEntry[2].peFlags = PC_NOCOLLAPSE;
|
||||||
|
lpPal->palPalEntry[3].peRed = 0;
|
||||||
|
lpPal->palPalEntry[3].peGreen = 0;
|
||||||
|
lpPal->palPalEntry[3].peBlue = 255;
|
||||||
|
lpPal->palPalEntry[3].peFlags = PC_NOCOLLAPSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hPalette = CreatePalette(lpPal);
|
||||||
|
if (hPalette) {
|
||||||
|
SelectPalette(hDC, hPalette, FALSE);
|
||||||
|
RealizePalette(hDC);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(lpPal);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseDC(hDC, hWnd);
|
||||||
|
return hWnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
|
||||||
|
LPSTR lpszCmdLine, int nCmdShow)
|
||||||
|
{
|
||||||
|
HGLRC hRC; /* opengl context */
|
||||||
|
HWND hWnd; /* window */
|
||||||
|
MSG msg; /* message */
|
||||||
|
|
||||||
|
// InitModel() initializes some data structures and
|
||||||
|
// does the progressive mesh polygon reduction algorithm
|
||||||
|
// on the model.
|
||||||
|
CalcFPSDeltaT(); // to time the algorithm
|
||||||
|
InitModel();
|
||||||
|
CalcFPSDeltaT();
|
||||||
|
|
||||||
|
hWnd = CreateOpenGLWindow("bunnylod by Stan Melax");
|
||||||
|
if (hWnd == NULL) exit(1);
|
||||||
|
|
||||||
|
hDC = GetDC(hWnd);
|
||||||
|
hRC = wglCreateContext(hDC);
|
||||||
|
wglMakeCurrent(hDC, hRC);
|
||||||
|
ShowWindow(hWnd, nCmdShow);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
PostString("Demo by Stan Melax (c)1998",5,-5,20);
|
||||||
|
PostString("Model by Viewpoint Datalabs (c)1996",5,-4,20);
|
||||||
|
char buf[128];
|
||||||
|
PostString("Mesh Reduction Algorithm (non-optimized)",1,0,5);
|
||||||
|
sprintf(buf,"was executed in %5.3f seconds",DeltaT);
|
||||||
|
PostString(buf,2,1,6);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
while(PeekMessage(&msg, hWnd, 0, 0, PM_NOREMOVE)) {
|
||||||
|
if(GetMessage(&msg, hWnd, 0, 0)) {
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
} else {
|
||||||
|
// This 'goto' was in the sample code
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CalcFPSDeltaT();
|
||||||
|
Display();
|
||||||
|
}
|
||||||
|
|
||||||
|
quit:
|
||||||
|
wglMakeCurrent(NULL, NULL);
|
||||||
|
ReleaseDC(hDC, hWnd);
|
||||||
|
wglDeleteContext(hRC);
|
||||||
|
DestroyWindow(hWnd);
|
||||||
|
if (hPalette) DeleteObject(hPalette);
|
||||||
|
return msg.wParam;
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: dev |
|
||||||
|
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class polyBoundaryMesh;
|
||||||
|
location "constant/polyMesh";
|
||||||
|
object boundary;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
6
|
||||||
|
(
|
||||||
|
inlet
|
||||||
|
{
|
||||||
|
type patch;
|
||||||
|
nFaces 840;
|
||||||
|
startFace 96680;
|
||||||
|
}
|
||||||
|
outlet
|
||||||
|
{
|
||||||
|
type patch;
|
||||||
|
nFaces 840;
|
||||||
|
startFace 97520;
|
||||||
|
}
|
||||||
|
innerWall
|
||||||
|
{
|
||||||
|
type wall;
|
||||||
|
nFaces 2480;
|
||||||
|
startFace 98360;
|
||||||
|
}
|
||||||
|
outerWall
|
||||||
|
{
|
||||||
|
type wall;
|
||||||
|
nFaces 880;
|
||||||
|
startFace 100840;
|
||||||
|
}
|
||||||
|
cyclic_half0
|
||||||
|
{
|
||||||
|
type cyclic;
|
||||||
|
nFaces 1600;
|
||||||
|
startFace 101720;
|
||||||
|
neighbourPatch cyclic_half1;
|
||||||
|
}
|
||||||
|
cyclic_half1
|
||||||
|
{
|
||||||
|
type cyclic;
|
||||||
|
nFaces 1600;
|
||||||
|
startFace 103320;
|
||||||
|
neighbourPatch cyclic_half0;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Reference in New Issue
Block a user