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