Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
part_ldr.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WW3D *
24 * *
25 * $Archive:: /VSS_Sync/ww3d2/part_ldr.cpp $*
26 * *
27 * Author:: Patrick Smith
28 * *
29 * $Modtime:: 10/26/01 2:57p $*
30 * *
31 * $Revision:: 11 $*
32 * *
33 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
34
35
36#include "part_ldr.h"
37#include "part_emt.h"
38#include "w3derr.h"
39#include "chunkio.h"
40#include "win.h" // for lstrcpy, can this be improved?
41#include "assetmgr.h"
42#include "texture.h"
43
44#ifndef SAFE_DELETE
45#define SAFE_DELETE(pointer) \
46{ \
47 if (pointer) { \
48 delete pointer; \
49 pointer = 0; \
50 } \
51}
52#endif //SAFE_DELETE
53
54#ifndef SAFE_DELETE_ARRAY
55#define SAFE_DELETE_ARRAY(pointer) \
56 if (pointer) { \
57 delete [] pointer; \
58 pointer = 0; \
59 } \
60
61#endif //SAFE_DELETE
62
63
65//
66// Global variable initialization
67//
69
70// This array is declared in "W3D_File.H"
72{
73 "Default"
74};
75
76
78//
79// ParticleEmitterDefClass
80//
82 : m_pName (NULL),
83 m_Version (0L),
84 m_pUserString (NULL),
85 m_iUserType (EMITTER_TYPEID_DEFAULT),
86 m_InitialOrientationRandom (0),
87 m_pCreationVolume (NULL),
88 m_pVelocityRandomizer (NULL)
89{
90 ::memset (&m_Info, 0, sizeof (m_Info));
91 ::memset (&m_InfoV2, 0, sizeof (m_InfoV2));
92 ::memset (&m_ExtraInfo, 0, sizeof (m_ExtraInfo));
93
94 ::memset (&m_ColorKeyframes, 0, sizeof (m_ColorKeyframes));
95 ::memset (&m_OpacityKeyframes, 0, sizeof (m_OpacityKeyframes));
96 ::memset (&m_SizeKeyframes, 0, sizeof (m_SizeKeyframes));
97 ::memset (&m_RotationKeyframes, 0, sizeof (m_RotationKeyframes));
98 ::memset (&m_FrameKeyframes, 0, sizeof (m_FrameKeyframes));
99 ::memset (&m_BlurTimeKeyframes, 0, sizeof (m_BlurTimeKeyframes));
100 ::memset (&m_LineProperties, 0, sizeof (m_LineProperties));
101 return ;
102}
103
104
106//
107// ParticleEmitterDefClass
108//
110 : m_pName (NULL),
111 m_Version (0L),
112 m_pUserString (NULL),
113 m_iUserType (EMITTER_TYPEID_DEFAULT),
114 m_InitialOrientationRandom (src.m_InitialOrientationRandom),
115 m_pCreationVolume (NULL),
116 m_pVelocityRandomizer (NULL)
117{
118 ::memset (&m_Info, 0, sizeof (m_Info));
119 ::memset (&m_InfoV2, 0, sizeof (m_InfoV2));
120 ::memset (&m_ExtraInfo, 0, sizeof (m_ExtraInfo));
121
122 ::memset (&m_ColorKeyframes, 0, sizeof (m_ColorKeyframes));
123 ::memset (&m_OpacityKeyframes, 0, sizeof (m_OpacityKeyframes));
124 ::memset (&m_SizeKeyframes, 0, sizeof (m_SizeKeyframes));
125 ::memset (&m_RotationKeyframes, 0, sizeof (m_RotationKeyframes));
126 ::memset (&m_FrameKeyframes, 0, sizeof (m_FrameKeyframes));
127 ::memset (&m_BlurTimeKeyframes, 0, sizeof (m_BlurTimeKeyframes));
128 ::memset (&m_LineProperties, 0, sizeof (m_LineProperties));
129
130 (*this) = src;
131 return ;
132}
133
134
136//
137// ~ParticleEmitterDefClass
138//
140{
141 // Free the name buffer if necessary
142 if (m_pName != NULL) {
143
144 // free() is used because the buffer was allocated with ::_strdup().
145 ::free (m_pName);
146 m_pName = NULL;
147 }
148
149 // Free the user-string buffer if necessary
150 if (m_pUserString != NULL) {
151
152 // free() is used because the buffer was allocated with ::malloc() or ::_strdup().
153 ::free (m_pUserString);
154 m_pUserString = NULL;
155 }
156
157 Free_Props ();
158
159 SAFE_DELETE (m_pCreationVolume);
160 SAFE_DELETE (m_pVelocityRandomizer);
161 return ;
162}
163
164
166//
167// ParticleEmitterDefClass
168//
171{
172 //
173 // Copy the user structures
174 //
175 Set_Name (src.Get_Name ());
178 m_Version = src.m_Version;
179
180 //
181 // Copy the information structures
182 //
183 ::memcpy (&m_Info, &src.m_Info, sizeof (m_Info));
184 ::memcpy (&m_InfoV2, &src.m_InfoV2, sizeof (m_InfoV2));
185 ::memcpy (&m_ExtraInfo, &src.m_ExtraInfo, sizeof (m_ExtraInfo));
186 ::memcpy (&m_LineProperties, &src.m_LineProperties, sizeof(m_LineProperties));
187
188 //
189 // Copy the keyframes
190 //
191 Free_Props ();
192 ::Copy_Emitter_Property_Struct (m_ColorKeyframes, src.m_ColorKeyframes);
193 ::Copy_Emitter_Property_Struct (m_OpacityKeyframes, src.m_OpacityKeyframes);
194 ::Copy_Emitter_Property_Struct (m_SizeKeyframes, src.m_SizeKeyframes);
195 ::Copy_Emitter_Property_Struct (m_RotationKeyframes, src.m_RotationKeyframes);
196 ::Copy_Emitter_Property_Struct (m_FrameKeyframes, src.m_FrameKeyframes);
197 ::Copy_Emitter_Property_Struct (m_BlurTimeKeyframes, src.m_BlurTimeKeyframes);
198 m_InitialOrientationRandom = src.m_InitialOrientationRandom;
199
200 //
201 // Create the randomizers
202 //
203 SAFE_DELETE (m_pCreationVolume);
204 SAFE_DELETE (m_pVelocityRandomizer);
205 m_pCreationVolume = Create_Randomizer (m_InfoV2.CreationVolume);
206 m_pVelocityRandomizer = Create_Randomizer (m_InfoV2.VelRandom);
207 return (*this);
208}
209
211//
212// Free_Props
213//
214void
216{
217 m_ColorKeyframes.NumKeyFrames = 0;
218 m_OpacityKeyframes.NumKeyFrames = 0;
219 m_SizeKeyframes.NumKeyFrames = 0;
220 m_RotationKeyframes.NumKeyFrames = 0;
221 m_FrameKeyframes.NumKeyFrames = 0;
222 m_BlurTimeKeyframes.NumKeyFrames = 0;
223
224 SAFE_DELETE_ARRAY (m_ColorKeyframes.KeyTimes);
225 SAFE_DELETE_ARRAY (m_ColorKeyframes.Values);
226 SAFE_DELETE_ARRAY (m_OpacityKeyframes.KeyTimes);
227 SAFE_DELETE_ARRAY (m_OpacityKeyframes.Values);
228 SAFE_DELETE_ARRAY (m_SizeKeyframes.KeyTimes);
229 SAFE_DELETE_ARRAY (m_SizeKeyframes.Values);
230 SAFE_DELETE_ARRAY (m_RotationKeyframes.KeyTimes);
231 SAFE_DELETE_ARRAY (m_RotationKeyframes.Values);
232 SAFE_DELETE_ARRAY (m_FrameKeyframes.KeyTimes);
233 SAFE_DELETE_ARRAY (m_FrameKeyframes.Values);
234 SAFE_DELETE_ARRAY (m_BlurTimeKeyframes.KeyTimes);
235 SAFE_DELETE_ARRAY (m_BlurTimeKeyframes.Values);
236
237 return ;
238}
239
240
242//
243// Set_Velocity_Random
244//
245void
247{
248 SAFE_DELETE (m_pVelocityRandomizer);
249 m_pVelocityRandomizer = randomizer;
250
251 //
252 // Ensure our persistent structure is up-to-date so it will save correctly
253 //
254 if (m_pVelocityRandomizer != NULL) {
255 Initialize_Randomizer_Struct (*m_pVelocityRandomizer, m_InfoV2.VelRandom);
256 }
257
258 return ;
259}
260
261
263//
264// Set_Creation_Volume
265//
266void
268{
269 SAFE_DELETE (m_pCreationVolume);
270 m_pCreationVolume = randomizer;
271
272 //
273 // Ensure our persistent structure is up-to-date so it will save correctly
274 //
275 if (m_pCreationVolume != NULL) {
276 Initialize_Randomizer_Struct (*m_pCreationVolume, m_InfoV2.CreationVolume);
277 }
278
279 return ;
280}
281
282
284//
285// Set_User_String
286//
287void
289{
290 SAFE_FREE (m_pUserString);
291 m_pUserString = ::_strdup (pstring);
292 return ;
293}
294
295
297//
298// Set_Name
299//
300void
302{
303 SAFE_FREE (m_pName);
304 m_pName = ::_strdup (pname);
305 return ;
306}
307
308
310//
311// Set_Texture_Filename
312//
313void
315{
316 ::lstrcpy (m_Info.TextureFilename, pname);
318 return ;
319}
320
321
323//
324// Normalize_Filename
325//
326void
328{
329 TCHAR path[MAX_PATH];
330 ::lstrcpy (path, m_Info.TextureFilename);
331
332 // Find the last occurance of the directory deliminator
333 LPCTSTR filename = ::strrchr (path, '\\');
334 if (filename != NULL) {
335
336 // Increment past the directory deliminator
337 filename ++;
338
339 // Now copy the filename protion of the path to the structure
340 ::lstrcpy (m_Info.TextureFilename, filename);
341 }
342
343 return ;
344}
345
346
348//
349// Load
350//
353{
354 // Assume error
357
358 // Attempt to read the different sections of the emitter definition
359 if ((Read_Header (chunk_load) == WW3D_ERROR_OK) &&
360 (Read_User_Data (chunk_load) == WW3D_ERROR_OK) &&
361 (Read_Info (chunk_load) == WW3D_ERROR_OK)) {
362
363 if (m_Version > 0x00010000) {
364
365 //
366 // Read the version 2.0 structures from the chunk
367 //
368 if ((Read_InfoV2 (chunk_load) == WW3D_ERROR_OK) &&
369 (Read_Props (chunk_load) == WW3D_ERROR_OK)) {
370
371 // Success!
372 ret_val = WW3D_ERROR_OK;
373 }
374 } else {
375
376 // Make sure the data fits version 2
378 ret_val = WW3D_ERROR_OK;
379 }
380 }
381
382 // (gth) Handle all future additions to the particle emitter file format
383 // in the typical chunk fashion.
384 while (chunk_load.Open_Chunk() && ret_val == WW3D_ERROR_OK) {
385
386 switch (chunk_load.Cur_Chunk_ID())
387 {
389 ret_val = Read_Line_Properties(chunk_load);
390 break;
391
393 ret_val = Read_Rotation_Keyframes(chunk_load);
394 break;
395
397 ret_val = Read_Frame_Keyframes(chunk_load);
398 break;
399
401 ret_val = Read_Blur_Time_Keyframes(chunk_load);
402 break;
403
405 ret_val = Read_Extra_Info(chunk_load);
406 break;
407
408 default:
409 WWDEBUG_SAY(("Unhandled Chunk! File: %s Line: %d\r\n",__FILE__,__LINE__));
410 break;
411 }
412
413 chunk_load.Close_Chunk();
414 }
415
416 // Return the WW3DErrorType return code
417 return ret_val;
418}
419
420
422//
423// Initialize_To_Ver2
424//
425void
427{
428 ::memset (&m_Info, 0, sizeof (m_Info));
429 ::memset (&m_InfoV2, 0, sizeof (m_InfoV2));
430 ::memset (&m_ExtraInfo, 0, sizeof (m_ExtraInfo));
431
432 //
433 // Set the version 2 values using defaults from version 1
434 //
435 m_InfoV2.BurstSize = 1;
436 m_InfoV2.OutwardVel = 0;
437 m_InfoV2.VelInherit = 0;
439
440 m_InfoV2.CreationVolume.ClassID = Vector3Randomizer::CLASSID_SOLIDBOX;
441 m_InfoV2.CreationVolume.Value1 = 0;
442 m_InfoV2.CreationVolume.Value2 = 0;
443 m_InfoV2.CreationVolume.Value3 = 0;
444
445 m_InfoV2.VelRandom.ClassID = Vector3Randomizer::CLASSID_SOLIDBOX;
446 m_InfoV2.VelRandom.Value1 = 0;
447 m_InfoV2.VelRandom.Value2 = 0;
448 m_InfoV2.VelRandom.Value3 = 0;
449
450 Free_Props ();
451 return ;
452}
453
454
456//
457// Convert_To_Ver2
458//
459void
461{
462 if (m_Version < 0x00020000) {
463 m_InfoV2.BurstSize = 1;
464 m_InfoV2.OutwardVel = 0;
465 m_InfoV2.VelInherit = 0;
466
467 //
468 // Determine which shader to use...
469 //
471 TextureClass *ptexture = WW3DAssetManager::Get_Instance ()->Get_Texture (m_Info.TextureFilename);
472 if (ptexture != NULL) {
473 // If texture has an alpha channel do alpha blending instead of additive
474 // (which is the default for point groups):
475// SurfaceClass::SurfaceDescription surf_desc;
476// ::ZeroMemory(&surf_desc, sizeof(SurfaceClass::SurfaceDescription));
477// ptexture->Get_Level_Description(surf_desc);
478// if (Has_Alpha(surf_desc.Format)) {
479 if (Has_Alpha(ptexture->Get_Texture_Format())) {
481 }
482 ptexture->Release_Ref();
483 }
484 W3dUtilityClass::Convert_Shader (shader, &m_InfoV2.Shader);
485
486
487 //
488 // Convert the randomziers
489 //
490 m_InfoV2.CreationVolume.ClassID = Vector3Randomizer::CLASSID_SOLIDBOX;
491 m_InfoV2.CreationVolume.Value1 = m_Info.PositionRandom / 1000.0f;
492 m_InfoV2.CreationVolume.Value2 = m_Info.PositionRandom / 1000.0f;
493 m_InfoV2.CreationVolume.Value3 = m_Info.PositionRandom / 1000.0f;
494
495 m_InfoV2.VelRandom.ClassID = Vector3Randomizer::CLASSID_SOLIDBOX;
496 m_InfoV2.VelRandom.Value1 = m_Info.VelocityRandom;
497 m_InfoV2.VelRandom.Value2 = m_Info.VelocityRandom;
498 m_InfoV2.VelRandom.Value3 = m_Info.VelocityRandom;
499
500 //
501 // Recreate the randomizers
502 //
503 SAFE_DELETE (m_pCreationVolume);
504 SAFE_DELETE (m_pVelocityRandomizer);
505 m_pCreationVolume = Create_Randomizer (m_InfoV2.CreationVolume);
506 m_pVelocityRandomizer = Create_Randomizer (m_InfoV2.VelRandom);
507
508 //
509 // Convert the colors, opacities, and sizes
510 //
511 Free_Props ();
512 m_ColorKeyframes.Start = RGBA_TO_VECTOR3 (m_Info.StartColor);
513 m_ColorKeyframes.Rand = Vector3 (0, 0, 0);
514 m_ColorKeyframes.NumKeyFrames = 1;
515 m_ColorKeyframes.KeyTimes = W3DNEW float(m_Info.FadeTime);
516 m_ColorKeyframes.Values = W3DNEW Vector3(RGBA_TO_VECTOR3 (m_Info.EndColor));
517
518 m_OpacityKeyframes.Start = ((float)(m_Info.StartColor.A)) / 255;
519 m_OpacityKeyframes.Rand = 0;
520 m_OpacityKeyframes.NumKeyFrames = 1;
521 m_OpacityKeyframes.KeyTimes = W3DNEW float(m_Info.FadeTime);
522 m_OpacityKeyframes.Values = W3DNEW float(((float)(m_Info.EndColor.A)) / 255);
523
524 m_SizeKeyframes.Start = m_Info.StartSize;
525 m_SizeKeyframes.Rand = 0;
526 m_SizeKeyframes.NumKeyFrames = 0;
527 }
528
529 return ;
530}
531
532
534//
535// Read_Header
536//
539{
540 // Assume error
542
543 // Is this the header chunk?
544 if (chunk_load.Open_Chunk () &&
545 (chunk_load.Cur_Chunk_ID () == W3D_CHUNK_EMITTER_HEADER)) {
546
547 W3dEmitterHeaderStruct header = { 0 };
548 if (chunk_load.Read (&header, sizeof (header)) == sizeof (header)) {
549
550 // Copy the name from the header structure
551 m_pName = ::_strdup (header.Name);
552 m_Version = header.Version;
553
554 // Success!
555 ret_val = WW3D_ERROR_OK;
556 }
557
558 // Close the chunk, so the next read will be successful.
559 chunk_load.Close_Chunk ();
560 }
561
562 // Return the WW3DErrorType return code
563 return ret_val;
564}
565
566
568//
569// Read_User_Data
570//
573{
574 // Assume error
576
577 // Is this the user chunk?
578 if (chunk_load.Open_Chunk () &&
579 (chunk_load.Cur_Chunk_ID () == W3D_CHUNK_EMITTER_USER_DATA)) {
580
581 W3dEmitterUserInfoStruct user_info = { 0 };
582 if (chunk_load.Read (&user_info, sizeof (user_info)) == sizeof (user_info)) {
583
584 // Assume success from here on out
585 ret_val = WW3D_ERROR_OK;
586
587 // Record the user information into our member data
588 m_iUserType = user_info.Type;
589
590 // Should we read the user string from the file?
591 if (user_info.SizeofStringParam > 0) {
592 m_pUserString = (char *)::malloc (sizeof (char) * (user_info.SizeofStringParam+1));
593 m_pUserString[0] = 0;
594
595 // Attempt to read the user-string from the chunk
596 if (chunk_load.Read (m_pUserString, user_info.SizeofStringParam) != user_info.SizeofStringParam) {
597 ret_val = WW3D_ERROR_LOAD_FAILED;
598 }
599 }
600 }
601
602 // Close the chunk, so the next read will be successful.
603 chunk_load.Close_Chunk ();
604 }
605
606 // Return the WW3DErrorType return code
607 return ret_val;
608}
609
610
612//
613// Read_Info
614//
617{
618 // Assume error
620
621 // Is this the user chunk?
622 if (chunk_load.Open_Chunk () &&
623 (chunk_load.Cur_Chunk_ID () == W3D_CHUNK_EMITTER_INFO)) {
624
625 // Read the chunk straight into our member structure
626 ::memset (&m_Info, 0, sizeof (m_Info));
627 if (chunk_load.Read (&m_Info, sizeof (m_Info)) == sizeof (m_Info)) {
628
629 // Success!
630 ret_val = WW3D_ERROR_OK;
631 }
632
633 // Close the chunk, so the next read will be successful.
634 chunk_load.Close_Chunk ();
635 }
636
637 // Return the WW3DErrorType return code
638 return ret_val;
639}
640
641
643//
644// Create_Randomizer
645//
648{
649 Vector3Randomizer *randomizer = NULL;
650 switch (info.ClassID)
651 {
653 randomizer = W3DNEW Vector3SolidBoxRandomizer (Vector3 (info.Value1, info.Value2, info.Value3));
654 break;
655
657 randomizer = W3DNEW Vector3SolidSphereRandomizer (info.Value1);
658 break;
659
661 randomizer = W3DNEW Vector3HollowSphereRandomizer (info.Value1);
662 break;
663
665 randomizer = W3DNEW Vector3SolidCylinderRandomizer (info.Value1, info.Value2);
666 break;
667 }
668
669 return randomizer;
670}
671
672
674//
675// Initialize_Randomizer_Struct
676//
677void
679(
680 const Vector3Randomizer & randomizer,
682)
683{
684 info.ClassID = randomizer.Class_ID ();
685 switch (randomizer.Class_ID ())
686 {
688 {
689 Vector3 extents = ((Vector3SolidBoxRandomizer &)randomizer).Get_Extents ();
690 info.Value1 = extents.X;
691 info.Value2 = extents.Y;
692 info.Value3 = extents.Z;
693 }
694 break;
695
697 info.Value1 = ((Vector3SolidSphereRandomizer &)randomizer).Get_Radius ();
698 break;
699
701 info.Value1 = ((Vector3HollowSphereRandomizer &)randomizer).Get_Radius ();
702 break;
703
705 info.Value1 = ((Vector3SolidCylinderRandomizer &)randomizer).Get_Height ();
706 info.Value2 = ((Vector3SolidCylinderRandomizer &)randomizer).Get_Radius ();
707 break;
708 }
709
710 return ;
711}
712
713
715//
716// Read_InfoV2
717//
720{
721 // Assume error
723
724 // Is this the user chunk?
725 if (chunk_load.Open_Chunk () &&
726 (chunk_load.Cur_Chunk_ID () == W3D_CHUNK_EMITTER_INFOV2)) {
727
728 // Read the chunk straight into our member structure
729 ::memset (&m_InfoV2, 0, sizeof (m_InfoV2));
730 if (chunk_load.Read (&m_InfoV2, sizeof (m_InfoV2)) == sizeof (m_InfoV2)) {
731
732 //
733 // Recreate the randomizers
734 //
735 SAFE_DELETE (m_pCreationVolume);
736 SAFE_DELETE (m_pVelocityRandomizer);
737 m_pCreationVolume = Create_Randomizer (m_InfoV2.CreationVolume);
738 m_pVelocityRandomizer = Create_Randomizer (m_InfoV2.VelRandom);
739
740 // Success!
741 ret_val = WW3D_ERROR_OK;
742 }
743
744 // Close the chunk, so the next read will be successful.
745 chunk_load.Close_Chunk ();
746 }
747
748 // Return the WW3DErrorClass::ErrorType return code
749 return ret_val;
750}
751
752
754//
755// Read_Props
756//
759{
760 // Assume error
762 Free_Props ();
763
764 // Is this the user chunk?
765 if (chunk_load.Open_Chunk () &&
766 (chunk_load.Cur_Chunk_ID () == W3D_CHUNK_EMITTER_PROPS)) {
767
768 W3dEmitterPropertyStruct info = { 0 };
769 if (chunk_load.Read (&info, sizeof (info)) == sizeof (info)) {
770
771 unsigned int index=0;
772
773 //ParticlePropertyStruct<Vector3>
774 m_ColorKeyframes.NumKeyFrames = info.ColorKeyframes - 1;
775 m_OpacityKeyframes.NumKeyFrames = info.OpacityKeyframes - 1;
776 m_SizeKeyframes.NumKeyFrames = info.SizeKeyframes - 1;
777 m_ColorKeyframes.Rand = RGBA_TO_VECTOR3 (info.ColorRandom);
778 m_OpacityKeyframes.Rand = info.OpacityRandom;
779 m_SizeKeyframes.Rand = info.SizeRandom;
780
781 //
782 // Allocate the array of color keyframes
783 //
784 if (m_ColorKeyframes.NumKeyFrames > 0) {
785 m_ColorKeyframes.KeyTimes = W3DNEWARRAY float[m_ColorKeyframes.NumKeyFrames];
786 m_ColorKeyframes.Values = W3DNEWARRAY Vector3[m_ColorKeyframes.NumKeyFrames];
787 }
788
789 //
790 // Allocate the array of opacity keyframes
791 //
792 if (m_OpacityKeyframes.NumKeyFrames > 0) {
793 m_OpacityKeyframes.KeyTimes = W3DNEWARRAY float[m_OpacityKeyframes.NumKeyFrames];
794 m_OpacityKeyframes.Values = W3DNEWARRAY float[m_OpacityKeyframes.NumKeyFrames];
795 }
796
797 //
798 // Allocate the array of size keyframes
799 //
800 if (m_SizeKeyframes.NumKeyFrames > 0) {
801 m_SizeKeyframes.KeyTimes = W3DNEWARRAY float[m_SizeKeyframes.NumKeyFrames];
802 m_SizeKeyframes.Values = W3DNEWARRAY float[m_SizeKeyframes.NumKeyFrames];
803 }
804
805 //
806 // Read the color keyframes from the chunk
807 //
808 Read_Color_Keyframe (chunk_load, NULL, &m_ColorKeyframes.Start);
809 for (index = 0; index < m_ColorKeyframes.NumKeyFrames; index ++) {
810 Read_Color_Keyframe (chunk_load,
811 &m_ColorKeyframes.KeyTimes[index],
812 &m_ColorKeyframes.Values[index]);
813 }
814
815 //
816 // If the last keyframe is 'black' and we are using a color randomizer,
817 // then make sure the last color is less then 0 so any randomized color
818 // will end up as black
819 //
820 int last_keyframe = (m_ColorKeyframes.NumKeyFrames - 1);
821 if ( last_keyframe > 0 &&
822 m_ColorKeyframes.Values[last_keyframe].X == 0 &&
823 m_ColorKeyframes.Values[last_keyframe].Y == 0 &&
824 m_ColorKeyframes.Values[last_keyframe].Z == 0 &&
825 (m_ColorKeyframes.Rand.X > 0 || m_ColorKeyframes.Rand.Y > 0 || m_ColorKeyframes.Rand.Z > 0))
826 {
827 m_ColorKeyframes.Values[last_keyframe].X = -m_ColorKeyframes.Rand.X;
828 m_ColorKeyframes.Values[last_keyframe].Y = -m_ColorKeyframes.Rand.Y;
829 m_ColorKeyframes.Values[last_keyframe].Z = -m_ColorKeyframes.Rand.Z;
830 }
831
832 //
833 // Read the opacity keyframes from the chunk
834 //
835 Read_Opacity_Keyframe (chunk_load, NULL, &m_OpacityKeyframes.Start);
836 for (index = 0; index < m_OpacityKeyframes.NumKeyFrames; index ++) {
837 Read_Opacity_Keyframe (chunk_load,
838 &m_OpacityKeyframes.KeyTimes[index],
839 &m_OpacityKeyframes.Values[index]);
840 }
841
842 //
843 // Read the size keyframes from the chunk
844 //
845 Read_Size_Keyframe (chunk_load, NULL, &m_SizeKeyframes.Start);
846 for (index = 0; index < m_SizeKeyframes.NumKeyFrames; index ++) {
847 Read_Size_Keyframe (chunk_load,
848 &m_SizeKeyframes.KeyTimes[index],
849 &m_SizeKeyframes.Values[index]);
850 }
851
852 // Success!
853 ret_val = WW3D_ERROR_OK;
854 }
855
856 // Close the chunk, so the next read will be successful.
857 chunk_load.Close_Chunk ();
858 }
859
860 // Return the WW3DErrorClass::ErrorType return code
861 return ret_val;
862}
863
864
866//
867// Read_Color_Keyframe
868//
869bool
871(
872 ChunkLoadClass & chunk_load,
873 float * key_time,
874 Vector3 * value
875)
876{
877 bool retval = false;
878
879 //
880 // Read the color key frame from the chunk
881 //
882 W3dEmitterColorKeyframeStruct key_frame = { 0 };
883 if (chunk_load.Read (&key_frame, sizeof (key_frame)) == sizeof (key_frame)) {
884
885 // Pass the key time to the caller
886 if (key_time != NULL) {
887 (*key_time) = key_frame.Time;
888 }
889
890 // Pass the oclor back to the caller
891 if (value != NULL) {
892 (*value) = RGBA_TO_VECTOR3 (key_frame.Color);
893 }
894
895 // Success!
896 retval = true;
897 }
898
899 return retval;
900}
901
902
904//
905// Read_Opacity_Keyframe
906//
907bool
909(
910 ChunkLoadClass & chunk_load,
911 float * key_time,
912 float * value
913)
914{
915 bool retval = false;
916
917 //
918 // Read the key frame from the chunk
919 //
920 W3dEmitterOpacityKeyframeStruct key_frame = { 0 };
921 if (chunk_load.Read (&key_frame, sizeof (key_frame)) == sizeof (key_frame)) {
922
923 // Pass the key time to the caller
924 if (key_time != NULL) {
925 (*key_time) = key_frame.Time;
926 }
927
928 // Pass the value back to the caller
929 if (value != NULL) {
930 (*value) = key_frame.Opacity;
931 }
932
933 // Success!
934 retval = true;
935 }
936
937 return retval;
938}
939
940
942//
943// Read_Size_Keyframe
944//
945bool
947(
948 ChunkLoadClass & chunk_load,
949 float * key_time,
950 float * value
951)
952{
953 bool retval = false;
954
955 //
956 // Read the key frame from the chunk
957 //
958 W3dEmitterSizeKeyframeStruct key_frame = { 0 };
959 if (chunk_load.Read (&key_frame, sizeof (key_frame)) == sizeof (key_frame)) {
960
961 // Pass the key time to the caller
962 if (key_time != NULL) {
963 (*key_time) = key_frame.Time;
964 }
965
966 // Pass the value back to the caller
967 if (value != NULL) {
968 (*value) = key_frame.Size;
969 }
970
971 // Success!
972 retval = true;
973 }
974
975 return retval;
976}
977
978
980//
981// Read_Line_Properties
982//
985{
986 // Assume error
988
989 // Is this the user chunk?
990 if (chunk_load.Cur_Chunk_ID () == W3D_CHUNK_EMITTER_LINE_PROPERTIES) {
991
992 // Read the chunk straight into our member structure
993 if (chunk_load.Read (&m_LineProperties, sizeof (m_LineProperties)) == sizeof (m_LineProperties)) {
994
995 // Success!
996 ret_val = WW3D_ERROR_OK;
997 }
998 }
999
1000 // Return the WW3DErrorType return code
1001 return ret_val;
1002}
1003
1004
1006//
1007// Read_Rotation_Keyframes
1008//
1011{
1012 // Assume success
1013 WW3DErrorType ret_val = WW3D_ERROR_OK;
1014
1015 // Read the header
1017 if (chunk_load.Read(&header,sizeof(header)) != sizeof(header)) {
1018 ret_val = WW3D_ERROR_LOAD_FAILED;
1019 }
1020 m_RotationKeyframes.NumKeyFrames = header.KeyframeCount;
1021 m_RotationKeyframes.Rand = header.Random;
1022 m_InitialOrientationRandom = header.OrientationRandom;
1023
1024 // Read in the first key
1026 if (chunk_load.Read(&key,sizeof(key)) == sizeof(key)) {
1027 m_RotationKeyframes.Start = key.Rotation;
1028 }
1029
1030 // Allocate the rotation keys
1031 if (m_RotationKeyframes.NumKeyFrames > 0) {
1032 m_RotationKeyframes.KeyTimes = W3DNEWARRAY float[m_RotationKeyframes.NumKeyFrames];
1033 m_RotationKeyframes.Values = W3DNEWARRAY float[m_RotationKeyframes.NumKeyFrames];
1034 }
1035
1036 // Read in the keys
1037 for (unsigned int i=0; (i<header.KeyframeCount) && (ret_val == WW3D_ERROR_OK); i++) {
1039 if (chunk_load.Read(&key,sizeof(key)) == sizeof(key)) {
1040 m_RotationKeyframes.KeyTimes[i] = key.Time;
1041 m_RotationKeyframes.Values[i] = key.Rotation;
1042 } else {
1043 m_RotationKeyframes.KeyTimes[i] = 0.0f;
1044 m_RotationKeyframes.Values[i] = 0.0f;
1045 ret_val = WW3D_ERROR_LOAD_FAILED;
1046 }
1047 }
1048 return ret_val;
1049}
1050
1051
1053//
1054// Read_Frame_Keyframes
1055//
1058{
1059 // Assume success
1060 WW3DErrorType ret_val = WW3D_ERROR_OK;
1061
1062 // Read the header
1064 if (chunk_load.Read(&header,sizeof(header)) != sizeof(header)) {
1065 ret_val = WW3D_ERROR_LOAD_FAILED;
1066 }
1067
1068 // Read in the first key
1070 if (chunk_load.Read(&key,sizeof(key)) == sizeof(key)) {
1071 m_FrameKeyframes.Start = key.Frame;
1072 }
1073
1074 // Allocate the keys
1075 m_FrameKeyframes.NumKeyFrames = header.KeyframeCount;
1076 m_FrameKeyframes.Rand = header.Random;
1077
1078 if (m_FrameKeyframes.NumKeyFrames > 0) {
1079 m_FrameKeyframes.KeyTimes = W3DNEWARRAY float[m_FrameKeyframes.NumKeyFrames];
1080 m_FrameKeyframes.Values = W3DNEWARRAY float[m_FrameKeyframes.NumKeyFrames];
1081 }
1082
1083 // Read in the keys
1084 for (unsigned int i=0; (i<header.KeyframeCount) && (ret_val == WW3D_ERROR_OK); i++) {
1086 if (chunk_load.Read(&key,sizeof(key)) != sizeof(key)) {
1087 ret_val = WW3D_ERROR_LOAD_FAILED;
1088 }
1089 m_FrameKeyframes.KeyTimes[i] = key.Time;
1090 m_FrameKeyframes.Values[i] = key.Frame;
1091 }
1092 return ret_val;
1093}
1094
1096//
1097// Read_Blur_Time_Keyframes
1098//
1101{
1102 // Assume success
1103 WW3DErrorType ret_val = WW3D_ERROR_OK;
1104
1105 // Read the header
1107 if (chunk_load.Read(&header,sizeof(header)) != sizeof(header)) {
1108 ret_val = WW3D_ERROR_LOAD_FAILED;
1109 }
1110
1111 // Read in the first key
1113 if (chunk_load.Read(&key,sizeof(key)) == sizeof(key)) {
1114 m_BlurTimeKeyframes.Start = key.BlurTime;
1115 }
1116
1117 // Allocate the keys
1118 m_BlurTimeKeyframes.NumKeyFrames = header.KeyframeCount;
1119 m_BlurTimeKeyframes.Rand = header.Random;
1120
1121 if (m_BlurTimeKeyframes.NumKeyFrames > 0) {
1122 m_BlurTimeKeyframes.KeyTimes = new float[m_BlurTimeKeyframes.NumKeyFrames];
1123 m_BlurTimeKeyframes.Values = new float[m_BlurTimeKeyframes.NumKeyFrames];
1124 }
1125
1126 // Read in the keys
1127 for (unsigned int i=0; (i<header.KeyframeCount) && (ret_val == WW3D_ERROR_OK); i++) {
1129 if (chunk_load.Read(&key,sizeof(key)) != sizeof(key)) {
1130 ret_val = WW3D_ERROR_LOAD_FAILED;
1131 }
1132 m_BlurTimeKeyframes.KeyTimes[i] = key.Time;
1133 m_BlurTimeKeyframes.Values[i] = key.BlurTime;
1134 }
1135 return ret_val;
1136}
1137
1139//
1140// Read_Extra_Info
1141//
1144{
1145 // Assume error
1147
1148 // Read the chunk straight into our member structure
1149 ::memset (&m_ExtraInfo, 0, sizeof (m_ExtraInfo));
1150 if (chunk_load.Read (&m_ExtraInfo, sizeof (m_ExtraInfo)) == sizeof (m_ExtraInfo)) {
1151 // Success!
1152 ret_val = WW3D_ERROR_OK;
1153 }
1154
1155 // Return the WW3DErrorType return code
1156 return ret_val;
1157}
1158
1160//
1161// Save
1162//
1165{
1166 // Assume error
1168
1169 // Begin a chunk that identifies an emitter
1170 if (chunk_save.Begin_Chunk (W3D_CHUNK_EMITTER) == TRUE) {
1171
1172 // Attempt to save the different sections of the emitter definition
1173 if ((Save_Header (chunk_save) == WW3D_ERROR_OK) &&
1174 (Save_User_Data (chunk_save) == WW3D_ERROR_OK) &&
1175 (Save_Info (chunk_save) == WW3D_ERROR_OK) &&
1176 (Save_InfoV2 (chunk_save) == WW3D_ERROR_OK) &&
1177 (Save_Props (chunk_save) == WW3D_ERROR_OK) &&
1178 (Save_Line_Properties (chunk_save) == WW3D_ERROR_OK) &&
1179 (Save_Rotation_Keyframes (chunk_save) == WW3D_ERROR_OK) &&
1180 (Save_Frame_Keyframes (chunk_save) == WW3D_ERROR_OK) &&
1181 (Save_Blur_Time_Keyframes (chunk_save) == WW3D_ERROR_OK) &&
1182 (Save_Extra_Info (chunk_save) == WW3D_ERROR_OK)
1183 )
1184 {
1185 // Success!
1186 ret_val = WW3D_ERROR_OK;
1187 }
1188
1189 // Close the emitter chunk
1190 chunk_save.End_Chunk ();
1191 }
1192
1193 // Return the WW3DErrorType return code
1194 return ret_val;
1195}
1196
1197
1199//
1200// Save_Header
1201//
1204{
1205 // Assume error
1207
1208 // Begin a chunk that identifies the emitter
1209 if (chunk_save.Begin_Chunk (W3D_CHUNK_EMITTER_HEADER) == TRUE) {
1210
1211 // Fill the header structure
1212 W3dEmitterHeaderStruct header = { 0 };
1214 ::lstrcpyn (header.Name, m_pName, sizeof (header.Name));
1215 header.Name[sizeof (header.Name) - 1] = 0;
1216
1217 // Write the header out to the chunk
1218 if (chunk_save.Write (&header, sizeof (header)) == sizeof (header))
1219 {
1220 // Success!
1221 ret_val = WW3D_ERROR_OK;
1222 }
1223
1224 // End the header chunk
1225 chunk_save.End_Chunk ();
1226 }
1227
1228 // Return the WW3DErrorType return code
1229 return ret_val;
1230}
1231
1232
1234//
1235// Save_User_Data
1236//
1239{
1240 // Assume error
1242
1243 // Begin a chunk that contains user information
1244 if (chunk_save.Begin_Chunk (W3D_CHUNK_EMITTER_USER_DATA) == TRUE) {
1245
1246 DWORD string_len = m_pUserString ? (::lstrlen (m_pUserString) + 1) : 0;
1247
1248 // Fill the header structure
1249 W3dEmitterUserInfoStruct user_info = { 0 };
1250 user_info.Type = m_iUserType;
1251 user_info.SizeofStringParam = string_len;
1252
1253 // Write the user information structure out to the chunk
1254 if (chunk_save.Write (&user_info, sizeof (user_info)) == sizeof (user_info))
1255 {
1256 // Assume success
1257 ret_val = WW3D_ERROR_OK;
1258
1259 // Do we need to write the user string to the file?
1260 if (m_pUserString != NULL) {
1261
1262 // Now write the user string param to the file
1263 if (chunk_save.Write (m_pUserString, string_len) != string_len) {
1264
1265 // Something went wrong
1266 ret_val = WW3D_ERROR_SAVE_FAILED;
1267 }
1268 }
1269 }
1270
1271 // End the user information chunk
1272 chunk_save.End_Chunk ();
1273 }
1274
1275 // Return the WW3DErrorType return code
1276 return ret_val;
1277}
1278
1279
1281//
1282// Save_Info
1283//
1286{
1287 // Assume error
1289
1290 // Begin a chunk that identifies the generic emitter settings
1291 if (chunk_save.Begin_Chunk (W3D_CHUNK_EMITTER_INFO) == TRUE) {
1292
1293 // Write the settings structure out to the chunk
1294 if (chunk_save.Write (&m_Info, sizeof (m_Info)) == sizeof (m_Info))
1295 {
1296 // Success!
1297 ret_val = WW3D_ERROR_OK;
1298 }
1299
1300 // End the settings chunk
1301 chunk_save.End_Chunk ();
1302 }
1303
1304 // Return the WW3DErrorType return code
1305 return ret_val;
1306}
1307
1308
1310//
1311// Save_InfoV2
1312//
1315{
1316 // Assume error
1318
1319 // Begin a chunk that identifies the generic emitter settings
1320 if (chunk_save.Begin_Chunk (W3D_CHUNK_EMITTER_INFOV2) == TRUE) {
1321
1322 // Write the settings structure out to the chunk
1323 if (chunk_save.Write (&m_InfoV2, sizeof (m_InfoV2)) == sizeof (m_InfoV2))
1324 {
1325 // Success!
1326 ret_val = WW3D_ERROR_OK;
1327 }
1328
1329 // End the settings chunk
1330 chunk_save.End_Chunk ();
1331 }
1332
1333 // Return the WW3DErrorType return code
1334 return ret_val;
1335}
1336
1337
1339//
1340// Save_Props
1341//
1344{
1345 // Assume error
1347
1348 // Begin a chunk that identifies the generic emitter settings
1349 if (chunk_save.Begin_Chunk (W3D_CHUNK_EMITTER_PROPS) == TRUE) {
1350
1351 //
1352 // Fill in the property struct
1353 //
1354 W3dEmitterPropertyStruct info = { 0 };
1355 info.ColorKeyframes = m_ColorKeyframes.NumKeyFrames + 1;
1356 info.OpacityKeyframes = m_OpacityKeyframes.NumKeyFrames + 1;
1357 info.SizeKeyframes = m_SizeKeyframes.NumKeyFrames + 1;
1358 info.OpacityRandom = m_OpacityKeyframes.Rand;
1359 info.SizeRandom = m_SizeKeyframes.Rand;
1360 VECTOR3_TO_RGBA (m_ColorKeyframes.Rand, info.ColorRandom);
1361
1362 //
1363 // Write the property structure out to the chunk
1364 //
1365 if (chunk_save.Write (&info, sizeof (info)) == sizeof (info)) {
1366
1367 //
1368 // Save the keyframes
1369 //
1370 if ((Save_Color_Keyframes (chunk_save) == WW3D_ERROR_OK) &&
1371 (Save_Opacity_Keyframes (chunk_save) == WW3D_ERROR_OK) &&
1372 (Save_Size_Keyframes (chunk_save) == WW3D_ERROR_OK)) {
1373
1374 // Success!
1375 ret_val = WW3D_ERROR_OK;
1376 }
1377 }
1378
1379 // End the settings chunk
1380 chunk_save.End_Chunk ();
1381 }
1382
1383 // Return the WW3DErrorType return code
1384 return ret_val;
1385}
1386
1387
1389//
1390// Save_Color_Keyframes
1391//
1394{
1395 // Assume error
1397
1398 W3dEmitterColorKeyframeStruct info = { 0 };
1399 info.Time = 0;
1400 VECTOR3_TO_RGBA (m_ColorKeyframes.Start, info.Color);
1401
1402 //
1403 // Write the starting color keyframe to the chunk
1404 //
1405 if (chunk_save.Write (&info, sizeof (info)) == sizeof (info)) {
1406
1407 //
1408 // Write each of the remaining color keyframes to the chunk
1409 //
1410 int count = m_ColorKeyframes.NumKeyFrames;
1411 bool success = true;
1412 for (int index = 0; (index < count) && success; index ++) {
1413 info.Time = m_ColorKeyframes.KeyTimes[index];
1414 VECTOR3_TO_RGBA (m_ColorKeyframes.Values[index], info.Color);
1415 success = (chunk_save.Write (&info, sizeof (info)) == sizeof (info));
1416 }
1417
1418 ret_val = success ? WW3D_ERROR_OK : WW3D_ERROR_SAVE_FAILED;
1419 }
1420
1421 // Return the WW3DErrorType return code
1422 return ret_val;
1423}
1424
1425
1427//
1428// Save_Opacity_Keyframes
1429//
1432{
1433 // Assume error
1435
1437 info.Time = 0;
1438 info.Opacity = m_OpacityKeyframes.Start;
1439
1440 //
1441 // Write the starting keyframe to the chunk
1442 //
1443 if (chunk_save.Write (&info, sizeof (info)) == sizeof (info)) {
1444
1445 //
1446 // Write each of the remaining keyframes to the chunk
1447 //
1448 int count = m_OpacityKeyframes.NumKeyFrames;
1449 bool success = true;
1450 for (int index = 0; (index < count) && success; index ++) {
1451 info.Time = m_OpacityKeyframes.KeyTimes[index];
1452 info.Opacity = m_OpacityKeyframes.Values[index];
1453 success = (chunk_save.Write (&info, sizeof (info)) == sizeof (info));
1454 }
1455
1456 ret_val = success ? WW3D_ERROR_OK : WW3D_ERROR_SAVE_FAILED;
1457 }
1458
1459 // Return the WW3DErrorType return code
1460 return ret_val;
1461}
1462
1463
1465//
1466// Save_Size_Keyframes
1467//
1470{
1471 // Assume error
1473
1474 W3dEmitterSizeKeyframeStruct info = { 0 };
1475 info.Time = 0;
1476 info.Size = m_SizeKeyframes.Start;
1477
1478 //
1479 // Write the starting keyframe to the chunk
1480 //
1481 if (chunk_save.Write (&info, sizeof (info)) == sizeof (info)) {
1482
1483 //
1484 // Write each of the remaining keyframes to the chunk
1485 //
1486 int count = m_SizeKeyframes.NumKeyFrames;
1487 bool success = true;
1488 for (int index = 0; (index < count) && success; index ++) {
1489 info.Time = m_SizeKeyframes.KeyTimes[index];
1490 info.Size = m_SizeKeyframes.Values[index];
1491 success = (chunk_save.Write (&info, sizeof (info)) == sizeof (info));
1492 }
1493
1494 ret_val = success ? WW3D_ERROR_OK : WW3D_ERROR_SAVE_FAILED;
1495 }
1496
1497 // Return the WW3DErrorType return code
1498 return ret_val;
1499}
1500
1503{
1504 // Assume error
1506
1507 // Begin a chunk that identifies the line properties
1509
1510 // Write the line properties structure out to the chunk
1511 if (chunk_save.Write (&m_LineProperties, sizeof (m_LineProperties)) == sizeof (m_LineProperties))
1512 {
1513 // Success!
1514 ret_val = WW3D_ERROR_OK;
1515 }
1516
1517 // End the chunk
1518 chunk_save.End_Chunk ();
1519 }
1520
1521 // Return the WW3DErrorType return code
1522 return ret_val;
1523}
1524
1526//
1527// Save_Rotation_Keyframes
1528// NOTE: Rotation keyframes are saved in a separate chunk unlike color,size,and
1529// opacity which are embedded inside the PROPS chunk.
1530//
1533{
1534 // Assume error
1536
1537 // Begin a chunk that identifies the rotation keyframes
1539
1540 // Write the header
1542 header.KeyframeCount = m_RotationKeyframes.NumKeyFrames;
1543 header.Random = m_RotationKeyframes.Rand;
1544 header.OrientationRandom = m_InitialOrientationRandom;
1545 chunk_save.Write (&header, sizeof (W3dEmitterRotationHeaderStruct));
1546
1547 // Write the keyframes
1548 bool success = true;
1550
1551 // Write the start keyframe
1552 key.Time = 0;
1553 key.Rotation = m_RotationKeyframes.Start;
1554 chunk_save.Write (&key, sizeof (key));
1555
1556 // Write the remaining keyframes
1557 for (unsigned int index = 0; (index < header.KeyframeCount) && success; index ++) {
1558 key.Time = m_RotationKeyframes.KeyTimes[index];
1559 key.Rotation = m_RotationKeyframes.Values[index];
1560 success = (chunk_save.Write (&key, sizeof (key)) == sizeof (key));
1561 }
1562
1563 ret_val = success ? WW3D_ERROR_OK : WW3D_ERROR_SAVE_FAILED;
1564
1565 // End the chunk
1566 chunk_save.End_Chunk ();
1567 }
1568
1569 // Return the WW3DErrorType return code
1570 return ret_val;
1571}
1572
1573
1575//
1576// Save_Frame_Keyframes
1577// NOTE: Frame keyframes are saved in a separate chunk unlike color,size,and
1578// opacity which are embedded inside the PROPS chunk.
1579//
1582{
1583 // Assume error
1585
1586 // Begin a chunk that identifies the rotation keyframes
1588
1589 // Write the header
1591 header.KeyframeCount = m_FrameKeyframes.NumKeyFrames;
1592 header.Random = m_FrameKeyframes.Rand;
1593 chunk_save.Write (&header, sizeof (W3dEmitterFrameHeaderStruct));
1594
1595 // Write the keyframes
1596 bool success = true;
1598
1599 // Write the start keyframe
1600 key.Time = 0;
1601 key.Frame = m_FrameKeyframes.Start;
1602 chunk_save.Write (&key, sizeof (key));
1603
1604 // Write the remaining keyframes
1605 for (unsigned int index = 0; (index < header.KeyframeCount) && success; index ++) {
1606 key.Time = m_FrameKeyframes.KeyTimes[index];
1607 key.Frame = m_FrameKeyframes.Values[index];
1608 success = (chunk_save.Write (&key, sizeof (key)) == sizeof (key));
1609 }
1610
1611 ret_val = success ? WW3D_ERROR_OK : WW3D_ERROR_SAVE_FAILED;
1612
1613 // End the chunk
1614 chunk_save.End_Chunk ();
1615 }
1616
1617 // Return the WW3DErrorType return code
1618 return ret_val;
1619}
1620
1622//
1623// Save_Blur_Time_Keyframes
1624// NOTE: Blur Time keyframes are saved in a separate chunk unlike color,size,and
1625// opacity which are embedded inside the PROPS chunk.
1626//
1629{
1630 // Assume error
1632
1633 // Begin a chunk that identifies the rotation keyframes
1635
1636 // Write the header
1638 header.KeyframeCount = m_BlurTimeKeyframes.NumKeyFrames;
1639 header.Random = m_BlurTimeKeyframes.Rand;
1640 chunk_save.Write (&header, sizeof (W3dEmitterBlurTimeHeaderStruct));
1641
1642 // Write the keyframes
1643 bool success = true;
1645
1646 // Write the start keyframe
1647 key.Time = 0;
1648 key.BlurTime = m_BlurTimeKeyframes.Start;
1649 chunk_save.Write (&key, sizeof (key));
1650
1651 // Write the remaining keyframes
1652 for (unsigned int index = 0; (index < header.KeyframeCount) && success; index ++) {
1653 key.Time = m_BlurTimeKeyframes.KeyTimes[index];
1654 key.BlurTime = m_BlurTimeKeyframes.Values[index];
1655 success = (chunk_save.Write (&key, sizeof (key)) == sizeof (key));
1656 }
1657
1658 ret_val = success ? WW3D_ERROR_OK : WW3D_ERROR_SAVE_FAILED;
1659
1660 // End the chunk
1661 chunk_save.End_Chunk ();
1662 }
1663
1664 // Return the WW3DErrorType return code
1665 return ret_val;
1666}
1667
1670{
1671 // Assume error
1673
1674 // Begin a chunk that identifies the extra info
1675 if (chunk_save.Begin_Chunk (W3D_CHUNK_EMITTER_EXTRA_INFO) == TRUE) {
1676
1678
1679 memset(&data, 0, sizeof(data));
1681 bool success = (chunk_save.Write (&data, sizeof (data)) == sizeof (data));
1682 ret_val = success ? WW3D_ERROR_OK : WW3D_ERROR_SAVE_FAILED;
1683
1684 chunk_save.End_Chunk ();
1685 }
1686
1687 return ret_val;
1688}
1689
1691//
1692// Set_Color_Keyframes
1693//
1694void
1696{
1697 SAFE_DELETE_ARRAY (m_ColorKeyframes.KeyTimes);
1698 SAFE_DELETE_ARRAY (m_ColorKeyframes.Values);
1699
1700 ::Copy_Emitter_Property_Struct (m_ColorKeyframes, keyframes);
1701 return ;
1702}
1703
1704
1706//
1707// Set_Opacity_Keyframes
1708//
1709void
1711{
1712 SAFE_DELETE_ARRAY (m_OpacityKeyframes.KeyTimes);
1713 SAFE_DELETE_ARRAY (m_OpacityKeyframes.Values);
1714
1715 ::Copy_Emitter_Property_Struct (m_OpacityKeyframes, keyframes);
1716 return ;
1717}
1718
1719
1721//
1722// Set_Size_Keyframes
1723//
1724void
1726{
1727 SAFE_DELETE_ARRAY (m_SizeKeyframes.KeyTimes);
1728 SAFE_DELETE_ARRAY (m_SizeKeyframes.Values);
1729
1730 ::Copy_Emitter_Property_Struct (m_SizeKeyframes, keyframes);
1731 return ;
1732}
1733
1734
1736//
1737// Set_Rotation_Keyframes
1738//
1739void
1741{
1742 SAFE_DELETE_ARRAY (m_RotationKeyframes.KeyTimes);
1743 SAFE_DELETE_ARRAY (m_RotationKeyframes.Values);
1744
1745 ::Copy_Emitter_Property_Struct (m_RotationKeyframes, keyframes);
1746 m_InitialOrientationRandom = orient_rnd;
1747 return ;
1748}
1749
1751//
1752// Set_Frame_Keyframes
1753//
1754void
1756{
1757 SAFE_DELETE_ARRAY (m_FrameKeyframes.KeyTimes);
1758 SAFE_DELETE_ARRAY (m_FrameKeyframes.Values);
1759
1760 ::Copy_Emitter_Property_Struct (m_FrameKeyframes, keyframes);
1761 return ;
1762}
1763
1765//
1766// Set_Blur_Time_Keyframes
1767//
1768void
1770{
1771 SAFE_DELETE_ARRAY (m_BlurTimeKeyframes.KeyTimes);
1772 SAFE_DELETE_ARRAY (m_BlurTimeKeyframes.Values);
1773
1774 ::Copy_Emitter_Property_Struct (m_BlurTimeKeyframes, keyframes);
1775 return ;
1776}
1777
1779//
1780// Get_Color_Keyframes
1781//
1782void
1784{
1785 ::Copy_Emitter_Property_Struct (keyframes, m_ColorKeyframes);
1786 return ;
1787}
1788
1789
1791//
1792// Get_Opacity_Keyframes
1793//
1794void
1796{
1797 ::Copy_Emitter_Property_Struct (keyframes, m_OpacityKeyframes);
1798 return ;
1799}
1800
1801
1803//
1804// Get_Size_Keyframes
1805//
1806void
1808{
1809 ::Copy_Emitter_Property_Struct (keyframes, m_SizeKeyframes);
1810 return ;
1811}
1812
1814//
1815// Get_Rotation_Keyframes
1816//
1817void
1819{
1820 ::Copy_Emitter_Property_Struct (keyframes, m_RotationKeyframes);
1821 return ;
1822}
1823
1824
1826//
1827// Get_Frame_Keyframes
1828//
1829void
1831{
1832 ::Copy_Emitter_Property_Struct (keyframes, m_FrameKeyframes);
1833 return ;
1834}
1835
1837//
1838// Get_Blur_Time_Keyframes
1839//
1840void
1842{
1843 ::Copy_Emitter_Property_Struct (blurtimeframes, m_BlurTimeKeyframes);
1844 return ;
1845}
1846
1847
1849//
1850// Create
1851//
1857
1858
1860//
1861// Load
1862//
1865{
1866 // Assume failure
1867 ParticleEmitterPrototypeClass *pprototype = NULL;
1868
1869 // Create a definition object
1871 if (pdefinition != NULL) {
1872
1873 // Ask the definition object to load the emitter data
1874 if (pdefinition->Load_W3D (chunk_load) != WW3D_ERROR_OK) {
1875
1876 // Error! Free the definition
1877 delete pdefinition;
1878 pdefinition = NULL;
1879 } else {
1880
1881 // Success! Create a prototype from the definition
1882 pprototype = W3DNEW ParticleEmitterPrototypeClass (pdefinition);
1883 }
1884 }
1885
1886 // Return a pointer to the prototype
1887 return pprototype;
1888}
#define NULL
Definition BaseType.h:92
#define TRUE
Definition BaseType.h:109
void const char * value
#define W3D_CURRENT_EMITTER_VERSION
Definition w3d_file.h:1743
@ W3D_CHUNK_EMITTER_FRAME_KEYFRAMES
Definition w3d_file.h:455
@ W3D_CHUNK_EMITTER_INFOV2
Definition w3d_file.h:448
@ W3D_CHUNK_EMITTER_BLUR_TIME_KEYFRAMES
Definition w3d_file.h:456
@ W3D_CHUNK_EMITTER
Definition w3d_file.h:444
@ W3D_CHUNK_EMITTER_ROTATION_KEYFRAMES
Definition w3d_file.h:454
@ W3D_CHUNK_EMITTER_LINE_PROPERTIES
Definition w3d_file.h:453
@ W3D_CHUNK_EMITTER_USER_DATA
Definition w3d_file.h:446
@ W3D_CHUNK_EMITTER_HEADER
Definition w3d_file.h:445
@ W3D_CHUNK_EMITTER_EXTRA_INFO
Definition w3d_file.h:457
@ W3D_CHUNK_EMITTER_INFO
Definition w3d_file.h:447
@ W3D_CHUNK_EMITTER_PROPS
Definition w3d_file.h:449
@ EMITTER_TYPEID_DEFAULT
Definition w3d_file.h:1756
@ EMITTER_TYPEID_COUNT
Definition w3d_file.h:1757
#define W3DNEWARRAY
Definition always.h:110
#define W3DNEW
Definition always.h:109
unsigned long DWORD
Definition bittype.h:57
bool Close_Chunk()
Definition chunkio.cpp:448
uint32 Cur_Chunk_ID()
Definition chunkio.cpp:484
uint32 Read(void *buf, uint32 nbytes)
Definition chunkio.cpp:692
bool Open_Chunk()
Definition chunkio.cpp:412
uint32 Write(const void *buf, uint32 nbytes)
Definition chunkio.cpp:264
bool Begin_Chunk(uint32 id)
Definition chunkio.cpp:108
bool End_Chunk()
Definition chunkio.cpp:148
static ParticleEmitterClass * Create_From_Definition(const ParticleEmitterDefClass &definition)
Definition part_emt.cpp:205
virtual WW3DErrorType Save_Color_Keyframes(ChunkSaveClass &chunk_save)
virtual void Convert_To_Ver2(void)
Definition part_ldr.cpp:460
virtual WW3DErrorType Save_W3D(ChunkSaveClass &chunk_save)
float Get_Future_Start_Time(void) const
Definition part_ldr.h:147
virtual void Get_Size_Keyframes(ParticlePropertyStruct< float > &keyframes) const
virtual void Set_User_Type(int type)
Definition part_ldr.h:200
virtual WW3DErrorType Save_Extra_Info(ChunkSaveClass &chunk_save)
virtual void Set_User_String(const char *pstring)
Definition part_ldr.cpp:288
virtual void Set_Texture_Filename(const char *pname)
Definition part_ldr.cpp:314
const char * Get_Name(void) const
Definition part_ldr.h:122
virtual void Set_Frame_Keyframes(ParticlePropertyStruct< float > &keyframes)
virtual void Set_Size_Keyframes(ParticlePropertyStruct< float > &keyframes)
virtual WW3DErrorType Load_W3D(ChunkLoadClass &chunk_load)
Definition part_ldr.cpp:352
const ParticleEmitterDefClass & operator=(const ParticleEmitterDefClass &src)
Definition part_ldr.cpp:170
virtual void Get_Opacity_Keyframes(ParticlePropertyStruct< float > &keyframes) const
virtual WW3DErrorType Read_Rotation_Keyframes(ChunkLoadClass &chunk_load)
virtual bool Read_Opacity_Keyframe(ChunkLoadClass &chunk_load, float *key_time, float *value)
Definition part_ldr.cpp:909
virtual void Set_Name(const char *pname)
Definition part_ldr.cpp:301
virtual WW3DErrorType Read_Props(ChunkLoadClass &chunk_load)
Definition part_ldr.cpp:758
virtual void Get_Color_Keyframes(ParticlePropertyStruct< Vector3 > &keyframes) const
virtual WW3DErrorType Read_Extra_Info(ChunkLoadClass &chunk_load)
virtual void Set_Velocity_Random(Vector3Randomizer *randomizer)
Definition part_ldr.cpp:246
virtual WW3DErrorType Save_Size_Keyframes(ChunkSaveClass &chunk_save)
virtual Vector3Randomizer * Create_Randomizer(W3dVolumeRandomizerStruct &info)
Definition part_ldr.cpp:647
virtual WW3DErrorType Save_Header(ChunkSaveClass &chunk_save)
virtual ~ParticleEmitterDefClass(void)
Definition part_ldr.cpp:139
virtual WW3DErrorType Save_InfoV2(ChunkSaveClass &chunk_save)
const char * Get_User_String(void) const
Definition part_ldr.h:197
int Get_User_Type(void) const
Definition part_ldr.h:198
virtual WW3DErrorType Save_Props(ChunkSaveClass &chunk_save)
virtual WW3DErrorType Read_User_Data(ChunkLoadClass &chunk_load)
Definition part_ldr.cpp:572
virtual WW3DErrorType Read_Info(ChunkLoadClass &chunk_load)
Definition part_ldr.cpp:616
virtual void Normalize_Filename(void)
Definition part_ldr.cpp:327
virtual WW3DErrorType Read_Frame_Keyframes(ChunkLoadClass &chunk_load)
virtual void Get_Rotation_Keyframes(ParticlePropertyStruct< float > &rotationframes) const
virtual void Free_Props(void)
Definition part_ldr.cpp:215
virtual WW3DErrorType Read_Header(ChunkLoadClass &chunk_load)
Definition part_ldr.cpp:538
virtual bool Read_Size_Keyframe(ChunkLoadClass &chunk_load, float *key_time, float *value)
Definition part_ldr.cpp:947
virtual WW3DErrorType Read_Line_Properties(ChunkLoadClass &chunk_load)
Definition part_ldr.cpp:984
virtual WW3DErrorType Save_Frame_Keyframes(ChunkSaveClass &chunk_save)
virtual void Set_Color_Keyframes(ParticlePropertyStruct< Vector3 > &keyframes)
virtual void Initialize_Randomizer_Struct(const Vector3Randomizer &randomizer, W3dVolumeRandomizerStruct &info)
Definition part_ldr.cpp:679
virtual WW3DErrorType Save_Info(ChunkSaveClass &chunk_save)
virtual WW3DErrorType Read_Blur_Time_Keyframes(ChunkLoadClass &chunk_load)
virtual WW3DErrorType Read_InfoV2(ChunkLoadClass &chunk_load)
Definition part_ldr.cpp:719
virtual void Set_Rotation_Keyframes(ParticlePropertyStruct< float > &keyframes, float orient_rnd)
virtual WW3DErrorType Save_Rotation_Keyframes(ChunkSaveClass &chunk_save)
virtual WW3DErrorType Save_Blur_Time_Keyframes(ChunkSaveClass &chunk_save)
virtual WW3DErrorType Save_Line_Properties(ChunkSaveClass &chunk_save)
virtual void Set_Blur_Time_Keyframes(ParticlePropertyStruct< float > &keyframes)
virtual bool Read_Color_Keyframe(ChunkLoadClass &chunk_load, float *key_time, Vector3 *value)
Definition part_ldr.cpp:871
virtual void Set_Opacity_Keyframes(ParticlePropertyStruct< float > &keyframes)
virtual void Get_Frame_Keyframes(ParticlePropertyStruct< float > &frameframes) const
virtual void Initialize_To_Ver2(void)
Definition part_ldr.cpp:426
virtual void Set_Creation_Volume(Vector3Randomizer *randomizer)
Definition part_ldr.cpp:267
virtual void Get_Blur_Time_Keyframes(ParticlePropertyStruct< float > &blurtimeframes) const
virtual WW3DErrorType Save_User_Data(ChunkSaveClass &chunk_save)
virtual WW3DErrorType Save_Opacity_Keyframes(ChunkSaveClass &chunk_save)
virtual PrototypeClass * Load_W3D(ChunkLoadClass &chunk_load)
virtual RenderObjClass * Create(void)
ParticleEmitterDefClass * m_pDefinition
Definition part_ldr.h:356
WWINLINE void Release_Ref(void) const
Definition refcount.h:146
static ShaderClass _PresetAdditiveSpriteShader
Definition shader.h:398
static ShaderClass _PresetAlphaSpriteShader
Definition shader.h:403
WW3DFormat Get_Texture_Format() const
Definition texture.h:338
float X
Definition vector3.h:90
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91
@ CLASSID_SOLIDCYLINDER
Definition v3_rnd.h:67
virtual unsigned int Class_ID(void) const =0
static void Convert_Shader(const W3dShaderStruct &shader, ShaderClass *set)
Definition w3d_util.cpp:106
virtual TextureClass * Get_Texture(const char *filename, MipCountType mip_level_count=MIP_LEVELS_ALL, WW3DFormat texture_format=WW3D_FORMAT_UNKNOWN, bool allow_compression=true, TextureBaseClass::TexAssetType type=TextureBaseClass::TEX_REGULAR, bool allow_reduction=true)
static WW3DAssetManager * Get_Instance(void)
Definition assetmgr.h:205
__inline void Copy_Emitter_Property_Struct(ParticlePropertyStruct< T > &dest, const ParticlePropertyStruct< T > &src)
Definition part_emt.h:76
#define SAFE_DELETE(pointer)
Definition part_ldr.cpp:45
ParticleEmitterLoaderClass _ParticleEmitterLoader
Definition part_ldr.cpp:68
#define SAFE_DELETE_ARRAY(pointer)
Definition part_ldr.cpp:55
const char * EMITTER_TYPE_NAMES[EMITTER_TYPEID_COUNT]
Definition part_ldr.cpp:71
#define VECTOR3_TO_RGBA(vector3, rgba)
Definition part_ldr.h:83
#define SAFE_FREE(pointer)
Definition part_ldr.h:64
#define RGBA_TO_VECTOR3(rgba)
Definition part_ldr.h:80
else return(RetVal)
char Name[W3D_NAME_LEN]
Definition w3d_file.h:1769
W3dRGBAStruct ColorRandom
Definition w3d_file.h:1847
WW3DErrorType
Definition w3derr.h:51
@ WW3D_ERROR_LOAD_FAILED
Definition w3derr.h:54
@ WW3D_ERROR_OK
Definition w3derr.h:52
@ WW3D_ERROR_SAVE_FAILED
Definition w3derr.h:55
bool Has_Alpha(WW3DFormat format)
Definition ww3dformat.h:126
#define WWDEBUG_SAY(x)
Definition wwdebug.h:114