Initial source commit
This commit is contained in:
commit
f1384c11ee
335 changed files with 52715 additions and 0 deletions
138
minorGems/graphics/3d/LandscapePrimitive3D.h
Normal file
138
minorGems/graphics/3d/LandscapePrimitive3D.h
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Modification History
|
||||
*
|
||||
* 2001-January-9 Jason Rohrer
|
||||
* Created. Copied from LandscapePrimitiveGL, which this class will replace
|
||||
*
|
||||
* 2001-January-15 Jason Rohrer
|
||||
* Fixed a bug in the constructor.
|
||||
*
|
||||
* 2001-January-17 Jason Rohrer
|
||||
* Fliped how x and y in height map correspond to x and z in the terrain.
|
||||
*
|
||||
* 2001-January-19 Jason Rohrer
|
||||
* Changed to support multi-texturing.
|
||||
*
|
||||
* 2001-January-30 Jason Rohrer
|
||||
* Fixed a bug that occurs when the class defaults to no detail texture.
|
||||
*
|
||||
* 2001-March-11 Jason Rohrer
|
||||
* Fixed a bug in the texture map anchor points.
|
||||
*/
|
||||
|
||||
#ifndef LANDSCAPE_PRIMITIVE_3D_INCLUDED
|
||||
#define LANDSCAPE_PRIMITIVE_3D_INCLUDED
|
||||
|
||||
#include "Primitive3D.h"
|
||||
|
||||
/**
|
||||
* Primitive 3D lanscape object.
|
||||
*
|
||||
* Made from a height map. Mesh generated spans both x and z between -1 and
|
||||
* 1, and can vary in height (y) from 0 to 1.
|
||||
*
|
||||
* @author Jason Rohrer
|
||||
*/
|
||||
class LandscapePrimitive3D : public Primitive3D {
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a LandscapePrimitive with a multi-layer texture.
|
||||
*
|
||||
* @param inWide width of mesh in number of vertices.
|
||||
* Must be even and at least 2.
|
||||
* @param inHigh height of mesh in number of vertices.
|
||||
* @param inHeights array of heights for each vertex, each in
|
||||
* [0,1]. Must be destroyed by caller.
|
||||
* @param inTexture the texture to map onto the lanscape.
|
||||
* Texture is anchored by its corners to the corners of the
|
||||
* lanscape. inTexture is destroyed when primitive is destroyed.
|
||||
* @param inDetailTexture the second layer in the multi-texture.
|
||||
* The alpha channel of inDetailTexture will be used as
|
||||
* the blending factor to mix the detail with the global texture.
|
||||
* Set to NULL to use only a single layer.
|
||||
* @param inDetailScale the scale factor of the detailed texture.
|
||||
* Setting to 1.0 will anchor the detail at the corners of the
|
||||
* mesh (just like inTexture). Setting to 0.25 will cause
|
||||
* the detail texture to cycle 4 times across the surface of the
|
||||
* mesh.
|
||||
*/
|
||||
LandscapePrimitive3D( int inWide, int inHigh, double *inHeights,
|
||||
RGBAImage *inTexture, RGBAImage *inDetailTexture = NULL,
|
||||
double inDetailScale = 1.0 );
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline LandscapePrimitive3D::LandscapePrimitive3D( int inWide,
|
||||
int inHigh, double *inHeights,
|
||||
RGBAImage *inTexture, RGBAImage *inDetailTexture,
|
||||
double inDetailScale ) {
|
||||
|
||||
// first, set Primitve3D members
|
||||
mHigh = inHigh;
|
||||
mWide = inWide;
|
||||
mNumVertices = mHigh * mWide;
|
||||
|
||||
if( inDetailTexture == NULL ) {
|
||||
mNumTextures = 1;
|
||||
mTexture = new RGBAImage*[1];
|
||||
mTexture[0] = inTexture;
|
||||
|
||||
mAnchorX = new double*[1];
|
||||
mAnchorY = new double*[1];
|
||||
mAnchorX[0] = new double[mNumVertices];
|
||||
mAnchorY[0] = new double[mNumVertices];
|
||||
}
|
||||
else {
|
||||
mNumTextures = 2;
|
||||
mTexture = new RGBAImage*[2];
|
||||
mTexture[0] = inTexture;
|
||||
mTexture[1] = inDetailTexture;
|
||||
|
||||
mAnchorX = new double*[2];
|
||||
mAnchorY = new double*[2];
|
||||
mAnchorX[0] = new double[mNumVertices];
|
||||
mAnchorY[0] = new double[mNumVertices];
|
||||
mAnchorX[1] = new double[mNumVertices];
|
||||
mAnchorY[1] = new double[mNumVertices];
|
||||
}
|
||||
|
||||
|
||||
mVertices = new Vector3D*[mNumVertices];
|
||||
|
||||
// anchor at texture corners, and step linearly through texture
|
||||
double anchorYStep = 1.0 / ( mHigh - 1 );
|
||||
double anchorXStep = 1.0 / ( mWide - 1 );
|
||||
|
||||
double detailAnchorYStep = 1.0 / ( ( mHigh - 1 ) * inDetailScale );
|
||||
double detailAnchorXStep = 1.0 / ( ( mWide - 1 ) * inDetailScale );
|
||||
|
||||
for( int y=0; y<mHigh; y++ ) {
|
||||
for( int x=0; x<mWide; x++ ) {
|
||||
int index = y * mWide + x;
|
||||
|
||||
mAnchorX[0][index] = anchorXStep * x;
|
||||
mAnchorY[0][index] = anchorYStep * y;
|
||||
|
||||
if( mNumTextures == 2 ) {
|
||||
mAnchorX[1][index] = detailAnchorXStep * x;
|
||||
mAnchorY[1][index] = detailAnchorYStep * y;
|
||||
}
|
||||
|
||||
// add height for this x and y position
|
||||
mVertices[index] = new Vector3D( 2 * mAnchorX[0][index] - 1,
|
||||
inHeights[index], -2 * mAnchorY[0][index] + 1 );
|
||||
// note that y coordinates in the 2d height map must be
|
||||
// inverted before they can be used as z coordinates in the mesh
|
||||
}
|
||||
}
|
||||
|
||||
generateNormals();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
129
minorGems/graphics/3d/LathePrimitive3D.h
Normal file
129
minorGems/graphics/3d/LathePrimitive3D.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Modification History
|
||||
*
|
||||
* 2001-January-9 Jason Rohrer
|
||||
* Created. Copied from LathePrimitiveGL, which this class will replace.
|
||||
*
|
||||
* 2001-January-19 Jason Rohrer
|
||||
* Changed to support multi-texturing internally, though this primitive
|
||||
* type doesn't use it.
|
||||
*
|
||||
* 2001-January-21 Jason Rohrer
|
||||
* Fixed a bug in the constructor.
|
||||
*
|
||||
* 2001-January-31 Jason Rohrer
|
||||
* Got rid of an unused variable.
|
||||
*
|
||||
* 2001-March-11 Jason Rohrer
|
||||
* Fixed a bug in the texture map anchor points.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LATHE_PRIMITIVE_3D_INCLUDED
|
||||
#define LATHE_PRIMITIVE_3D_INCLUDED
|
||||
|
||||
#include "Primitive3D.h"
|
||||
|
||||
/**
|
||||
* Primitive 3D lathe object.
|
||||
*
|
||||
* Made of a curve rotated around an axis.
|
||||
*
|
||||
* @author Jason Rohrer
|
||||
*/
|
||||
class LathePrimitive3D : public Primitive3D {
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a LathePrimitive. The lathe curve is rotated
|
||||
* about the y axis.
|
||||
*
|
||||
* No parameters are copied, so they should not be destroyed
|
||||
* or re-accessed by caller. All are destroyed when the
|
||||
* primitive is destroyed.
|
||||
*
|
||||
* @param inNumCurvePoints number of points in curve to be lathed.
|
||||
* @param inCurvePoints points to be lathed. All z components
|
||||
* are set to 0 before lathing, so only x and y values matter.
|
||||
* @param inNumLatheSteps the number of quad segments around
|
||||
* the circumference of the lathed object. For example,
|
||||
* setting to 4 (with a lathe angle of 2pi)
|
||||
* will produce an extruded square object.
|
||||
* @param inNetLatheAngle total angle to sweep during lathing,
|
||||
* in (0,2pi].
|
||||
* @param inTexture the texture to map onto the lathed object.
|
||||
* Texture is anchored by its corners to the ends of the lath
|
||||
* curve at the beginning and end of the lathe sweep
|
||||
*/
|
||||
LathePrimitive3D( int inNumCurvePoints, Vector3D **inCurvePoints,
|
||||
int inNumLatheSteps, double inNetLatheAngle,
|
||||
RGBAImage *inTexture );
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline LathePrimitive3D::LathePrimitive3D( int inNumCurvePoints,
|
||||
Vector3D **inCurvePoints,
|
||||
int inNumLatheSteps, double inNetLatheAngle,
|
||||
RGBAImage *inTexture ) {
|
||||
|
||||
// first, set Primitve3D members
|
||||
mHigh = inNumCurvePoints;
|
||||
mWide = inNumLatheSteps + 1;
|
||||
mNumVertices = mHigh * mWide;
|
||||
|
||||
mNumTextures = 1;
|
||||
mTexture = new RGBAImage*[1];
|
||||
mTexture[0] = inTexture;
|
||||
|
||||
|
||||
double stepAngle = inNetLatheAngle / inNumLatheSteps;
|
||||
|
||||
int i;
|
||||
|
||||
// first, set all z values for control points to 0
|
||||
for( i=0; i<inNumCurvePoints; i++ ) {
|
||||
inCurvePoints[i]->mZ = 0;
|
||||
}
|
||||
|
||||
mVertices = new Vector3D*[mNumVertices];
|
||||
|
||||
mAnchorX = new double*[1];
|
||||
mAnchorY = new double*[1];
|
||||
mAnchorX[0] = new double[mNumVertices];
|
||||
mAnchorY[0] = new double[mNumVertices];
|
||||
|
||||
// anchor at texture corners, and step linearly through texture
|
||||
double anchorYStep = 1.0 / ( mHigh - 1 );
|
||||
double anchorXStep = 1.0 / ( mWide - 1 );
|
||||
|
||||
for( int y=0; y<mHigh; y++ ) {
|
||||
for( int x=0; x<mWide; x++ ) {
|
||||
int index = y * mWide + x;
|
||||
|
||||
mAnchorX[0][index] = anchorXStep * x;
|
||||
mAnchorY[0][index] = anchorYStep * y;
|
||||
|
||||
// copy curve into each lathe step
|
||||
mVertices[index] = new Vector3D( inCurvePoints[y] );
|
||||
|
||||
// rotate the copied curve by x steps around y-axis
|
||||
Angle3D *latheRotation = new Angle3D( 0, stepAngle * x, 0 );
|
||||
mVertices[index]->reverseRotate( latheRotation );
|
||||
|
||||
delete latheRotation;
|
||||
}
|
||||
|
||||
// cleanup as we go along
|
||||
delete inCurvePoints[y];
|
||||
}
|
||||
|
||||
delete [] inCurvePoints;
|
||||
|
||||
generateNormals();
|
||||
}
|
||||
|
||||
#endif
|
349
minorGems/graphics/3d/Object3D.h
Normal file
349
minorGems/graphics/3d/Object3D.h
Normal file
|
@ -0,0 +1,349 @@
|
|||
/*
|
||||
* Modification History
|
||||
*
|
||||
* 2001-January-9 Jason Rohrer
|
||||
* Created. Copied from ObjectGL.
|
||||
*
|
||||
* 2001-January-10 Jason Rohrer
|
||||
* Made class serializable. Added a parameterless constructor
|
||||
* to facilitate deserialization.
|
||||
*
|
||||
* 2001-January-15 Jason Rohrer
|
||||
* Fixed several bugs in the deserialize() function, as well as in the
|
||||
* destructor.
|
||||
*
|
||||
* 2001-January-16 Jason Rohrer
|
||||
* Changed to use a Transform3D instead of Vectors, Angles, and scales for
|
||||
* each primitive in the object.
|
||||
*
|
||||
* 2001-January-24 Jason Rohrer
|
||||
* Added a copy() function.
|
||||
* Fixed a bug in deserialize().
|
||||
* Made mMembersAllocated public for copy function.
|
||||
*
|
||||
* 2001-January-26 Jason Rohrer
|
||||
* Fixed a bug in copy().
|
||||
*
|
||||
* 2001-January-31 Jason Rohrer
|
||||
* Fixed bugs in serialize() and deserialize().
|
||||
*
|
||||
* 2001-February-3 Jason Rohrer
|
||||
* Updated serialization code to use new interfaces.
|
||||
*
|
||||
* 2001-March-11 Jason Rohrer
|
||||
* Added support for paramatization and temporal animations.
|
||||
*
|
||||
* 2001-March-13 Jason Rohrer
|
||||
* Added interface for getting the number of parameters and animations.
|
||||
*
|
||||
* 2001-March-14 Jason Rohrer
|
||||
* Added use of Primitive3DFactory for typed subclass primitive
|
||||
* de/serialization.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef OBJECT_3D_INCLUDED
|
||||
#define OBJECT_3D_INCLUDED
|
||||
|
||||
#include "Primitive3D.h"
|
||||
#include "minorGems/math/geometry/Transform3D.h"
|
||||
|
||||
#include "minorGems/io/Serializable.h"
|
||||
|
||||
#include "Primitive3DFactory.h"
|
||||
|
||||
/**
|
||||
* 3D object.
|
||||
*
|
||||
* Comprised of a collection of primitives.
|
||||
*
|
||||
* @author Jason Rohrer
|
||||
*/
|
||||
class Object3D : public Serializable {
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an Object.
|
||||
*
|
||||
* No parameters are copied, so they should not be destroyed
|
||||
* or re-accessed by caller. All are destroyed when the
|
||||
* object is destroyed.
|
||||
*
|
||||
* @param inNumPrimitives the number of primitives in this object.
|
||||
* @param inPrimitives the primitives comprising this object.
|
||||
* @param inTransform a transform for each object.
|
||||
*/
|
||||
Object3D( long inNumPrimitives, Primitive3D **inPrimitives,
|
||||
Transform3D **inTransform );
|
||||
|
||||
Object3D();
|
||||
|
||||
~Object3D();
|
||||
|
||||
|
||||
/**
|
||||
* Copies this object.
|
||||
*
|
||||
* @return a copy of this object, which must be destroyed
|
||||
* by the caller.
|
||||
*/
|
||||
Object3D *copy();
|
||||
|
||||
|
||||
/**
|
||||
* Gets the number of parameters associated with this object.
|
||||
*
|
||||
* @return the number of parameters.
|
||||
*/
|
||||
virtual int getNumParameters();
|
||||
|
||||
|
||||
/**
|
||||
* Gets the number of animations associated with this object.
|
||||
*
|
||||
* @return the number of animations.
|
||||
*/
|
||||
virtual int getNumAnimations();
|
||||
|
||||
|
||||
/*
|
||||
* Note that the default implementations for all the parameter
|
||||
* and temporal animation functions do nothing.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets a parameter for this object.
|
||||
*
|
||||
* @param inParameterIndex the index of the parameter to set.
|
||||
* If an index for a non-existing parameter is specified,
|
||||
* this call has no effect.
|
||||
* @param inValue the value to set the parameter to, in [-1, 1].
|
||||
* The default value for all parameters is 0.
|
||||
*/
|
||||
virtual void setParameter( int inParameterIndex, double inValue );
|
||||
|
||||
|
||||
/**
|
||||
* Gets a parameter for this object.
|
||||
*
|
||||
* @param inParameterIndex the index of the parameter to get.
|
||||
* If an index for a non-existing parameter is specified,
|
||||
* 0 is returned.
|
||||
*
|
||||
* @return the value of the parameter, in [-1, 1].
|
||||
* The default value for all parameters is 0.
|
||||
*/
|
||||
virtual double getParameter( int inParameterIndex );
|
||||
|
||||
|
||||
/**
|
||||
* Steps this object forward in time.
|
||||
*
|
||||
* @param inStepSize the size of the timestep to take.
|
||||
*/
|
||||
virtual void step( double inStepSize );
|
||||
|
||||
|
||||
/**
|
||||
* Starts a temporal animation of this object.
|
||||
* The animation progresses as step() is called repeatedly.
|
||||
* If called for a non-existent animation or for one that is
|
||||
* already running, this function has no effect.
|
||||
*/
|
||||
virtual void startAnimation( int inAnimationIndex );
|
||||
|
||||
|
||||
/**
|
||||
* Stops a temporal animation of this object. If called
|
||||
* for a non-existent animation or for one that is not currently
|
||||
* running, this function has no effect.
|
||||
*/
|
||||
virtual void stopAnimation( int inAnimationIndex );
|
||||
|
||||
|
||||
long mNumPrimitives;
|
||||
|
||||
Primitive3D **mPrimitives;
|
||||
|
||||
Transform3D **mTransform;
|
||||
|
||||
// implement the Serializable interface
|
||||
virtual int serialize( OutputStream *inOutputStream );
|
||||
virtual int deserialize( InputStream *inInputStream );
|
||||
|
||||
char mMembersAllocated;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline Object3D::Object3D( long inNumPrimitives, Primitive3D **inPrimitives,
|
||||
Transform3D **inTransform )
|
||||
: mNumPrimitives( inNumPrimitives ), mPrimitives( inPrimitives ),
|
||||
mTransform( inTransform ), mMembersAllocated( true ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline Object3D::Object3D()
|
||||
: mMembersAllocated( false ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline Object3D::~Object3D() {
|
||||
if( mMembersAllocated ) {
|
||||
for( int i=0; i<mNumPrimitives; i++ ) {
|
||||
delete mPrimitives[i];
|
||||
delete mTransform[i];
|
||||
}
|
||||
delete [] mTransform;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline Object3D *Object3D::copy() {
|
||||
Object3D *objCopy = new Object3D();
|
||||
|
||||
objCopy->mNumPrimitives = mNumPrimitives;
|
||||
|
||||
objCopy->mPrimitives = new Primitive3D*[ mNumPrimitives ];
|
||||
objCopy->mTransform = new Transform3D*[ mNumPrimitives ];
|
||||
|
||||
int i;
|
||||
for( i=0; i<mNumPrimitives; i++ ) {
|
||||
objCopy->mPrimitives[i] = mPrimitives[i]->copy();
|
||||
objCopy->mTransform[i] = new Transform3D( mTransform[i] );
|
||||
}
|
||||
|
||||
objCopy->mMembersAllocated = true;
|
||||
|
||||
return objCopy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int Object3D::getNumParameters() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int Object3D::getNumAnimations() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// the base class versions of these functions do nothing
|
||||
|
||||
inline void Object3D::setParameter( int inParameterIndex, double inValue ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline double Object3D::getParameter( int inParameterIndex ) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void Object3D::step( double inStepSize ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void Object3D::startAnimation( int inAnimationIndex ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void Object3D::stopAnimation( int inAnimationIndex ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int Object3D::serialize( OutputStream *inOutputStream ) {
|
||||
int i;
|
||||
int numBytes = 0;
|
||||
|
||||
numBytes += inOutputStream->writeLong( mNumPrimitives );
|
||||
|
||||
|
||||
// write each primitive
|
||||
for( i=0; i<mNumPrimitives; i++ ) {
|
||||
// write a type flag for each primitive
|
||||
long typeFlag =
|
||||
Primitive3DFactory::primitive3DToInt( mPrimitives[i] );
|
||||
numBytes += inOutputStream->writeLong( typeFlag );
|
||||
|
||||
// write the primitive
|
||||
numBytes += mPrimitives[i]->serialize( inOutputStream );
|
||||
}
|
||||
|
||||
// write each primitive's transform
|
||||
for( i=0; i<mNumPrimitives; i++ ) {
|
||||
numBytes += mTransform[i]->serialize( inOutputStream );
|
||||
}
|
||||
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int Object3D::deserialize( InputStream *inInputStream ) {
|
||||
|
||||
if( mMembersAllocated ) {
|
||||
// first, delete current contents of object
|
||||
for( int i=0; i<mNumPrimitives; i++ ) {
|
||||
delete mPrimitives[i];
|
||||
delete mTransform[i];
|
||||
}
|
||||
delete [] mPrimitives;
|
||||
delete [] mTransform;
|
||||
}
|
||||
|
||||
int i;
|
||||
int numBytes = 0;
|
||||
|
||||
numBytes += inInputStream->readLong( &mNumPrimitives );
|
||||
|
||||
printf( "receiving %d primitives\n", mNumPrimitives );
|
||||
mPrimitives = new Primitive3D*[mNumPrimitives];
|
||||
|
||||
for( i=0; i<mNumPrimitives; i++ ) {
|
||||
// read the type flag for this primitive
|
||||
long typeFlag;
|
||||
numBytes += inInputStream->readLong( &typeFlag );
|
||||
|
||||
// construct a new object based on the type flag
|
||||
mPrimitives[i] =
|
||||
Primitive3DFactory::intToPrimitive3D( typeFlag );
|
||||
|
||||
// deserialize it
|
||||
numBytes += mPrimitives[i]->deserialize( inInputStream );
|
||||
}
|
||||
|
||||
mTransform = new Transform3D*[mNumPrimitives];
|
||||
for( i=0; i<mNumPrimitives; i++ ) {
|
||||
mTransform[i] = new Transform3D();
|
||||
numBytes += mTransform[i]->deserialize( inInputStream );
|
||||
}
|
||||
|
||||
mMembersAllocated = true;
|
||||
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
129
minorGems/graphics/3d/Object3DFactory.h
Normal file
129
minorGems/graphics/3d/Object3DFactory.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Modification History
|
||||
*
|
||||
* 2001-March-14 Jason Rohrer
|
||||
* Created.
|
||||
*
|
||||
* 2001-March-17 Jason Rohrer
|
||||
* Finished implementation.
|
||||
*
|
||||
* 2001-April-1 Jason Rohrer
|
||||
* Fixed flag name.
|
||||
*/
|
||||
|
||||
#ifndef OBJECT_3D_FACTORY_INCLUDED
|
||||
#define OBJECT_3D_FACTORY_INCLUDED
|
||||
|
||||
#include "Object3D.h"
|
||||
|
||||
// Run-time type identification interface (RTTI)
|
||||
#include <typeinfo>
|
||||
|
||||
|
||||
// include these objects only if we are part of subreal
|
||||
#ifdef SUBREAL
|
||||
#include "subreal/entity/EntityObject3D.h"
|
||||
#define FACTORY_ENTITY_OBJECT_FLAG 1
|
||||
|
||||
#endif
|
||||
|
||||
// the default flag
|
||||
#define FACTORY_DEFAULT_OBJECT_FLAG 0
|
||||
|
||||
|
||||
/**
|
||||
* Class that maps Object3D integer subclass type flags to Object3D
|
||||
* subclass instances.
|
||||
*
|
||||
* Motivation for this class:
|
||||
* We have Object3D instances that exist simultaneously on opposite
|
||||
* sides of the network (at both the client and server ends). Initially,
|
||||
* we just let the objects get sent to the server via the base class
|
||||
* Object3D serialization function. At that time, subclasses of Object3D
|
||||
* did nothing more than init an Object3D in a particular way. This
|
||||
* worked fine when we didn't have animations associated with various
|
||||
* Object3D subclasses, but doesn't work now that we have animation
|
||||
* code in various subclasses. During serialization (if the object
|
||||
* is sent as a generic Object3D), the animation code is lost on
|
||||
* the client end. We need a way for the client to pick the correct
|
||||
* subclass to construct for deserialization. We can encode the
|
||||
* various subtypes by integers, and then this factory class can
|
||||
* be used to construct a class of appropriate subtype before
|
||||
* deserialization.
|
||||
*
|
||||
* @author Jason Rohrer
|
||||
*/
|
||||
class Object3DFactory {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Finds an integer subclass type flag for an object instance.
|
||||
*
|
||||
* @param inObject the object to determine a flag for. Must
|
||||
* be destroyed by the caller.
|
||||
*
|
||||
* @return a type flag for inObject. 0 (the defautl Object3D
|
||||
* baseclass flag) will be returned if subclass determination fails.
|
||||
*/
|
||||
static int object3DToInt( Object3D *inObject );
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new, unitialized Object3D (in other words,
|
||||
* an Object3D ready for deserialization) of a subclass
|
||||
* type matching inTypeFlag.
|
||||
*
|
||||
* @param inTypeFlag the type flag specifying the class
|
||||
* of the returned object.
|
||||
*
|
||||
* @return an (unitialized) Object3D class instance with a
|
||||
* subclass type corresponding to inTypeFlag. If no
|
||||
* matching class is found, a default Object3D baseclass
|
||||
* instance is returned. Must be destroyed by the caller.
|
||||
*/
|
||||
static Object3D *intToObject3D( int inTypeFlag );
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline int Object3DFactory::object3DToInt( Object3D *inObject ) {
|
||||
|
||||
// use RTTI to determine type of inObject
|
||||
|
||||
#ifdef SUBREAL
|
||||
if( typeid( *inObject ) == typeid( EntityObject3D ) ) {
|
||||
return FACTORY_ENTITY_OBJECT_FLAG;
|
||||
}
|
||||
#endif
|
||||
// else return the default flag
|
||||
return FACTORY_DEFAULT_OBJECT_FLAG;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline Object3D *Object3DFactory::intToObject3D( int inTypeFlag ) {
|
||||
switch( inTypeFlag ) {
|
||||
case FACTORY_DEFAULT_OBJECT_FLAG:
|
||||
return new Object3D();
|
||||
break;
|
||||
|
||||
/* these objects are only defined if
|
||||
* we are part of subreal
|
||||
*/
|
||||
#ifdef SUBREAL
|
||||
case FACTORY_ENTITY_OBJECT_FLAG:
|
||||
return new EntityObject3D();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
// unknown object flag type
|
||||
return new Object3D();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
676
minorGems/graphics/3d/Primitive3D.h
Normal file
676
minorGems/graphics/3d/Primitive3D.h
Normal file
|
@ -0,0 +1,676 @@
|
|||
/*
|
||||
* Modification History
|
||||
*
|
||||
* 2001-January-9 Jason Rohrer
|
||||
* Created.
|
||||
*
|
||||
* 2001-January-10 Jason Rohrer
|
||||
* Made class serializable.
|
||||
* Added a mMembersAllocated flag and made parameterless constructor
|
||||
* public to help with deserialization.
|
||||
*
|
||||
* 2001-January-15 Jason Rohrer
|
||||
* Fixed a bug in the deserialize() function.
|
||||
*
|
||||
* 2001-January-16 Jason Rohrer
|
||||
* Fixed a bug in the anchor serialization code.
|
||||
*
|
||||
* 2001-January-19 Jason Rohrer
|
||||
* Changed to support multi-texturing.
|
||||
*
|
||||
* 2001-January-24 Jason Rohrer
|
||||
* Added a copy() function.
|
||||
* Fixed a bug in deserialize().
|
||||
* Made mMembersAllocated public for copy function.
|
||||
*
|
||||
* 2001-February-3 Jason Rohrer
|
||||
* Updated serialization code to use new interfaces.
|
||||
*
|
||||
* 2001-March-11 Jason Rohrer
|
||||
* Added support for paramatization and temporal animations.
|
||||
*
|
||||
* 2001-March-13 Jason Rohrer
|
||||
* Added interface for getting the number of parameters and animations.
|
||||
*
|
||||
* 2001-April-1 Jason Rohrer
|
||||
* Made copy function virtual. Added a getNewInstance function
|
||||
* to make derived-class-specific copying easier.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PRIMITIVE_3D_INCLUDED
|
||||
#define PRIMITIVE_3D_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "minorGems/graphics/RGBAImage.h"
|
||||
#include "minorGems/math/geometry/Angle3D.h"
|
||||
|
||||
#include "minorGems/math/geometry/Vector3D.h"
|
||||
#include "minorGems/math/geometry/Angle3D.h"
|
||||
|
||||
#include "minorGems/io/Serializable.h"
|
||||
|
||||
/**
|
||||
* 3D primitive object.
|
||||
*
|
||||
* Comprised of a triangle mesh, texture map, and anchor points.
|
||||
*
|
||||
* @author Jason Rohrer
|
||||
*/
|
||||
class Primitive3D : public Serializable {
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a Primitive.
|
||||
*
|
||||
* No parameters are copied, so they should not be destroyed
|
||||
* or re-accessed by caller. All are destroyed when the
|
||||
* primitive is destroyed.
|
||||
*
|
||||
* @param inWide width of mesh in number of vertices.
|
||||
* Must be even and at least 2.
|
||||
* @param inHigh height of mesh in number of vertices.
|
||||
* @param inVertices vertices in row-major order.
|
||||
* @param inNumTextures number of multi-texture layers for
|
||||
* this primitive.
|
||||
* @param inTexture array of textures to map onto mesh.
|
||||
* Note that no RGBAImage in this array should have a
|
||||
* selection in it.
|
||||
* @param inAnchorX x texture anchors for each texture and
|
||||
* each vertex (indexed as inAnchorX[textNum][vertNum]),
|
||||
* in range [0,1] (outside this range, texture will wrap).
|
||||
* @param inAnchorY y texture anchors for each texture and
|
||||
* each vertex (indexed as inAnchorY[textNum][vertNum]),
|
||||
* in range [0,1] (outside this range, texture will wrap).
|
||||
*/
|
||||
Primitive3D( long inWide, long inHigh, Vector3D **inVertices,
|
||||
long inNumTextures, RGBAImage **inTexture,
|
||||
double **inAnchorX, double **inAnchorY );
|
||||
|
||||
|
||||
// construct without initializing any members
|
||||
// for use by subclasses and for deserialization.
|
||||
Primitive3D();
|
||||
char mMembersAllocated;
|
||||
|
||||
|
||||
~Primitive3D();
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether this primitive is transparent or not. Default
|
||||
* is not transparent.
|
||||
*
|
||||
* @param inTransparent true if this primitive is transparent.
|
||||
*/
|
||||
void setTransparent( char inTransparent );
|
||||
|
||||
|
||||
/**
|
||||
* Gets whether this primitive is transparent or not.
|
||||
*
|
||||
* @return true iff this primitive is transparent.
|
||||
*/
|
||||
char isTransparent();
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether this primitive's back face is visible. Default
|
||||
* is not visible.
|
||||
*
|
||||
* @param inIsVisible true if the back face is visible.
|
||||
*/
|
||||
void setBackVisible( char inIsVisible );
|
||||
|
||||
|
||||
/**
|
||||
* Gets whether this primitive's back face is visible or not.
|
||||
*
|
||||
* @return true iff the back face is visible.
|
||||
*/
|
||||
char isBackVisible();
|
||||
|
||||
|
||||
/**
|
||||
* Gets a new instance of the derived class type.
|
||||
*
|
||||
* Should be equivalent to calling the default constructor
|
||||
* for the derived class type.
|
||||
*
|
||||
* Should be overridden by all derived classes that
|
||||
* have data members beyond those provided by Primitive3D.
|
||||
* Note that if the extra data members require copying,
|
||||
* then the copy() function should be overridden instead
|
||||
* of simply overriding this function.
|
||||
*
|
||||
* Primitive3D::copy() will use this function to produce
|
||||
* a class instance before doing a copy.
|
||||
*
|
||||
* Note that this functionality SHOULD be provided by
|
||||
* the built-in RTTI, but it doesn't seem to be.
|
||||
*
|
||||
* @return an instance of the derived class.
|
||||
*/
|
||||
virtual Primitive3D *getNewInstance();
|
||||
|
||||
|
||||
/**
|
||||
* Copies this primitive.
|
||||
*
|
||||
* @return a copy of this primitive, which must be destroyed
|
||||
* by the caller.
|
||||
*/
|
||||
virtual Primitive3D *copy();
|
||||
|
||||
/**
|
||||
* Gets the number of parameters associated with this object.
|
||||
*
|
||||
* @return the number of parameters.
|
||||
*/
|
||||
virtual int getNumParameters();
|
||||
|
||||
|
||||
/**
|
||||
* Gets the number of animations associated with this object.
|
||||
*
|
||||
* @return the number of animations.
|
||||
*/
|
||||
virtual int getNumAnimations();
|
||||
|
||||
|
||||
/*
|
||||
* Note that the default implementations for all the parameter
|
||||
* and temporal animation functions do nothing.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets a parameter for this primative.
|
||||
*
|
||||
* @param inParameterIndex the index of the parameter to set.
|
||||
* If an index for a non-existing parameter is specified,
|
||||
* this call has no effect.
|
||||
* @param inValue the value to set the parameter to, in [-1, 1].
|
||||
* The default value for all parameters is 0.
|
||||
*/
|
||||
virtual void setParameter( int inParameterIndex, double inValue );
|
||||
|
||||
|
||||
/**
|
||||
* Gets a parameter for this primative.
|
||||
*
|
||||
* @param inParameterIndex the index of the parameter to get.
|
||||
* If an index for a non-existing parameter is specified,
|
||||
* 0 is returned.
|
||||
*
|
||||
* @return the value of the parameter, in [-1, 1].
|
||||
* The default value for all parameters is 0.
|
||||
*/
|
||||
virtual double getParameter( int inParameterIndex );
|
||||
|
||||
|
||||
/**
|
||||
* Steps this primitive forward in time.
|
||||
*
|
||||
* @param inStepSize the size of the timestep to take.
|
||||
*/
|
||||
virtual void step( double inStepSize );
|
||||
|
||||
|
||||
/**
|
||||
* Starts a temporal animation of this primitive.
|
||||
* The animation progresses as step() is called repeatedly.
|
||||
* If called for a non-existent animation or for one that is
|
||||
* already running, this function has no effect.
|
||||
*/
|
||||
virtual void startAnimation( int inAnimationIndex );
|
||||
|
||||
/**
|
||||
* Stops a temporal animation of this primitive. If called
|
||||
* for a non-existent animation or for one that is not currently
|
||||
* running, this function has no effect.
|
||||
*/
|
||||
virtual void stopAnimation( int inAnimationIndex );
|
||||
|
||||
|
||||
long mHigh, mWide;
|
||||
long mNumVertices;
|
||||
|
||||
Vector3D **mVertices;
|
||||
Vector3D **mNormals;
|
||||
|
||||
long mNumTextures;
|
||||
|
||||
// Note that no RGBAImage in this array should have a
|
||||
// selection in it.
|
||||
RGBAImage **mTexture;
|
||||
|
||||
double **mAnchorX;
|
||||
double **mAnchorY;
|
||||
|
||||
|
||||
// implement the Serializable interface
|
||||
virtual int serialize( OutputStream *inOutputStream );
|
||||
virtual int deserialize( InputStream *inInputStream );
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
/**
|
||||
* Generates standard normals from the vertices.
|
||||
*
|
||||
* If subclass is not generating normals, this
|
||||
* must be called before primitive is drawn, but after
|
||||
* the vertices have been initialized.
|
||||
*/
|
||||
void generateNormals();
|
||||
|
||||
|
||||
char mTransparent;
|
||||
char mBackVisible;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline Primitive3D::Primitive3D( long inWide, long inHigh,
|
||||
Vector3D **inVertices, long inNumTextures, RGBAImage **inTexture,
|
||||
double **inAnchorX, double **inAnchorY )
|
||||
: mHigh( inHigh ), mWide( inWide ), mNumVertices( inHigh * inWide ),
|
||||
mNumTextures( inNumTextures ), mVertices( inVertices ),
|
||||
mTexture( inTexture ), mAnchorX( inAnchorX ), mAnchorY( inAnchorY ),
|
||||
mTransparent( false ), mBackVisible( false ),
|
||||
mMembersAllocated( true ) {
|
||||
|
||||
generateNormals();
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline Primitive3D::Primitive3D()
|
||||
: mTransparent( false ), mBackVisible( false ),
|
||||
mMembersAllocated( false ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline Primitive3D::~Primitive3D() {
|
||||
if( mMembersAllocated ) {
|
||||
int i;
|
||||
for( i=0; i<mNumVertices; i++ ) {
|
||||
delete mVertices[i];
|
||||
delete mNormals[i];
|
||||
}
|
||||
for( i=0; i<mNumTextures; i++ ) {
|
||||
delete [] mAnchorX[i];
|
||||
delete [] mAnchorY[i];
|
||||
delete mTexture[i];
|
||||
}
|
||||
delete [] mVertices;
|
||||
delete [] mNormals;
|
||||
delete [] mAnchorX;
|
||||
delete [] mAnchorY;
|
||||
|
||||
delete [] mTexture;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void Primitive3D::generateNormals() {
|
||||
|
||||
mNormals = new Vector3D*[ mNumVertices ];
|
||||
|
||||
// for each non-edge vertex
|
||||
for( int y=0; y<mHigh; y++ ) {
|
||||
for( int x=0; x<mWide; x++ ) {
|
||||
int index = y * mWide + x;
|
||||
|
||||
// each point is adjacent to up to 4 other points, and thus
|
||||
// is part of up to 4 edges (or 8 edge pairs)
|
||||
|
||||
// if we sum the normals generated by taking the cross of
|
||||
// each edge pair, we'll have a good approximation of the
|
||||
// normal at this point.
|
||||
Vector3D *normalSum = new Vector3D( 0.0, 0.0, 0.0 );
|
||||
|
||||
// is there a more elegant way to do this?
|
||||
|
||||
Vector3D **edges = new Vector3D*[4];
|
||||
|
||||
// watch for boundary cases.
|
||||
// use NULL for any non-existing edge (i.e., at edge of mesh)
|
||||
|
||||
if( x != 0 ) {
|
||||
edges[0] = new Vector3D( mVertices[ index - 1 ] ); // x - 1
|
||||
}
|
||||
else {
|
||||
edges[0] = NULL;
|
||||
}
|
||||
|
||||
if( y != 0 ) {
|
||||
edges[1] = new Vector3D( mVertices[ index - mWide ] ); // y - 1
|
||||
}
|
||||
else {
|
||||
edges[1] = NULL;
|
||||
}
|
||||
|
||||
if( x != mWide - 1 ) {
|
||||
edges[2] = new Vector3D( mVertices[ index + 1 ] ); // x + 1
|
||||
}
|
||||
else {
|
||||
edges[2] = NULL;
|
||||
}
|
||||
|
||||
if( y != mHigh - 1 ) {
|
||||
edges[3] = new Vector3D( mVertices[ index + mWide ] ); // y + 1
|
||||
}
|
||||
else {
|
||||
edges[3] = NULL;
|
||||
}
|
||||
|
||||
int e;
|
||||
// subtract this vertex from each to get a directional vector
|
||||
for( e=0; e<4; e++ ) {
|
||||
if( edges[e] != NULL ) {
|
||||
edges[e]->subtract( mVertices[ index ] );
|
||||
}
|
||||
}
|
||||
|
||||
// now cross and add into sum
|
||||
for( e=0; e<4; e++ ) {
|
||||
if( edges[e] != NULL && edges[ (e+1) % 4 ] != NULL ) {
|
||||
// not that this order of crossing works
|
||||
// because our cross product is right handed
|
||||
Vector3D *normal = edges[e]->cross( edges[ (e+1) % 4 ] );
|
||||
normal->normalize();
|
||||
|
||||
// add this normal to our sum
|
||||
normalSum->add( normal );
|
||||
|
||||
delete normal;
|
||||
}
|
||||
}
|
||||
|
||||
// now delete edges
|
||||
for( e=0; e<4; e++ ) {
|
||||
if( edges[e] != NULL ) {
|
||||
delete edges[e];
|
||||
}
|
||||
}
|
||||
delete [] edges;
|
||||
|
||||
// save summed normal as normal for this point
|
||||
normalSum->normalize();
|
||||
mNormals[index] = normalSum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void Primitive3D::setTransparent( char inTransparent ) {
|
||||
mTransparent = inTransparent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline char Primitive3D::isTransparent() {
|
||||
return mTransparent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void Primitive3D::setBackVisible( char inIsVisible ) {
|
||||
mBackVisible = inIsVisible;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline char Primitive3D::isBackVisible() {
|
||||
return mBackVisible;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline Primitive3D *Primitive3D::getNewInstance() {
|
||||
return new Primitive3D();
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline Primitive3D *Primitive3D::copy() {
|
||||
// get an instance of the derived class, if they've
|
||||
// overridden getNewInstance()
|
||||
Primitive3D *primCopy = getNewInstance();
|
||||
|
||||
primCopy->mHigh = mHigh;
|
||||
primCopy->mWide = mWide;
|
||||
primCopy->mNumVertices = mNumVertices;
|
||||
|
||||
primCopy->mVertices = new Vector3D*[mNumVertices];
|
||||
primCopy->mNormals = new Vector3D*[mNumVertices];
|
||||
|
||||
int i;
|
||||
for( i=0; i<mNumVertices; i++ ) {
|
||||
primCopy->mVertices[i] = new Vector3D( mVertices[i] );
|
||||
primCopy->mNormals[i] = new Vector3D( mNormals[i] );
|
||||
}
|
||||
primCopy->mNumTextures = mNumTextures;
|
||||
|
||||
primCopy->mTexture = new RGBAImage*[mNumTextures];
|
||||
primCopy->mAnchorX = new double*[mNumTextures];
|
||||
primCopy->mAnchorY = new double*[mNumTextures];
|
||||
|
||||
for( i=0; i<mNumTextures; i++ ) {
|
||||
primCopy->mTexture[i] = mTexture[i]->copy();
|
||||
|
||||
primCopy->mAnchorX[i] = new double[mNumVertices];
|
||||
primCopy->mAnchorY[i] = new double[mNumVertices];
|
||||
|
||||
memcpy( primCopy->mAnchorX[i], mAnchorX[i],
|
||||
sizeof( double ) * mNumVertices );
|
||||
memcpy( primCopy->mAnchorY[i], mAnchorY[i],
|
||||
sizeof( double ) * mNumVertices );
|
||||
}
|
||||
primCopy->mMembersAllocated = true;
|
||||
|
||||
primCopy->setBackVisible( isBackVisible() );
|
||||
primCopy->setTransparent( isTransparent() );
|
||||
|
||||
return primCopy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int Primitive3D::getNumParameters() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int Primitive3D::getNumAnimations() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// the base class versions of these functions do nothing
|
||||
|
||||
inline void Primitive3D::setParameter( int inParameterIndex, double inValue ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline double Primitive3D::getParameter( int inParameterIndex ) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void Primitive3D::step( double inStepSize ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void Primitive3D::startAnimation( int inAnimationIndex ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void Primitive3D::stopAnimation( int inAnimationIndex ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int Primitive3D::serialize( OutputStream *inOutputStream ) {
|
||||
int numBytes = 0;
|
||||
|
||||
numBytes += inOutputStream->writeLong( mWide );
|
||||
numBytes += inOutputStream->writeLong( mHigh );
|
||||
|
||||
int i;
|
||||
|
||||
// output vertices and normals
|
||||
for( i=0; i<mNumVertices; i++ ) {
|
||||
numBytes += mVertices[i]->serialize( inOutputStream );
|
||||
}
|
||||
|
||||
for( i=0; i<mNumVertices; i++ ) {
|
||||
numBytes += mNormals[i]->serialize( inOutputStream );
|
||||
}
|
||||
|
||||
numBytes += inOutputStream->writeLong( mNumTextures );
|
||||
|
||||
// output textures
|
||||
for( i=0; i<mNumTextures; i++ ) {
|
||||
numBytes += mTexture[i]->serialize( inOutputStream );
|
||||
}
|
||||
|
||||
// output anchor arrays
|
||||
for( i=0; i<mNumTextures; i++ ) {
|
||||
for( int p=0; p<mNumVertices; p++ ) {
|
||||
numBytes += inOutputStream->writeDouble( mAnchorX[i][p] );
|
||||
}
|
||||
}
|
||||
|
||||
for( i=0; i<mNumTextures; i++ ) {
|
||||
for( int p=0; p<mNumVertices; p++ ) {
|
||||
numBytes += inOutputStream->writeDouble( mAnchorY[i][p] );
|
||||
}
|
||||
}
|
||||
|
||||
numBytes +=
|
||||
inOutputStream->write( (unsigned char *)&mTransparent, 1 );
|
||||
|
||||
numBytes +=
|
||||
inOutputStream->write( (unsigned char *)&mBackVisible, 1 );
|
||||
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int Primitive3D::deserialize( InputStream *inInputStream ) {
|
||||
int numBytes = 0;
|
||||
|
||||
int i;
|
||||
if( mMembersAllocated ) {
|
||||
// delete the old vertices, normals, and anchors
|
||||
for( i=0; i<mNumVertices; i++ ) {
|
||||
delete mVertices[i];
|
||||
delete mNormals[i];
|
||||
}
|
||||
for( i=0; i<mNumTextures; i++ ) {
|
||||
delete [] mAnchorX[i];
|
||||
delete [] mAnchorY[i];
|
||||
delete mTexture[i];
|
||||
}
|
||||
delete [] mVertices;
|
||||
delete [] mNormals;
|
||||
delete [] mAnchorX;
|
||||
delete [] mAnchorY;
|
||||
|
||||
delete [] mTexture;
|
||||
}
|
||||
|
||||
|
||||
int numBytesRead = 0;
|
||||
|
||||
unsigned char *intByteArray = new unsigned char[4];
|
||||
|
||||
numBytes += inInputStream->readLong( &mWide );
|
||||
numBytes += inInputStream->readLong( &mHigh );
|
||||
|
||||
mNumVertices = mHigh * mWide;
|
||||
|
||||
mVertices = new Vector3D*[mNumVertices];
|
||||
mNormals = new Vector3D*[mNumVertices];
|
||||
|
||||
|
||||
// input vertices and normals
|
||||
for( i=0; i<mNumVertices; i++ ) {
|
||||
mVertices[i] = new Vector3D( 0, 0, 0 );
|
||||
numBytes += mVertices[i]->deserialize( inInputStream );
|
||||
}
|
||||
|
||||
for( i=0; i<mNumVertices; i++ ) {
|
||||
mNormals[i] = new Vector3D( 0, 0, 0 );
|
||||
numBytes += mNormals[i]->deserialize( inInputStream );
|
||||
}
|
||||
|
||||
// input number of textures
|
||||
numBytes += inInputStream->readLong( &mNumTextures );
|
||||
|
||||
mAnchorX = new double*[mNumTextures];
|
||||
mAnchorY = new double*[mNumTextures];
|
||||
mTexture = new RGBAImage*[mNumTextures];
|
||||
|
||||
|
||||
// input textures
|
||||
for( i=0; i<mNumTextures; i++ ) {
|
||||
mTexture[i] = new RGBAImage( 0, 0 );
|
||||
numBytes += mTexture[i]->deserialize( inInputStream );
|
||||
}
|
||||
|
||||
// input anchor arrays
|
||||
for( i=0; i<mNumTextures; i++ ) {
|
||||
mAnchorX[i] = new double[mNumVertices];
|
||||
|
||||
for( int p=0; p<mNumVertices; p++ ) {
|
||||
numBytes += inInputStream->readDouble( &( mAnchorX[i][p] ) );
|
||||
}
|
||||
}
|
||||
|
||||
for( i=0; i<mNumTextures; i++ ) {
|
||||
mAnchorY[i] = new double[mNumVertices];
|
||||
|
||||
for( int p=0; p<mNumVertices; p++ ) {
|
||||
numBytes += inInputStream->readDouble( &( mAnchorY[i][p] ) );
|
||||
}
|
||||
}
|
||||
|
||||
numBytes +=
|
||||
inInputStream->read( (unsigned char *)&mTransparent, 1 );
|
||||
|
||||
numBytes +=
|
||||
inInputStream->read( (unsigned char *)&mBackVisible, 1 );
|
||||
|
||||
mMembersAllocated = true;
|
||||
|
||||
return numBytesRead;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
129
minorGems/graphics/3d/Primitive3DFactory.h
Normal file
129
minorGems/graphics/3d/Primitive3DFactory.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Modification History
|
||||
*
|
||||
* 2001-March-14 Jason Rohrer
|
||||
* Created.
|
||||
*
|
||||
* 2001-April-1 Jason Rohrer
|
||||
* Added subreal entity vane class to factory.
|
||||
*/
|
||||
|
||||
#ifndef PRIMITIVE_3D_FACTORY_INCLUDED
|
||||
#define PRIMITIVE_3D_FACTORY_INCLUDED
|
||||
|
||||
#include "Primitive3D.h"
|
||||
|
||||
// Run-time type identification interface (RTTI)
|
||||
#include <typeinfo>
|
||||
|
||||
|
||||
// include these primitives only if we are part of subreal
|
||||
#ifdef SUBREAL
|
||||
#include "subreal/entity/EntityBodyPrimitive3D.h"
|
||||
#define FACTORY_ENTITY_BODY_PRIMITIVE_FLAG 1
|
||||
#include "subreal/entity/EntityVanePrimitive3D.h"
|
||||
#define FACTORY_ENTITY_VANE_PRIMITIVE_FLAG 2
|
||||
|
||||
#endif
|
||||
|
||||
// the default flag
|
||||
#define FACTORY_DEFAULT_PRIMITIVE_FLAG 0
|
||||
|
||||
|
||||
/**
|
||||
* Class that maps Primitive3D integer subclass type flags to Primitive3D
|
||||
* subclass instances.
|
||||
*
|
||||
* Motivation for this class:
|
||||
* We want to extend Object3D to support subclass typed serialization
|
||||
* and deserialization without placing too much of a burden on
|
||||
* future Object3D subclasses. For instance, we don't want subclasses
|
||||
* to have to write their own de/serialization functions so that
|
||||
* particular Primitive3D subclasses are serialized correctly.
|
||||
* We can avoid this burden by writing the base Object3D serialization
|
||||
* code so that it uses this factory to transmit subclasses with
|
||||
* type informaton.
|
||||
*
|
||||
* @author Jason Rohrer
|
||||
*/
|
||||
class Primitive3DFactory {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Finds an integer subclass type flag for a primitive instance.
|
||||
*
|
||||
* @param inPrimitive the primitive to determine a flag for. Must
|
||||
* be destroyed by the caller.
|
||||
*
|
||||
* @return a type flag for inObject. 0 (the default Object3D
|
||||
* baseclass flag) will be returned if subclass determination fails.
|
||||
*/
|
||||
static int primitive3DToInt( Primitive3D *inPrimitive );
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new, unitialized Primitive3D (in other words,
|
||||
* an Primitive3D ready for deserialization) of a subclass
|
||||
* type matching inTypeFlag.
|
||||
*
|
||||
* @param inTypeFlag the type flag specifying the class
|
||||
* of the returned primitive.
|
||||
*
|
||||
* @return an (unitialized) Primitive3D class instance with a
|
||||
* subclass type corresponding to inTypeFlag. If no
|
||||
* matching class is found, a default Primitive3D baseclass
|
||||
* instance is returned. Must be destroyed by the caller.
|
||||
*/
|
||||
static Primitive3D *intToPrimitive3D( int inTypeFlag );
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline int Primitive3DFactory::primitive3DToInt( Primitive3D *inPrimitive ) {
|
||||
|
||||
// use RTTI to determine type of inPrimitive
|
||||
|
||||
#ifdef SUBREAL
|
||||
if( typeid( *inPrimitive ) == typeid( EntityBodyPrimitive3D ) ) {
|
||||
return FACTORY_ENTITY_BODY_PRIMITIVE_FLAG;
|
||||
}
|
||||
else if( typeid( *inPrimitive ) == typeid( EntityVanePrimitive3D ) ) {
|
||||
return FACTORY_ENTITY_VANE_PRIMITIVE_FLAG;
|
||||
}
|
||||
#endif
|
||||
|
||||
// else return the default flag
|
||||
return FACTORY_DEFAULT_PRIMITIVE_FLAG;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline Primitive3D *Primitive3DFactory::intToPrimitive3D( int inTypeFlag ) {
|
||||
switch( inTypeFlag ) {
|
||||
case FACTORY_DEFAULT_PRIMITIVE_FLAG:
|
||||
return new Primitive3D();
|
||||
break;
|
||||
|
||||
/* these primitives are only defined if
|
||||
* we are part of subreal
|
||||
*/
|
||||
#ifdef SUBREAL
|
||||
case FACTORY_ENTITY_BODY_PRIMITIVE_FLAG:
|
||||
return new EntityBodyPrimitive3D();
|
||||
break;
|
||||
case FACTORY_ENTITY_VANE_PRIMITIVE_FLAG:
|
||||
return new EntityVanePrimitive3D();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
// unknown primitive flag type
|
||||
return new Primitive3D();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue