| Acknowledgments |
v |
| Preface |
xvii |
| Introduction |
1 |
| Offline Processing |
2 |
| Beating the RAM Barrier |
3 |
| Streaming |
4 |
| Other Factors |
5 |
| The Asset Pipeline |
6 |
| The Asset Feedback Loop |
6 |
| The Structure of Game Assets |
8 |
| Builds |
10 |
| Version Control |
10 |
| Asset Dependencies |
11 |
| Data Validation |
12 |
| Error Handling |
13 |
| Workflow |
14 |
| Conclusion |
15 |
| Where Do Assets Come From? |
17 |
| Tool Integration |
18 |
| Adding Features |
19 |
| Naming Conventions |
20 |
| Additional Data Fields |
20 |
| Plug-in Objects |
21 |
| Custom Export Tools |
22 |
| Data Formats |
23 |
| 2D Bitmap Data |
23 |
| Audio Data |
25 |
| Video Data |
26 |
| 3D Object Data |
28 |
| Custom Intermediate File Formats |
29 |
| Text or Binary? |
30 |
| File Structure |
32 |
| Wrapper Formats |
34 |
| XML |
37 |
| Conclusion |
39 |
| A High-Level View of Asset Management |
41 |
| Why Asset Management Is Not Source Control |
42 |
| Differences in Data |
43 |
| Handling Very Large Files |
44 |
| Asset Identification |
47 |
| Metadata |
47 |
| Change Tracking and History |
48 |
| Broken Data |
50 |
| Dealing with Broken Assets |
51 |
| Local Changes |
53 |
| Asset Building Shortcuts |
54 |
| Unrepresentative Previews |
55 |
| Runtime Editing |
56 |
| Synchronizing Code and Data |
57 |
| Integrating Code into the Asset Pipeline |
58 |
| Building a Distribution Package |
60 |
| Automated Testing |
60 |
| Conclusion |
61 |
| Building an Asset Management System |
63 |
| Storage Systems |
64 |
| Native Filing Systems |
64 |
| CVS |
66 |
| Subversion |
67 |
| Bitkeeper |
68 |
| Perforce |
69 |
| Alienbrain |
70 |
| Databases |
72 |
| Transactions and Locking |
73 |
| Operation Queues |
74 |
| Record Locking |
74 |
| Separating Metadata and File Locks |
75 |
| Client/Server Architecture |
76 |
| Clientless Architectures |
77 |
| The Client/Server Boundary |
77 |
| Using File Sharing Protocols |
78 |
| Intelligent File Updating |
79 |
| Client Tools |
80 |
| GUI Tools |
80 |
| Command-Line Tools |
80 |
| Shell Integration |
81 |
| Managing the Local Repository |
81 |
| Preventing Unwanted File Modifications |
82 |
| Handling Temporary Files |
83 |
| Client Tool UI and Functionality Considerations |
83 |
| Hierarchies and Views |
83 |
| Separating Projects |
85 |
| Sharing Files between Projects |
86 |
| Searching |
86 |
| Unique Identifiers |
87 |
| Linking Files |
88 |
| Metadata |
89 |
| Workflow Control |
91 |
| Preview Functionality |
93 |
| Showing Asset Modifications |
95 |
| Access Controls and Security |
95 |
| Using Views to Control Access |
96 |
| External Security |
97 |
| Providing an External API |
97 |
| Single and Multiple Client Models |
98 |
| Interface State |
99 |
| High-Level APIs |
100 |
| Scripting Support |
100 |
| Change Notification Handling |
101 |
| Caching Strategies |
102 |
| Archiving and Purging Data |
105 |
| Choosing Which Asset Revisions to Remove |
105 |
| Deleting Files |
106 |
| Archiving Files |
106 |
| Manually Purging Assets |
108 |
| Conclusion |
109 |
| Texture and Image Processing |
111 |
| Textures |
112 |
| Texture Swizzling |
112 |
| Texture Compression |
115 |
| Performing Texture Compression |
115 |
| Texture Quantization |
116 |
| Texture Resizing |
117 |
| Conforming Textures |
120 |
| Color Reduction |
121 |
| Dithering |
129 |
| Ordered Dithering |
129 |
| Error Diffusion Dithering |
130 |
| Dithering Textures |
131 |
| Using Alternative Color Spaces |
132 |
| The YUV Color Space |
133 |
| Conclusion |
135 |
| Geometry Processing |
137 |
| Mesh Data |
138 |
| Indexed Vertices |
140 |
| Model Hierarchy Information |
141 |
| Mesh Geometry Processing |
141 |
| Stripification |
141 |
| Building Triangle Strips |
142 |
| The Greedy Algorithm |
143 |
| The SGI Algorithm |
145 |
| Back-Face Culling and Winding Order |
146 |
| Merging Strips |
148 |
| Making Use of Draw-Cancel Flags |
149 |
| Strips versus Lists |
151 |
| Vertex Cache Optimization |
152 |
| Triangle Lists |
154 |
| Depth Sorting |
155 |
| Sanitizing Input Data |
157 |
| Orphaned Data |
158 |
| Vertex Welding |
158 |
| Removing Degenerate Triangles |
159 |
| Non-Coplanar Polygons |
160 |
| Regular Mesh Subdivision |
161 |
| Clipping Triangles |
162 |
| Clipping Polygons |
163 |
| Geometry Compression |
169 |
| Compressing Vertex Positions |
169 |
| Bone Weight Processing |
172 |
| Removing Redundant Bone Associations |
172 |
| Using Pre-Multiplied Bones |
173 |
| Constructing Composite Bones |
173 |
| Subdividing Skinned Meshes |
174 |
| Building Bounding Volumes |
175 |
| Axis-Aligned Bounding Boxes |
176 |
| Bounding Spheres |
176 |
| Oriented Bounding Boxes |
178 |
| Convex Hulls |
180 |
| Interior Bounding Volumes |
184 |
| Transparency and Bounding Volumes |
186 |
| Generating Multiple Bounding Volumes |
186 |
| Bounding Volumes for Animated Meshes |
189 |
| Bounding Volumes for Skinned Meshes |
190 |
| Performing Vertex Compression with Animated Bounding Boxes |
193 |
| Mesh Hierarchy Processing |
193 |
| Collapsing Nodes |
194 |
| Removing Leaf Nodes |
195 |
| Merging Nodes |
195 |
| Level of Detail Simplification |
197 |
| Hierarchy Merging |
197 |
| Polygon Reduction |
199 |
| Generating Imposter Sprites |
204 |
| Using Imposter Geometry |
206 |
| Audio and Video Processing |
209 |
| Audio |
209 |
| Resampling |
210 |
| Looping Samples |
212 |
| Audio Compression |
212 |
| ADPCM |
213 |
| MP3 |
214 |
| Scripting Languages |
216 |
| Compiling Script Code |
216 |
| Deriving Dependencies from Scripts |
216 |
| Video |
217 |
| Video Compression |
218 |
| Localizing Video |
220 |
| Subtitles |
221 |
| Video Standard Conversion |
221 |
| Conclusion |
222 |
| Environment Processing |
223 |
| BSP Trees |
224 |
| Building a BSP Tree |
225 |
| Potentially Visible Sets |
228 |
| Portals |
228 |
| Ray Casting |
229 |
| Beam Casting |
230 |
| Routing Information |
230 |
| Accessibility Information |
231 |
| Connectivity Information |
233 |
| Precalculated Lighting |
234 |
| Vertex Lighting |
234 |
| Lightmaps |
235 |
| Volumetric Lighting |
237 |
| Conclusion |
238 |
| Managing Asset Processing |
241 |
| Dependency-Based Processing |
242 |
| Determining Asset Dependencies |
245 |
| Determining When Assets Have Changed |
246 |
| Handling Code Changes |
247 |
| The Make Tool |
249 |
| Descriptor File Syntax |
249 |
| Advantages and Limitations of Make |
253 |
| Output Data Formats |
254 |
| Standardizing Wrapper Formats |
254 |
| Including Metadata |
255 |
| Memory Ready and Parsed Formats |
256 |
| Byte Order Considerations |
258 |
| Handling File Interdependencies |
259 |
| Building Robust Tools |
260 |
| Be Lenient in What You Accept, but Strict in What You Output |
260 |
| Handling Tool Failure |
261 |
| Debugging the Pipeline |
264 |
| Maintaining Data Integrity |
265 |
| Interfacing to Existing Systems |
266 |
| Conclusion |
267 |
| Final Data |
269 |
| File Packing |
270 |
| Packed File Formats |
271 |
| Handling Very Large Package Files |
271 |
| Using Multiple Package Files |
272 |
| Obfuscating Data |
272 |
| Data Layout |
273 |
| Optimizing Linear Loading Procedures |
273 |
| Optimizing Streaming |
274 |
| Audio Streams |
275 |
| Interleaved Streams |
275 |
| Integrity Checking |
276 |
| Digital Signatures |
278 |
| Public Key Signatures |
280 |
| Cryptographic Hashing |
280 |
| Using Cryptography in Games |
281 |
| Encryption |
282 |
| What to Encrypt |
283 |
| Compression |
284 |
| What Can Be Compressed? |
284 |
| Compression Schemes |
284 |
| Other Compression Issues |
286 |
| Distribution Media |
287 |
| CD-ROMs |
287 |
| DVDs |
288 |
| Cartridges |
288 |
| Hard Discs |
288 |
| Internet Distribution |
289 |
| After Shipping |
290 |
| Data Archival |
290 |
| Patching Data |
292 |
| Conclusion |
295 |
| Bibliography |
297 |
| Index |
299 |