| 1471 | } |
| 1472 | |
| 1473 | uint8_t* GenerateVertexDataFromAttributes(dmRig::HRigContext context, dmRig::HRigInstance instance, dmRigDDF::Mesh* mesh, const dmVMath::Matrix4& world_matrix, const dmVMath::Matrix4& normal_matrix, const dmGraphics::VertexAttributeInfos* attribute_infos, uint32_t vertex_stride, uint8_t* vertex_data_out) |
| 1474 | { |
| 1475 | const dmRigDDF::Model* model = instance->m_Model; |
| 1476 | |
| 1477 | if (!model || !mesh || !instance->m_DoRender) |
| 1478 | { |
| 1479 | return vertex_data_out; |
| 1480 | } |
| 1481 | |
| 1482 | dmArray<Matrix4>& pose_matrices = context->m_ScratchPoseMatrixBuffer; |
| 1483 | dmArray<Vector3>& positions_world = context->m_ScratchPositionBufferWorld; |
| 1484 | dmArray<Vector3>& positions_local = context->m_ScratchPositionBufferLocal; |
| 1485 | dmArray<Vector3>& normals = context->m_ScratchNormalBuffer; |
| 1486 | dmArray<Vector4>& tangents = context->m_ScratchTangentBuffer; |
| 1487 | |
| 1488 | uint32_t bone_count = GetBoneCount(instance); |
| 1489 | uint32_t vertex_count = mesh->m_Positions.m_Count / 3; |
| 1490 | |
| 1491 | dmGraphics::VertexAttributeInfoMetadata meta_datas = dmGraphics::GetVertexAttributeInfosMetaData(*attribute_infos); |
| 1492 | |
| 1493 | pose_matrices.SetSize(0); |
| 1494 | |
| 1495 | float* positions_buffer_world = 0; |
| 1496 | float* positions_buffer_local = 0; |
| 1497 | float* normals_buffer = 0; |
| 1498 | float* tangents_buffer = 0; |
| 1499 | |
| 1500 | if (meta_datas.m_HasAttributeWorldPosition || meta_datas.m_HasAttributeLocalPosition) |
| 1501 | { |
| 1502 | if (bone_count) |
| 1503 | { |
| 1504 | EnsureSize(pose_matrices, bone_count); |
| 1505 | PoseToMatrix(instance->m_Pose, pose_matrices.Begin()); |
| 1506 | |
| 1507 | // Premultiply pose matrices with the bind pose inverse so they |
| 1508 | // can be directly be used to transform each vertex. |
| 1509 | const dmArray<RigBone>& bind_pose = *instance->m_BindPose; |
| 1510 | for (uint32_t bi = 0; bi < pose_matrices.Size(); ++bi) |
| 1511 | { |
| 1512 | Matrix4& pose_matrix = pose_matrices[bi]; |
| 1513 | pose_matrix = pose_matrix * bind_pose[bi].m_ModelToLocal; |
| 1514 | } |
| 1515 | } |
| 1516 | |
| 1517 | if (meta_datas.m_HasAttributeWorldPosition) |
| 1518 | { |
| 1519 | EnsureSize(positions_world, vertex_count); |
| 1520 | positions_buffer_world = (float*) positions_world.Begin(); |
| 1521 | } |
| 1522 | if (meta_datas.m_HasAttributeLocalPosition) |
| 1523 | { |
| 1524 | EnsureSize(positions_local, vertex_count); |
| 1525 | positions_buffer_local = (float*) positions_local.Begin(); |
| 1526 | } |
| 1527 | |
| 1528 | dmRig::GeneratePositionData(mesh, world_matrix, pose_matrices, positions_buffer_world, positions_buffer_local); |
| 1529 | } |
| 1530 | if (meta_datas.m_HasAttributeNormal && mesh->m_Normals.m_Count) |
no test coverage detected