1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10
11
12
13
14 #include <dx/dx.h>
15 #include <math.h>
16 #include <string.h>
17
18 #define WHERE_IN in[0]
19 #define DEFAULT_CAMERA in[1]
20 #define RESET_CAMERA in[2]
21 #define DEFAULT_OBJECT in[3]
22 #define RESET_OBJECT in[4]
23 #define WINDOW_SIZE in[5]
24 #define MOUSE in[6]
25 #define MODE in[7]
26 #define ARGS in[8]
27
28 #define OBJECT out[0]
29 #define CAMERA out[1]
30 #define WHERE_OUT out[2]
31 #define EVENTS out[3]
32
33 #define CACHE_CAMERA "CACHED_CAMERA_"
34 #define CACHE_OBJECT "CACHED_OBJECT_"
35
36 static Error Spin(Camera, Camera *, Object, Object *,
37 int, DXEvents, int *, int, Object, DXEvents *, int *);
38
39 extern Error DXRegisterForNotification(char *, Pointer); /* from libdx/notify.c */
40
41 extern int _dxd_nUserInteractors;
42 extern void *_dxd_UserInteractors;
43
44 int
m_SuperviseState(Object * in,Object * out)45 m_SuperviseState(Object *in, Object *out)
46 {
47 char *where, *cameraCacheTag = NULL, *objectCacheTag = NULL;
48 Pointer modid = NULL;
49 int resetCamera, resetObject;
50 int mode;
51 int windowSz[2];
52 char old[256], new[256];
53 char *left, *right;
54
55 CAMERA = NULL;
56 WHERE_OUT = NULL;
57 EVENTS = NULL;
58
59 if (!WHERE_IN || !DXExtractString(WHERE_IN, &where))
60 {
61 DXSetError(ERROR_MISSING_DATA, "where parameter");
62 return ERROR;
63 }
64
65 if (! strstr(where, "#X"))
66 {
67 DXSetError(ERROR_BAD_PARAMETER, "where must be a SuperviseWindow where output");
68 goto error;
69 }
70
71 left = strchr(where, '[');
72 if (left && ((right = strchr(where, ']')) != NULL) && right > left)
73 {
74 Object o;
75 char oTag[512], nTag[512];
76
77 strncpy(new, where, (left - where));
78 new[left-where] = '\0';
79 strncpy(old, left+1, (right - (left+1)));
80 old[right - (left+1)] = '\0';
81
82 DXMessage("old: %s new %s", old, new);
83
84 where = new;
85
86 sprintf(oTag, "%s%s", CACHE_CAMERA, old);
87 sprintf(nTag, "%s%s", CACHE_CAMERA, new);
88 if (NULL != (o = DXGetCacheEntry(oTag, 0, 0)))
89 {
90 DXSetCacheEntry(o, CACHE_PERMANENT, nTag, 0, 0);
91 DXSetCacheEntry(NULL, CACHE_PERMANENT, oTag, 0, 0);
92 }
93
94 sprintf(oTag, "%s%s", CACHE_OBJECT, old);
95 sprintf(nTag, "%s%s", CACHE_OBJECT, new);
96 if (NULL != (o = DXGetCacheEntry(oTag, 0, 0)))
97 {
98 DXSetCacheEntry(o, CACHE_PERMANENT, nTag, 0, 0);
99 DXSetCacheEntry(NULL, CACHE_PERMANENT, oTag, 0, 0);
100 }
101
102 WHERE_OUT = (Object)DXNewString(new);
103 }
104 else
105 WHERE_OUT = WHERE_IN;
106
107 if (RESET_CAMERA)
108 {
109 if (! DXExtractInteger(RESET_CAMERA, &resetCamera))
110 DXSetError(ERROR_BAD_PARAMETER, "resetCamera");
111 }
112 else
113 resetCamera = 0;
114
115 cameraCacheTag = (char *)DXAllocate(strlen(where)+strlen(CACHE_CAMERA)+2);
116 if (! cameraCacheTag)
117 goto error;
118
119 sprintf(cameraCacheTag, "%s%s", CACHE_CAMERA, where);
120
121 if (! resetCamera)
122 {
123 Object lastCam;
124 modid = DXGetModuleId();
125 DXRegisterForNotification(cameraCacheTag, modid);
126 DXFreeModuleId(modid);
127 lastCam = DXGetCacheEntry(cameraCacheTag, 0, 0);
128 CAMERA = DXCopy(lastCam, COPY_STRUCTURE);
129 DXReference(CAMERA);
130 DXDelete(lastCam);
131 }
132
133 if (! CAMERA)
134 {
135 if (! DEFAULT_CAMERA)
136 {
137 DXSetError(ERROR_MISSING_DATA,
138 "either cached camera or default camera must be available");
139 goto error;
140 }
141 CAMERA = DXCopy((Object)DEFAULT_CAMERA, COPY_STRUCTURE);
142 DXReference(CAMERA);
143 }
144
145 if (RESET_OBJECT)
146 {
147 if (! DXExtractInteger(RESET_OBJECT, &resetObject))
148 DXSetError(ERROR_BAD_PARAMETER, "resetObject");
149 }
150 else
151 resetObject = 0;
152
153 objectCacheTag = (char *)DXAllocate(strlen(where)+strlen(CACHE_OBJECT)+2);
154 if (! objectCacheTag)
155 goto error;
156
157 sprintf(objectCacheTag, "%s%s", CACHE_OBJECT, where);
158
159 if (! resetObject)
160 {
161 modid = DXGetModuleId();
162 DXRegisterForNotification(objectCacheTag, modid);
163 DXFreeModuleId(modid);
164 OBJECT = DXGetCacheEntry(objectCacheTag, 0, 0);
165 }
166
167 if (! OBJECT)
168 {
169 if (! DEFAULT_OBJECT)
170 {
171 DXSetError(ERROR_MISSING_DATA,
172 "either cached object or default object must be available");
173 goto error;
174 }
175 OBJECT = DXCopy((Object)DEFAULT_OBJECT, COPY_STRUCTURE);
176 DXReference(OBJECT);
177 }
178
179 mode = -1;
180 if (MODE && !DXExtractInteger(MODE, &mode))
181 {
182 DXSetError(ERROR_BAD_PARAMETER, "mode must be an int");
183 goto error;
184 }
185
186 if (WINDOW_SIZE)
187 {
188 float w;
189
190 if (! DXExtractParameter(WINDOW_SIZE, TYPE_INT, 2, 1, &windowSz))
191 {
192 DXSetError(ERROR_DATA_INVALID, "windowsize");
193 goto error;
194 }
195
196 DXSetResolution((Camera)CAMERA, windowSz[0], 1.0);
197
198 if (DXGetOrthographic((Camera)CAMERA, &w, NULL))
199 DXSetOrthographic((Camera)CAMERA, w,
200 (double)(windowSz[1]+0.99)/windowSz[0]);
201 else
202 {
203 DXGetPerspective((Camera)CAMERA, &w, NULL);
204 DXSetPerspective((Camera)CAMERA, w,
205 (double)(windowSz[1]+0.99)/windowSz[0]);
206 }
207 }
208 else
209 DXGetCameraResolution((Camera)CAMERA, &windowSz[0], &windowSz[1]);
210
211
212 if (mode >= _dxd_nUserInteractors)
213 {
214 DXSetError(ERROR_BAD_PARAMETER,
215 "only %d user interactors are available", _dxd_nUserInteractors);
216 goto error;
217 }
218
219 if ((mode >= 0) && MOUSE)
220 {
221 DXEvents dxEvents;
222 int nDXEvents;
223 Category c;
224 Type t;
225 int r, s;
226 DXEvents uEvents;
227 int nuEvents;
228
229 if (DXGetObjectClass(MOUSE) != CLASS_ARRAY)
230 {
231 DXSetError(ERROR_DATA_INVALID, "mouse must be an array");
232 return ERROR;
233 }
234
235 DXGetArrayInfo((Array)MOUSE, &nDXEvents, &t, &c, &r, &s);
236
237 if (t != TYPE_INT || r != 1 || s != sizeof(DXEvent)/DXTypeSize(TYPE_INT))
238 {
239 DXSetError(ERROR_DATA_INVALID,
240 "mouse must be an array of mouse events");
241 return ERROR;
242 }
243
244 dxEvents = DXGetArrayData((Array)MOUSE);
245
246 if (!Spin((Camera)CAMERA, (Camera *)&CAMERA, OBJECT, &OBJECT,
247 nDXEvents, dxEvents, windowSz, mode, ARGS,
248 &uEvents, &nuEvents) ||
249 ! CAMERA || ! OBJECT)
250 goto error;
251
252 if (nuEvents)
253 {
254 EVENTS = (Object)DXNewArray(TYPE_INT, CATEGORY_REAL, 1, sizeof(DXEvent)/DXTypeSize(TYPE_INT));
255 DXAddArrayData((Array)EVENTS, 0, nuEvents, (Pointer)uEvents);
256 DXFree((Pointer)uEvents);
257 }
258 }
259
260 DXSetCacheEntry(CAMERA, CACHE_PERMANENT, cameraCacheTag, 0, 0);
261 DXSetCacheEntry(OBJECT, CACHE_PERMANENT, objectCacheTag, 0, 0);
262
263 if (mode == -1)
264 {
265 DXSetAttribute(CAMERA, "interaction mode", NULL);
266 }
267 else
268 {
269 Group g = DXNewGroup();
270 Array a;
271 int *i;
272 a = DXNewArray(TYPE_INT, CATEGORY_REAL, 0);
273 DXAddArrayData(a, 0, 1, NULL);
274 i = (int *)DXGetArrayData(a);
275 *i = 9; /* INTERACTION_USER in hwClientMessage.c */
276 DXSetMember(g, "mode", (Object)a);
277 a = DXNewArray(TYPE_INT, CATEGORY_REAL, 0);
278 DXAddArrayData(a, 0, 1, NULL);
279 i = (int *)DXGetArrayData(a);
280 *i = mode;
281 DXSetMember(g, "submode", (Object)a);
282 DXSetMember(g, "args", ARGS);
283
284 DXSetAttribute(OBJECT, "interaction mode", (Object)g);
285 }
286
287 DXUnreference((Object)CAMERA);
288 DXUnreference((Object)OBJECT);
289
290 DXFree((Pointer)cameraCacheTag);
291 DXFree((Pointer)objectCacheTag);
292
293 return OK;
294
295 error:
296 DXFree((Pointer)cameraCacheTag);
297 DXFree((Pointer)objectCacheTag);
298
299 return ERROR;
300
301 }
302
303 static Error
Spin(Camera in_camera,Camera * out_camera,Object in_object,Object * out_object,int nEvents,DXEvents events,int * wsz,int mode,Object args,DXEvents * uevents,int * nuevents)304 Spin(Camera in_camera, Camera *out_camera,
305 Object in_object, Object *out_object,
306 int nEvents, DXEvents events, int *wsz,
307 int mode, Object args,
308 DXEvents *uevents, int *nuevents)
309 {
310 float aspect;
311 float F[3], T[3], U[3];
312 Point fp, tp;
313 Vector uv;
314 float width;
315 int pixwidth;
316 float fov;
317 int projection;
318
319 *uevents = NULL;
320 *nuevents = 0;
321
322 DXGetView(in_camera, (Point *)F, (Point *)T, (Vector *)U);
323
324 if (DXGetOrthographic(in_camera, &width, &aspect))
325 {
326 projection = 0;
327 }
328 else
329 {
330 DXGetPerspective(in_camera, &fov, &aspect);
331 projection = 1;
332 }
333 DXGetCameraResolution(in_camera, &pixwidth, NULL);
334
335 if (nEvents)
336 {
337 int i;
338 void *udata = NULL;
339 int mask;
340 UserInteractor *imode = ((UserInteractor *)_dxd_UserInteractors) + mode;
341
342 udata = imode->InitMode(args, wsz[0], wsz[1], &mask);
343
344 if (imode->SetCamera)
345 imode->SetCamera(udata, T, F, U, projection, fov, width);
346
347 if (imode->SetRenderable)
348 imode->SetRenderable(udata, in_object);
349
350 *nuevents = 0;
351
352 for (i = 0; i < nEvents; i++)
353 {
354 if (! (events[i].any.event & mask))
355 {
356 (*nuevents)++;
357 continue;
358 }
359
360 imode->EventHandler(udata, (DXEvent *)(events+i));
361 }
362
363 if (imode->GetCamera)
364 imode->GetCamera(udata, T, F, U, &projection, &fov, &width);
365
366 if (imode->GetRenderable)
367 {
368 Object tmp;
369
370 imode->GetRenderable(udata, &tmp);
371 if (tmp)
372 {
373 DXDelete(in_object);
374 in_object = DXReference(tmp);
375 tmp = NULL;
376 }
377 }
378
379 imode->EndMode(udata);
380
381 if (*nuevents)
382 {
383 int i, j;
384
385 *uevents = DXAllocate(*nuevents * sizeof(DXEvent));
386 if (! *uevents)
387 return ERROR;
388
389 for (i = j = 0; i < nEvents; i++)
390 if (! (events[i].any.event & mask))
391 (*uevents)[j++] = events[i];
392 }
393 }
394
395 if (out_object)
396 *out_object = in_object;
397
398 if (out_camera)
399 {
400 *out_camera = (Camera)DXCopy((Object)in_camera, COPY_STRUCTURE);
401 if (! *out_camera)
402 return ERROR;
403
404 DXReference((Object)*out_camera);
405
406 aspect = (double)(wsz[1]+0.99)/wsz[0];
407
408 fp.x = F[0]; fp.y = F[1]; fp.z = F[2];
409 tp.x = T[0]; tp.y = T[1]; tp.z = T[2];
410 uv.x = U[0]; uv.y = U[1]; uv.z = U[2];
411
412 DXSetView(*out_camera, fp, tp, uv);
413 if (projection)
414 DXSetPerspective(*out_camera, fov, aspect);
415 else
416 DXSetOrthographic(*out_camera, width, aspect);
417
418 }
419
420 return OK;
421 }
422