1 | #include "VssRay.h"
|
---|
2 | #include "Beam.h"
|
---|
3 |
|
---|
4 |
|
---|
5 |
|
---|
6 | void
|
---|
7 | Beam::Construct(const AxisAlignedBox3 &box, const AxisAlignedBox3 &dBox)
|
---|
8 | {
|
---|
9 | // the frustum is defined by set of negative halfspace described by mPlanes
|
---|
10 |
|
---|
11 | // construct
|
---|
12 | Vector3 center = box.Center();
|
---|
13 | Vector3 dCenter = dBox.Center();
|
---|
14 |
|
---|
15 | // "back plane"
|
---|
16 | mPlanes.push_back(Plane3(-VssRay::GetDirection(dCenter.x, dCenter.y), center));
|
---|
17 |
|
---|
18 | Vector3 directions[4];
|
---|
19 | directions[0] = VssRay::GetDirection(dBox.Min().x, dBox.Min().y);
|
---|
20 | directions[1] = VssRay::GetDirection(dBox.Max().x, dBox.Min().y);
|
---|
21 | directions[2] = VssRay::GetDirection(dBox.Max().x, dBox.Max().y);
|
---|
22 | directions[3] = VssRay::GetDirection(dBox.Min().x, dBox.Max().y);
|
---|
23 |
|
---|
24 | // side planes
|
---|
25 | mPlanes.push_back(Plane3(CrossProd(directions[0], directions[1]), center));
|
---|
26 | mPlanes.push_back(Plane3(CrossProd(directions[1], directions[2]), center));
|
---|
27 | mPlanes.push_back(Plane3(CrossProd(directions[2], directions[3]), center));
|
---|
28 | mPlanes.push_back(Plane3(CrossProd(directions[3], directions[0]), center));
|
---|
29 |
|
---|
30 |
|
---|
31 | // now make sure all planes contain the spatial box
|
---|
32 | int i, j;
|
---|
33 | for (i=0; i < mPlanes.size(); i++) {
|
---|
34 | for (j=0; j < 8; j++) {
|
---|
35 | float dist = mPlanes[i].Distance(box.GetVertex(j));
|
---|
36 | if (dist > 0)
|
---|
37 | mPlanes[i].mD -= dist;
|
---|
38 | }
|
---|
39 | }
|
---|
40 |
|
---|
41 | mBox = box;
|
---|
42 | mDirBox = dBox;
|
---|
43 |
|
---|
44 | SetValid();
|
---|
45 | }
|
---|
46 |
|
---|
47 | // conservative frustum box intersection
|
---|
48 | // returns
|
---|
49 | // 0 - box intersects the frustum
|
---|
50 | // -1 - box intersects the frustum and is fully inside
|
---|
51 | // 1 - box does not intersect the frustum
|
---|
52 |
|
---|
53 | int
|
---|
54 | Beam::ComputeIntersection(const AxisAlignedBox3 &box)
|
---|
55 | {
|
---|
56 | int i;
|
---|
57 | int result = -1;
|
---|
58 | for (i=0; i < mPlanes.size(); i++) {
|
---|
59 | int side = box.Side(mPlanes[i]);
|
---|
60 | if (side == 1)
|
---|
61 | return 1;
|
---|
62 | if (side > result)
|
---|
63 | result = side;
|
---|
64 | }
|
---|
65 | return result;
|
---|
66 | }
|
---|
67 |
|
---|
68 |
|
---|
69 | void Beam::ComputeFrustum(float &left, float &right,
|
---|
70 | float &bottom, float &top,
|
---|
71 | float &near, float &far,
|
---|
72 | const AxisAlignedBox3 &sceneBBox) const
|
---|
73 | {
|
---|
74 | const float xDirRange = mDirBox.Max().x - mDirBox.Min().x;
|
---|
75 | const float yDirRange = mDirBox.Max().y - mDirBox.Min().y;
|
---|
76 |
|
---|
77 | near = 0.1; // NOTE: what is the best value for near and far plane?
|
---|
78 | far = 2.0f * Magnitude(sceneBBox.Diagonal());
|
---|
79 |
|
---|
80 | left = near / tan(xDirRange * 0.5);
|
---|
81 | right = near / tan(xDirRange * 0.5);
|
---|
82 |
|
---|
83 | bottom = near / tan(yDirRange * 0.5);
|
---|
84 | top = near / tan(yDirRange * 0.5);
|
---|
85 | }
|
---|
86 |
|
---|
87 | Vector3 Beam::GetMainDirection() const
|
---|
88 | {
|
---|
89 | Vector3 directions[4];
|
---|
90 |
|
---|
91 | directions[0] = VssRay::GetDirection(dBox.Min().x, dBox.Min().y);
|
---|
92 | directions[1] = VssRay::GetDirection(dBox.Max().x, dBox.Min().y);
|
---|
93 | directions[2] = VssRay::GetDirection(dBox.Max().x, dBox.Max().y);
|
---|
94 | directions[3] = VssRay::GetDirection(dBox.Min().x, dBox.Max().y);
|
---|
95 |
|
---|
96 | return Normalize(direction[0], direction[1], direction[2], direction[3]);
|
---|
97 | } |
---|