Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
quadsquare_cull.cpp
Go to the documentation of this file.
1 #include "quadsquare.h"
2 
3 void quadsquare::ResetTree()
4 {
5 //Clear all enabled flags, and delete all non-static child nodes.
6  int i;
7  for (i = 0; i < 4; i++)
8  if (Child[i]) {
9  Child[i]->ResetTree();
10  if (Child[i]->Static == false) {
11  delete Child[i];
12  Child[i] = 0;
13  }
14  }
15  EnabledFlags = 0;
16  SubEnabledCount[0] = 0;
17  SubEnabledCount[1] = 0;
18  Dirty = true;
19 }
20 
21 void quadsquare::StaticCullData( const quadcornerdata &cd, float ThresholdDetail )
22 {
23 //Examine the tree and remove nodes which don't contain necessary
24 //detail. Necessary detail is defined as vertex data with a
25 //edge-length to height ratio less than ThresholdDetail.
26  //First, clean non-static nodes out of the tree.
27  ResetTree();
28  //Make sure error values are up-to-date.
30  //Recursively check all the nodes and do necessary removal.
31  //We must start at the bottom of the tree, and do one level of
32  //the tree at a time, to ensure the dependencies are accounted
33  //for properly.
34  int level;
35  for (level = 0; level < 15; level++)
36  StaticCullAux( cd, ThresholdDetail, level );
37 }
38 
39 void quadsquare::StaticCullAux( const quadcornerdata &cd, float ThresholdDetail, int TargetLevel )
40 {
41 //Check this node and its descendents, and remove nodes which don't contain
42 //necessary detail.
43  int i, j;
45  if (cd.Level > TargetLevel) {
46  //Just recurse to child nodes.
47  for (j = 0; j < 4; j++) {
48  if (j < 2) i = 1-j;
49  else i = j;
50  if (Child[i]) {
51  SetupCornerData( &q, cd, i );
52  Child[i]->StaticCullAux( q, ThresholdDetail, TargetLevel );
53  }
54  }
55  return;
56  }
57  //We're at the target level. Check this node to see if it's OK to delete it.
58 
59  //Check edge vertices to see if they're necessary.
60  float size = 2<<cd.Level; //Edge length.
61  if (Child[0] == NULL && Child[3] == NULL && Error[0]*ThresholdDetail < size) {
62  quadsquare *s = GetFarNeighbor( 0, cd );
63  if ( s == NULL || (s->Child[1] == NULL && s->Child[2] == NULL) ) {
64  //Force vertex height to the edge value.
65  unsigned short y = (unsigned short) ( (cd.Verts[0].Y+cd.Verts[3].Y)*0.5 );
66  Vertex[1].Y = y;
67  Error[0] = 0;
68  //Force alias vertex to match.
69  if (s) s->Vertex[3].Y = y;
70  Dirty = true;
71  }
72  }
73  if (Child[2] == NULL && Child[3] == NULL && Error[1]*ThresholdDetail < size) {
74  quadsquare *s = GetFarNeighbor( 3, cd );
75  if ( s == NULL || (s->Child[0] == NULL && s->Child[1] == NULL) ) {
76  unsigned short y = (unsigned short) ( (cd.Verts[2].Y+cd.Verts[3].Y)*0.5 );
77  Vertex[4].Y = y;
78  Error[1] = 0;
79  if (s) s->Vertex[2].Y = y;
80  Dirty = true;
81  }
82  }
83  //See if we have child nodes.
84  bool StaticChildren = false;
85  for (i = 0; i < 4; i++)
86  if (Child[i]) {
87  StaticChildren = true;
88  if (Child[i]->Dirty) Dirty = true;
89  }
90  //If we have no children and no necessary edges, then see if we can delete ourself.
91  if (StaticChildren == false && cd.Parent != NULL) {
92  bool NecessaryEdges = false;
93  for (i = 0; i < 4; i++) {
94  //See if vertex deviates from edge between corners.
95  float diff = fabs( Vertex[i+1].Y-(cd.Verts[i].Y+cd.Verts[(i+3)&3].Y)*0.5 );
96  if (diff > 0.00001)
97  NecessaryEdges = true;
98  }
99  if (!NecessaryEdges) {
100  size *= 1.414213562; //sqrt(2), because diagonal is longer than side.
101  if (cd.Parent->Square->Error[2+cd.ChildIndex]*ThresholdDetail < size) {
102  delete cd.Parent->Square->Child[cd.ChildIndex]; //Delete this.
103  cd.Parent->Square->Child[cd.ChildIndex] = 0; //Clear the pointer.
104  }
105  }
106  }
107 }
108