void
ColladaInstanceController::read(void)
{
    OSG_COLLADA_LOG(("ColladaInstanceController::read\n"));

    ColladaControllerRefPtr colCont = getTargetElem();

    if(colCont == NULL)
    {
        colCont = dynamic_pointer_cast<ColladaController>(
            ColladaElementFactory::the()->create(
                getTargetDOMElem(), getGlobal()));

        colCont->read();
    }

	domInstance_controllerRef instCont = getDOMElementAs<domInstance_controller>();
	
	_joints = instCont->getSkeleton_array();

    domBind_materialRef     bindMat = instCont->getBind_material            ();

    if(bindMat == NULL)
    {
        SWARNING << "ColladaInstanceController::read: No <bind_material> found."
                 << std::endl;
        return;
    }

    domBind_material::domTechnique_commonRef  techCom      =
        bindMat->getTechnique_common();
    const domInstance_material_Array         &instMatArray =
        techCom->getInstance_material_array();

    for(UInt32 i = 0; i < instMatArray.getCount(); ++i)
    {
        ColladaInstanceMaterialRefPtr colInstMat =
            getUserDataAs<ColladaInstanceMaterial>(instMatArray[i]);

        if(colInstMat == NULL)
        {
            colInstMat = dynamic_pointer_cast<ColladaInstanceMaterial>(
                ColladaElementFactory::the()->create(
                    instMatArray[i], getGlobal()));

            colInstMat->read();
        }

        _matMap[colInstMat->getSymbol()] = colInstMat;

        OSG_COLLADA_LOG(("ColladaInstanceController::read: binding symbol [%s] "
                         "to target [%s]\n",
                         colInstMat->getSymbol().c_str(),
                         instMatArray[i]->getTarget().getURI()));
    }
}
void
ColladaGeometry::readTriangles(domMesh *mesh, domTriangles *triangles)
{
    OSG_COLLADA_LOG(("ColladaGeometry::readTriangles\n"));

    const domInputLocal_Array       &vertInputs =
        mesh->getVertices()->getInput_array();
    const domInputLocalOffset_Array &inputs     =
        triangles          ->getInput_array();

    IndexStore idxStore;
    UInt32     geoIdx   = setupGeometry(vertInputs, inputs,
                                        triangles->getMaterial(), idxStore);

    const domListOfUInts &pList   = triangles->getP()->getValue();
    UInt32                currIdx = 0;
    UInt32                length  = 0;

    for(UInt32 i = 0; i < pList.getCount(); ++i)
    {
        idxStore[currIdx]->push_back(pList[i]);

        ++currIdx;

        if(currIdx == idxStore.size())
        {
            currIdx = 0;
            ++length;
        }
    }

    _geoStore[geoIdx]._types  ->push_back(GL_TRIANGLES);
    _geoStore[geoIdx]._lengths->push_back(length      );

    OSG_COLLADA_LOG(("ColladaGeometry::readTriangles: material symbol [%s] "
                     "vertices [%d] triangles [%d]\n",
                     (triangles->getMaterial() != NULL ?
                      triangles->getMaterial() : ""),
                     length, length/3));

    if(length == 0)
    {
        SWARNING << "ColladaGeometry::readTriangles: Empty <triangles> "
                 << "with material ["
                 << (triangles->getMaterial() != NULL ?
                     triangles->getMaterial() : "")
                 << "]." << std::endl;

        _geoStore.erase(_geoStore.begin() + geoIdx);
    }
}
Node *
ColladaLight::createInstance(ColladaInstInfo *colInstInfo)
{
    domLightRef light = getDOMElementAs<domLight>();

    OSG_COLLADA_LOG(("ColladaLight::createInstance id [%s]\n",
                     light->getId()));

    NodeUnrecPtr                      retVal        = NULL;
    ColladaLightInstInfo             *lightInstInfo =
        dynamic_cast<ColladaLightInstInfo *>(colInstInfo);
    domLight::domTechnique_commonRef  techComm      =
        light->getTechnique_common();

    const domTechnique_Array &techs = light->getTechnique_array();

    for(UInt32 i = 0; i < techs.getCount(); ++i)
    {
        retVal = createInstanceTechnique(lightInstInfo, techs[i]);

        // stop as soon as something is created
        if(retVal != NULL)
            return retVal;
    }

    // if we get here no technique was choosen so we evaluate
    // <technique_common>
    retVal = createInstanceCommon(lightInstInfo, techComm);

    return retVal;
}
void
ColladaInstanceGeometry::read(ColladaElement *colElemParent)
{
    OSG_COLLADA_LOG(("ColladaInstanceGeometry::read\n"));

    ColladaGeometryRefPtr colGeo = getTargetElem();

    if(colGeo == NULL)
    {
        colGeo = dynamic_pointer_cast<ColladaGeometry>(
            ColladaElementFactory::the()->create(
                getTargetDOMElem(), getGlobal()));

        colGeo->read(this);
    }

    domInstance_geometryRef instGeo = getDOMElementAs<domInstance_geometry>();
    domBind_materialRef     bindMat = instGeo->getBind_material            ();

    if(bindMat == NULL)
    {
        SWARNING << "ColladaInstanceGeometry::read: "
                 << "No <bind_material> found." << std::endl;
        return;
    }

    readBindMaterial(bindMat);
}
void
ColladaLight::read(ColladaElement *colElemParent)
{
    domLightRef light = getDOMElementAs<domLight>();

    OSG_COLLADA_LOG(("ColladaLight::read id [%s]\n", light->getId()));
}
Node *
ColladaVisualScene::createInstance(ColladaInstanceElement *colInstElem)
{
    OSG_COLLADA_LOG(("ColladaVisualScene::createInstance\n"));

    ColladaInstanceVisualSceneRefPtr colInstVisScene =
        dynamic_cast<ColladaInstanceVisualScene *>(colInstElem);

    domVisual_sceneRef   visScene = getDOMElementAs<domVisual_scene>();
    const domNode_Array &nodes    = visScene->getNode_array         ();

    for(UInt32 i = 0; i < nodes.getCount(); ++i)
    {
        ColladaNodeRefPtr colNode = getUserDataAs<ColladaNode>(nodes[i]);

        if(colNode == NULL)
        {
            colNode = dynamic_pointer_cast<ColladaNode>(
                ColladaElementFactory::the()->create(nodes[i], getGlobal()));

            colNode->setVisualScene(this);
            colNode->read();
        }

        if(nodes.getCount() > 1)
        {
            if(_RootN == NULL)
            {
                GroupUnrecPtr group = Group::create();
                _RootN = makeNodeFor(group);
            }

            Node *childN = colNode->getTopNode();

            if(childN->getParent() != NULL)
            {
                SWARNING << "ColladaVisualScene::createInstance: <node> [" << i
                         << "] already has a parent." << std::endl;
            }

            _RootN->addChild(childN);
        }
        else
        {
            Node *childN = colNode->getTopNode();

            if(childN->getParent() != NULL)
            {
                SWARNING << "ColladaVisualScene::createInstance: <node> [" << i
                         << "] already has a parent." << std::endl;
            }

            _RootN = childN;
        }
    }

    editInstStore().push_back(_RootN);

    return _RootN;
}
void
ColladaLight::createAmbientLight(ColladaLightAmbientInstInfo *colInstInfo)
{
    OSG_COLLADA_LOG(("ColladaLight::createAmbientLight\n"));

    LightLoaderState *state =
        getGlobal()->getLoaderStateAs<LightLoaderState>(_loaderStateName);
    OSG_ASSERT(state != NULL);

    ChunkOverrideGroupUnrecPtr coGroup  = ChunkOverrideGroup::create();
    NodeUnrecPtr               coGroupN = makeNodeFor(coGroup);

    coGroup->addChunk(state->getLightModelChunk());

    Node *rootN = getGlobal()->getRoot();

    while(rootN->getNChildren() > 0)
    {
        coGroupN->addChild(rootN->getChild(0));
    }

    if(getGlobal()->getOptions()->getCreateNameAttachments() == true)
    {
        setName(coGroupN, "OpenSG_AmbientLight");
    }

    rootN->addChild(coGroupN);
}
void
ColladaImage::read(ColladaElement *colElemParent)
{
    OSG_COLLADA_LOG(("ColladaImage::read\n"));

    domImageRef image = getDOMElementAs<domImage>();

    domImage::domInit_fromRef initFrom = image->getInit_from();

    if(initFrom != NULL)
    {
        daeURI      imageURI  = initFrom->getValue();
        std::string imagePath = cdom::uriToNativePath(imageURI.str());
        
        OSG_COLLADA_LOG(("ColladaImage::read: URI [%s] path [%s]\n",
                         imageURI.getURI(), imagePath.c_str()));

#ifdef WIN32
        if(imagePath.size() >  3   &&
           imagePath[0]     == '/' &&
           imagePath[2]     == ':'   )
        {
            _image =
                ImageFileHandler::the()->read(imagePath.substr(1).c_str());
        }
        else
        {
            _image = ImageFileHandler::the()->read(imagePath.c_str());
        }
#else
        _image = ImageFileHandler::the()->read(imagePath.c_str());
#endif

        if(_image == NULL)
        {
            SWARNING << "ColladaImage::read: Loading of image ["
                     << imagePath << "] failed." << std::endl;
        }
    }
    else
    {
        SWARNING << "ColladaImage::read: No <init_from> tag found."
                 << std::endl;
    }
}
Node *
ColladaLight::createInstanceTechnique(
    ColladaLightInstInfo *colInstInfo, domTechnique *tech)
{
    domLightRef light = getDOMElementAs<domLight>();

    OSG_COLLADA_LOG(("ColladaLight::createInstanceTechnique id [%s] "
                     "profile [%s]\n", light->getId(), tech->getProfile()));

    return NULL;
}
Node *
ColladaInstanceController::process(ColladaElement *parent)
{
    OSG_COLLADA_LOG(("ColladaInstanceController::process\n"));

    ColladaControllerRefPtr colCont = getTargetElem();

	getGlobal()->addInstanceController(this);

    return colCont->createInstance(this);
}
UInt32
ColladaGeometry::mapSemantic(
    const std::string &semantic, UInt32 set, UInt32 geoIdx)
{
    UInt32 propIdx = Geometry::MaxAttribs;

    if(semantic == "POSITION")
    {
        propIdx = Geometry::PositionsIndex;
    }
    else if(semantic == "NORMAL")
    {
        propIdx = Geometry::NormalsIndex;
    }
    else if(semantic == "TEXCOORD")
    {
        if(set <= Geometry::TexCoords7Index)
        {
            propIdx = Geometry::TexCoordsIndex + set;
        }
        else
        {
            SWARNING << "ColladaGeometry::mapSemantic: TEXCOORD semantic has "
                     << "out of range set [" << set << "]"
                     << std::endl;
        }
    }
    else
    {
        OSG_COLLADA_LOG(("ColladaGeometry::mapSemantic: Unknown semantic [%s] "
                         "set [%d]\n", semantic.c_str(), set));
    }

    OSG_COLLADA_LOG(("ColladaGeometry::mapSemantic: semantic [%s] "
                     "set [%d] -> propIdx [%d]\n",
                     semantic.c_str(), set, propIdx));

    return propIdx;
}
void
ColladaNode::NodeLoaderState::dumpNodePath(void) const
{
    NodePathConstIt npIt  = _nodePath.begin();
    NodePathConstIt npEnd = _nodePath.end  ();

    OSG_COLLADA_LOG(("node path ["));

    for(; npIt != npEnd; ++npIt)
    {
        OSG_COLLADA_PLOG((" '%s'", npIt->c_str()));
    }

    OSG_COLLADA_PLOG((" ]\n"));
}
Example #13
0
void
ColladaInstanceNode::read(void)
{
    OSG_COLLADA_LOG(("ColladaInstanceNode::read\n"));

    ColladaNodeRefPtr colNode = getTargetElem();

    if(colNode == NULL)
    {
        colNode = dynamic_pointer_cast<ColladaNode>(
            ColladaElementFactory::the()->create(
                getTargetDOMElem(), getGlobal()));

        colNode->read();
    }
}
void
ColladaGeometry::read(ColladaElement *colElemParent)
{
    domGeometryRef geometry = getDOMElementAs<domGeometry>();
    domMeshRef     mesh     = geometry->getMesh();

    OSG_COLLADA_LOG(("ColladaGeometry::read id [%s]\n",
                     geometry->getId()));

    if(mesh == NULL)
    {
        SWARNING << "ColladaGeometry::read: No <mesh>" << std::endl;
        return;
    }

    readMesh(mesh);
}
void
ColladaMaterial::read(ColladaElement *colElemParent)
{
    OSG_COLLADA_LOG(("ColladaMaterial::read\n"));

    domMaterialRef              material      = getDOMElementAs<domMaterial>();
    domInstance_effectRef       instEffect    = material->getInstance_effect();
    ColladaInstanceEffectRefPtr colInstEffect =
        getUserDataAs<ColladaInstanceEffect>(instEffect);

    if(colInstEffect == NULL)
    {
        colInstEffect = dynamic_pointer_cast<ColladaInstanceEffect>(
            ColladaElementFactory::the()->create(instEffect, getGlobal()));

        colInstEffect->read(this);
    }
}
void
ColladaSurface::read(void)
{
    OSG_COLLADA_LOG(("ColladaSurface::read\n"));

    domFx_surface_commonRef surface = getDOMElementAs<domFx_surface_common>();

    switch(surface->getType())
    {
    case FX_SURFACE_TYPE_ENUM_UNTYPED:
        readUntyped(surface);
        break;

    case FX_SURFACE_TYPE_ENUM_1D:
        read1D(surface);
        break;

    case FX_SURFACE_TYPE_ENUM_2D:
        read2D(surface);
        break;

    case FX_SURFACE_TYPE_ENUM_3D:
        read3D(surface);
        break;

    case FX_SURFACE_TYPE_ENUM_RECT:
        readRect(surface);
        break;

    case FX_SURFACE_TYPE_ENUM_CUBE:
        readCube(surface);
        break;

    case FX_SURFACE_TYPE_ENUM_DEPTH:
        readDepth(surface);
        break;

    case FX_SURFACE_TYPE_ENUM_COUNT:
        SWARNING << "ColladaSurface::read FX_SURFACE_TYPE_ENUM_COUNT "
                 << "not handled"
                 << std::endl;
        break;
    }
}
Node *
ColladaNode::createInstance(ColladaInstanceElement *colInstElem)
{
    OSG_COLLADA_LOG(("ColladaNode::createInstance\n"));

    NodeUnrecPtr retVal = NULL;

   // if(getInstStore().empty() == true)
   // {
   //     retVal = _topN;
   // }
   // else
   // {
        retVal = cloneTree(_topN);
   // }

    editInstStore().push_back(retVal);

    return retVal;
}
Material *
ColladaMaterial::createInstance(ColladaInstInfo *colInstInfo)
{
    OSG_COLLADA_LOG(("ColladaMaterial::createInstance\n"));

    MaterialUnrecPtr            retVal        = NULL;
    domMaterialRef              material      = getDOMElementAs<domMaterial>();
    domInstance_effectRef       instEffect    = material->getInstance_effect();
    ColladaInstanceEffectRefPtr colInstEffect =
        getUserDataAs<ColladaInstanceEffect>(instEffect);

    if(getInstStore().empty() == true)
    {
        OSG_ASSERT(colInstEffect                  != NULL);
        OSG_ASSERT(colInstEffect->getTargetElem() != NULL);

        ColladaInstInfoRefPtr colEffectInstInfo =
            ColladaEffect::ColladaEffectInstInfo::create(this, colInstEffect);

        retVal = colInstEffect->getTargetElem()->createInstance(
            colEffectInstInfo);

        if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
           material->getName()                                   != NULL   )
        {
            setName(retVal, material->getName());
        }

        editInstStore().push_back(retVal);
    }
    else
    {
        retVal = dynamic_pointer_cast<Material>(getInstStore()[0]);

        getGlobal()->getStatCollector()->getElem(
            ColladaGlobal::statNMaterialUsed)->inc();
    }

    return retVal;
}
void
ColladaNode::read(ColladaElement *colElemParent)
{
    domNodeRef node = getDOMElementAs<domNode>();

    OSG_COLLADA_LOG(("ColladaNode::read id [%s]\n", node->getId()));

    // <node>
    const domNode_Array &nodes = node->getNode_array();
    for(UInt32 i = 0; i < nodes.getCount(); ++i)
        readNode(nodes[i]);

    // <instance_node>
    const domInstance_node_Array &instNodes =
        node->getInstance_node_array();

    for(UInt32 i = 0; i < instNodes.getCount(); ++i)
        readInstanceNode(instNodes[i]);

    // <instance_light>
    const domInstance_light_Array &instLights =
        node->getInstance_light_array();

    for(UInt32 i = 0; i < instLights.getCount(); ++i)
        readInstanceLight(instLights[i]);
    // <instance_geometry>
    const domInstance_geometry_Array &instGeos =
        node->getInstance_geometry_array();

    for(UInt32 i = 0; i < instGeos.getCount(); ++i)
        readInstanceGeometry(instGeos[i]);

    // <instance_controller>
    const domInstance_controller_Array &instControllers =
        node->getInstance_controller_array();

    for(UInt32 i = 0; i < instControllers.getCount(); ++i)
        readInstanceController(instControllers[i]);
}
void
ColladaInstanceGeometry::readBindMaterial(domBind_material *bindMat)
{
    domBind_material::domTechnique_commonRef  techCom      =
        bindMat->getTechnique_common();
    const domInstance_material_Array         &instMatArray =
        techCom->getInstance_material_array();

    for(UInt32 i = 0; i < instMatArray.getCount(); ++i)
    {
        ColladaInstanceMaterialRefPtr colInstMat =
            getUserDataAs<ColladaInstanceMaterial>(instMatArray[i]);

        if(colInstMat == NULL)
        {
            colInstMat = dynamic_pointer_cast<ColladaInstanceMaterial>(
                ColladaElementFactory::the()->create(
                    instMatArray[i], getGlobal()));

            colInstMat->read(this);
        }

        _matMap[colInstMat->getSymbol()] = colInstMat;

        OSG_COLLADA_LOG(("ColladaInstanceGeometry::readBindMaterial: "
                         "binding symbol [%s] to target [%s]\n",
                         colInstMat->getSymbol().c_str(),
                         instMatArray[i]->getTarget().getURI()));
    }

    const domParam_Array &params = bindMat->getParam_array();

    if(params.getCount() > 0)
    {
        SWARNING << "ColladaInstanceGeometry::readBindMaterial: "
                 << "Ignoring [" << params.getCount()
                 << "] <param> elements." << std::endl;
    }
}
void
ColladaInstanceEffect::read(ColladaElement *colElemParent)
{
    OSG_COLLADA_LOG(("ColladaInstanceEffect::read\n"));

    ColladaEffectRefPtr colEffect = getTargetElem();

    if(colEffect == NULL)
    {
        colEffect = dynamic_pointer_cast<ColladaEffect>(
            ColladaElementFactory::the()->create(
                getTargetDOMElem(), getGlobal()));

        colEffect->read(this);
    }

    domInstance_effectRef instEffect = getDOMElementAs<domInstance_effect>();

    const domInstance_effect::domTechnique_hint_Array &techHints =
        instEffect->getTechnique_hint_array();

    if(techHints.getCount() > 0)
    {
        SWARNING << "ColladaInstanceEffect::read: Ignoring ["
                 << techHints.getCount() << "] <technique_hint> elements."
                 << std::endl;
    }

    const domInstance_effect::domSetparam_Array &setParams =
        instEffect->getSetparam_array();

    if(setParams.getCount() > 0)
    {
        SWARNING << "ColladaInstanceEffect::read: Ignoring ["
                 << setParams.getCount() << "] <setparam> elements."
                 << std::endl;
    }
}
Example #22
0
void
ColladaScene::read(void)
{
    OSG_COLLADA_LOG(("ColladaScene::read\n"));

    domCOLLADA::domSceneRef scene = getDOMElementAs<domCOLLADA::domScene>();

    OSG_ASSERT(scene != NULL);

    domInstanceWithExtraRef instVisScene = scene->getInstance_visual_scene();

    if(instVisScene != NULL)
    {
        _colInstVisScene = dynamic_pointer_cast<ColladaInstanceVisualScene>(
                               ColladaElementFactory::the()->create(instVisScene, getGlobal()));

        _colInstVisScene->read();
    }
    else
    {
        SWARNING << "ColladaScene::read: No <instance_visual_scene> tag."
                 << std::endl;
    }
}
Node *
ColladaNode::createInstanceJoint(ColladaInstInfo *colInstInfo, domNode *node)
{
    NodeUnrecPtr retVal    = NULL;
    bool         startSkel = false;

    // if there is a ColladaInstanceElement someone tried to use <instance_node>
    // with this joint as target - this is currently not supported
    if(colInstInfo->getColInst() != NULL)
    {
        SWARNING << "ColladaNode::createInstanceJoint: <instance_node> with "
                 << "target <node> of type JOINT not supported." << std::endl;
        return retVal;
    }

    NodeLoaderState *state =
        getGlobal()->getLoaderStateAs<NodeLoaderState>(_loaderStateName);
    OSG_ASSERT(state != NULL);

    state->pushNodePath(node->getId() != NULL ? node->getId() : "");
    state->dumpNodePath();

    InstData instData;
    instData._nodePath = state->getNodePath();
    instData._skel     = state->getSkeleton();

    if(instData._skel == NULL)
    {
        startSkel      = true;
        instData._skel = Skeleton::create();

        state->setSkeleton(instData._skel);
        state->setJointId (0             );

        OSG_COLLADA_LOG(("ColladaNode::createInstanceJoint: id [%s] "
                         "root joint\n", node->getId()));
    }
    else
    {
        state->setJointId(state->getJointId() + 1);

        OSG_COLLADA_LOG(("ColladaNode::createInstanceJoint: id [%s] "
                         "joint [%d]\n", node->getId(), state->getJointId()));
    }

    const daeElementRefArray &contents = node->getContents();

    for(UInt32 i = 0; i < contents.getCount(); ++i)
    {
        switch(contents[i]->getElementType())
        {
        case COLLADA_TYPE::LOOKAT:
            handleLookAt(daeSafeCast<domLookat>(contents[i]), instData);
            break;

        case COLLADA_TYPE::MATRIX:
            handleMatrix(daeSafeCast<domMatrix>(contents[i]), instData);
            break;

        case COLLADA_TYPE::ROTATE:
            handleRotate(daeSafeCast<domRotate>(contents[i]), instData);
            break;

        case COLLADA_TYPE::SCALE:
            handleScale(daeSafeCast<domScale>(contents[i]), instData);
            break;

        case COLLADA_TYPE::SKEW:
            handleSkew(daeSafeCast<domSkew>(contents[i]), instData);
            break;

        case COLLADA_TYPE::TRANSLATE:
            handleTranslate(daeSafeCast<domTranslate>(contents[i]), instData);
            break;
        }
    }

    // assert top and bottom are both set or both unset
    OSG_ASSERT((instData._topN != NULL && instData._bottomN != NULL) ||
               (instData._topN == NULL && instData._bottomN == NULL)   );

    if(instData._topN == NULL && instData._bottomN == NULL)
    {
        // no xforms were created, make a SkeletonJoint for this <node>

        SkeletonJointUnrecPtr joint = SkeletonJoint::create();

        joint->setJointId(state->getJointId());

        instData._topN    = makeNodeFor(joint);
        instData._bottomN = instData._topN;

        if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
           node->getName()                                       != NULL   )
        {
            setName(instData._topN, node->getName());
        }
    }
    else if(getGlobal()->getOptions()->getMergeTransforms() == false)
    {
        // when not merging transforms add SkeletonJoint core now

        SkeletonJointUnrecPtr joint  = SkeletonJoint::create();
        NodeUnrecPtr          jointN = makeNodeFor(joint);

        joint->setJointId(state->getJointId());

        instData._bottomN->addChild(jointN);
        instData._bottomN = jointN;
    }

    if(startSkel == true)
    {
        // add a transform for the world matrix up to this node to put
        // the Skeleton in the correct coordinate system

        TransformUnrecPtr xform  = Transform::create();
        NodeUnrecPtr      xformN = makeNodeFor(xform);

        xform->setMatrix(state->getWorldMatrix());

        xformN->addChild(instData._topN);
        instData._topN = xformN;

        if(getGlobal()->getOptions()->getCreateNameAttachments() == true)
            setName(xformN, "SkeletonWorldMatrix");
    }

    // update world matrix before we instantiate child nodes, etc.
    state->pushMatrix(instData._localMatrix);

    // add <node> child elements
    const domNode_Array &nodes = node->getNode_array();

    for(UInt32 i = 0; i < nodes.getCount(); ++i)
        handleNode(nodes[i], instData);

    // add <instance_node> child elements
    const domInstance_node_Array &instNodes =
        node->getInstance_node_array();

    for(UInt32 i = 0; i < instNodes.getCount(); ++i)
        handleInstanceNode(instNodes[i], instData);

    // we don't handle other <instance_*> tags here, it does not
    // make sense to have them inside a skeleton

    editInstStore().push_back(instData._topN);
    _instDataStore .push_back(instData      );
    retVal = instData._topN;

    if(startSkel == true)
    {
        instData._skel->pushToRoots(instData._topN);

        state->setSkeleton(NULL);
        state->setJointId (SkeletonJoint::INVALID_JOINT_ID);
    }

    state->popMatrix  ();
    state->popNodePath();

    return retVal;
}
Node *
ColladaNode::createInstanceNode(ColladaInstInfo *colInstInfo, domNode *node)
{
    OSG_COLLADA_LOG(("ColladaNode::createInstanceNode id [%s]\n",
                     node->getId()));

    NodeLoaderState *state =
        getGlobal()->getLoaderStateAs<NodeLoaderState>(_loaderStateName);
    OSG_ASSERT(state != NULL);

    state->pushNodePath(node->getId() != NULL ? node->getId() : "");
    state->dumpNodePath();

    NodeUnrecPtr retVal = NULL;
    InstData     instData;

    instData._nodePath = state->getNodePath();
    const daeElementRefArray &contents = node->getContents();

    // read "transform" child elements in the order
    // they occur in the document
    for(UInt32 i = 0; i < contents.getCount(); ++i)
    {
        switch(contents[i]->getElementType())
        {
        case COLLADA_TYPE::LOOKAT:
            handleLookAt(daeSafeCast<domLookat>(contents[i]), instData);
            break;

        case COLLADA_TYPE::MATRIX:
            handleMatrix(daeSafeCast<domMatrix>(contents[i]), instData);
            break;

        case COLLADA_TYPE::ROTATE:
            handleRotate(daeSafeCast<domRotate>(contents[i]), instData);
            break;

        case COLLADA_TYPE::SCALE:
            handleScale(daeSafeCast<domScale>(contents[i]), instData);
            break;

        case COLLADA_TYPE::SKEW:
            handleSkew(daeSafeCast<domSkew>(contents[i]), instData);
            break;

        case COLLADA_TYPE::TRANSLATE:
            handleTranslate(daeSafeCast<domTranslate>(contents[i]), instData);
            break;
        }
    }

    // assert top and bottom are both set or both unset
    OSG_ASSERT((instData._topN != NULL && instData._bottomN != NULL) ||
               (instData._topN == NULL && instData._bottomN == NULL)   );

    // if no xforms were created make a group for this <node>
    if(instData._topN == NULL && instData._bottomN == NULL)
    {
        instData._topN    = makeCoredNode<Group>();
        instData._bottomN = instData._topN;

        if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
           node->getName()                                       != NULL   )
        {
            setName(instData._topN, node->getName());
        }
    }

    // update world matrix before we instantiate child nodes, etc.
    state->pushMatrix(instData._localMatrix);

    // add <node> child elements
    const domNode_Array &nodes = node->getNode_array();

    for(UInt32 i = 0; i < nodes.getCount(); ++i)
        handleNode(nodes[i], instData);

    // add <instance_node> child elements
    const domInstance_node_Array &instNodes =
        node->getInstance_node_array();

    for(UInt32 i = 0; i < instNodes.getCount(); ++i)
        handleInstanceNode(instNodes[i], instData);

    // add <instance_light> child elements
    const domInstance_light_Array &instLights =
        node->getInstance_light_array();

    for(UInt32 i = 0; i < instLights.getCount(); ++i)
        handleInstanceLight(instLights[i], instData);

    // add <instance_geometry> child elements
    const domInstance_geometry_Array &instGeos =
        node->getInstance_geometry_array();

    for(UInt32 i = 0; i < instGeos.getCount(); ++i)
        handleInstanceGeometry(instGeos[i], instData);

    // add <instance_controller> child elemnts
    const domInstance_controller_Array &instControllers =
        node->getInstance_controller_array();

    for(UInt32 i = 0; i < instControllers.getCount(); ++i)
        handleInstanceController(instControllers[i], instData);

    editInstStore().push_back(instData._topN);
    _instDataStore .push_back(instData      );
    retVal = instData._topN;

    state->popMatrix  ();
    state->popNodePath();

    return retVal;
}
void
ColladaGeometry::readTriStrips(domMesh *mesh, domTristrips *triStrips)
{
    OSG_COLLADA_LOG(("ColladaGeometry::readTriStrips\n"));

    const domInputLocal_Array       &vertInputs =
        mesh->getVertices()->getInput_array();
    const domInputLocalOffset_Array &inputs     =
        triStrips          ->getInput_array();

    IndexStore idxStore;
    UInt32     geoIdx   = setupGeometry(vertInputs, inputs,
                                        triStrips->getMaterial(), idxStore);

    const domP_Array &pArray  = triStrips->getP_array();
    UInt32            currIdx = 0;
    UInt32            length  = 0;
    UInt32            verts   = 0;

    for(UInt32 i = 0; i < pArray.getCount(); ++i)
    {
        const domListOfUInts &pList = pArray[i]->getValue();

        for(UInt32 j = 0; j < pList.getCount(); ++j)
        {
            idxStore[currIdx]->push_back(pList[j]);

            ++currIdx;

            if(currIdx == idxStore.size())
            {
                currIdx = 0;
                ++length;
            }
        }

        // only add non-empty tri strip
        if(length > 0)
        {
            _geoStore[geoIdx]._types  ->push_back(GL_TRIANGLE_STRIP);
            _geoStore[geoIdx]._lengths->push_back(length           );
        }

        verts  += length;
        length =  0;
    }

    OSG_COLLADA_LOG(("ColladaGeometry::readTriStrips: material symbol [%s] "
                     "vertices [%d] strips [%d]\n",
                     (triStrips->getMaterial() != NULL ?
                      triStrips->getMaterial() : ""), verts,
                     _geoStore[geoIdx]._lengths->size()));

    // remove empty geometry
    if(verts == 0)
    {
        SWARNING << "ColladaGeometry::readTriStrips: Empty <tristrips> "
                 << "with material ["
                 << (triStrips->getMaterial() != NULL ?
                     triStrips->getMaterial() : "")
                 << "]." << std::endl;

        _geoStore.erase(_geoStore.begin() + geoIdx);
    }
}
UInt32
ColladaGeometry::setupGeometry(const domInputLocal_Array       &vertInputs,
                               const domInputLocalOffset_Array &inputs,
                               xsNCName                         matSymbol,
                               IndexStore                      &idxStore   )
{
    OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry\n"));

    typedef std::vector<UInt32>             UnhandledStore;
    typedef UnhandledStore::const_iterator  UnhandledStoreConstIt;

    Int32          vertInputIndex       = -1;  // <input> with sem "VERTEX"
    UnhandledStore unhandledVertInputs;
    UnhandledStore unhandledInputs;

    UInt32 geoIdx = _geoStore.size();
    _geoStore.push_back(GeoInfo());

    if(matSymbol != NULL)
    {
        _geoStore[geoIdx]._matSymbol = matSymbol;
    }
    else
    {
        SWARNING << "ColladaGeometry::setupGeometry: "
                 << "Found empty material symbol." << std::endl;
    }

    for(UInt32 i = 0; i < inputs.getCount(); ++i)
    {
        std::string semantic = inputs[i]->getSemantic();
        UInt32      set      = inputs[i]->getSet     ();
        UInt32      offset   = inputs[i]->getOffset  ();
        std::string sourceId = inputs[i]->getSource  ().id();

        OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: input [%d] "
                         "semantic [%s] set [%d] offset [%d] - source [%s]\n",
                         i, semantic.c_str(), set, offset, sourceId.c_str()));

        if(semantic == "VERTEX")
        {
            // handle <input> tag with semantic "VERTEX"
            // by processing vertInputs, i.e. the <vertices> tag

            vertInputIndex = i;

            // all vertInputs use the same index - with the offset from the
            // <input> with semantic == VERTEX
            if(offset >= idxStore.size() || idxStore[offset] == NULL)
            {
                OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: "
                                 "new index property for offset [%d]\n",
                                 offset));

                // new index
                idxStore.resize(
                    osgMax<UInt32>(offset + 1, idxStore.size()), NULL);
                idxStore[offset] = GeoUInt32Property::create();
            }

            for(UInt32 j = 0; j < vertInputs.getCount(); ++j)
            {
                semantic = vertInputs[j]->getSemantic();
                sourceId = vertInputs[j]->getSource  ().id();

                OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: vertices [%d] "
                                 "semantic [%s] - source [%s]\n",
                                 j, semantic.c_str(), sourceId.c_str()));

                UInt32 propIdx = mapSemantic(semantic, 0, geoIdx);

                if(propIdx == Geometry::MaxAttribs)
                {
                    unhandledVertInputs.push_back(j);
                }
                else
                {
                    setupProperty(geoIdx, propIdx, semantic, set, sourceId,
                                  idxStore[offset]                         );
                }
            }
        }
        else
        {
            // handle regular <input> tags

            if(offset >= idxStore.size() || idxStore[offset] == NULL)
            {
                OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: "
                                 "new index property for offset [%d]\n",
                                 offset));

                // new index
                idxStore.resize(osgMax<UInt32>(offset + 1, idxStore.size()), NULL);
                idxStore[offset] = GeoUInt32Property::create();
            }

            UInt32 propIdx = mapSemantic(semantic, set, geoIdx);

            if(propIdx == Geometry::MaxAttribs)
            {
                unhandledInputs.push_back(i);
            }
            else
            {
                setupProperty(geoIdx, propIdx, semantic, set, sourceId,
                              idxStore[offset]                         );
            }
        }
    }

    // some <inputs> could not be handled above because their
    // semantic was not recognized.
    // after everything else is set put them into free attribute
    // slots, starting at Geometry::TexCoordsIndex

    UnhandledStoreConstIt uhIt  = unhandledVertInputs.begin();
    UnhandledStoreConstIt uhEnd = unhandledVertInputs.end  ();

    for(; uhIt != uhEnd; ++uhIt)
    {
        std::string semantic = vertInputs[*uhIt         ]->getSemantic();
        UInt32      set      = inputs    [vertInputIndex]->getSet     ();
        UInt32      offset   = inputs    [vertInputIndex]->getOffset  ();
        std::string sourceId = vertInputs[*uhIt         ]->getSource  ().id();

        UInt32 propIdx = findFreePropertyIndex(geoIdx);

        OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: unhandled vertex "
                         " <input> [%d] semantic [%s] set [%d] offset [%d] - "
                         "source [%s] mapped to propIdx [%d]\n",
                         *uhIt, semantic.c_str(), set, offset, sourceId.c_str(),
                         propIdx));

        setupProperty(geoIdx, propIdx, semantic, set, sourceId,
                      idxStore[offset]                         );
    }

    uhIt  = unhandledInputs.begin();
    uhEnd = unhandledInputs.end  ();

    for(; uhIt != uhEnd; ++uhIt)
    {
        std::string semantic = inputs[*uhIt]->getSemantic();
        UInt32      set      = inputs[*uhIt]->getSet     ();
        UInt32      offset   = inputs[*uhIt]->getOffset  ();
        std::string sourceId = inputs[*uhIt]->getSource  ().id();

        UInt32 propIdx = findFreePropertyIndex(geoIdx);

        OSG_COLLADA_LOG(("ColladaGeometry::setupGeometry: unhandled <input> "
                         "[%d] semantic [%s] set [%d] offset [%d] - "
                         "source [%s] mapped to propIdx [%d]\n",
                         *uhIt, semantic.c_str(), set, offset, sourceId.c_str(),
                         propIdx));

        setupProperty(geoIdx, propIdx, semantic, set, sourceId,
                      idxStore[offset]                         );
    }

