source: OniSplit/Akira/MaterialLibrary.cs

Last change on this file was 1114, checked in by iritscen, 5 years ago

Adding OniSplit source code (v0.9.99.0). Many thanks to Neo for all his work over the years.

File size: 12.0 KB
Line 
1using System;
2using System.Collections.Generic;
3using Oni.Imaging;
4
5namespace Oni.Akira
6{
7 internal class MaterialLibrary
8 {
9 private readonly MarkerMaterials markers = new MarkerMaterials();
10 private readonly Dictionary<string, Material> materials = new Dictionary<string, Material>(StringComparer.OrdinalIgnoreCase);
11 private Material notFound;
12
13 #region internal class MarkerMaterials
14
15 internal class MarkerMaterials
16 {
17 private Material ghost;
18 private Material stairs;
19 private Material door;
20 private Material danger;
21 private Material barrier;
22 private Material impassable;
23 private Material blackness;
24 private Material floor;
25
26 public Material GetMarker(string name)
27 {
28 EnsureMaterials();
29
30 switch (name)
31 {
32 case "_marker_door":
33 return door;
34 case "_marker_ghost":
35 return ghost;
36 case "_marker_stairs":
37 return stairs;
38 case "_marker_danger":
39 return danger;
40 case "_marker_barrier":
41 return barrier;
42 case "_marker_impassable":
43 return impassable;
44 case "_marker_blackness":
45 return blackness;
46 case "_marker_floor":
47 return floor;
48 default:
49 return null;
50 }
51 }
52
53 public Material GetMarker(Polygon polygon)
54 {
55 EnsureMaterials();
56
57 var flags = polygon.Flags & ~(GunkFlags.ProjectionBit0 | GunkFlags.ProjectionBit1 | GunkFlags.Horizontal | GunkFlags.Vertical);
58 var adjacencyFlags = GunkFlags.Ghost | GunkFlags.StairsUp | GunkFlags.StairsDown;
59
60 if ((flags & (GunkFlags.DoorFrame | adjacencyFlags)) == GunkFlags.DoorFrame)
61 return door;
62
63 if ((flags & adjacencyFlags) != 0)
64 return ghost;
65
66 if ((flags & GunkFlags.Invisible) != 0)
67 {
68 flags &= ~GunkFlags.Invisible;
69
70 if ((flags & GunkFlags.Danger) != 0)
71 return danger;
72
73 if ((flags & GunkFlags.Stairs) != 0)
74 return stairs;
75
76 if ((flags & (GunkFlags.NoObjectCollision | GunkFlags.NoCharacterCollision)) == GunkFlags.NoObjectCollision)
77 return barrier;
78
79 if ((flags & (GunkFlags.NoObjectCollision | GunkFlags.NoCharacterCollision | GunkFlags.NoCollision)) == 0)
80 return impassable;
81
82 //
83 // What's the point of a invisible and no collision polygon?!
84 //
85
86 if ((flags & GunkFlags.NoCollision) != 0)
87 return null;
88
89 Console.Error.WriteLine("Unknown invisible material, fix tool: {0}", flags);
90 }
91 else
92 {
93 if ((flags & (GunkFlags.TwoSided | GunkFlags.NoCollision)) == (GunkFlags.TwoSided | GunkFlags.NoCollision)
94 && polygon.Material != null
95 && polygon.Material.Name == "BLACKNESS")
96 {
97 return blackness;
98 }
99 }
100
101 return null;
102 }
103
104 private void EnsureMaterials()
105 {
106 if (ghost != null)
107 return;
108
109 CreateGhost();
110 CreateBarrier();
111 CreateDanger();
112 CreateDoor();
113 CreateStairs();
114 CreateImpassable();
115 CreateBlackness();
116 CreateFloor();
117 }
118
119 private void CreateBarrier()
120 {
121 var surface = new Surface(128, 128);
122
123 var fill = new Color(0, 240, 20, 180);
124 var sign = new Color(240, 20, 0, 255);
125
126 surface.Fill(0, 0, 128, 128, fill);
127
128 surface.Fill(0, 0, 128, 1, sign);
129 surface.Fill(0, 127, 128, 1, sign);
130 surface.Fill(0, 1, 1, 126, sign);
131 surface.Fill(127, 1, 1, 126, sign);
132 surface.Fill(64, 1, 1, 126, sign);
133 surface.Fill(1, 64, 126, 1, sign);
134
135 barrier = new Material("_marker_barrier", true)
136 {
137 Flags = GunkFlags.NoObjectCollision | GunkFlags.Invisible,
138 Image = surface
139 };
140 }
141
142 private void CreateImpassable()
143 {
144 var surface = new Surface(128, 128);
145
146 var fill = new Color(240, 0, 20, 180);
147 var sign = new Color(240, 20, 0, 255);
148
149 surface.Fill(0, 0, 128, 128, fill);
150
151 surface.Fill(0, 0, 128, 1, sign);
152 surface.Fill(0, 127, 128, 1, sign);
153 surface.Fill(0, 1, 1, 126, sign);
154 surface.Fill(127, 1, 1, 126, sign);
155 surface.Fill(64, 1, 1, 126, sign);
156 surface.Fill(1, 64, 126, 1, sign);
157
158 impassable = new Material("_marker_impassable", true)
159 {
160 Flags = GunkFlags.Invisible,
161 Image = surface
162 };
163 }
164
165 private void CreateGhost()
166 {
167 var surface = new Surface(128, 128);
168
169 var border = new Color(16, 48, 240, 240);
170 var fill = new Color(208, 240, 240, 80);
171
172 surface.Fill(0, 0, 128, 128, fill);
173
174 surface.Fill(0, 0, 128, 1, border);
175 surface.Fill(0, 127, 128, 1, border);
176 surface.Fill(0, 1, 1, 126, border);
177 surface.Fill(127, 1, 1, 126, border);
178 surface.Fill(64, 1, 1, 126, border);
179 surface.Fill(1, 64, 126, 1, border);
180
181 ghost = new Material("_marker_ghost", true);
182 ghost.Flags = GunkFlags.Ghost | GunkFlags.TwoSided | GunkFlags.Transparent | GunkFlags.NoCollision;
183 ghost.Image = surface;
184 }
185
186 private void CreateDoor()
187 {
188 var surface = new Surface(128, 128);
189
190 var fill = new Color(240, 240, 0, 208);
191 var line = new Color(0, 0, 240);
192
193 surface.Fill(0, 0, 128, 128, fill);
194
195 surface.Fill(1, 1, 126, 1, line);
196 surface.Fill(1, 1, 1, 126, line);
197 surface.Fill(1, 126, 126, 1, line);
198 surface.Fill(126, 1, 1, 126, line);
199
200 door = new Material("_marker_door", true)
201 {
202 Flags = GunkFlags.DoorFrame | GunkFlags.TwoSided | GunkFlags.Transparent | GunkFlags.NoCollision,
203 Image = surface
204 };
205 }
206
207 private void CreateDanger()
208 {
209 var surface = new Surface(128, 128);
210
211 var fill = new Color(255, 10, 0, 208);
212 var sign = new Color(255, 255, 255, 255);
213
214 surface.Fill(0, 0, 128, 128, fill);
215 surface.Fill(52, 16, 24, 64, sign);
216 surface.Fill(52, 96, 24, 16, sign);
217
218 danger = new Material("_marker_danger", true)
219 {
220 Flags = GunkFlags.Danger | GunkFlags.Invisible | GunkFlags.NoCollision | GunkFlags.NoOcclusion,
221 Image = surface
222 };
223 }
224
225 private void CreateStairs()
226 {
227 var surface = new Surface(128, 128);
228
229 var fill = new Color(40, 240, 0, 180);
230 var step = new Color(40, 0, 240, 180);
231
232 surface.Fill(0, 0, 128, 128, fill);
233
234 for (int y = 0; y < surface.Height; y += 32)
235 surface.Fill(0, y, surface.Width, 16, step);
236
237 stairs = new Material("_marker_stairs", true)
238 {
239 Flags = GunkFlags.Stairs | GunkFlags.Invisible | GunkFlags.NoObjectCollision | GunkFlags.TwoSided,
240 Image = surface
241 };
242 }
243
244 private void CreateBlackness()
245 {
246 var surface = new Surface(16, 16, SurfaceFormat.BGRX);
247
248 surface.Fill(0, 0, 16, 16, Color.Black);
249
250 blackness = new Material("_marker_blackness", true)
251 {
252 Flags = GunkFlags.TwoSided | GunkFlags.NoCollision,
253 Image = surface
254 };
255 }
256
257 private void CreateFloor()
258 {
259 var surface = new Surface(256, 256);
260
261 surface.Fill(0, 0, 16, 16, Color.White);
262
263 for (int x = 0; x < 256; x += 4)
264 {
265 surface.Fill(x, 0, 1, 256, Color.Black);
266 surface.Fill(0, x, 256, 1, Color.Black);
267 }
268
269 floor = new Material("_marker_floor", true)
270 {
271 Flags = GunkFlags.NoCollision,
272 Image = surface
273 };
274 }
275
276 public Material Barrier
277 {
278 get
279 {
280 EnsureMaterials();
281 return barrier;
282 }
283 }
284
285 public Material Ghost
286 {
287 get
288 {
289 EnsureMaterials();
290 return ghost;
291 }
292 }
293
294 public Material Danger
295 {
296 get
297 {
298 EnsureMaterials();
299 return danger;
300 }
301 }
302
303 public Material DoorFrame
304 {
305 get
306 {
307 EnsureMaterials();
308 return door;
309 }
310 }
311
312 public Material Stairs
313 {
314 get
315 {
316 EnsureMaterials();
317 return stairs;
318 }
319 }
320
321 public Material Floor
322 {
323 get
324 {
325 EnsureMaterials();
326 return floor;
327 }
328 }
329
330 public Material Blackness
331 {
332 get
333 {
334 EnsureMaterials();
335 return blackness;
336 }
337 }
338 }
339
340 #endregion
341
342 public MarkerMaterials Markers => markers;
343
344 public Material NotFound
345 {
346 get
347 {
348 if (notFound == null)
349 notFound = GetMaterial("notfoundtex");
350
351 return notFound;
352 }
353 }
354
355 public IEnumerable<Material> All => materials.Values;
356
357 public Material GetMaterial(string name)
358 {
359 Material material;
360
361 if (!materials.TryGetValue(name, out material))
362 {
363 material = markers.GetMarker(name);
364
365 if (material == null)
366 material = new Material(name);
367
368 materials.Add(name, material);
369 }
370
371 if (name.StartsWith("lmap_", StringComparison.OrdinalIgnoreCase))
372 {
373 material.Flags |= GunkFlags.NoCollision | GunkFlags.NoOcclusion | GunkFlags.SoundTransparent;
374 }
375
376 return material;
377 }
378 }
379}
Note: See TracBrowser for help on using the repository browser.