00001 /* 00002 File: RadPane.cc 00003 00004 Function: Display pane for radiosity mesh 00005 00006 Author: Andrew Willmott 00007 00008 Notes: 00009 */ 00010 00011 #include "RadPane.h" 00012 #include "RadMethod.h" 00013 #include "HierRad.h" 00014 #include "HRMesh.h" 00015 00016 #include "gcl/Scene.h" 00017 #include "gcl/Camera.h" 00018 00019 Void FormsScenePane::SetParent(Form *newParent) 00020 { 00021 parent = newParent; 00022 } 00023 00024 00025 // --- RadScenePane class ----------------------------------------------------- 00026 00027 00028 RadScenePane::RadScenePane(Bool doubleBuf) : FormsScenePane(doubleBuf) 00029 { 00030 selPatch[0] = 0; 00031 selPatch[1] = 0; 00032 selElem[0] = 0; 00033 selElem[1] = 0; 00034 enabled = false; 00035 } 00036 00037 static scGroup *lastScene = 0; 00038 00039 Void RadScenePane::SetScene(scScenePtr scene) 00040 { 00041 Int i; 00042 00043 enabled = false; 00044 selPatch[0] = 0; 00045 selPatch[1] = 0; 00046 ScenePane::SetScene(scene); 00047 mesh = gRadControl->radObject; 00048 00049 00050 enabled = true; 00051 Redraw(); 00052 } 00053 00054 Void RadScenePane::Redraw() 00055 { 00056 if (enabled) 00057 ScenePane::Redraw(); 00058 } 00059 00060 Void RadScenePane::StartDrag(Coord c, Int modifiers) 00061 { 00062 if (modifiers & wmButton3) 00063 inverseTransform = inv(itsCamera->ProjMatrix() * 00064 itsCamera->ModelMatrix()); 00065 ScenePane::StartDrag(c, modifiers); 00066 } 00067 00068 Void RadScenePane::EndDrag(Coord c, Int modifiers) 00069 { 00070 ScenePane::EndDrag(c, modifiers); 00071 00072 00073 if (parent) 00074 parent->Event(msgPick); 00075 } 00076 00077 Void RadScenePane::Drag(Coord c, Int modifiers) 00078 { 00079 offset = c - dragStart; 00080 00081 if (modifiersStart & wmButton3) 00082 { 00083 if (modifiersStart & wmControl) 00084 ComplexityDrag(); 00085 else 00086 SelectDrag(); 00087 } 00088 else 00089 ScenePane::Drag(c, modifiers); 00090 } 00091 00092 Void RadScenePane::SelectDrag() 00093 { 00094 if (!mesh) 00095 return; 00096 00097 RadElem *pickedElem; 00098 HRElem *pickedHRElem; 00099 Point p, from; 00100 Vector dir; 00101 Coord coord, start; 00102 Int i, which; 00103 Int levelsUp = (Int) (8.0 * sqrt(len(offset))); 00104 00105 // selecting light source or receiver 00106 which = 0; 00107 if (modifiersStart & wmShift) 00108 which++; 00109 00110 // de-highlight previous selection 00111 if (selPatch[which]) 00112 { 00113 if (which == 0) 00114 gRadControl->pvData = 0; 00115 selPatch[which]->SetHighlight(0); 00116 selPatch[which] = 0; 00117 } 00118 if (selElem[which]) 00119 { 00120 if (which == 0) 00121 gRadControl->pvData = 0; 00122 selElem[which]->SetHighlight(0); 00123 selElem[which] = 0; 00124 } 00125 00126 if (modifiersStart & wmAlt) 00127 return; 00128 00129 start[0] = 2.0 * dragStart[0] - 1.0; 00130 start[1] = 2.0 * dragStart[1] - 1.0; 00131 00132 FindWorldRay(start, inverseTransform, from, dir); 00133 00134 if (gRadControl->method != kHierarchical && 00135 (pickedElem = mesh->ClosestIntersection(from, dir, p))) 00136 { 00137 coord = pickedElem->FindCoord(p); 00138 00139 if (selPatch[which]) 00140 selPatch[which]->SetHighlight(0); 00141 else if (selElem[which]) 00142 selElem[which]->SetHighlight(0); 00143 00144 if (gRadControl->method == kProgSubstruct) 00145 { 00146 selPatch[which] = pickedElem->FindContainer(coord); 00147 00148 // if this is a light, select a patch rather than an element. 00149 if (which == 1) 00150 levelsUp = 1000; 00151 00152 for (i = 0; i < levelsUp && ((HierElem*) selPatch[which])->parent; 00153 i++) 00154 selPatch[which] = ((HierElem*) selPatch[which])->parent; 00155 00156 if (i < levelsUp) 00157 if (which == 0) 00158 // jump to the container element 00159 selPatch[which] = pickedElem; 00160 } 00161 else 00162 { 00163 if (levelsUp < 3) 00164 selPatch[which] = pickedElem->FindContainer(coord); 00165 else 00166 selPatch[which] = pickedElem; 00167 } 00168 00169 if (selPatch[which]) 00170 selPatch[which]->SetHighlight(2 + which); 00171 else 00172 { 00173 cerr << "Bad coord: " << coord << endl; 00174 _Error("(SelectDrag) Bad Coordinate"); 00175 } 00176 gRadControl->pvData = 0; 00177 } 00178 else if (gRadControl->method == kHierarchical && 00179 (pickedHRElem = ((HierRad*) mesh)->ClosestHRIntersection(from, dir, p))) 00180 00181 { 00182 HierElem *patchElem = 0; 00183 00184 if (selPatch[which]) 00185 selPatch[which]->SetHighlight(0); 00186 else if (selElem[which]) 00187 selElem[which]->SetHighlight(0); 00188 00189 i = 0; 00190 00191 if (pickedHRElem->IsPatch()) 00192 { 00193 patchElem = dynamic_cast<HRMeshElem*>(pickedHRElem); 00194 coord = patchElem->FindCoord(p); 00195 patchElem = dynamic_cast<HierElem*>(patchElem->FindContainer(coord)); 00196 00197 for (; i < levelsUp && patchElem->parent; i++) 00198 patchElem = patchElem->parent; 00199 00200 pickedHRElem = dynamic_cast<HRMeshElem*>(patchElem); 00201 } 00202 00203 // continue up HR hierarchy 00204 for (; i < levelsUp && pickedHRElem->eltParent; i++) 00205 pickedHRElem = pickedHRElem->eltParent; 00206 00207 if (pickedHRElem->IsPatch()) 00208 { 00209 selPatch[which] = patchElem; 00210 selElem[which] = pickedHRElem; 00211 } 00212 else 00213 { 00214 selPatch[which] = 0; 00215 selElem[which] = pickedHRElem; 00216 } 00217 pickedHRElem->SetHighlight(2 + which); 00218 gRadControl->pvData = pickedHRElem; 00219 } 00220 00221 Redraw(); 00222 }