1 /*
2  * Modification History
3  *
4  * 2001-January-9		Jason Rohrer
5  * Created.  Copied from ObjectGL.
6  *
7  * 2001-January-10		Jason Rohrer
8  * Made class serializable.  Added a parameterless constructor
9  * to facilitate deserialization.
10  *
11  * 2001-January-15		Jason Rohrer
12  * Fixed several bugs in the deserialize() function, as well as in the
13  * destructor.
14  *
15  * 2001-January-16		Jason Rohrer
16  * Changed to use a Transform3D instead of Vectors, Angles, and scales for
17  * each primitive in the object.
18  *
19  * 2001-January-24		Jason Rohrer
20  * Added a copy() function.
21  * Fixed a bug in deserialize().
22  * Made mMembersAllocated public for copy function.
23  *
24  * 2001-January-26		Jason Rohrer
25  * Fixed a bug in copy().
26  *
27  * 2001-January-31		Jason Rohrer
28  * Fixed bugs in serialize() and deserialize().
29  *
30  * 2001-February-3		Jason Rohrer
31  * Updated serialization code to use new interfaces.
32  *
33  * 2001-March-11   Jason Rohrer
34  * Added support for paramatization and temporal animations.
35  *
36  * 2001-March-13   Jason Rohrer
37  * Added interface for getting the number of parameters and animations.
38  *
39  * 2001-March-14   Jason Rohrer
40  * Added use of Primitive3DFactory for typed subclass primitive
41  * de/serialization.
42  */
43 
44 
45 #ifndef OBJECT_3D_INCLUDED
46 #define OBJECT_3D_INCLUDED
47 
48 #include "Primitive3D.h"
49 #include "minorGems/math/geometry/Transform3D.h"
50 
51 #include "minorGems/io/Serializable.h"
52 
53 #include "Primitive3DFactory.h"
54 
55 /**
56  * 3D object.
57  *
58  * Comprised of a collection of primitives.
59  *
60  * @author Jason Rohrer
61  */
62 class Object3D : public Serializable {
63 
64 	public:
65 
66 
67 		/**
68 		 * Constructs an Object.
69 		 *
70 		 * No parameters are copied, so they should not be destroyed
71 		 * or re-accessed by caller.  All are destroyed when the
72 		 * object is destroyed.
73 		 *
74 		 * @param inNumPrimitives the number of primitives in this object.
75 		 * @param inPrimitives the primitives comprising this object.
76 		 * @param inTransform a transform for each object.
77 		 */
78 		Object3D( long inNumPrimitives, Primitive3D **inPrimitives,
79 			Transform3D **inTransform );
80 
81 		Object3D();
82 
83 		~Object3D();
84 
85 
86 		/**
87 		 * Copies this object.
88 		 *
89 		 * @return a copy of this object, which must be destroyed
90 		 *   by the caller.
91 		 */
92 		Object3D *copy();
93 
94 
95 		/**
96 		 * Gets the number of parameters associated with this object.
97 		 *
98 		 * @return the number of parameters.
99 		 */
100 		virtual int getNumParameters();
101 
102 
103 		/**
104 		 * Gets the number of animations associated with this object.
105 		 *
106 		 * @return the number of animations.
107 		 */
108 		virtual int getNumAnimations();
109 
110 
111 		/*
112 		 * Note that the default implementations for all the parameter
113 		 * and temporal animation functions do nothing.
114 		 */
115 
116 		/**
117 		 * Sets a parameter for this object.
118 		 *
119 		 * @param inParameterIndex the index of the parameter to set.
120 		 *   If an index for a non-existing parameter is specified,
121 		 *   this call has no effect.
122 		 * @param inValue the value to set the parameter to, in [-1, 1].
123 		 *   The default value for all parameters is 0.
124 		 */
125 		virtual void setParameter( int inParameterIndex, double inValue );
126 
127 
128 		/**
129 		 * Gets a parameter for this object.
130 		 *
131 		 * @param inParameterIndex the index of the parameter to get.
132 		 *   If an index for a non-existing parameter is specified,
133 		 *   0 is returned.
134 		 *
135 		 * @return the value of the parameter, in [-1, 1].
136 		 *   The default value for all parameters is 0.
137 		 */
138 		virtual double getParameter( int inParameterIndex );
139 
140 
141 		/**
142 		 * Steps this object forward in time.
143 		 *
144 		 * @param inStepSize the size of the timestep to take.
145 		 */
146 		virtual void step( double inStepSize );
147 
148 
149 		/**
150 		 * Starts a temporal animation of this object.
151 		 * The animation progresses as step() is called repeatedly.
152 		 * If called for a non-existent animation or for one that is
153 		 * already running, this function has no effect.
154 		 */
155 		virtual void startAnimation( int inAnimationIndex );
156 
157 
158 		/**
159 		 * Stops a temporal animation of this object.  If called
160 		 * for a non-existent animation or for one that is not currently
161 		 * running, this function has no effect.
162 		 */
163 		virtual void stopAnimation( int inAnimationIndex );
164 
165 
166 		long mNumPrimitives;
167 
168 		Primitive3D **mPrimitives;
169 
170 		Transform3D **mTransform;
171 
172 		// implement the Serializable interface
173 		virtual int serialize( OutputStream *inOutputStream );
174 		virtual int deserialize( InputStream *inInputStream );
175 
176 		char mMembersAllocated;
177 
178 	};
179 
180 
181 
Object3D(long inNumPrimitives,Primitive3D ** inPrimitives,Transform3D ** inTransform)182 inline Object3D::Object3D( long inNumPrimitives, Primitive3D **inPrimitives,
183 	Transform3D **inTransform )
184 	: mNumPrimitives( inNumPrimitives ), mPrimitives( inPrimitives ),
185 	mTransform( inTransform ), mMembersAllocated( true ) {
186 
187 	}
188 
189 
190 
Object3D()191 inline Object3D::Object3D()
192 	: mMembersAllocated( false ) {
193 
194 	}
195 
196 
197 
~Object3D()198 inline Object3D::~Object3D() {
199 	if( mMembersAllocated ) {
200 		for( int i=0; i<mNumPrimitives; i++ ) {
201 			delete mPrimitives[i];
202 			delete mTransform[i];
203 			}
204 		delete [] mTransform;
205 		}
206 	}
207 
208 
209 
copy()210 inline Object3D *Object3D::copy() {
211 	Object3D *objCopy = new Object3D();
212 
213 	objCopy->mNumPrimitives = mNumPrimitives;
214 
215 	objCopy->mPrimitives = new Primitive3D*[ mNumPrimitives ];
216 	objCopy->mTransform = new Transform3D*[ mNumPrimitives ];
217 
218 	int i;
219 	for( i=0; i<mNumPrimitives; i++ ) {
220 		objCopy->mPrimitives[i] = mPrimitives[i]->copy();
221 		objCopy->mTransform[i] = new Transform3D( mTransform[i] );
222 		}
223 
224 	objCopy->mMembersAllocated = true;
225 
226 	return objCopy;
227 	}
228 
229 
230 
getNumParameters()231 inline int Object3D::getNumParameters() {
232 	return 0;
233 	}
234 
235 
236 
getNumAnimations()237 inline int Object3D::getNumAnimations() {
238 	return 0;
239 	}
240 
241 
242 
243 // the base class versions of these functions do nothing
244 
setParameter(int inParameterIndex,double inValue)245 inline void Object3D::setParameter( int inParameterIndex, double inValue ) {
246 
247 	}
248 
249 
250 
getParameter(int inParameterIndex)251 inline double Object3D::getParameter( int inParameterIndex ) {
252 
253 	return 0;
254 	}
255 
256 
257 
step(double inStepSize)258 inline void Object3D::step( double inStepSize ) {
259 
260 	}
261 
262 
263 
startAnimation(int inAnimationIndex)264 inline void Object3D::startAnimation( int inAnimationIndex ) {
265 
266 	}
267 
268 
269 
stopAnimation(int inAnimationIndex)270 inline void Object3D::stopAnimation( int inAnimationIndex ) {
271 
272 	}
273 
274 
275 
serialize(OutputStream * inOutputStream)276 inline int Object3D::serialize( OutputStream *inOutputStream ) {
277 	int i;
278 	int numBytes = 0;
279 
280 	numBytes += inOutputStream->writeLong( mNumPrimitives );
281 
282 
283 	// write each primitive
284 	for( i=0; i<mNumPrimitives; i++ ) {
285 		// write a type flag for each primitive
286 		long typeFlag =
287 			Primitive3DFactory::primitive3DToInt( mPrimitives[i] );
288 		numBytes += inOutputStream->writeLong( typeFlag );
289 
290 		// write the primitive
291 		numBytes += mPrimitives[i]->serialize( inOutputStream );
292 		}
293 
294 	// write each primitive's transform
295 	for( i=0; i<mNumPrimitives; i++ ) {
296 		numBytes += mTransform[i]->serialize( inOutputStream );
297 		}
298 
299 	return numBytes;
300 	}
301 
302 
303 
deserialize(InputStream * inInputStream)304 inline int Object3D::deserialize( InputStream *inInputStream ) {
305 
306 	if( mMembersAllocated ) {
307 		// first, delete current contents of object
308 		for( int i=0; i<mNumPrimitives; i++ ) {
309 			delete mPrimitives[i];
310 			delete mTransform[i];
311 			}
312 		delete [] mPrimitives;
313 		delete [] mTransform;
314 		}
315 
316 	int i;
317 	int numBytes = 0;
318 
319 	numBytes += inInputStream->readLong( &mNumPrimitives );
320 
321 	printf( "receiving %d primitives\n", mNumPrimitives );
322 	mPrimitives = new Primitive3D*[mNumPrimitives];
323 
324 	for( i=0; i<mNumPrimitives; i++ ) {
325 		// read the type flag for this primitive
326 		long typeFlag;
327 		numBytes += inInputStream->readLong( &typeFlag );
328 
329 		// construct a new object based on the type flag
330 		mPrimitives[i] =
331 			Primitive3DFactory::intToPrimitive3D( typeFlag );
332 
333 		// deserialize it
334 		numBytes += mPrimitives[i]->deserialize( inInputStream );
335 		}
336 
337 	mTransform = new Transform3D*[mNumPrimitives];
338 	for( i=0; i<mNumPrimitives; i++ ) {
339 		mTransform[i] = new Transform3D();
340 		numBytes += mTransform[i]->deserialize( inInputStream );
341 		}
342 
343 	mMembersAllocated = true;
344 
345 	return numBytes;
346 	}
347 
348 
349 #endif
350