Пример #1
0
bool BodyLoaderImpl::extractShapeNodeTraverse
(VrmlNode* node, const Affine3& T, const function<bool(VrmlShape* shapeNode, const Affine3& T)>& callback)
{
    bool doContinue = true;
    
    if(node->isCategoryOf(PROTO_INSTANCE_NODE)){
        VrmlProtoInstance* protoInstance = static_cast<VrmlProtoInstance*>(node);
        if(protoInstance->actualNode){
            doContinue = extractShapeNodeTraverse(protoInstance->actualNode.get(), T, callback);
        }

    } else if(node->isCategoryOf(GROUPING_NODE)) {

        VrmlGroup* groupNode = static_cast<VrmlGroup*>(node);
        
        Affine3 T2;
        VrmlTransform* transformNode = dynamic_cast<VrmlTransform*>(groupNode);
        if(transformNode){
            T2 = T * transformNode->toAffine3d();
        }

        VrmlSwitch* switchNode = dynamic_cast<VrmlSwitch*>(node);
        if(switchNode){
            int whichChoice = switchNode->whichChoice;
            if(whichChoice >= 0 && whichChoice < switchNode->countChildren()){
                extractShapeNodeTraverse(switchNode->getChild(whichChoice), (transformNode ? T2 : T), callback);
            }
        } else {
            for(int i=0; i < groupNode->countChildren(); ++i){
                if(!extractShapeNodeTraverse(groupNode->getChild(i), (transformNode ? T2 : T), callback)){
                    doContinue = false;
                    break;
                }
            }
        }

    } else if(node->isCategoryOf(SHAPE_NODE)) {
        doContinue = callback(static_cast<VrmlShape*>(node), T);
    }

    return doContinue;
}
Пример #2
0
void ModelNodeSetImpl::extractChildNodes
(JointNodeSetPtr jointNodeSet, MFNode& childNodes, const ProtoIdSet acceptableProtoIds, const Matrix44& T)
{
    for(size_t i = 0; i < childNodes.size(); i++){
        VrmlNode* childNode = childNodes[i].get();
        const Matrix44* pT;
        if(childNode->isCategoryOf(GROUPING_NODE)){
            VrmlGroup* groupNode = static_cast<VrmlGroup*>(childNode);
            VrmlTransform* transformNode = dynamic_cast<VrmlTransform*>(groupNode);
            Matrix44 T2;
            if( transformNode ){
                Matrix44 Tlocal;
                calcTransformMatrix(transformNode, Tlocal);
                T2 = T * Tlocal;
                pT = &T2;
            } else {
                pT = &T;
            }
            extractChildNodes(jointNodeSet, groupNode->getChildren(), acceptableProtoIds, *pT);

        } else if(childNode->isCategoryOf(LIGHT_NODE)){
            jointNodeSet->lightNodes.push_back(std::make_pair(T,childNode));
        } else if(childNode->isCategoryOf(PROTO_INSTANCE_NODE)){

            VrmlProtoInstance* protoInstance = static_cast<VrmlProtoInstance*>(childNode);
            int id = PROTO_UNDEFINED;
            bool doTraverseChildren = false;
            ProtoIdSet acceptableChildProtoIds(acceptableProtoIds);

            const string& protoName = protoInstance->proto->protoName;
            ProtoNameToInfoMap::iterator p = protoNameToInfoMap.find(protoName);

            if(p == protoNameToInfoMap.end()){
                doTraverseChildren = true;
            } else {
                id = p->second.id;
                if(!acceptableProtoIds.test(id)){
                    throw ModelNodeSet::Exception(protoName + " node is not in a correct place.");
                }
            }

            messageIndent += 2;

            switch(id){
                
            case PROTO_JOINT:
                if(T != Matrix44::Identity())
                    throw ModelNodeSet::Exception(protoName + " node is not in a correct place.");
                jointNodeSet->childJointNodeSets.push_back(addJointNodeSet(protoInstance));
                break;
                
            case PROTO_SENSOR:
                if(T != Matrix44::Identity())
                    throw ModelNodeSet::Exception(protoName + " node is not in a correct place.");
                jointNodeSet->sensorNodes.push_back(protoInstance);
                putMessage(protoName + protoInstance->defName);
                break;
                
            case PROTO_HARDWARECOMPONENT:
                if(T != Matrix44::Identity())
                    throw ModelNodeSet::Exception(protoName + " node is not in a correct place.");
                jointNodeSet->hwcNodes.push_back(protoInstance);
                putMessage(protoName + protoInstance->defName);
                break;
                
            case PROTO_SEGMENT:
                {
                    jointNodeSet->segmentNodes.push_back(protoInstance);
                    jointNodeSet->transforms.push_back(T);
                    putMessage(string("Segment node ") + protoInstance->defName);

                    doTraverseChildren = true;
                    acceptableChildProtoIds.reset();
                    acceptableChildProtoIds.set(PROTO_SENSOR);
                }
                break;
                
            default:
                break;
            }

            if(doTraverseChildren){
                if (protoInstance->fields.count("children")){
                    MFNode& childNodes = protoInstance->fields["children"].mfNode();
                    extractChildNodes(jointNodeSet, childNodes, acceptableChildProtoIds, T);
                }
            }

            messageIndent -= 2;
        }
    }
}
Пример #3
0
/*!
  @if jp
  Shape ノード探索のための再帰関数

  node以下のシーングラフをたどり、ShapeInfoを生成していく。
  生成したShapeInfoはshapes_に追加する。
  shapes_に追加した位置(index)を io_shapeIndicesに追加する。
  io_shapeIndices は、BodyInfo構築時は LinkInfoのshapeIndices になり、
  SceneInfo 構築時は SceneInfo のshapeIndicesになる。

  @endif
*/
void ShapeSetInfo_impl::traverseShapeNodes
(VrmlNode* node, const Matrix44& T, TransformedShapeIndexSequence& io_shapeIndices, DblArray12Sequence& inlinedShapeM, const SFString* url)
{
    static int inline_count=0;   
    SFString url_ = *url;
    if(node->isCategoryOf(PROTO_INSTANCE_NODE)){
        VrmlProtoInstance* protoInstance = static_cast<VrmlProtoInstance*>(node);
        if(protoInstance->actualNode){
            traverseShapeNodes(protoInstance->actualNode.get(), T, io_shapeIndices, inlinedShapeM, url);
        }

    } else if(node->isCategoryOf(GROUPING_NODE)) {
        VrmlGroup* groupNode = static_cast<VrmlGroup*>(node);
        VrmlTransform* transformNode = dynamic_cast<VrmlTransform*>(groupNode);
        VrmlInline* inlineNode = NULL;
        
        inlineNode = dynamic_cast<VrmlInline*>(groupNode);
        const Matrix44* pT;
        if(inlineNode){
            if(!inline_count){
                int inlinedShapeMIndex = inlinedShapeM.length();
                inlinedShapeM.length(inlinedShapeMIndex+1);
                int p = 0;
                for(int row=0; row < 3; ++row){
                    for(int col=0; col < 4; ++col){
                        inlinedShapeM[inlinedShapeMIndex][p++] = T(row, col);
                    }
                }  
                url_ = inlineNode->urls[0];
            }
            inline_count++;
            for( MFString::iterator ite = inlineNode->urls.begin(); ite != inlineNode->urls.end(); ++ite ){
                string filename(deleteURLScheme(*ite));
                struct stat statbuff;
                time_t mtime = 0;
                if( stat( filename.c_str(), &statbuff ) == 0 ){
                    mtime = statbuff.st_mtime;
                }
                fileTimeMap.insert(make_pair(filename, mtime));
            }
        }
        Matrix44 T2;
        if( transformNode ){
            Matrix44 Tlocal;
            calcTransformMatrix(transformNode, Tlocal);
            T2 = T * Tlocal;
            pT = &T2;
        } else {
            pT = &T;
        }

        VrmlSwitch* switchNode = dynamic_cast<VrmlSwitch*>(node);
        if(switchNode){
            int whichChoice = switchNode->whichChoice;
            if( whichChoice >= 0 && whichChoice < switchNode->countChildren() )
                traverseShapeNodes(switchNode->getChild(whichChoice), *pT, io_shapeIndices, inlinedShapeM, &url_);
        }else{
            for(int i=0; i < groupNode->countChildren(); ++i){
                traverseShapeNodes(groupNode->getChild(i), *pT, io_shapeIndices, inlinedShapeM, &url_);
            }
        }
        if(inlineNode)
            inline_count--;

        
    } else if(node->isCategoryOf(SHAPE_NODE)) {

        VrmlShape* shapeNode = static_cast<VrmlShape*>(node);
        short shapeInfoIndex;
        
        ShapeNodeToShapeInfoIndexMap::iterator p = shapeInfoIndexMap.find(shapeNode);
        if(p != shapeInfoIndexMap.end()){
            shapeInfoIndex = p->second;
        } else {
            shapeInfoIndex = createShapeInfo(shapeNode, url);
        }
        
        if(shapeInfoIndex >= 0){
            long length = io_shapeIndices.length();
            io_shapeIndices.length(length + 1);
            TransformedShapeIndex& tsi = io_shapeIndices[length];
            tsi.shapeIndex = shapeInfoIndex;
            int p = 0;
            for(int row=0; row < 3; ++row){
                for(int col=0; col < 4; ++col){
                    tsi.transformMatrix[p++] = T(row, col);
                }
            }
            if(inline_count)
                tsi.inlinedShapeTransformMatrixIndex=inlinedShapeM.length()-1;
            else
                tsi.inlinedShapeTransformMatrixIndex=-1;
        }
    }
}