1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 |
|
---|
4 | namespace Oni.Akira
|
---|
5 | {
|
---|
6 | internal class AlphaBspBuilder
|
---|
7 | {
|
---|
8 | private PolygonMesh mesh;
|
---|
9 | private bool debug;
|
---|
10 |
|
---|
11 | public static AlphaBspNode Build(PolygonMesh mesh, bool debug)
|
---|
12 | {
|
---|
13 | var builder = new AlphaBspBuilder
|
---|
14 | {
|
---|
15 | mesh = mesh,
|
---|
16 | debug = debug
|
---|
17 | };
|
---|
18 |
|
---|
19 | return builder.Build();
|
---|
20 | }
|
---|
21 |
|
---|
22 | private AlphaBspNode Build()
|
---|
23 | {
|
---|
24 | var transparent = new List<Polygon>(1024);
|
---|
25 |
|
---|
26 | transparent.AddRange(mesh.Polygons.Where(p => p.IsTransparent));
|
---|
27 |
|
---|
28 | if (debug)
|
---|
29 | transparent.AddRange(mesh.Ghosts.Where(p => p.IsTransparent));
|
---|
30 |
|
---|
31 | Console.Error.WriteLine("Building bsp tree for {0} transparent polygons...", transparent.Count);
|
---|
32 | return Build(transparent);
|
---|
33 | }
|
---|
34 |
|
---|
35 | private AlphaBspNode Build(List<Polygon> polygons)
|
---|
36 | {
|
---|
37 | if (polygons.Count == 0)
|
---|
38 | return null;
|
---|
39 |
|
---|
40 | var separator = polygons[0].Plane;
|
---|
41 | AlphaBspNode frontNode = null, backNode = null;
|
---|
42 |
|
---|
43 | if (polygons.Count > 1)
|
---|
44 | {
|
---|
45 | var front = new List<Polygon>(polygons.Count);
|
---|
46 | var back = new List<Polygon>(polygons.Count);
|
---|
47 |
|
---|
48 | for (int i = 1; i < polygons.Count; i++)
|
---|
49 | {
|
---|
50 | var polygon = polygons[i];
|
---|
51 | var plane = polygon.Plane;
|
---|
52 |
|
---|
53 | bool isFront = false;
|
---|
54 | bool isBack = false;
|
---|
55 |
|
---|
56 | if (Math.Abs(plane.D - separator.D) < 0.001f
|
---|
57 | && Vector3.Distance(plane.Normal, separator.Normal) < 0.001f)
|
---|
58 | {
|
---|
59 | isFront = true;
|
---|
60 | }
|
---|
61 | else
|
---|
62 | {
|
---|
63 | foreach (var point in polygon.Points)
|
---|
64 | {
|
---|
65 | if (separator.DotCoordinate(point) > 0.0f)
|
---|
66 | isFront = true;
|
---|
67 | else
|
---|
68 | isBack = true;
|
---|
69 | }
|
---|
70 | }
|
---|
71 |
|
---|
72 | if (isFront)
|
---|
73 | front.Add(polygon);
|
---|
74 |
|
---|
75 | if (isBack)
|
---|
76 | back.Add(polygon);
|
---|
77 | }
|
---|
78 |
|
---|
79 | frontNode = Build(front);
|
---|
80 | backNode = Build(back);
|
---|
81 | }
|
---|
82 |
|
---|
83 | return new AlphaBspNode(polygons[0], frontNode, backNode);
|
---|
84 | }
|
---|
85 | }
|
---|
86 | }
|
---|