Created
November 5, 2013 05:10
-
-
Save borisbat/7314207 to your computer and use it in GitHub Desktop.
instanceNodes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/////////////////////////////////////////// | |
// parse library_visual_scenes (nodes) here | |
void importDaeNodeArray ( const pugi::xpath_node_set & nodes, vector<NodePtr> & outNodes, const WeakNodePtr & parent ) | |
{ | |
using namespace pugi; | |
if ( nodes.size()==0 ) | |
return; | |
outNodes.resize(nodes.size()); | |
for ( unsigned int ni=0; ni<nodes.size(); ni++ ) | |
{ | |
const xml_node & node = nodes[ni].node(); | |
NodePtr pNode(new Node()); | |
outNodes[ni] = pNode; | |
pNode->mParent = parent; | |
pNode->mDae = mpDae->shared_from_this(); | |
pNode->mId = node.attribute("id").value(); | |
pNode->mName = node.attribute("name").value(); | |
if ( node.attribute("id") ) | |
mpDae->mNodeId2Node[pNode->mId] = pNode; | |
// check if its joint | |
pNode->mIsJoint = string(node.attribute("type").value()) == "JOINT"; | |
// sid | |
// note: according to Remi, its "ass id" | |
if ( node.attribute("sid") ) | |
if ( nodeSid2Node.find(node.attribute("sid").value())==nodeSid2Node.end() ) | |
nodeSid2Node[node.attribute("sid").value()] = pNode; | |
else | |
Log() << TAG::ERROR() << "duplicate node sid=" << node.attribute("sid").value() << TAG::_ERROR() << endl; | |
// transforms | |
auto arm = node.select_nodes("matrix"); | |
for ( unsigned int mi=0; mi<arm.size(); mi++ ) | |
{ | |
float4x4simd matrix; | |
const char * matrix_ptr = arm[mi].node().child_value(); | |
parseMatrix ( matrix, matrix_ptr ); | |
// TODO: verify order | |
float4x4simd nodeMulMatrix; | |
Mul ( nodeMulMatrix, matrix, pNode->transform ); | |
pNode->transform = nodeMulMatrix; | |
} | |
auto art = node.select_nodes( "translate" ); | |
for ( unsigned int ti=0; ti<art.size(); ti++ ) | |
{ | |
const char * translate_ptr = art[ti].node().child_value(); | |
float x = strtof( translate_ptr, &translate_ptr ); | |
float y = strtof( translate_ptr, &translate_ptr ); | |
float z = strtof( translate_ptr, &translate_ptr ); | |
float4x4simd matrix; | |
Translation(matrix, x, y, z ); | |
float4x4simd nodeMulMatrix; | |
Mul ( nodeMulMatrix, matrix, pNode->transform ); | |
pNode->transform = nodeMulMatrix; | |
} | |
auto arr = node.select_nodes( "rotate" ); | |
for ( unsigned int ri=0; ri<arr.size(); ri++ ) | |
{ | |
const char * rotate_ptr = arr[ri].node().child_value(); | |
float x = strtof( rotate_ptr, &rotate_ptr ); | |
float y = strtof( rotate_ptr, &rotate_ptr ); | |
float z = strtof( rotate_ptr, &rotate_ptr ); | |
float w = strtof( rotate_ptr, &rotate_ptr ); | |
float4x4simd matrix; | |
RotationAxis(matrix, Float4simd(x, y, z, 0), Degree2Rad(w) ); | |
float4x4simd nodeMulMatrix; | |
Mul ( nodeMulMatrix, matrix, pNode->transform ); | |
pNode->transform = nodeMulMatrix; | |
} | |
auto ars = node.select_nodes( "scale" ); | |
for ( unsigned int si=0; si<ars.size(); si++ ) | |
{ | |
const char * scale_ptr = ars[si].node().child_value(); | |
float x = strtof( scale_ptr, &scale_ptr ); | |
float y = strtof( scale_ptr, &scale_ptr ); | |
float z = strtof( scale_ptr, &scale_ptr ); | |
float4x4simd matrix; | |
Scale(matrix, x, y, z ); | |
float4x4simd nodeMulMatrix; | |
Mul ( nodeMulMatrix, matrix, pNode->transform ); | |
pNode->transform = nodeMulMatrix; | |
} | |
// instance geometries | |
auto geometries = node.select_nodes( "instance_geometry" ); | |
if ( geometries.size() ) | |
{ | |
pNode->mGeometries.resize(geometries.size()); | |
for ( unsigned int ig=0; ig<geometries.size(); ig++ ) | |
{ | |
// make new | |
InstanceGeometryPtr pInstanceGeometry(new InstanceGeometry()); | |
const xml_node & pig = geometries[ig].node(); | |
string geomId = string(pig.attribute( "url" ).value()).substr(1); | |
GeometryMap::const_iterator itg = geometryId2Geometry.find(geomId); | |
if ( itg!=geometryId2Geometry.end() ) | |
{ | |
pInstanceGeometry->mpGeometry = itg->second; | |
GeometryPtr pGeom = pInstanceGeometry->mpGeometry.lock(); | |
const xml_node & pbm = pig.child("bind_material"); | |
if ( pGeom && pbm ) | |
bindGeomMaterials ( pGeom, pbm ); | |
} | |
else | |
Log() << TAG::WARNING() << "referring to unknown geometry " << geomId << TAG::_WARNING() << endl; | |
pNode->mGeometries[ig] = pInstanceGeometry; | |
} | |
} | |
//handle all extras here | |
auto extras = node.select_nodes( "extra" ); | |
for ( unsigned int nExtra=0; nExtra<extras.size(); ++nExtra ) | |
{ | |
auto extra = extras[nExtra].node(); | |
auto techniques = extra.select_nodes( "technique" ); | |
for ( unsigned int nTechnique=0; nTechnique<techniques.size(); ++nTechnique ) | |
{ | |
auto technique = techniques[nTechnique].node(); | |
const char * techniqueProfile = technique.attribute( "profile" ).value(); | |
// handle fl4re technique | |
if ( stricmp(techniqueProfile, "fl4re") == 0 ) | |
{ | |
// instance audio objects | |
importDaeInstanceAudioObjects(technique, pNode); | |
importDaeNodeParticleSystem(technique, pNode); | |
} | |
} | |
} | |
// instance controllers | |
auto ika = node.select_nodes("instance_controller"); | |
if ( ika.size() ) | |
{ | |
pNode->mInstanceControllers.resize(ika.size()); | |
for ( unsigned int ink=0; ink<ika.size(); ink++ ) | |
{ | |
const xml_node & ikontroller = ika[ink].node(); | |
string url = string(ikontroller.attribute("url").value()).substr(1); | |
if ( url.size() ) | |
{ | |
InstanceControllerPtr pInstController ( new InstanceController() ); | |
pInstController->mControllerId = url; | |
// lookup controller | |
ControllerMap::iterator it = controllerId2Controller.find(pInstController->mControllerId); | |
if ( it!=controllerId2Controller.end() ) | |
{ | |
pInstController->mpController = it->second; | |
GeometryPtr pGeom = pInstController->mpController.lock()->mpGeometry.lock(); | |
const xml_node & pbm = ikontroller.child("bind_material"); | |
if ( pGeom && pbm ) | |
bindGeomMaterials ( pGeom, pbm ); | |
} | |
else | |
Log() << TAG::ERROR() << "undefined controller instance " << pInstController->mControllerId << TAG::_ERROR() << endl; | |
// we good | |
pNode->mInstanceControllers[ink] = pInstController; | |
} | |
else | |
{ | |
Log() << TAG::ERROR() << "instance controller with garbage url" << TAG::_ERROR() << endl; | |
} | |
} | |
} | |
// | |
// TODO: | |
// | |
// bellow are 3 identical loops | |
// they vary in few different ways, but the code is very common | |
// it would be nice to turn it into more or less one function | |
// it should handle dependencies for cameras and lights too | |
// it should allow external file cameras and lights | |
// basically very similar to that node goo | |
// | |
// instance nodes | |
auto ina = node.select_nodes("instance_node"); | |
if ( ina.size() ) | |
{ | |
// lets see how many non-garbage ones are there | |
for ( unsigned int ini=0; ini<ina.size(); ini++ ) | |
{ | |
const xml_node & inode = ina[ini].node(); | |
string url = string(inode.attribute("url").value()); | |
if ( url.size() ) | |
{ | |
Uri daeUri = resolveUri( Uri(url) ); | |
Uri strippedUri = daeUri.stripped(); | |
// ok, lets test if its really local dependency | |
// TODO: we need to resolve it right here, right? | |
if ( strippedUri!=mpDae->mUri ) | |
dependencies.insert(strippedUri); | |
InstanceNodePtr inp ( new InstanceNode() ); | |
inp->mDaeUri = strippedUri; | |
inp->mNodeId = daeUri.getFragment(); | |
pNode->mInstanceNodes.push_back(inp); | |
} | |
} | |
} | |
// instance cameras | |
auto ica = node.select_nodes("instance_camera"); | |
if ( ica.size() ) | |
{ | |
pNode->mInstanceCameras.resize(ica.size()); | |
for ( unsigned int inc=0; inc<ica.size(); inc++ ) | |
{ | |
const xml_node & icamera = ica[inc].node(); | |
string url = string(icamera.attribute("url").value()).substr(1); | |
if ( url.size() ) | |
{ | |
InstanceCameraPtr pInstCam ( new InstanceCamera() ); | |
pInstCam->mCameraId = url; | |
// lookup camera | |
CameraMap::iterator it = cameraId2Camera.find(pInstCam->mCameraId); | |
if ( it!=cameraId2Camera.end() ) | |
pInstCam->mpCamera = it->second; | |
// we good | |
pNode->mInstanceCameras[inc] = pInstCam; | |
} | |
else | |
{ | |
Log() << TAG::ERROR() << "instance camera with garbage url " << TAG::_ERROR() << endl; | |
} | |
} | |
} | |
// instance lights | |
auto ila = node.select_nodes( "instance_light" ); | |
if ( ila.size() ) | |
{ | |
pNode->mInstanceLights.resize(ila.size()); | |
for ( unsigned int inl=0; inl<ila.size(); inl++ ) | |
{ | |
const xml_node & ilight = ila[inl].node(); | |
string url = string(ilight.attribute("url").value()).substr(1); | |
if ( url.size() ) | |
{ | |
InstanceLightPtr pInstLight ( new InstanceLight() ); | |
pInstLight->mLightId = url; | |
// lookup light | |
LightMap::iterator it = lightId2Light.find(pInstLight->mLightId); | |
if ( it!=lightId2Light.end() ) | |
pInstLight->Set ( it->second ); | |
else | |
Log() << TAG::ERROR() << "undefined light instance " << pInstLight->mLightId << TAG::_ERROR() << endl; | |
// we good | |
pNode->mInstanceLights[inl] = pInstLight; | |
} | |
else | |
{ | |
Log() << TAG::ERROR() << "instance light with garbage url" << TAG::_ERROR() << endl; | |
} | |
} | |
} | |
// Log() << "Node " << pNode->mId << ", " << pNode->mName << endl << JsValue(pNode->transform) << endl; | |
// recursively import | |
importDaeNodeArray(node.select_nodes("node"), pNode->mChildren, pNode); | |
// build mesh-and-style pairs | |
// as well as bounding boxes | |
pNode->BuildMeshAndStyleInfo(); | |
// BBATKIN: SPEAKER!!! | |
/* | |
<extra> | |
<technique profile="fl4re"> | |
<param name="group_id" type="int">4</param> | |
</technique> | |
</extra> | |
*/ | |
if ( const xml_node& extra = node.child("extra") ) | |
{ | |
if ( const xml_node& technique = extra.child("technique") ) | |
{ | |
string profile = technique.attribute("profile").value(); | |
if ( profile=="fl4re" ) | |
{ | |
SpeakerProfilePtr pSpeaker = make_shared<SpeakerProfile>(); | |
pSpeaker->mNodeId = pNode->mId; | |
auto params = technique.select_nodes("param"); | |
if ( params.size()) | |
{ | |
for ( unsigned int pi=0; pi<params.size(); pi++ ) | |
{ | |
const xml_node & param = params[pi].node(); | |
if ( auto name = param.attribute("name") ) | |
{ | |
string paramname = name.value(); | |
if ( paramname=="group_id" ) | |
{ | |
pSpeaker->mGroupId = stoi ( param.child_value() ); | |
} | |
else if ( paramname=="type" ) | |
{ | |
pSpeaker->mSpeaker = param.child_value(); | |
} | |
} | |
} | |
} | |
if ( pSpeaker->mGroupId >= 0 ) | |
mpDae->mLibrarySpeakerProfiles.push_back(pSpeaker); | |
} | |
} | |
} | |
} | |
} | |
void importDaeLibraryNodes ( pugi::xml_node & lnd ) | |
{ | |
if ( !lnd ) | |
return; | |
importDaeNodeArray ( lnd.select_nodes("node"), mpDae->mLibraryNodes, WeakNodePtr() ); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment