ide/Debugger: Rubber Ducking Support
[sdk] / ide / src / documents / ModelView.ec
1 #ifdef ECERE_STATIC
2 import static "ecere"
3 #else
4 import "ecere"
5 #endif
6
7 class ModelView : Window
8 {
9    isActiveClient = true;
10    background = lightBlue;
11    anchor = { left = 0, top = 0, right = 0, bottom = 0 };
12
13    FillModeValue fillMode;
14    bool moving, lightMoving;
15    char fileName[MAX_LOCATION];
16    Camera camera
17    {
18       attached,
19       fovDirection = vertical,
20       fov = 53,
21       position = { 0, 0, -10 },
22       eulerOrientation = Euler { 30, 0, 0 },
23       zMin = 1;
24       zMax = 10000;
25    };
26    Object cameraTarget { };
27    Object model {};
28    Point startPosition;
29    Euler startOrientation;
30    Light light
31    {
32       orientation = Euler { pitch = 50, yaw = 45 };
33       diffuse = white, specular = white;
34    }; // light.diffuse.r = light.diffuse.g = light.diffuse.b = 1; light.specular.r = light.specular.g = light.specular.b = 1;
35    Window help;
36
37    Timer timer
38    {
39       userData = this, delay = 0.05;
40       bool DelayExpired()
41       {
42          if(model)
43             model.frame++; //Animate(model.frame + 1);
44
45          Update(null);
46          return true;
47       }
48    };
49
50    property char * modelFile
51    {
52       set
53       {
54          strcpy(fileName, value);
55       }
56       get { return fileName; }
57    }
58
59    void OnUnloadGraphics()
60    {
61       model.Free(displaySystem);
62       delete model;  // At the moment the reload preserving hierarchy position is not working, causing things to be misplaced in some models
63       model = { };
64    }
65
66    void OnDestroy()
67    {
68       DisplaySystem displaySystem = parent.displaySystem;
69       /*delete model;
70       model = { };*/
71       if(_class.count == 1 && parent.displaySystem)
72       {
73          displaySystem.ClearMaterials();
74          displaySystem.ClearTextures();
75          displaySystem.ClearMeshes();
76       }
77    }
78
79    void OnResize(int w, int h)
80    {
81       camera.Setup(w, h, null);
82       Update(null);
83    }
84
85    bool OnLeftButtonDown(int x, int y, Modifiers mods)
86    {
87       if(!moving && !lightMoving)
88       {
89          bool clicked = false;
90          OldList list {};
91
92          display.StartSelection(x,y, 0,0);
93          display.SetCamera(null, camera);
94          display.CollectHits();
95          display.DrawObject(model);
96          if(display.GetHits(list))
97          {
98             clicked = true;
99             list.Free(null);
100          }
101          display.SetCamera(null, null);
102          display.StopSelection();
103
104          if(clicked)
105          {
106             startPosition.x = x;
107             startPosition.y = y;
108             startOrientation = camera.eulerOrientation;
109             Capture();
110             moving = true;
111             return false;
112          }
113       }
114       return true;
115    }
116
117    bool OnLeftButtonUp(int x, int y, Modifiers mods)
118    {
119       if(moving)
120       {
121          ReleaseCapture();
122          moving = false;
123       }
124       return true;
125    }
126
127    bool OnRightButtonDown(int x, int y, Modifiers mods)
128    {
129       if(!moving && !lightMoving)
130       {
131          startPosition.x = x;
132          startPosition.y = y;
133          startOrientation = light.orientation;
134          Capture();
135          lightMoving = true;
136       }
137       return true;
138    }
139
140    bool OnRightButtonUp(int x, int y, Modifiers mods)
141    {
142       if(lightMoving)
143       {
144          ReleaseCapture();
145          lightMoving = false;
146       }
147       return true;
148    }
149
150    bool OnMouseMove(int x, int y, Modifiers mods)
151    {
152       if(moving)
153       {
154          Euler euler
155          {
156             startOrientation.yaw   - (x - startPosition.x),
157             startOrientation.pitch + (y - startPosition.y),
158             0
159          };
160
161          camera.eulerOrientation = euler;
162
163          Update(null);
164       }
165       else if(lightMoving)
166       {
167          light.orientation = Euler
168          {
169             startOrientation.yaw   - (x - startPosition.x),
170             startOrientation.pitch + (y - startPosition.y),
171             0
172          };
173
174          Update(null);
175       }
176       return true;
177    }
178
179    bool OnKeyDown(Key key, unichar ch)
180    {
181       switch(key)
182       {
183          case g:
184             fillMode = (fillMode == wireframe) ? solid : wireframe;
185             break;
186       }
187       return true;
188    }
189
190    bool OnKeyHit(Key key, unichar ch)
191    {
192       switch((SmartKey) key)
193       {
194          case wheelDown: case minus: camera.position.z *= 1.1111111f; Update(null); break;
195          case wheelUp: case plus: camera.position.z *= 0.9f; Update(null); break;
196          case up:    camera.position.y += camera.position.z / 20; Update(null); break;
197          case down:  camera.position.y -= camera.position.z / 20; Update(null); break;
198          case left:    camera.position.x += camera.position.z / 20; Update(null); break;
199          case right:  camera.position.x -= camera.position.z / 20; Update(null); break;
200          /*
201             case pageDown: model.Animate(model.frame + 1); break;
202             case pageUp: model.Animate(model.frame - 1); break;
203             case home: model.Animate(model.startFrame); break;
204             case end: model.Animate(model.endFrame); break;
205          */
206       }
207       return true;
208    }
209
210    bool OnLoadGraphics()
211    {
212       if(model.Load(fileName, null, displaySystem))
213       {
214          float r = model.radius;
215          cameraTarget.transform.position =
216          {
217             (model.max.x + model.min.x) / 2,
218             (model.max.y + model.min.y) / 2,
219             (model.max.z + model.min.z) / 2
220          };
221
222          camera.zMin = 1;
223          camera.zMax = 10000;
224          camera.position = { 0, 0, -r * 2 };
225          camera.eulerOrientation = Euler { 30, 0, 0 };
226          light.orientation = Euler { pitch = 50, yaw = 45 };
227
228          if(r * 2 < camera.zMax / 10)
229          {
230             while(r * 2 < camera.zMax / 100)
231             {
232                camera.zMax /= 10;
233                camera.zMin /= 10;
234             }
235          }
236          else
237             while(r * 2 > camera.zMax / 10)
238             {
239                camera.zMax *= 10;
240                camera.zMin *= 10;
241             }
242
243          camera.target = cameraTarget;
244          return true;
245       }
246       return false;
247    }
248
249    void OnRedraw(Surface surface)
250    {
251       //display.fogColor = blue;
252       display.fogDensity = 0; //0.000001f;
253
254       surface.Clear(depthBuffer);
255       camera.Update();
256
257       display.SetLight(0, light);
258       display.SetCamera(surface, camera);
259
260       //display.SetLight(0, light);
261
262       display.fillMode = fillMode;
263       display.DrawObject(model);
264       display.fillMode = solid;
265
266       display.SetCamera(surface, null);
267
268       surface.SetForeground(black);
269    }
270
271    ModelView()
272    {
273       fillMode = solid;
274       light.orientation.Yaw(0);
275       // timer.Start();
276    }
277
278    void SetFormat(char * format)
279    {
280       OnLoadGraphics();
281    }
282
283 }