void GeoVectorPropertyBase::execSyncV(      FieldContainer    &oFrom,
        ConstFieldMaskArg  whichField,
        AspectOffsetStore &oOffsets,
        ConstFieldMaskArg  syncMode,
        const UInt32             uiSyncInfo)
{
    GeoVectorProperty *pThis = static_cast<GeoVectorProperty *>(this);

    pThis->execSync(static_cast<GeoVectorProperty *>(&oFrom),
                    whichField,
                    oOffsets,
                    syncMode,
                    uiSyncInfo);
}
void CPUSkinningAlgorithm::transformGeometry(
    SkinnedGeometry           *skinGeo,
    Skeleton                  *skel,
    CPUSkinningDataAttachment *data)
{
    const SkinnedGeometry::MFPropIndicesType *mfOrigIdx   =
        skinGeo->getMFPropIndices();
    const SkinnedGeometry::MFPropertiesType  *mfOrigProps =
        skinGeo->getMFProperties();
    SkinnedGeometry::MFPropertiesType        *mfProps     =
        data->editMFProperties();

    const GeoVec4fProperty *jointIdxProp    =
        dynamic_cast<const GeoVec4fProperty *>(
            (*mfOrigProps)[skinGeo->getJointIndexProperty()]);
    const GeoVec4fProperty *jointWeightProp =
        dynamic_cast<const GeoVec4fProperty *>(
            (*mfOrigProps)[skinGeo->getJointWeightProperty()]);

    if(skinGeo->getIndex(skinGeo->getJointIndexProperty ()) !=
       skinGeo->getIndex(skinGeo->getJointWeightProperty())   )
    {
        SWARNING << "CPUSkinningAlgorithm::transformGeometry: "
                 << "Multi indexed geometry not supported!"
                 << std::endl;
        return;
    }

    mfProps->resize(mfOrigProps->size(), NULL);

    const MFMatrix *mfJointMat       = NULL;
    const MFMatrix *mfJointNormalMat = NULL;

    // if the geometry has a non-identity bind shape matrix
    // premultiply joint matrices with bind shape matrix and store in data
    // attachment
    if(skinGeo->getBindShapeMatrix().equals(Matrix::identity(), Eps) == false)
    {
        mfJointMat               = skel->getMFJointMatrices ();
        MFMatrix *mfJointBindMat = data->editMFJointMatrices();

        mfJointBindMat->resize(mfJointMat->size());

        for(UInt32 i = 0; i < mfJointMat->size(); ++i)
        {
            (*mfJointBindMat)[i] = (*mfJointMat)[i];
            (*mfJointBindMat)[i].mult(skinGeo->getBindShapeMatrix());
        }

        mfJointMat = data->getMFJointMatrices();

        if(skel->getCalcNormalMatrices() == true)
        {
            mfJointNormalMat               = skel->getMFJointNormalMatrices ();
            MFMatrix *mfJointNormalBindMat = data->editMFJointNormalMatrices();

            mfJointNormalBindMat->resize(mfJointNormalMat->size());

            for(UInt32 i = 0; i < mfJointNormalMat->size(); ++i)
            {
                (*mfJointNormalBindMat)[i] = (*mfJointNormalMat)[i];
                (*mfJointNormalBindMat)[i].mult(skinGeo->getBindShapeMatrix());
            }

            mfJointNormalMat = data->getMFJointNormalMatrices();
        }
        else
        {
            mfJointNormalMat = data->getMFJointMatrices();
        }
    }
    else
    {
        mfJointMat = skel->getMFJointMatrices();

        if(skel->getCalcNormalMatrices() == true)
        {
            mfJointNormalMat = skel->getMFJointNormalMatrices();
        }
        else
        {
            mfJointNormalMat = skel->getMFJointMatrices();
        }
    }

    // transform all properties

    for(UInt16 i = 0; i < mfProps->size(); ++i)
    {
        // do not transform the vertex joint indices/weights
        if(i == skinGeo->getJointIndexProperty () ||
           i == skinGeo->getJointWeightProperty()   )
        {
            continue;
        }

        GeoIntegralProperty *origPropIdx = (*mfOrigIdx  )[i];
        GeoVectorProperty   *origProp    = (*mfOrigProps)[i];
        GeoVectorProperty   *prop        = (*mfProps    )[i];

        if(origProp == NULL)
            continue;

        if(prop == NULL)
        {
            GeoVectorPropertyUnrecPtr newProp =
                dynamic_pointer_cast<GeoVectorProperty>(origProp->clone());

            mfProps->replace(i, newProp);
            prop = newProp;
        }
        else if(prop->size() != origProp->size())
        {
            prop->resize(origProp->size());
        }

        switch(origProp->getUsage() & GeoProperty::UsageSpaceMask)
        {
        case GeoProperty::UsageObjectSpace:
        {
             transformObjectSpaceProperty(
                 mfJointMat,
                 jointIdxProp, jointWeightProp,
                 origPropIdx, origProp, prop);
        }
        break;

        case GeoProperty::UsageTangentSpace:
        {
            transformTangentSpaceProperty(
                mfJointNormalMat,
                jointIdxProp, jointWeightProp,
                origPropIdx, origProp, prop);
        }
        break;

        default:
            // only need to transform object/tangent space properties
            break;
        }
    }
}
/*! Push \a srcTrans into \a dstGeo
 */
