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); }
CQ3ObjectRef Duplicator::DuplicateDisplayGroup( TQ3Object inGroup ) { CQ3ObjectRef theDupe; if (Q3Object_IsType( inGroup, kQ3DisplayGroupTypeOrdered )) { theDupe = CQ3ObjectRef( Q3OrderedDisplayGroup_New() ); } else { theDupe = CQ3ObjectRef( Q3DisplayGroup_New() ); } // Copy the display group state TQ3DisplayGroupState theState; Q3DisplayGroup_GetState( inGroup, &theState ); Q3DisplayGroup_SetState( theDupe.get(), theState ); // Duplicate the objects belonging to the group Q3GroupIterator iter( inGroup ); CQ3ObjectRef theItem; while ( (theItem = iter.NextObject()).isvalid() ) { CQ3ObjectRef itemDupe( Duplicate( theItem.get() ) ); Q3Group_AddObject( theDupe.get(), itemDupe.get() ); } return theDupe; }
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 TQ3GroupObject QD3DSupport_NewTrackGroup(TQ3ShaderObject theShader) { TQ3GroupObject myGroup = NULL; if ((myGroup = Q3OrderedDisplayGroup_New()) != NULL ) { TQ3GroupPosition myGroupPosition; /* ADD TEXTURE SHADER OBJECT TO GROUP */ myGroupPosition = Q3Group_AddObject(myGroup, theShader); if ( myGroupPosition == nil ) { Utils_DisplayErrorMsg("Group_AddObject failed!"); } } /* Done! */ return ( myGroup ); }
//------------------------------------------------------------------------------------------- // 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; }
/*! @function TransformSeparatorV1ToObject @abstract Attempt to convert a VRML 1 TransformSeparator node to a Quesa object. @param ioNode Node to convert. @param inReader The reader object. @result An object reference, or NULL on failure. */ CQ3ObjectRef TransformSeparatorV1ToObject( PolyValue& ioNode, CVRMLReader& inReader ) { CQ3ObjectRef theGroup; PolyValue::Dictionary& nodeDict( ioNode.GetDictionary() ); if (IsKeyPresent( nodeDict, "children" )) { PolyValue& childrenNode( nodeDict["children"] ); if (childrenNode.GetType() == PolyValue::kDataTypeArray) { PolyValue::PolyVec& childVec( childrenNode.GetPolyVec() ); if (not childVec.empty()) { theGroup = CQ3ObjectRef( Q3DisplayGroup_New() ); ThrowIfNullQuesaOb_( theGroup ); for (PolyValue::PolyVec::iterator i = childVec.begin(); i != childVec.end(); ++i) { CQ3ObjectRef aChild( NodeV1ToObject( *i, inReader ) ); if (aChild.isvalid()) { Q3Group_AddObject( theGroup.get(), aChild.get() ); } } // If this Separator was named with DEF, set that as the name of the // Quesa object. if (IsKeyPresent( nodeDict, "[name]" )) { PolyValue& nameValue( nodeDict["[name]"] ); const std::string& theName( nameValue.GetString() ); ::CENameElement_SetData( theGroup.get(), theName.c_str() ); } } } } return theGroup; }
/*! @function CylinderV1ToObject @abstract Attempt to convert a VRML 1 Cylinder node to a Quesa object. @param ioNode Node to convert. @param inReader The reader object. @result An object reference, or NULL on failure. */ CQ3ObjectRef CylinderV1ToObject( PolyValue& ioNode, CVRMLReader& inReader ) { CQ3ObjectRef theCylinder; PolyValue::Dictionary& theDict( ioNode.GetDictionary() ); float radius = 1.0f; if (IsKeyPresent( theDict, "radius" )) { radius = theDict["radius"].GetFloat(); } float height = 2.0f; if (IsKeyPresent( theDict, "height" )) { height = theDict["height"].GetFloat(); } int partsMask = eVRML1Parts_ALL; if (IsKeyPresent( theDict, "parts" )) { partsMask = theDict["parts"].GetInt(); } bool hasBottom = ((partsMask & eVRML1Parts_BOTTOM) != 0); bool hasTop = ((partsMask & eVRML1Parts_TOP) != 0); bool hasSides = ((partsMask & eVRML1Parts_SIDES) != 0); int curMaterialBinding = inReader.GetVRML1State().materialBinding; bool isMultiColored = (curMaterialBinding == eVRML1Value_PER_PART) or (curMaterialBinding == eVRML1Value_PER_PART_INDEXED); TQ3CylinderData cylData = { { 0.0f, -height/2, 0.0f }, { 0.0f, height, 0.0f }, { 0.0f, 0.0f, radius }, { radius, 0.0f, 0.0f }, 0.0f, 1.0f, 0.0f, 1.0f, 0, NULL, NULL, NULL, NULL, NULL }; CQ3ObjectRef sideColor, bottomColor, topColor, allColor; if (isMultiColored) { sideColor = GetIndexedMaterial( inReader, 0 ); topColor = GetIndexedMaterial( inReader, 1 ); bottomColor = GetIndexedMaterial( inReader, 2 ); } else { allColor = GetIndexedMaterial( inReader, 0 ); } if (hasSides) { if (isMultiColored) { cylData.topAttributeSet = topColor.get(); cylData.faceAttributeSet = sideColor.get(); cylData.bottomAttributeSet = bottomColor.get(); } else { cylData.cylinderAttributeSet = allColor.get(); } if (hasTop) { cylData.caps |= kQ3EndCapMaskTop; } if (hasBottom) { cylData.caps |= kQ3EndCapMaskBottom; } theCylinder = CQ3ObjectRef( Q3Cylinder_New( &cylData ) ); } else if (hasTop or hasBottom) { theCylinder = CQ3ObjectRef( Q3DisplayGroup_New() ); ThrowIfNullQuesaOb_( theCylinder ); if (hasTop) { TQ3DiskData topData = { { 0.0f, height/2, 0.0f }, { 0.0f, 0.0f, radius }, { radius, 0.0f, 0.0f }, 0.0f, 1.0f, 0.0f, 1.0f, NULL }; if (isMultiColored) { topData.diskAttributeSet = topColor.get(); } else { topData.diskAttributeSet = allColor.get(); } CQ3ObjectRef topDisk( Q3Disk_New( &topData ) ); ThrowIfNullQuesaOb_( topDisk ); Q3Group_AddObject( theCylinder.get(), topDisk.get() ); } if (hasBottom) { TQ3DiskData bottomData = { { 0.0f, -height/2, 0.0f }, { radius, 0.0f, 0.0f }, { 0.0f, 0.0f, radius }, 0.0f, 1.0f, 0.0f, 1.0f, NULL }; if (isMultiColored) { bottomData.diskAttributeSet = bottomColor.get(); } else { bottomData.diskAttributeSet = allColor.get(); } CQ3ObjectRef bottomDisk( Q3Disk_New( &bottomData ) ); ThrowIfNullQuesaOb_( bottomDisk ); Q3Group_AddObject( theCylinder.get(), bottomDisk.get() ); } } return theCylinder; }
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 ); }
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 ); }
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; }
// 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; }
/*! @function IndexedLineSetV1ToObject @abstract Attempt to convert a VRML 1 IndexedLineSet node to a Quesa object. @param ioNode Node to convert. @param inReader The reader object. @result An object reference, or NULL on failure. */ CQ3ObjectRef IndexedLineSetV1ToObject( PolyValue& ioNode, CVRMLReader& inReader ) { CQ3ObjectRef theObject( Q3DisplayGroup_New() ); ThrowIfNullQuesaOb_( theObject ); PolyValue::Dictionary& theDict( ioNode.GetDictionary() ); int polylineNum = 0; // I am not going to bother with normals, so it is better not to use lighting. CQ3ObjectRef theShader( Q3NULLIllumination_New() ); ThrowIfNullQuesaOb_( theShader ); Q3Group_AddObject( theObject.get(), theShader.get() ); // Gather data PolyValue::IntVec pointIndices; PolyValue::IntVec colorIndices; GetIntVecFromField( theDict, "coordIndex", pointIndices ); GetIntVecFromField( theDict, "materialIndex", colorIndices ); StandardizeIndexVector( pointIndices ); StandardizeIndexVector( colorIndices ); const SVRML1State& theState( inReader.GetVRML1State() ); const std::vector<TQ3Point3D>& thePoints( theState.coordinate3 ); const std::vector<TQ3ColorRGB>& theColors( theState.diffuseColor ); bool isColorPerVertex( (theState.materialBinding == eVRML1Value_PER_VERTEX) or (theState.materialBinding == eVRML1Value_PER_VERTEX_INDEXED) ); // Note: the VRML 1 spec, unlike the VRML 2 spec, indicates that colors // can be per segment rather than per polyline. Currently I will not // support that. bool isColorPerPolyline( (theState.materialBinding == eVRML1Value_PER_PART) or (theState.materialBinding == eVRML1Value_PER_PART_INDEXED) or (theState.materialBinding == eVRML1Value_PER_FACE) or (theState.materialBinding == eVRML1Value_PER_FACE_INDEXED) ); // Start building polylines std::vector<TQ3Vertex3D> vertices; std::vector<CQ3ObjectRef> vertAttSets; for (unsigned int i = 0; i < pointIndices.size(); ++i) { if (pointIndices[i] < 0) { // FInish a PolyLine TQ3PolyLineData polyData; polyData.numVertices = vertices.size(); polyData.vertices = &vertices[0]; polyData.segmentAttributeSet = NULL; CQ3ObjectRef polyAtts; if (not theColors.empty()) { polyAtts = GetIndexedMaterial( inReader, 0 ); if (isColorPerPolyline) { TQ3ColorRGB polyColor; if (colorIndices.empty()) { polyColor = theColors[ polylineNum ]; } else { polyColor = theColors[ colorIndices[polylineNum] ]; } Q3AttributeSet_Add( polyAtts.get(), kQ3AttributeTypeDiffuseColor, &polyColor ); } polyData.polyLineAttributeSet = polyAtts.get(); } else { polyData.polyLineAttributeSet = NULL; } CQ3ObjectRef polyLine( Q3PolyLine_New( &polyData ) ); ThrowIfNullQuesaOb_( polyLine ); Q3Group_AddObject( theObject.get(), polyLine.get() ); vertices.clear(); vertAttSets.clear(); polylineNum += 1; } else { TQ3Vertex3D aVertex; aVertex.point = thePoints[ pointIndices[i] ]; if (isColorPerVertex and (not theColors.empty())) { TQ3ColorRGB vertColor; if (colorIndices.empty()) { vertColor = theColors[ pointIndices[i] ]; } else { vertColor = theColors[ colorIndices[i] ]; } CQ3ObjectRef vertAtts( Q3AttributeSet_New() ); ThrowIfNullQuesaOb_( vertAtts ); Q3AttributeSet_Add( vertAtts.get(), kQ3AttributeTypeDiffuseColor, &vertColor ); vertAttSets.push_back( vertAtts ); aVertex.attributeSet = vertAtts.get(); } else { aVertex.attributeSet = NULL; } vertices.push_back( aVertex ); } } if (polylineNum == 0) { // no sense returning an empty display group theObject = CQ3ObjectRef(); } return theObject; }
static TQ3Boolean parse3DStudioCallback (TobjectManagerCmd cmd, void *cmdData, void *userData) { TE3FFormat_3ds_Data *instanceData = (TE3FFormat_3ds_Data *)userData; if (instanceData == NULL) { return (kQ3False); } switch (cmd) { case kParseBegin: instanceData->model = Q3DisplayGroup_New (); break; #ifdef LATER case kNewMaterial: { TmaterialData *materialData = (TmaterialData *)cmdData; RtMaterial *material = new RtMaterial; material->name = materialData->name; materialData->name = NULL; material->specularcolor = materialData->specularcolor; material->Cs = materialData->Cs; material->Os = materialData->Os; material->texturename = materialData->texturename; materialData->texturename = NULL; material->id = materialData->id; materialData->id = NULL; material->next = TparseScene::fsMaterialList->next; TparseScene::fsMaterialList->next = material; } break; #endif case kNewPointsPolygon: { unsigned int t; TpointsPolygonData *polygonData = (TpointsPolygonData *)cmdData; TQ3TriMeshData triMeshData; TQ3GeometryObject triMesh; // Set up the data triMeshData.triMeshAttributeSet = NULL; triMeshData.numTriangles = polygonData->npolys; triMeshData.triangles = (TQ3TriMeshTriangleData *)(polygonData->verts); triMeshData.numPoints = 0; for (t = 0; t < triMeshData.numTriangles; t++) { TQ3TriMeshTriangleData *triangleData = triMeshData.triangles + t; if (triangleData->pointIndices[0] > triMeshData.numPoints) triMeshData.numPoints = triangleData->pointIndices[0]; if (triangleData->pointIndices[1] > triMeshData.numPoints) triMeshData.numPoints = triangleData->pointIndices[1]; if (triangleData->pointIndices[2] > triMeshData.numPoints) triMeshData.numPoints = triangleData->pointIndices[2]; } triMeshData.numPoints++; triMeshData.points = (TQ3Point3D *)(polygonData->Ppointer); triMeshData.numTriangleAttributeTypes = 0; triMeshData.triangleAttributeTypes = NULL; triMeshData.numEdges = 0; triMeshData.edges = NULL; triMeshData.numEdgeAttributeTypes = 0; triMeshData.edgeAttributeTypes = NULL; triMeshData.numVertexAttributeTypes = 0; triMeshData.vertexAttributeTypes = NULL; Q3BoundingBox_SetFromPoints3D (&triMeshData.bBox, triMeshData.points, triMeshData.numPoints, sizeof(TQ3Point3D)); triMesh = Q3TriMesh_New (&triMeshData); Q3Group_AddObject (instanceData->model, triMesh); Q3Object_Dispose (triMesh); } break; #ifdef LATER case kNewLight: { TpointsPolygonData *polygonData = (TpointsPolygonData *)cmdData; RtNodeData *node = new RtNodeData; node->name = polygonData->name; polygonData->name = NULL; node->nodeType = RtNodeData::kLightNode; TparseScene::fsWorld->addObject (node); } break; case kNewCamera: { TpointsPolygonData *polygonData = (TpointsPolygonData *)cmdData; RtNodeData *node = new RtNodeData; node->name = polygonData->name; polygonData->name = NULL; node->nodeType = RtNodeData::kCameraNode; TcameraData *cameraData = (TcameraData *)(polygonData->hanger); if (cameraData != NULL) { RtCameraData *camera = new RtCameraData; camera->setEye (cameraData->eyePt); camera->setView (cameraData->viewPt); camera->setTwist (cameraData->twist); if ((me->fCamera != NULL) && !me->fCameraSet) { *me->fCamera = *camera; me->fCameraSet = RI_TRUE; } node->hanger = camera; } TparseScene::fsWorld->addObject (node); } break; #endif case kParseDone: // RtMaterial::destroy (TparseScene::fsMaterialList); // TparseScene::fsMaterialList = NULL; break; } return (kQ3True); }
/*! @function IndexedLineSetV2ToObject @abstract Attempt to convert a VRML 2 IndexedLineSet node to a Quesa object. @param ioNode Node to convert. @param inReader The reader object. @result An object reference, or NULL on failure. */ CQ3ObjectRef IndexedLineSetV2ToObject( PolyValue& ioNode ) { CQ3ObjectRef theObject( Q3DisplayGroup_New() ); ThrowIfNullQuesaOb_( theObject ); // The VRML 2 spec says that lines are not lit. CQ3ObjectRef theShader( Q3NULLIllumination_New() ); ThrowIfNullQuesaOb_( theShader ); Q3Group_AddObject( theObject.get(), theShader.get() ); PolyValue::Dictionary& theDict( ioNode.GetDictionary() ); // Gather data from fields std::vector<TQ3Point3D> thePoints; std::vector<TQ3ColorRGB> theColors; PolyValue::IntVec pointIndices; PolyValue::IntVec colorIndices; GetNodeArray( theDict, "coord", "Coordinate", "point", thePoints ); GetNodeArray( theDict, "color", "Color", "color", theColors ); GetIntVecFromField( theDict, "coordIndex", pointIndices ); GetIntVecFromField( theDict, "colorIndex", colorIndices ); StandardizeIndexVector( pointIndices ); StandardizeIndexVector( colorIndices ); bool isColorPerVertex = true; if (IsKeyPresent( theDict, "colorPerVertex" )) { PolyValue& theNode( theDict[ "colorPerVertex" ] ); if (theNode.GetType() == PolyValue::kDataTypeBool) { isColorPerVertex = theNode.GetBool(); } } // Start building polylines std::vector<TQ3Vertex3D> vertices; std::vector<CQ3ObjectRef> vertAttSets; int polylineNum = 0; for (unsigned int i = 0; i < pointIndices.size(); ++i) { if (pointIndices[i] < 0) { // FInish a PolyLine TQ3PolyLineData polyData; polyData.numVertices = vertices.size(); polyData.vertices = &vertices[0]; polyData.segmentAttributeSet = NULL; CQ3ObjectRef polyAtts; if ((not isColorPerVertex) and (not theColors.empty())) { TQ3ColorRGB polyColor; if (colorIndices.empty()) { polyColor = theColors[ polylineNum ]; } else { polyColor = theColors[ colorIndices[polylineNum] ]; } polyAtts = CQ3ObjectRef( Q3AttributeSet_New() ); ThrowIfNullQuesaOb_( polyAtts ); Q3AttributeSet_Add( polyAtts.get(), kQ3AttributeTypeDiffuseColor, &polyColor ); polyData.polyLineAttributeSet = polyAtts.get(); } else { polyData.polyLineAttributeSet = NULL; } CQ3ObjectRef polyLine( Q3PolyLine_New( &polyData ) ); ThrowIfNullQuesaOb_( polyLine ); Q3Group_AddObject( theObject.get(), polyLine.get() ); vertices.clear(); vertAttSets.clear(); polylineNum += 1; } else { TQ3Vertex3D aVertex; aVertex.point = thePoints[ pointIndices[i] ]; if (isColorPerVertex and (not theColors.empty())) { TQ3ColorRGB vertColor; if (colorIndices.empty()) { vertColor = theColors[ pointIndices[i] ]; } else { vertColor = theColors[ colorIndices[i] ]; } CQ3ObjectRef vertAtts( Q3AttributeSet_New() ); ThrowIfNullQuesaOb_( vertAtts ); Q3AttributeSet_Add( vertAtts.get(), kQ3AttributeTypeDiffuseColor, &vertColor ); vertAttSets.push_back( vertAtts ); aVertex.attributeSet = vertAtts.get(); } else { aVertex.attributeSet = NULL; } vertices.push_back( aVertex ); } } if (polylineNum == 0) { // no sense returning an empty display group theObject = CQ3ObjectRef(); } return theObject; }