diff --git a/skelatool64/src/ExtendedMesh.cpp b/skelatool64/src/ExtendedMesh.cpp index 275debb..70cffe3 100644 --- a/skelatool64/src/ExtendedMesh.cpp +++ b/skelatool64/src/ExtendedMesh.cpp @@ -48,6 +48,27 @@ aiMesh* copyMesh(aiMesh* mesh) { } } + result->mNumBones = mesh->mNumBones; + result->mBones = new aiBone*[mesh->mNumBones]; + + for (unsigned i = 0; i < mesh->mNumBones; ++i) { + aiBone* newBone = new aiBone; + aiBone* oldBone = mesh->mBones[i]; + newBone->mArmature = oldBone->mArmature; + newBone->mName = oldBone->mName; + newBone->mNode = oldBone->mNode; + newBone->mNumWeights = oldBone->mNumWeights; + newBone->mOffsetMatrix = oldBone->mOffsetMatrix; + + newBone->mWeights = new aiVertexWeight[oldBone->mNumWeights]; + + for (unsigned weightIndex = 0; weightIndex < oldBone->mNumWeights; ++weightIndex) { + newBone->mWeights[weightIndex] = oldBone->mWeights[weightIndex]; + } + + result->mBones[i] = newBone; + } + result->mName = mesh->mName; return result; @@ -234,8 +255,6 @@ std::shared_ptr ExtendedMesh::Transform(const aiMatrix4x4& transfo aiMatrix3x3 inverseRotation = rotationOnly; inverseRotation.Inverse(); - - for (unsigned i = 0; i < result->mMesh->mNumVertices; ++i) { result->mMesh->mVertices[i] = transform * result->mMesh->mVertices[i]; @@ -249,6 +268,10 @@ std::shared_ptr ExtendedMesh::Transform(const aiMatrix4x4& transfo result->mNormalInverseTransform[i] = result->mNormalInverseTransform[i] * inverseRotation; } } + + for (unsigned i = 0; i < result->mMesh->mNumBones; ++i) { + result->mMesh->mBones[i]->mOffsetMatrix = result->mMesh->mBones[i]->mOffsetMatrix * inverseTransform; + } result->RecalcBB(); diff --git a/skelatool64/src/ZSorter.cpp b/skelatool64/src/ZSorter.cpp index 98d6a1e..2c3dde1 100644 --- a/skelatool64/src/ZSorter.cpp +++ b/skelatool64/src/ZSorter.cpp @@ -1,5 +1,7 @@ #include "ZSorter.h" +#include + struct SingleFace { aiFace* face; std::pair bonePair; @@ -124,31 +126,41 @@ RenderChunk renderChunksRebuildFromFaces(const aiScene* scene, std::vectormNumBones = 0; - if (start->bonePair.first) { - newAiMesh->mNumBones = boneHeirarchy.GetBoneCount(); + newAiMesh->mNumBones = source->mMesh->mNumBones; + if (newAiMesh->mNumBones) { newAiMesh->mBones = new aiBone*[newAiMesh->mNumBones]; for (unsigned i = 0; i < newAiMesh->mNumBones; ++i) { aiBone* bone = new aiBone; + aiBone* srcBone = source->mMesh->mBones[i]; - bone->mArmature = NULL; - bone->mName = start->bonePair.first->GetName(); - bone->mNode = NULL; + bone->mArmature = srcBone->mArmature; + bone->mName = srcBone->mName; + bone->mNode = srcBone->mNode; + bone->mOffsetMatrix = srcBone->mOffsetMatrix; - if (start->bonePair.first->GetName() == boneHeirarchy.BoneByIndex(i)->GetName()) { - bone->mNode = scene->mRootNode->FindNode(start->bonePair.first->GetName().c_str()); - bone->mOffsetMatrix = (settings.CreateCollisionTransform() * aiBuildOffsetMatrix(bone->mNode)).Inverse(); + std::vector attachedIndices; - bone->mNumWeights = newAiMesh->mNumVertices; - bone->mWeights = new aiVertexWeight[newAiMesh->mNumVertices]; + std::set includedBefore; + for (unsigned weightIndex = 0; weightIndex < srcBone->mNumWeights; ++weightIndex) { + includedBefore.insert(srcBone->mWeights[weightIndex].mVertexId); + } - for (unsigned index = 0; index < newAiMesh->mNumVertices; ++index) { - bone->mWeights[index].mVertexId = index; - bone->mWeights[index].mWeight = 1.0f; + for (unsigned vertexIndex = 0; vertexIndex < newAiMesh->mNumVertices; ++vertexIndex) { + unsigned sourceIndex = mesh.sourceIndex[vertexIndex]; + + if (includedBefore.find(sourceIndex) != includedBefore.end()) { + attachedIndices.push_back(vertexIndex); } - } else { - bone->mNumWeights = 0; + } + + bone->mNumWeights = attachedIndices.size(); + bone->mWeights = new aiVertexWeight[attachedIndices.size()]; + + for (unsigned weightIndex = 0; weightIndex < attachedIndices.size(); ++weightIndex) { + bone->mWeights[weightIndex].mVertexId = attachedIndices[weightIndex]; + bone->mWeights[weightIndex].mWeight = 1.0f; } newAiMesh->mBones[i] = bone; diff --git a/src/scene/portal_gun.c b/src/scene/portal_gun.c index 71dea33..2c1207a 100644 --- a/src/scene/portal_gun.c +++ b/src/scene/portal_gun.c @@ -22,12 +22,13 @@ struct Transform gGunTransform = { {0.0f, 0.0f, 0.0f}, - {0.0f, 0.0f, 0.0f, 1.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f}, }; void portalGunInit(struct PortalGun* portalGun, struct Transform* at){ skArmatureInit(&portalGun->armature, &portal_gun_v_portalgun_armature); + skAnimatorInit(&portalGun->animator, portal_gun_v_portalgun_armature.numberOfBones); portalGun->portalGunVisible = 0; portalGun->shootAnimationTimer = 0.0; portalGun->shootTotalAnimationTimer = 0.0; @@ -37,6 +38,8 @@ void portalGunInit(struct PortalGun* portalGun, struct Transform* at){ portalTrailInit(&portalGun->projectiles[0].trail); portalTrailInit(&portalGun->projectiles[1].trail); + + skAnimatorRunClip(&portalGun->animator, &portal_gun_v_portalgun_Armature_pickup_clip, 0.0f, SKAnimatorFlagsLoop); } #define PORTAL_PROJECTILE_RADIUS 0.15f @@ -120,7 +123,7 @@ void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* render } u16 perspectiveNormalize; - guPerspective(&matrix[1], &perspectiveNormalize, fromCamera->fov, getAspect(), 0.05f * SCENE_SCALE, 2.0f * SCENE_SCALE, 1.0f); + guPerspective(&matrix[1], &perspectiveNormalize, fromCamera->fov, getAspect(), 0.05f * SCENE_SCALE, 4.0f * SCENE_SCALE, 1.0f); gSPMatrix(renderState->dl++, &matrix[1], G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH); gSPLookAt(renderState->dl++, &gLookAt); @@ -149,6 +152,7 @@ void portalGunUpdatePosition(struct PortalGun* portalGun, struct Player* player) } void portalGunUpdate(struct PortalGun* portalGun, struct Player* player) { + skAnimatorUpdate(&portalGun->animator, portalGun->armature.pose, FIXED_DELTA_TIME); portalGunUpdatePosition(portalGun, player); if (player->flags & (PlayerHasFirstPortalGun | PlayerHasSecondPortalGun)) { diff --git a/src/scene/portal_gun.h b/src/scene/portal_gun.h index 64961c1..7eae7ea 100644 --- a/src/scene/portal_gun.h +++ b/src/scene/portal_gun.h @@ -12,6 +12,7 @@ #include "../effects/portal_trail.h" #include "../scene/camera.h" #include "../sk64/skelatool_armature.h" +#include "../sk64/skelatool_animator.h" struct PortalGunProjectile { struct Ray positionDirection; @@ -30,6 +31,7 @@ struct PortalGunProjectile { struct PortalGun { struct SKArmature armature; + struct SKAnimator animator; int portalGunVisible; float shootAnimationTimer; float shootTotalAnimationTimer;