void TransformPushGraphOp::pushToGeometry(
    const Transform *srcTrans, Geometry *dstGeo)
{
    typedef Vec4f  VecType;
    typedef Pnt3f  PntType;
    
    Matrix mat    = srcTrans->getMatrix();
    Matrix invMat = mat;

    invMat[3][0] = invMat[3][1] = invMat[3][2] = 0.f;

    invMat.invert   ();
    invMat.transpose();

    const Geometry::SFLengthsType     *sfLen  = dstGeo->getSFLengths     ();
          Geometry::MFPropertiesType  *mfProp = dstGeo->editMFProperties ();
          Geometry::MFPropIndicesType *mfInd  = dstGeo->editMFPropIndices();
    
    Geometry::MFPropertiesType::const_iterator  propIt  = mfProp->begin();
    Geometry::MFPropertiesType::const_iterator  propEnd = mfProp->end  ();
    
    Geometry::MFPropIndicesType::const_iterator indIt   = mfInd ->begin();
    Geometry::MFPropIndicesType::const_iterator indEnd  = mfInd ->end  ();
    
    UInt32 propUsed = 0;
    for(UInt32 i = 0; i < sfLen->getValue()->size(); ++i)
        propUsed += sfLen->getValue()->getValue<UInt32>(i);
    
    for(; propIt != propEnd && indIt != indEnd; ++propIt, ++indIt)
    {
              GeoVectorProperty   *prop = *propIt;
        const GeoIntegralProperty *ind  = *indIt;
        
        if(prop == NULL)
            continue;
        
        if(ind == NULL)
        {
            // unindexed
            if((prop->getUsage() & GeoProperty::UsageObjectSpace) != 0x0000)
            {
                // transform with mat
                for(UInt32 i = 0; i < propUsed; ++i)
                {
                    PntType pnt = prop->getValue<PntType>(i);
                    mat.multFull(pnt, pnt);
                    prop->setValue(pnt, i);
                }
            }
            else if((prop->getUsage() & GeoProperty::UsageTangentSpace) != 0x0000)
            {
                // transform with invMat
                for(UInt32 i = 0; i < propUsed; ++i)
                {
                    VecType vec = prop->getValue<VecType>(i);
                    invMat.mult(vec, vec);
                    prop->setValue(vec, i);
                }
            }
        }
        else
        {
            std::set<UInt32> transInd;
            
            if((prop->getUsage() & GeoProperty::UsageObjectSpace) != 0x0000)
            {
                // transform with mat
                for(UInt32 i = 0; i < propUsed; ++i)
                {
                    UInt32 j = ind->getValue(i);
                    
                    if(transInd.find(j) == transInd.end())
                    {
                        PntType pnt = prop->getValue<PntType>(j);
                        mat.multFull(pnt, pnt);
                        prop->setValue(pnt, j);
                        
                        transInd.insert(j);
                    }
                }
            }
            else if((prop->getUsage() & GeoProperty::UsageTangentSpace) != 0x0000)
            {
                // transform with invMat
                for(UInt32 i = 0; i < propUsed; ++i)
                {
                    UInt32 j = ind->getValue(i);
                    
                    if(transInd.find(j) == transInd.end())
                    {
                        VecType vec = prop->getValue<VecType>(j);
                        invMat.mult(vec, vec);
                        prop->setValue(vec, j);
                        
                        transInd.insert(j);
                    }
                }
            }
        }
    }
}
Пример #4
0
void Geometry::fill(DrawableStatsAttachment *pStat)
{
    if(pStat == NULL)
    {
        FINFO(("Geometry::fill(DrawableStatsAttachment *): "
               "No attachment given.\n"));

        return;
    }

    // Att Bytes
    UInt32 storedAttBytes    = 0;
    UInt32 attBytesPerVertex = 0;

    for(UInt16 i = 0; i < Geometry::MaxAttribs; ++i)
    {
        if(this->getProperty(i) == NULL)
            continue;

        attBytesPerVertex += this->getProperty(i)->getFormatSize() *
                             this->getProperty(i)->getDimension();
        storedAttBytes    += this->getProperty(i)->getFormatSize() *
                             this->getProperty(i)->getDimension()  *
                             this->getProperty(i)->size();
    }


    GeoIntegralProperty *geoTypePtr = this->getTypes();
    GeoIntegralProperty *lensPtr    = this->getLengths();

    UInt32 lN, tN, len, type;

    lN = (lensPtr    == NULL) ? 0 : lensPtr   ->getSize();
    tN = (geoTypePtr == NULL) ? 0 : geoTypePtr->getSize();

    if((tN == 0) || (lN != 0 && tN != lN) || (lN == 0 && tN != 1))
    {
        FINFO(("GeoStatsAttachment::calc: "
               "Lengths and Types information mismatch.\n"));
        return;
    }

    UInt32 triangle = 0, line = 0, point = 0, vertices = 0,
           procAttBytes = 0;

    for(UInt32 i = 0; i < tN; ++i)
    {
        geoTypePtr->getValue(type, i);

        if(lN != 0)
        {
            lensPtr->getValue(len, i);
        }
        else
        {
            GeoVectorProperty *pos = this->getPositions();

            if(pos == NULL)
            {
                FINFO(("GeoStatsAttachment::calc: No Positions!\n"));
                return;
            }

            len = pos->size();
        }

        vertices     += len;
        procAttBytes += len * attBytesPerVertex;

        switch(type)
        {
            case GL_POINTS:
                point += len;
                break;
            case GL_LINES:
                line += len / 2;
                break;
            case GL_LINE_LOOP:
                line += len;
                break;
            case GL_LINE_STRIP:
                line += len - 1;
                break;
            case GL_TRIANGLES:
                triangle += len / 3;
                break;
            case GL_TRIANGLE_STRIP:
                triangle += len - 2;
                break;
            case GL_TRIANGLE_FAN:
                triangle += len - 2;
                break;
            case GL_QUADS:
                triangle += len / 2;
                break;
            case GL_QUAD_STRIP:
                triangle += len - 2;
                break;
            case GL_POLYGON:
                triangle += len - 2;
                break;
            default:
                FWARNING(("GeoStatsAttachment::calc: Invalid geoType: %d\n",
                          type));
                break;
        }
    }

    pStat->setVertices(vertices);
    pStat->setPoints(point);
    pStat->setLines(line);
    pStat->setTriangles(triangle);
    pStat->setStoredAttributeBytes(storedAttBytes);
    pStat->setProcessedAttributeBytes(procAttBytes);
    pStat->setValid(true);
}