//============================================================================= // Q3Hit_EmptyData : Compatibility function. //----------------------------------------------------------------------------- TQ3Status Q3Hit_EmptyData(void *hitData) { TQ3HitData *hitDataPtr = (TQ3HitData*)hitData ; Q3HitPath_EmptyData ( &hitDataPtr->path ) ; if ( hitDataPtr->object ) Q3Object_Dispose ( hitDataPtr->object ) ; if ( hitDataPtr->shapePart ) Q3Object_Dispose ( hitDataPtr->shapePart ) ; return(kQ3Success); }
//============================================================================= // E3FFW_3DMF_Close: Close the format. //----------------------------------------------------------------------------- TQ3Status E3FFW_3DMF_Close( TQ3FileFormatObject format, TQ3Boolean abort ) { TE3FFormatW3DMF_Data* instanceData = (TE3FFormatW3DMF_Data*) format->FindLeafInstanceData () ; TQ3Status status = kQ3Success; TE3FFormat3DMF_TOC *toc = instanceData->toc; TQ3Uns32 i; if(toc != NULL) // delete the toc { for(i = 0; i < toc->nEntries; i++) { if(toc->tocEntries[i].object != NULL) { Q3Object_Dispose(toc->tocEntries[i].object); } } Q3Memory_Free(&instanceData->toc); } if (instanceData->index != NULL) { delete instanceData->index; } return status; }
TQ3ShaderObject QutTexture_CreateTextureFromPixmap( PixMapHandle thePixMap, TQ3PixelType pixelType, TQ3Boolean wantMipMaps) { TQ3TextureObject qd3dTextureObject = NULL ; TQ3ShaderObject qd3dTextureShader = NULL ; // Create the texture qd3dTextureObject = QutTexture_CreateTextureObjectFromPixmap( thePixMap, pixelType, wantMipMaps) ; // Create the texture shader if (qd3dTextureObject != NULL) { qd3dTextureShader = Q3TextureShader_New(qd3dTextureObject); Q3Object_Dispose(qd3dTextureObject); } return(qd3dTextureShader); }
//============================================================================= // e3geom_disk_duplicate : Disk duplicate method. //----------------------------------------------------------------------------- static TQ3Status e3geom_disk_duplicate(TQ3Object fromObject, const void *fromPrivateData, TQ3Object toObject, void *toPrivateData) { TQ3DiskData *toInstanceData = (TQ3DiskData *) toPrivateData; TQ3Status qd3dStatus; TQ3AttributeSet dupSet; #pragma unused(fromPrivateData) #pragma unused(toObject) // Validate our parameters Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(fromObject), kQ3Failure); Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(toPrivateData), kQ3Failure); // Copy the data from fromObject to toObject qd3dStatus = Q3Disk_GetData(fromObject, toInstanceData); if ( (qd3dStatus == kQ3Success) && (toInstanceData->diskAttributeSet != NULL) ) { dupSet = Q3Object_Duplicate( toInstanceData->diskAttributeSet ); Q3Object_Dispose( toInstanceData->diskAttributeSet ); toInstanceData->diskAttributeSet = dupSet; if (dupSet == NULL) { qd3dStatus = kQ3Failure; } } return(qd3dStatus); }
static TQ3GroupObject QD3DSupport_NewLights() { TQ3GroupPosition myGroupPosition; TQ3GroupObject myLightList; TQ3LightData myLightData; TQ3LightObject myAmbientLight = NULL; TQ3ColorRGB WhiteLight = { 1.0F, 1.0F, 1.0F }; /* Set up light data for ambient light. This light data will be used for point and fill light also. */ myLightData.isOn = kQ3True; myLightData.color = WhiteLight; /* Create ambient light. */ myLightData.brightness = 0.8F; myAmbientLight = Q3AmbientLight_New(&myLightData); if ( myAmbientLight == nil ) { goto bail; } /* Create light group and add each of the lights into the group. */ myLightList = Q3LightGroup_New(); if ( myLightList == nil ) { goto bail; } myGroupPosition = Q3Group_AddObject(myLightList, myAmbientLight); if ( myGroupPosition == 0 ) { goto bail; } Q3Object_Dispose( myAmbientLight ) ; /* Done! */ return ( myLightList ); bail: /* If any of the above failed, then return nothing! */ if (myAmbientLight != NULL) { Q3Object_Dispose( myAmbientLight ) ; } return ( nil ); }
static TQ3GroupPosition MyAddTransformedObjectToGroup( TQ3GroupObject theGroup, TQ3Object theObject, TQ3Vector3D *translation ) { TQ3TransformObject transform; transform = Q3TranslateTransform_New(translation); Q3Group_AddObject(theGroup, transform); Q3Object_Dispose(transform); return Q3Group_AddObject(theGroup, theObject); }
//============================================================================= // E3FFW_3DMF_Group : handle groups. //----------------------------------------------------------------------------- TQ3Status E3FFW_3DMF_Group(TQ3ViewObject theView, void *fileFormatPrivate, TQ3GroupObject theGroup, TQ3ObjectType objectType, const void *objectData) { #pragma unused(objectType) #pragma unused(objectData) TQ3Status qd3dStatus; TQ3GroupPosition position; TQ3Object subObject; TQ3DisplayGroupState groupState; TQ3Boolean wroteReference; if(Q3Group_GetType (theGroup) == kQ3GroupTypeDisplay){ Q3DisplayGroup_GetState (theGroup, &groupState); if((groupState & kQ3DisplayGroupStateMaskIsWritten) != kQ3DisplayGroupStateMaskIsWritten) return kQ3Success; } // submit the group start tag qd3dStatus = e3ffw_3DMF_TraverseObject_CheckRef (theView, (TE3FFormatW3DMF_Data*)fileFormatPrivate, theGroup, Q3Object_GetLeafType (theGroup), theGroup->FindLeafInstanceData (), &wroteReference); // If we actually wrote a reference instead of a group start tag, then we don't // want to write contents and group end. if (wroteReference == kQ3True) { return qd3dStatus; } // submit the group contents for(Q3Group_GetFirstPosition (theGroup, &position); (position != NULL) && (qd3dStatus == kQ3Success); Q3Group_GetNextPosition (theGroup, &position)) { qd3dStatus = Q3Group_GetPositionObject (theGroup, position, &subObject); if(qd3dStatus != kQ3Success) break; qd3dStatus = Q3Object_Submit (subObject, theView); Q3Object_Dispose (subObject); } // submit the group end tag if(qd3dStatus == kQ3Success) qd3dStatus = E3FFW_3DMF_TraverseObject (theView, (TE3FFormatW3DMF_Data*)fileFormatPrivate, NULL, 0x656E6467 /* endg - EndGroup*/, NULL); return(qd3dStatus); }
//------------------------------------------------------------------------------------------- // change the geometry of the object type with number num McoStatus LogoWin2::ChangeGeometry (McoQ3DType type, long num) { TQ3Status status; TQ3Object object = NULL; TQ3GroupPosition position; unsigned long triGridLibNum; McoQ3DObject *gammutObj; if (Document.fModel == nil) return MCO_OBJECT_NOT_INITIALIZED; status = Q3Group_GetFirstPositionOfType(Document.fModel, kQ3ShapeTypeGeometry, &position); while (status == kQ3Success && position != nil) { gammutObj = getObject(object); if (gammutObj->IsTypeNum(type,num)) { status = Q3Group_GetNextPosition(Document.fModel, &position); object = Q3Group_RemovePosition(Document.fModel, position); Q3Object_Dispose(object); removeObject(object); object = NULL; break; } Q3Group_GetNextPositionOfType(Document.fModel, kQ3ShapeTypeGeometry, &position); } object = NewPolyGCIELabRef(); //object = NewLogoObject(); if (object == NULL) return MCO_FAILURE; addObject(object,type,num); if (position != nil) Q3Group_AddObjectBefore (Document.fModel, position, object); else Q3Group_AddObject (Document.fModel, object); AddResourceTextureToGroup( LW_TEXTURE, Document.fModel); Q3Object_Dispose(object); return MCO_SUCCESS; }
TQ3Status MyDeleteView( DocumentPtr theDocument ) { BOOL result; TQ3Status aStatus = kQ3Success; if( kQ3DrawContextTypePixmap == theDocument->drawcontextType) { result = DeleteObject(theDocument->fBitmap); result = DeleteDC(theDocument->fMemoryDC); } Q3Object_Dispose(theDocument->fView); return aStatus; }
void QD3DSupport_DisposeDoc3DData( DocumentPtr theDocument) { TQ3Status status; Q3Object_Dispose(theDocument->fView) ; /* the view for the scene */ Q3Object_Dispose(theDocument->fCamera) ; /* the camera for the scene */ Q3Object_Dispose(theDocument->fTrackGroup) ; Q3Object_Dispose(theDocument->fGroundGroup) ; Q3Object_Dispose(theDocument->fInterpolation) ; /* interpolation style used when rendering */ Q3Object_Dispose(theDocument->fBackFacing) ; /* whether to draw shapes that face away from the camera */ Q3Object_Dispose(theDocument->fFillStyle) ; /* whether drawn as solid filled object or decomposed to components */ Q3Object_Dispose(theDocument->fTrackShader) ; /* whether drawn as solid filled object or decomposed to components */ status = Q3Exit(); if ( status == kQ3Failure ) { Utils_DisplayErrorMsg("QD3D Exit returned failure"); } }
//============================================================================= // QutTexture_CreateCompressedTextureFromPixmap : Create a QD3D compressed // texture from a Pixmap. //----------------------------------------------------------------------------- TQ3ShaderObject QutTexture_CreateCompressedTextureFromPixmap( PixMapHandle thePixMap, TQ3PixelType pixelType, TQ3Boolean wantMipMaps) { TQ3ShaderObject theShader = NULL; TQ3TextureObject theTexture = NULL; theTexture = QutTexture_CreateCompressedTextureObjectFromPixmap( thePixMap, pixelType, wantMipMaps ) ; if ( theTexture != NULL) { theShader = Q3TextureShader_New( theTexture ); Q3Object_Dispose( theTexture ); } return(theShader) ; }
//============================================================================= // QutTexture_CreateCompressedTextureFromFile : Create a QD3D compressed // texture from a file. //----------------------------------------------------------------------------- TQ3ShaderObject QutTexture_CreateCompressedTextureFromFile( const FSSpec * theFSSpec, TQ3PixelType pixelType, TQ3Boolean wantMipMaps) { TQ3TextureObject theTexture = NULL; TQ3ShaderObject theShader = NULL; theTexture = QutTexture_CreateCompressedTextureObjectFromFile( theFSSpec, pixelType, wantMipMaps ) ; if ( theTexture != NULL) { theShader = Q3TextureShader_New( theTexture ); Q3Object_Dispose( theTexture ); } return(theShader); }
TQ3Status MyResizeView( DocumentPtr theDocument,unsigned long width, unsigned long height ) { BOOL result; TQ3Status aStatus = kQ3Success; if( theDocument->fWidth == width && theDocument->fHeight == height ) return aStatus; theDocument->fWidth = width; theDocument->fHeight = height; if( kQ3DrawContextTypePixmap == theDocument->drawcontextType) { Q3Object_Dispose(theDocument->fView); result = DeleteObject(theDocument->fBitmap); theDocument->fBitmap = NULL; result = DeleteDC(theDocument->fMemoryDC); theDocument->fMemoryDC = NULL; theDocument->fView = MyNewView(theDocument); } return aStatus; }
//----------------------------------------------------------------------------- // QutTexture_CreateTextureFromTGAFile : Create texture shader from a TGA file. //----------------------------------------------------------------------------- TQ3ShaderObject QutTexture_CreateTextureFromTGAFile( const char* inFilePath ) { TQ3TextureObject qd3dTextureObject = NULL ; TQ3ShaderObject qd3dTextureShader = NULL ; // Create the texture qd3dTextureObject = QutTexture_CreateTextureObjectFromTGAFile( inFilePath ); // Create the texture shader if (qd3dTextureObject != NULL) { qd3dTextureShader = Q3TextureShader_New(qd3dTextureObject); Q3Object_Dispose(qd3dTextureObject); } return(qd3dTextureShader); }
TQ3TextureObject QutTexture_CreateTextureObjectFromPixmap(PixMapHandle thePixMap, TQ3PixelType pixelType, TQ3Boolean wantMipMaps) { TQ3Uns32 x, y, theWidth, theHeight, rowBytes, pixelBytes; TQ3TextureObject qd3dTextureObject = NULL; TQ3StorageObject qd3dMemoryStorage; TQ3StoragePixmap qd3dPixMap; TQ3Mipmap qd3dMipMap; UInt16 *pixelPtr; UInt8 *baseAddr; OSType pixelFormat; TQ3Endian byteOrder; // Get the details we need from the PixMap NoPurgePixels(thePixMap); LockPixels(thePixMap); theWidth = (*thePixMap)->bounds.right - (*thePixMap)->bounds.left; theHeight = (*thePixMap)->bounds.bottom - (*thePixMap)->bounds.top; rowBytes = (*thePixMap)->rowBytes & 0x7FFF; pixelBytes = (*thePixMap)->pixelSize / 8; baseAddr = (UInt8 *) GetPixBaseAddr(thePixMap); #if OLDPIXMAPSTRUCT pixelFormat = 0; #else pixelFormat = (*thePixMap)->pixelFormat; #endif // If this is a 16 bit alpha channel texture, set the alpha bits. // We assume that black is transparent. if (pixelType == kQ3PixelTypeARGB16) { for (y = 0; y < theHeight; y++) { for (x = 0; x < theWidth; x++) { pixelPtr = (UInt16 *) (baseAddr + (y * rowBytes) + (x * 2)); if (*pixelPtr != 0x0000) *pixelPtr |= (1 << 15); } } } // Set the byte order if ( (pixelFormat == k32BGRAPixelFormat) || (pixelFormat == k16LE555PixelFormat) ) { byteOrder = kQ3EndianLittle; } else { byteOrder = kQ3EndianBig; } // Create a storage object based on the GWorld qd3dMemoryStorage = Q3MemoryStorage_New(baseAddr, theHeight * rowBytes); if (qd3dMemoryStorage != NULL) { // Create the appropriate type of texture. Note that if mip-maps are // required, we create a QD3D PixMap. This might seem back to front, // but QD3D automatically creates mip-maps for PixMaps. // // If mip-maps are not required, we create a QD3D MipMap by hand and // signal that we don't want any other mip-maps to be created. // // We need to work around a bug in Q3MipmapTexture_New: if the rowByte // for the pixel exactly matches the size of each row, the texture is // distorted - we can fix this by using Q3PixmapTexture_New instead. if (wantMipMaps || (rowBytes == theWidth * pixelBytes)) { // Create a PixMap from the GWorld data qd3dPixMap.image = qd3dMemoryStorage; qd3dPixMap.width = theWidth; qd3dPixMap.height = theHeight; qd3dPixMap.rowBytes = rowBytes; qd3dPixMap.pixelSize = (pixelType == kQ3PixelTypeARGB32 || pixelType == kQ3PixelTypeRGB32) ? 32 : 16; qd3dPixMap.pixelType = pixelType; qd3dPixMap.bitOrder = byteOrder; qd3dPixMap.byteOrder = byteOrder; qd3dTextureObject = Q3PixmapTexture_New(&qd3dPixMap); } else { // Create a MipMap from the GWorld data qd3dMipMap.image = qd3dMemoryStorage; qd3dMipMap.useMipmapping = kQ3False; qd3dMipMap.pixelType = pixelType; qd3dMipMap.bitOrder = byteOrder; qd3dMipMap.byteOrder = byteOrder; qd3dMipMap.reserved = 0; qd3dMipMap.mipmaps[0].width = theWidth; qd3dMipMap.mipmaps[0].height = theHeight; qd3dMipMap.mipmaps[0].rowBytes = rowBytes; qd3dMipMap.mipmaps[0].offset = 0; qd3dTextureObject = Q3MipmapTexture_New(&qd3dMipMap); } Q3Object_Dispose(qd3dMemoryStorage); } // Clean up and return UnlockPixels(thePixMap); return(qd3dTextureObject); }
// Load a QD3D model object: TQ3Object LoadModel(FileSpecifier& Spec) { // First create a file object and a storage object, // and associate the storage object with the file object. // MacOS / FSSpec version: // modify as necessary for Quesa and SDL -- // Quesa has similar calls with the MacOS FSSpec being replaced by a Windows file handle // and a Unix file path TQ3StorageObject StorageObject = Q3FSSpecStorage_New(&Spec.GetSpec()); if (!StorageObject) return NULL; TQ3FileObject FileObject = Q3File_New(); if (!FileObject) { Q3Object_Dispose(StorageObject); return NULL; } Q3File_SetStorage(FileObject, StorageObject); Q3Object_Dispose(StorageObject); // Read in the model object if (Q3File_OpenRead(FileObject, NULL) != kQ3Success) { Q3Object_Dispose(FileObject); return NULL; } // Create a group for holding all the read-in objects TQ3Object ModelObject = Q3DisplayGroup_New(); if (!ModelObject) { Q3Object_Dispose(FileObject); return NULL; } // All at once: slurp in now and process later while (Q3File_IsEndOfFile(FileObject) == kQ3False) { // Grab an object from the file TQ3Object MemberObject = Q3File_ReadObject(FileObject); if (!MemberObject) continue; // Only interested in renderable objects (no hints or comments or ...) if (Q3Object_IsDrawable(MemberObject)) Q3Group_AddObject(ModelObject, MemberObject); // Clean up if (MemberObject) Q3Object_Dispose(MemberObject); } // Done with the file object Q3Object_Dispose(FileObject); if (Q3Error_Get(NULL) != kQ3ErrorNone) { if (ModelObject) Q3Object_Dispose(ModelObject); return NULL; } // Finally! return ModelObject; }
// Returns whether the creation was a success bool CreateTriangulator(void) { // No need to create it more than once if (TriangulatorView) return true; TriangulatorClass = Q3XObjectHierarchy_RegisterClass( kQ3SharedTypeRenderer, &TriangulatorClassType, "BG-Inspired Triangulator", TriangulatorMetaHandler, NULL, 0, 0); if(!TriangulatorClass) return false; if(!TriangulatorClassType) return false; // Dummy draw context: a pixmap (image buffer) that is empty TQ3PixmapDrawContextData PixmapContextData = { // drawContextData { kQ3ClearMethodWithColor, {0,0,0,0}, {{0,0},{0,0}}, kQ3False, NULL, kQ3False, kQ3True }, // pixmap { NULL, 0, 0, 0, 32, kQ3PixelTypeARGB32, kQ3EndianBig, kQ3EndianBig } }; TQ3DrawContextObject DrawContextObject = Q3PixmapDrawContext_New(&PixmapContextData); if (!DrawContextObject) return false; TQ3RendererObject RendererObject = Q3Renderer_NewFromType(TriangulatorClassType); if (!RendererObject) { Q3Object_Dispose(DrawContextObject); return false; } TriangulatorView = Q3View_New(); bool Success = TriangulatorView != NULL; if(Success) Success = (Q3View_SetDrawContext(TriangulatorView, DrawContextObject) == kQ3Success); if(Success) Success = (Q3View_SetRenderer(TriangulatorView, RendererObject) == kQ3Success); // No longer needed Q3Object_Dispose(DrawContextObject); Q3Object_Dispose(RendererObject); return Success; }
static TQ3GroupObject QD3DSupport_GroundInit(TQ3ShaderObject groundShaderObject) { long i; TQ3GeometryObject polygonObj = NULL; TQ3GroupPosition myGroupPosition; TQ3GroupObject groundGroup; TQ3PolygonData polygonData; TQ3Vertex3D vertices[kNumGrndTextureVertices] = {0,-3,GROUND_SIZE,nil, GROUND_SIZE,-3,GROUND_SIZE,nil, GROUND_SIZE,-3,-GROUND_SIZE,nil, 0,-3,-GROUND_SIZE,nil}; TQ3AttributeSet attribs[kNumGrndTextureVertices] = {NULL, NULL, NULL, NULL}; float ambient = 1.0F; TQ3Param2D uv[kNumGrndTextureVertices] = {0,0,1,0,1,1,0,1}; if (groundShaderObject == NULL) { return NULL; } groundGroup = Q3OrderedDisplayGroup_New(); if (groundGroup == NULL) { return NULL; } /* ADD TEXTURE SHADER OBJECT TO GROUP */ myGroupPosition = Q3Group_AddObject(groundGroup, groundShaderObject); if ( myGroupPosition == nil ) { Utils_DisplayErrorMsg("Q3Group_AddObject failed!"); goto outOfMem; } Q3Object_Dispose(groundShaderObject); /* CREATE VERTICES */ for (i=0; i < kNumGrndTextureVertices; i++) { attribs[i] = Q3AttributeSet_New(); if( attribs[i] == NULL ) { Utils_DisplayErrorMsg("Attribute set creation failed!"); goto outOfMem; } Q3AttributeSet_Add(attribs[i], kQ3AttributeTypeShadingUV, &uv[i]); vertices[i].attributeSet = attribs[i]; } /* CREATE NEW POLYGON OBJECT */ polygonData.numVertices = kNumGrndTextureVertices; polygonData.vertices = vertices; polygonData.polygonAttributeSet = nil; polygonObj = Q3Polygon_New(&polygonData); if( polygonObj == NULL ) { Utils_DisplayErrorMsg("Polygon_New failed!"); goto outOfMem; } for (i=0; i < kNumGrndTextureVertices; i++) { Q3Object_Dispose(attribs[i]); attribs[i] = NULL; } myGroupPosition = Q3Group_AddObject(groundGroup, polygonObj); Q3Object_Dispose(polygonObj); if ( myGroupPosition == nil ) { Utils_DisplayErrorMsg("Q3Group_AddObject failed!"); goto outOfMem; } /* Success! */ return groundGroup; /* Error handling */ outOfMem: if (groundGroup) { Q3Object_Dispose(groundGroup); } for (i=0; i < kNumGrndTextureVertices; i++) { if( attribs[i] ) { Q3Object_Dispose(attribs[i]); } } return NULL; }
//----------------------------------------------------------------------------- // QutTexture_CreateTextureObjectFromTGAFile : Create texture object from a TGA file. //----------------------------------------------------------------------------- TQ3TextureObject QutTexture_CreateTextureObjectFromTGAFile( const char* inFilePath ) { TQ3TextureObject theTexture = NULL; FILE* theFile = NULL; TGAHeader theHeader; int numPixels, bytesPerPixel, n, i, j; int oppositeRow, packetHeader, chunkSize, rowBytes; TQ3Object memStorage = NULL; unsigned char p[5]; unsigned char* theBuffer; TQ3Uns32 bufferSize; TQ3StoragePixmap thePixMap; TQ3PixelType pixelType; theFile = fopen( inFilePath, "rb" ); if (theFile != NULL) { // Read the file header. theHeader.IDLength = fgetc( theFile ); theHeader.colorMapType = fgetc( theFile ); theHeader.dataTypeCode = fgetc( theFile ); theHeader.colorMapOrigin = qutTexture_read_littleendian_short( theFile ); theHeader.colorMapLength = qutTexture_read_littleendian_short( theFile ); theHeader.colorMapDepth = fgetc( theFile ); theHeader.x_origin = qutTexture_read_littleendian_short( theFile ); theHeader.y_origin = qutTexture_read_littleendian_short( theFile ); theHeader.width = qutTexture_read_littleendian_short( theFile ); theHeader.height = qutTexture_read_littleendian_short( theFile ); theHeader.bitsPerPixel = fgetc( theFile ); theHeader.imageDescriptor = fgetc( theFile ); // Check that the image format is one we can handle. if ( ( (theHeader.dataTypeCode == kTGATypeColor) || (theHeader.dataTypeCode == kTGATypeColorRLE) ) && ( (theHeader.bitsPerPixel == 16) || (theHeader.bitsPerPixel == 24) || (theHeader.bitsPerPixel == 32) ) && ( (theHeader.colorMapType == 0) || (theHeader.colorMapType == 1) ) && ! (feof(theFile) || ferror(theFile)) ) { // Skip identification field, if any. fseek( theFile, theHeader.IDLength, SEEK_CUR ); // Skip color map, if any. fseek( theFile, theHeader.colorMapType * theHeader.colorMapLength, SEEK_CUR ); // Make a storage object to hold the pixels. bytesPerPixel = theHeader.bitsPerPixel / 8; numPixels = theHeader.width * theHeader.height; bufferSize = numPixels * bytesPerPixel; theBuffer = (unsigned char*) malloc( bufferSize ); if (theBuffer != NULL) { // Read the image. n = 0; while ( (n < numPixels) && (!feof(theFile)) && (!ferror(theFile)) ) { if (theHeader.dataTypeCode == kTGATypeColor) // uncompressed { fread( theBuffer + n * bytesPerPixel, bytesPerPixel, 1, theFile ); ++n; } else // RLE compressed { packetHeader = fgetc( theFile ); chunkSize = (packetHeader & 0x7F) + 1; if (packetHeader & 0x80) // RLE chunk { fread( p, bytesPerPixel, 1, theFile ); for (i=0; i < chunkSize; ++i) { memcpy( theBuffer + n * bytesPerPixel, p, bytesPerPixel ); ++n; } } else // uncompressed chunk { fread( theBuffer + n * bytesPerPixel, bytesPerPixel, chunkSize, theFile ); n += chunkSize; } } } // We may need to flip the image into the usual top to bottom row order. rowBytes = theHeader.width * bytesPerPixel; if ( (theHeader.imageDescriptor & kTGADescTopToBottom) == 0) { for (i = 0; i < theHeader.height / 2; ++i) { oppositeRow = theHeader.height - i - 1; for (j = 0; j < rowBytes; ++j) { unsigned char temp = theBuffer[ i * rowBytes + j ]; theBuffer[ i * rowBytes + j ] = theBuffer[ oppositeRow * rowBytes + j ]; theBuffer[ oppositeRow * rowBytes + j ] = temp; } } } // Set the pixel type switch (bytesPerPixel) { case 2: pixelType = kQ3PixelTypeRGB16; break; case 3: pixelType = kQ3PixelTypeRGB24; break; default: // quiet an uninitialized-variable warning case 4: pixelType = kQ3PixelTypeARGB32; // Typically TGA format uses non-premultiplied alpha, // whereas Quesa usually expects premultiplied alpha, so // we multiply here. for (i = 0; i < theHeader.width * theHeader.height; ++i) { unsigned short a = theBuffer[i*4+3]; theBuffer[i*4] = (theBuffer[i*4]*a) / 255; theBuffer[i*4+1] = (theBuffer[i*4+1]*a) / 255; theBuffer[i*4+2] = (theBuffer[i*4+2]*a) / 255; } break; } #if TARGET_API_MAC_OS8 // QD3D on Mac does not support kQ3PixelTypeRGB24, and also appears to // ignore the byte order, so we must convert to kQ3PixelTypeRGB32 in // big-endian order. if (pixelType == kQ3PixelTypeRGB24) { unsigned char* bigBuffer = malloc( numPixels * 4 ); if (bigBuffer != NULL) { pixelType = kQ3PixelTypeRGB32; for (i = 0; i < numPixels; ++i) { bigBuffer[4*i + 3] = theBuffer[3*i]; bigBuffer[4*i + 2] = theBuffer[3*i + 1]; bigBuffer[4*i + 1] = theBuffer[3*i + 2]; } bytesPerPixel = 4; rowBytes = theHeader.width * bytesPerPixel; bufferSize = numPixels * bytesPerPixel; free( theBuffer ); theBuffer = bigBuffer; } } #endif // Create a memory storage object holding a copy of the buffer memStorage = Q3MemoryStorage_New( theBuffer, bufferSize ); if (memStorage != NULL) { // Create the texture object thePixMap.image = memStorage; thePixMap.width = theHeader.width; thePixMap.height = theHeader.height; thePixMap.rowBytes = rowBytes; thePixMap.pixelSize = bytesPerPixel * 8; thePixMap.bitOrder = kQ3EndianLittle; thePixMap.byteOrder = kQ3EndianLittle; thePixMap.pixelType = pixelType; theTexture = Q3PixmapTexture_New( &thePixMap ); Q3Object_Dispose( memStorage ); } free( theBuffer ); } } fclose( theFile ); } return theTexture; }
TQ3GroupObject MyNewModel() { TQ3GroupObject myGroup = NULL; TQ3GeometryObject myBox; TQ3BoxData myBoxData; TQ3ShaderObject myIlluminationShader ; TQ3SetObject faces[6] ; short face ; // Create a group for the complete model. // do not use Q3OrderedDisplayGroup_New since in this // type of group all of the translations are applied before // the objects in the group are drawn, in this instance we // dont want this. if ((myGroup = Q3DisplayGroup_New()) != NULL ) { // Define a shading type for the group // and add the shader to the group myIlluminationShader = Q3PhongIllumination_New(); Q3Group_AddObject(myGroup, myIlluminationShader); // set up the colored faces for the box data myBoxData.faceAttributeSet = faces; myBoxData.boxAttributeSet = NULL; MyColorBoxFaces( &myBoxData ) ; #define kBoxSide 0.8F #define kBoxSidePlusGap 0.1F // create the box itself Q3Point3D_Set(&myBoxData.origin, 0.0F, 0.0F, 0.0F); Q3Vector3D_Set(&myBoxData.orientation, 0.0F, kBoxSide, 0.0F); Q3Vector3D_Set(&myBoxData.majorAxis, 0.0F, 0.0F, kBoxSide); Q3Vector3D_Set(&myBoxData.minorAxis, kBoxSide, 0.0F, 0.0F); myBox = Q3Box_New(&myBoxData); #if 0 // one box Q3Group_AddObject(myGroup, myBox); #else // 4 boxes { TQ3Vector3D translation; translation.x = 0.0F; translation.y = kBoxSidePlusGap; translation.z = 0.0F; MyAddTransformedObjectToGroup( myGroup, myBox, &translation ) ; translation.x = 2 * kBoxSide; translation.y = kBoxSidePlusGap; translation.z = 0.0F; MyAddTransformedObjectToGroup( myGroup, myBox, &translation ) ; translation.x = 0.0F; translation.y = kBoxSidePlusGap; translation.z = -2 * kBoxSide; MyAddTransformedObjectToGroup( myGroup, myBox, &translation ) ; translation.x = -2 * kBoxSide; translation.y = kBoxSidePlusGap; translation.z = 0.0F; MyAddTransformedObjectToGroup( myGroup, myBox, &translation ) ; } #endif for( face = 0; face < 6; face++) { if( myBoxData.faceAttributeSet[face] != NULL ) Q3Object_Dispose(myBoxData.faceAttributeSet[face]); } if( myBox ) Q3Object_Dispose( myBox ); } // dispose of the objects we created here if( myIlluminationShader ) Q3Object_Dispose(myIlluminationShader); // Done! return ( myGroup ); }
TQ3GeometryObject LogoWin2::NewLogoObject(void) { TQ3GeometryObject geometryObject = NULL; TQ3TriGridData data; TQ3Vertex3D *vertices; TQ3Vertex3D norms; unsigned long i,j,k; float uuValue, vvValue, uuMin, uuMax, uuStep, vvMin, vvMax, vvStep, radius; TQ3Boolean hasUVAttributes; TQ3Param2D param2D; TQ3ColorRGB color = { 0.0, 0.0, 0.0 }; double *gammutSurface; double lab[4]; McoStatus status; double x,y,z,X,Y,Z; // uuValue is an angle used to revolve the cross section about the y axis // vvValue is an angle used to generate each half circular cross section uuMin = 0.0; uuMax = 360.0; vvMin = - 90.0; vvMax = 90.0; uuStep = 12.0; vvStep = 12.0; radius = 1.0; // Setup TQ3TriGridData data.numRows = (unsigned long) ((vvMax - vvMin) / vvStep) + 1; data.numColumns = (unsigned long) ((uuMax - uuMin) / uuStep) + 1; data.facetAttributeSet = NULL; data.triGridAttributeSet= NULL; data.vertices = (TQ3Vertex3D *) NewPtr (data.numRows * data.numColumns * sizeof(TQ3Vertex3D)); if (data.vertices == NULL) return NULL; // Set trigrid vertices and shading UVs, if it hasUVAttributes vertices = data.vertices; i = 0; for (vvValue = vvMin; vvValue <= vvMax; vvValue += vvStep) { for (uuValue = uuMax; uuValue >= uuMin; uuValue -= uuStep) { vertices[i].point.x = uMath_Cos_Deg(vvValue) * uMath_Cos_Deg(uuValue) * radius; vertices[i].point.y = 1.5*uMath_Sin_Deg(vvValue) * radius; vertices[i].point.z = uMath_Cos_Deg(vvValue) * uMath_Sin_Deg(uuValue) * radius; param2D.u = 1.0 - ((uuValue - uuMin) / (uuMax - uuMin)); param2D.v = (vvValue - vvMin) / (vvMax - vvMin); vertices[i].attributeSet = Q3AttributeSet_New(); Q3AttributeSet_Add(vertices[i].attributeSet, kQ3AttributeTypeShadingUV, ¶m2D); norms.point.x = uMath_Cos_Deg(vvValue) * uMath_Cos_Deg(uuValue) * (radius+1); norms.point.y = 1.5*uMath_Sin_Deg(vvValue)*(radius+1); norms.point.z = uMath_Cos_Deg(vvValue) * uMath_Sin_Deg(uuValue) * (radius+1); Q3AttributeSet_Add(vertices[i].attributeSet, kQ3AttributeTypeNormal, &norms); i++; } } geometryObject = Q3TriGrid_New (&data); for (i = 0; i < data.numRows * data.numColumns; i++) Q3Object_Dispose(vertices[i].attributeSet); DisposePtr ((char *) vertices); return geometryObject; }
TQ3ViewObject MyNewView(DocumentPtr theDocument) { TQ3Status myStatus; TQ3ViewObject myView; TQ3DrawContextObject myDrawContext; TQ3RendererObject myRenderer; TQ3CameraObject myCamera; TQ3GroupObject myLights; myView = Q3View_New(); // Create and set draw context. switch( theDocument->drawcontextType ) { case kQ3DrawContextTypeWin32DC: if ((myDrawContext = NewWin32DCDrawContext(theDocument)) == NULL ) goto bail; break; case kQ3DrawContextTypeDDSurface: goto bail; /* TBD */ default: case kQ3DrawContextTypePixmap: if ((myDrawContext = NewPixmapDrawContext(theDocument, theDocument->fPixelFormat )) == NULL ) goto bail; break; } if ((myStatus = Q3View_SetDrawContext(myView, myDrawContext)) == kQ3Failure ) goto bail; Q3Object_Dispose( myDrawContext ) ; // Create and set renderer. switch( theDocument->rendererType ) { case kQ3RendererTypeWireFrame: // this uses the wire frame renderer myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeWireFrame); if ((myStatus = Q3View_SetRenderer(myView, myRenderer)) == kQ3Failure ) { goto bail; } break; default: case kQ3RendererTypeInteractive: // this uses the interactive renderer if ((myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeInteractive)) != NULL ) { if ((myStatus = Q3View_SetRenderer(myView, myRenderer)) == kQ3Failure ) { goto bail; } // these two lines set us up to use the best possible renderer, // including hardware if it is installed. Q3InteractiveRenderer_SetDoubleBufferBypass (myRenderer, kQ3True); Q3InteractiveRenderer_SetPreferences(myRenderer, kQAVendor_BestChoice, 0); } else { goto bail; } break; } Q3Object_Dispose( myRenderer ) ; // Create and set camera if ( (myCamera = MyNewCamera(theDocument)) == NULL ) goto bail; if ((myStatus = Q3View_SetCamera(myView, myCamera)) == kQ3Failure ) goto bail; Q3Object_Dispose( myCamera ) ; // Create and set lights if ((myLights = MyNewLights()) == NULL ) goto bail; if ((myStatus = Q3View_SetLightGroup(myView, myLights)) == kQ3Failure ) goto bail; Q3Object_Dispose(myLights); return ( myView ); bail: // If any of the above failed, then don't return a view. return ( NULL ); }
static TQ3ViewObject QD3DSupport_NewView(HWND theWindow) #endif { TQ3Status myStatus; TQ3ViewObject myView; TQ3DrawContextObject myDrawContext; TQ3RendererObject myRenderer; TQ3GroupObject myLights; TQ3CameraObject myCamera; #if TARGET_OS_WIN32 RECT clientRect; BOOL success; #endif myView = Q3View_New(); if (myView == nil) { goto bail; } // Create and set draw context. if ((myDrawContext = QD3DSupport_NewDrawContext(theWindow)) == nil ) { goto bail; } if ((myStatus = Q3View_SetDrawContext(myView, myDrawContext)) == kQ3Failure ) { goto bail; } Q3Object_Dispose( myDrawContext ) ; // Create and set renderer. // this would use the Z-Buffer renderer #if 0 myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeWireFrame); if ((myStatus = Q3View_SetRenderer(myView, myRenderer)) == kQ3Failure ) { goto bail; } #else // this would use the interactive software renderer if ((myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeInteractive)) != nil ) { if ((myStatus = Q3View_SetRenderer(myView, myRenderer)) == kQ3Failure ) { goto bail; } // these two lines set us up to use the best possible renderer, // including hardware if it is installed. Q3InteractiveRenderer_SetDoubleBufferBypass (myRenderer, kQ3True); Q3InteractiveRenderer_SetPreferences(myRenderer, kQAVendor_BestChoice, 0); } else { goto bail; } #endif Q3Object_Dispose( myRenderer ) ; // Create and set camera. #if TARGET_OS_MAC if ( (myCamera = QD3DSupport_NewCamera((float) (theWindow->portRect.right - theWindow->portRect.left), (float) (theWindow->portRect.bottom - theWindow->portRect.top))) == nil ) { goto bail; } #else if TARGET_OS_WIN32 success = GetClientRect(theWindow, &clientRect); if (success) { if ( (myCamera = QD3DSupport_NewCamera((float)RECT_WIDTH(clientRect), (float)RECT_HEIGHT(clientRect))) == nil ) { goto bail; } } else { goto bail; } #endif if ((myStatus = Q3View_SetCamera(myView, myCamera)) == kQ3Failure ) { goto bail; } Q3Object_Dispose( myCamera ) ; // Create and set lights. if ((myLights = QD3DSupport_NewLights()) == nil ) { goto bail; } if ((myStatus = Q3View_SetLightGroup(myView, myLights)) == kQ3Failure ) { goto bail; } Q3Object_Dispose(myLights); // Done!!! return ( myView ); bail: // If any of the above failed, then don't return a view. return ( nil ); }
TQ3GroupObject MyNewLights() { TQ3GroupPosition myGroupPosition; TQ3GroupObject myLightList; TQ3LightData myLightData; TQ3PointLightData myPointLightData; TQ3DirectionalLightData myDirectionalLightData; TQ3LightObject myAmbientLight, myPointLight, myFillLight; TQ3Point3D pointLocation = { -10.0F, 0.0F, 10.0F }; TQ3Vector3D fillDirection = { 10.0F, 0.0F, 10.0F }; TQ3ColorRGB WhiteLight = { 1.0F, 1.0F, 1.0F }; // Set up light data for ambient light. This light data will be used for point and fill // light also. myLightData.isOn = kQ3True; myLightData.color = WhiteLight; // Create ambient light. myLightData.brightness = .25F; myAmbientLight = Q3AmbientLight_New(&myLightData); if ( myAmbientLight == NULL ) goto bail; // Create point light. myLightData.brightness = 1.0F; myPointLightData.lightData = myLightData; myPointLightData.castsShadows = kQ3False; myPointLightData.attenuation = kQ3AttenuationTypeNone; myPointLightData.location = pointLocation; myPointLight = Q3PointLight_New(&myPointLightData); if ( myPointLight == NULL ) goto bail; // Create fill light. myLightData.brightness = .3F; myDirectionalLightData.lightData = myLightData; myDirectionalLightData.castsShadows = kQ3False; myDirectionalLightData.direction = fillDirection; myFillLight = Q3DirectionalLight_New(&myDirectionalLightData); if ( myFillLight == NULL ) goto bail; // Create light group and add each of the lights into the group. myLightList = Q3LightGroup_New(); if ( myLightList == NULL ) goto bail; myGroupPosition = Q3Group_AddObject(myLightList, myAmbientLight); if ( myGroupPosition == 0 ) goto bail; myGroupPosition = Q3Group_AddObject(myLightList, myPointLight); if ( myGroupPosition == 0 ) goto bail; myGroupPosition = Q3Group_AddObject(myLightList, myFillLight); if ( myGroupPosition == 0 ) goto bail; Q3Object_Dispose( myAmbientLight ) ; Q3Object_Dispose( myPointLight ) ; Q3Object_Dispose( myFillLight ) ; // Done! return ( myLightList ); bail: // If any of the above failed, then return nothing! return ( NULL ); }
//============================================================================= // e3ffw_3DMF_TraverseObject_CheckRef: Do the traverse. //----------------------------------------------------------------------------- // This is identical to E3FFW_3DMF_TraverseObject, except that it informs // the caller whether it wrote a reference object. // E3FFW_3DMF_Group needs to know. //----------------------------------------------------------------------------- static TQ3Status e3ffw_3DMF_TraverseObject_CheckRef(TQ3ViewObject theView, TE3FFormatW3DMF_Data *fileFormatPrivate, TQ3Object theObject, TQ3ObjectType objectType, const void *objectData, TQ3Boolean* wroteReference ) { TQ3Status qd3dStatus = kQ3Success; TQ3Object submittedObject; TQ3ObjectType old_lastObjectType; TQ3Object old_lastObject; TQ3Uns32 old_lastTocIndex; E3ClassInfoPtr theClass = NULL; TQ3XObjectTraverseMethod traverse; TQ3FileObject theFile = E3View_AccessFile (theView); *wroteReference = kQ3False; // until further notice old_lastTocIndex = fileFormatPrivate->lastTocIndex; old_lastObject = fileFormatPrivate->lastObject; old_lastObjectType = fileFormatPrivate->lastObjectType; // fileFormatPrivate->lastObject = theObject; // called below since it can be substituted by a reference fileFormatPrivate->lastObjectType = objectType; fileFormatPrivate->lastTocIndex = kQ3ArrayIndexNULL; submittedObject = theObject; //find the object traverse method if(theObject != NULL){ if(Q3Object_IsType(theObject, kQ3ObjectTypeShared)) { if(e3ffw_3DMF_filter_in_toc(fileFormatPrivate, theObject, &submittedObject) != kQ3Success) return (kQ3Failure); } // will add a reference to the object // to retain the eventually made reference object if(submittedObject != theObject) { fileFormatPrivate->lastObjectType = Q3Object_GetLeafType(submittedObject); objectData = submittedObject->FindLeafInstanceData () ; } theClass = submittedObject->GetClass () ; } else theClass = E3ClassTree::GetClass ( objectType ) ; if (theClass == NULL) goto exit; traverse = (TQ3XObjectTraverseMethod) theClass->GetMethod ( kQ3XMethodTypeObjectTraverse ) ; if (traverse == NULL) goto exit; // mark our level fileFormatPrivate->baseData.groupDeepCounter++; fileFormatPrivate->lastObject = submittedObject; // Call the method qd3dStatus = traverse(submittedObject, (void*)objectData, theView); // If this is a shape, submit any custom elements attached to it. // This saves each shape traversal method from worrying about it. if ( (qd3dStatus == kQ3Success) && (submittedObject != NULL) && Q3Object_IsType( submittedObject, kQ3SharedTypeShape ) ) { qd3dStatus = E3Shape_SubmitElements( submittedObject, theView ); } fileFormatPrivate->baseData.groupDeepCounter--; if((fileFormatPrivate->baseData.groupDeepCounter == 0) && (qd3dStatus == kQ3Success)){ // we're again in the root object if(fileFormatPrivate->stackCount != 0){ qd3dStatus = e3ffw_3DMF_write_objects (fileFormatPrivate,theFile); // clean the stack fileFormatPrivate->stackCount = 0; Q3Memory_Free(&fileFormatPrivate->stack); } } exit: *wroteReference = (fileFormatPrivate->lastObjectType == kQ3ShapeTypeReference)? kQ3True : kQ3False; fileFormatPrivate->lastObjectType = old_lastObjectType; fileFormatPrivate->lastObject = old_lastObject; fileFormatPrivate->lastTocIndex = old_lastTocIndex; if(submittedObject != NULL && Q3Object_IsType(submittedObject, kQ3ObjectTypeShared)) { // remove the reference made by e3ffw_3DMF_filter_in_toc Q3Object_Dispose(submittedObject); } return (qd3dStatus); }
TQ3Status E3CompressedPixmapTexture_CompressImage(TQ3CompressedPixmap * compressedPixmap, PixMapHandle sourcePixMap, CodecType codecType, CodecComponent codecComponent, TQ3Int16 codedDepth, CodecQ codecQuality) { // If we support QuickTime, compress the image ImageDescriptionHandle imageDescH = NULL; long maxCompressedSize = 0; Handle compressedDataH = NULL; Ptr compressedDataP = NULL; OSErr theErr = noErr; Rect bounds = (**sourcePixMap).bounds; TQ3StorageObject compressedImage = NULL; TQ3StorageObject imageDesc = NULL; // Make sure QuickTime is present if ((TQ3Uns32) EnterMovies == (TQ3Uns32) kUnresolvedCFragSymbolAddress) return(kQ3Failure); theErr = GetMaxCompressionSize( sourcePixMap, &bounds, codedDepth, codecQuality, codecType, (CompressorComponent)codecComponent, &maxCompressedSize); if ( theErr != noErr ) { // paramErr or noCodecErr E3ErrorManager_PostError( kQ3ErrorInvalidParameter, kQ3False ) ; // failure return(kQ3Failure); } // allocate memory - we need to use Mac OS Handles for QuickTime imageDescH = (ImageDescriptionHandle) NewHandle( 4 ); compressedDataH = NewHandle( maxCompressedSize ); if ( compressedDataH != NULL && imageDescH != NULL ) { HLock(compressedDataH); compressedDataP = *compressedDataH; theErr = FCompressImage(sourcePixMap, &bounds, codedDepth, codecQuality, codecType, (CompressorComponent) codecComponent, NULL, 0, 0, NULL, NULL, imageDescH, compressedDataP); if ( theErr != noErr ) { // post error if (MemError() != noErr) E3ErrorManager_PostError( kQ3ErrorOutOfMemory , kQ3False ) ; else E3ErrorManager_PostError( kQ3ErrorInvalidParameter , kQ3False ) ; //deallocate handle storage DisposeHandle( (Handle)imageDescH); DisposeHandle( compressedDataH); // failure return(kQ3Failure) ; } } // otherwise we have a memory error else { // deallocate handle storage if (imageDescH) DisposeHandle( (Handle)imageDescH); if (compressedDataH) DisposeHandle( compressedDataH); // post error E3ErrorManager_PostError( kQ3ErrorOutOfMemory , kQ3False ) ; //failure return( kQ3Failure) ; } if (imageDescH) DisposeHandle( (Handle)imageDescH); if (compressedDataH) DisposeHandle( compressedDataH); // lock the image desc handle HLock( (Handle) imageDescH ) ; // store the data in storage objects compressedImage = Q3MemoryStorage_New( (unsigned char *) compressedDataP, (TQ3Uns32) (**imageDescH).dataSize ) ; imageDesc = Q3MemoryStorage_New( (unsigned char *) imageDescH, (TQ3Uns32) (**imageDescH).idSize ) ; // make sure memory was allocated if( compressedImage == NULL && imageDesc == NULL ) { if( compressedImage != NULL ) Q3Object_Dispose( compressedImage ) ; if( imageDesc != NULL ) Q3Object_Dispose( imageDesc ) ; // deallocate handle storage DisposeHandle( (Handle) imageDescH ) ; DisposeHandle( compressedDataH ) ; // we don't need to post a memory error because it // has already been done, return failure return(kQ3Failure); } // store the data in the compressed pixmap structure E3Shared_Acquire(&compressedPixmap->compressedImage, compressedImage); E3Shared_Acquire(&compressedPixmap->imageDesc, imageDesc); // NOTE: we do not fill out the other fields of the data structure, // since this is the defined QD3D behaviour // deallocate handle storage DisposeHandle( (Handle) imageDescH ) ; DisposeHandle( compressedDataH ) ; return(kQ3Success) ; }
bool LoadModel_QD3D(FileSpecifier& Spec, Model3D& Model) { // Clear out the final model object Model.Clear(); // Test for QD3D/Quesa's presence and initialize it if not present if (QD3D_Presence_Checked) { if (!QD3D_Present) return false; } else { QD3D_Presence_Checked = true; // MacOS QD3D; modify this for Quesa as appropriate if ((void*)Q3Initialize != (void*)kUnresolvedCFragSymbolAddress) { TQ3Status Success = Q3Initialize(); QD3D_Present = (Success == kQ3Success); } // Do additional setup; // if the triangulator could not be created, then act as if // QD3D/Quesa had not been loaded if (QD3D_Present) { Q3Error_Register(QD3D_Error_Handler,0); QD3D_Present = CreateTriangulator(); } if (!QD3D_Present) Q3Exit(); } if (DBOut) { // Read buffer const int BufferSize = 256; char Buffer[BufferSize]; Spec.GetName(Buffer); fprintf(DBOut,"Loading QuickDraw-3D model file %s\n",Buffer); } TQ3Object ModelObject = LoadModel(Spec); if (!ModelObject) return false; StartAccumulatingVertices(); if (Q3View_StartRendering(TriangulatorView) == kQ3Failure) { if (DBOut) fprintf(DBOut,"ERROR: couldn't start triangulation 'rendering'\n"); Q3Object_Dispose(ModelObject); return false; } do { Q3SubdivisionStyle_Submit(&TesselationData, TriangulatorView); if (Q3Object_Submit(ModelObject, TriangulatorView) == kQ3Failure) { if (DBOut) fprintf(DBOut,"ERROR: model could not be 'rendered'\n"); } } while (Q3View_EndRendering(TriangulatorView) == kQ3ViewStatusRetraverse); // Done with the model Q3Object_Dispose(ModelObject); GetVerticesIntoModel(Model); return !Model.Positions.empty(); }
void pvCamera_Fit(DocumentPtr theDocument) { TQ3Point3D from, to; TQ3BoundingBox viewBBox; float fieldOfView, hither, yon; if (!theDocument) return; if (!theDocument->fModel) return; pvBBox_Get(theDocument, &viewBBox); pvBBoxCenter(&viewBBox, &to); { TQ3Vector3D viewVector; TQ3Vector3D normViewVector; TQ3Vector3D eyeToFrontClip; TQ3Vector3D eyeToBackClip; TQ3Vector3D diagonalVector; float viewDistance; float maxDimension; Q3Point3D_Subtract(&viewBBox.max, &viewBBox.min, &diagonalVector); maxDimension = Q3Vector3D_Length(&diagonalVector); if (maxDimension == 0.0F) maxDimension = 1.0F; maxDimension *= 8.0F / 7.0F; from.x = to.x; from.y = to.y; from.z = to.z + (2 * maxDimension); Q3Point3D_Subtract(&to, &from, &viewVector); viewDistance = Q3Vector3D_Length(&viewVector); Q3Vector3D_Normalize(&viewVector, &normViewVector); maxDimension /= 2.0F; Q3Vector3D_Scale(&normViewVector, viewDistance - maxDimension, &eyeToFrontClip); Q3Vector3D_Scale(&normViewVector, viewDistance + maxDimension, &eyeToBackClip); hither = Q3Vector3D_Length(&eyeToFrontClip); yon = Q3Vector3D_Length(&eyeToBackClip); fieldOfView = Q3Math_RadiansToDegrees(1.25 * ErMath_Atan(maxDimension/hither)); } { TQ3ViewAngleAspectCameraData data; TQ3Vector3D up = { 0.0F, 1.0F, 0.0F }; data.cameraData.placement.cameraLocation = from; data.cameraData.placement.pointOfInterest = to; data.cameraData.placement.upVector = up; data.cameraData.range.hither = hither; data.cameraData.range.yon = yon; data.cameraData.viewPort.origin.x = -1.0F; data.cameraData.viewPort.origin.y = 1.0F; data.cameraData.viewPort.width = 2.0F; data.cameraData.viewPort.height = 2.0F; data.fov = Q3Math_DegreesToRadians(fieldOfView); { float w = (float)(theDocument->fWidth); float h = (float)(theDocument->fHeight); data.aspectRatioXToY = w/h; } if (theDocument->fView) { TQ3CameraObject camera; Q3View_GetCamera(theDocument->fView, &camera); if (camera) { Q3ViewAngleAspectCamera_SetData(camera, &data); Q3Object_Dispose(camera); } else { camera = Q3ViewAngleAspectCamera_New (&data); if (camera) { Q3View_SetCamera (theDocument->fView, camera); Q3Object_Dispose(camera); } } } } }
//============================================================================= // Q3Pick_GetHitData : Compatibility function. //----------------------------------------------------------------------------- TQ3Status Q3Pick_GetHitData(TQ3PickObject pickObject, TQ3Uns32 theIndex, void *hitData) { TQ3HitData *hitDataPtr = (TQ3HitData*)hitData ; hitDataPtr->part = kQ3PickPartsObject ; hitDataPtr->pickID = 0; hitDataPtr->path.rootGroup = NULL; hitDataPtr->path.depth = 0; hitDataPtr->path.positions = NULL; hitDataPtr->object = NULL; Q3Matrix4x4_SetIdentity ( &hitDataPtr->localToWorldMatrix ); hitDataPtr->xyzPoint.x = 0; hitDataPtr->xyzPoint.y = 0; hitDataPtr->xyzPoint.z = 0; hitDataPtr->distance = 0 ; hitDataPtr->normal.x = 0; hitDataPtr->normal.y = 0; hitDataPtr->normal.z = 0; hitDataPtr->shapePart = 0; if ( Q3Pick_GetPickDetailValidMask ( pickObject , theIndex , &hitDataPtr->validMask ) == kQ3Failure ) return(kQ3Failure); if ( hitDataPtr->validMask & kQ3PickDetailMaskPickID ) { if ( Q3Pick_GetPickDetailData ( pickObject , theIndex , kQ3PickDetailMaskPickID , &hitDataPtr->pickID ) == kQ3Failure ) return(kQ3Failure); } if ( hitDataPtr->validMask & kQ3PickDetailMaskLocalToWorldMatrix ) { if ( Q3Pick_GetPickDetailData ( pickObject , theIndex , kQ3PickDetailMaskLocalToWorldMatrix , &hitDataPtr->localToWorldMatrix ) == kQ3Failure ) return(kQ3Failure); } if ( hitDataPtr->validMask & kQ3PickDetailMaskXYZ ) { if ( Q3Pick_GetPickDetailData ( pickObject , theIndex , kQ3PickDetailMaskXYZ , &hitDataPtr->xyzPoint ) == kQ3Failure ) return(kQ3Failure); } if ( hitDataPtr->validMask & kQ3PickDetailMaskDistance ) { if ( Q3Pick_GetPickDetailData ( pickObject , theIndex , kQ3PickDetailMaskDistance , &hitDataPtr->distance ) == kQ3Failure ) return(kQ3Failure); } if ( hitDataPtr->validMask & kQ3PickDetailMaskNormal ) { if ( Q3Pick_GetPickDetailData ( pickObject , theIndex , kQ3PickDetailMaskNormal , &hitDataPtr->normal ) == kQ3Failure ) return(kQ3Failure); } if ( hitDataPtr->validMask & kQ3PickDetailMaskShapePart ) { if ( Q3Pick_GetPickDetailData ( pickObject , theIndex , kQ3PickDetailMaskShapePart , &hitDataPtr->shapePart ) == kQ3Failure ) return(kQ3Failure); } if ( hitDataPtr->validMask & kQ3PickDetailMaskObject ) { if ( Q3Pick_GetPickDetailData ( pickObject , theIndex , kQ3PickDetailMaskObject , &hitDataPtr->object ) == kQ3Failure ) { if ( hitDataPtr->shapePart ) { Q3Object_Dispose ( hitDataPtr->shapePart ) ; hitDataPtr->shapePart = NULL ; } return(kQ3Failure); } } if ( hitDataPtr->validMask & kQ3PickDetailMaskPath ) { if ( Q3Pick_GetPickDetailData ( pickObject , theIndex , kQ3PickDetailMaskPath , &hitDataPtr->path ) == kQ3Failure ) { if ( hitDataPtr->shapePart ) { Q3Object_Dispose ( hitDataPtr->shapePart ) ; hitDataPtr->shapePart = NULL ; } if ( hitDataPtr->object ) { Q3Object_Dispose ( hitDataPtr->object ) ; hitDataPtr->object = NULL ; } return(kQ3Failure); } } return(kQ3Success); }
// build a polygon that is a CIELab refrence TQ3GeometryObject LogoWin2::NewPolyGCIELabRef(void) { TQ3GeometryObject geometryObject = NULL; //TQ3TriGridData ciepoly; TQ3PolygonData ciepoly; TQ3Vertex3D *vertices; long i; double Lxy[4]; double lab[4]; McoStatus state; TQ3ColorRGB color = { 0.0, 0.0, 0.0 }; double big_ab,big_rgb; TQ3Param2D param2D; ciepoly.numVertices = NumCIExyzRef; ciepoly.vertices = (TQ3Vertex3D *) NewPtr (NumCIExyzRef * sizeof(TQ3Vertex3D)); if (ciepoly.vertices == NULL) return NULL; vertices = ciepoly.vertices; ciepoly.polygonAttributeSet = NULL; for (i=0; i<NumCIExyzRef; i++) { Lxy[0] = 50; Lxy[1] = CIExyzRef2[i*4+1]; Lxy[2] = CIExyzRef2[i*4+2]; vertices[i].point.x = Lxy[1]; vertices[i].point.y = Lxy[2]; vertices[i].point.z = 0.5; sxyztolab(Lxy,lab); big_ab = bigger(fabs(lab[1]),fabs(lab[2])); if (big_ab>127) { lab[1] = lab[1]*127/big_ab; lab[2] = lab[2]*127/big_ab; } labtonxyzinplace(lab,1); state = xyztorgb->compute(lab, monitor_z, 1); if(state != MCO_SUCCESS) return NULL; big_rgb = bigger(lab[1],bigger(lab[2],lab[3])); if (big_rgb>255) { lab[0] = lab[0]*255/big_rgb; lab[1] = lab[1]*255/big_rgb; lab[2] = lab[2]*255/big_rgb; } color.r = lab[0]/256; color.g = lab[1]/256; color.b = lab[2]/256; vertices[i].attributeSet = Q3AttributeSet_New(); Q3AttributeSet_Add(vertices[i].attributeSet, kQ3AttributeTypeDiffuseColor, &color); param2D.u = Lxy[1]*1.37; param2D.v = Lxy[2]*1.1; Q3AttributeSet_Add(vertices[i].attributeSet, kQ3AttributeTypeShadingUV, ¶m2D); } geometryObject = Q3Polygon_New(&ciepoly); for (i = 0; i < NumCIExyzRef; i++) Q3Object_Dispose(vertices[i].attributeSet); DisposePtr ((char *) vertices); return geometryObject; }