stuff
This commit is contained in:
+37
-70
@@ -1,7 +1,9 @@
|
||||
#include "Character.h"
|
||||
#include "Animator.h"
|
||||
#include "Ragdoll.h"
|
||||
#include "tFunctions.h"
|
||||
#include <cctype>
|
||||
#include <cfloat>
|
||||
#include <cmath>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
@@ -89,46 +91,6 @@ void Character::TurnToDirection(float dt) {
|
||||
body->t.RotateToQuaternion(glm::normalize(glm::slerp(current, target, blend)));
|
||||
}
|
||||
|
||||
void Character::SetPunchAnimation(Animation* animation) {
|
||||
if (!body || !animation)
|
||||
return;
|
||||
|
||||
if (!punchAnimator) {
|
||||
punchAnimator = body->AddAnimator(10);
|
||||
punchAnimator->blendDuration = 0.08f;
|
||||
}
|
||||
|
||||
punchAnimation = animation;
|
||||
punchAnimator->SetAnimation(animation);
|
||||
punchAnimator->loops = false;
|
||||
punchAnimator->playbackSpeed = punchAnimationSpeed;
|
||||
punchAnimator->onAnimationEnd = [this]() { OnPunchAnimationEnd(); };
|
||||
punchAnimator->StopAnimation();
|
||||
punchHitbox.active = false;
|
||||
punchHitbox.hitTargets.clear();
|
||||
}
|
||||
|
||||
void Character::SetPunchLooping(bool looping) {
|
||||
if (punchAnimator)
|
||||
punchAnimator->loops = looping;
|
||||
}
|
||||
|
||||
void Character::Punch(const glm::vec3& lookDirection) {
|
||||
if (!punchAnimation || !punchAnimator || punchAnimator->isPlaying)
|
||||
return;
|
||||
|
||||
const glm::vec3 flatLook(lookDirection.x, 0.0f, lookDirection.z);
|
||||
punchLookLocked = glm::length(flatLook) > 0.0001f;
|
||||
if (punchLookLocked) {
|
||||
punchLookDirection = glm::normalize(flatLook);
|
||||
SetTurnDirection(punchLookDirection);
|
||||
}
|
||||
|
||||
punchHitbox.hitTargets.clear();
|
||||
punchAnimator->playbackSpeed = punchAnimationSpeed;
|
||||
punchAnimator->PlayAnimation();
|
||||
}
|
||||
|
||||
void Character::SetWalking(bool walking) {
|
||||
if (body && body->animator)
|
||||
body->animator->playbackSpeed = walking ? 1.0f : 0.0f;
|
||||
@@ -146,24 +108,38 @@ glm::vec3 Character::GetForwardDirection() const {
|
||||
return forward / length;
|
||||
}
|
||||
|
||||
void Character::OnPunchAnimationEnd() {
|
||||
void Character::EnableRagdoll(Physics& physics) {
|
||||
if (!ragdoll)
|
||||
ragdoll = new Ragdoll(*body, GetRigMatrix(), physics);
|
||||
}
|
||||
|
||||
glm::mat4 Character::GetRigMatrix() const {
|
||||
// body->t's scale is the hitbox only; the rig is drawn at visualScale so it fills that hitbox
|
||||
return body->t.GetTranslationMatrix() * body->t.GetRotationMatrix()
|
||||
* glm::scale(glm::mat4(1.0f), glm::vec3(visualScale));
|
||||
}
|
||||
|
||||
bool Character::GetWorldBounds(BoundingBox& bounds) const {
|
||||
if (!body)
|
||||
return;
|
||||
return false;
|
||||
|
||||
punchHitbox.hitTargets.clear();
|
||||
if (ragdoll && !ragdoll->GetParts().empty()) {
|
||||
bounds.min = glm::vec3(FLT_MAX);
|
||||
bounds.max = glm::vec3(-FLT_MAX);
|
||||
for (const Ragdoll::Part* part : ragdoll->GetParts()) {
|
||||
const BoundingBox partBounds = part->transform.t.GetAABB();
|
||||
bounds.min = glm::min(bounds.min, partBounds.min);
|
||||
bounds.max = glm::max(bounds.max, partBounds.max);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
glm::vec3 forward = -body->t.GetFrontVector();
|
||||
forward.y = 0.0f;
|
||||
if (glm::length(forward) <= 0.0001f)
|
||||
return;
|
||||
forward = glm::normalize(forward);
|
||||
|
||||
punchHitbox.transform.TranslateTo(body->t.GetTranslation() + forward * punchReach);
|
||||
punchHitbox.transform.RotateToQuaternion(LookAt(forward));
|
||||
punchHitbox.transform.ScaleTo(punchHitboxSize);
|
||||
punchHitbox.damage = (int)punchDamage;
|
||||
punchHitbox.knockback = 3.5f;
|
||||
punchHitbox.active = true;
|
||||
// The rig is about 2 units across natively in every direction it reaches, arms out included.
|
||||
// A cube that size around the body covers any pose and any turn.
|
||||
const glm::vec3 reach(visualScale);
|
||||
bounds.min = body->t.GetTranslation() - reach;
|
||||
bounds.max = body->t.GetTranslation() + reach;
|
||||
return true;
|
||||
}
|
||||
|
||||
Character::Character() {
|
||||
@@ -174,24 +150,15 @@ Character::Character() {
|
||||
|
||||
void Character::Render(Shader& shader) {
|
||||
if (!body || !body->rig || !body->animator) return;
|
||||
if (body->animator->m_CurrentAnimation == nullptr) {
|
||||
for (int i = 0; i < 100; i++)
|
||||
shader.SetMat4(("finalBonesMatrices[" + std::to_string(i) + "]").c_str(), glm::mat4(1.0f));
|
||||
}
|
||||
else {
|
||||
std::vector<glm::mat4> transforms = body->GetBlendedBoneMatrices();
|
||||
|
||||
for (int i = 0; i < transforms.size(); i++)
|
||||
shader.SetMat4(("finalBonesMatrices[" + std::to_string(i) + "]").c_str(), transforms[i]);
|
||||
}
|
||||
const std::vector<glm::mat4> transforms = ragdoll ? ragdoll->GetBoneMatrices()
|
||||
: body->animator->m_CurrentAnimation ? body->GetBlendedBoneMatrices()
|
||||
: std::vector<glm::mat4>(100, glm::mat4(1.0f));
|
||||
shader.SetMat4Array("finalBonesMatrices", transforms.data(), glm::min((int)transforms.size(), 100));
|
||||
shader.Set4F("colorOverride", colorOverride);
|
||||
shader.SetInt("useTexture", 0);
|
||||
shader.SetInt("tex", 1);
|
||||
surface.Apply(shader, 1, glm::vec3(visualScale));
|
||||
shader.Set1F("metallic", metallic);
|
||||
shader.Set1F("roughness", roughness);
|
||||
shader.Set1F("ao", ao);
|
||||
// body->t's scale is the hitbox only; the rig is drawn at visualScale so it fills that hitbox
|
||||
body->rig->Render(shader, body->t.GetTranslationMatrix() * body->t.GetRotationMatrix()
|
||||
* glm::scale(glm::mat4(1.0f), glm::vec3(visualScale)));
|
||||
body->rig->Render(shader, ragdoll ? glm::mat4(1.0f) : GetRigMatrix()); // ragdoll bones are already in world space
|
||||
shader.Set4F("colorOverride", glm::vec4(0.0f)); // don't leak into other rig draws
|
||||
}
|
||||
Reference in New Issue
Block a user