#ifdef OSG_DEBUG
    // check for holes in idxStore - which is not supported
    IndexStoreConstIt idxIt  = idxStore.begin();
    IndexStoreConstIt idxEnd = idxStore.end  ();

    for(UInt32 i = 0; idxIt != idxEnd; ++idxIt, ++i)
    {
        if(*idxIt == NULL)
        {
            SWARNING << "ColladaGeometry::setupGeometry: idxStore contains "
                     << "hole at [" << i << "]" << std::endl;
        }
    }
#endif

    _geoStore[geoIdx]._lengths = GeoUInt32Property::create();
    _geoStore[geoIdx]._types   = GeoUInt8Property ::create();

    return geoIdx;
}
Example #27
0
void
ColladaInstanceMaterial::read(void)
{
    OSG_COLLADA_LOG(("ColladaInstanceMaterial::read\n"));

    domInstance_materialRef instMat =
        getDOMElementAs<domInstance_material>();
    ColladaMaterialRefPtr   colMat  = getTargetElem();

    if(colMat == NULL)
    {
        colMat = dynamic_pointer_cast<ColladaMaterial>(
            ColladaElementFactory::the()->create(
                getTargetDOMElem(), getGlobal()));

        colMat->read();
    }

    if(instMat->getSymbol() != NULL)
    {
        _symbol = instMat->getSymbol();
    }
    else
    {
        SFATAL << "ColladaInstanceMaterial::read: No symbol."
               << std::endl;
    }

    _target = instMat->getTarget().str();

    const domInstance_material::domBind_Array &binds   =
        instMat->getBind_array();

    _bindStore.resize(binds.getCount());

    for(UInt32 i = 0; i < binds.getCount(); ++i)
    {
        std::string target   = binds[i]->getTarget();
        std::string semantic;

        if(binds[i]->getSemantic() != NULL)
        {
            semantic = binds[i]->getSemantic();
        }

        OSG_COLLADA_LOG(("ColladaInstanceMaterial::read: "
                         "<bind> semantic [%s] target [%s]\n",
                         semantic.c_str(), target.c_str()));

        _bindStore[i].semantic = semantic;
        _bindStore[i].target   = target;
    }

    const domInstance_material::domBind_vertex_input_Array &bindVerts =
        instMat->getBind_vertex_input_array();

    _bindVertexStore.resize(bindVerts.getCount());

    for(UInt32 i = 0; i < bindVerts.getCount(); ++i)
    {
        std::string semantic   = bindVerts[i]->getSemantic      ();
        std::string inSemantic = bindVerts[i]->getInput_semantic();
        UInt32      inSet      = bindVerts[i]->getInput_set     ();

        OSG_COLLADA_LOG(("ColladaInstanceMaterial::read "
                         "<bind_vertex_input> semantic [%s] "
                         "inSemantic [%s] inSet [%d]\n",
                         semantic.c_str(), inSemantic.c_str(), inSet));

        _bindVertexStore[i].semantic   = semantic;
        _bindVertexStore[i].inSemantic = inSemantic;
        _bindVertexStore[i].inSet      = inSet;
    }
}
void
ColladaAnimationClip::read(ColladaElement *colElemParent)
{
    domAnimation_clipRef animClip = getDOMElementAs<domAnimation_clip>();

    OSG_COLLADA_LOG(("ColladaAnimationClip::read: id [%s]\n",
                     animClip->getId()));

#if !defined(OSG_USE_COLLADA_ANIMCLIP_INSTANCE_HACK)

    AnimKeyFrameTemplateUnrecPtr animTmpl = AnimKeyFrameTemplate::create();
    getGlobal()->getGlobalsAtt()->editMFElements()->push_back(animTmpl);

    const domInstanceWithExtra_Array &animInsts =
        animClip->getInstance_animation_array();

    for(UInt32 i = 0; i < animInsts.getCount(); ++i)
    {
        ColladaInstanceAnimationRefPtr colInstAnim =
            getUserDataAs<ColladaInstanceAnimation>(animInsts[i]);

        if(colInstAnim == NULL)
        {
            colInstAnim = dynamic_pointer_cast<ColladaInstanceAnimation>(
                ColladaElementFactory::the()->create(
                    animInsts[i], getGlobal(), "instance_animation"));

            colInstAnim->read(this);
        }

        ColladaInstInfoRefPtr animInstInfo =
            ColladaAnimation::ColladaAnimationInstInfo::create(
                this, colInstAnim, NULL, animTmpl);

        getGlobal()->editInstQueue().push_back(animInstInfo);
    }

#else

    // add anim template to the globals attachment
    AnimKeyFrameTemplateUnrecPtr animTmpl = AnimKeyFrameTemplate::create();
    getGlobal()->getGlobalsAtt()->editMFElements()->push_back(animTmpl);

    domCOLLADA *docRoot = getGlobal()->getDocRoot();
    const domLibrary_animations_Array &libAnims =
        docRoot->getLibrary_animations_array();

    for(UInt32 i = 0; i < libAnims.getCount(); ++i)
    {
        const domAnimation_Array &anims = libAnims[i]->getAnimation_array();

        for(UInt32 j = 0; j < anims.getCount(); ++j)
        {
            ColladaAnimationRefPtr colAnim =
                getUserDataAs<ColladaAnimation>(anims[j]);

            if(colAnim == NULL)
            {
                colAnim = dynamic_pointer_cast<ColladaAnimation>(
                    ColladaElementFactory::the()->create(
                        anims[j], getGlobal(), "animation"));

                colAnim->read(this);
            }

            // queue an instance
            ColladaInstInfoRefPtr animInstInfo =
                ColladaAnimation::ColladaAnimationInstInfo::create(
                    this, NULL, colAnim, animTmpl);

            getGlobal()->editInstQueue().push_back(animInstInfo);
        }
    }
#endif // OSG_USE_COLLADA_ANIMCLIP_INSTANCE_HACK
}
Example #29
0
void
ColladaSampler2D::read(void)
{
    OSG_COLLADA_LOG(("OSGColladaSampler2D::read\n"));

    domFx_sampler2D_commonRef            sampler2D =
        getDOMElementAs<domFx_sampler2D_common>();
    domFx_sampler2D_common::domSourceRef source    = sampler2D->getSource();

    if(_colEffect == NULL)
    {
        SWARNING << "ColladaSampler2D::read: No effect set, can not resolve "
                 << "<source> elements." << std::endl;
        return;
    }

    ColladaElement *colElem    = _colEffect->findParam(source->getValue());
    ColladaSurface *colSurface = dynamic_cast<ColladaSurface *>(colElem);

    if(colElem == NULL || colSurface == NULL)
    {
        SWARNING << "ColladaSampler2D::read: Could not resolve <source> ["
                 << source->getValue() << "]." << std::endl;
    }
    
    _texObj = TextureObjChunk::create();
    _texObj->setImage(colSurface->getImage());

    getGlobal()->getStatCollector()->getElem(
        ColladaGlobal::statNTextureCreated)->inc();

    if(sampler2D->getWrap_s() != NULL)
    {
        switch(sampler2D->getWrap_s()->getValue())
        {
        case FX_SAMPLER_WRAP_COMMON_NONE:
            SWARNING << "ColladaSampler2D::read: <wrap_s> == NONE "
                     << "not supported" << std::endl;
            break;

        case FX_SAMPLER_WRAP_COMMON_WRAP:
            _texObj->setWrapS(GL_REPEAT);
            break;

        case FX_SAMPLER_WRAP_COMMON_MIRROR:
            _texObj->setWrapS(GL_MIRRORED_REPEAT);
            break;

        case FX_SAMPLER_WRAP_COMMON_CLAMP:
            _texObj->setWrapS(GL_CLAMP_TO_EDGE);
            break;

        case FX_SAMPLER_WRAP_COMMON_BORDER:
            _texObj->setWrapS(GL_CLAMP_TO_BORDER);
            break;
        case FX_SAMPLER_WRAP_COMMON_COUNT:
            SWARNING << "OSGColladaSampler2D::read <wrap_s> "
                     << "FX_SAMPLER_WRAP_COMMON_COUNT not handled" 
                     << std::endl;
            break;
        }
    }

    if(sampler2D->getWrap_t() != NULL)
    {
        switch(sampler2D->getWrap_t()->getValue())
        {
        case FX_SAMPLER_WRAP_COMMON_NONE:
            SWARNING << "ColladaSampler2D::read: <wrap_t> == NONE "
                     << "not supported" << std::endl;
            break;

        case FX_SAMPLER_WRAP_COMMON_WRAP:
            _texObj->setWrapT(GL_REPEAT);
            break;

        case FX_SAMPLER_WRAP_COMMON_MIRROR:
            _texObj->setWrapT(GL_MIRRORED_REPEAT);
            break;

        case FX_SAMPLER_WRAP_COMMON_CLAMP:
            _texObj->setWrapT(GL_CLAMP_TO_EDGE);
            break;

        case FX_SAMPLER_WRAP_COMMON_BORDER:
            _texObj->setWrapT(GL_CLAMP_TO_BORDER);
            break;            
        case FX_SAMPLER_WRAP_COMMON_COUNT:
            SWARNING << "OSGColladaSampler2D::read <wrap_t> "
                     << "FX_SAMPLER_WRAP_COMMON_COUNT not handled" 
                     << std::endl;
            break;
        }
    }
}
/*! Read the file stored in _docPath from the DAE _dae.
 */
