//----------------------------------------------------------------------------- CPUTAssetSet *CPUTAssetSet::Create( const std::string &name, const std::string &absolutePathAndFilename, int numSystemMaterials, std::string *pSystemMaterialNames ) { CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary(); // Create the root node. CPUTNullNode *pRootNode = CPUTNullNode::Create(); pRootNode->SetName("_CPUTAssetSetRootNode_"); // Create the asset set, set its root, and load it CPUTAssetSet *pNewAssetSet = new CPUTAssetSet(); pNewAssetSet->IsEnabled = true; pNewAssetSet->SetRoot( pRootNode ); pAssetLibrary->AddNullNode( name, "", "_Root", pRootNode ); CPUTResult result = pNewAssetSet->LoadAssetSet(absolutePathAndFilename, numSystemMaterials, pSystemMaterialNames); if( CPUTSUCCESS(result) ) { pAssetLibrary->AddAssetSet(name, "", "", pNewAssetSet); return pNewAssetSet; } ASSERT( CPUTSUCCESS(result), "Error loading AssetSet\n'"+absolutePathAndFilename+"'"); pNewAssetSet->Release(); return NULL; }
//----------------------------------------------------------------------------- CPUTResult CPUTAssetSet::LoadAssetSet(std::string name, int numSystemMaterials, std::string *pSystemMaterialNames) { CPUTResult result = CPUT_SUCCESS; // if not found, load the set file CPUTConfigFile ConfigFile; result = ConfigFile.LoadFile(name); if( !CPUTSUCCESS(result) ) { return result; } // ASSERT( CPUTSUCCESS(result), "Failed loading set file '" + name + "'." ); mAssetCount = ConfigFile.BlockCount() + 1; // Add one for the implied root node mppAssetList = new CPUTRenderNode*[mAssetCount]; mppAssetList[0] = mpRootNode; mpRootNode->AddRef(); CPUTAssetLibrary *pAssetLibrary = (CPUTAssetLibrary*)CPUTAssetLibrary::GetAssetLibrary(); CPUTAnimation *pDefaultAnimation = NULL; for(UINT ii=0; ii<mAssetCount-1; ii++) // Note: -1 because we added one for the root node (we don't load it) { CPUTConfigBlock *pBlock = ConfigFile.GetBlock(ii); ASSERT(pBlock != NULL, "Cannot find block"); if( !pBlock ) { return CPUT_ERROR_PARAMETER_BLOCK_NOT_FOUND; } std::string nodeType = pBlock->GetValueByName("type")->ValueAsString(); CPUTRenderNode *pParentNode = NULL; // TODO: use Get*() instead of Load*() ? std::string name = pBlock->GetValueByName("name")->ValueAsString(); int parentIndex; CPUTRenderNode *pNode = NULL; if(0==nodeType.compare("null")) { pNode = pNode = CPUTNullNode::Create(); result = ((CPUTNullNode*)pNode)->LoadNullNode(pBlock, &parentIndex); pParentNode = mppAssetList[parentIndex+1]; std::string &parentPrefix = pParentNode->GetPrefix(); std::string prefix = parentPrefix; prefix.append("."); prefix.append(name); pNode->SetPrefix(prefix); // pNode->SetPrefix( parentPrefix + "." + name ); pAssetLibrary->AddNullNode("", parentPrefix + name, "", (CPUTNullNode*)pNode); // Add this null's name to our prefix // Append this null's name to our parent's prefix pNode->SetParent( pParentNode ); pParentNode->AddChild( pNode ); } else if(0==nodeType.compare("model")) { CPUTConfigEntry *pValue = pBlock->GetValueByName( "instance" ); CPUTModel *pModel = CPUTModel::Create(); if( pValue == &CPUTConfigEntry::sNullConfigValue ) { // Not found. So, not an instance. pModel->LoadModel(pBlock, &parentIndex, NULL, numSystemMaterials, pSystemMaterialNames); } else { int instance = pValue->ValueAsInt(); // If the current node is an instance of itself then it has no "master" model if(ii == instance) { // TODO: create instance model object pModel->LoadModel(pBlock, &parentIndex, NULL, numSystemMaterials, pSystemMaterialNames); } else { pModel->LoadModel(pBlock, &parentIndex, (CPUTModel*)mppAssetList[instance+1], numSystemMaterials, pSystemMaterialNames); } } pParentNode = mppAssetList[parentIndex+1]; pModel->SetParent( pParentNode ); pParentNode->AddChild( pModel ); std::string &parentPrefix = pParentNode->GetPrefix(); pModel->SetPrefix( parentPrefix ); pAssetLibrary->AddModel(name, parentPrefix, "", pModel); pModel->UpdateBoundsWorldSpace(); #ifdef SUPPORT_DRAWING_BOUNDING_BOXES // Create a mesh for rendering the bounding box // TODO: There is definitely a better way to do this. But, want to see the bounding boxes! pModel->CreateBoundingBoxMesh(); #endif pNode = pModel; } else if(0==nodeType.compare("light")) { pNode = CPUTLight::Create(); ((CPUTLight*)pNode)->LoadLight(pBlock, &parentIndex); pParentNode = mppAssetList[parentIndex+1]; // +1 because we added a root node to the start pNode->SetParent( pParentNode ); pParentNode->AddChild( pNode ); std::string &parentPrefix = pParentNode->GetPrefix(); pNode->SetPrefix( parentPrefix ); pAssetLibrary->AddLight(name, parentPrefix, "", (CPUTLight*)pNode); } else if(0==nodeType.compare("camera")) { pNode = CPUTCamera::Create(CPUT_PERSPECTIVE); ((CPUTCamera*)pNode)->LoadCamera(pBlock, &parentIndex); pParentNode = mppAssetList[parentIndex+1]; // +1 because we added a root node to the start pNode->SetParent( pParentNode ); pParentNode->AddChild( pNode ); std::string &parentPrefix = pParentNode->GetPrefix(); pNode->SetPrefix( parentPrefix ); pAssetLibrary->AddCamera(name, parentPrefix, "", (CPUTCamera*)pNode); if( !mpFirstCamera ) { mpFirstCamera = (CPUTCamera*)pNode; mpFirstCamera->AddRef();} ++mCameraCount; } else { ASSERT(0,"Unsupported node type '" + nodeType + "'."); } CPUTConfigEntry *pAnimValue = pBlock->GetValueByName( "Animation0" ); //int autoPlayAnimationIndex = pBlock->GetValueByName( "DefaultAnimation" ); for(int i = 1; pAnimValue != &CPUTConfigEntry::sNullConfigValue; ++i ) { CPUTAnimation *pCurrentAnimation = pAssetLibrary->GetAnimation(pAnimValue->ValueAsString()); //First Animation will be default for now if(pCurrentAnimation != NULL && i == 1 /*autoPlayAnimationIndex*/) { pDefaultAnimation = pCurrentAnimation ; pCurrentAnimation->AddRef(); } std::stringstream animName; animName << "Animation" << i; pAnimValue = pBlock->GetValueByName(animName.str()); pNode->mAnimationList.push_back(pCurrentAnimation); } // Add the node to our asset list (i.e., the linear list, not the hierarchical) mppAssetList[ii+1] = pNode; // Don't AddRef.Creating it set the refcount to 1. We add it to the list, and then we're done with it. // Net effect is 0 (+1 to add to list, and -1 because we're done with it) // pNode->AddRef(); } //Set the default animation to the current Asset Set if(pDefaultAnimation != NULL && mAssetCount > 1) { //Apply Animation to root of the setfile mppAssetList[1]->SetAnimation(pDefaultAnimation); } SAFE_RELEASE(pDefaultAnimation); return result; }