1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-18 16:32:32 +02:00

Initial CharacterObject Clump implementation

This commit is contained in:
Daniel Evans 2017-01-08 02:52:04 +00:00
parent 1514bd2cc5
commit 3163a5dd57
4 changed files with 51 additions and 73 deletions

View File

@ -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});

View File

@ -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;

View File

@ -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;

View File

@ -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: