示例#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
/*!
  @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;
        }
    }
}