//----------------------------------------------------------------------- void HardwareSkinning::addPositionCalculations(Function* vsMain, int& funcCounter) { FunctionInvocation* curFuncInvocation = NULL; if (mDoBoneCalculations == true) { //set functions to calculate world position for(int i = 0 ; i < getWeightCount() ; ++i) { addIndexedPositionWeight(vsMain, i, funcCounter); } //update back the original position relative to the object curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInInvWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //update the projective position thereby filling the transform stage role curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //update from object to world space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //update from object to projective space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } }
//----------------------------------------------------------------------- void DualQuaternionSkinning::addPositionCalculations(Function* vsMain, int& funcCounter) { FunctionInvocation* curFuncInvocation = NULL; if (mDoBoneCalculations == true) { if(mScalingShearingSupport) { //Construct a scaling and shearing matrix based on the blend weights for(int i = 0 ; i < getWeightCount() ; ++i) { //Assign the local param based on the current index of the scaling and shearing matrices curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInScaleShearMatrices, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexToMask(i), 1); curFuncInvocation->pushOperand(mParamTempFloat3x4, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Calculate the resultant scaling and shearing matrix based on the weights given addIndexedPositionWeight(vsMain, i, mParamTempFloat3x4, mParamTempFloat3x4, mParamBlendS, funcCounter); } //Transform the position based by the scaling and shearing matrix curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamBlendS, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mParamLocalBlendPosition, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //Assign the input position to the local blended position curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mParamLocalBlendPosition, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } //Set functions to calculate world position for(int i = 0 ; i < getWeightCount() ; ++i) { //Set the index of the matrix curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexToMask(i)); curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Multiply the index by 2 curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(2.0f), Operand::OPS_IN); curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Add 1 to the index and assign as the second row's index curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0f), Operand::OPS_IN); curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamIndex2, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Build the dual quaternion matrix curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_BUILD_DUAL_QUATERNION_MATRIX, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_IN, Operand::OPM_ALL, 1); curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamIndex2, Operand::OPS_IN, Operand::OPM_ALL, 1); curFuncInvocation->pushOperand(mParamTempFloat2x4, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Adjust the podalities of the dual quaternions if(mCorrectAntipodalityHandling) { adjustForCorrectAntipodality(vsMain, i, funcCounter, mParamTempFloat2x4); } //Calculate the resultant dual quaternion based on the weights given addIndexedPositionWeight(vsMain, i, mParamTempFloat2x4, mParamTempFloat2x4, mParamBlendDQ, funcCounter); } //Normalize the dual quaternion curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_NORMALIZE_DUAL_QUATERNION, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamBlendDQ, Operand::OPS_INOUT); vsMain->addAtomInstance(curFuncInvocation); //Calculate the blend position curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_CALCULATE_BLEND_POSITION, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamLocalBlendPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamBlendDQ, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //Update from object to projective space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //update from object to world space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //update from object to projective space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } }