mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-07 03:12:36 +01:00
Initial CharacterObject Clump implementation
This commit is contained in:
parent
1514bd2cc5
commit
3163a5dd57
@ -4,20 +4,12 @@
|
||||
#include <objects/ProjectileObject.hpp>
|
||||
|
||||
void Weapon::fireHitscan(WeaponData* weapon, CharacterObject* owner) {
|
||||
auto handFrame = owner->getModel()->findFrame("srhand");
|
||||
glm::mat4 handMatrix;
|
||||
if (handFrame) {
|
||||
while (handFrame->getParent()) {
|
||||
handMatrix =
|
||||
owner->skeleton->getMatrix(handFrame->getIndex()) * handMatrix;
|
||||
handFrame = handFrame->getParent();
|
||||
}
|
||||
}
|
||||
auto handFrame = owner->getClump()->findFrame("srhand");
|
||||
glm::mat4 handMatrix = handFrame->getWorldTransform();
|
||||
|
||||
const auto& raydirection = owner->getLookDirection();
|
||||
const auto rayend = owner->getPosition() + raydirection * weapon->hitRange;
|
||||
auto handPos = glm::vec3(handMatrix[3]);
|
||||
auto fireOrigin = owner->getPosition() + owner->getRotation() * handPos;
|
||||
auto fireOrigin = glm::vec3(handMatrix[3]);
|
||||
float dmg = weapon->damage;
|
||||
|
||||
owner->engine->doWeaponScan({dmg, fireOrigin, rayend, weapon});
|
||||
|
@ -71,6 +71,7 @@ CharacterObject::CharacterObject(GameWorld* engine, const glm::vec3& pos,
|
||||
animations.ko_shot_front = engine->data->animations["ko_shot_front"];
|
||||
|
||||
auto info = getModelInfo<PedModelInfo>();
|
||||
setClump(ClumpPtr(info->getModel()->clone()));
|
||||
if (info->getModel()) {
|
||||
setModel(info->getModel());
|
||||
skeleton = new Skeleton;
|
||||
@ -108,9 +109,8 @@ void CharacterObject::createActor(const glm::vec2& size) {
|
||||
physCharacter =
|
||||
new btKinematicCharacterController(physObject, physShape, 0.30f, 2);
|
||||
#else
|
||||
physCharacter =
|
||||
new btKinematicCharacterController(physObject, physShape, 0.30f,
|
||||
btVector3(0.f, 0.f, 1.f));
|
||||
physCharacter = new btKinematicCharacterController(
|
||||
physObject, physShape, 0.30f, btVector3(0.f, 0.f, 1.f));
|
||||
#endif
|
||||
physCharacter->setFallSpeed(20.f);
|
||||
physCharacter->setUseGhostSweepTest(true);
|
||||
@ -220,42 +220,41 @@ glm::vec3 CharacterObject::updateMovementAnimation(float dt) {
|
||||
}
|
||||
|
||||
// If we have to, interrogate the movement animation
|
||||
if (movementAnimation != animations.idle) {
|
||||
if (!getModel()->frames[0]->getChildren().empty()) {
|
||||
ModelFrame* root = getModel()->frames[0]->getChildren()[0];
|
||||
auto it = movementAnimation->bones.find(root->getName());
|
||||
if (it != movementAnimation->bones.end()) {
|
||||
AnimationBone* rootBone = it->second;
|
||||
float step = dt;
|
||||
const float duration =
|
||||
animator->getAnimation(AnimIndexMovement)->duration;
|
||||
float animTime = fmod(
|
||||
animator->getAnimationTime(AnimIndexMovement), duration);
|
||||
|
||||
// Handle any remaining transformation before the end of the
|
||||
// keyframes
|
||||
if ((animTime + step) > duration) {
|
||||
glm::vec3 a =
|
||||
rootBone->getInterpolatedKeyframe(animTime).position;
|
||||
glm::vec3 b =
|
||||
rootBone->getInterpolatedKeyframe(duration).position;
|
||||
glm::vec3 d = (b - a);
|
||||
animTranslate.y += d.y;
|
||||
step -= (duration - animTime);
|
||||
animTime = 0.f;
|
||||
}
|
||||
const auto& modelroot = getModel()->getFrame();
|
||||
if (movementAnimation != animations.idle &&
|
||||
!modelroot->getChildren().empty()) {
|
||||
const auto& root = modelroot->getChildren()[0];
|
||||
auto it = movementAnimation->bones.find(root->getName());
|
||||
if (it != movementAnimation->bones.end()) {
|
||||
AnimationBone* rootBone = it->second;
|
||||
float step = dt;
|
||||
const float duration =
|
||||
animator->getAnimation(AnimIndexMovement)->duration;
|
||||
float animTime =
|
||||
fmod(animator->getAnimationTime(AnimIndexMovement), duration);
|
||||
|
||||
// Handle any remaining transformation before the end of the
|
||||
// keyframes
|
||||
if ((animTime + step) > duration) {
|
||||
glm::vec3 a =
|
||||
rootBone->getInterpolatedKeyframe(animTime).position;
|
||||
glm::vec3 b =
|
||||
rootBone->getInterpolatedKeyframe(animTime + step).position;
|
||||
rootBone->getInterpolatedKeyframe(duration).position;
|
||||
glm::vec3 d = (b - a);
|
||||
animTranslate.y += d.y;
|
||||
|
||||
Skeleton::FrameData fd = skeleton->getData(root->getIndex());
|
||||
fd.a.translation.y = 0.f;
|
||||
skeleton->setData(root->getIndex(), fd);
|
||||
step -= (duration - animTime);
|
||||
animTime = 0.f;
|
||||
}
|
||||
|
||||
glm::vec3 a = rootBone->getInterpolatedKeyframe(animTime).position;
|
||||
glm::vec3 b =
|
||||
rootBone->getInterpolatedKeyframe(animTime + step).position;
|
||||
glm::vec3 d = (b - a);
|
||||
animTranslate.y += d.y;
|
||||
|
||||
Skeleton::FrameData fd = skeleton->getData(root->getIndex());
|
||||
fd.a.translation.y = 0.f;
|
||||
skeleton->setData(root->getIndex(), fd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,8 +275,7 @@ void CharacterObject::tick(float dt) {
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterObject::setRotation(const glm::quat &orientation)
|
||||
{
|
||||
void CharacterObject::setRotation(const glm::quat& orientation) {
|
||||
m_look.x = glm::roll(orientation);
|
||||
rotation = orientation;
|
||||
}
|
||||
@ -332,6 +330,7 @@ void CharacterObject::updateCharacter(float dt) {
|
||||
yaw += std::atan2(movement.z, movement.x);
|
||||
}
|
||||
rotation = glm::quat(glm::vec3(0.f, 0.f, yaw));
|
||||
getClump()->getFrame()->setRotation(glm::mat3_cast(rotation));
|
||||
}
|
||||
|
||||
walkDir = rotation * walkDir;
|
||||
@ -352,6 +351,7 @@ void CharacterObject::updateCharacter(float dt) {
|
||||
auto Pos =
|
||||
physCharacter->getGhostObject()->getWorldTransform().getOrigin();
|
||||
position = glm::vec3(Pos.x(), Pos.y(), Pos.z());
|
||||
getClump()->getFrame()->setTranslation(position);
|
||||
|
||||
// Handle above waist height water.
|
||||
auto wi = engine->data->getWaterIndexAt(getPosition());
|
||||
@ -407,6 +407,7 @@ void CharacterObject::setPosition(const glm::vec3& pos) {
|
||||
physCharacter->warp(bpos);
|
||||
}
|
||||
position = pos;
|
||||
getClump()->getFrame()->setTranslation(pos);
|
||||
}
|
||||
|
||||
bool CharacterObject::isAlive() const {
|
||||
@ -611,8 +612,7 @@ void CharacterObject::useItem(bool active, bool primary) {
|
||||
if (!currentState.primaryActive && active) {
|
||||
// If we've just started, activate
|
||||
controller->setNextActivity(new Activities::UseItem(item));
|
||||
}
|
||||
else if (currentState.primaryActive && !active) {
|
||||
} else if (currentState.primaryActive && !active) {
|
||||
// UseItem will cancel itself upon !primaryActive
|
||||
}
|
||||
currentState.primaryActive = active;
|
||||
|
@ -98,7 +98,7 @@ struct AnimationGroup {
|
||||
* @brief The CharacterObject struct
|
||||
* Implements Character object behaviours.
|
||||
*/
|
||||
class CharacterObject : public GameObject {
|
||||
class CharacterObject : public GameObject, public ClumpObject {
|
||||
private:
|
||||
CharacterState currentState;
|
||||
|
||||
|
@ -194,28 +194,27 @@ void ObjectRenderer::renderInstance(InstanceObject* instance,
|
||||
|
||||
void ObjectRenderer::renderCharacter(CharacterObject* pedestrian,
|
||||
RenderList& outList) {
|
||||
glm::mat4 matrixModel;
|
||||
const auto& clump = pedestrian->getClump();
|
||||
|
||||
if (pedestrian->getCurrentVehicle()) {
|
||||
auto vehicle = pedestrian->getCurrentVehicle();
|
||||
const auto& vehicleclump = vehicle->getClump();
|
||||
auto seat = pedestrian->getCurrentSeat();
|
||||
matrixModel = vehicle->getTimeAdjustedTransform(m_renderAlpha);
|
||||
auto matrixModel = vehicleclump->getFrame()->getWorldTransform();
|
||||
if (pedestrian->isEnteringOrExitingVehicle()) {
|
||||
matrixModel = glm::translate(matrixModel,
|
||||
vehicle->getSeatEntryPosition(seat));
|
||||
clump->getFrame()->setTransform(matrixModel);
|
||||
} else {
|
||||
if (seat < vehicle->info->seats.size()) {
|
||||
matrixModel = glm::translate(matrixModel,
|
||||
vehicle->info->seats[seat].offset);
|
||||
clump->getFrame()->setTransform(matrixModel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
matrixModel = pedestrian->getTimeAdjustedTransform(m_renderAlpha);
|
||||
}
|
||||
|
||||
if (!pedestrian->getModel()) return;
|
||||
|
||||
renderClump(pedestrian->getModel(), matrixModel, nullptr, outList);
|
||||
renderClump(pedestrian->getClump().get(), glm::mat4(), nullptr, outList);
|
||||
|
||||
auto item = pedestrian->getActiveItem();
|
||||
const auto& weapon = pedestrian->engine->data->weaponData[item];
|
||||
@ -224,22 +223,13 @@ void ObjectRenderer::renderCharacter(CharacterObject* pedestrian,
|
||||
return; // No model for this item
|
||||
}
|
||||
|
||||
auto handFrame = pedestrian->getModel()->findFrame("srhand");
|
||||
glm::mat4 localMatrix;
|
||||
auto handFrame = pedestrian->getClump()->findFrame("srhand");
|
||||
if (handFrame) {
|
||||
while (handFrame->getParent()) {
|
||||
localMatrix =
|
||||
pedestrian->skeleton->getMatrix(handFrame->getIndex()) *
|
||||
localMatrix;
|
||||
handFrame = handFrame->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
// Assume items are all simple
|
||||
auto simple =
|
||||
auto simple =
|
||||
m_world->data->findModelInfo<SimpleModelInfo>(weapon->modelID);
|
||||
auto itematomic = simple->getAtomic(0);
|
||||
renderAtomic(itematomic, matrixModel * localMatrix, nullptr, outList);
|
||||
auto itematomic = simple->getAtomic(0);
|
||||
renderAtomic(itematomic, handFrame->getWorldTransform(), nullptr, outList);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectRenderer::renderVehicle(VehicleObject* vehicle,
|
||||
@ -367,10 +357,6 @@ void ObjectRenderer::renderProjectile(ProjectileObject* projectile,
|
||||
}
|
||||
|
||||
void ObjectRenderer::buildRenderList(GameObject* object, RenderList& outList) {
|
||||
if (object->skeleton) {
|
||||
object->skeleton->interpolate(m_renderAlpha);
|
||||
}
|
||||
|
||||
// Right now specialized on each object type
|
||||
switch (object->type()) {
|
||||
case GameObject::Instance:
|
||||
|
Loading…
Reference in New Issue
Block a user