/***********************************************************************/ /* 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 "hwList.h" #include "hwClipped.h" #include "hwMatrix.h" #include "hwMemory.h" #include "hwPortLayer.h" #include "hwGather.h" #include "hwXfield.h" #include "hwWindow.h" #include "hwObjectHash.h" #include "hwSort.h" #include "hwDebug.h" static Error _gatherRecurse(dxObject object, dxObject *newObject, gatherO gather, attributeP attributes, void *globals); typedef struct clipPlanesS *clipPlaneP; struct clipPlanesS { int n; Point *p; Vector *v; clipPlaneP next; } clipPlanesT; typedef struct gatherS { long int flags; listO lights; RGBColor ambientColor; materialO lastUsedMaterial; dxObject object; /* modified copy of original object */ dxObject clipObject; /* modified copy of object doing tranp clip */ clipPlaneP clipStack; } gatherT, *gatherP; static gatherP _getHwGatherData(gatherO go) { return (gatherP)_dxf_getHwObjectData((dxObject)go); } Error _dxf_pushHwGatherClipPlanes(gatherO go, int n, Point *p, Vector *v) { int i; gatherP gop; clipPlaneP clips = NULL; if (! go) return ERROR; gop = _getHwGatherData(go); clips = (clipPlaneP)DXAllocateZero(sizeof(clipPlanesT)); if (! clips) goto error; clips->n = n; if (n > 0) { clips->p = (Point *)DXAllocateZero(n*sizeof(Point)); if (! clips->p) goto error; clips->v = (Point *)DXAllocateZero(n*sizeof(Vector)); if (! clips->v) goto error; for (i = 0; i < n; i++) { clips->p[i] = p[i]; clips->v[i] = v[i]; } } clips->next = gop->clipStack; gop->clipStack = clips; return OK; error: if (clips) { DXFree((Pointer)clips->p); DXFree((Pointer)clips->v); DXFree((Pointer)clips); } return ERROR; } Error _dxf_getHwGatherClipPlanes(gatherO go, int *nClips, Point **p, Vector **v) { gatherP gop; clipPlaneP clips; *p = NULL; *v = NULL; if (! go) return ERROR; gop = _getHwGatherData(go); *nClips = 0; for (clips = gop->clipStack; clips; clips = clips->next) *nClips += clips->n; if (*nClips) { int i, j; *p = (Point *)DXAllocate((*nClips)*sizeof(Point)); *v = (Point *)DXAllocate((*nClips)*sizeof(Point)); if (! *p || ! *v) goto error; for (j = 0, clips = gop->clipStack; clips; clips = clips->next) for (i = 0; i < clips->n; i++, j++) { (*p)[j] = clips->p[i]; (*v)[j] = clips->v[i]; } } return OK; error: DXFree((Pointer)*p); DXFree((Pointer)*v); return ERROR; } static Error __popHwGatherClipPlanes(gatherP gop) { clipPlaneP top; if (! gop) return OK; if (NULL == (top = gop->clipStack)) return ERROR; gop->clipStack = top->next; DXFree((Pointer)top->p); DXFree((Pointer)top->v); DXFree((Pointer)top); return OK; } Error _dxf_popHwGatherClipPlanes(gatherO go) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); return __popHwGatherClipPlanes(gop); return OK; } Error _dxf_getHwGatherFlags(gatherO go, int *flags) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); if (!gop) return ERROR; if (flags) *flags = gop->flags; return OK; } Error _dxf_setHwGatherFlags(gatherO go, int flags) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); if (!gop) return ERROR; gop->flags = flags; return OK; } Error _dxf_getHwGatherLights(gatherO go, listO *list) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); if (!gop) return ERROR; if (list) *list = gop->lights; return OK; } Error _dxf_setHwGatherLights(gatherO go, listO list) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); if (!gop) return ERROR; if (gop->lights) { DXDelete((dxObject)gop->lights); gop->lights = NULL; } if (list) gop->lights = (listO)DXReference((dxObject)list); return OK; } Error _dxf_getHwGatherAmbientColor(gatherO go, RGBColor *color) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); if (!gop) return ERROR; if (color) *color = gop->ambientColor; return OK; } Error _dxf_setHwGatherAmbientColor(gatherO go, RGBColor color) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); if (!gop) return ERROR; gop->ambientColor = color; return OK; } Error _dxf_getHwGatherMaterial(gatherO go, materialO *mat) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); if (!gop) return ERROR; if (mat) *mat = gop->lastUsedMaterial; return OK; } Error _dxf_setHwGatherMaterial(gatherO go, materialO mat) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); if (!gop) return ERROR; if (gop->lastUsedMaterial) { DXDelete((dxObject)gop->lastUsedMaterial); gop->lastUsedMaterial = NULL; } DXReference((dxObject)mat); gop->lastUsedMaterial = mat; return OK; } Error _dxf_getHwGatherObject(gatherO go, dxObject *object) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); if (!gop) return ERROR; if (object) *object = gop->object; return OK; } Error _dxf_setHwGatherObject(gatherO go, dxObject object) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); if (!gop) return ERROR; if (gop->object) { DXDelete((dxObject)gop->object); gop->object = NULL; } if (object) gop->object = (dxObject)DXReference(object); return OK; } Error _dxf_getHwGatherClipObject(gatherO go, dxObject *clipObject) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); if (!gop) return ERROR; if (clipObject) *clipObject = gop->clipObject; return OK; } Error _dxf_setHwGatherClipObject(gatherO go, dxObject clipObject) { gatherP gop; if (! go) return ERROR; gop = _getHwGatherData(go); if (!gop) return ERROR; if (gop->clipObject) { DXDelete((dxObject)gop->clipObject); gop->clipObject = NULL; } if (clipObject) gop->clipObject = (dxObject)DXReference(clipObject); return OK; } static Error _deleteGather(Pointer arg) { gatherP gp = (gatherP)arg; ENTRY(("_dxf_deleteGather(0x%x)", arg)); if (gp) { if (gp->lights) { DXDelete((dxObject)gp->lights); gp->lights = NULL; } if (gp->lastUsedMaterial) { DXDelete((dxObject)gp->lastUsedMaterial); gp->lastUsedMaterial = NULL; } if(gp->object) { DXDelete(gp->object); gp->object = NULL; } if(gp->clipObject) { DXDelete(gp->clipObject); gp->clipObject = NULL; } while(__popHwGatherClipPlanes(gp)); } DXFree(gp); gp = NULL; tdmCheckAllocTable(3); EXIT(("OK")); return OK; } gatherO _dxf_newHwGather(void) { gatherP ret; gatherO go; ENTRY(("_dxf_newGather()")); ret = (gatherP)DXAllocateZero(sizeof(gatherT)); if(!ret) goto error; ret->lights = _dxf_newList(8, (int(*)(void*))DXDelete); if(!ret->lights) goto error; go = (gatherO)_dxf_newHwObject(HW_CLASS_GATHER, (Pointer)ret, _deleteGather); if (!go) goto error; EXIT(("ret = 0x%x", ret)); return go; error: if(ret) { DXFree(ret); ret = NULL; } EXIT(("ERROR")); DXErrorReturn(ERROR_NO_MEMORY,""); } /* * Gather * * NOTE: This function should only do View Independent and Medium Indepenant * functions. (No camera or medium is available) * * Gathers together camera independent lights * Gathers a single clip object for transparent fields. * Creates a new object heirarchy with: * fields replaced with xfields (which contain accumulated model xforms) * SCREEN_WORLD screen objects replaced with SCREEN_VIEWPORT screen objects * modeling transforms carried down through clip and render objects * XForms objects removed * count the total number of connections in all transparent fields. * * Sets global flags indicating: * if transparent fields exist in the object * if Volume fields exist in the object * if a single regular volume is the only transparent object ????? * if Clip objects exist in the object * */ Error _dxf_gather(dxObject object, gatherO gather, void *globals) { DEFGLOBALDATA(globals); DEFPORT(PORT_HANDLE); attributeP attributes = NULL; dxObject newObject, savenew; int flags; ENTRY(("_dxf_gather(0x%x, 0x%x, 0x%x)", object, gather, globals)); attributes = _dxf_newAttribute(NULL); if (!object) { EXIT(("object == NULL")); return OK; } /* * Initialize (or create) the mesh and texture hash tables. * During the gather traversal, whenever we hit a triangle- or * quad-strippable field, look in the mesh hash table to see if * there already is one. Same for textures. In the initialization * process, the hit flag for every object (of either kind) is * set to 0. When an object is accessed on this traversal, its * hit flag is set to 1. At the end of the traversal, the hash * tables are traversed, and any object with a hit flag of 0 * (indicating that it wasn't needed in this rendering) is discarded. */ if (! MESHHASH) MESHHASH = _dxf_InitObjectHash(); else _dxf_ResetObjectHash(MESHHASH); if (! TEXTUREHASH) TEXTUREHASH = _dxf_InitObjectHash(); else _dxf_ResetObjectHash(TEXTUREHASH); _dxf_clearSortList(SORTLIST); if(!(savenew = newObject = DXCopy(object,COPY_ATTRIBUTES))) goto error; if(!(_gatherRecurse(object, &newObject, gather, attributes, globals))) goto error; if(savenew != newObject) DXDelete(savenew); if (! _dxf_getHwGatherFlags(gather, &flags)) goto error; if(!(flags & CONTAINS_LIGHT)) { listO lo; Vector direction = {-1.0, 0.0, 1.0}; RGBColor color = {1.0, 1.0, 1.0}; Light newLight; if(!(newLight = DXNewCameraDistantLight(direction,color))) goto error; DXReference((dxObject)newLight); if (! _dxf_getHwGatherLights(gather, &lo)) goto error; if (! _dxf_listAppendItem(lo, (Pointer)newLight)) goto error; color.r = color.g = color.b = 0.2; if (! _dxf_setHwGatherAmbientColor(gather, color)) goto error; } if (! _dxf_setHwGatherObject(gather, newObject)) goto error; if (attributes) _dxf_deleteAttribute(attributes); /* * Now delete all the un-hit objects from the mesh and * texture hashes */ MESHHASH = _dxf_CullObjectHash(MESHHASH); TEXTUREHASH = _dxf_CullObjectHash(TEXTUREHASH); EXIT(("OK")); return OK; error: if(attributes) _dxf_deleteAttribute(attributes); EXIT(("ERROR")); return ERROR; } #define OPACITY(offset) \ *(float *)((xf->omap) ? \ DXGetArrayEntry(xf->omap, \ *(char *) DXGetArrayEntry(xf->opacities, offset, &iscratch), \ fscratch) : \ DXGetArrayEntry(xf->opacities, \ offset, \ fscratch)) static Error _gatherField(Field f, dxObject *newObject, gatherO gather, attributeP attributes, void *globals) { DEFGLOBALDATA(globals); DEFPORT(PORT_HANDLE); xfieldP xf; hwFlags attFlags; hwFlags servicesFlags; ENTRY(("_gatherField(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)", f, newObject, gather, attributes, globals)); if (DXEmptyField(f)) { *newObject = NULL; EXIT(("OK: f is empty")); return OK; } servicesFlags = _dxf_SERVICES_FLAGS(); if(_dxf_isFlagsSet(servicesFlags,SF_VOLUME_BOUNDARY)) { dxObject connections; char *elementType = NULL; int one = 1; if(connections = DXGetComponentValue(f,"connections")) { if(!DXGetStringAttribute(connections,"element type",&elementType)) DXErrorGoto(ERROR_BAD_PARAMETER, "#13070"); if(!strcmp(elementType,"tetrahedra") || !strcmp(elementType,"cubes")) { Array validity; dxObject newField; ModuleInput inputs[2]; ModuleOutput outputs[1]; if (!(validity = (Array)DXNewArray(TYPE_INT, CATEGORY_REAL, 0))) goto error; if (!DXAddArrayData((Array)validity, 0, 1, (Pointer)&one)) goto error; DXReference((dxObject)validity); DXSetModuleInput(inputs[0],"input",(dxObject)f); DXSetModuleInput(inputs[1],"validity",(dxObject)validity); DXSetModuleOutput(outputs[0],"output",&newField); if(!DXCallModule("ShowBoundary",2,inputs,1,outputs)) { if (DXGetError() == ERROR_NONE) DXSetError(ERROR_INTERNAL, "ShowBoundary or DXCallModule failed, no error code set"); DXDelete((dxObject)validity); goto error; } DXDelete((dxObject)validity); DXReference((dxObject)newField); if (!_gatherRecurse(newField,newObject, gather, attributes, globals)) { DXDelete(newField); goto error; } DXDelete(newField); EXIT(("OK")); return OK; } } } /* allocate xfield */ *newObject = (dxObject)_dxf_newXfieldO(f,attributes,globals); if (! *newObject) goto error; xf = _dxf_getXfieldData((xfieldO)*newObject); if (! xf) goto error; attFlags = _dxf_attributeFlags(_dxf_xfieldAttributes(xf)); if (!(_dxf_isFlagsSet(attFlags,(CONTAINS_TRANSPARENT | CONTAINS_VOLUME)))) { EXIT(("OK: neither transparent nor volume field")); return OK; } /* * OK we're into the transparent fields (and volumes) now */ if(_dxf_isFlagsSet(attFlags,IN_SCREEN_OBJECT)) { EXIT(("ERROR")); DXErrorReturn(ERROR_BAD_PARAMETER, "Transparent fields not allowed in screen object"); } /* _dxf_setFlags(attFlags,CONTAINS_TRANSPARENT); */ switch (xf->opacitiesDep) { case dep_field: { int i; float fscratch[1]; int iscratch; if (OPACITY(0)) for (i = 0; i < xf->nconnections; i++) if (!xf->invCntns || !DXIsElementInvalid(xf->invCntns,i)) _dxf_Insert_Translucent(SORTLIST, (void *)xf, i); break; } case dep_connections: { int i; float fscratch[1]; int iscratch; for (i = 0; i < xf->nconnections; i++) if (!xf->invCntns || !DXIsElementInvalid(xf->invCntns,i)) if (OPACITY(i)) _dxf_Insert_Translucent(SORTLIST, (void *)xf, i); break; } case dep_positions: { int i, j; float fscratch[1]; int iscratch; int *c, cscr[8]; for (i = 0; i < xf->nconnections; i++) { if (!xf->invCntns || !DXIsElementInvalid(xf->invCntns,i)) { c = (int*)DXGetArrayEntry(xf->connections,i,cscr); for (j = 0; j < xf->posPerConn; j++) if (OPACITY(c[j])) { _dxf_Insert_Translucent(SORTLIST, (void *)xf, i); break; } } } break; } case dep_none: default: break; } EXIT(("OK")); return OK; error: EXIT(("ERROR")); return ERROR; } static Error _gatherRecurse(dxObject object, dxObject *newObject, gatherO gather, attributeP attributes, void *globals) { DEFGLOBALDATA(globals); DEFPORT(PORT_HANDLE); dxObject subObject,tmpObject,tmpObject1, attr; int i; attributeP new = NULL; Class class,groupClass; hwFlags newFlags; ENTRY(("_gatherRecurse(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)", object, newObject, gather, attributes, globals)); attr = DXGetAttribute(object, "visible"); if (attr) { int flag; DXExtractInteger(attr, &flag); if (flag == 0) { *newObject = NULL; return OK; } } if (!(new = _dxf_parameters((dxObject)object, attributes))) goto error; if (!(class = DXGetObjectClass(object))) goto error; newFlags = _dxf_attributeFlags(new); /* * XXX check for empty dxObject */ switch (class) { case CLASS_GROUP: { *newObject = DXCopy(object,COPY_ATTRIBUTES); if(!(groupClass = DXGetGroupClass((Group)object))) goto error; switch(groupClass) { case CLASS_COMPOSITEFIELD: { _dxf_setFlags(newFlags,IGNORE_PARAMS); i = 0; while (NULL != (subObject = DXGetEnumeratedMember((Group)object, i, NULL))) { dxObject tmpObject; if (!_gatherRecurse(subObject, &tmpObject, gather, new, globals)) goto error; if (tmpObject) { if (!DXSetMember((Group)*newObject,NULL,tmpObject)) goto error; } i++; } break; } case CLASS_SERIES: { float p; int j; _dxf_clearFlags(newFlags, IGNORE_PARAMS); i = j = 0; while (NULL != (subObject = DXGetSeriesMember((Series)object, i, &p))) { dxObject tmpObject; if (!_gatherRecurse(subObject, &tmpObject, gather, new, globals)) goto error; if (tmpObject) { if (!DXSetSeriesMember((Series)*newObject, j++, p, tmpObject)) goto error; } i++; } break; } default: { char *name; _dxf_clearFlags(newFlags, IGNORE_PARAMS); i = 0; while (NULL != (subObject = DXGetEnumeratedMember((Group)object, i, &name))) { dxObject tmpObject; if (!_gatherRecurse(subObject, &tmpObject, gather, new, globals)) goto error; if (tmpObject) { if (!DXSetMember((Group)*newObject, name, tmpObject)) goto error; } i++; } break; } } break; } case CLASS_FIELD: if(!_gatherField((Field)object,newObject,gather,new,globals)) goto error; break; case CLASS_SCREEN: { int positionUnits, z; float matrix[4][4]; float ident[4][4]; int flags; COPYMATRIX(ident,identity); if(!(DXGetScreenInfo((dxScreen)object,&subObject,&positionUnits,&z))) goto error; /* * Set the modeling matrix to identity for recursion */ _dxf_attributeMatrix(attributes,matrix); _dxf_setAttributeMatrix(new, ident); _dxf_setFlags(newFlags,IN_SCREEN_OBJECT); if (positionUnits != SCREEN_STATIONARY) { if (z) new->ff = 1.0 / 1000000; new->fuzz *= new->ff; } if (!_gatherRecurse(subObject, &tmpObject, gather, new, globals)) goto error; if(tmpObject) { *newObject = (dxObject)_dxf_newHwScreen((dxScreen)object, (dxObject) tmpObject, NULL,matrix, 0,0); if (! *newObject) goto error; if (! _dxf_getHwGatherFlags(gather, &flags)) goto error; flags |= CONTAINS_SCREEN; if (! _dxf_setHwGatherFlags(gather, flags)) goto error; } else { *newObject = NULL; } } break; case CLASS_CLIPPED: { dxObject clipObject; float m[4][4],atm[4][4]; double dm[4][4],datm[4][4]; static Vector X={1.0,0.0,0.0},Y={0.0,1.0,0.0},Z={0.0,0.0,1.0}; Array attr; Pointer attP; Point pt,min,max,newMin,newMax; Vector normal; float fpt[3],fnormal[3]; clippedO cpo; /* * validity checks */ if(_dxf_isFlagsSet(newFlags,IN_SCREEN_OBJECT)) { EXIT(("ERROR")); DXErrorReturn(ERROR_BAD_PARAMETER, "Clipped objects not allowed in screen object"); } if(_dxf_isFlagsSet(newFlags,BEING_CLIPPED)) { EXIT(("ERROR")); DXErrorReturn(ERROR_BAD_PARAMETER, "Clipped objects cannot be clipped."); } if(_dxf_isFlagsSet(newFlags,IN_CLIP_OBJECT)) { EXIT(("ERROR")); DXErrorReturn(ERROR_BAD_PARAMETER, "Nested clipped objects not allowed."); } DXGetClippedInfo((Clipped)object, &subObject, &clipObject); _dxf_setFlags(newFlags,BEING_CLIPPED); if (!_gatherRecurse(subObject, &tmpObject, gather, new, globals)) goto error; _dxf_clearFlags(newFlags,BEING_CLIPPED); if(tmpObject) { /* Get the current modeling transform and adjointTranspose */ _dxf_attributeMatrix(new,m); COPYMATRIX(dm,m); _dxfAdjointTranspose(datm,dm); if((attr = (Array)DXGetAttribute(clipObject,"clipplane normal"))) { Point *cp_pt; Vector *cp_nrm; attP = (Vector *)DXGetConstantArrayData(attr); if(!attP) DXErrorGoto(ERROR_BAD_PARAMETER, "clip plane has invalid normal"); normal = *(Vector*)attP; attr = (Array)DXGetAttribute(clipObject,"clipplane point"); if (!attr) DXErrorGoto(ERROR_BAD_PARAMETER, "clip plane contains no point"); attP = (Point *)DXGetConstantArrayData(attr); if(!attP) DXErrorGoto(ERROR_BAD_PARAMETER, "clip plane has invalid point"); pt = *(Vector*)attP; cpo = _dxf_newHwClipped(1, tmpObject); if (! cpo) goto error; APPLY3((float *)&pt,dm); APPLY3((float *)&normal,datm); if (! _dxf_getHwClippedInfo(cpo, &cp_pt, &cp_nrm, NULL, NULL)) goto error; /* Negate the sense of the normal (undoes same in DXClipPlane) and normalize */ *cp_pt = pt; *cp_nrm = DXNormalize(DXNeg(normal)); *newObject = (dxObject)cpo; } else if (attr = (Array)DXGetAttribute(clipObject,"clipbox min")) { Point *cp_pts; Vector *cp_nrms; attP = (Point *)DXGetConstantArrayData(attr); if(!attP) DXErrorGoto(ERROR_BAD_PARAMETER, "clip box has invalid min"); min = *(Point *)attP; attr = (Array)DXGetAttribute(clipObject,"clipbox max"); if(!attr) DXErrorGoto(ERROR_BAD_PARAMETER, "clip box contains no max"); attP = (Point *)DXGetConstantArrayData(attr); if(!attP) DXErrorGoto(ERROR_BAD_PARAMETER, "clip box has invalid max"); max = *(Point *)attP; newMin.x = min.x < max.x ? min.x : max.x; newMin.y = min.y < max.y ? min.y : max.y; newMin.z = min.z < max.z ? min.z : max.z; newMax.x = min.x > max.x ? min.x : max.x; newMax.y = min.y > max.y ? min.y : max.y; newMax.z = min.z > max.z ? min.z : max.z; APPLY3((float*)&newMin,dm); APPLY3((float*)&newMax,dm); APPLY3((float*)&X,datm); APPLY3((float*)&Y,datm); APPLY3((float*)&Z,datm); cpo = _dxf_newHwClipped(6, tmpObject); if (! cpo) goto error; if (! _dxf_getHwClippedInfo(cpo, &cp_pts, &cp_nrms, NULL, NULL)) goto error; cp_pts[0] = newMin; cp_nrms[0] = X; cp_pts[1] = newMin; cp_nrms[1] = Y; cp_pts[2] = newMin; cp_nrms[2] = Z; cp_pts[3] = newMax; cp_nrms[3] = DXNeg(X); cp_pts[4] = newMax; cp_nrms[4] = DXNeg(Y); cp_pts[5] = newMax; cp_nrms[5] = DXNeg(Z); *newObject = (dxObject)cpo; } else { *newObject = NULL; DXErrorGoto(ERROR_BAD_PARAMETER,"unrecognized clip object"); } _dxf_setFlags(newFlags,CONTAINS_CLIP_OBJECT); } else *newObject = NULL; } break; case CLASS_XFORM: { dxMatrix matrix; float tmp[4][4],tmp1[4][4],tmp2[4][4]; /* * remove XForms from tree, propagate Xforms to Fields */ if (!DXGetXformInfo((Xform)object, &subObject, &matrix)) { EXIT(("DXGetXformInfo returns NULL")); return NULL; } CONVERTMATRIX(tmp,matrix); _dxf_attributeMatrix(new,tmp1); MULTMATRIX(tmp2,tmp,tmp1); _dxf_setAttributeMatrix(new,tmp2); if (!_gatherRecurse(subObject, newObject, gather, new, globals)) goto error; } break; case CLASS_LIGHT: { float direction[3]; RGBColor color; int flags; *newObject = NULL; if(_dxf_isFlagsSet(newFlags,IN_SCREEN_OBJECT)) { EXIT(("ERROR")); DXErrorReturn(ERROR_BAD_PARAMETER, "Light objects not allowed in Screen object"); } if(DXQueryCameraDistantLight((Light)object,(Vector*)direction,&color)) { listO lights; if (! _dxf_getHwGatherLights(gather, &lights)) goto error; /* only first 8 lights are used */ if(_dxf_listSize(lights) >= 8) { DXWarning("#5195") ; break; } DXReference(object); if(! _dxf_listAppendItem(lights,(Pointer) object)) goto error; } else if (DXQueryDistantLight((Light)object,(Vector*)direction,&color)) { listO lights; if (! _dxf_getHwGatherLights(gather, &lights)) goto error; if(_dxf_listSize(lights) >= 8) { DXWarning("#5195") ; break; } DXReference(object); if(! _dxf_listAppendItem(lights,(Pointer) object)) goto error; } else if(DXQueryAmbientLight((Light)object,&color)) { RGBColor gcolor; if (! _dxf_getHwGatherAmbientColor(gather, &gcolor)) goto error; gcolor.r += color.r; gcolor.g += color.g; gcolor.b += color.b; if (! _dxf_setHwGatherAmbientColor(gather, gcolor)) goto error; } else { PRINT(("invalid light")); DXErrorGoto(ERROR_INVALID_DATA, "#13750"); } if (! _dxf_getHwGatherFlags(gather, &flags)) goto error; flags |= CONTAINS_LIGHT; if (! _dxf_setHwGatherFlags(gather, flags)) goto error; } break; default: break; } if(new) _dxf_deleteAttribute(new); EXIT(("OK")); return OK; error: if(new) _dxf_deleteAttribute(new); EXIT(("OK")); return ERROR; }