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); } } } } } }
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); }