/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #include "hwDeclarations.h" #include "hwWindow.h" #include "hwView.h" #include "hwGather.h" #include "hwMatrix.h" #include "hwMemory.h" #include "hwScreen.h" #include "hwDebug.h" #ifndef ABS #define ABS(x) (x<0.0?-x:x) #endif static Error _updateViewRecurse(dxObject object, viewO view, screenO parent); /* * updateView * * NOTE: This function should do View Dependent and Medium Independent * functions. (No medium is available) * * Add camera dependent lights to view struct * Add camera Transform (viewing transform) to all xfields * (Screen objects modify the camera transform) * * XXXX If no lights found, add default lights to view structure * */ Error _dxf_updateView(viewO view, void *globals, screenO camScreen) { DEFGLOBALDATA(globals); int i,j; dxObject object,clipObject; int flags; gatherO gather; ENTRY(("_dxf_updateView(0x%x, 0x%x, 0x%x)", view, globals, camScreen)); if (! _dxf_getHwViewInfo(view, &flags, &gather, NULL, NULL, NULL, NULL)) goto error; if (! _dxf_getHwGatherObject(gather, &object)) goto error; if (! _dxf_getHwGatherClipObject(gather, &clipObject)) goto error; if(!(flags & (CONTAINS_SCREEN))) { EXIT(("OK: !(view->flags & (CONTAINS_SCREEN))")); return OK; } if(object) if(!( _updateViewRecurse(object,view, camScreen))) goto error; if(clipObject) if(!( _updateViewRecurse(clipObject,view, camScreen))) goto error; EXIT(("OK")); return OK; error: EXIT(("ERROR")); return ERROR; } static Error _updateViewRecurse(dxObject object, viewO view, screenO parent) { dxObject subObject,opaqueObject; int i; Class class; ENTRY(("_updateViewRecurse(0x%x, 0x%x, 0x%x)", object, view, parent)); if (!(class = DXGetObjectClass(object))) goto error; /* * XXX check for empty dxObject */ switch (class) { case CLASS_GROUP: for (i=0; subObject=DXGetEnumeratedMember((Group)object, i, NULL); i++) { /* DXDebug("g", "member %d", i); */ if (!_updateViewRecurse(subObject, view, parent)) goto error; } break; case CLASS_PRIVATE: /* created from CLASS_FIELD in gather */ { switch(_dxf_getHwClass(object)) { case HW_CLASS_CLIPPED: { dxObject clipObject; if (! _dxf_getHwClippedInfo((clippedO)object, NULL, NULL, NULL, &clipObject)) goto error; if (!_updateViewRecurse(clipObject, view, parent)) goto error; } break; case HW_CLASS_XFIELD: break; case HW_CLASS_SCREEN: { screenO sp = (screenO) object; int positionUnits,z; int width,height; dxScreen s; float mm[4][4],vm[4][4],pm[4][4],vpm[4][4],tmp[4][4],ident[4][4]; if(!(_dxf_getHwScreenView(sp,&s,&subObject,NULL,mm, NULL,NULL))) goto error; if(!(_dxf_getHwScreenView(parent,NULL,NULL,vm,pm, &width,&height))) goto error; if(!(DXGetScreenInfo(s,NULL,&positionUnits,&z))) goto error; /* * take 'SCREEN_WORLD' origin from world to view space */ COPYMATRIX(tmp,identity); MULTMATRIX(vpm,vm,pm); switch (positionUnits) { case SCREEN_WORLD: { float matrix[4][4]; MULTMATRIX(matrix,mm,vpm); tmp[3][0] = matrix[3][0]; tmp[3][1] = matrix[3][1]; /* * Adjust for perspective */ if(vpm[3][2]) { tmp[3][0] /= matrix[3][3]; tmp[3][1] /= matrix[3][3]; } } break; case SCREEN_VIEWPORT: { /* * HW viewport is -1 to +1, viewport here is 0 +1, so * scale by 2. and translate by -1. */ tmp[3][0] = mm[3][0] * 2. - 1.0; tmp[3][1] = mm[3][1] * 2. - 1.0; } break; case SCREEN_PIXEL: { /* * HW viewport is -1 to +1, viewport here is 0 to 1 * width (or height), * so adjust the translation by 2./ width (or height) -1. */ tmp[3][0] = mm[3][0] * 2. / width - 1.0; tmp[3][1] = mm[3][1] * 2. / height - 1.0; } break; case SCREEN_STATIONARY: { tmp[3][0] = 0.0; tmp[3][1] = 0.0; } break; } /* * Scale the object from pixel to viewport size pixel is 0, width * HW viewport is -1, +1 */ tmp[0][0] = tmp[0][0] * 2. / (float)width; tmp[1][1] = tmp[1][1] * 2. / (float)height; /* * Set z scale and translation, we reserve the front 5% and back 5% * of the z depth for screen objects, dividing by 100k brings a * unit sized object to about the resolution of the z buffer. * The translation brings it to the front or back 5%. */ tmp[2][2] = 1./100000.; tmp[3][2] = z > 0 ? -.99 : (float)z * -.91; COPYMATRIX(ident,identity); _dxf_setHwScreenView(sp,s,subObject, tmp,NULL,width,height); if (!_updateViewRecurse(subObject, view, sp)) goto error; break; } } } break; case CLASS_SCREEN: case CLASS_FIELD: /* * should not be any screen or field objects at this point. * They were converted to CLASS_PRIVATE objects during the gather step. */ DXErrorGoto (ERROR_INTERNAL, "Invalid Object during update view"); break; case CLASS_XFORM: { /* * should not be any xform objects at this point. * They were removed during the gather step. */ goto error; } break; case CLASS_LIGHT: break; default: break; } EXIT(("OK")); return OK; error: EXIT(("ERROR")); return ERROR; }