1// tWorld.h 
2// 
3// This class represents entire worlds of tObjects. Instances, materials, models, paths, lights, skeletons, and cameras 
4// may all be present in a tWorld. It is able to load multiple tChunk-based binary tac files. It can also save them. 
5// 
6// Every saved tac file contains a version chunk with both major and minor version numbers. Increment the minor number 
7// if there is a change to a tObject that does not break binary compatibility. For example, you can add a new chunk ID 
8// as long as loading it is optional. The major version number must be incremented if file compatibility is broken. 
9// This can happen if chunks are rearranged or chunk contents are altered. This allows an exporters to change, perhaps 
10// a new chunk was added, without the tac file parsing tool needing an upgrade immediately (forward compatibility). The 
11// minor version should be reset to 0 when the major number is incremented. Any tools, by looking at the major number, 
12// can maintain backwards compatibility. 
13// 
14// Version History 
15// 1.0 Initial release. 
16// 
17// Copyright (c) 2006, 2017 Tristan Grimmer. 
18// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
19// granted, provided that the above copyright notice and this permission notice appear in all copies. 
20// 
21// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
22// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
23// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
24// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
25// PERFORMANCE OF THIS SOFTWARE. 
26 
27#pragma once 
28#include <Foundation/tPlatform.h> 
29#include <Foundation/tList.h> 
30#include "Scene/tCamera.h" 
31#include "Scene/tLight.h" 
32#include "Scene/tPath.h" 
33#include "Scene/tMaterial.h" 
34#include "Scene/tSkeleton.h" 
35#include "Scene/tPolyModel.h" 
36#include "Scene/tLodGroup.h" 
37#include "Scene/tInstance.h" 
38#include "Scene/tSelection.h" 
39namespace tScene 
40
41 
42 
43const uint32 SceneMajorVersion = 1
44const uint32 SceneMinorVersion = 0
45 
46 
47class tWorld 
48
49public
50 // When loading a tac file, what object types do we process. Filters can be combined. 
51 enum tLoadFilter 
52
53 tLoadFilter_None = 0x00000000
54 tLoadFilter_Cameras = 0x00000001
55 tLoadFilter_Lights = 0x00000002
56 tLoadFilter_Paths = 0x00000004
57 tLoadFilter_Materials = 0x00000008
58 tLoadFilter_Skeletons = 0x00000010
59 tLoadFilter_Models = 0x00000020
60 tLoadFilter_LodGroups = 0x00000040
61 tLoadFilter_Instances = 0x00000080
62 tLoadFilter_Selections = 0x00000100
63 tLoadFilter_All = 0xFFFFFFFF 
64 }; 
65 
66 tWorld() { } 
67 
68 // Loads scene from a tac chunk file. Any externally referenced files get turned into absolute paths. For example, 
69 // a tMaterial may refer to a dds file relative to it's location on disk. After the tWorld is created, the path to 
70 // the dds will be absolute. This allows the tWorld Load call to be called multiple times and load several files 
71 // into a single world. 
72 tWorld(const tString& tacFile, uint32 filter = tLoadFilter_All) { Load(tacFile, filter); } 
73 
74 // This constructor can load from multiple tac files and merges them all into one world. 
75 tWorld(const tItList<tString>& tacFiles, uint32 filter = tLoadFilter_All) { Load(tacFiles, filter); } 
76 virtual ~tWorld() { Clear(); } 
77 
78 void Clear(); // Clears the scene. Frees any lists or internal objects. 
79 void Scale(float); // Scales the scene and all its objects. 
80 
81 // @todo Allow save to take filters. 
82 void Save(const tString& tacFile) const
83 
84 // Load may be called more than once to load more objects into the same world. 
85 void Load(const tString& tacFile, uint32 filter = tLoadFilter_All); 
86 void Load(const tItList<tString>& tacFiles, uint32 filter = tLoadFilter_All) { for (tItList<tString>::Iter file = tacFiles.First(); file.IsValid(); ++file) Load(*file, filter); } 
87 
88 void AddOffsetToAllIDs(uint32 offset); 
89 
90 // This merges the srcWorld into the current world. In doing so, the srcWorld is left empty and invalid. 
91 void MergeScene(tWorld& srcWorld); 
92 
93 // This function merges various tObject types into the current world. Since some tObject types can refer to other 
94 // tObject types, it is important that you supply the objects you want to merge _and_ any objects that may be 
95 // referenced. You need to go 'all the way down the tree' until you are referencing nothing. Here's a chart that 
96 // shows what tObjects may reference others: 
97 // 
98 // cameras reference nothing 
99 // lights reference nothing 
100 // paths reference nothing 
101 // materials reference nothing (external files only) 
102 // skeletons reference nothing 
103 // polyModels reference materials, skeletons 
104 // lodGroups reference polyModels 
105 // instances reference lodGroups, polyModels, cameras, lights, paths 
106 // selectionSets reference instances 
107 // 
108 // The passed-in object lists are emptied and merged into the scene. Returns true if all the necessary objects were 
109 // supplied and the merge was successful. 
110 bool MergeItems 
111
112 tItList<tCamera>*, tItList<tLight>*, tItList<tPath>*, 
113 tItList<tMaterial>*, tItList<tSkeleton>*, tItList<tPolyModel>*, 
114 tItList<tLodGroup>*, tItList<tInstance>*, tItList<tSelection>* 
115 ); 
116 
117 // CombinePolyModelInstances combines a list of tPolyModel instances, their meshes and their materials into a 
118 // single new instance called instName. The polymodel instances you want to combine must already be in the scene. 
119 // The polymodel instances you provide may no longer in the scene after this call if there are no other instances 
120 // that refer to it. The new instance will have it's own new polymodel. Returns success. 
121 bool CombinePolyModelInstances(tItList<tInstance>& polymodelInstances, tString newInstName); 
122 
123 // Returns the number of cameras in the world. If name is supplied, returns the number with that particular name. 
124 int GetNumCameras(const tString& name = tString()) const
125 
126 // Inserts the supplied camera into the scene. 
127 void InsertCamera(tCamera*); 
128 
129 // Returns first camera with supplied name. Returns nullptr if not found. 
130 tCamera* FindCamera(const tString& name) const
131 
132 // Returns the camera having the id supplied. Returns nullptr if not found. 
133 tCamera* FindCamera(uint32 id) const
134 
135 // The rest of these functions are similar to the 4 above except for different tObject types. 
136 int GetNumLights(const tString& name = tString()) const
137 void InsertLight(tLight*); 
138 tLight* FindLight(const tString& name) const
139 tLight* FindLight(uint32 id) const
140 
141 int GetNumPaths(const tString& name = tString()) const
142 void InsertPath(tPath*); 
143 tPath* FindPath(const tString& name) const
144 tPath* FindPath(uint32 id) const
145 
146 int GetMaterials(const tMesh& mesh, tItList<tMaterial>&); // Returns the materials used by a particular mesh. 
147 int GetNumMaterials(const tString& name = tString()) const
148 void InsertMaterial(tMaterial*); 
149 tMaterial* FindMaterial(const tString& name) const
150 tMaterial* FindMaterial(uint32 id) const
151 
152 int GetNumSkeletons(const tString& name = tString()) const
153 void InsertSkeleton(tSkeleton*); 
154 tSkeleton* FindSkeleton(const tString& name) const
155 tSkeleton* FindSkeleton(uint32 id) const
156 
157 int GetNumModels(const tString& name = tString()) const
158 void InsertPolyModel(tPolyModel*); 
159 tPolyModel* FindPolyModel(const tString& name) const
160 tPolyModel* FindPolyModel(uint32 id) const
161 
162 int GetNumLodGroups(const tString& name = tString()) const
163 void InsertLodGroup(tLodGroup*); 
164 tLodGroup* FindLodGroup(const tString& name) const
165 tLodGroup* FindLodGroup(uint32 id) const
166 
167 int GetNumInstances(const tString& name = tString()) const
168 void InsertInstance(tInstance*); 
169 tInstance* FindInstance(const tString& name) const
170 tInstance* FindInstance(uint32 id) const
171 bool IsInstanceInSelection(const tInstance*, const tSelection*) const
172 
173 int GetNumSelections(const tString& name = tString()) const
174 void InsertSelection(tSelection*); 
175 tSelection* FindSelection(const tString& name) const
176 tSelection* FindSelection(uint32 id) const
177 
178 // Returns a list of pointers to all selection sets that contain partialName somewhere in their name. You must 
179 // empty the list yourself afterwards (you own it), but you don't own the things the pointers on the list point to 
180 // (the selection sets). 
181 void FindSelectionsContaining(tItList<tSelection*>&, const tString& partialName) const
182 
183 // This call generates additional tLodGroups based on a model naming convention. All models must be present in the 
184 // scene before calling this. The model naming convention is: "ModelName_LOD_n" where n is the percent of screen 
185 // space above which the model will be used. The "ModelName" becomes the name of the group, and all models that 
186 // follow the pattern get their IsLodGroupMember member set. Returns the number of additional tLodGroups that were 
187 // added to the scene. 
188 // 
189 // This functionality should arguably be in the exporter code itself, but since it's a lot of work to make Lod plugins 
190 // for some modeling packages we've decided a naming convention is reasonable. Multiple modeling SW may need this 
191 // functionality so it makes sense to put it in a shared location like the tWorld (here). It is ok if there are 
192 // already LodGroups in the scene. Any new ones simply get assigned new IDs starting at a value one higher than the 
193 // highest of any current LodGroups. 
194 int GenerateLodGroupsFromModelNamingConvention(); 
195 
196private
197 // These are helper functions to save and load different types of tObjects. 
198 void SaveMaterials(tChunkWriter&) const
199 void SaveObjects(tChunkWriter&) const
200 void SaveGroups(tChunkWriter&) const
201 void SaveInstances(tChunkWriter&) const
202 void SaveSelections(tChunkWriter&) const
203 
204 void LoadMaterials(const tChunk&, tItList<tMaterial>&); 
205 void LoadObjects 
206
207 const tChunk&, 
208 tItList<tPolyModel>&, tItList<tSkeleton>&, tItList<tCamera>&, tItList<tLight>&, tItList<tPath>&, 
209 uint32 loadFilter 
210 ); 
211 void LoadGroups(const tChunk&, tItList<tLodGroup>&); 
212 void LoadInstances(const tChunk&, tItList<tInstance>&); 
213 void LoadSelections(const tChunk&, tItList<tSelection>&); 
214 
215 void CorrectCameraIDs(tItList<tCamera>&, tItList<tInstance>&); 
216 void CorrectLightIDs(tItList<tLight>&, tItList<tInstance>&); 
217 void CorrectPathIDs(tItList<tPath>&, tItList<tInstance>&); 
218 void CorrectMaterialIDs(tItList<tMaterial>&, tItList<tPolyModel>&); 
219 void CorrectSkeletonIDs(tItList<tSkeleton>&, tItList<tPolyModel>&); 
220 void CorrectPolyModelIDs(tItList<tPolyModel>&, tItList<tLodGroup>&, tItList<tInstance>&); 
221 void CorrectLodGroupIDs(tItList<tLodGroup>&); 
222 void CorrectInstanceIDs(tItList<tInstance>&, tItList<tSelection>&); 
223 void CorrectSelectionIDs(tItList<tSelection>&); 
224 void MergeToExistingSelections(tItList<tSelection>&); 
225 
226public
227 tString Name
228 tString LastLoadedFilename
229 
230 // These don't reference anything else in the world, only external file references. 
231 tItList<tCamera> Cameras
232 tItList<tLight> Lights
233 tItList<tPath> Paths
234 tItList<tMaterial> Materials
235 tItList<tSkeleton> Skeletons
236 
237 // These may reference materials and skeletons. 
238 tItList<tPolyModel> PolyModels
239 
240 // These may reference poly-models. 
241 tItList<tLodGroup> LodGroups
242 
243 // Instances may reference anything above. 
244 tItList<tInstance> Instances
245 
246 // Selection sets may reference instances. 
247 tItList<tSelection> Selections
248 
249 // These are always the version numbers of the last file loaded. 
250 uint32 MajorVersion = SceneMajorVersion
251 uint32 MinorVersion = SceneMinorVersion
252 
253 // Used to assign new IDs sequentially. 
254 uint32 NextCameraID = 0
255 uint32 NextLightID = 0
256 uint32 NextPathID = 0
257 uint32 NextMaterialID = 0
258 uint32 NextSkeletonID = 0
259 uint32 NextPolyModelID = 0
260 uint32 NextLodGroupID = 0
261 uint32 NextInstanceID = 0
262 uint32 NextSelectionID = 0
263}; 
264 
265 
266
267