NodeTransitPtr
ColladaGlobal::doRead(void)
{
    NodeTransitPtr rootN(NULL);

    if(_statColl == NULL)
        _statColl = new StatCollector;

    // force creation of the statistic elements
    _statColl->getElem(statNGeometryCreated, true);
    _statColl->getElem(statNGeometryUsed,    true);
    _statColl->getElem(statNMaterialCreated, true);
    _statColl->getElem(statNMaterialUsed,    true);
    _statColl->getElem(statNLightCreated,    true);
    _statColl->getElem(statNLightUsed,       true);
    _statColl->getElem(statNTextureCreated,  true);
    _statColl->getElem(statNTextureUsed,     true);

    _statColl->reset  (StatElemDescBase::RESET_ALWAYS);

    _globalsAtt = GlobalsAttachment::create();
    _docRoot    = dynamic_cast<domCOLLADA *>(_dae->getRoot(_docPath));

    if(_docRoot != NULL)
    {
        ColladaCOLLADARefPtr colCOL = dynamic_pointer_cast<ColladaCOLLADA>(
                                          ColladaElementFactory::the()->create(_docRoot, this));

        colCOL->read(NULL);

        for(UInt32 i = 0; _instQueue.empty() == false; ++i)
        {
            if(i > 10)
            {
                SWARNING << "ColladaGlobal::doRead: InstanceQueue loop "
                         << "maximum iteration count reached." << std::endl;
                break;
            }

            InstanceQueue workQueue;
            workQueue.swap(_instQueue);

            InstanceQueueIt iqIt  = workQueue.begin();
            InstanceQueueIt iqEnd = workQueue.end  ();

            for(; iqIt != iqEnd; ++iqIt)
                (*iqIt)->process();
        }
    }
    else
    {
        SWARNING << "ColladaGlobal::read: collada-dom failed to obtain "
                 << "document root for file [" << _docPath << "]."
                 << std::endl;
    }

    if(_globalsAtt->getMFElements()->empty() == false)
        _rootN->addAttachment(_globalsAtt);

    rootN = _rootN;

    _docRoot    = NULL;
    _globalsAtt = NULL;
    _instQueue  .clear();
    _loaderState.clear();
    _elemStore  .clear();

#ifndef OSG_COLLADA_SILENT
    std::string statString;
    _statColl->putToString(statString);

    OSG_COLLADA_LOG(("ColladaGlobal:read: Statistics\n%s\n",
                     statString.c_str()));
#endif // OSG_COLLADA_SILENT

    return rootN;
}