From: Côme Chilliet Date: Fri, 9 Dec 2016 09:29:14 +0000 (+0700) Subject: Moved Skeleton and Animation to their own folder. X-Git-Url: https://git.jsancho.org/?a=commitdiff_plain;h=4d0ec1838440e55f24e8ec9501a62348cd9e2ec3;p=lugaru.git Moved Skeleton and Animation to their own folder. Moved Animation class in Animation.* files. Using a vector for animations. Deactivated the deallocation for now, probable memory leaks, will be fixed by futur commit --- diff --git a/CMakeLists.txt b/CMakeLists.txt index dfcea4f..ddcbd70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") set(LUGARU_SRCS ${SRCDIR}/main.cpp + ${SRCDIR}/Animation/Animation.cpp + ${SRCDIR}/Animation/Skeleton.cpp ${SRCDIR}/Frustum.cpp ${SRCDIR}/Account.cpp ${SRCDIR}/ConsoleCmds.cpp @@ -56,7 +58,6 @@ set(LUGARU_SRCS ${SRCDIR}/Person.cpp ${SRCDIR}/private.c ${SRCDIR}/Quaternions.cpp - ${SRCDIR}/Skeleton.cpp ${SRCDIR}/Skybox.cpp ${SRCDIR}/Sprite.cpp ${SRCDIR}/Terrain.cpp @@ -69,13 +70,14 @@ set(LUGARU_SRCS ${SRCDIR}/Input.cpp ${SRCDIR}/Settings.cpp ${SRCDIR}/Stereo.cpp - ${SRCDIR}/Animation.cpp ${SRCDIR}/Sounds.cpp ${SRCDIR}/Awards.cpp ${SRCDIR}/Utils/Folders.cpp ) set(LUGARU_H + ${SRCDIR}/Animation/Animation.h + ${SRCDIR}/Animation/Skeleton.h ${SRCDIR}/Frustum.h ${SRCDIR}/Account.h ${SRCDIR}/ConsoleCmds.h @@ -89,7 +91,6 @@ set(LUGARU_H ${SRCDIR}/PhysicsMath.h ${SRCDIR}/Quaternions.h ${SRCDIR}/Random.h - ${SRCDIR}/Skeleton.h ${SRCDIR}/Skybox.h ${SRCDIR}/Sprite.h ${SRCDIR}/ImageIO.h @@ -105,7 +106,6 @@ set(LUGARU_H ${SRCDIR}/private.h ${SRCDIR}/Settings.h ${SRCDIR}/Stereo.h - ${SRCDIR}/Animation.h ${SRCDIR}/Sounds.h ${SRCDIR}/Utils/Folders.h ) diff --git a/Source/Animation.cpp b/Source/Animation.cpp deleted file mode 100644 index b7e3995..0000000 --- a/Source/Animation.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file) - -This file is part of Lugaru. - -Lugaru is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -Lugaru is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Lugaru. If not, see . -*/ - -#include "Skeleton.h" -#include "Animation.h" - -struct animation_data_elt { - const std::string& filename; - int height; - int attack; -}; - -static animation_data_elt animation_data[animation_count] = { -#define DECLARE_ANIM(id, file, height, attack, ...) {file, height, attack}, -#include "Animation.def" -#undef DECLARE_ANIM -}; - -void loadAllAnimations() -{ - for (int i = 0; i < loadable_anim_end; i++) { - animation_data_elt *e = animation_data + i; - animation[i].Load(e->filename, e->height, e->attack); - } -} diff --git a/Source/Animation.def b/Source/Animation.def deleted file mode 100644 index de695f7..0000000 --- a/Source/Animation.def +++ /dev/null @@ -1,167 +0,0 @@ -/* -Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file) - -This file is part of Lugaru. - -Lugaru is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -Lugaru is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Lugaru. If not, see . -*/ - -#ifdef DECLARE_ANIM_BIT -DECLARE_ANIM_BIT(ab_idle) -DECLARE_ANIM_BIT(ab_sit) -DECLARE_ANIM_BIT(ab_sleep) -DECLARE_ANIM_BIT(ab_crouch) -DECLARE_ANIM_BIT(ab_run) -DECLARE_ANIM_BIT(ab_stop) -DECLARE_ANIM_BIT(ab_land) -DECLARE_ANIM_BIT(ab_landhard) -DECLARE_ANIM_BIT(ab_flip) -DECLARE_ANIM_BIT(ab_walljump) -#endif - -#ifdef DECLARE_ANIM -DECLARE_ANIM(runanim, "Run", middleheight, neutral, ab_run) -DECLARE_ANIM(bounceidleanim, "Idle", middleheight, neutral, ab_idle) -DECLARE_ANIM(stopanim, "Stop", middleheight, neutral, ab_stop) -DECLARE_ANIM(jumpupanim, "JumpUp", highheight, neutral, 0) -DECLARE_ANIM(jumpdownanim, "JumpDown", highheight, neutral, 0) -DECLARE_ANIM(landanim, "Landing", lowheight, neutral, ab_land) -DECLARE_ANIM(landhardanim, "LandHard", lowheight, neutral, ab_landhard) -DECLARE_ANIM(climbanim, "Climb", lowheight, neutral, 0) -DECLARE_ANIM(hanganim, "HangOn", lowheight, neutral, 0) -DECLARE_ANIM(spinkickanim, "SpinKick", middleheight, normalattack, 0) -DECLARE_ANIM(getupfromfrontanim, "GetUpFromFront", lowheight, neutral, 0) -DECLARE_ANIM(getupfrombackanim, "GetUpFromBack", lowheight, neutral, 0) -DECLARE_ANIM(crouchanim, "Crouch", lowheight, neutral, ab_crouch) -DECLARE_ANIM(sneakanim, "Sneak", lowheight, neutral, 0) -DECLARE_ANIM(rollanim, "Roll", lowheight, neutral, 0) -DECLARE_ANIM(flipanim, "Flip", highheight, neutral, ab_flip) -DECLARE_ANIM(frontflipanim, "Flip", highheight, neutral, ab_flip) -DECLARE_ANIM(spinkickreversedanim, "SpinKickCaught", middleheight, reversed, 0) -DECLARE_ANIM(spinkickreversalanim, "SpinKickCatch", middleheight, reversal, 0) -DECLARE_ANIM(lowkickanim, "LowKick", middleheight, normalattack, 0) -DECLARE_ANIM(sweepanim, "Sweep", lowheight, normalattack, 0) -DECLARE_ANIM(sweepreversedanim, "SweepCaught", lowheight, reversed, 0) -DECLARE_ANIM(sweepreversalanim, "SweepCatch", middleheight, reversal, 0) -DECLARE_ANIM(rabbitkickanim, "RabbitKick", middleheight, normalattack, 0) -DECLARE_ANIM(rabbitkickreversedanim, "RabbitKickCaught", middleheight, reversed, 0) -DECLARE_ANIM(rabbitkickreversalanim, "RabbitKickCatch", lowheight, reversal, 0) -DECLARE_ANIM(upunchanim, "Upunch", middleheight, normalattack, 0) -DECLARE_ANIM(staggerbackhighanim, "StaggerBackHigh", middleheight, neutral, 0) -DECLARE_ANIM(upunchreversedanim, "UpunchCaught", middleheight, reversed, 0) -DECLARE_ANIM(upunchreversalanim, "UpunchCatch", middleheight, reversal, 0) -DECLARE_ANIM(hurtidleanim, "HurtIdle", middleheight, neutral, ab_idle) -DECLARE_ANIM(backhandspringanim, "BackHandspring", middleheight, neutral, 0) -DECLARE_ANIM(fightidleanim, "FightIdle", middleheight, neutral, ab_idle) -DECLARE_ANIM(walkanim, "Walk", middleheight, neutral, 0) -DECLARE_ANIM(fightsidestep, "FightSideStep", middleheight, neutral, ab_idle) -DECLARE_ANIM(killanim, "Kill", middleheight, normalattack, 0) -DECLARE_ANIM(sneakattackanim, "SneakAttack", middleheight, reversal, 0) -DECLARE_ANIM(sneakattackedanim, "SneakAttacked", middleheight, reversed, 0) -DECLARE_ANIM(drawrightanim, "DrawRight", middleheight, neutral, 0) -DECLARE_ANIM(knifeslashstartanim, "SlashStart", middleheight, normalattack, 0) -DECLARE_ANIM(crouchdrawrightanim, "CrouchDrawRight", lowheight, neutral, 0) -DECLARE_ANIM(crouchstabanim, "CrouchStab", lowheight, normalattack, 0) -DECLARE_ANIM(knifefollowanim, "SlashFollow", middleheight, reversal, 0) -DECLARE_ANIM(knifefollowedanim, "SlashFollowed", middleheight, reversed, 0) -DECLARE_ANIM(knifethrowanim, "KnifeThrow", middleheight, normalattack, 0) -DECLARE_ANIM(removeknifeanim, "RemoveKnife", middleheight, neutral, 0) -DECLARE_ANIM(crouchremoveknifeanim, "CrouchRemoveKnife", lowheight, neutral, 0) -DECLARE_ANIM(jumpreversedanim, "JumpCaught", middleheight, reversed, 0) -DECLARE_ANIM(jumpreversalanim, "JumpCatch", middleheight, reversal, 0) -DECLARE_ANIM(staggerbackhardanim, "StaggerBackHard", middleheight, neutral, 0) -DECLARE_ANIM(dropkickanim, "DropKick", middleheight, normalattack, 0) -DECLARE_ANIM(winduppunchanim, "WindUpPunch", middleheight, normalattack, 0) -DECLARE_ANIM(winduppunchblockedanim, "WindUpPunchBlocked", middleheight, normalattack, 0) -DECLARE_ANIM(blockhighleftanim, "BlockHighLeft", middleheight, normalattack, 0) -DECLARE_ANIM(blockhighleftstrikeanim, "BlockHighLeftStrike", middleheight, normalattack, 0) -DECLARE_ANIM(backflipanim, "BackFlip", highheight, neutral, ab_flip) -DECLARE_ANIM(walljumpbackanim, "WallJumpBack", highheight, neutral, ab_walljump) -DECLARE_ANIM(walljumpfrontanim, "WallJumpFront", highheight, neutral, ab_walljump) -DECLARE_ANIM(rightflipanim, "RightFlip", highheight, neutral, ab_flip) -DECLARE_ANIM(walljumprightanim, "WallJumpRight", highheight, neutral, ab_walljump) -DECLARE_ANIM(leftflipanim, "LeftFlip", highheight, neutral, ab_flip) -DECLARE_ANIM(walljumpleftanim, "WallJumpLeft", highheight, neutral, ab_walljump) -DECLARE_ANIM(walljumprightkickanim, "WallJumpRightKick", highheight, neutral, ab_flip) -DECLARE_ANIM(walljumpleftkickanim, "WallJumpLeftKick", highheight, neutral, ab_flip) -DECLARE_ANIM(knifefightidleanim, "KnifeFightIdle", middleheight, neutral, ab_idle) -DECLARE_ANIM(knifesneakattackanim, "KnifeSneakAttack", middleheight, reversal, 0) -DECLARE_ANIM(knifesneakattackedanim, "KnifeSneakAttacked", middleheight, reversed, 0) -DECLARE_ANIM(swordfightidleanim, "SwordFightIdle", middleheight, neutral, ab_idle) -DECLARE_ANIM(drawleftanim, "DrawLeft", middleheight, neutral, 0) -DECLARE_ANIM(swordslashanim, "SwordSlash", middleheight, normalattack, 0) -DECLARE_ANIM(swordgroundstabanim, "SwordGroundStab", lowheight, normalattack, 0) -DECLARE_ANIM(dodgebackanim, "DodgeBack", middleheight, neutral, 0) -DECLARE_ANIM(swordsneakattackanim, "SwordSneakAttack", middleheight, reversal, 0) -DECLARE_ANIM(swordsneakattackedanim, "SwordSneakAttacked", middleheight, reversed, 0) -DECLARE_ANIM(swordslashreversedanim, "SwordSlashCaught", middleheight, reversed, 0) -DECLARE_ANIM(swordslashreversalanim, "SwordSlashCatch", middleheight, reversal, 0) -DECLARE_ANIM(knifeslashreversedanim, "KnifeSlashCaught", middleheight, reversed, 0) -DECLARE_ANIM(knifeslashreversalanim, "KnifeSlashCatch", middleheight, reversal, 0) -DECLARE_ANIM(swordfightidlebothanim, "SwordFightIdleBoth", middleheight, neutral, ab_idle) -DECLARE_ANIM(swordslashparryanim, "SwordUprightParry", middleheight, normalattack, 0) -DECLARE_ANIM(swordslashparriedanim, "SwordSlashParried", middleheight, normalattack, 0) -DECLARE_ANIM(wolfidle, "WolfIdle", middleheight, neutral, ab_idle) -DECLARE_ANIM(wolfcrouchanim, "WolfCrouch", lowheight, neutral, ab_crouch) -DECLARE_ANIM(wolflandanim, "WolfLanding", lowheight, neutral, ab_land) -DECLARE_ANIM(wolflandhardanim, "WolfLandHard", lowheight, neutral, ab_landhard) -DECLARE_ANIM(wolfrunanim, "WolfRun", middleheight, neutral, ab_run) -DECLARE_ANIM(wolfrunninganim, "WolfRunning", middleheight, neutral, ab_run) -DECLARE_ANIM(rabbitrunninganim, "RabbitRunning", middleheight, neutral, ab_run) -DECLARE_ANIM(wolfstopanim, "WolfStop", middleheight, neutral, ab_stop) -DECLARE_ANIM(rabbittackleanim, "RabbitTackle", middleheight, neutral, 0) -DECLARE_ANIM(rabbittacklinganim, "RabbitTackling", middleheight, reversal, 0) -DECLARE_ANIM(rabbittackledbackanim, "RabbitTackledBack", middleheight, reversed, 0) -DECLARE_ANIM(rabbittackledfrontanim, "RabbitTackledFront", middleheight, reversed, 0) -DECLARE_ANIM(wolfslapanim, "WolfSlap", middleheight, normalattack, 0) -DECLARE_ANIM(staffhitanim, "StaffHit", middleheight, normalattack, 0) -DECLARE_ANIM(staffgroundsmashanim, "StaffGroundSmash", lowheight, normalattack, 0) -DECLARE_ANIM(staffspinhitanim, "SpinWhack", middleheight, normalattack, 0) -DECLARE_ANIM(staffhitreversedanim, "StaffHitCaught", middleheight, reversed, 0) -DECLARE_ANIM(staffhitreversalanim, "StaffHitCatch", middleheight, reversal, 0) -DECLARE_ANIM(staffspinhitreversedanim, "SpinWhackCaught", middleheight, reversed, 0) -DECLARE_ANIM(staffspinhitreversalanim, "SpinWhackCatch", middleheight, reversal, 0) -DECLARE_ANIM(sitanim, "Sit", lowheight, neutral, ab_idle | ab_sit) -DECLARE_ANIM(sleepanim, "Sleep", lowheight, neutral, ab_idle | ab_sleep) -DECLARE_ANIM(talkidleanim, "TalkIdle", middleheight, neutral, ab_idle) -DECLARE_ANIM(sitwallanim, "Dying", lowheight, neutral, ab_sit) -DECLARE_ANIM(dead1anim, "Dead1", lowheight, neutral, ab_sleep) -DECLARE_ANIM(dead2anim, "Dead2", lowheight, neutral, ab_sleep) -DECLARE_ANIM(dead3anim, "Dead3", lowheight, neutral, ab_sleep) -DECLARE_ANIM(dead4anim, "Dead4", lowheight, neutral, ab_sleep) - -DECLARE_ANIM(loadable_anim_end, "", 0, 0, 0) - -/* Not implemented. */ -DECLARE_ANIM(rabbittacklereversal, "", 0, 0, 0) -DECLARE_ANIM(rabbittacklereversed, "", 0, 0, 0) -DECLARE_ANIM(sworddisarmanim, "", 0, 0, 0) -DECLARE_ANIM(swordslashleftanim, "", 0, 0, 0) -DECLARE_ANIM(swordslashrightanim, "", 0, 0, 0) -DECLARE_ANIM(swordstabanim, "", 0, 0, 0) -DECLARE_ANIM(wolfbashanim, "", 0, 0, 0) -DECLARE_ANIM(wolfclawanim, "", 0, 0, 0) -DECLARE_ANIM(wolffightidle, "", 0, 0, 0) -DECLARE_ANIM(wolfhurtidle, "", 0, 0, 0) -DECLARE_ANIM(wolfsneakanim, "", 0, 0, 0) -DECLARE_ANIM(wolfswordidle, "", 0, 0, 0) -DECLARE_ANIM(wolftackleanim, "", 0, 0, 0) -DECLARE_ANIM(wolftackledbacanim, "", 0, 0, 0) -DECLARE_ANIM(wolftackledfrontanim, "", 0, 0, 0) -DECLARE_ANIM(wolftacklereversal, "", 0, 0, 0) -DECLARE_ANIM(wolftacklereversed, "", 0, 0, 0) -DECLARE_ANIM(wolftacklinganim, "", 0, 0, 0) - -DECLARE_ANIM(tempanim, "", 0, 0, 0) -#endif diff --git a/Source/Animation.h b/Source/Animation.h deleted file mode 100644 index 7448589..0000000 --- a/Source/Animation.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file) - -This file is part of Lugaru. - -Lugaru is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -Lugaru is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Lugaru. If not, see . -*/ - -#ifndef ANIMATION_H -#define ANIMATION_H - -enum anim_attack_type { - neutral, normalattack, reversed, reversal -}; - -enum anim_height_type { - lowheight, middleheight, highheight -}; - -enum animation_types { -#define DECLARE_ANIM(id, ...) id, -#include "Animation.def" -#undef DECLARE_ANIM - animation_count -}; - -enum animation_bit_offsets { -#define DECLARE_ANIM_BIT(bit) o_##bit, -#include "Animation.def" -#undef DECLARE_ANIM_BIT - animation_bit_count -}; - -enum animation_bits_def { -#define DECLARE_ANIM_BIT(bit) bit = 1 << o_##bit, -#include "Animation.def" -#undef DECLARE_ANIM_BIT -}; - -static const int animation_bits[animation_count] = { -#define DECLARE_ANIM(id, name, height, type, bits) bits, -#include "Animation.def" -#undef DECLARE_ANIM -}; - -extern Animation animation[animation_count]; - -extern void loadAllAnimations(); -#endif diff --git a/Source/Animation/Animation.cpp b/Source/Animation/Animation.cpp new file mode 100644 index 0000000..3ccd17c --- /dev/null +++ b/Source/Animation/Animation.cpp @@ -0,0 +1,299 @@ +/* +Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file) + +This file is part of Lugaru. + +Lugaru is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +Lugaru is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Lugaru. If not, see . +*/ + +#include "Animation/Skeleton.h" +#include "Animation/Animation.h" +#include "Utils/Folders.h" +#include "Game.h" + +extern bool visibleloading; + +//~ struct animation_data_elt { + //~ const std::string& filename; + //~ int height; + //~ int attack; +//~ }; + +//~ static animation_data_elt animation_data[animation_count] = { +//~ #define DECLARE_ANIM(id, file, height, attack, ...) {file, height, attack}, +//~ #include "Animation.def" +//~ #undef DECLARE_ANIM +//~ }; +std::vector Animation::animations; + +void Animation::loadAll() +{ + int i = 0; +#define DECLARE_ANIM(id, file, height, attack, ...) if (i++ < loadable_anim_end) animations.emplace_back(file, height, attack); +#include "Animation.def" +#undef DECLARE_ANIM +} + + +Animation::Animation(): + numframes(0), + height(0), + attack(0), + joints(0), + weapontargetnum(0), + + position(0), + twist(0), + twist2(0), + speed(0), + onground(0), + forward(0), + label(0), + weapontarget(0) +{ +} + +/* EFFECT + * load an animation from file + */ +Animation::Animation(const std::string& filename, int aheight, int aattack): + Animation() +{ + FILE *tfile; + int i, j; + XYZ endoffset; + + LOGFUNC; + + // Changing the filename into something the OS can understand + std::string filepath = Folders::getResourcePath("Animations/"+filename); + + LOG(std::string("Loading animation...") + filepath); + + height = aheight; + attack = aattack; + + if (visibleloading) + Game::LoadingScreen(); + + // read file in binary mode + tfile = Folders::openMandatoryFile( filepath, "rb" ); + + // read numframes, joints to know how much memory to allocate + funpackf(tfile, "Bi Bi", &numframes, &joints); + + // allocate memory for everything + + position = (XYZ**)malloc(sizeof(XYZ*) * joints); + for (i = 0; i < joints; i++) + position[i] = (XYZ*)malloc(sizeof(XYZ) * numframes); + + twist = (float**)malloc(sizeof(float*) * joints); + for (i = 0; i < joints; i++) + twist[i] = (float*)malloc(sizeof(float) * numframes); + + twist2 = (float**)malloc(sizeof(float*) * joints); + for (i = 0; i < joints; i++) + twist2[i] = (float*)malloc(sizeof(float) * numframes); + + speed = (float*)malloc(sizeof(float) * numframes); + + onground = (bool**)malloc(sizeof(bool*) * joints); + for (i = 0; i < joints; i++) + onground[i] = (bool*)malloc(sizeof(bool) * numframes); + + forward = (XYZ*)malloc(sizeof(XYZ) * numframes); + weapontarget = (XYZ*)malloc(sizeof(XYZ) * numframes); + label = (int*)malloc(sizeof(int) * numframes); + + // read binary data as animation + + // for each frame... + for (i = 0; i < numframes; i++) { + // for each joint in the skeleton... + for (j = 0; j < joints; j++) { + // read joint position + funpackf(tfile, "Bf Bf Bf", &position[j][i].x, &position[j][i].y, &position[j][i].z); + } + for (j = 0; j < joints; j++) { + // read twist + funpackf(tfile, "Bf", &twist[j][i]); + } + for (j = 0; j < joints; j++) { + // read onground (boolean) + unsigned char uch; + funpackf(tfile, "Bb", &uch); + onground[j][i] = (uch != 0); + } + // read frame speed (?) + funpackf(tfile, "Bf", &speed[i]); + } + // read twist2 for whole animation + for (i = 0; i < numframes; i++) { + for (j = 0; j < joints; j++) { + funpackf(tfile, "Bf", &twist2[j][i]); + } + } + // read label for each frame + for (i = 0; i < numframes; i++) { + funpackf(tfile, "Bf", &label[i]); + } + // read weapontargetnum + funpackf(tfile, "Bi", &weapontargetnum); + // read weapontarget positions for each frame + for (i = 0; i < numframes; i++) { + funpackf(tfile, "Bf Bf Bf", &weapontarget[i].x, &weapontarget[i].y, &weapontarget[i].z); + } + + fclose(tfile); + + endoffset = 0; + // find average position of certain joints on last frames + // and save in endoffset + // (not sure what exactly this accomplishes. the y < 1 test confuses me.) + for (j = 0; j < joints; j++) { + if (position[j][numframes - 1].y < 1) + endoffset += position[j][numframes - 1]; + } + endoffset /= joints; + offset = endoffset; + offset.y = 0; +} + +Animation::~Animation() +{ + //~ deallocate(); +} + +void Animation::deallocate() +{ + int i = 0; + + if (position) { + for (i = 0; i < joints; i++) + free(position[i]); + + free(position); + } + position = 0; + + if (twist) { + for (i = 0; i < joints; i++) + free(twist[i]); + + free(twist); + } + twist = 0; + + if (twist2) { + for (i = 0; i < joints; i++) + free(twist2[i]); + + free(twist2); + } + twist2 = 0; + + if (onground) { + for (i = 0; i < joints; i++) + free(onground[i]); + + free(onground); + } + onground = 0; + + if (speed) + free(speed); + speed = 0; + + if (forward) + free(forward); + forward = 0; + + if (weapontarget) + free(weapontarget); + weapontarget = 0; + + if (label) + free(label); + label = 0; + + joints = 0; +} + +Animation & Animation::operator = (const Animation & ani) +{ + int i = 0; + + bool allocate = ((ani.numframes != numframes) || (ani.joints != joints)); + + if (allocate) + deallocate(); + + numframes = ani.numframes; + height = ani.height; + attack = ani.attack; + joints = ani.joints; + weapontargetnum = ani.weapontargetnum; + offset = ani.offset; + + if (allocate) + position = (XYZ**)malloc(sizeof(XYZ*)*ani.joints); + for (i = 0; i < ani.joints; i++) { + if (allocate) + position[i] = (XYZ*)malloc(sizeof(XYZ) * ani.numframes); + memcpy(position[i], ani.position[i], sizeof(XYZ)*ani.numframes); + } + + if (allocate) + twist = (float**)malloc(sizeof(float*)*ani.joints); + for (i = 0; i < ani.joints; i++) { + if (allocate) + twist[i] = (float*)malloc(sizeof(float) * ani.numframes); + memcpy(twist[i], ani.twist[i], sizeof(float)*ani.numframes); + } + + if (allocate) + twist2 = (float**)malloc(sizeof(float*)*ani.joints); + for (i = 0; i < ani.joints; i++) { + if (allocate) + twist2[i] = (float*)malloc(sizeof(float) * ani.numframes); + memcpy(twist2[i], ani.twist2[i], sizeof(float)*ani.numframes); + } + + if (allocate) + speed = (float*)malloc(sizeof(float) * ani.numframes); + memcpy(speed, ani.speed, sizeof(float)*ani.numframes); + + if (allocate) + onground = (bool**)malloc(sizeof(bool*)*ani.joints); + for (i = 0; i < ani.joints; i++) { + if (allocate) + onground[i] = (bool*)malloc(sizeof(bool) * ani.numframes); + memcpy(onground[i], ani.onground[i], sizeof(bool)*ani.numframes); + } + + if (allocate) + forward = (XYZ*)malloc(sizeof(XYZ) * ani.numframes); + memcpy(forward, ani.forward, sizeof(XYZ)*ani.numframes); + + if (allocate) + weapontarget = (XYZ*)malloc(sizeof(XYZ) * ani.numframes); + memcpy(weapontarget, ani.weapontarget, sizeof(XYZ)*ani.numframes); + + if (allocate) + label = (int*)malloc(sizeof(int) * ani.numframes); + memcpy(label, ani.label, sizeof(int)*ani.numframes); + + return (*this); +} diff --git a/Source/Animation/Animation.def b/Source/Animation/Animation.def new file mode 100644 index 0000000..2a48c42 --- /dev/null +++ b/Source/Animation/Animation.def @@ -0,0 +1,167 @@ +/* +Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file) + +This file is part of Lugaru. + +Lugaru is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +Lugaru is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Lugaru. If not, see . +*/ + +#ifdef DECLARE_ANIM_BIT +DECLARE_ANIM_BIT(ab_idle) +DECLARE_ANIM_BIT(ab_sit) +DECLARE_ANIM_BIT(ab_sleep) +DECLARE_ANIM_BIT(ab_crouch) +DECLARE_ANIM_BIT(ab_run) +DECLARE_ANIM_BIT(ab_stop) +DECLARE_ANIM_BIT(ab_land) +DECLARE_ANIM_BIT(ab_landhard) +DECLARE_ANIM_BIT(ab_flip) +DECLARE_ANIM_BIT(ab_walljump) +#endif + +#ifdef DECLARE_ANIM +DECLARE_ANIM(runanim, "Run", middleheight, neutral, ab_run) +DECLARE_ANIM(bounceidleanim, "Idle", middleheight, neutral, ab_idle) +DECLARE_ANIM(stopanim, "Stop", middleheight, neutral, ab_stop) +DECLARE_ANIM(jumpupanim, "JumpUp", highheight, neutral, 0) +DECLARE_ANIM(jumpdownanim, "JumpDown", highheight, neutral, 0) +DECLARE_ANIM(landanim, "Landing", lowheight, neutral, ab_land) +DECLARE_ANIM(landhardanim, "LandHard", lowheight, neutral, ab_landhard) +DECLARE_ANIM(climbanim, "Climb", lowheight, neutral, 0) +DECLARE_ANIM(hanganim, "HangOn", lowheight, neutral, 0) +DECLARE_ANIM(spinkickanim, "SpinKick", middleheight, normalattack, 0) +DECLARE_ANIM(getupfromfrontanim, "GetUpFromFront", lowheight, neutral, 0) +DECLARE_ANIM(getupfrombackanim, "GetUpFromBack", lowheight, neutral, 0) +DECLARE_ANIM(crouchanim, "Crouch", lowheight, neutral, ab_crouch) +DECLARE_ANIM(sneakanim, "Sneak", lowheight, neutral, 0) +DECLARE_ANIM(rollanim, "Roll", lowheight, neutral, 0) +DECLARE_ANIM(flipanim, "Flip", highheight, neutral, ab_flip) +DECLARE_ANIM(frontflipanim, "Flip", highheight, neutral, ab_flip) +DECLARE_ANIM(spinkickreversedanim, "SpinKickCaught", middleheight, reversed, 0) +DECLARE_ANIM(spinkickreversalanim, "SpinKickCatch", middleheight, reversal, 0) +DECLARE_ANIM(lowkickanim, "LowKick", middleheight, normalattack, 0) +DECLARE_ANIM(sweepanim, "Sweep", lowheight, normalattack, 0) +DECLARE_ANIM(sweepreversedanim, "SweepCaught", lowheight, reversed, 0) +DECLARE_ANIM(sweepreversalanim, "SweepCatch", middleheight, reversal, 0) +DECLARE_ANIM(rabbitkickanim, "RabbitKick", middleheight, normalattack, 0) +DECLARE_ANIM(rabbitkickreversedanim, "RabbitKickCaught", middleheight, reversed, 0) +DECLARE_ANIM(rabbitkickreversalanim, "RabbitKickCatch", lowheight, reversal, 0) +DECLARE_ANIM(upunchanim, "Upunch", middleheight, normalattack, 0) +DECLARE_ANIM(staggerbackhighanim, "StaggerBackHigh", middleheight, neutral, 0) +DECLARE_ANIM(upunchreversedanim, "UpunchCaught", middleheight, reversed, 0) +DECLARE_ANIM(upunchreversalanim, "UpunchCatch", middleheight, reversal, 0) +DECLARE_ANIM(hurtidleanim, "HurtIdle", middleheight, neutral, ab_idle) +DECLARE_ANIM(backhandspringanim, "BackHandspring", middleheight, neutral, 0) +DECLARE_ANIM(fightidleanim, "FightIdle", middleheight, neutral, ab_idle) +DECLARE_ANIM(walkanim, "Walk", middleheight, neutral, 0) +DECLARE_ANIM(fightsidestep, "FightSideStep", middleheight, neutral, ab_idle) +DECLARE_ANIM(killanim, "Kill", middleheight, normalattack, 0) +DECLARE_ANIM(sneakattackanim, "SneakAttack", middleheight, reversal, 0) +DECLARE_ANIM(sneakattackedanim, "SneakAttacked", middleheight, reversed, 0) +DECLARE_ANIM(drawrightanim, "DrawRight", middleheight, neutral, 0) +DECLARE_ANIM(knifeslashstartanim, "SlashStart", middleheight, normalattack, 0) +DECLARE_ANIM(crouchdrawrightanim, "CrouchDrawRight", lowheight, neutral, 0) +DECLARE_ANIM(crouchstabanim, "CrouchStab", lowheight, normalattack, 0) +DECLARE_ANIM(knifefollowanim, "SlashFollow", middleheight, reversal, 0) +DECLARE_ANIM(knifefollowedanim, "SlashFollowed", middleheight, reversed, 0) +DECLARE_ANIM(knifethrowanim, "KnifeThrow", middleheight, normalattack, 0) +DECLARE_ANIM(removeknifeanim, "RemoveKnife", middleheight, neutral, 0) +DECLARE_ANIM(crouchremoveknifeanim, "CrouchRemoveKnife", lowheight, neutral, 0) +DECLARE_ANIM(jumpreversedanim, "JumpCaught", middleheight, reversed, 0) +DECLARE_ANIM(jumpreversalanim, "JumpCatch", middleheight, reversal, 0) +DECLARE_ANIM(staggerbackhardanim, "StaggerBackHard", middleheight, neutral, 0) +DECLARE_ANIM(dropkickanim, "DropKick", middleheight, normalattack, 0) +DECLARE_ANIM(winduppunchanim, "WindUpPunch", middleheight, normalattack, 0) +DECLARE_ANIM(winduppunchblockedanim, "WindUpPunchBlocked", middleheight, normalattack, 0) +DECLARE_ANIM(blockhighleftanim, "BlockHighLeft", middleheight, normalattack, 0) +DECLARE_ANIM(blockhighleftstrikeanim, "BlockHighLeftStrike", middleheight, normalattack, 0) +DECLARE_ANIM(backflipanim, "BackFlip", highheight, neutral, ab_flip) +DECLARE_ANIM(walljumpbackanim, "WallJumpBack", highheight, neutral, ab_walljump) +DECLARE_ANIM(walljumpfrontanim, "WallJumpFront", highheight, neutral, ab_walljump) +DECLARE_ANIM(rightflipanim, "RightFlip", highheight, neutral, ab_flip) +DECLARE_ANIM(walljumprightanim, "WallJumpRight", highheight, neutral, ab_walljump) +DECLARE_ANIM(leftflipanim, "LeftFlip", highheight, neutral, ab_flip) +DECLARE_ANIM(walljumpleftanim, "WallJumpLeft", highheight, neutral, ab_walljump) +DECLARE_ANIM(walljumprightkickanim, "WallJumpRightKick", highheight, neutral, ab_flip) +DECLARE_ANIM(walljumpleftkickanim, "WallJumpLeftKick", highheight, neutral, ab_flip) +DECLARE_ANIM(knifefightidleanim, "KnifeFightIdle", middleheight, neutral, ab_idle) +DECLARE_ANIM(knifesneakattackanim, "KnifeSneakAttack", middleheight, reversal, 0) +DECLARE_ANIM(knifesneakattackedanim, "KnifeSneakAttacked", middleheight, reversed, 0) +DECLARE_ANIM(swordfightidleanim, "SwordFightIdle", middleheight, neutral, ab_idle) +DECLARE_ANIM(drawleftanim, "DrawLeft", middleheight, neutral, 0) +DECLARE_ANIM(swordslashanim, "SwordSlash", middleheight, normalattack, 0) +DECLARE_ANIM(swordgroundstabanim, "SwordGroundStab", lowheight, normalattack, 0) +DECLARE_ANIM(dodgebackanim, "DodgeBack", middleheight, neutral, 0) +DECLARE_ANIM(swordsneakattackanim, "SwordSneakAttack", middleheight, reversal, 0) +DECLARE_ANIM(swordsneakattackedanim, "SwordSneakAttacked", middleheight, reversed, 0) +DECLARE_ANIM(swordslashreversedanim, "SwordSlashCaught", middleheight, reversed, 0) +DECLARE_ANIM(swordslashreversalanim, "SwordSlashCatch", middleheight, reversal, 0) +DECLARE_ANIM(knifeslashreversedanim, "KnifeSlashCaught", middleheight, reversed, 0) +DECLARE_ANIM(knifeslashreversalanim, "KnifeSlashCatch", middleheight, reversal, 0) +DECLARE_ANIM(swordfightidlebothanim, "SwordFightIdleBoth", middleheight, neutral, ab_idle) +DECLARE_ANIM(swordslashparryanim, "SwordUprightParry", middleheight, normalattack, 0) +DECLARE_ANIM(swordslashparriedanim, "SwordSlashParried", middleheight, normalattack, 0) +DECLARE_ANIM(wolfidle, "WolfIdle", middleheight, neutral, ab_idle) +DECLARE_ANIM(wolfcrouchanim, "WolfCrouch", lowheight, neutral, ab_crouch) +DECLARE_ANIM(wolflandanim, "WolfLanding", lowheight, neutral, ab_land) +DECLARE_ANIM(wolflandhardanim, "WolfLandHard", lowheight, neutral, ab_landhard) +DECLARE_ANIM(wolfrunanim, "WolfRun", middleheight, neutral, ab_run) +DECLARE_ANIM(wolfrunninganim, "WolfRunning", middleheight, neutral, ab_run) +DECLARE_ANIM(rabbitrunninganim, "RabbitRunning", middleheight, neutral, ab_run) +DECLARE_ANIM(wolfstopanim, "WolfStop", middleheight, neutral, ab_stop) +DECLARE_ANIM(rabbittackleanim, "RabbitTackle", middleheight, neutral, 0) +DECLARE_ANIM(rabbittacklinganim, "RabbitTackling", middleheight, reversal, 0) +DECLARE_ANIM(rabbittackledbackanim, "RabbitTackledBack", middleheight, reversed, 0) +DECLARE_ANIM(rabbittackledfrontanim, "RabbitTackledFront", middleheight, reversed, 0) +DECLARE_ANIM(wolfslapanim, "WolfSlap", middleheight, normalattack, 0) +DECLARE_ANIM(staffhitanim, "StaffHit", middleheight, normalattack, 0) +DECLARE_ANIM(staffgroundsmashanim, "StaffGroundSmash", lowheight, normalattack, 0) +DECLARE_ANIM(staffspinhitanim, "SpinWhack", middleheight, normalattack, 0) +DECLARE_ANIM(staffhitreversedanim, "StaffHitCaught", middleheight, reversed, 0) +DECLARE_ANIM(staffhitreversalanim, "StaffHitCatch", middleheight, reversal, 0) +DECLARE_ANIM(staffspinhitreversedanim, "SpinWhackCaught", middleheight, reversed, 0) +DECLARE_ANIM(staffspinhitreversalanim, "SpinWhackCatch", middleheight, reversal, 0) +DECLARE_ANIM(sitanim, "Sit", lowheight, neutral, ab_idle | ab_sit) +DECLARE_ANIM(sleepanim, "Sleep", lowheight, neutral, ab_idle | ab_sleep) +DECLARE_ANIM(talkidleanim, "TalkIdle", middleheight, neutral, ab_idle) +DECLARE_ANIM(sitwallanim, "Dying", lowheight, neutral, ab_sit) +DECLARE_ANIM(dead1anim, "Dead1", lowheight, neutral, ab_sleep) +DECLARE_ANIM(dead2anim, "Dead2", lowheight, neutral, ab_sleep) +DECLARE_ANIM(dead3anim, "Dead3", lowheight, neutral, ab_sleep) +DECLARE_ANIM(dead4anim, "Dead4", lowheight, neutral, ab_sleep) + +DECLARE_ANIM(tempanim, "", 0, 0, 0) + +DECLARE_ANIM(loadable_anim_end, "", 0, 0, 0) + +/* Not implemented. */ +DECLARE_ANIM(rabbittacklereversal, "", 0, 0, 0) +DECLARE_ANIM(rabbittacklereversed, "", 0, 0, 0) +DECLARE_ANIM(sworddisarmanim, "", 0, 0, 0) +DECLARE_ANIM(swordslashleftanim, "", 0, 0, 0) +DECLARE_ANIM(swordslashrightanim, "", 0, 0, 0) +DECLARE_ANIM(swordstabanim, "", 0, 0, 0) +DECLARE_ANIM(wolfbashanim, "", 0, 0, 0) +DECLARE_ANIM(wolfclawanim, "", 0, 0, 0) +DECLARE_ANIM(wolffightidle, "", 0, 0, 0) +DECLARE_ANIM(wolfhurtidle, "", 0, 0, 0) +DECLARE_ANIM(wolfsneakanim, "", 0, 0, 0) +DECLARE_ANIM(wolfswordidle, "", 0, 0, 0) +DECLARE_ANIM(wolftackleanim, "", 0, 0, 0) +DECLARE_ANIM(wolftackledbacanim, "", 0, 0, 0) +DECLARE_ANIM(wolftackledfrontanim, "", 0, 0, 0) +DECLARE_ANIM(wolftacklereversal, "", 0, 0, 0) +DECLARE_ANIM(wolftacklereversed, "", 0, 0, 0) +DECLARE_ANIM(wolftacklinganim, "", 0, 0, 0) +#endif diff --git a/Source/Animation/Animation.h b/Source/Animation/Animation.h new file mode 100644 index 0000000..3633de9 --- /dev/null +++ b/Source/Animation/Animation.h @@ -0,0 +1,90 @@ +/* +Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file) + +This file is part of Lugaru. + +Lugaru is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +Lugaru is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Lugaru. If not, see . +*/ + +#ifndef ANIMATION_H +#define ANIMATION_H + +#include + +enum anim_attack_type { + neutral, normalattack, reversed, reversal +}; + +enum anim_height_type { + lowheight, middleheight, highheight +}; + +enum animation_types { +#define DECLARE_ANIM(id, ...) id, +#include "Animation.def" +#undef DECLARE_ANIM + animation_count +}; + +enum animation_bit_offsets { +#define DECLARE_ANIM_BIT(bit) o_##bit, +#include "Animation.def" +#undef DECLARE_ANIM_BIT + animation_bit_count +}; + +enum animation_bits_def { +#define DECLARE_ANIM_BIT(bit) bit = 1 << o_##bit, +#include "Animation.def" +#undef DECLARE_ANIM_BIT +}; + +static const int animation_bits[animation_count] = { +#define DECLARE_ANIM(id, name, height, type, bits) bits, +#include "Animation.def" +#undef DECLARE_ANIM +}; + +class Animation +{ +public: + static std::vector animations; + static void loadAll(); + + int numframes; + int height; + int attack; + int joints; + int weapontargetnum; + + XYZ** position; + float** twist; + float** twist2; + float* speed; + bool** onground; + XYZ* forward; + int* label; + XYZ* weapontarget; + + XYZ offset; + + Animation(); + Animation(const std::string& fileName, int aheight, int aattack); + ~Animation(); + Animation & operator = (const Animation & ani); + +protected: + void deallocate(); +}; +#endif diff --git a/Source/Animation/Skeleton.cpp b/Source/Animation/Skeleton.cpp new file mode 100644 index 0000000..aac06ee --- /dev/null +++ b/Source/Animation/Skeleton.cpp @@ -0,0 +1,1451 @@ +/* +Copyright (C) 2003, 2010 - Wolfire Games +Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file) + +This file is part of Lugaru. + +Lugaru is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +Lugaru is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Lugaru. If not, see . +*/ + +/**> HEADER FILES <**/ +#include "Game.h" +#include "Animation/Skeleton.h" +#include "openal_wrapper.h" +#include "Animation/Animation.h" +#include "Utils/Folders.h" + +extern float multiplier; +extern float gravity; +extern Terrain terrain; +extern Objects objects; +extern int environment; +extern float camerashake; +extern bool freeze; +extern int detail; +extern int tutoriallevel; + +extern int whichjointstartarray[26]; +extern int whichjointendarray[26]; + +extern bool visibleloading; + +/* EFFECT + */ +void dealloc2(void* param) +{ + free(param); +} + +enum {boneconnect, constraint, muscle}; + + +/* EFFECT + * sets strength, length, + * parent1->position, parent2->position, + * parent1->velocity, parent2->velocity + * used for ragdolls? + * + * USES: + * Skeleton::DoConstraints + */ +void Muscle::DoConstraint(bool spinny) +{ + // FIXME: relaxlength shouldn't be static, but may not always be set + // so I don't want to change the existing behavior even though it's probably a bug + static float relaxlength; + + float oldlength = length; + + if (type != boneconnect) + relaxlength = findDistance(&parent1->position, &parent2->position); + + if (type == boneconnect) + strength = 1; + if (type == constraint) + strength = 0; + + // clamp strength + if (strength < 0) + strength = 0; + if (strength > 1) + strength = 1; + + length -= (length - relaxlength) * (1 - strength) * multiplier * 10000; + length -= (length - targetlength) * (strength) * multiplier * 10000; + if (strength == 0) + length = relaxlength; + + if ((relaxlength - length > 0 && relaxlength - oldlength < 0) || (relaxlength - length < 0 && relaxlength - oldlength > 0)) + length = relaxlength; + + // clamp length + if (length < minlength) + length = minlength; + if (length > maxlength) + length = maxlength; + + if (length == relaxlength) + return; + + // relax muscle? + + //Find midpoint + XYZ midp = (parent1->position * parent1->mass + parent2->position * parent2->mass) / (parent1->mass + parent2->mass); + + //Find vector from midpoint to second vector + XYZ vel = parent2->position - midp; + + //Change to unit vector + Normalise(&vel); + + //Apply velocity change + XYZ newpoint1 = midp - vel * length * (parent2->mass / (parent1->mass + parent2->mass)); + XYZ newpoint2 = midp + vel * length * (parent1->mass / (parent1->mass + parent2->mass)); + if (!freeze && spinny) { + parent1->velocity = parent1->velocity + (newpoint1 - parent1->position) / multiplier / 4; + parent2->velocity = parent2->velocity + (newpoint2 - parent2->position) / multiplier / 4; + } else { + parent1->velocity = parent1->velocity + (newpoint1 - parent1->position); + parent2->velocity = parent2->velocity + (newpoint2 - parent2->position); + } + + //Move child point to within certain distance of parent point + parent1->position = newpoint1; + parent2->position = newpoint2; +} + +/* EFFECT + * sets forward, lowforward, specialforward[] + * + * USES: + * Skeleton::Load + * Person/Person::DoAnimations + * Person/Person::DrawSkeleton + */ +void Skeleton::FindForwards() +{ + //Find forward vectors + CrossProduct(joints[forwardjoints[1]].position - joints[forwardjoints[0]].position, joints[forwardjoints[2]].position - joints[forwardjoints[0]].position, &forward); + Normalise(&forward); + + CrossProduct(joints[lowforwardjoints[1]].position - joints[lowforwardjoints[0]].position, joints[lowforwardjoints[2]].position - joints[lowforwardjoints[0]].position, &lowforward); + Normalise(&lowforward); + + //Special forwards + specialforward[0] = forward; + + specialforward[1] = jointPos(rightshoulder) + jointPos(rightwrist); + specialforward[1] = jointPos(rightelbow) - specialforward[1] / 2; + specialforward[1] += forward * .4; + Normalise(&specialforward[1]); + specialforward[2] = jointPos(leftshoulder) + jointPos(leftwrist); + specialforward[2] = jointPos(leftelbow) - specialforward[2] / 2; + specialforward[2] += forward * .4; + Normalise(&specialforward[2]); + + specialforward[3] = jointPos(righthip) + jointPos(rightankle); + specialforward[3] = specialforward[3] / 2 - jointPos(rightknee); + specialforward[3] += lowforward * .4; + Normalise(&specialforward[3]); + specialforward[4] = jointPos(lefthip) + jointPos(leftankle); + specialforward[4] = specialforward[4] / 2 - jointPos(leftknee); + specialforward[4] += lowforward * .4; + Normalise(&specialforward[4]); +} + +/* EFFECT + * TODO + * + * USES: + * Person/Person::RagDoll + * Person/Person::DoStuff + * Person/IKHelper + */ +float Skeleton::DoConstraints(XYZ *coords, float *scale) +{ + float friction = 1.5; + const float elasticity = .3; + XYZ bounceness; + const int numrepeats = 3; + float groundlevel = .15; + int i, j, k, m; + XYZ temp; + XYZ terrainnormal; + int whichhit; + float frictionness; + XYZ terrainlight; + int whichpatchx; + int whichpatchz; + float damage = 0; // eventually returned from function + bool breaking = false; + + if (free) { + freetime += multiplier; + + whichpatchx = coords->x / (terrain.size / subdivision * terrain.scale); + whichpatchz = coords->z / (terrain.size / subdivision * terrain.scale); + + terrainlight = *coords; + objects.SphereCheckPossible(&terrainlight, 1); + + //Add velocity + for (i = 0; i < num_joints; i++) { + joints[i].position = joints[i].position + joints[i].velocity * multiplier; + + switch (joints[i].label) { + case head: + groundlevel = .8; + break; + case righthand: + case rightwrist: + case rightelbow: + case lefthand: + case leftwrist: + case leftelbow: + groundlevel = .2; + break; + default: + groundlevel = .15; + break; + } + + joints[i].position.y -= groundlevel; + joints[i].oldvelocity = joints[i].velocity; + } + + float tempmult = multiplier; + //multiplier/=numrepeats; + + for (j = 0; j < numrepeats; j++) { + float r = .05; + // right leg constraints? + if (!joint(rightknee).locked && !joint(righthip).locked) { + temp = jointPos(rightknee) - (jointPos(righthip) + jointPos(rightankle)) / 2; + while (normaldotproduct(temp, lowforward) > -.1 && !sphere_line_intersection(&jointPos(righthip), &jointPos(rightankle), &jointPos(rightknee), &r)) { + jointPos(rightknee) -= lowforward * .05; + if (spinny) + jointVel(rightknee) -= lowforward * .05 / multiplier / 4; + else + jointVel(rightknee) -= lowforward * .05; + jointPos(rightankle) += lowforward * .025; + if (spinny) + jointVel(rightankle) += lowforward * .025 / multiplier / 4; + else + jointVel(rightankle) += lowforward * .25; + jointPos(righthip) += lowforward * .025; + if (spinny) + jointVel(righthip) += lowforward * .025 / multiplier / 4; + else + jointVel(righthip) += lowforward * .025; + temp = jointPos(rightknee) - (jointPos(righthip) + jointPos(rightankle)) / 2; + } + } + + // left leg constraints? + if (!joint(leftknee).locked && !joint(lefthip).locked) { + temp = jointPos(leftknee) - (jointPos(lefthip) + jointPos(leftankle)) / 2; + while (normaldotproduct(temp, lowforward) > -.1 && !sphere_line_intersection(&jointPos(lefthip), &jointPos(leftankle), &jointPos(leftknee), &r)) { + jointPos(leftknee) -= lowforward * .05; + if (spinny) + jointVel(leftknee) -= lowforward * .05 / multiplier / 4; + else + jointVel(leftknee) -= lowforward * .05; + jointPos(leftankle) += lowforward * .025; + if (spinny) + jointVel(leftankle) += lowforward * .025 / multiplier / 4; + else + jointVel(leftankle) += lowforward * .25; + jointPos(lefthip) += lowforward * .025; + if (spinny) + jointVel(lefthip) += lowforward * .025 / multiplier / 4; + else + jointVel(lefthip) += lowforward * .025; + temp = jointPos(leftknee) - (jointPos(lefthip) + jointPos(leftankle)) / 2; + } + } + + for (i = 0; i < num_joints; i++) { + if (joints[i].locked && !spinny && findLengthfast(&joints[i].velocity) > 320) + joints[i].locked = 0; + if (spinny && findLengthfast(&joints[i].velocity) > 600) + joints[i].locked = 0; + if (joints[i].delay > 0) { + bool freely = true; + for (j = 0; j < num_joints; j++) { + if (joints[j].locked) + freely = false; + } + if (freely) + joints[i].delay -= multiplier * 3; + } + } + + if (num_muscles) + for (i = 0; i < num_muscles; i++) { + //Length constraints + muscles[i].DoConstraint(spinny); + } + + for (i = 0; i < num_joints; i++) { + //Length constraints + //Ground constraint + groundlevel = 0; + if (joints[i].position.y * (*scale) + coords->y < terrain.getHeight(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) + groundlevel) { + freefall = 0; + friction = 1.5; + if (joints[i].label == groin && !joints[i].locked && joints[i].delay <= 0) { + joints[i].locked = 1; + joints[i].delay = 1; + if (tutoriallevel != 1 || id == 0) { + emit_sound_at(landsound1, joints[i].position * (*scale) + *coords, 128.); + } + breaking = true; + } + + if (joints[i].label == head && !joints[i].locked && joints[i].delay <= 0) { + joints[i].locked = 1; + joints[i].delay = 1; + if (tutoriallevel != 1 || id == 0) { + emit_sound_at(landsound2, joints[i].position * (*scale) + *coords, 128.); + } + } + + terrainnormal = terrain.getNormal(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z); + ReflectVector(&joints[i].velocity, &terrainnormal); + bounceness = terrainnormal * findLength(&joints[i].velocity) * (abs(normaldotproduct(joints[i].velocity, terrainnormal))); + if (!joints[i].locked) + damage += findLengthfast(&bounceness) / 4000; + if (findLengthfast(&joints[i].velocity) < findLengthfast(&bounceness)) + bounceness = 0; + frictionness = abs(normaldotproduct(joints[i].velocity, terrainnormal)); + joints[i].velocity -= bounceness; + if (1 - friction * frictionness > 0) + joints[i].velocity *= 1 - friction * frictionness; + else + joints[i].velocity = 0; + + if (tutoriallevel != 1 || id == 0) + if (findLengthfast(&bounceness) > 8000 && breaking) { + // FIXME: this crashes because k is not initialized! + // to reproduce, type 'wolfie' in console and play a while + // I'll just comment it out for now + //objects.model[k].MakeDecal(breakdecal, DoRotation(temp - objects.position[k], 0, -objects.yaw[k], 0), .4, .5, Random() % 360); + Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, 4, .2); + breaking = false; + camerashake += .6; + + emit_sound_at(breaksound2, joints[i].position * (*scale) + *coords); + + addEnvSound(*coords, 64); + } + + if (findLengthfast(&bounceness) > 2500) { + Normalise(&bounceness); + bounceness = bounceness * 50; + } + + joints[i].velocity += bounceness * elasticity; + + if (findLengthfast(&joints[i].velocity) > findLengthfast(&joints[i].oldvelocity)) { + bounceness = 0; + joints[i].velocity = joints[i].oldvelocity; + } + + + if (joints[i].locked == 0) + if (findLengthfast(&joints[i].velocity) < 1) + joints[i].locked = 1; + + if (environment == snowyenvironment && findLengthfast(&bounceness) > 500 && terrain.getOpacity(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) < .2) { + terrainlight = terrain.getLighting(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z); + Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7); + if (detail == 2) + terrain.MakeDecal(bodyprintdecal, joints[i].position * (*scale) + *coords, .4, .4, 0); + } else if (environment == desertenvironment && findLengthfast(&bounceness) > 500 && terrain.getOpacity(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) < .2) { + terrainlight = terrain.getLighting(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z); + Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7); + } + + else if (environment == grassyenvironment && findLengthfast(&bounceness) > 500 && terrain.getOpacity(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) < .2) { + terrainlight = terrain.getLighting(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z); + Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5); + } else if (findLengthfast(&bounceness) > 500) + Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x, terrainlight.y, terrainlight.z, .5, .2); + + + joints[i].position.y = (terrain.getHeight(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) + groundlevel - coords->y) / (*scale); + if (longdead > 100) + broken = 1; + } + if (terrain.patchobjectnum[whichpatchx][whichpatchz]) + for (m = 0; m < terrain.patchobjectnum[whichpatchx][whichpatchz]; m++) { + k = terrain.patchobjects[whichpatchx][whichpatchz][m]; + if (k < objects.numobjects && k >= 0) + if (objects.possible[k]) { + friction = objects.friction[k]; + XYZ start = joints[i].realoldposition; + XYZ end = joints[i].position * (*scale) + *coords; + whichhit = objects.model[k].LineCheckPossible(&start, &end, &temp, &objects.position[k], &objects.yaw[k]); + if (whichhit != -1) { + if (joints[i].label == groin && !joints[i].locked && joints[i].delay <= 0) { + joints[i].locked = 1; + joints[i].delay = 1; + if (tutoriallevel != 1 || id == 0) { + emit_sound_at(landsound1, joints[i].position * (*scale) + *coords, 128.); + } + breaking = true; + } + + if (joints[i].label == head && !joints[i].locked && joints[i].delay <= 0) { + joints[i].locked = 1; + joints[i].delay = 1; + if (tutoriallevel != 1 || id == 0) { + emit_sound_at(landsound2, joints[i].position * (*scale) + *coords, 128.); + } + } + + terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1; + if (terrainnormal.y > .8) + freefall = 0; + bounceness = terrainnormal * findLength(&joints[i].velocity) * (abs(normaldotproduct(joints[i].velocity, terrainnormal))); + if (findLengthfast(&joints[i].velocity) > findLengthfast(&joints[i].oldvelocity)) { + bounceness = 0; + joints[i].velocity = joints[i].oldvelocity; + } + if (tutoriallevel != 1 || id == 0) + if (findLengthfast(&bounceness) > 4000 && breaking) { + objects.model[k].MakeDecal(breakdecal, DoRotation(temp - objects.position[k], 0, -objects.yaw[k], 0), .4, .5, Random() % 360); + Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, 4, .2); + breaking = false; + camerashake += .6; + + emit_sound_at(breaksound2, joints[i].position * (*scale) + *coords); + + addEnvSound(*coords, 64); + } + if (objects.type[k] == treetrunktype) { + objects.rotx[k] += joints[i].velocity.x * multiplier * .4; + objects.roty[k] += joints[i].velocity.z * multiplier * .4; + objects.rotx[k + 1] += joints[i].velocity.x * multiplier * .4; + objects.roty[k + 1] += joints[i].velocity.z * multiplier * .4; + } + if (!joints[i].locked) + damage += findLengthfast(&bounceness) / 2500; + ReflectVector(&joints[i].velocity, &terrainnormal); + frictionness = abs(normaldotproduct(joints[i].velocity, terrainnormal)); + joints[i].velocity -= bounceness; + if (1 - friction * frictionness > 0) + joints[i].velocity *= 1 - friction * frictionness; + else + joints[i].velocity = 0; + if (findLengthfast(&bounceness) > 2500) { + Normalise(&bounceness); + bounceness = bounceness * 50; + } + joints[i].velocity += bounceness * elasticity; + + + if (!joints[i].locked) + if (findLengthfast(&joints[i].velocity) < 1) { + joints[i].locked = 1; + } + if (findLengthfast(&bounceness) > 500) + Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, .5, .2); + joints[i].position = (temp - *coords) / (*scale) + terrainnormal * .005; + if (longdead > 100) + broken = 1; + } + } + } + joints[i].realoldposition = joints[i].position * (*scale) + *coords; + } + } + multiplier = tempmult; + + + if (terrain.patchobjectnum[whichpatchx][whichpatchz]) + for (m = 0; m < terrain.patchobjectnum[whichpatchx][whichpatchz]; m++) { + k = terrain.patchobjects[whichpatchx][whichpatchz][m]; + if (objects.possible[k]) { + for (i = 0; i < 26; i++) { + //Make this less stupid + XYZ start = joints[jointlabels[whichjointstartarray[i]]].position * (*scale) + *coords; + XYZ end = joints[jointlabels[whichjointendarray[i]]].position * (*scale) + *coords; + whichhit = objects.model[k].LineCheckSlidePossible(&start, &end, &temp, &objects.position[k], &objects.yaw[k]); + if (whichhit != -1) { + joints[jointlabels[whichjointendarray[i]]].position = (end - *coords) / (*scale); + for (j = 0; j < num_muscles; j++) { + if ((muscles[j].parent1->label == whichjointstartarray[i] && muscles[j].parent2->label == whichjointendarray[i]) || (muscles[j].parent2->label == whichjointstartarray[i] && muscles[j].parent1->label == whichjointendarray[i])) + muscles[j].DoConstraint(spinny); + } + } + } + } + } + + for (i = 0; i < num_joints; i++) { + switch (joints[i].label) { + case head: + groundlevel = .8; + break; + case righthand: + case rightwrist: + case rightelbow: + case lefthand: + case leftwrist: + case leftelbow: + groundlevel = .2; + break; + default: + groundlevel = .15; + break; + } + joints[i].position.y += groundlevel; + joints[i].mass = 1; + if (joints[i].label == lefthip || joints[i].label == leftknee || joints[i].label == leftankle || joints[i].label == righthip || joints[i].label == rightknee || joints[i].label == rightankle) + joints[i].mass = 2; + if (joints[i].locked) { + joints[i].mass = 4; + } + } + + return damage; + } + + if (!free) { + for (i = 0; i < num_muscles; i++) { + if (muscles[i].type == boneconnect) + muscles[i].DoConstraint(0); + } + } + + return 0; +} + +/* EFFECT + * applies gravity to the skeleton + * + * USES: + * Person/Person::DoStuff + */ +void Skeleton::DoGravity(float *scale) +{ + static int i; + for (i = 0; i < num_joints; i++) { + if ( + ( + ((joints[i].label != leftknee) && (joints[i].label != rightknee)) || + (lowforward.y > -.1) || + (joints[i].mass < 5) + ) && ( + ((joints[i].label != leftelbow) && (joints[i].label != rightelbow)) || + (forward.y < .3) + ) + ) + joints[i].velocity.y += gravity * multiplier / (*scale); + } +} + +/* EFFECT + * set muscles[which].rotate1 + * .rotate2 + * .rotate3 + * + * special case if animation == hanganim + */ +void Skeleton::FindRotationMuscle(int which, int animation) +{ + XYZ p1, p2, fwd; + float dist; + + p1 = muscles[which].parent1->position; + p2 = muscles[which].parent2->position; + dist = findDistance(&p1, &p2); + if (p1.y - p2.y <= dist) + muscles[which].rotate2 = asin((p1.y - p2.y) / dist); + if (p1.y - p2.y > dist) + muscles[which].rotate2 = asin(1.f); + muscles[which].rotate2 *= 360.0 / 6.2831853; + + p1.y = 0; + p2.y = 0; + dist = findDistance(&p1, &p2); + if (p1.z - p2.z <= dist) + muscles[which].rotate1 = acos((p1.z - p2.z) / dist); + if (p1.z - p2.z > dist) + muscles[which].rotate1 = acos(1.f); + muscles[which].rotate1 *= 360.0 / 6.2831853; + if (p1.x > p2.x) + muscles[which].rotate1 = 360 - muscles[which].rotate1; + if (!isnormal(muscles[which].rotate1)) + muscles[which].rotate1 = 0; + if (!isnormal(muscles[which].rotate2)) + muscles[which].rotate2 = 0; + + const int label1 = muscles[which].parent1->label; + const int label2 = muscles[which].parent2->label; + switch (label1) { + case head: + fwd = specialforward[0]; + break; + case rightshoulder: + case rightelbow: + case rightwrist: + case righthand: + fwd = specialforward[1]; + break; + case leftshoulder: + case leftelbow: + case leftwrist: + case lefthand: + fwd = specialforward[2]; + break; + case righthip: + case rightknee: + case rightankle: + case rightfoot: + fwd = specialforward[3]; + break; + case lefthip: + case leftknee: + case leftankle: + case leftfoot: + fwd = specialforward[4]; + break; + default: + if (muscles[which].parent1->lower) + fwd = lowforward; + else + fwd = forward; + break; + } + + if (animation == hanganim) { + if (label1 == righthand || label2 == righthand) { + fwd = 0; + fwd.x = -1; + } + if (label1 == lefthand || label2 == lefthand) { + fwd = 0; + fwd.x = 1; + } + } + + if (free == 0) { + if (label1 == rightfoot || label2 == rightfoot) { + fwd.y -= .3; + } + if (label1 == leftfoot || label2 == leftfoot) { + fwd.y -= .3; + } + } + + fwd = DoRotation(fwd, 0, muscles[which].rotate1 - 90, 0); + fwd = DoRotation(fwd, 0, 0, muscles[which].rotate2 - 90); + fwd.y = 0; + fwd /= findLength(&fwd); + if (fwd.z <= 1 && fwd.z >= -1) + muscles[which].rotate3 = acos(0 - fwd.z); + else + muscles[which].rotate3 = acos(-1.f); + muscles[which].rotate3 *= 360.0 / 6.2831853; + if (0 > fwd.x) + muscles[which].rotate3 = 360 - muscles[which].rotate3; + if (!isnormal(muscles[which].rotate3)) + muscles[which].rotate3 = 0; +} + +/* EFFECT + * load skeleton + * takes filenames for three skeleton files and various models + */ +void Skeleton::Load(const std::string& filename, const std::string& lowfilename, const std::string& clothesfilename, + const std::string& modelfilename, const std::string& model2filename, + const std::string& model3filename, const std::string& model4filename, + const std::string& model5filename, const std::string& model6filename, + const std::string& model7filename, const std::string& modellowfilename, + const std::string& modelclothesfilename, bool clothes) +{ + GLfloat M[16]; + int parentID; + FILE *tfile; + float lSize; + int i, j; + int edit; + + LOGFUNC; + + num_models = 7; + + // load various models + // rotate, scale, do normals, do texcoords for each as needed + + model[0].loadnotex(modelfilename); + model[1].loadnotex(model2filename); + model[2].loadnotex(model3filename); + model[3].loadnotex(model4filename); + model[4].loadnotex(model5filename); + model[5].loadnotex(model6filename); + model[6].loadnotex(model7filename); + + for (i = 0; i < num_models; i++) { + model[i].Rotate(180, 0, 0); + model[i].Scale(.04, .04, .04); + model[i].CalculateNormals(0); + } + + drawmodel.load(modelfilename, 0); + drawmodel.Rotate(180, 0, 0); + drawmodel.Scale(.04, .04, .04); + drawmodel.FlipTexCoords(); + if (tutoriallevel == 1 && id != 0) + drawmodel.UniformTexCoords(); + if (tutoriallevel == 1 && id != 0) + drawmodel.ScaleTexCoords(0.1); + drawmodel.CalculateNormals(0); + + modellow.loadnotex(modellowfilename); + modellow.Rotate(180, 0, 0); + modellow.Scale(.04, .04, .04); + modellow.CalculateNormals(0); + + drawmodellow.load(modellowfilename, 0); + drawmodellow.Rotate(180, 0, 0); + drawmodellow.Scale(.04, .04, .04); + drawmodellow.FlipTexCoords(); + if (tutoriallevel == 1 && id != 0) + drawmodellow.UniformTexCoords(); + if (tutoriallevel == 1 && id != 0) + drawmodellow.ScaleTexCoords(0.1); + drawmodellow.CalculateNormals(0); + + if (clothes) { + modelclothes.loadnotex(modelclothesfilename); + modelclothes.Rotate(180, 0, 0); + modelclothes.Scale(.041, .04, .041); + modelclothes.CalculateNormals(0); + + drawmodelclothes.load(modelclothesfilename, 0); + drawmodelclothes.Rotate(180, 0, 0); + drawmodelclothes.Scale(.04, .04, .04); + drawmodelclothes.FlipTexCoords(); + drawmodelclothes.CalculateNormals(0); + } + + // FIXME: three similar blocks follow, one for each of: + // filename, lowfilename, clothesfilename + + // load skeleton + + tfile = Folders::openMandatoryFile( Folders::getResourcePath(filename), "rb" ); + + // read num_joints + funpackf(tfile, "Bi", &num_joints); + + // allocate memory + if (joints) + delete [] joints; //dealloc2(joints); + joints = (Joint*)new Joint[num_joints]; + + // read info for each joint + for (i = 0; i < num_joints; i++) { + funpackf(tfile, "Bf Bf Bf Bf Bf", &joints[i].position.x, &joints[i].position.y, &joints[i].position.z, &joints[i].length, &joints[i].mass); + funpackf(tfile, "Bb Bb", &joints[i].hasparent, &joints[i].locked); + funpackf(tfile, "Bi", &joints[i].modelnum); + funpackf(tfile, "Bb Bb", &joints[i].visible, &joints[i].sametwist); + funpackf(tfile, "Bi Bi", &joints[i].label, &joints[i].hasgun); + funpackf(tfile, "Bb", &joints[i].lower); + funpackf(tfile, "Bi", &parentID); + if (joints[i].hasparent) + joints[i].parent = &joints[parentID]; + joints[i].velocity = 0; + joints[i].oldposition = joints[i].position; + } + + // read num_muscles + funpackf(tfile, "Bi", &num_muscles); + + // allocate memory + if (muscles) + delete [] muscles; //dealloc2(muscles); + muscles = (Muscle*)new Muscle[num_muscles]; //malloc(sizeof(Muscle)*num_muscles); + + // for each muscle... + for (i = 0; i < num_muscles; i++) { + // read info + funpackf(tfile, "Bf Bf Bf Bf Bf Bi Bi", &muscles[i].length, &muscles[i].targetlength, &muscles[i].minlength, &muscles[i].maxlength, &muscles[i].strength, &muscles[i].type, &muscles[i].numvertices); + + // allocate memory for vertices + muscles[i].vertices = (int*)malloc(sizeof(int) * muscles[i].numvertices); + + // read vertices + edit = 0; + for (j = 0; j < muscles[i].numvertices - edit; j++) { + funpackf(tfile, "Bi", &muscles[i].vertices[j + edit]); + if (muscles[i].vertices[j + edit] >= model[0].vertexNum) { + muscles[i].numvertices--; + edit--; + } + } + + // read more info + funpackf(tfile, "Bb Bi", &muscles[i].visible, &parentID); + muscles[i].parent1 = &joints[parentID]; + funpackf(tfile, "Bi", &parentID); + muscles[i].parent2 = &joints[parentID]; + } + + // read forwardjoints (?) + for (j = 0; j < 3; j++) { + funpackf(tfile, "Bi", &forwardjoints[j]); + } + // read lowforwardjoints (?) + for (j = 0; j < 3; j++) { + funpackf(tfile, "Bi", &lowforwardjoints[j]); + } + + // ??? + for (j = 0; j < num_muscles; j++) { + for (i = 0; i < muscles[j].numvertices; i++) { + for (int k = 0; k < num_models; k++) { + if (muscles[j].numvertices && muscles[j].vertices[i] < model[k].vertexNum) + model[k].owner[muscles[j].vertices[i]] = j; + } + } + } + + // calculate some stuff + FindForwards(); + for (i = 0; i < num_joints; i++) { + joints[i].startpos = joints[i].position; + } + for (i = 0; i < num_muscles; i++) { + FindRotationMuscle(i, -1); + } + // this seems to use opengl purely for matrix calculations + for (int k = 0; k < num_models; k++) { + for (i = 0; i < model[k].vertexNum; i++) { + model[k].vertex[i] = model[k].vertex[i] - (muscles[model[k].owner[i]].parent1->position + muscles[model[k].owner[i]].parent2->position) / 2; + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glRotatef(muscles[model[k].owner[i]].rotate3, 0, 1, 0); + glRotatef(muscles[model[k].owner[i]].rotate2 - 90, 0, 0, 1); + glRotatef(muscles[model[k].owner[i]].rotate1 - 90, 0, 1, 0); + glTranslatef(model[k].vertex[i].x, model[k].vertex[i].y, model[k].vertex[i].z); + glGetFloatv(GL_MODELVIEW_MATRIX, M); + model[k].vertex[i].x = M[12] * 1; + model[k].vertex[i].y = M[13] * 1; + model[k].vertex[i].z = M[14] * 1; + glPopMatrix(); + } + model[k].CalculateNormals(0); + } + fclose(tfile); + + // load ??? + + tfile = Folders::openMandatoryFile( Folders::getResourcePath(lowfilename), "rb" ); + + // skip joints section + + lSize = sizeof(num_joints); + fseek(tfile, lSize, SEEK_CUR); + for (i = 0; i < num_joints; i++) { + // skip joint info + lSize = sizeof(XYZ) + + sizeof(float) + + sizeof(float) + + 1 //sizeof(bool) + + 1 //sizeof(bool) + + sizeof(int) + + 1 //sizeof(bool) + + 1 //sizeof(bool) + + sizeof(int) + + sizeof(int) + + 1 //sizeof(bool) + + sizeof(int); + fseek(tfile, lSize, SEEK_CUR); + + if (joints[i].hasparent) + joints[i].parent = &joints[parentID]; + joints[i].velocity = 0; + joints[i].oldposition = joints[i].position; + } + + // read num_muscles + funpackf(tfile, "Bi", &num_muscles); + + for (i = 0; i < num_muscles; i++) { + // skip muscle info + lSize = sizeof(float) + + sizeof(float) + + sizeof(float) + + sizeof(float) + + sizeof(float) + + sizeof(int); + fseek(tfile, lSize, SEEK_CUR); + + // read numverticeslow + funpackf(tfile, "Bi", &muscles[i].numverticeslow); + + if (muscles[i].numverticeslow) { + // allocate memory + muscles[i].verticeslow = (int*)malloc(sizeof(int) * muscles[i].numverticeslow); + + // read verticeslow + edit = 0; + for (j = 0; j < muscles[i].numverticeslow - edit; j++) { + funpackf(tfile, "Bi", &muscles[i].verticeslow[j + edit]); + if (muscles[i].verticeslow[j + edit] >= modellow.vertexNum) { + muscles[i].numverticeslow--; + edit--; + } + } + } + + // skip more stuff + lSize = 1; //sizeof(bool); + fseek ( tfile, lSize, SEEK_CUR); + lSize = sizeof(int); + fseek ( tfile, lSize, SEEK_CUR); + fseek ( tfile, lSize, SEEK_CUR); + } + + for (j = 0; j < num_muscles; j++) { + for (i = 0; i < muscles[j].numverticeslow; i++) { + if (muscles[j].verticeslow[i] < modellow.vertexNum) + modellow.owner[muscles[j].verticeslow[i]] = j; + } + } + + // use opengl for its matrix math + for (i = 0; i < modellow.vertexNum; i++) { + modellow.vertex[i] = modellow.vertex[i] - (muscles[modellow.owner[i]].parent1->position + muscles[modellow.owner[i]].parent2->position) / 2; + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glRotatef(muscles[modellow.owner[i]].rotate3, 0, 1, 0); + glRotatef(muscles[modellow.owner[i]].rotate2 - 90, 0, 0, 1); + glRotatef(muscles[modellow.owner[i]].rotate1 - 90, 0, 1, 0); + glTranslatef(modellow.vertex[i].x, modellow.vertex[i].y, modellow.vertex[i].z); + glGetFloatv(GL_MODELVIEW_MATRIX, M); + modellow.vertex[i].x = M[12]; + modellow.vertex[i].y = M[13]; + modellow.vertex[i].z = M[14]; + glPopMatrix(); + } + + modellow.CalculateNormals(0); + + // load clothes + + if (clothes) { + tfile = Folders::openMandatoryFile( Folders::getResourcePath(clothesfilename), "rb" ); + + // skip num_joints + lSize = sizeof(num_joints); + fseek ( tfile, lSize, SEEK_CUR); + + for (i = 0; i < num_joints; i++) { + // skip joint info + lSize = sizeof(XYZ) + + sizeof(float) + + sizeof(float) + + 1 //sizeof(bool) + + 1 //sizeof(bool) + + sizeof(int) + + 1 //sizeof(bool) + + 1 //sizeof(bool) + + sizeof(int) + + sizeof(int) + + 1 //sizeof(bool) + + sizeof(int); + fseek(tfile, lSize, SEEK_CUR); + + if (joints[i].hasparent) + joints[i].parent = &joints[parentID]; + joints[i].velocity = 0; + joints[i].oldposition = joints[i].position; + } + + // read num_muscles + funpackf(tfile, "Bi", &num_muscles); + + for (i = 0; i < num_muscles; i++) { + // skip muscle info + lSize = sizeof(float) + + sizeof(float) + + sizeof(float) + + sizeof(float) + + sizeof(float) + + sizeof(int); + fseek(tfile, lSize, SEEK_CUR); + + // read numverticesclothes + funpackf(tfile, "Bi", &muscles[i].numverticesclothes); + + // read verticesclothes + if (muscles[i].numverticesclothes) { + muscles[i].verticesclothes = (int*)malloc(sizeof(int) * muscles[i].numverticesclothes); + edit = 0; + for (j = 0; j < muscles[i].numverticesclothes - edit; j++) { + funpackf(tfile, "Bi", &muscles[i].verticesclothes[j + edit]); + if (muscles[i].verticesclothes[j + edit] >= modelclothes.vertexNum) { + muscles[i].numverticesclothes--; + edit--; + } + } + } + + // skip more stuff + lSize = 1; //sizeof(bool); + fseek ( tfile, lSize, SEEK_CUR); + lSize = sizeof(int); + fseek ( tfile, lSize, SEEK_CUR); + fseek ( tfile, lSize, SEEK_CUR); + } + + // ??? + lSize = sizeof(int); + for (j = 0; j < num_muscles; j++) { + for (i = 0; i < muscles[j].numverticesclothes; i++) { + if (muscles[j].numverticesclothes && muscles[j].verticesclothes[i] < modelclothes.vertexNum) + modelclothes.owner[muscles[j].verticesclothes[i]] = j; + } + } + + // use opengl for its matrix math + for (i = 0; i < modelclothes.vertexNum; i++) { + modelclothes.vertex[i] = modelclothes.vertex[i] - (muscles[modelclothes.owner[i]].parent1->position + muscles[modelclothes.owner[i]].parent2->position) / 2; + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glRotatef(muscles[modelclothes.owner[i]].rotate3, 0, 1, 0); + glRotatef(muscles[modelclothes.owner[i]].rotate2 - 90, 0, 0, 1); + glRotatef(muscles[modelclothes.owner[i]].rotate1 - 90, 0, 1, 0); + glTranslatef(modelclothes.vertex[i].x, modelclothes.vertex[i].y, modelclothes.vertex[i].z); + glGetFloatv(GL_MODELVIEW_MATRIX, M); + modelclothes.vertex[i].x = M[12]; + modelclothes.vertex[i].y = M[13]; + modelclothes.vertex[i].z = M[14]; + glPopMatrix(); + } + + modelclothes.CalculateNormals(0); + } + fclose(tfile); + + for (i = 0; i < num_joints; i++) { + for (j = 0; j < num_joints; j++) { + if (joints[i].label == j) + jointlabels[j] = i; + } + } + + free = 0; +} + +Skeleton::Skeleton() +{ + num_joints = 0; + + num_muscles = 0; + + selected = 0; + + memset(forwardjoints, 0, sizeof(forwardjoints)); + // XYZ forward; + + id = 0; + + memset(lowforwardjoints, 0, sizeof(lowforwardjoints)); + // XYZ lowforward; + + // XYZ specialforward[5]; + memset(jointlabels, 0, sizeof(jointlabels)); + + // Model model[7]; + // Model modellow; + // Model modelclothes; + num_models = 0; + + // Model drawmodel; + // Model drawmodellow; + // Model drawmodelclothes; + + clothes = 0; + spinny = 0; + + memset(skinText, 0, sizeof(skinText)); + skinsize = 0; + + checkdelay = 0; + + longdead = 0; + broken = 0; + + free = 0; + oldfree = 0; + freetime = 0; + freefall = 0; + + joints = 0; + muscles = 0; +} + +Skeleton::~Skeleton() +{ + if (muscles) { + delete [] muscles; + } + muscles = 0; + + if (joints) { + delete [] joints; + } + joints = 0; +} + +Muscle::Muscle() +{ + vertices = 0; + verticeslow = 0; + verticesclothes = 0; + + numvertices = 0; + numverticeslow = 0; + numverticesclothes = 0; + length = 0; + targetlength = 0; + parent1 = 0; + parent2 = 0; + maxlength = 0; + minlength = 0; + type = 0; + visible = 0; + rotate1 = 0, rotate2 = 0, rotate3 = 0; + lastrotate1 = 0, lastrotate2 = 0, lastrotate3 = 0; + oldrotate1 = 0, oldrotate2 = 0, oldrotate3 = 0; + newrotate1 = 0, newrotate2 = 0, newrotate3 = 0; + + strength = 0; +} + +Muscle::~Muscle() +{ + dealloc2(vertices); + dealloc2(verticeslow); + dealloc2(verticesclothes); +} + +#if 0 + +// the following functions are not used anywhere + +/* EFFECT + * sets forward, lowforward, specialforward[] + * + * USES: + * NONE + */ +void Skeleton::FindForwardsfirst() +{ + //Find forward vectors + CrossProduct(joints[forwardjoints[1]].position - joints[forwardjoints[0]].position, joints[forwardjoints[2]].position - joints[forwardjoints[0]].position, &forward); + Normalise(&forward); + + CrossProduct(joints[lowforwardjoints[1]].position - joints[lowforwardjoints[0]].position, joints[lowforwardjoints[2]].position - joints[lowforwardjoints[0]].position, &lowforward); + Normalise(&lowforward); + + //Special forwards + specialforward[0] = forward; + specialforward[1] = forward; + specialforward[2] = forward; + specialforward[3] = forward; + specialforward[4] = forward; + +} + +/* EFFECT + * + * USES: + * NONE + */ +void Skeleton::Draw(int muscleview) +{ + static float jointcolor[4]; + + if (muscleview != 2) { + jointcolor[0] = 0; + jointcolor[1] = 0; + jointcolor[2] = .5; + jointcolor[3] = 1; + } + + if (muscleview == 2) { + jointcolor[0] = 0; + jointcolor[1] = 0; + jointcolor[2] = 0; + jointcolor[3] = .5; + } + //Calc motionblur-ness + for (int i = 0; i < num_joints; i++) { + joints[i].oldposition = joints[i].position; + joints[i].blurred = findDistance(&joints[i].position, &joints[i].oldposition) * 100; + if (joints[i].blurred < 1) + joints[i].blurred = 1; + } + + //Do Motionblur + glDepthMask(0); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBegin(GL_QUADS); + for (int i = 0; i < num_joints; i++) { + if (joints[i].hasparent) { + glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].blurred); + glVertex3f(joints[i].position.x, joints[i].position.y, joints[i].position.z); + glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].parent->blurred); + glVertex3f(joints[i].parent->position.x, joints[i].parent->position.y, joints[i].parent->position.z); + glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].parent->blurred); + glVertex3f(joints[i].parent->oldposition.x, joints[i].parent->oldposition.y, joints[i].parent->oldposition.z); + glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].blurred); + glVertex3f(joints[i].oldposition.x, joints[i].oldposition.y, joints[i].oldposition.z); + } + } + for (int i = 0; i < num_muscles; i++) { + if (muscles[i].type == boneconnect) { + glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent2->blurred); + glVertex3f(muscles[i].parent1->position.x, muscles[i].parent1->position.y, muscles[i].parent1->position.z); + glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent2->blurred); + glVertex3f(muscles[i].parent2->position.x, muscles[i].parent2->position.y, muscles[i].parent2->position.z); + glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent2->blurred); + glVertex3f(muscles[i].parent2->oldposition.x, muscles[i].parent2->oldposition.y, muscles[i].parent2->oldposition.z); + glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent1->blurred); + glVertex3f(muscles[i].parent1->oldposition.x, muscles[i].parent1->oldposition.y, muscles[i].parent1->oldposition.z); + } + } + glEnd(); + + glBegin(GL_LINES); + for (int i = 0; i < num_joints; i++) { + if (joints[i].hasparent) { + glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].blurred); + glVertex3f(joints[i].position.x, joints[i].position.y, joints[i].position.z); + glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].parent->blurred); + glVertex3f(joints[i].parent->position.x, joints[i].parent->position.y, joints[i].parent->position.z); + } + } + for (int i = 0; i < num_muscles; i++) { + if (muscles[i].type == boneconnect) { + glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent1->blurred); + glVertex3f(muscles[i].parent1->position.x, muscles[i].parent1->position.y, muscles[i].parent1->position.z); + glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent2->blurred); + glVertex3f(muscles[i].parent2->position.x, muscles[i].parent2->position.y, muscles[i].parent2->position.z); + } + } + glColor3f(.6, .6, 0); + if (muscleview == 1) + for (int i = 0; i < num_muscles; i++) { + if (muscles[i].type != boneconnect) { + glVertex3f(muscles[i].parent1->position.x, muscles[i].parent1->position.y, muscles[i].parent1->position.z); + glVertex3f(muscles[i].parent2->position.x, muscles[i].parent2->position.y, muscles[i].parent2->position.z); + } + } + glEnd(); + + if (muscleview != 2) { + glPointSize(3); + glBegin(GL_POINTS); + for (int i = 0; i < num_joints; i++) { + if (i != selected) + glColor4f(0, 0, .5, 1); + if (i == selected) + glColor4f(1, 1, 0, 1); + if (joints[i].locked && i != selected) + glColor4f(1, 0, 0, 1); + glVertex3f(joints[i].position.x, joints[i].position.y, joints[i].position.z); + } + glEnd(); + } + + //Set old position to current position + if (muscleview == 2) + for (int i = 0; i < num_joints; i++) { + joints[i].oldposition = joints[i].position; + } + glDepthMask(1); +} + +/* EFFECT + * + * USES: + * NONE + */ +void Skeleton::AddJoint(float x, float y, float z, int which) +{ + if (num_joints < max_joints - 1) { + joints[num_joints].velocity = 0; + joints[num_joints].position.x = x; + joints[num_joints].position.y = y; + joints[num_joints].position.z = z; + joints[num_joints].mass = 1; + joints[num_joints].locked = 0; + + joints[num_joints].hasparent = 0; + num_joints++; + if (which < num_joints && which >= 0) + AddMuscle(num_joints - 1, which, 0, 10, boneconnect); + } +} + +/* EFFECT + * + * USES: + * NONE + */ +void Skeleton::DeleteJoint(int whichjoint) +{ + if (whichjoint < num_joints && whichjoint >= 0) { + joints[whichjoint].velocity = joints[num_joints - 1].velocity; + joints[whichjoint].position = joints[num_joints - 1].position; + joints[whichjoint].oldposition = joints[num_joints - 1].oldposition; + joints[whichjoint].hasparent = joints[num_joints - 1].hasparent; + joints[whichjoint].parent = joints[num_joints - 1].parent; + joints[whichjoint].length = joints[num_joints - 1].length; + joints[whichjoint].locked = joints[num_joints - 1].locked; + joints[whichjoint].modelnum = joints[num_joints - 1].modelnum; + joints[whichjoint].visible = joints[num_joints - 1].visible; + + for (int i = 0; i < num_muscles; i++) { + while (muscles[i].parent1 == &joints[whichjoint] && i < num_muscles)DeleteMuscle(i); + while (muscles[i].parent2 == &joints[whichjoint] && i < num_muscles)DeleteMuscle(i); + } + for (int i = 0; i < num_muscles; i++) { + while (muscles[i].parent1 == &joints[num_joints - 1] && i < num_muscles)muscles[i].parent1 = &joints[whichjoint]; + while (muscles[i].parent2 == &joints[num_joints - 1] && i < num_muscles)muscles[i].parent2 = &joints[whichjoint]; + } + for (int i = 0; i < num_joints; i++) { + if (joints[i].parent == &joints[whichjoint]) + joints[i].hasparent = 0; + } + for (int i = 0; i < num_joints; i++) { + if (joints[i].parent == &joints[num_joints - 1]) + joints[i].parent = &joints[whichjoint]; + } + + num_joints--; + } +} + +/* EFFECT + * + * USES: + * Skeleton::DeleteJoint - UNUSED + */ +void Skeleton::DeleteMuscle(int whichmuscle) +{ + if (whichmuscle < num_muscles) { + muscles[whichmuscle].minlength = muscles[num_muscles - 1].minlength; + muscles[whichmuscle].maxlength = muscles[num_muscles - 1].maxlength; + muscles[whichmuscle].strength = muscles[num_muscles - 1].strength; + muscles[whichmuscle].parent1 = muscles[num_muscles - 1].parent1; + muscles[whichmuscle].parent2 = muscles[num_muscles - 1].parent2; + muscles[whichmuscle].length = muscles[num_muscles - 1].length; + muscles[whichmuscle].visible = muscles[num_muscles - 1].visible; + muscles[whichmuscle].type = muscles[num_muscles - 1].type; + muscles[whichmuscle].targetlength = muscles[num_muscles - 1].targetlength; + + num_muscles--; + } +} + +/* EFFECT + * + * USES: + * NONE + */ +void Skeleton::SetJoint(float x, float y, float z, int which, int whichjoint) +{ + if (whichjoint < num_joints) { + joints[whichjoint].velocity = 0; + joints[whichjoint].position.x = x; + joints[whichjoint].position.y = y; + joints[whichjoint].position.z = z; + + if (which >= num_joints || which < 0) + joints[whichjoint].hasparent = 0; + if (which < num_joints && which >= 0) { + joints[whichjoint].parent = &joints[which]; + joints[whichjoint].hasparent = 1; + joints[whichjoint].length = findDistance(&joints[whichjoint].position, &joints[whichjoint].parent->position); + } + } +} + +/* EFFECT + * + * USES: + * Skeleton::AddJoint - UNUSED + */ +void Skeleton::AddMuscle(int attach1, int attach2, float minlength, float maxlength, int type) +{ + const int max_muscles = 100; // FIXME: Probably can be dropped + if (num_muscles < max_muscles - 1 && attach1 < num_joints && attach1 >= 0 && attach2 < num_joints && attach2 >= 0 && attach1 != attach2) { + muscles[num_muscles].parent1 = &joints[attach1]; + muscles[num_muscles].parent2 = &joints[attach2]; + muscles[num_muscles].length = findDistance(&muscles[num_muscles].parent1->position, &muscles[num_muscles].parent2->position); + muscles[num_muscles].targetlength = findDistance(&muscles[num_muscles].parent1->position, &muscles[num_muscles].parent2->position); + muscles[num_muscles].strength = .7; + muscles[num_muscles].type = type; + muscles[num_muscles].minlength = minlength; + muscles[num_muscles].maxlength = maxlength; + + num_muscles++; + } +} + +/* EFFECT + * + * USES: + * NONE + */ +void Skeleton::MusclesSet() +{ + for (int i = 0; i < num_muscles; i++) { + muscles[i].length = findDistance(&muscles[i].parent1->position, &muscles[i].parent2->position); + } +} + +/* EFFECT + * + * USES: + * NONE + */ +void Skeleton::DoBalance() +{ + /*XYZ newpoint; + newpoint=joints[0].position; + newpoint.x=(joints[2].position.x+joints[4].position.x)/2; + newpoint.z=(joints[2].position.z+joints[4].position.z)/2; + joints[0].velocity=joints[0].velocity+(newpoint-joints[0].position); + //Move child point to within certain distance of parent point + joints[0].position=newpoint; + + MusclesSet();*/ +} + +#endif + diff --git a/Source/Animation/Skeleton.h b/Source/Animation/Skeleton.h new file mode 100644 index 0000000..7c482f9 --- /dev/null +++ b/Source/Animation/Skeleton.h @@ -0,0 +1,201 @@ +/* +Copyright (C) 2003, 2010 - Wolfire Games +Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file) + +This file is part of Lugaru. + +Lugaru is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +Lugaru is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Lugaru. If not, see . +*/ + +#ifndef _SKELETON_H_ +#define _SKELETON_H_ + +#include "Models.h" +#include "Quaternions.h" + + +/**> HEADER FILES <**/ +#include "gamegl.h" +#include "Quaternions.h" +#include "Objects.h" +#include "Sprite.h" +#include "binio.h" +#include "Animation/Animation.h" + +enum bodyparts { + head, neck, + leftshoulder, leftelbow, leftwrist, lefthand, + rightshoulder, rightelbow, rightwrist, righthand, + abdomen, lefthip, righthip, groin, + leftknee, leftankle, leftfoot, + rightknee, rightankle, rightfoot +}; + +class Joint +{ +public: + XYZ position; + XYZ oldposition; + XYZ realoldposition; + XYZ velocity; + XYZ oldvelocity; + XYZ startpos; + float blurred; + float length; + float mass; + bool lower; + bool hasparent; + bool locked; + int modelnum; + bool visible; + Joint* parent; + bool sametwist; + int label; + int hasgun; + float delay; + XYZ velchange; + + Joint() { + blurred = 0; + length = 0; + mass = 0; + lower = 0; + hasparent = 0; + locked = 0; + modelnum = 0; + visible = 0; + parent = 0; + sametwist = 0; + label = 0; + hasgun = 0; + delay = 0; + } +}; + +class Muscle +{ +public: + int numvertices; + int* vertices; + int numverticeslow; + int* verticeslow; + int numverticesclothes; + int* verticesclothes; + float length; + float targetlength; + Joint* parent1; + Joint* parent2; + float maxlength; + float minlength; + int type; + bool visible; + float rotate1, rotate2, rotate3; + float lastrotate1, lastrotate2, lastrotate3; + float oldrotate1, oldrotate2, oldrotate3; + float newrotate1, newrotate2, newrotate3; + + float strength; + + Muscle(); + ~Muscle(); + void DoConstraint(bool spinny); +}; + +const int max_joints = 50; + +class Skeleton +{ +public: + int num_joints; + //Joint joints[max_joints]; + //Joint *joints; + Joint* joints; + + int num_muscles; + //Muscle muscles[max_muscles]; + //Muscle *muscles; + Muscle* muscles; + + int selected; + + int forwardjoints[3]; + XYZ forward; + + int id; + + int lowforwardjoints[3]; + XYZ lowforward; + + XYZ specialforward[5]; + int jointlabels[max_joints]; + + Model model[7]; + Model modellow; + Model modelclothes; + int num_models; + + Model drawmodel; + Model drawmodellow; + Model drawmodelclothes; + + bool clothes; + bool spinny; + + GLubyte skinText[512 * 512 * 3]; + int skinsize; + + float checkdelay; + + float longdead; + bool broken; + + int free; + int oldfree; + float freetime; + bool freefall; + + void FindForwards(); + float DoConstraints(XYZ *coords, float *scale); + void DoGravity(float *scale); + void FindRotationJoint(int which); + void FindRotationJointSameTwist(int which); + void FindRotationMuscle(int which, int animation); + void Load(const std::string& fileName, const std::string& lowfileName, const std::string& clothesfileName, const std::string& modelfileName, const std::string& model2fileName, const std::string& model3fileName, const std::string& model4fileName, const std::string& model5fileNamee, const std::string& model6fileName, const std::string& model7fileName, const std::string& modellowfileName, const std::string& modelclothesfileName, bool aclothes); + + /* + // unused + void FindForwardsfirst(); + void Draw(int muscleview); + void AddJoint(float x, float y, float z, int which); + void SetJoint(float x, float y, float z, int which, int whichjoint); + void DeleteJoint(int whichjoint); + void AddMuscle(int attach1, int attach2, float maxlength, float minlength, int type); + void DeleteMuscle(int whichmuscle); + void DoBalance(); + void MusclesSet(); + */ + + Skeleton(); + ~Skeleton(); + +private: + // convenience functions + // only for Skeleton.cpp + inline Joint& joint(int bodypart) { return joints[jointlabels[bodypart]]; } + inline XYZ& jointPos(int bodypart) { return joint(bodypart).position; } + inline XYZ& jointVel(int bodypart) { return joint(bodypart).velocity; } + +}; + +#endif diff --git a/Source/Game.h b/Source/Game.h index 4f7a2aa..5526681 100644 --- a/Source/Game.h +++ b/Source/Game.h @@ -27,7 +27,7 @@ along with Lugaru. If not, see . #include "Terrain.h" #include "Skybox.h" -#include "Skeleton.h" +#include "Animation/Skeleton.h" #include "Models.h" #include "Lights.h" #include "Person.h" diff --git a/Source/GameInitDispose.cpp b/Source/GameInitDispose.cpp index c12904d..24a9de3 100644 --- a/Source/GameInitDispose.cpp +++ b/Source/GameInitDispose.cpp @@ -20,7 +20,7 @@ along with Lugaru. If not, see . #include "Game.h" #include "openal_wrapper.h" -#include "Animation.h" +#include "Animation/Animation.h" #include "Texture.h" #include "Utils/Folders.h" @@ -628,6 +628,8 @@ void Game::InitGame() newscreenheight = screenheight; LoadMenu(); + + Animation::loadAll(); } @@ -819,58 +821,57 @@ void Game::LoadStuff() firstload = 0; - loadAllAnimations(); //Fix knife stab, too lazy to do it manually XYZ moveamount; moveamount = 0; moveamount.z = 2; for (i = 0; i < Person::players[0]->skeleton.num_joints; i++) { - for (j = 0; j < animation[knifesneakattackanim].numframes; j++) { - animation[knifesneakattackanim].position[i][j] += moveamount; + for (j = 0; j < Animation::animations[knifesneakattackanim].numframes; j++) { + Animation::animations[knifesneakattackanim].position[i][j] += moveamount; } } LoadingScreen(); for (i = 0; i < Person::players[0]->skeleton.num_joints; i++) { - for (j = 0; j < animation[knifesneakattackedanim].numframes; j++) { - animation[knifesneakattackedanim].position[i][j] += moveamount; + for (j = 0; j < Animation::animations[knifesneakattackedanim].numframes; j++) { + Animation::animations[knifesneakattackedanim].position[i][j] += moveamount; } } LoadingScreen(); for (i = 0; i < Person::players[0]->skeleton.num_joints; i++) { - animation[dead1anim].position[i][1] = animation[dead1anim].position[i][0]; - animation[dead2anim].position[i][1] = animation[dead2anim].position[i][0]; - animation[dead3anim].position[i][1] = animation[dead3anim].position[i][0]; - animation[dead4anim].position[i][1] = animation[dead4anim].position[i][0]; + Animation::animations[dead1anim].position[i][1] = Animation::animations[dead1anim].position[i][0]; + Animation::animations[dead2anim].position[i][1] = Animation::animations[dead2anim].position[i][0]; + Animation::animations[dead3anim].position[i][1] = Animation::animations[dead3anim].position[i][0]; + Animation::animations[dead4anim].position[i][1] = Animation::animations[dead4anim].position[i][0]; } - animation[dead1anim].speed[0] = 0.001; - animation[dead2anim].speed[0] = 0.001; - animation[dead3anim].speed[0] = 0.001; - animation[dead4anim].speed[0] = 0.001; + Animation::animations[dead1anim].speed[0] = 0.001; + Animation::animations[dead2anim].speed[0] = 0.001; + Animation::animations[dead3anim].speed[0] = 0.001; + Animation::animations[dead4anim].speed[0] = 0.001; - animation[dead1anim].speed[1] = 0.001; - animation[dead2anim].speed[1] = 0.001; - animation[dead3anim].speed[1] = 0.001; - animation[dead4anim].speed[1] = 0.001; + Animation::animations[dead1anim].speed[1] = 0.001; + Animation::animations[dead2anim].speed[1] = 0.001; + Animation::animations[dead3anim].speed[1] = 0.001; + Animation::animations[dead4anim].speed[1] = 0.001; for (i = 0; i < Person::players[0]->skeleton.num_joints; i++) { - for (j = 0; j < animation[swordsneakattackanim].numframes; j++) { - animation[swordsneakattackanim].position[i][j] += moveamount; + for (j = 0; j < Animation::animations[swordsneakattackanim].numframes; j++) { + Animation::animations[swordsneakattackanim].position[i][j] += moveamount; } } LoadingScreen(); - for (j = 0; j < animation[swordsneakattackanim].numframes; j++) { - animation[swordsneakattackanim].weapontarget[j] += moveamount; + for (j = 0; j < Animation::animations[swordsneakattackanim].numframes; j++) { + Animation::animations[swordsneakattackanim].weapontarget[j] += moveamount; } LoadingScreen(); for (i = 0; i < Person::players[0]->skeleton.num_joints; i++) { - for (j = 0; j < animation[swordsneakattackedanim].numframes; j++) { - animation[swordsneakattackedanim].position[i][j] += moveamount; + for (j = 0; j < Animation::animations[swordsneakattackedanim].numframes; j++) { + Animation::animations[swordsneakattackedanim].position[i][j] += moveamount; } } diff --git a/Source/GameTick.cpp b/Source/GameTick.cpp index df0bc20..da2291f 100644 --- a/Source/GameTick.cpp +++ b/Source/GameTick.cpp @@ -38,7 +38,7 @@ along with Lugaru. If not, see . #include "openal_wrapper.h" #include "Settings.h" #include "Input.h" -#include "Animation.h" +#include "Animation/Animation.h" #include "Awards.h" #include "Menu.h" #include "ConsoleCmds.h" @@ -827,7 +827,7 @@ void Game::Loadlevel(const std::string& name) hostiletime = 0; won = 0; - animation[bounceidleanim].Load("Idle", middleheight, neutral); + //~ Animation::animations[bounceidleanim].Load("Idle", middleheight, neutral); Dialog::dialogs.clear(); @@ -1159,7 +1159,7 @@ void Game::Loadlevel(const std::string& name) Person::players[i]->proportionlegs.z = 0; } - Person::players[i]->tempanimation.Load("Tempanim", 0, 0); + Person::players[i]->tempanimation = Animation("Tempanim", 0, 0); if (i == 0) { Person::players[i]->headmorphness = 0; @@ -1694,7 +1694,7 @@ void doTutorial() tutorialsuccess = 1; break; case 28: - if (animation[Person::players[0]->animTarget].attack == reversed && Person::players[0]->feint) + if (Animation::animations[Person::players[0]->animTarget].attack == reversed && Person::players[0]->feint) tutorialsuccess = 1; break; case 29: @@ -1706,15 +1706,15 @@ void doTutorial() } break; case 33: - if (animation[Person::players[0]->animTarget].attack == reversal) + if (Animation::animations[Person::players[0]->animTarget].attack == reversal) tutorialsuccess = 1; break; case 34: - if (animation[Person::players[0]->animTarget].attack == reversal) + if (Animation::animations[Person::players[0]->animTarget].attack == reversal) tutorialsuccess = 1; break; case 35: - if (animation[Person::players[0]->animTarget].attack == reversal) { + if (Animation::animations[Person::players[0]->animTarget].attack == reversal) { tutorialsuccess = 1; reversaltrain = 0; cananger = 0; @@ -1734,15 +1734,15 @@ void doTutorial() tutorialsuccess = 1; break; case 44: - if (animation[Person::players[0]->animTarget].attack == reversal) + if (Animation::animations[Person::players[0]->animTarget].attack == reversal) tutorialsuccess = 1; break; case 45: - if (animation[Person::players[0]->animTarget].attack == reversal) + if (Animation::animations[Person::players[0]->animTarget].attack == reversal) tutorialsuccess = 1; break; case 46: - if (animation[Person::players[0]->animTarget].attack == reversal) + if (Animation::animations[Person::players[0]->animTarget].attack == reversal) tutorialsuccess = 1; break; case 49: @@ -2238,7 +2238,7 @@ void doDebugKeys() Person::players.back()->proportionlegs.z = 0; } - Person::players.back()->tempanimation.Load("Tempanim", 0, 0); + Person::players.back()->tempanimation = Animation("Tempanim", 0, 0); Person::players.back()->damagetolerance = 200; @@ -2424,7 +2424,7 @@ void doJumpReversals() if (Person::players[i]->animTarget == jumpupanim && Person::players[k]->animTarget != getupfrombackanim && Person::players[k]->animTarget != getupfromfrontanim && - animation[Person::players[k]->animTarget].height == middleheight && + Animation::animations[Person::players[k]->animTarget].height == middleheight && normaldotproduct(Person::players[i]->velocity, Person::players[k]->coords - Person::players[i]->coords) < 0 && ((Person::players[k]->aitype == playercontrolled && Person::players[k]->attackkeydown) || Person::players[k]->aitype != playercontrolled)) { @@ -2463,7 +2463,7 @@ void doJumpReversals() if (Person::players[k]->animTarget == jumpupanim && Person::players[i]->animTarget != getupfrombackanim && Person::players[i]->animTarget != getupfromfrontanim && - animation[Person::players[i]->animTarget].height == middleheight && + Animation::animations[Person::players[i]->animTarget].height == middleheight && normaldotproduct(Person::players[k]->velocity, Person::players[i]->coords - Person::players[k]->coords) < 0 && ((Person::players[i]->aitype == playercontrolled && Person::players[i]->attackkeydown) || Person::players[i]->aitype != playercontrolled)) { @@ -2531,7 +2531,7 @@ void doAerialAcrobatics() Person::players[k]->animTarget == backhandspringanim || Person::players[k]->animTarget == dodgebackanim || Person::players[k]->animTarget == rollanim || - (animation[Person::players[k]->animTarget].attack && + (Animation::animations[Person::players[k]->animTarget].attack && Person::players[k]->animTarget != rabbitkickanim && (Person::players[k]->animTarget != crouchstabanim || Person::players[k]->hasvictim) && (Person::players[k]->animTarget != swordgroundstabanim || Person::players[k]->hasvictim))) { @@ -2682,7 +2682,7 @@ void doAerialAcrobatics() if (Person::players[k]->animTarget == jumpdownanim || Person::players[k]->isFlip()) { //flipped into a rock - if (Person::players[k]->isFlip() && animation[Person::players[k]->animTarget].label[Person::players[k]->frameTarget] == 7) + if (Person::players[k]->isFlip() && Animation::animations[Person::players[k]->animTarget].label[Person::players[k]->frameTarget] == 7) Person::players[k]->RagDoll(0); if (Person::players[k]->animTarget == jumpupanim) { @@ -2960,7 +2960,7 @@ void doAttacks() } } //attack - if (!animation[Person::players[k]->animTarget].attack && + if (!Animation::animations[Person::players[k]->animTarget].attack && !Person::players[k]->backkeydown && (Person::players[k]->isIdle() || Person::players[k]->isRun() || @@ -2975,7 +2975,7 @@ void doAttacks() if (i == k || !(k == 0 || i == 0)) continue; if (!Person::players[k]->hasvictim) - if (animation[Person::players[k]->animTarget].attack != reversal) { + if (Animation::animations[Person::players[k]->animTarget].attack != reversal) { //choose an attack const float distance = distsq(&Person::players[k]->coords, &Person::players[i]->coords); if (distance < 4.5 && @@ -2988,7 +2988,7 @@ void doAttacks() Person::players[i]->animTarget != getupfrombackanim && (Person::players[i]->animTarget != staggerbackhighanim && (Person::players[i]->animTarget != staggerbackhardanim || - animation[staggerbackhardanim].label[Person::players[i]->frameTarget] == 6)) && + Animation::animations[staggerbackhardanim].label[Person::players[i]->frameTarget] == 6)) && Person::players[i]->animTarget != jumpdownanim && Person::players[i]->animTarget != jumpupanim && Person::players[i]->animTarget != getupfromfrontanim) { @@ -2998,11 +2998,11 @@ void doAttacks() //sweep if (distance < 2.5 * sq(Person::players[k]->scale * 5) && Person::players[k]->crouchkeydown && - animation[Person::players[i]->animTarget].height != lowheight) + Animation::animations[Person::players[i]->animTarget].height != lowheight) Person::players[k]->animTarget = sweepanim; //winduppunch else if (distance < 1.5 * sq(Person::players[k]->scale * 5) && - animation[Person::players[i]->animTarget].height != lowheight && + Animation::animations[Person::players[i]->animTarget].height != lowheight && !Person::players[k]->forwardkeydown && !Person::players[k]->leftkeydown && !Person::players[k]->rightkeydown && @@ -3012,7 +3012,7 @@ void doAttacks() Person::players[k]->animTarget = winduppunchanim; //upunch else if (distance < 2.5 * sq(Person::players[k]->scale * 5) && - animation[Person::players[i]->animTarget].height != lowheight && + Animation::animations[Person::players[i]->animTarget].height != lowheight && !Person::players[k]->forwardkeydown && !Person::players[k]->leftkeydown && !Person::players[k]->rightkeydown && @@ -3027,7 +3027,7 @@ void doAttacks() Person::players[k]->animTarget = knifefollowanim; //knifeslashstart else if (distance < 2.5 * sq(Person::players[k]->scale * 5) && - animation[Person::players[i]->animTarget].height != lowheight && + Animation::animations[Person::players[i]->animTarget].height != lowheight && !Person::players[k]->forwardkeydown && !Person::players[k]->leftkeydown && !Person::players[k]->rightkeydown && @@ -3037,14 +3037,14 @@ void doAttacks() Person::players[k]->animTarget = knifeslashstartanim; //swordslash else if (distance < 4.5 * sq(Person::players[k]->scale * 5) && - animation[Person::players[i]->animTarget].height != lowheight && + Animation::animations[Person::players[i]->animTarget].height != lowheight && !Person::players[k]->crouchkeydown && attackweapon == sword && Person::players[k]->weaponmissdelay <= 0) Person::players[k]->animTarget = swordslashanim; //staffhit else if (distance < 4.5 * sq(Person::players[k]->scale * 5) && - animation[Person::players[i]->animTarget].height != lowheight && + Animation::animations[Person::players[i]->animTarget].height != lowheight && !Person::players[k]->crouchkeydown && attackweapon == staff && Person::players[k]->weaponmissdelay <= 0 && @@ -3054,36 +3054,36 @@ void doAttacks() Person::players[k]->animTarget = staffhitanim; //staffspinhit else if (distance < 4.5 * sq(Person::players[k]->scale * 5) && - animation[Person::players[i]->animTarget].height != lowheight && + Animation::animations[Person::players[i]->animTarget].height != lowheight && !Person::players[k]->crouchkeydown && attackweapon == staff && Person::players[k]->weaponmissdelay <= 0) Person::players[k]->animTarget = staffspinhitanim; //spinkick else if (distance < 2.5 * sq(Person::players[k]->scale * 5) && - animation[Person::players[i]->animTarget].height != lowheight) + Animation::animations[Person::players[i]->animTarget].height != lowheight) Person::players[k]->animTarget = spinkickanim; //lowkick else if (distance < 2.5 * sq(Person::players[k]->scale * 5) && - animation[Person::players[i]->animTarget].height == lowheight && - animation[Person::players[k]->animTarget].attack != normalattack) + Animation::animations[Person::players[i]->animTarget].height == lowheight && + Animation::animations[Person::players[k]->animTarget].attack != normalattack) Person::players[k]->animTarget = lowkickanim; } else { //AI player if (distance < 4.5 * sq(Person::players[k]->scale * 5)) { randattack = abs(Random() % 5); if (!attackweapon && distance < 2.5 * sq(Person::players[k]->scale * 5)) { //sweep - if (randattack == 0 && animation[Person::players[i]->animTarget].height != lowheight) + if (randattack == 0 && Animation::animations[Person::players[i]->animTarget].height != lowheight) Person::players[k]->animTarget = sweepanim; //upunch - else if (randattack == 1 && animation[Person::players[i]->animTarget].height != lowheight && + else if (randattack == 1 && Animation::animations[Person::players[i]->animTarget].height != lowheight && !attackweapon) Person::players[k]->animTarget = upunchanim; //spinkick - else if (randattack == 2 && animation[Person::players[i]->animTarget].height != lowheight) + else if (randattack == 2 && Animation::animations[Person::players[i]->animTarget].height != lowheight) Person::players[k]->animTarget = spinkickanim; //lowkick - else if (animation[Person::players[i]->animTarget].height == lowheight) + else if (Animation::animations[Person::players[i]->animTarget].height == lowheight) Person::players[k]->animTarget = lowkickanim; } if (attackweapon) { @@ -3091,7 +3091,7 @@ void doAttacks() if ((tutoriallevel != 1 || !attackweapon) && distance < 2.5 * sq(Person::players[k]->scale * 5) && randattack == 0 && - animation[Person::players[i]->animTarget].height != lowheight) + Animation::animations[Person::players[i]->animTarget].height != lowheight) Person::players[k]->animTarget = sweepanim; //knifeslashstart else if (distance < 2.5 * sq(Person::players[k]->scale * 5) && @@ -3125,12 +3125,12 @@ void doAttacks() else if ((tutoriallevel != 1 || !attackweapon) && distance < 2.5 * sq(Person::players[k]->scale * 5) && randattack == 1 && - animation[Person::players[i]->animTarget].height != lowheight) + Animation::animations[Person::players[i]->animTarget].height != lowheight) Person::players[k]->animTarget = spinkickanim; //lowkick else if (distance < 2.5 * sq(Person::players[k]->scale * 5) && - animation[Person::players[i]->animTarget].height == lowheight && - animation[Person::players[k]->animTarget].attack != normalattack) + Animation::animations[Person::players[i]->animTarget].height == lowheight && + Animation::animations[Person::players[k]->animTarget].attack != normalattack) Person::players[k]->animTarget = lowkickanim; } } @@ -3195,7 +3195,7 @@ void doAttacks() Person::players[i]->targetyaw = Person::players[i]->yaw; } } - if (animation[Person::players[k]->animTarget].attack == normalattack && + if (Animation::animations[Person::players[k]->animTarget].attack == normalattack && Person::players[k]->victim == Person::players[i] && (!Person::players[i]->skeleton.free)) { oldattackkey = 1; @@ -3245,7 +3245,7 @@ void doAttacks() if (i == k) continue; if ((playerrealattackkeydown || Person::players[i]->dead || !hasstaff) && - animation[Person::players[k]->animTarget].attack == neutral) { + Animation::animations[Person::players[k]->animTarget].attack == neutral) { const float distance = distsq(&Person::players[k]->coords, &Person::players[i]->coords); if (!Person::players[i]->dead || !realthreat || (!attackweapon && Person::players[k]->crouchkeydown)) if (Person::players[i]->skeleton.free) @@ -3324,7 +3324,7 @@ void doAttacks() } } } - if (animation[Person::players[k]->animTarget].attack == normalattack && + if (Animation::animations[Person::players[k]->animTarget].attack == normalattack && Person::players[k]->victim == Person::players[i] && (!Person::players[i]->skeleton.free || Person::players[k]->animTarget == killanim || @@ -3392,7 +3392,7 @@ void doAttacks() !Person::players[k]->victim->skeleton.free && Person::players[k]->victim->animTarget != getupfrombackanim && Person::players[k]->victim->animTarget != getupfromfrontanim && - animation[Person::players[k]->victim->animTarget].height != lowheight && + Animation::animations[Person::players[k]->victim->animTarget].height != lowheight && Person::players[k]->aitype != playercontrolled && //wat??? normaldotproduct(Person::players[k]->facing, Person::players[k]->victim->coords - Person::players[k]->coords) > 0 && Person::players[k]->rabbitkickenabled) || @@ -3401,7 +3401,7 @@ void doAttacks() Person::players[k]->setAnimation(rabbitkickanim); } //update counts - if (animation[Person::players[k]->animTarget].attack && k == 0) { + if (Animation::animations[Person::players[k]->animTarget].attack && k == 0) { numattacks++; switch (attackweapon) { case 0: @@ -3432,14 +3432,14 @@ void doPlayerCollisions() for (unsigned k = 0; k < Person::players.size(); k++) for (unsigned i = k + 1; i < Person::players.size(); i++) { //neither player is part of a reversal - if ((animation[Person::players[i]->animTarget].attack != reversed && - animation[Person::players[i]->animTarget].attack != reversal && - animation[Person::players[k]->animTarget].attack != reversed && - animation[Person::players[k]->animTarget].attack != reversal) || (i != 0 && k != 0)) - if ((animation[Person::players[i]->animCurrent].attack != reversed && - animation[Person::players[i]->animCurrent].attack != reversal && - animation[Person::players[k]->animCurrent].attack != reversed && - animation[Person::players[k]->animCurrent].attack != reversal) || (i != 0 && k != 0)) + if ((Animation::animations[Person::players[i]->animTarget].attack != reversed && + Animation::animations[Person::players[i]->animTarget].attack != reversal && + Animation::animations[Person::players[k]->animTarget].attack != reversed && + Animation::animations[Person::players[k]->animTarget].attack != reversal) || (i != 0 && k != 0)) + if ((Animation::animations[Person::players[i]->animCurrent].attack != reversed && + Animation::animations[Person::players[i]->animCurrent].attack != reversal && + Animation::animations[Person::players[k]->animCurrent].attack != reversed && + Animation::animations[Person::players[k]->animCurrent].attack != reversal) || (i != 0 && k != 0)) //neither is sleeping if (Person::players[i]->howactive <= typesleeping && Person::players[k]->howactive <= typesleeping) if (Person::players[i]->howactive != typesittingwall && Person::players[k]->howactive != typesittingwall) @@ -3519,16 +3519,16 @@ void doPlayerCollisions() k == 0 && findLengthfast(&rotatetarget) > 50 && Person::players[0]->rabbitkickragdoll) && normaldotproduct(rotatetarget, Person::players[k]->coords - Person::players[i]->coords) > 0) && (k == 0 || - k != 0 && Person::players[i]->skeleton.oldfree == 1 && animation[Person::players[k]->animCurrent].attack == neutral || - /*i!=0&&*/Person::players[k]->skeleton.oldfree == 1 && animation[Person::players[i]->animCurrent].attack == neutral)) || + k != 0 && Person::players[i]->skeleton.oldfree == 1 && Animation::animations[Person::players[k]->animCurrent].attack == neutral || + /*i!=0&&*/Person::players[k]->skeleton.oldfree == 1 && Animation::animations[Person::players[i]->animCurrent].attack == neutral)) || (Person::players[i]->animTarget == jumpupanim || Person::players[i]->animTarget == jumpdownanim || Person::players[i]->isFlip()) && (Person::players[k]->animTarget == jumpupanim || Person::players[k]->animTarget == jumpdownanim || Person::players[k]->isFlip()) && k == 0 && !Person::players[i]->skeleton.oldfree && !Person::players[k]->skeleton.oldfree) { //If hit by body if ( (i != 0 || Person::players[i]->skeleton.free) && (k != 0 || Person::players[k]->skeleton.free) || - (animation[Person::players[i]->animTarget].height == highheight && - animation[Person::players[k]->animTarget].height == highheight)) { + (Animation::animations[Person::players[i]->animTarget].height == highheight && + Animation::animations[Person::players[k]->animTarget].height == highheight)) { if (tutoriallevel != 1) { emit_sound_at(heavyimpactsound, Person::players[i]->coords); } @@ -3553,10 +3553,10 @@ void doPlayerCollisions() } } - if ( (animation[Person::players[i]->animTarget].attack == neutral || - animation[Person::players[i]->animTarget].attack == normalattack) && - (animation[Person::players[k]->animTarget].attack == neutral || - animation[Person::players[k]->animTarget].attack == normalattack)) { + if ( (Animation::animations[Person::players[i]->animTarget].attack == neutral || + Animation::animations[Person::players[i]->animTarget].attack == normalattack) && + (Animation::animations[Person::players[k]->animTarget].attack == neutral || + Animation::animations[Person::players[k]->animTarget].attack == normalattack)) { //If bumped if (Person::players[i]->skeleton.oldfree == 0 && Person::players[k]->skeleton.oldfree == 0) { if (distsq(&Person::players[k]->coords, &Person::players[i]->coords) < .5 * sq((Person::players[i]->scale + Person::players[k]->scale) * 2.5)) { @@ -3777,12 +3777,12 @@ void doAI(unsigned i) distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 400 && Person::players[i]->occluded < 25) { if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 12 && - animation[Person::players[0]->animTarget].height != lowheight && + Animation::animations[Person::players[0]->animTarget].height != lowheight && !editorenabled && (Person::players[0]->coords.y < Person::players[i]->coords.y + 5 || Person::players[0]->onterrain)) Person::players[i]->aitype = attacktypecutoff; if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 30 && - animation[Person::players[0]->animTarget].height == highheight && + Animation::animations[Person::players[0]->animTarget].height == highheight && !editorenabled) Person::players[i]->aitype = attacktypecutoff; @@ -3790,7 +3790,7 @@ void doAI(unsigned i) Person::players[i]->losupdatedelay = .2; for (unsigned j = 0; j < Person::players.size(); j++) if (j == 0 || Person::players[j]->skeleton.free || Person::players[j]->aitype != passivetype) - if (abs(Random() % 2) || animation[Person::players[j]->animTarget].height != lowheight || j != 0) + if (abs(Random() % 2) || Animation::animations[Person::players[j]->animTarget].height != lowheight || j != 0) if (distsq(&Person::players[i]->coords, &Person::players[j]->coords) < 400) if (normaldotproduct(Person::players[i]->facing, Person::players[j]->coords - Person::players[i]->coords) > 0) if (Person::players[j]->coords.y < Person::players[i]->coords.y + 5 || Person::players[j]->onterrain) @@ -3900,10 +3900,10 @@ void doAI(unsigned i) distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 400 && Person::players[i]->occluded < 25) { if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 12 && - animation[Person::players[0]->animTarget].height != lowheight && !editorenabled) + Animation::animations[Person::players[0]->animTarget].height != lowheight && !editorenabled) Person::players[i]->aitype = attacktypecutoff; if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 30 && - animation[Person::players[0]->animTarget].height == highheight && !editorenabled) + Animation::animations[Person::players[0]->animTarget].height == highheight && !editorenabled) Person::players[i]->aitype = attacktypecutoff; //wolf smell @@ -3934,7 +3934,7 @@ void doAI(unsigned i) Person::players[i]->losupdatedelay = .2; for (unsigned j = 0; j < Person::players.size(); j++) { if (j == 0 || Person::players[j]->skeleton.free || Person::players[j]->aitype != passivetype) { - if (abs(Random() % 2) || animation[Person::players[j]->animTarget].height != lowheight || j != 0) + if (abs(Random() % 2) || Animation::animations[Person::players[j]->animTarget].height != lowheight || j != 0) if (distsq(&Person::players[i]->coords, &Person::players[j]->coords) < 400) if (normaldotproduct(Person::players[i]->facing, Person::players[j]->coords - Person::players[i]->coords) > 0) if ((-1 == checkcollide( @@ -3946,7 +3946,7 @@ void doAI(unsigned i) (Person::players[j]->animTarget == hanganim && normaldotproduct(Person::players[j]->facing, Person::players[i]->coords - Person::players[j]->coords) < 0)) { Person::players[i]->lastseentime -= .2; - if (j == 0 && animation[Person::players[j]->animTarget].height == lowheight) + if (j == 0 && Animation::animations[Person::players[j]->animTarget].height == lowheight) Person::players[i]->lastseentime -= .4; else Person::players[i]->lastseentime -= .6; @@ -4068,11 +4068,11 @@ void doAI(unsigned i) Person::players[i]->occluded < 2 && ((tutoriallevel != 1 || cananger) && hostile)) { Person::players[i]->losupdatedelay = .2; - if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 4 && animation[Person::players[i]->animTarget].height != lowheight) { + if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 4 && Animation::animations[Person::players[i]->animTarget].height != lowheight) { Person::players[i]->aitype = attacktypecutoff; Person::players[i]->lastseentime = 1; } - if (abs(Random() % 2) || animation[Person::players[i]->animTarget].height != lowheight) + if (abs(Random() % 2) || Animation::animations[Person::players[i]->animTarget].height != lowheight) //TODO: factor out canSeePlayer() if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 400) if (normaldotproduct(Person::players[i]->facing, Person::players[0]->coords - Person::players[i]->coords) > 0) @@ -4350,7 +4350,7 @@ void doAI(unsigned i) } //dodge/reverse walljump kicks if (Person::players[i]->damage < Person::players[i]->damagetolerance / 2) - if (animation[Person::players[i]->animTarget].height != highheight) + if (Animation::animations[Person::players[i]->animTarget].height != highheight) if (Person::players[i]->damage < Person::players[i]->damagetolerance * .5 && ((Person::players[0]->animTarget == walljumprightkickanim || Person::players[0]->animTarget == walljumpleftkickanim) && @@ -4388,7 +4388,7 @@ void doAI(unsigned i) } //lose sight of player in the air (?) if (Person::players[0]->coords.y > Person::players[i]->coords.y + 5 && - animation[Person::players[0]->animTarget].height != highheight && + Animation::animations[Person::players[0]->animTarget].height != highheight && !Person::players[0]->onterrain) { Person::players[i]->aitype = pathfindtype; Person::players[i]->finalfinaltarget = Person::players[i]->waypoints[Person::players[i]->waypoint]; @@ -4401,7 +4401,7 @@ void doAI(unsigned i) } //it's time to think (?) if (Person::players[i]->aiupdatedelay < 0 && - !animation[Person::players[i]->animTarget].attack && + !Animation::animations[Person::players[i]->animTarget].attack && Person::players[i]->animTarget != staggerbackhighanim && Person::players[i]->animTarget != staggerbackhardanim && Person::players[i]->animTarget != backhandspringanim && @@ -4550,7 +4550,7 @@ void doAI(unsigned i) Person::players[i]->lastseentime = 1; } } - if (animation[Person::players[0]->animTarget].height == highheight && + if (Animation::animations[Person::players[0]->animTarget].height == highheight && (Person::players[i]->aitype == attacktypecutoff || Person::players[i]->aitype == searchtype)) if (Person::players[0]->coords.y > terrain.getHeight(Person::players[0]->coords.x, Person::players[0]->coords.z) + 10) { @@ -5427,7 +5427,7 @@ void Game::Tick() talkdelay = 1; talkdelay -= multiplier; - if (talkdelay <= 0 && !Dialog::inDialog() && animation[Person::players[0]->animTarget].height != highheight) { + if (talkdelay <= 0 && !Dialog::inDialog() && Animation::animations[Person::players[0]->animTarget].height != highheight) { for (int i = 0; i < Dialog::dialogs.size(); i++) { Dialog::dialogs[i].tick(i); } @@ -5782,7 +5782,7 @@ void Game::Tick() oldtargetyaw = Person::players[i]->targetyaw; if (i == 0 && !Dialog::inDialog()) { //TODO: refactor repetitive code - if (!animation[Person::players[0]->animTarget].attack && + if (!Animation::animations[Person::players[0]->animTarget].attack && Person::players[0]->animTarget != staggerbackhighanim && Person::players[0]->animTarget != staggerbackhardanim && Person::players[0]->animTarget != crouchremoveknifeanim && @@ -5814,7 +5814,7 @@ void Game::Tick() Person::players[i]->targetheadpitch = pitch; } if (i != 0 && Person::players[i]->aitype == playercontrolled && !Dialog::inDialog()) { - if (!animation[Person::players[i]->animTarget].attack && + if (!Animation::animations[Person::players[i]->animTarget].attack && Person::players[i]->animTarget != staggerbackhighanim && Person::players[i]->animTarget != staggerbackhardanim && Person::players[i]->animTarget != crouchremoveknifeanim && @@ -5884,7 +5884,7 @@ void Game::Tick() doAI(i); - if (animation[Person::players[i]->animTarget].attack == reversed) { + if (Animation::animations[Person::players[i]->animTarget].attack == reversed) { //Person::players[i]->targetyaw=Person::players[i]->yaw; Person::players[i]->forwardkeydown = 0; Person::players[i]->leftkeydown = 0; @@ -5929,7 +5929,7 @@ void Game::Tick() Person::players[i]->aitype == attacktypecutoff && !Person::players[i]->dead && !Person::players[i]->skeleton.free && - animation[Person::players[i]->animTarget].attack == neutral) + Animation::animations[Person::players[i]->animTarget].attack == neutral) numresponded = 1; if (!Person::players[i]->throwkeydown) @@ -6257,7 +6257,7 @@ void Game::Tick() } movekey = 0; //Do controls - if (!animation[Person::players[i]->animTarget].attack && + if (!Animation::animations[Person::players[i]->animTarget].attack && Person::players[i]->animTarget != staggerbackhighanim && Person::players[i]->animTarget != staggerbackhardanim && Person::players[i]->animTarget != backhandspringanim && @@ -7107,7 +7107,7 @@ void Game::TickOnceAfter() viewerfacing = facing; if (!cameramode) { - if ((animation[Person::players[0]->animTarget].attack != 3 && animation[Person::players[0]->animCurrent].attack != 3) || Person::players[0]->skeleton.free) + if ((Animation::animations[Person::players[0]->animTarget].attack != 3 && Animation::animations[Person::players[0]->animCurrent].attack != 3) || Person::players[0]->skeleton.free) target = Person::players[0]->coords + Person::players[0]->currentoffset * (1 - Person::players[0]->target) * Person::players[0]->scale + Person::players[0]->targetoffset * Person::players[0]->target * Person::players[0]->scale - Person::players[0]->facing * .05; else target = Person::players[0]->oldcoords + Person::players[0]->currentoffset * (1 - Person::players[0]->target) * Person::players[0]->scale + Person::players[0]->targetoffset * Person::players[0]->target * Person::players[0]->scale - Person::players[0]->facing * .05; diff --git a/Source/Globals.cpp b/Source/Globals.cpp index 9e68823..8c09b7b 100644 --- a/Source/Globals.cpp +++ b/Source/Globals.cpp @@ -23,7 +23,8 @@ along with Lugaru. If not, see . #include "gamegl.h" #include "Quaternions.h" #include "Lights.h" -#include "Skeleton.h" +#include "Animation/Animation.h" +#include "Animation/Skeleton.h" #include "Terrain.h" #include "Sprite.h" #include "Frustum.h" @@ -34,7 +35,6 @@ along with Lugaru. If not, see . #include "openal_wrapper.h" #include "Stereo.h" -#include "Animation.h" bool visibleloading = 0; @@ -66,7 +66,6 @@ int environment = 0; float texscale = 0; float gravity = 0; Light light; -Animation animation[animation_count]; Terrain terrain; SDL_Window *sdlwindow; diff --git a/Source/Person.cpp b/Source/Person.cpp index 3c9a123..b745378 100644 --- a/Source/Person.cpp +++ b/Source/Person.cpp @@ -21,7 +21,7 @@ along with Lugaru. If not, see . /**> HEADER FILES <**/ #include "Person.h" #include "openal_wrapper.h" -#include "Animation.h" +#include "Animation/Animation.h" #include "Sounds.h" #include "Awards.h" #include "Game.h" @@ -472,7 +472,7 @@ void Person::CheckKick() && !victim->skeleton.free)) return; - if (animation[victim->animTarget].height != lowheight) { + if (Animation::animations[victim->animTarget].height != lowheight) { float damagemult = (creature == wolftype ? 2.5 : 1.) * power * power; XYZ relative = velocity; relative.y = 0; @@ -1477,7 +1477,7 @@ void Person::Reverse() if (aitype != playercontrolled && Random() % 10 == 0 && escapednum < 2 && difficulty == 0) feint = 1; - if (victim->id == 0 && animation[victim->animTarget].attack == reversal) + if (victim->id == 0 && Animation::animations[victim->animTarget].attack == reversal) numreversals++; } @@ -1736,16 +1736,16 @@ void Person::RagDoll(bool checkcollision) skeleton.joints[i].velchange = 0; } skeleton.DoConstraints(&coords, &scale); - if (animation[animCurrent].height == lowheight || animation[animTarget].height == lowheight) { + if (Animation::animations[animCurrent].height == lowheight || Animation::animations[animTarget].height == lowheight) { skeleton.DoConstraints(&coords, &scale); skeleton.DoConstraints(&coords, &scale); skeleton.DoConstraints(&coords, &scale); skeleton.DoConstraints(&coords, &scale); } - speed = animation[animTarget].speed[frameTarget] * 2; - if (animation[animCurrent].speed[frameCurrent] > animation[animTarget].speed[frameTarget]) { - speed = animation[animCurrent].speed[frameCurrent] * 2; + speed = Animation::animations[animTarget].speed[frameTarget] * 2; + if (Animation::animations[animCurrent].speed[frameCurrent] > Animation::animations[animTarget].speed[frameTarget]) { + speed = Animation::animations[animCurrent].speed[frameCurrent] * 2; } if (transspeed) speed = transspeed * 2; @@ -1753,8 +1753,8 @@ void Person::RagDoll(bool checkcollision) speed *= speedmult; for (int i = 0; i < skeleton.num_joints; i++) { - if ((animation[animCurrent].attack != reversed || animCurrent == swordslashreversedanim) && animCurrent != rabbitkickanim && !isLanding() && !wasLanding() && animation[animCurrent].height == animation[animTarget].height) - skeleton.joints[i].velocity = velocity / scale + facing * 5 + DoRotation(DoRotation(DoRotation((animation[animTarget].position[i][frameTarget] - animation[animCurrent].position[i][frameCurrent]) * speed, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0); + if ((Animation::animations[animCurrent].attack != reversed || animCurrent == swordslashreversedanim) && animCurrent != rabbitkickanim && !isLanding() && !wasLanding() && Animation::animations[animCurrent].height == Animation::animations[animTarget].height) + skeleton.joints[i].velocity = velocity / scale + facing * 5 + DoRotation(DoRotation(DoRotation((Animation::animations[animTarget].position[i][frameTarget] - Animation::animations[animCurrent].position[i][frameCurrent]) * speed, 0, 0, tilt), tilt2, 0, 0), 0, yaw, 0); else skeleton.joints[i].velocity = velocity / scale + facing * 5; change.x = (float)(Random() % 100) / 100; @@ -1922,7 +1922,7 @@ void Person::DoAnimations() normalsupdatedelay = 0; if (animTarget == tempanim || animCurrent == tempanim) { - animation[tempanim] = tempanimation; + Animation::animations[tempanim] = tempanimation; } if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) { float gLoc[3]; @@ -1962,21 +1962,21 @@ void Person::DoAnimations() numflipped++; } - if (animation[animTarget].attack != reversed) + if (Animation::animations[animTarget].attack != reversed) feint = 0; if (!crouchkeydown || (isLanding() || isLandhard()) || (wasLanding() || wasLandhard())) { crouchtogglekeydown = 0; if (aitype == playercontrolled) feint = 0; } else { - if (!crouchtogglekeydown && animation[animTarget].attack == reversed && aitype == playercontrolled && (escapednum < 2 || reversaltrain)) + if (!crouchtogglekeydown && Animation::animations[animTarget].attack == reversed && aitype == playercontrolled && (escapednum < 2 || reversaltrain)) feint = 1; if (!isFlip()) crouchtogglekeydown = 1; } - if (animation[animTarget].attack || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim) { + if (Animation::animations[animTarget].attack || animCurrent == getupfrombackanim || animCurrent == getupfromfrontanim) { if (detail) normalsupdatedelay = 0; } @@ -2015,7 +2015,7 @@ void Person::DoAnimations() } } - if (!drawtogglekeydown && drawkeydown && (weaponactive == -1 || num_weapons == 1) && (animation[animTarget].label[frameTarget] || (animTarget != animCurrent && animCurrent == rollanim)) && num_weapons > 0 && creature != wolftype) { + if (!drawtogglekeydown && drawkeydown && (weaponactive == -1 || num_weapons == 1) && (Animation::animations[animTarget].label[frameTarget] || (animTarget != animCurrent && animCurrent == rollanim)) && num_weapons > 0 && creature != wolftype) { if (weapons[weaponids[0]].getType() == knife) { if (weaponactive == -1) weaponactive = 0; @@ -2033,39 +2033,39 @@ void Person::DoAnimations() } //Footstep sounds if (tutoriallevel != 1 || id == 0) - if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) { + if ((Animation::animations[animTarget].label[frameTarget] && (Animation::animations[animTarget].label[frameTarget] < 5 || Animation::animations[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==Animation::animations[rollanim].numframes-1)*/) { int whichsound; if (onterrain) { if (terrain.getOpacity(coords.x, coords.z) < .2) { - if (animation[animTarget].label[frameTarget] == 1) + if (Animation::animations[animTarget].label[frameTarget] == 1) whichsound = footstepsound; else whichsound = footstepsound2; - if (animation[animTarget].label[frameTarget] == 1) + if (Animation::animations[animTarget].label[frameTarget] == 1) FootLand(leftfoot, 1); - if (animation[animTarget].label[frameTarget] == 2) + if (Animation::animations[animTarget].label[frameTarget] == 2) FootLand(rightfoot, 1); - if (animation[animTarget].label[frameTarget] == 3 && isRun()) { + if (Animation::animations[animTarget].label[frameTarget] == 3 && isRun()) { FootLand(rightfoot, 1); FootLand(leftfoot, 1); } } if (terrain.getOpacity(coords.x, coords.z) >= .2) { - if (animation[animTarget].label[frameTarget] == 1) + if (Animation::animations[animTarget].label[frameTarget] == 1) whichsound = footstepsound3; else whichsound = footstepsound4; } } if (!onterrain) { - if (animation[animTarget].label[frameTarget] == 1) + if (Animation::animations[animTarget].label[frameTarget] == 1) whichsound = footstepsound3; else whichsound = footstepsound4; } - if (animation[animTarget].label[frameTarget] == 4 && (weaponactive == -1 || (animTarget != knifeslashstartanim && animTarget != knifethrowanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != knifefollowanim))) { - if (animation[animTarget].attack != neutral) { + if (Animation::animations[animTarget].label[frameTarget] == 4 && (weaponactive == -1 || (animTarget != knifeslashstartanim && animTarget != knifethrowanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != knifefollowanim))) { + if (Animation::animations[animTarget].attack != neutral) { unsigned r = abs(Random() % 3); if (r == 0) whichsound = lowwhooshsound; @@ -2074,11 +2074,11 @@ void Person::DoAnimations() if (r == 2) whichsound = highwhooshsound; } - if (animation[animTarget].attack == neutral) + if (Animation::animations[animTarget].attack == neutral) whichsound = movewhooshsound; - } else if (animation[animTarget].label[frameTarget] == 4) + } else if (Animation::animations[animTarget].label[frameTarget] == 4) whichsound = knifeswishsound; - if (animation[animTarget].label[frameTarget] == 8 && tutoriallevel != 1) + if (Animation::animations[animTarget].label[frameTarget] == 8 && tutoriallevel != 1) whichsound = landsound2; emit_sound_at(whichsound, coords, 256.); @@ -2092,7 +2092,7 @@ void Person::DoAnimations() } } - if (animation[animTarget].label[frameTarget] == 3) { + if (Animation::animations[animTarget].label[frameTarget] == 3) { whichsound--; emit_sound_at(whichsound, coords, 128.); } @@ -2102,10 +2102,10 @@ void Person::DoAnimations() if (tutoriallevel != 1 || id == 0) if (speechdelay <= 0) if (animTarget != crouchstabanim && animTarget != swordgroundstabanim && animTarget != staffgroundsmashanim) - if ((animation[animTarget].label[frameTarget] && (animation[animTarget].label[frameTarget] < 5 || animation[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==animation[rollanim].numframes-1)*/) { + if ((Animation::animations[animTarget].label[frameTarget] && (Animation::animations[animTarget].label[frameTarget] < 5 || Animation::animations[animTarget].label[frameTarget] == 8))/*||(animTarget==rollanim&&frameTarget==Animation::animations[rollanim].numframes-1)*/) { int whichsound = -1; - if (animation[animTarget].label[frameTarget] == 4 && aitype != playercontrolled) { - if (animation[animTarget].attack != neutral) { + if (Animation::animations[animTarget].label[frameTarget] == 4 && aitype != playercontrolled) { + if (Animation::animations[animTarget].attack != neutral) { unsigned r = abs(Random() % 4); if (creature == rabbittype) { if (r == 0) whichsound = rabbitattacksound; @@ -2141,7 +2141,7 @@ void Person::DoAnimations() animCurrent = animTarget; frameTarget++; - if (animTarget == removeknifeanim && animation[animTarget].label[frameCurrent] == 5) { + if (animTarget == removeknifeanim && Animation::animations[animTarget].label[frameCurrent] == 5) { for (unsigned i = 0; i < weapons.size(); i++) { if (weapons[i].owner == -1) if (distsqflat(&coords, &weapons[i].position) < 4 && weaponactive == -1) { @@ -2156,7 +2156,7 @@ void Person::DoAnimations() } } - if (animTarget == crouchremoveknifeanim && animation[animTarget].label[frameCurrent] == 5) { + if (animTarget == crouchremoveknifeanim && Animation::animations[animTarget].label[frameCurrent] == 5) { for (unsigned i = 0; i < weapons.size(); i++) { bool willwork = true; if (weapons[i].owner != -1) @@ -2232,7 +2232,7 @@ void Person::DoAnimations() } } - if (animCurrent == drawleftanim && animation[animTarget].label[frameCurrent] == 5) { + if (animCurrent == drawleftanim && Animation::animations[animTarget].label[frameCurrent] == 5) { if (weaponactive == -1) weaponactive = 0; else if (weaponactive == 0) { @@ -2299,7 +2299,7 @@ void Person::DoAnimations() } } if (closestid != -1) - if (closestdist < 5 && !Person::players[closestid]->dead && animation[Person::players[closestid]->animTarget].height != lowheight && Person::players[closestid]->animTarget != backhandspringanim) { + if (closestdist < 5 && !Person::players[closestid]->dead && Animation::animations[Person::players[closestid]->animTarget].height != lowheight && Person::players[closestid]->animTarget != backhandspringanim) { hasvictim = 1; victim = Person::players[closestid]; coords = victim->coords; @@ -2329,9 +2329,9 @@ void Person::DoAnimations() if (hasvictim) { damagemult /= victim->damagetolerance / 200; } - if ((animation[animTarget].attack == normalattack || animTarget == walljumprightkickanim || animTarget == walljumpleftkickanim) && (!feint) && (victim->skeleton.free != 2 || animTarget == killanim || animTarget == dropkickanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == staffgroundsmashanim)) { - if (animTarget == spinkickanim && animation[animTarget].label[frameCurrent] == 5) { - if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) { + if ((Animation::animations[animTarget].attack == normalattack || animTarget == walljumprightkickanim || animTarget == walljumpleftkickanim) && (!feint) && (victim->skeleton.free != 2 || animTarget == killanim || animTarget == dropkickanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || animTarget == staffgroundsmashanim)) { + if (animTarget == spinkickanim && Animation::animations[animTarget].label[frameCurrent] == 5) { + if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && Animation::animations[victim->animTarget].height != lowheight) { escapednum = 0; if (id == 0) camerashake += .4; @@ -2366,8 +2366,8 @@ void Person::DoAnimations() } } - if (animTarget == wolfslapanim && animation[animTarget].label[frameCurrent] == 5) { - if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && animation[victim->animTarget].height != lowheight) { + if (animTarget == wolfslapanim && Animation::animations[animTarget].label[frameCurrent] == 5) { + if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && 3 && Animation::animations[victim->animTarget].height != lowheight) { escapednum = 0; if (id == 0) camerashake += .4; @@ -2399,8 +2399,8 @@ void Person::DoAnimations() } } - if (animTarget == walljumprightkickanim && animation[animTarget].label[frameCurrent] == 5) { - if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) { + if (animTarget == walljumprightkickanim && Animation::animations[animTarget].label[frameCurrent] == 5) { + if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != lowheight) { escapednum = 0; if (id == 0) camerashake += .4; @@ -2434,8 +2434,8 @@ void Person::DoAnimations() } } - if (animTarget == walljumpleftkickanim && animation[animTarget].label[frameCurrent] == 5) { - if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) { + if (animTarget == walljumpleftkickanim && Animation::animations[animTarget].label[frameCurrent] == 5) { + if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != lowheight) { escapednum = 0; if (id == 0) camerashake += .4; @@ -2469,8 +2469,8 @@ void Person::DoAnimations() } } - if (animTarget == blockhighleftstrikeanim && animation[animTarget].label[frameCurrent] == 5) { - if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != lowheight) { + if (animTarget == blockhighleftstrikeanim && Animation::animations[animTarget].label[frameCurrent] == 5) { + if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != lowheight) { escapednum = 0; if (id == 0) camerashake += .4; @@ -2493,7 +2493,7 @@ void Person::DoAnimations() } } - if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 8) { + if (animTarget == killanim && Animation::animations[animTarget].label[frameCurrent] == 8) { if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && victim->dead) { escapednum = 0; if (id == 0) @@ -2527,7 +2527,7 @@ void Person::DoAnimations() } } - if (animTarget == killanim && animation[animTarget].label[frameCurrent] == 5) { + if (animTarget == killanim && Animation::animations[animTarget].label[frameCurrent] == 5) { if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->dead) { escapednum = 0; if (id == 0) @@ -2552,7 +2552,7 @@ void Person::DoAnimations() } } - if (animTarget == dropkickanim && animation[animTarget].label[frameCurrent] == 7) { + if (animTarget == dropkickanim && Animation::animations[animTarget].label[frameCurrent] == 7) { if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 9 && victim->skeleton.free) { escapednum = 0; if (id == 0) @@ -2593,7 +2593,7 @@ void Person::DoAnimations() } } - if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 5) { + if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && Animation::animations[animTarget].label[frameCurrent] == 5) { if (hasvictim) if (!victim->skeleton.free) @@ -2682,7 +2682,7 @@ void Person::DoAnimations() } } - if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && animation[animTarget].label[frameCurrent] == 6) { + if ((animTarget == crouchstabanim || animTarget == swordgroundstabanim) && Animation::animations[animTarget].label[frameCurrent] == 6) { if (!hasvictim) { emit_sound_at(knifedrawsound, coords, 128); } @@ -2781,7 +2781,7 @@ void Person::DoAnimations() } } - if (animTarget == upunchanim && animation[animTarget].label[frameCurrent] == 5) { + if (animTarget == upunchanim && Animation::animations[animTarget].label[frameCurrent] == 5) { if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) { escapednum = 0; if (id == 0) @@ -2819,16 +2819,16 @@ void Person::DoAnimations() } - if (animTarget == winduppunchanim && animation[animTarget].label[frameCurrent] == 5) { + if (animTarget == winduppunchanim && Animation::animations[animTarget].label[frameCurrent] == 5) { if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 2) { escapednum = 0; if (id == 0) camerashake += .4; - if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height != lowheight) { + if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && Animation::animations[victim->animTarget].height != lowheight) { if (tutoriallevel != 1) { emit_sound_at(thudsound, victim->coords); } - } else if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && animation[victim->animTarget].height == lowheight) { + } else if (victim->damage <= victim->damagetolerance - 60 && normaldotproduct(victim->facing, victim->coords - coords) < (scale * 5) * (scale * 5) * 0 && Animation::animations[victim->animTarget].height == lowheight) { if (tutoriallevel != 1) { emit_sound_at(whooshhitsound, victim->coords); } @@ -2838,7 +2838,7 @@ void Person::DoAnimations() } } - if (victim->damage > victim->damagetolerance - 60 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || animation[victim->animTarget].height == lowheight) + if (victim->damage > victim->damagetolerance - 60 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || Animation::animations[victim->animTarget].height == lowheight) victim->RagDoll(0); XYZ relative; relative = victim->coords - coords; @@ -2864,7 +2864,7 @@ void Person::DoAnimations() } } - if (animTarget == blockhighleftanim && animation[animTarget].label[frameCurrent] == 5) { + if (animTarget == blockhighleftanim && Animation::animations[animTarget].label[frameCurrent] == 5) { if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) { if (victim->id == 0) camerashake += .4; @@ -2874,7 +2874,7 @@ void Person::DoAnimations() } } - if (animTarget == swordslashparryanim && animation[animTarget].label[frameCurrent] == 5) { + if (animTarget == swordslashparryanim && Animation::animations[animTarget].label[frameCurrent] == 5) { if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4) { if (victim->id == 0) camerashake += .4; @@ -2896,7 +2896,7 @@ void Person::DoAnimations() } } - if (animTarget == knifethrowanim && animation[animTarget].label[frameCurrent] == 5) { + if (animTarget == knifethrowanim && Animation::animations[animTarget].label[frameCurrent] == 5) { if (weaponactive != -1) { escapednum = 0; XYZ aim; @@ -2911,9 +2911,9 @@ void Person::DoAnimations() } } - if (animTarget == knifeslashstartanim && animation[animTarget].label[frameCurrent] == 5) { + if (animTarget == knifeslashstartanim && Animation::animations[animTarget].label[frameCurrent] == 5) { if (hasvictim) - if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4.5 &&/*animation[victim->animTarget].height!=lowheight&&*/victim->animTarget != dodgebackanim && victim->animTarget != rollanim) { + if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 4.5 &&/*Animation::animations[victim->animTarget].height!=lowheight&&*/victim->animTarget != dodgebackanim && victim->animTarget != rollanim) { escapednum = 0; if (tutoriallevel != 1) victim->DoBloodBig(1.5 / victim->armorhigh, 225); @@ -2923,7 +2923,7 @@ void Person::DoAnimations() emit_sound_at(knifeslicesound, victim->coords); } //victim->jointVel(abdomen)+=relative*damagemult*200; - if (animation[victim->animTarget].attack && (victim->aitype != playercontrolled || victim->animTarget == knifeslashstartanim) && (victim->creature == rabbittype || victim->deathbleeding <= 0)) { + if (Animation::animations[victim->animTarget].attack && (victim->aitype != playercontrolled || victim->animTarget == knifeslashstartanim) && (victim->creature == rabbittype || victim->deathbleeding <= 0)) { if (victim->id != 0 || difficulty == 2) { victim->frameTarget = 0; victim->animTarget = staggerbackhardanim; @@ -2965,7 +2965,7 @@ void Person::DoAnimations() victim->DoDamage(damagemult * 0); } } - if (animTarget == swordslashanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) { + if (animTarget == swordslashanim && Animation::animations[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) { if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim) { if (victim->weaponactive == -1 || normaldotproduct(victim->facing, victim->coords - coords) > 0 || (Random() % 2 == 0)) { award_bonus(id, Slashbonus); @@ -3053,7 +3053,7 @@ void Person::DoAnimations() } } - if (animTarget == staffhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) { + if (animTarget == staffhitanim && Animation::animations[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) { if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) { if (tutoriallevel != 1) { weapons[weaponids[0]].damage += .4 + float(abs(Random() % 100) - 50) / 250; @@ -3087,7 +3087,7 @@ void Person::DoAnimations() } } - if (animTarget == staffspinhitanim && animation[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) { + if (animTarget == staffspinhitanim && Animation::animations[animTarget].label[frameCurrent] == 5 && victim->animTarget != rollanim) { if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5 && victim->animTarget != dodgebackanim && victim->animTarget != sweepanim) { if (tutoriallevel != 1) { weapons[weaponids[0]].damage += .6 + float(abs(Random() % 100) - 50) / 250; @@ -3119,7 +3119,7 @@ void Person::DoAnimations() } } - if (animTarget == staffgroundsmashanim && animation[animTarget].label[frameCurrent] == 5) { + if (animTarget == staffgroundsmashanim && Animation::animations[animTarget].label[frameCurrent] == 5) { if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 6.5) { escapednum = 0; if (tutoriallevel != 1) { @@ -3169,8 +3169,8 @@ void Person::DoAnimations() } } - if (animTarget == lowkickanim && animation[animTarget].label[frameCurrent] == 5) { - if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && animation[victim->animTarget].height != highheight) { + if (animTarget == lowkickanim && Animation::animations[animTarget].label[frameCurrent] == 5) { + if (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3 && Animation::animations[victim->animTarget].height != highheight) { escapednum = 0; if (id == 0) camerashake += .4; @@ -3181,7 +3181,7 @@ void Person::DoAnimations() SolidHitBonus(id); - if (animation[victim->animTarget].height == lowheight) { + if (Animation::animations[victim->animTarget].height == lowheight) { if (Random() % 2) { victim->spurt = 1; DoBlood(.2, 250); @@ -3229,7 +3229,7 @@ void Person::DoAnimations() } } - if (animTarget == sweepanim && animation[animTarget].label[frameCurrent] == 5) { + if (animTarget == sweepanim && Animation::animations[animTarget].label[frameCurrent] == 5) { if ((victim->animTarget != jumpupanim) && (distsq(&coords, &victim->coords) < (scale * 5) * (scale * 5) * 3) && (victim != this->shared_from_this())) { @@ -3244,7 +3244,7 @@ void Person::DoAnimations() relative.y = 0; Normalise(&relative); - if (animation[victim->animTarget].height == middleheight || animation[victim->animCurrent].height == middleheight || victim->damage >= victim->damagetolerance - 40) { + if (Animation::animations[victim->animTarget].height == middleheight || Animation::animations[victim->animCurrent].height == middleheight || victim->damage >= victim->damagetolerance - 40) { victim->RagDoll(0); for (int i = 0; i < victim->skeleton.num_joints; i++) { @@ -3287,8 +3287,8 @@ void Person::DoAnimations() } } } - if (animation[animTarget].attack == reversal && (!victim->feint || (victim->lastattack == victim->lastattack2 && victim->lastattack2 == victim->lastattack3 && Random() % 2) || animTarget == knifefollowanim)) { - if (animTarget == spinkickreversalanim && animation[animTarget].label[frameCurrent] == 7) { + if (Animation::animations[animTarget].attack == reversal && (!victim->feint || (victim->lastattack == victim->lastattack2 && victim->lastattack2 == victim->lastattack3 && Random() % 2) || animTarget == knifefollowanim)) { + if (animTarget == spinkickreversalanim && Animation::animations[animTarget].label[frameCurrent] == 7) { escapednum = 0; if (id == 0) camerashake += .4; @@ -3319,7 +3319,7 @@ void Person::DoAnimations() award_bonus(id, Reversal); } - if ((animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim) && animation[animTarget].label[frameCurrent] == 5) { + if ((animTarget == swordslashreversalanim || animTarget == knifeslashreversalanim || animTarget == staffhitreversalanim || animTarget == staffspinhitreversalanim) && Animation::animations[animTarget].label[frameCurrent] == 5) { if (victim->weaponactive != -1 && victim->num_weapons > 0) { if (weapons[victim->weaponids[victim->weaponactive]].owner == int(victim->id)) { takeWeapon(victim->weaponids[victim->weaponactive]); @@ -3332,7 +3332,7 @@ void Person::DoAnimations() } } - if (animTarget == staffhitreversalanim && animation[animTarget].label[frameCurrent] == 5) { + if (animTarget == staffhitreversalanim && Animation::animations[animTarget].label[frameCurrent] == 5) { escapednum = 0; if (id == 0) camerashake += .4; @@ -3354,7 +3354,7 @@ void Person::DoAnimations() victim->DoDamage(damagemult * 70 / victim->protectionhigh); } - if (animTarget == staffspinhitreversalanim && animation[animTarget].label[frameCurrent] == 7) { + if (animTarget == staffspinhitreversalanim && Animation::animations[animTarget].label[frameCurrent] == 7) { escapednum = 0; if (id == 0) camerashake += .4; @@ -3383,7 +3383,7 @@ void Person::DoAnimations() victim->DoDamage(damagemult * 70 / victim->protectionhigh); } - if (animTarget == upunchreversalanim && animation[animTarget].label[frameCurrent] == 7) { + if (animTarget == upunchreversalanim && Animation::animations[animTarget].label[frameCurrent] == 7) { escapednum = 0; victim->RagDoll(1); XYZ relative; @@ -3433,7 +3433,7 @@ void Person::DoAnimations() - if (animTarget == swordslashreversalanim && animation[animTarget].label[frameCurrent] == 7) { + if (animTarget == swordslashreversalanim && Animation::animations[animTarget].label[frameCurrent] == 7) { escapednum = 0; victim->RagDoll(1); XYZ relative; @@ -3456,7 +3456,7 @@ void Person::DoAnimations() award_bonus(id, swordreversebonus); } - if (hasvictim && animTarget == knifeslashreversalanim && animation[animTarget].label[frameCurrent] == 7) { + if (hasvictim && animTarget == knifeslashreversalanim && Animation::animations[animTarget].label[frameCurrent] == 7) { escapednum = 0; if (id == 0) camerashake += .4; @@ -3483,7 +3483,7 @@ void Person::DoAnimations() award_bonus(id, Reversal); } - if (hasvictim && animTarget == sneakattackanim && animation[animTarget].label[frameCurrent] == 7) { + if (hasvictim && animTarget == sneakattackanim && Animation::animations[animTarget].label[frameCurrent] == 7) { escapednum = 0; victim->RagDoll(0); victim->skeleton.spinny = 0; @@ -3523,7 +3523,7 @@ void Person::DoAnimations() award_bonus(id, spinecrusher); } - if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 5) { + if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && Animation::animations[animTarget].label[frameCurrent] == 5) { if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) { escapednum = 0; if (animTarget == knifefollowanim) @@ -3565,7 +3565,7 @@ void Person::DoAnimations() } } - if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && animation[animTarget].label[frameCurrent] == 6) { + if (hasvictim && (animTarget == knifefollowanim || animTarget == knifesneakattackanim) && Animation::animations[animTarget].label[frameCurrent] == 6) { escapednum = 0; victim->velocity = 0; for (int i = 0; i < victim->skeleton.num_joints; i++) { @@ -3577,7 +3577,7 @@ void Person::DoAnimations() victim->skeleton.joints[i].velocity = 0; } } - if (weaponactive != -1 && animation[victim->animTarget].attack != reversal) { + if (weaponactive != -1 && Animation::animations[victim->animTarget].attack != reversal) { emit_sound_at(fleshstabremovesound, victim->coords); if (bloodtoggle) weapons[weaponids[weaponactive]].bloody = 2; @@ -3596,7 +3596,7 @@ void Person::DoAnimations() } } - if (hasvictim && (animTarget == swordsneakattackanim) && animation[animTarget].label[frameCurrent] == 5) { + if (hasvictim && (animTarget == swordsneakattackanim) && Animation::animations[animTarget].label[frameCurrent] == 5) { if (weaponactive != -1 && victim->bloodloss < victim->damagetolerance) { award_bonus(id, backstab); @@ -3623,7 +3623,7 @@ void Person::DoAnimations() } } - if (hasvictim && animTarget == swordsneakattackanim && animation[animTarget].label[frameCurrent] == 6) { + if (hasvictim && animTarget == swordsneakattackanim && Animation::animations[animTarget].label[frameCurrent] == 6) { escapednum = 0; victim->velocity = 0; for (int i = 0; i < victim->skeleton.num_joints; i++) { @@ -3648,7 +3648,7 @@ void Person::DoAnimations() } } - if (animTarget == sweepreversalanim && animation[animTarget].label[frameCurrent] == 7) { + if (animTarget == sweepreversalanim && Animation::animations[animTarget].label[frameCurrent] == 7) { escapednum = 0; if (id == 0) camerashake += .4; @@ -3704,7 +3704,7 @@ void Person::DoAnimations() victim->velocity = 0; } - if (animTarget == sweepreversalanim && ((animation[animTarget].label[frameCurrent] == 9 && victim->damage < victim->damagetolerance) || (animation[animTarget].label[frameCurrent] == 7 && victim->damage > victim->damagetolerance))) { + if (animTarget == sweepreversalanim && ((Animation::animations[animTarget].label[frameCurrent] == 9 && victim->damage < victim->damagetolerance) || (Animation::animations[animTarget].label[frameCurrent] == 7 && victim->damage > victim->damagetolerance))) { escapednum = 0; victim->RagDoll(0); XYZ relative; @@ -3728,7 +3728,7 @@ void Person::DoAnimations() //Animation end - if (frameTarget > animation[animCurrent].numframes - 1) { + if (frameTarget > Animation::animations[animCurrent].numframes - 1) { frameTarget = 0; if (wasStop()) { animTarget = getIdle(); @@ -3951,7 +3951,7 @@ void Person::DoAnimations() animTarget = getIdle(); lastfeint = 0; } - if (animation[animTarget].attack == reversal && animCurrent != sneakattackanim && animCurrent != knifesneakattackanim && animCurrent != swordsneakattackanim && animCurrent != knifefollowanim) { + if (Animation::animations[animTarget].attack == reversal && animCurrent != sneakattackanim && animCurrent != knifesneakattackanim && animCurrent != swordsneakattackanim && animCurrent != knifefollowanim) { float ycoords = oldcoords.y; animTarget = getStop(); targetyaw += 180; @@ -4002,7 +4002,7 @@ void Person::DoAnimations() velocity.y = -5; RagDoll(0); } - if (animation[animTarget].attack == reversed) { + if (Animation::animations[animTarget].attack == reversed) { escapednum++; if (animTarget == sweepreversedanim) targetyaw += 90; @@ -4039,11 +4039,11 @@ void Person::DoAnimations() oldcoords = coords; coords += (DoRotation(jointPos(leftfoot), 0, yaw, 0) + DoRotation(jointPos(rightfoot), 0, yaw, 0)) / 2 * scale; coords.y = oldcoords.y; - //coords+=DoRotation(animation[animCurrent].offset,0,yaw,0)*scale; + //coords+=DoRotation(Animation::animations[animCurrent].offset,0,yaw,0)*scale; targetoffset.y = coords.y; if (onterrain) targetoffset.y = terrain.getHeight(coords.x, coords.z); - currentoffset = DoRotation(animation[animCurrent].offset * -1, 0, yaw, 0) * scale; + currentoffset = DoRotation(Animation::animations[animCurrent].offset * -1, 0, yaw, 0) * scale; currentoffset.y -= (coords.y - targetoffset.y); coords.y = targetoffset.y; targetoffset = 0; @@ -4110,10 +4110,10 @@ void Person::DoAnimations() lastfeint = 0; } - if (animation[animCurrent].attack == normalattack && !victim->skeleton.free && victim->animTarget != staggerbackhighanim && victim->animTarget != staggerbackhardanim && animTarget != winduppunchblockedanim && animTarget != blockhighleftanim && animTarget != swordslashparryanim && animTarget != swordslashparriedanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim) { + if (Animation::animations[animCurrent].attack == normalattack && !victim->skeleton.free && victim->animTarget != staggerbackhighanim && victim->animTarget != staggerbackhardanim && animTarget != winduppunchblockedanim && animTarget != blockhighleftanim && animTarget != swordslashparryanim && animTarget != swordslashparriedanim && animTarget != crouchstabanim && animTarget != swordgroundstabanim) { animTarget = getupfromfrontanim; lastfeint = 0; - } else if (animation[animCurrent].attack == normalattack) { + } else if (Animation::animations[animCurrent].attack == normalattack) { animTarget = getIdle(); lastfeint = 0; } @@ -4140,28 +4140,28 @@ void Person::DoAnimations() } if (!skeleton.free) { oldtarget = target; - if (!transspeed && animation[animTarget].attack != 2 && animation[animTarget].attack != 3) { + if (!transspeed && Animation::animations[animTarget].attack != 2 && Animation::animations[animTarget].attack != 3) { if (!isRun() || !wasRun()) { - if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent]) - target += multiplier * animation[animTarget].speed[frameTarget] * speed * 2; - if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent]) - target += multiplier * animation[animCurrent].speed[frameCurrent] * speed * 2; + if (Animation::animations[animTarget].speed[frameTarget] > Animation::animations[animCurrent].speed[frameCurrent]) + target += multiplier * Animation::animations[animTarget].speed[frameTarget] * speed * 2; + if (Animation::animations[animTarget].speed[frameTarget] <= Animation::animations[animCurrent].speed[frameCurrent]) + target += multiplier * Animation::animations[animCurrent].speed[frameCurrent] * speed * 2; } if (isRun() && wasRun()) { float tempspeed; tempspeed = velspeed; if (tempspeed < 10 * speedmult) tempspeed = 10 * speedmult; - target += multiplier * animation[animTarget].speed[frameCurrent] * speed * 1.7 * tempspeed / (speed * 45 * scale); + target += multiplier * Animation::animations[animTarget].speed[frameCurrent] * speed * 1.7 * tempspeed / (speed * 45 * scale); } } else if (transspeed) target += multiplier * transspeed * speed * 2; else { if (!isRun() || !wasRun()) { - if (animation[animTarget].speed[frameTarget] > animation[animCurrent].speed[frameCurrent]) - target += multiplier * animation[animTarget].speed[frameTarget] * 2; - if (animation[animTarget].speed[frameTarget] <= animation[animCurrent].speed[frameCurrent]) - target += multiplier * animation[animCurrent].speed[frameCurrent] * 2; + if (Animation::animations[animTarget].speed[frameTarget] > Animation::animations[animCurrent].speed[frameCurrent]) + target += multiplier * Animation::animations[animTarget].speed[frameTarget] * 2; + if (Animation::animations[animTarget].speed[frameTarget] <= Animation::animations[animCurrent].speed[frameCurrent]) + target += multiplier * Animation::animations[animCurrent].speed[frameCurrent] * 2; } } @@ -4183,7 +4183,7 @@ void Person::DoAnimations() if (animCurrent != oldanimCurrent || animTarget != oldanimTarget || ((frameCurrent != oldframeCurrent || frameTarget != oldframeTarget) && !calcrot)) { //Old rotates for (int i = 0; i < skeleton.num_joints; i++) { - skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent]; + skeleton.joints[i].position = Animation::animations[animCurrent].position[i][frameCurrent]; } skeleton.FindForwards(); @@ -4206,7 +4206,7 @@ void Person::DoAnimations() //New rotates for (int i = 0; i < skeleton.num_joints; i++) { - skeleton.joints[i].position = animation[animTarget].position[i][frameTarget]; + skeleton.joints[i].position = Animation::animations[animTarget].position[i][frameTarget]; } skeleton.FindForwards(); @@ -4233,8 +4233,8 @@ void Person::DoAnimations() } } } - if (frameCurrent >= animation[animCurrent].numframes) - frameCurrent = animation[animCurrent].numframes - 1; + if (frameCurrent >= Animation::animations[animCurrent].numframes) + frameCurrent = Animation::animations[animCurrent].numframes - 1; oldanimCurrent = animCurrent; oldanimTarget = animTarget; @@ -4242,8 +4242,8 @@ void Person::DoAnimations() oldframeCurrent = frameCurrent; for (int i = 0; i < skeleton.num_joints; i++) { - skeleton.joints[i].velocity = (animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target) - skeleton.joints[i].position) / multiplier; - skeleton.joints[i].position = animation[animCurrent].position[i][frameCurrent] * (1 - target) + animation[animTarget].position[i][frameTarget] * (target); + skeleton.joints[i].velocity = (Animation::animations[animCurrent].position[i][frameCurrent] * (1 - target) + Animation::animations[animTarget].position[i][frameTarget] * (target) - skeleton.joints[i].position) / multiplier; + skeleton.joints[i].position = Animation::animations[animCurrent].position[i][frameCurrent] * (1 - target) + Animation::animations[animTarget].position[i][frameTarget] * (target); } offset = currentoffset * (1 - target) + targetoffset * target; for (int i = 0; i < skeleton.num_muscles; i++) { @@ -4458,7 +4458,7 @@ void Person::DoStuff() deathbleeding -= multiplier * 1.6; if (deathbleeding < 0) deathbleeding = 0; - if (bloodloss > damagetolerance && animation[animTarget].attack == neutral) { + if (bloodloss > damagetolerance && Animation::animations[animTarget].attack == neutral) { if (weaponactive != -1) { weapons[weaponids[0]].drop(velocity * scale * -.3, velocity * scale); weapons[weaponids[0]].velocity.x += .01; @@ -5592,7 +5592,7 @@ void Person::DoStuff() terrainnormal = terrain.getNormal(coords.x, coords.z); - if (animation[animTarget].attack != reversal) { + if (Animation::animations[animTarget].attack != reversal) { if (!isnormal(coords.x)) coords = oldcoords; oldcoords = coords; @@ -5613,7 +5613,7 @@ void Person::DoStuff() targettilt2 = 0; } onterrain = 0; - if (!isRun() && !animation[animTarget].attack && animTarget != getupfromfrontanim && animTarget != getupfrombackanim && animTarget != sneakanim) + if (!isRun() && !Animation::animations[animTarget].attack && animTarget != getupfromfrontanim && animTarget != getupfrombackanim && animTarget != sneakanim) targettilt2 = 0; if (animTarget == jumpupanim || animTarget == jumpdownanim || isFlip()) { flatvelocity = velocity; @@ -5642,7 +5642,7 @@ void Person::DoStuff() } else if (tilt2 < targettilt2) { tilt2 += multiplier * 400; } - if (!animation[animTarget].attack && animTarget != getupfrombackanim && animTarget != getupfromfrontanim) { + if (!Animation::animations[animTarget].attack && animTarget != getupfrombackanim && animTarget != getupfromfrontanim) { if (tilt2 > 25) tilt2 = 25; if (tilt2 < -25) @@ -5709,7 +5709,7 @@ void Person::DoStuff() velocity = flatfacing * velspeed; } - if (animTarget == rollanim && animation[animTarget].label[frameTarget] != 6) { + if (animTarget == rollanim && Animation::animations[animTarget].label[frameTarget] != 6) { velocity += facing * multiplier * speed * 700 * scale; velspeed = findLength(&velocity); if (velspeed > speed * 45 * scale) { @@ -5784,7 +5784,7 @@ void Person::DoStuff() coords -= facing * multiplier * speed * 16 * scale; velocity = 0; } - if (animTarget == staggerbackhardanim && animation[staggerbackhardanim].label[frameTarget] != 6) { + if (animTarget == staggerbackhardanim && Animation::animations[staggerbackhardanim].label[frameTarget] != 6) { coords -= facing * multiplier * speed * 20 * scale; velocity = 0; } @@ -5831,7 +5831,7 @@ void Person::DoStuff() coords += velocity * multiplier; if (coords.y < terrain.getHeight(coords.x, coords.z) && (animTarget == jumpdownanim || animTarget == jumpupanim || isFlip())) { - if (isFlip() && animation[animTarget].label[frameTarget] == 7) + if (isFlip() && Animation::animations[animTarget].label[frameTarget] == 7) RagDoll(0); if (animTarget == jumpupanim) { @@ -5866,7 +5866,7 @@ void Person::DoStuff() } - if (isIdle() || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || isStop() || animTarget == removeknifeanim || animTarget == crouchremoveknifeanim || isLanding() || isCrouch() || animation[animTarget].attack || (animTarget == rollanim && animation[animTarget].label[frameTarget] == 6)) { + if (isIdle() || animTarget == drawrightanim || animTarget == drawleftanim || animTarget == crouchdrawrightanim || animTarget == crouchstabanim || animTarget == swordgroundstabanim || isStop() || animTarget == removeknifeanim || animTarget == crouchremoveknifeanim || isLanding() || isCrouch() || Animation::animations[animTarget].attack || (animTarget == rollanim && Animation::animations[animTarget].label[frameTarget] == 6)) { velspeed = findLength(&velocity); velocity.y = 0; if (velspeed < multiplier * 300 * scale) { @@ -5914,7 +5914,7 @@ void Person::DoStuff() } } - if (animation[animTarget].attack == normalattack && animTarget != rabbitkickanim && !victim->skeleton.free) { + if (Animation::animations[animTarget].attack == normalattack && animTarget != rabbitkickanim && !victim->skeleton.free) { terrainnormal = victim->coords - coords; Normalise(&terrainnormal); targetyaw = -asin(0 - terrainnormal.x); @@ -5924,7 +5924,7 @@ void Person::DoStuff() targettilt2 = -asin(terrainnormal.y) * 360 / 6.28; //*-70; } - if (animation[animTarget].attack == reversal && animTarget != rabbittacklinganim) { + if (Animation::animations[animTarget].attack == reversal && animTarget != rabbittacklinganim) { targetyaw = victim->targetyaw; } if (animTarget == rabbittacklinganim) { @@ -6079,12 +6079,12 @@ int Person::DrawSkeleton() } } - if (!skeleton.free && (!animation[animTarget].attack && animTarget != getupfrombackanim && ((animTarget != rollanim && !isFlip()) || animation[animTarget].label[frameTarget] == 6) && animTarget != getupfromfrontanim && animTarget != wolfrunninganim && animTarget != rabbitrunninganim && animTarget != backhandspringanim && animTarget != walljumpfrontanim && animTarget != hurtidleanim && !isLandhard() && !isSleeping())) + if (!skeleton.free && (!Animation::animations[animTarget].attack && animTarget != getupfrombackanim && ((animTarget != rollanim && !isFlip()) || Animation::animations[animTarget].label[frameTarget] == 6) && animTarget != getupfromfrontanim && animTarget != wolfrunninganim && animTarget != rabbitrunninganim && animTarget != backhandspringanim && animTarget != walljumpfrontanim && animTarget != hurtidleanim && !isLandhard() && !isSleeping())) DoHead(); else { targetheadyaw = -targetyaw; targetheadpitch = 0; - if (animation[animTarget].attack == 3) + if (Animation::animations[animTarget].attack == 3) targetheadyaw += 180; } for (i = 0; i < skeleton.drawmodel.vertexNum; i++) { @@ -6363,7 +6363,7 @@ int Person::DrawSkeleton() glEnable(GL_LIGHTING); glEnable(GL_BLEND); if (canattack && cananger) - if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) { + if (Animation::animations[animTarget].attack == normalattack || Animation::animations[animTarget].attack == reversed) { glDisable(GL_TEXTURE_2D); glColor4f(1, 0, 0, 0.8); } @@ -6387,7 +6387,7 @@ int Person::DrawSkeleton() skeleton.drawmodellow.drawdifftex(skeleton.drawmodel.textureptr); } - if (!(animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed)) + if (!(Animation::animations[animTarget].attack == normalattack || Animation::animations[animTarget].attack == reversed)) if (tutoriallevel && id != 0) { glPopMatrix(); glMatrixMode(GL_MODELVIEW); @@ -6397,7 +6397,7 @@ int Person::DrawSkeleton() glEnable(GL_LIGHTING); glEnable(GL_BLEND); if (canattack && cananger) - if (animation[animTarget].attack == normalattack || animation[animTarget].attack == reversed) { + if (Animation::animations[animTarget].attack == normalattack || Animation::animations[animTarget].attack == reversed) { glDisable(GL_TEXTURE_2D); glColor4f(1, 0, 0, 0.8); } @@ -6534,7 +6534,7 @@ int Person::DrawSkeleton() float distance; temppoint1 = jointPos(righthand); - temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target); + temppoint2 = Animation::animations[animCurrent].weapontarget[frameCurrent] * (1 - target) + Animation::animations[animTarget].weapontarget[frameTarget] * (target); distance = findDistance(&temppoint1, &temppoint2); weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance); weapons[i].rotation2 *= 360 / 6.28; @@ -6553,7 +6553,7 @@ int Person::DrawSkeleton() float distance; temppoint1 = jointPos(righthand); - temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target); + temppoint2 = Animation::animations[animCurrent].weapontarget[frameCurrent] * (1 - target) + Animation::animations[animTarget].weapontarget[frameTarget] * (target); distance = findDistance(&temppoint1, &temppoint2); weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance); weapons[i].rotation2 *= 360 / 6.28; @@ -6596,8 +6596,8 @@ int Person::DrawSkeleton() XYZ temppoint1, temppoint2; float distance; - temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand); - temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target); + temppoint1 = Animation::animations[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + Animation::animations[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand); + temppoint2 = Animation::animations[animCurrent].weapontarget[frameCurrent] * (1 - target) + Animation::animations[animTarget].weapontarget[frameTarget] * (target); distance = findDistance(&temppoint1, &temppoint2); weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance); weapons[i].rotation2 *= 360 / 6.28; @@ -6619,8 +6619,8 @@ int Person::DrawSkeleton() XYZ temppoint1, temppoint2; float distance; - temppoint1 = animation[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + animation[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand); - temppoint2 = animation[animCurrent].weapontarget[frameCurrent] * (1 - target) + animation[animTarget].weapontarget[frameTarget] * (target); + temppoint1 = Animation::animations[animCurrent].position[skeleton.jointlabels[righthand]][frameCurrent] * (1 - target) + Animation::animations[animTarget].position[skeleton.jointlabels[righthand]][frameTarget] * (target); //jointPos(righthand); + temppoint2 = Animation::animations[animCurrent].weapontarget[frameCurrent] * (1 - target) + Animation::animations[animTarget].weapontarget[frameTarget] * (target); distance = findDistance(&temppoint1, &temppoint2); weapons[i].rotation2 = asin((temppoint1.y - temppoint2.y) / distance); weapons[i].rotation2 *= 360 / 6.28; @@ -6664,7 +6664,7 @@ int Person::DrawSkeleton() calcrot = 0; if (skeleton.free) calcrot = 1; - if (animation[animTarget].attack || isRun() || animTarget == staggerbackhardanim || isFlip() || animTarget == climbanim || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim || animTarget == backhandspringanim || isWallJump()) + if (Animation::animations[animTarget].attack || isRun() || animTarget == staggerbackhardanim || isFlip() || animTarget == climbanim || animTarget == sneakanim || animTarget == rollanim || animTarget == walkanim || animTarget == backhandspringanim || isWallJump()) calcrot = 1; if (animCurrent != animTarget) calcrot = 1; @@ -6726,7 +6726,7 @@ int Person::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate, if (LineFacetd(&start, &end, &model->vertex[model->Triangles[j].vertex[0]], &model->vertex[model->Triangles[j].vertex[1]], &model->vertex[model->Triangles[j].vertex[2]], &model->facenormals[j], &point)) { p1->y = point.y + radius; if ((animTarget == jumpdownanim || isFlip())) { - if (isFlip() && (frameTarget < 5 || animation[animTarget].label[frameTarget] == 7 || animation[animTarget].label[frameTarget] == 4)) + if (isFlip() && (frameTarget < 5 || Animation::animations[animTarget].label[frameTarget] == 7 || Animation::animations[animTarget].label[frameTarget] == 4)) RagDoll(0); if (animTarget == jumpupanim) { diff --git a/Source/Person.h b/Source/Person.h index 4e0edae..21768a4 100644 --- a/Source/Person.h +++ b/Source/Person.h @@ -25,14 +25,14 @@ along with Lugaru. If not, see . #include "gamegl.h" #include "Quaternions.h" -#include "Skeleton.h" +#include "Animation/Skeleton.h" #include "Models.h" #include "Terrain.h" #include "Sprite.h" #include #include #include "Weapons.h" -#include "Animation.h" +#include "Animation/Animation.h" #define passivetype 0 #define guardtype 1 diff --git a/Source/Skeleton.cpp b/Source/Skeleton.cpp deleted file mode 100644 index 5a0e274..0000000 --- a/Source/Skeleton.cpp +++ /dev/null @@ -1,1709 +0,0 @@ -/* -Copyright (C) 2003, 2010 - Wolfire Games -Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file) - -This file is part of Lugaru. - -Lugaru is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -Lugaru is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Lugaru. If not, see . -*/ - -/**> HEADER FILES <**/ -#include "Game.h" -#include "Skeleton.h" -#include "openal_wrapper.h" -#include "Animation.h" -#include "Utils/Folders.h" - -extern float multiplier; -extern float gravity; -extern Terrain terrain; -extern Objects objects; -extern int environment; -extern float camerashake; -extern bool freeze; -extern int detail; -extern int tutoriallevel; - -extern int whichjointstartarray[26]; -extern int whichjointendarray[26]; - -extern bool visibleloading; - -/* EFFECT - */ -void dealloc2(void* param) -{ - free(param); -} - -enum {boneconnect, constraint, muscle}; - - -/* EFFECT - * sets strength, length, - * parent1->position, parent2->position, - * parent1->velocity, parent2->velocity - * used for ragdolls? - * - * USES: - * Skeleton::DoConstraints - */ -void Muscle::DoConstraint(bool spinny) -{ - // FIXME: relaxlength shouldn't be static, but may not always be set - // so I don't want to change the existing behavior even though it's probably a bug - static float relaxlength; - - float oldlength = length; - - if (type != boneconnect) - relaxlength = findDistance(&parent1->position, &parent2->position); - - if (type == boneconnect) - strength = 1; - if (type == constraint) - strength = 0; - - // clamp strength - if (strength < 0) - strength = 0; - if (strength > 1) - strength = 1; - - length -= (length - relaxlength) * (1 - strength) * multiplier * 10000; - length -= (length - targetlength) * (strength) * multiplier * 10000; - if (strength == 0) - length = relaxlength; - - if ((relaxlength - length > 0 && relaxlength - oldlength < 0) || (relaxlength - length < 0 && relaxlength - oldlength > 0)) - length = relaxlength; - - // clamp length - if (length < minlength) - length = minlength; - if (length > maxlength) - length = maxlength; - - if (length == relaxlength) - return; - - // relax muscle? - - //Find midpoint - XYZ midp = (parent1->position * parent1->mass + parent2->position * parent2->mass) / (parent1->mass + parent2->mass); - - //Find vector from midpoint to second vector - XYZ vel = parent2->position - midp; - - //Change to unit vector - Normalise(&vel); - - //Apply velocity change - XYZ newpoint1 = midp - vel * length * (parent2->mass / (parent1->mass + parent2->mass)); - XYZ newpoint2 = midp + vel * length * (parent1->mass / (parent1->mass + parent2->mass)); - if (!freeze && spinny) { - parent1->velocity = parent1->velocity + (newpoint1 - parent1->position) / multiplier / 4; - parent2->velocity = parent2->velocity + (newpoint2 - parent2->position) / multiplier / 4; - } else { - parent1->velocity = parent1->velocity + (newpoint1 - parent1->position); - parent2->velocity = parent2->velocity + (newpoint2 - parent2->position); - } - - //Move child point to within certain distance of parent point - parent1->position = newpoint1; - parent2->position = newpoint2; -} - -/* EFFECT - * sets forward, lowforward, specialforward[] - * - * USES: - * Skeleton::Load - * Person/Person::DoAnimations - * Person/Person::DrawSkeleton - */ -void Skeleton::FindForwards() -{ - //Find forward vectors - CrossProduct(joints[forwardjoints[1]].position - joints[forwardjoints[0]].position, joints[forwardjoints[2]].position - joints[forwardjoints[0]].position, &forward); - Normalise(&forward); - - CrossProduct(joints[lowforwardjoints[1]].position - joints[lowforwardjoints[0]].position, joints[lowforwardjoints[2]].position - joints[lowforwardjoints[0]].position, &lowforward); - Normalise(&lowforward); - - //Special forwards - specialforward[0] = forward; - - specialforward[1] = jointPos(rightshoulder) + jointPos(rightwrist); - specialforward[1] = jointPos(rightelbow) - specialforward[1] / 2; - specialforward[1] += forward * .4; - Normalise(&specialforward[1]); - specialforward[2] = jointPos(leftshoulder) + jointPos(leftwrist); - specialforward[2] = jointPos(leftelbow) - specialforward[2] / 2; - specialforward[2] += forward * .4; - Normalise(&specialforward[2]); - - specialforward[3] = jointPos(righthip) + jointPos(rightankle); - specialforward[3] = specialforward[3] / 2 - jointPos(rightknee); - specialforward[3] += lowforward * .4; - Normalise(&specialforward[3]); - specialforward[4] = jointPos(lefthip) + jointPos(leftankle); - specialforward[4] = specialforward[4] / 2 - jointPos(leftknee); - specialforward[4] += lowforward * .4; - Normalise(&specialforward[4]); -} - -/* EFFECT - * TODO - * - * USES: - * Person/Person::RagDoll - * Person/Person::DoStuff - * Person/IKHelper - */ -float Skeleton::DoConstraints(XYZ *coords, float *scale) -{ - float friction = 1.5; - const float elasticity = .3; - XYZ bounceness; - const int numrepeats = 3; - float groundlevel = .15; - int i, j, k, m; - XYZ temp; - XYZ terrainnormal; - int whichhit; - float frictionness; - XYZ terrainlight; - int whichpatchx; - int whichpatchz; - float damage = 0; // eventually returned from function - bool breaking = false; - - if (free) { - freetime += multiplier; - - whichpatchx = coords->x / (terrain.size / subdivision * terrain.scale); - whichpatchz = coords->z / (terrain.size / subdivision * terrain.scale); - - terrainlight = *coords; - objects.SphereCheckPossible(&terrainlight, 1); - - //Add velocity - for (i = 0; i < num_joints; i++) { - joints[i].position = joints[i].position + joints[i].velocity * multiplier; - - switch (joints[i].label) { - case head: - groundlevel = .8; - break; - case righthand: - case rightwrist: - case rightelbow: - case lefthand: - case leftwrist: - case leftelbow: - groundlevel = .2; - break; - default: - groundlevel = .15; - break; - } - - joints[i].position.y -= groundlevel; - joints[i].oldvelocity = joints[i].velocity; - } - - float tempmult = multiplier; - //multiplier/=numrepeats; - - for (j = 0; j < numrepeats; j++) { - float r = .05; - // right leg constraints? - if (!joint(rightknee).locked && !joint(righthip).locked) { - temp = jointPos(rightknee) - (jointPos(righthip) + jointPos(rightankle)) / 2; - while (normaldotproduct(temp, lowforward) > -.1 && !sphere_line_intersection(&jointPos(righthip), &jointPos(rightankle), &jointPos(rightknee), &r)) { - jointPos(rightknee) -= lowforward * .05; - if (spinny) - jointVel(rightknee) -= lowforward * .05 / multiplier / 4; - else - jointVel(rightknee) -= lowforward * .05; - jointPos(rightankle) += lowforward * .025; - if (spinny) - jointVel(rightankle) += lowforward * .025 / multiplier / 4; - else - jointVel(rightankle) += lowforward * .25; - jointPos(righthip) += lowforward * .025; - if (spinny) - jointVel(righthip) += lowforward * .025 / multiplier / 4; - else - jointVel(righthip) += lowforward * .025; - temp = jointPos(rightknee) - (jointPos(righthip) + jointPos(rightankle)) / 2; - } - } - - // left leg constraints? - if (!joint(leftknee).locked && !joint(lefthip).locked) { - temp = jointPos(leftknee) - (jointPos(lefthip) + jointPos(leftankle)) / 2; - while (normaldotproduct(temp, lowforward) > -.1 && !sphere_line_intersection(&jointPos(lefthip), &jointPos(leftankle), &jointPos(leftknee), &r)) { - jointPos(leftknee) -= lowforward * .05; - if (spinny) - jointVel(leftknee) -= lowforward * .05 / multiplier / 4; - else - jointVel(leftknee) -= lowforward * .05; - jointPos(leftankle) += lowforward * .025; - if (spinny) - jointVel(leftankle) += lowforward * .025 / multiplier / 4; - else - jointVel(leftankle) += lowforward * .25; - jointPos(lefthip) += lowforward * .025; - if (spinny) - jointVel(lefthip) += lowforward * .025 / multiplier / 4; - else - jointVel(lefthip) += lowforward * .025; - temp = jointPos(leftknee) - (jointPos(lefthip) + jointPos(leftankle)) / 2; - } - } - - for (i = 0; i < num_joints; i++) { - if (joints[i].locked && !spinny && findLengthfast(&joints[i].velocity) > 320) - joints[i].locked = 0; - if (spinny && findLengthfast(&joints[i].velocity) > 600) - joints[i].locked = 0; - if (joints[i].delay > 0) { - bool freely = true; - for (j = 0; j < num_joints; j++) { - if (joints[j].locked) - freely = false; - } - if (freely) - joints[i].delay -= multiplier * 3; - } - } - - if (num_muscles) - for (i = 0; i < num_muscles; i++) { - //Length constraints - muscles[i].DoConstraint(spinny); - } - - for (i = 0; i < num_joints; i++) { - //Length constraints - //Ground constraint - groundlevel = 0; - if (joints[i].position.y * (*scale) + coords->y < terrain.getHeight(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) + groundlevel) { - freefall = 0; - friction = 1.5; - if (joints[i].label == groin && !joints[i].locked && joints[i].delay <= 0) { - joints[i].locked = 1; - joints[i].delay = 1; - if (tutoriallevel != 1 || id == 0) { - emit_sound_at(landsound1, joints[i].position * (*scale) + *coords, 128.); - } - breaking = true; - } - - if (joints[i].label == head && !joints[i].locked && joints[i].delay <= 0) { - joints[i].locked = 1; - joints[i].delay = 1; - if (tutoriallevel != 1 || id == 0) { - emit_sound_at(landsound2, joints[i].position * (*scale) + *coords, 128.); - } - } - - terrainnormal = terrain.getNormal(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z); - ReflectVector(&joints[i].velocity, &terrainnormal); - bounceness = terrainnormal * findLength(&joints[i].velocity) * (abs(normaldotproduct(joints[i].velocity, terrainnormal))); - if (!joints[i].locked) - damage += findLengthfast(&bounceness) / 4000; - if (findLengthfast(&joints[i].velocity) < findLengthfast(&bounceness)) - bounceness = 0; - frictionness = abs(normaldotproduct(joints[i].velocity, terrainnormal)); - joints[i].velocity -= bounceness; - if (1 - friction * frictionness > 0) - joints[i].velocity *= 1 - friction * frictionness; - else - joints[i].velocity = 0; - - if (tutoriallevel != 1 || id == 0) - if (findLengthfast(&bounceness) > 8000 && breaking) { - // FIXME: this crashes because k is not initialized! - // to reproduce, type 'wolfie' in console and play a while - // I'll just comment it out for now - //objects.model[k].MakeDecal(breakdecal, DoRotation(temp - objects.position[k], 0, -objects.yaw[k], 0), .4, .5, Random() % 360); - Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, 4, .2); - breaking = false; - camerashake += .6; - - emit_sound_at(breaksound2, joints[i].position * (*scale) + *coords); - - addEnvSound(*coords, 64); - } - - if (findLengthfast(&bounceness) > 2500) { - Normalise(&bounceness); - bounceness = bounceness * 50; - } - - joints[i].velocity += bounceness * elasticity; - - if (findLengthfast(&joints[i].velocity) > findLengthfast(&joints[i].oldvelocity)) { - bounceness = 0; - joints[i].velocity = joints[i].oldvelocity; - } - - - if (joints[i].locked == 0) - if (findLengthfast(&joints[i].velocity) < 1) - joints[i].locked = 1; - - if (environment == snowyenvironment && findLengthfast(&bounceness) > 500 && terrain.getOpacity(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) < .2) { - terrainlight = terrain.getLighting(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z); - Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7); - if (detail == 2) - terrain.MakeDecal(bodyprintdecal, joints[i].position * (*scale) + *coords, .4, .4, 0); - } else if (environment == desertenvironment && findLengthfast(&bounceness) > 500 && terrain.getOpacity(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) < .2) { - terrainlight = terrain.getLighting(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z); - Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7); - } - - else if (environment == grassyenvironment && findLengthfast(&bounceness) > 500 && terrain.getOpacity(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) < .2) { - terrainlight = terrain.getLighting(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z); - Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5); - } else if (findLengthfast(&bounceness) > 500) - Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x, terrainlight.y, terrainlight.z, .5, .2); - - - joints[i].position.y = (terrain.getHeight(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) + groundlevel - coords->y) / (*scale); - if (longdead > 100) - broken = 1; - } - if (terrain.patchobjectnum[whichpatchx][whichpatchz]) - for (m = 0; m < terrain.patchobjectnum[whichpatchx][whichpatchz]; m++) { - k = terrain.patchobjects[whichpatchx][whichpatchz][m]; - if (k < objects.numobjects && k >= 0) - if (objects.possible[k]) { - friction = objects.friction[k]; - XYZ start = joints[i].realoldposition; - XYZ end = joints[i].position * (*scale) + *coords; - whichhit = objects.model[k].LineCheckPossible(&start, &end, &temp, &objects.position[k], &objects.yaw[k]); - if (whichhit != -1) { - if (joints[i].label == groin && !joints[i].locked && joints[i].delay <= 0) { - joints[i].locked = 1; - joints[i].delay = 1; - if (tutoriallevel != 1 || id == 0) { - emit_sound_at(landsound1, joints[i].position * (*scale) + *coords, 128.); - } - breaking = true; - } - - if (joints[i].label == head && !joints[i].locked && joints[i].delay <= 0) { - joints[i].locked = 1; - joints[i].delay = 1; - if (tutoriallevel != 1 || id == 0) { - emit_sound_at(landsound2, joints[i].position * (*scale) + *coords, 128.); - } - } - - terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1; - if (terrainnormal.y > .8) - freefall = 0; - bounceness = terrainnormal * findLength(&joints[i].velocity) * (abs(normaldotproduct(joints[i].velocity, terrainnormal))); - if (findLengthfast(&joints[i].velocity) > findLengthfast(&joints[i].oldvelocity)) { - bounceness = 0; - joints[i].velocity = joints[i].oldvelocity; - } - if (tutoriallevel != 1 || id == 0) - if (findLengthfast(&bounceness) > 4000 && breaking) { - objects.model[k].MakeDecal(breakdecal, DoRotation(temp - objects.position[k], 0, -objects.yaw[k], 0), .4, .5, Random() % 360); - Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, 4, .2); - breaking = false; - camerashake += .6; - - emit_sound_at(breaksound2, joints[i].position * (*scale) + *coords); - - addEnvSound(*coords, 64); - } - if (objects.type[k] == treetrunktype) { - objects.rotx[k] += joints[i].velocity.x * multiplier * .4; - objects.roty[k] += joints[i].velocity.z * multiplier * .4; - objects.rotx[k + 1] += joints[i].velocity.x * multiplier * .4; - objects.roty[k + 1] += joints[i].velocity.z * multiplier * .4; - } - if (!joints[i].locked) - damage += findLengthfast(&bounceness) / 2500; - ReflectVector(&joints[i].velocity, &terrainnormal); - frictionness = abs(normaldotproduct(joints[i].velocity, terrainnormal)); - joints[i].velocity -= bounceness; - if (1 - friction * frictionness > 0) - joints[i].velocity *= 1 - friction * frictionness; - else - joints[i].velocity = 0; - if (findLengthfast(&bounceness) > 2500) { - Normalise(&bounceness); - bounceness = bounceness * 50; - } - joints[i].velocity += bounceness * elasticity; - - - if (!joints[i].locked) - if (findLengthfast(&joints[i].velocity) < 1) { - joints[i].locked = 1; - } - if (findLengthfast(&bounceness) > 500) - Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, .5, .2); - joints[i].position = (temp - *coords) / (*scale) + terrainnormal * .005; - if (longdead > 100) - broken = 1; - } - } - } - joints[i].realoldposition = joints[i].position * (*scale) + *coords; - } - } - multiplier = tempmult; - - - if (terrain.patchobjectnum[whichpatchx][whichpatchz]) - for (m = 0; m < terrain.patchobjectnum[whichpatchx][whichpatchz]; m++) { - k = terrain.patchobjects[whichpatchx][whichpatchz][m]; - if (objects.possible[k]) { - for (i = 0; i < 26; i++) { - //Make this less stupid - XYZ start = joints[jointlabels[whichjointstartarray[i]]].position * (*scale) + *coords; - XYZ end = joints[jointlabels[whichjointendarray[i]]].position * (*scale) + *coords; - whichhit = objects.model[k].LineCheckSlidePossible(&start, &end, &temp, &objects.position[k], &objects.yaw[k]); - if (whichhit != -1) { - joints[jointlabels[whichjointendarray[i]]].position = (end - *coords) / (*scale); - for (j = 0; j < num_muscles; j++) { - if ((muscles[j].parent1->label == whichjointstartarray[i] && muscles[j].parent2->label == whichjointendarray[i]) || (muscles[j].parent2->label == whichjointstartarray[i] && muscles[j].parent1->label == whichjointendarray[i])) - muscles[j].DoConstraint(spinny); - } - } - } - } - } - - for (i = 0; i < num_joints; i++) { - switch (joints[i].label) { - case head: - groundlevel = .8; - break; - case righthand: - case rightwrist: - case rightelbow: - case lefthand: - case leftwrist: - case leftelbow: - groundlevel = .2; - break; - default: - groundlevel = .15; - break; - } - joints[i].position.y += groundlevel; - joints[i].mass = 1; - if (joints[i].label == lefthip || joints[i].label == leftknee || joints[i].label == leftankle || joints[i].label == righthip || joints[i].label == rightknee || joints[i].label == rightankle) - joints[i].mass = 2; - if (joints[i].locked) { - joints[i].mass = 4; - } - } - - return damage; - } - - if (!free) { - for (i = 0; i < num_muscles; i++) { - if (muscles[i].type == boneconnect) - muscles[i].DoConstraint(0); - } - } - - return 0; -} - -/* EFFECT - * applies gravity to the skeleton - * - * USES: - * Person/Person::DoStuff - */ -void Skeleton::DoGravity(float *scale) -{ - static int i; - for (i = 0; i < num_joints; i++) { - if ( - ( - ((joints[i].label != leftknee) && (joints[i].label != rightknee)) || - (lowforward.y > -.1) || - (joints[i].mass < 5) - ) && ( - ((joints[i].label != leftelbow) && (joints[i].label != rightelbow)) || - (forward.y < .3) - ) - ) - joints[i].velocity.y += gravity * multiplier / (*scale); - } -} - -/* EFFECT - * set muscles[which].rotate1 - * .rotate2 - * .rotate3 - * - * special case if animation == hanganim - */ -void Skeleton::FindRotationMuscle(int which, int animation) -{ - XYZ p1, p2, fwd; - float dist; - - p1 = muscles[which].parent1->position; - p2 = muscles[which].parent2->position; - dist = findDistance(&p1, &p2); - if (p1.y - p2.y <= dist) - muscles[which].rotate2 = asin((p1.y - p2.y) / dist); - if (p1.y - p2.y > dist) - muscles[which].rotate2 = asin(1.f); - muscles[which].rotate2 *= 360.0 / 6.2831853; - - p1.y = 0; - p2.y = 0; - dist = findDistance(&p1, &p2); - if (p1.z - p2.z <= dist) - muscles[which].rotate1 = acos((p1.z - p2.z) / dist); - if (p1.z - p2.z > dist) - muscles[which].rotate1 = acos(1.f); - muscles[which].rotate1 *= 360.0 / 6.2831853; - if (p1.x > p2.x) - muscles[which].rotate1 = 360 - muscles[which].rotate1; - if (!isnormal(muscles[which].rotate1)) - muscles[which].rotate1 = 0; - if (!isnormal(muscles[which].rotate2)) - muscles[which].rotate2 = 0; - - const int label1 = muscles[which].parent1->label; - const int label2 = muscles[which].parent2->label; - switch (label1) { - case head: - fwd = specialforward[0]; - break; - case rightshoulder: - case rightelbow: - case rightwrist: - case righthand: - fwd = specialforward[1]; - break; - case leftshoulder: - case leftelbow: - case leftwrist: - case lefthand: - fwd = specialforward[2]; - break; - case righthip: - case rightknee: - case rightankle: - case rightfoot: - fwd = specialforward[3]; - break; - case lefthip: - case leftknee: - case leftankle: - case leftfoot: - fwd = specialforward[4]; - break; - default: - if (muscles[which].parent1->lower) - fwd = lowforward; - else - fwd = forward; - break; - } - - if (animation == hanganim) { - if (label1 == righthand || label2 == righthand) { - fwd = 0; - fwd.x = -1; - } - if (label1 == lefthand || label2 == lefthand) { - fwd = 0; - fwd.x = 1; - } - } - - if (free == 0) { - if (label1 == rightfoot || label2 == rightfoot) { - fwd.y -= .3; - } - if (label1 == leftfoot || label2 == leftfoot) { - fwd.y -= .3; - } - } - - fwd = DoRotation(fwd, 0, muscles[which].rotate1 - 90, 0); - fwd = DoRotation(fwd, 0, 0, muscles[which].rotate2 - 90); - fwd.y = 0; - fwd /= findLength(&fwd); - if (fwd.z <= 1 && fwd.z >= -1) - muscles[which].rotate3 = acos(0 - fwd.z); - else - muscles[which].rotate3 = acos(-1.f); - muscles[which].rotate3 *= 360.0 / 6.2831853; - if (0 > fwd.x) - muscles[which].rotate3 = 360 - muscles[which].rotate3; - if (!isnormal(muscles[which].rotate3)) - muscles[which].rotate3 = 0; -} - -/* EFFECT - * load an animation from file - */ -void Animation::Load(const std::string& filename, int aheight, int aattack) -{ - FILE *tfile; - int i, j; - XYZ endoffset; - - LOGFUNC; - - // Changing the filename into something the OS can understand - std::string filepath = Folders::getResourcePath("Animations/"+filename); - - LOG(std::string("Loading animation...") + filepath); - - // clear existing data - deallocate(); - - height = aheight; - attack = aattack; - - if (visibleloading) - Game::LoadingScreen(); - - // read file in binary mode - tfile = Folders::openMandatoryFile( filepath, "rb" ); - - // read numframes, joints to know how much memory to allocate - funpackf(tfile, "Bi Bi", &numframes, &joints); - - // allocate memory for everything - - position = (XYZ**)malloc(sizeof(XYZ*) * joints); - for (i = 0; i < joints; i++) - position[i] = (XYZ*)malloc(sizeof(XYZ) * numframes); - - twist = (float**)malloc(sizeof(float*) * joints); - for (i = 0; i < joints; i++) - twist[i] = (float*)malloc(sizeof(float) * numframes); - - twist2 = (float**)malloc(sizeof(float*) * joints); - for (i = 0; i < joints; i++) - twist2[i] = (float*)malloc(sizeof(float) * numframes); - - speed = (float*)malloc(sizeof(float) * numframes); - - onground = (bool**)malloc(sizeof(bool*) * joints); - for (i = 0; i < joints; i++) - onground[i] = (bool*)malloc(sizeof(bool) * numframes); - - forward = (XYZ*)malloc(sizeof(XYZ) * numframes); - weapontarget = (XYZ*)malloc(sizeof(XYZ) * numframes); - label = (int*)malloc(sizeof(int) * numframes); - - // read binary data as animation - - // for each frame... - for (i = 0; i < numframes; i++) { - // for each joint in the skeleton... - for (j = 0; j < joints; j++) { - // read joint position - funpackf(tfile, "Bf Bf Bf", &position[j][i].x, &position[j][i].y, &position[j][i].z); - } - for (j = 0; j < joints; j++) { - // read twist - funpackf(tfile, "Bf", &twist[j][i]); - } - for (j = 0; j < joints; j++) { - // read onground (boolean) - unsigned char uch; - funpackf(tfile, "Bb", &uch); - onground[j][i] = (uch != 0); - } - // read frame speed (?) - funpackf(tfile, "Bf", &speed[i]); - } - // read twist2 for whole animation - for (i = 0; i < numframes; i++) { - for (j = 0; j < joints; j++) { - funpackf(tfile, "Bf", &twist2[j][i]); - } - } - // read label for each frame - for (i = 0; i < numframes; i++) { - funpackf(tfile, "Bf", &label[i]); - } - // read weapontargetnum - funpackf(tfile, "Bi", &weapontargetnum); - // read weapontarget positions for each frame - for (i = 0; i < numframes; i++) { - funpackf(tfile, "Bf Bf Bf", &weapontarget[i].x, &weapontarget[i].y, &weapontarget[i].z); - } - - fclose(tfile); - - endoffset = 0; - // find average position of certain joints on last frames - // and save in endoffset - // (not sure what exactly this accomplishes. the y < 1 test confuses me.) - for (j = 0; j < joints; j++) { - if (position[j][numframes - 1].y < 1) - endoffset += position[j][numframes - 1]; - } - endoffset /= joints; - offset = endoffset; - offset.y = 0; -} - - -/* EFFECT - * load skeleton - * takes filenames for three skeleton files and various models - */ -void Skeleton::Load(const std::string& filename, const std::string& lowfilename, const std::string& clothesfilename, - const std::string& modelfilename, const std::string& model2filename, - const std::string& model3filename, const std::string& model4filename, - const std::string& model5filename, const std::string& model6filename, - const std::string& model7filename, const std::string& modellowfilename, - const std::string& modelclothesfilename, bool clothes) -{ - GLfloat M[16]; - int parentID; - FILE *tfile; - float lSize; - int i, j; - int edit; - - LOGFUNC; - - num_models = 7; - - // load various models - // rotate, scale, do normals, do texcoords for each as needed - - model[0].loadnotex(modelfilename); - model[1].loadnotex(model2filename); - model[2].loadnotex(model3filename); - model[3].loadnotex(model4filename); - model[4].loadnotex(model5filename); - model[5].loadnotex(model6filename); - model[6].loadnotex(model7filename); - - for (i = 0; i < num_models; i++) { - model[i].Rotate(180, 0, 0); - model[i].Scale(.04, .04, .04); - model[i].CalculateNormals(0); - } - - drawmodel.load(modelfilename, 0); - drawmodel.Rotate(180, 0, 0); - drawmodel.Scale(.04, .04, .04); - drawmodel.FlipTexCoords(); - if (tutoriallevel == 1 && id != 0) - drawmodel.UniformTexCoords(); - if (tutoriallevel == 1 && id != 0) - drawmodel.ScaleTexCoords(0.1); - drawmodel.CalculateNormals(0); - - modellow.loadnotex(modellowfilename); - modellow.Rotate(180, 0, 0); - modellow.Scale(.04, .04, .04); - modellow.CalculateNormals(0); - - drawmodellow.load(modellowfilename, 0); - drawmodellow.Rotate(180, 0, 0); - drawmodellow.Scale(.04, .04, .04); - drawmodellow.FlipTexCoords(); - if (tutoriallevel == 1 && id != 0) - drawmodellow.UniformTexCoords(); - if (tutoriallevel == 1 && id != 0) - drawmodellow.ScaleTexCoords(0.1); - drawmodellow.CalculateNormals(0); - - if (clothes) { - modelclothes.loadnotex(modelclothesfilename); - modelclothes.Rotate(180, 0, 0); - modelclothes.Scale(.041, .04, .041); - modelclothes.CalculateNormals(0); - - drawmodelclothes.load(modelclothesfilename, 0); - drawmodelclothes.Rotate(180, 0, 0); - drawmodelclothes.Scale(.04, .04, .04); - drawmodelclothes.FlipTexCoords(); - drawmodelclothes.CalculateNormals(0); - } - - // FIXME: three similar blocks follow, one for each of: - // filename, lowfilename, clothesfilename - - // load skeleton - - tfile = Folders::openMandatoryFile( Folders::getResourcePath(filename), "rb" ); - - // read num_joints - funpackf(tfile, "Bi", &num_joints); - - // allocate memory - if (joints) - delete [] joints; //dealloc2(joints); - joints = (Joint*)new Joint[num_joints]; - - // read info for each joint - for (i = 0; i < num_joints; i++) { - funpackf(tfile, "Bf Bf Bf Bf Bf", &joints[i].position.x, &joints[i].position.y, &joints[i].position.z, &joints[i].length, &joints[i].mass); - funpackf(tfile, "Bb Bb", &joints[i].hasparent, &joints[i].locked); - funpackf(tfile, "Bi", &joints[i].modelnum); - funpackf(tfile, "Bb Bb", &joints[i].visible, &joints[i].sametwist); - funpackf(tfile, "Bi Bi", &joints[i].label, &joints[i].hasgun); - funpackf(tfile, "Bb", &joints[i].lower); - funpackf(tfile, "Bi", &parentID); - if (joints[i].hasparent) - joints[i].parent = &joints[parentID]; - joints[i].velocity = 0; - joints[i].oldposition = joints[i].position; - } - - // read num_muscles - funpackf(tfile, "Bi", &num_muscles); - - // allocate memory - if (muscles) - delete [] muscles; //dealloc2(muscles); - muscles = (Muscle*)new Muscle[num_muscles]; //malloc(sizeof(Muscle)*num_muscles); - - // for each muscle... - for (i = 0; i < num_muscles; i++) { - // read info - funpackf(tfile, "Bf Bf Bf Bf Bf Bi Bi", &muscles[i].length, &muscles[i].targetlength, &muscles[i].minlength, &muscles[i].maxlength, &muscles[i].strength, &muscles[i].type, &muscles[i].numvertices); - - // allocate memory for vertices - muscles[i].vertices = (int*)malloc(sizeof(int) * muscles[i].numvertices); - - // read vertices - edit = 0; - for (j = 0; j < muscles[i].numvertices - edit; j++) { - funpackf(tfile, "Bi", &muscles[i].vertices[j + edit]); - if (muscles[i].vertices[j + edit] >= model[0].vertexNum) { - muscles[i].numvertices--; - edit--; - } - } - - // read more info - funpackf(tfile, "Bb Bi", &muscles[i].visible, &parentID); - muscles[i].parent1 = &joints[parentID]; - funpackf(tfile, "Bi", &parentID); - muscles[i].parent2 = &joints[parentID]; - } - - // read forwardjoints (?) - for (j = 0; j < 3; j++) { - funpackf(tfile, "Bi", &forwardjoints[j]); - } - // read lowforwardjoints (?) - for (j = 0; j < 3; j++) { - funpackf(tfile, "Bi", &lowforwardjoints[j]); - } - - // ??? - for (j = 0; j < num_muscles; j++) { - for (i = 0; i < muscles[j].numvertices; i++) { - for (int k = 0; k < num_models; k++) { - if (muscles[j].numvertices && muscles[j].vertices[i] < model[k].vertexNum) - model[k].owner[muscles[j].vertices[i]] = j; - } - } - } - - // calculate some stuff - FindForwards(); - for (i = 0; i < num_joints; i++) { - joints[i].startpos = joints[i].position; - } - for (i = 0; i < num_muscles; i++) { - FindRotationMuscle(i, -1); - } - // this seems to use opengl purely for matrix calculations - for (int k = 0; k < num_models; k++) { - for (i = 0; i < model[k].vertexNum; i++) { - model[k].vertex[i] = model[k].vertex[i] - (muscles[model[k].owner[i]].parent1->position + muscles[model[k].owner[i]].parent2->position) / 2; - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glRotatef(muscles[model[k].owner[i]].rotate3, 0, 1, 0); - glRotatef(muscles[model[k].owner[i]].rotate2 - 90, 0, 0, 1); - glRotatef(muscles[model[k].owner[i]].rotate1 - 90, 0, 1, 0); - glTranslatef(model[k].vertex[i].x, model[k].vertex[i].y, model[k].vertex[i].z); - glGetFloatv(GL_MODELVIEW_MATRIX, M); - model[k].vertex[i].x = M[12] * 1; - model[k].vertex[i].y = M[13] * 1; - model[k].vertex[i].z = M[14] * 1; - glPopMatrix(); - } - model[k].CalculateNormals(0); - } - fclose(tfile); - - // load ??? - - tfile = Folders::openMandatoryFile( Folders::getResourcePath(lowfilename), "rb" ); - - // skip joints section - - lSize = sizeof(num_joints); - fseek(tfile, lSize, SEEK_CUR); - for (i = 0; i < num_joints; i++) { - // skip joint info - lSize = sizeof(XYZ) - + sizeof(float) - + sizeof(float) - + 1 //sizeof(bool) - + 1 //sizeof(bool) - + sizeof(int) - + 1 //sizeof(bool) - + 1 //sizeof(bool) - + sizeof(int) - + sizeof(int) - + 1 //sizeof(bool) - + sizeof(int); - fseek(tfile, lSize, SEEK_CUR); - - if (joints[i].hasparent) - joints[i].parent = &joints[parentID]; - joints[i].velocity = 0; - joints[i].oldposition = joints[i].position; - } - - // read num_muscles - funpackf(tfile, "Bi", &num_muscles); - - for (i = 0; i < num_muscles; i++) { - // skip muscle info - lSize = sizeof(float) - + sizeof(float) - + sizeof(float) - + sizeof(float) - + sizeof(float) - + sizeof(int); - fseek(tfile, lSize, SEEK_CUR); - - // read numverticeslow - funpackf(tfile, "Bi", &muscles[i].numverticeslow); - - if (muscles[i].numverticeslow) { - // allocate memory - muscles[i].verticeslow = (int*)malloc(sizeof(int) * muscles[i].numverticeslow); - - // read verticeslow - edit = 0; - for (j = 0; j < muscles[i].numverticeslow - edit; j++) { - funpackf(tfile, "Bi", &muscles[i].verticeslow[j + edit]); - if (muscles[i].verticeslow[j + edit] >= modellow.vertexNum) { - muscles[i].numverticeslow--; - edit--; - } - } - } - - // skip more stuff - lSize = 1; //sizeof(bool); - fseek ( tfile, lSize, SEEK_CUR); - lSize = sizeof(int); - fseek ( tfile, lSize, SEEK_CUR); - fseek ( tfile, lSize, SEEK_CUR); - } - - for (j = 0; j < num_muscles; j++) { - for (i = 0; i < muscles[j].numverticeslow; i++) { - if (muscles[j].verticeslow[i] < modellow.vertexNum) - modellow.owner[muscles[j].verticeslow[i]] = j; - } - } - - // use opengl for its matrix math - for (i = 0; i < modellow.vertexNum; i++) { - modellow.vertex[i] = modellow.vertex[i] - (muscles[modellow.owner[i]].parent1->position + muscles[modellow.owner[i]].parent2->position) / 2; - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glRotatef(muscles[modellow.owner[i]].rotate3, 0, 1, 0); - glRotatef(muscles[modellow.owner[i]].rotate2 - 90, 0, 0, 1); - glRotatef(muscles[modellow.owner[i]].rotate1 - 90, 0, 1, 0); - glTranslatef(modellow.vertex[i].x, modellow.vertex[i].y, modellow.vertex[i].z); - glGetFloatv(GL_MODELVIEW_MATRIX, M); - modellow.vertex[i].x = M[12]; - modellow.vertex[i].y = M[13]; - modellow.vertex[i].z = M[14]; - glPopMatrix(); - } - - modellow.CalculateNormals(0); - - // load clothes - - if (clothes) { - tfile = Folders::openMandatoryFile( Folders::getResourcePath(clothesfilename), "rb" ); - - // skip num_joints - lSize = sizeof(num_joints); - fseek ( tfile, lSize, SEEK_CUR); - - for (i = 0; i < num_joints; i++) { - // skip joint info - lSize = sizeof(XYZ) - + sizeof(float) - + sizeof(float) - + 1 //sizeof(bool) - + 1 //sizeof(bool) - + sizeof(int) - + 1 //sizeof(bool) - + 1 //sizeof(bool) - + sizeof(int) - + sizeof(int) - + 1 //sizeof(bool) - + sizeof(int); - fseek(tfile, lSize, SEEK_CUR); - - if (joints[i].hasparent) - joints[i].parent = &joints[parentID]; - joints[i].velocity = 0; - joints[i].oldposition = joints[i].position; - } - - // read num_muscles - funpackf(tfile, "Bi", &num_muscles); - - for (i = 0; i < num_muscles; i++) { - // skip muscle info - lSize = sizeof(float) - + sizeof(float) - + sizeof(float) - + sizeof(float) - + sizeof(float) - + sizeof(int); - fseek(tfile, lSize, SEEK_CUR); - - // read numverticesclothes - funpackf(tfile, "Bi", &muscles[i].numverticesclothes); - - // read verticesclothes - if (muscles[i].numverticesclothes) { - muscles[i].verticesclothes = (int*)malloc(sizeof(int) * muscles[i].numverticesclothes); - edit = 0; - for (j = 0; j < muscles[i].numverticesclothes - edit; j++) { - funpackf(tfile, "Bi", &muscles[i].verticesclothes[j + edit]); - if (muscles[i].verticesclothes[j + edit] >= modelclothes.vertexNum) { - muscles[i].numverticesclothes--; - edit--; - } - } - } - - // skip more stuff - lSize = 1; //sizeof(bool); - fseek ( tfile, lSize, SEEK_CUR); - lSize = sizeof(int); - fseek ( tfile, lSize, SEEK_CUR); - fseek ( tfile, lSize, SEEK_CUR); - } - - // ??? - lSize = sizeof(int); - for (j = 0; j < num_muscles; j++) { - for (i = 0; i < muscles[j].numverticesclothes; i++) { - if (muscles[j].numverticesclothes && muscles[j].verticesclothes[i] < modelclothes.vertexNum) - modelclothes.owner[muscles[j].verticesclothes[i]] = j; - } - } - - // use opengl for its matrix math - for (i = 0; i < modelclothes.vertexNum; i++) { - modelclothes.vertex[i] = modelclothes.vertex[i] - (muscles[modelclothes.owner[i]].parent1->position + muscles[modelclothes.owner[i]].parent2->position) / 2; - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glRotatef(muscles[modelclothes.owner[i]].rotate3, 0, 1, 0); - glRotatef(muscles[modelclothes.owner[i]].rotate2 - 90, 0, 0, 1); - glRotatef(muscles[modelclothes.owner[i]].rotate1 - 90, 0, 1, 0); - glTranslatef(modelclothes.vertex[i].x, modelclothes.vertex[i].y, modelclothes.vertex[i].z); - glGetFloatv(GL_MODELVIEW_MATRIX, M); - modelclothes.vertex[i].x = M[12]; - modelclothes.vertex[i].y = M[13]; - modelclothes.vertex[i].z = M[14]; - glPopMatrix(); - } - - modelclothes.CalculateNormals(0); - } - fclose(tfile); - - for (i = 0; i < num_joints; i++) { - for (j = 0; j < num_joints; j++) { - if (joints[i].label == j) - jointlabels[j] = i; - } - } - - free = 0; -} - -Animation::Animation() -{ - numframes = 0; - height = 0; - attack = 0; - joints = 0; - weapontargetnum = 0; - - position = 0; - twist = 0; - twist2 = 0; - speed = 0; - onground = 0; - forward = 0; - label = 0; - weapontarget = 0; -} - -Animation::~Animation() -{ - deallocate(); -} - -void Animation::deallocate() -{ - int i = 0; - - if (position) { - for (i = 0; i < joints; i++) - dealloc2(position[i]); - - dealloc2(position); - } - position = 0; - - if (twist) { - for (i = 0; i < joints; i++) - dealloc2(twist[i]); - - dealloc2(twist); - } - twist = 0; - - if (twist2) { - for (i = 0; i < joints; i++) - dealloc2(twist2[i]); - - dealloc2(twist2); - } - twist2 = 0; - - if (onground) { - for (i = 0; i < joints; i++) - dealloc2(onground[i]); - - dealloc2(onground); - } - onground = 0; - - if (speed) - dealloc2(speed); - speed = 0; - - if (forward) - dealloc2(forward); - forward = 0; - - if (weapontarget) - dealloc2(weapontarget); - weapontarget = 0; - - if (label) - dealloc2(label); - label = 0; - - joints = 0; -} - -Skeleton::Skeleton() -{ - num_joints = 0; - - num_muscles = 0; - - selected = 0; - - memset(forwardjoints, 0, sizeof(forwardjoints)); - // XYZ forward; - - id = 0; - - memset(lowforwardjoints, 0, sizeof(lowforwardjoints)); - // XYZ lowforward; - - // XYZ specialforward[5]; - memset(jointlabels, 0, sizeof(jointlabels)); - - // Model model[7]; - // Model modellow; - // Model modelclothes; - num_models = 0; - - // Model drawmodel; - // Model drawmodellow; - // Model drawmodelclothes; - - clothes = 0; - spinny = 0; - - memset(skinText, 0, sizeof(skinText)); - skinsize = 0; - - checkdelay = 0; - - longdead = 0; - broken = 0; - - free = 0; - oldfree = 0; - freetime = 0; - freefall = 0; - - joints = 0; - muscles = 0; -} - -Skeleton::~Skeleton() -{ - if (muscles) { - delete [] muscles; - } - muscles = 0; - - if (joints) { - delete [] joints; - } - joints = 0; -} - -Muscle::Muscle() -{ - vertices = 0; - verticeslow = 0; - verticesclothes = 0; - - numvertices = 0; - numverticeslow = 0; - numverticesclothes = 0; - length = 0; - targetlength = 0; - parent1 = 0; - parent2 = 0; - maxlength = 0; - minlength = 0; - type = 0; - visible = 0; - rotate1 = 0, rotate2 = 0, rotate3 = 0; - lastrotate1 = 0, lastrotate2 = 0, lastrotate3 = 0; - oldrotate1 = 0, oldrotate2 = 0, oldrotate3 = 0; - newrotate1 = 0, newrotate2 = 0, newrotate3 = 0; - - strength = 0; -} - -Muscle::~Muscle() -{ - dealloc2(vertices); - dealloc2(verticeslow); - dealloc2(verticesclothes); -} - -Animation & Animation::operator = (const Animation & ani) -{ - int i = 0; - - bool allocate = ((ani.numframes != numframes) || (ani.joints != joints)); - - if (allocate) - deallocate(); - - numframes = ani.numframes; - height = ani.height; - attack = ani.attack; - joints = ani.joints; - weapontargetnum = ani.weapontargetnum; - offset = ani.offset; - - if (allocate) - position = (XYZ**)malloc(sizeof(XYZ*)*ani.joints); - for (i = 0; i < ani.joints; i++) { - if (allocate) - position[i] = (XYZ*)malloc(sizeof(XYZ) * ani.numframes); - memcpy(position[i], ani.position[i], sizeof(XYZ)*ani.numframes); - } - - if (allocate) - twist = (float**)malloc(sizeof(float*)*ani.joints); - for (i = 0; i < ani.joints; i++) { - if (allocate) - twist[i] = (float*)malloc(sizeof(float) * ani.numframes); - memcpy(twist[i], ani.twist[i], sizeof(float)*ani.numframes); - } - - if (allocate) - twist2 = (float**)malloc(sizeof(float*)*ani.joints); - for (i = 0; i < ani.joints; i++) { - if (allocate) - twist2[i] = (float*)malloc(sizeof(float) * ani.numframes); - memcpy(twist2[i], ani.twist2[i], sizeof(float)*ani.numframes); - } - - if (allocate) - speed = (float*)malloc(sizeof(float) * ani.numframes); - memcpy(speed, ani.speed, sizeof(float)*ani.numframes); - - if (allocate) - onground = (bool**)malloc(sizeof(bool*)*ani.joints); - for (i = 0; i < ani.joints; i++) { - if (allocate) - onground[i] = (bool*)malloc(sizeof(bool) * ani.numframes); - memcpy(onground[i], ani.onground[i], sizeof(bool)*ani.numframes); - } - - if (allocate) - forward = (XYZ*)malloc(sizeof(XYZ) * ani.numframes); - memcpy(forward, ani.forward, sizeof(XYZ)*ani.numframes); - - if (allocate) - weapontarget = (XYZ*)malloc(sizeof(XYZ) * ani.numframes); - memcpy(weapontarget, ani.weapontarget, sizeof(XYZ)*ani.numframes); - - if (allocate) - label = (int*)malloc(sizeof(int) * ani.numframes); - memcpy(label, ani.label, sizeof(int)*ani.numframes); - - return (*this); -} - - - - -#if 0 - -// the following functions are not used anywhere - -/* EFFECT - * sets forward, lowforward, specialforward[] - * - * USES: - * NONE - */ -void Skeleton::FindForwardsfirst() -{ - //Find forward vectors - CrossProduct(joints[forwardjoints[1]].position - joints[forwardjoints[0]].position, joints[forwardjoints[2]].position - joints[forwardjoints[0]].position, &forward); - Normalise(&forward); - - CrossProduct(joints[lowforwardjoints[1]].position - joints[lowforwardjoints[0]].position, joints[lowforwardjoints[2]].position - joints[lowforwardjoints[0]].position, &lowforward); - Normalise(&lowforward); - - //Special forwards - specialforward[0] = forward; - specialforward[1] = forward; - specialforward[2] = forward; - specialforward[3] = forward; - specialforward[4] = forward; - -} - -/* EFFECT - * - * USES: - * NONE - */ -void Skeleton::Draw(int muscleview) -{ - static float jointcolor[4]; - - if (muscleview != 2) { - jointcolor[0] = 0; - jointcolor[1] = 0; - jointcolor[2] = .5; - jointcolor[3] = 1; - } - - if (muscleview == 2) { - jointcolor[0] = 0; - jointcolor[1] = 0; - jointcolor[2] = 0; - jointcolor[3] = .5; - } - //Calc motionblur-ness - for (int i = 0; i < num_joints; i++) { - joints[i].oldposition = joints[i].position; - joints[i].blurred = findDistance(&joints[i].position, &joints[i].oldposition) * 100; - if (joints[i].blurred < 1) - joints[i].blurred = 1; - } - - //Do Motionblur - glDepthMask(0); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBegin(GL_QUADS); - for (int i = 0; i < num_joints; i++) { - if (joints[i].hasparent) { - glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].blurred); - glVertex3f(joints[i].position.x, joints[i].position.y, joints[i].position.z); - glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].parent->blurred); - glVertex3f(joints[i].parent->position.x, joints[i].parent->position.y, joints[i].parent->position.z); - glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].parent->blurred); - glVertex3f(joints[i].parent->oldposition.x, joints[i].parent->oldposition.y, joints[i].parent->oldposition.z); - glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].blurred); - glVertex3f(joints[i].oldposition.x, joints[i].oldposition.y, joints[i].oldposition.z); - } - } - for (int i = 0; i < num_muscles; i++) { - if (muscles[i].type == boneconnect) { - glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent2->blurred); - glVertex3f(muscles[i].parent1->position.x, muscles[i].parent1->position.y, muscles[i].parent1->position.z); - glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent2->blurred); - glVertex3f(muscles[i].parent2->position.x, muscles[i].parent2->position.y, muscles[i].parent2->position.z); - glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent2->blurred); - glVertex3f(muscles[i].parent2->oldposition.x, muscles[i].parent2->oldposition.y, muscles[i].parent2->oldposition.z); - glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent1->blurred); - glVertex3f(muscles[i].parent1->oldposition.x, muscles[i].parent1->oldposition.y, muscles[i].parent1->oldposition.z); - } - } - glEnd(); - - glBegin(GL_LINES); - for (int i = 0; i < num_joints; i++) { - if (joints[i].hasparent) { - glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].blurred); - glVertex3f(joints[i].position.x, joints[i].position.y, joints[i].position.z); - glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].parent->blurred); - glVertex3f(joints[i].parent->position.x, joints[i].parent->position.y, joints[i].parent->position.z); - } - } - for (int i = 0; i < num_muscles; i++) { - if (muscles[i].type == boneconnect) { - glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent1->blurred); - glVertex3f(muscles[i].parent1->position.x, muscles[i].parent1->position.y, muscles[i].parent1->position.z); - glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent2->blurred); - glVertex3f(muscles[i].parent2->position.x, muscles[i].parent2->position.y, muscles[i].parent2->position.z); - } - } - glColor3f(.6, .6, 0); - if (muscleview == 1) - for (int i = 0; i < num_muscles; i++) { - if (muscles[i].type != boneconnect) { - glVertex3f(muscles[i].parent1->position.x, muscles[i].parent1->position.y, muscles[i].parent1->position.z); - glVertex3f(muscles[i].parent2->position.x, muscles[i].parent2->position.y, muscles[i].parent2->position.z); - } - } - glEnd(); - - if (muscleview != 2) { - glPointSize(3); - glBegin(GL_POINTS); - for (int i = 0; i < num_joints; i++) { - if (i != selected) - glColor4f(0, 0, .5, 1); - if (i == selected) - glColor4f(1, 1, 0, 1); - if (joints[i].locked && i != selected) - glColor4f(1, 0, 0, 1); - glVertex3f(joints[i].position.x, joints[i].position.y, joints[i].position.z); - } - glEnd(); - } - - //Set old position to current position - if (muscleview == 2) - for (int i = 0; i < num_joints; i++) { - joints[i].oldposition = joints[i].position; - } - glDepthMask(1); -} - -/* EFFECT - * - * USES: - * NONE - */ -void Skeleton::AddJoint(float x, float y, float z, int which) -{ - if (num_joints < max_joints - 1) { - joints[num_joints].velocity = 0; - joints[num_joints].position.x = x; - joints[num_joints].position.y = y; - joints[num_joints].position.z = z; - joints[num_joints].mass = 1; - joints[num_joints].locked = 0; - - joints[num_joints].hasparent = 0; - num_joints++; - if (which < num_joints && which >= 0) - AddMuscle(num_joints - 1, which, 0, 10, boneconnect); - } -} - -/* EFFECT - * - * USES: - * NONE - */ -void Skeleton::DeleteJoint(int whichjoint) -{ - if (whichjoint < num_joints && whichjoint >= 0) { - joints[whichjoint].velocity = joints[num_joints - 1].velocity; - joints[whichjoint].position = joints[num_joints - 1].position; - joints[whichjoint].oldposition = joints[num_joints - 1].oldposition; - joints[whichjoint].hasparent = joints[num_joints - 1].hasparent; - joints[whichjoint].parent = joints[num_joints - 1].parent; - joints[whichjoint].length = joints[num_joints - 1].length; - joints[whichjoint].locked = joints[num_joints - 1].locked; - joints[whichjoint].modelnum = joints[num_joints - 1].modelnum; - joints[whichjoint].visible = joints[num_joints - 1].visible; - - for (int i = 0; i < num_muscles; i++) { - while (muscles[i].parent1 == &joints[whichjoint] && i < num_muscles)DeleteMuscle(i); - while (muscles[i].parent2 == &joints[whichjoint] && i < num_muscles)DeleteMuscle(i); - } - for (int i = 0; i < num_muscles; i++) { - while (muscles[i].parent1 == &joints[num_joints - 1] && i < num_muscles)muscles[i].parent1 = &joints[whichjoint]; - while (muscles[i].parent2 == &joints[num_joints - 1] && i < num_muscles)muscles[i].parent2 = &joints[whichjoint]; - } - for (int i = 0; i < num_joints; i++) { - if (joints[i].parent == &joints[whichjoint]) - joints[i].hasparent = 0; - } - for (int i = 0; i < num_joints; i++) { - if (joints[i].parent == &joints[num_joints - 1]) - joints[i].parent = &joints[whichjoint]; - } - - num_joints--; - } -} - -/* EFFECT - * - * USES: - * Skeleton::DeleteJoint - UNUSED - */ -void Skeleton::DeleteMuscle(int whichmuscle) -{ - if (whichmuscle < num_muscles) { - muscles[whichmuscle].minlength = muscles[num_muscles - 1].minlength; - muscles[whichmuscle].maxlength = muscles[num_muscles - 1].maxlength; - muscles[whichmuscle].strength = muscles[num_muscles - 1].strength; - muscles[whichmuscle].parent1 = muscles[num_muscles - 1].parent1; - muscles[whichmuscle].parent2 = muscles[num_muscles - 1].parent2; - muscles[whichmuscle].length = muscles[num_muscles - 1].length; - muscles[whichmuscle].visible = muscles[num_muscles - 1].visible; - muscles[whichmuscle].type = muscles[num_muscles - 1].type; - muscles[whichmuscle].targetlength = muscles[num_muscles - 1].targetlength; - - num_muscles--; - } -} - -/* EFFECT - * - * USES: - * NONE - */ -void Skeleton::SetJoint(float x, float y, float z, int which, int whichjoint) -{ - if (whichjoint < num_joints) { - joints[whichjoint].velocity = 0; - joints[whichjoint].position.x = x; - joints[whichjoint].position.y = y; - joints[whichjoint].position.z = z; - - if (which >= num_joints || which < 0) - joints[whichjoint].hasparent = 0; - if (which < num_joints && which >= 0) { - joints[whichjoint].parent = &joints[which]; - joints[whichjoint].hasparent = 1; - joints[whichjoint].length = findDistance(&joints[whichjoint].position, &joints[whichjoint].parent->position); - } - } -} - -/* EFFECT - * - * USES: - * Skeleton::AddJoint - UNUSED - */ -void Skeleton::AddMuscle(int attach1, int attach2, float minlength, float maxlength, int type) -{ - const int max_muscles = 100; // FIXME: Probably can be dropped - if (num_muscles < max_muscles - 1 && attach1 < num_joints && attach1 >= 0 && attach2 < num_joints && attach2 >= 0 && attach1 != attach2) { - muscles[num_muscles].parent1 = &joints[attach1]; - muscles[num_muscles].parent2 = &joints[attach2]; - muscles[num_muscles].length = findDistance(&muscles[num_muscles].parent1->position, &muscles[num_muscles].parent2->position); - muscles[num_muscles].targetlength = findDistance(&muscles[num_muscles].parent1->position, &muscles[num_muscles].parent2->position); - muscles[num_muscles].strength = .7; - muscles[num_muscles].type = type; - muscles[num_muscles].minlength = minlength; - muscles[num_muscles].maxlength = maxlength; - - num_muscles++; - } -} - -/* EFFECT - * - * USES: - * NONE - */ -void Skeleton::MusclesSet() -{ - for (int i = 0; i < num_muscles; i++) { - muscles[i].length = findDistance(&muscles[i].parent1->position, &muscles[i].parent2->position); - } -} - -/* EFFECT - * - * USES: - * NONE - */ -void Skeleton::DoBalance() -{ - /*XYZ newpoint; - newpoint=joints[0].position; - newpoint.x=(joints[2].position.x+joints[4].position.x)/2; - newpoint.z=(joints[2].position.z+joints[4].position.z)/2; - joints[0].velocity=joints[0].velocity+(newpoint-joints[0].position); - //Move child point to within certain distance of parent point - joints[0].position=newpoint; - - MusclesSet();*/ -} - -#endif - diff --git a/Source/Skeleton.h b/Source/Skeleton.h deleted file mode 100644 index eb2afff..0000000 --- a/Source/Skeleton.h +++ /dev/null @@ -1,231 +0,0 @@ -/* -Copyright (C) 2003, 2010 - Wolfire Games -Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file) - -This file is part of Lugaru. - -Lugaru is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -Lugaru is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Lugaru. If not, see . -*/ - -#ifndef _SKELETON_H_ -#define _SKELETON_H_ - -#include "Models.h" -#include "Quaternions.h" - - -/**> HEADER FILES <**/ -#include "gamegl.h" -#include "Quaternions.h" -#include "Objects.h" -#include "Sprite.h" -#include "binio.h" - -enum bodyparts { - head, neck, - leftshoulder, leftelbow, leftwrist, lefthand, - rightshoulder, rightelbow, rightwrist, righthand, - abdomen, lefthip, righthip, groin, - leftknee, leftankle, leftfoot, - rightknee, rightankle, rightfoot -}; - -class Joint -{ -public: - XYZ position; - XYZ oldposition; - XYZ realoldposition; - XYZ velocity; - XYZ oldvelocity; - XYZ startpos; - float blurred; - float length; - float mass; - bool lower; - bool hasparent; - bool locked; - int modelnum; - bool visible; - Joint* parent; - bool sametwist; - int label; - int hasgun; - float delay; - XYZ velchange; - - Joint() { - blurred = 0; - length = 0; - mass = 0; - lower = 0; - hasparent = 0; - locked = 0; - modelnum = 0; - visible = 0; - parent = 0; - sametwist = 0; - label = 0; - hasgun = 0; - delay = 0; - } -}; - -class Muscle -{ -public: - int numvertices; - int* vertices; - int numverticeslow; - int* verticeslow; - int numverticesclothes; - int* verticesclothes; - float length; - float targetlength; - Joint* parent1; - Joint* parent2; - float maxlength; - float minlength; - int type; - bool visible; - float rotate1, rotate2, rotate3; - float lastrotate1, lastrotate2, lastrotate3; - float oldrotate1, oldrotate2, oldrotate3; - float newrotate1, newrotate2, newrotate3; - - float strength; - - Muscle(); - ~Muscle(); - void DoConstraint(bool spinny); -}; - -class Animation -{ -public: - int numframes; - int height; - int attack; - int joints; - int weapontargetnum; - - XYZ** position; - float** twist; - float** twist2; - float* speed; - bool** onground; - XYZ* forward; - int* label; - XYZ* weapontarget; - - XYZ offset; - - Animation(); - ~Animation(); - Animation & operator = (const Animation & ani); - - void Load(const std::string& fileName, int aheight, int aattack); - -protected: - void deallocate(); -}; - - -const int max_joints = 50; - -class Skeleton -{ -public: - int num_joints; - //Joint joints[max_joints]; - //Joint *joints; - Joint* joints; - - int num_muscles; - //Muscle muscles[max_muscles]; - //Muscle *muscles; - Muscle* muscles; - - int selected; - - int forwardjoints[3]; - XYZ forward; - - int id; - - int lowforwardjoints[3]; - XYZ lowforward; - - XYZ specialforward[5]; - int jointlabels[max_joints]; - - Model model[7]; - Model modellow; - Model modelclothes; - int num_models; - - Model drawmodel; - Model drawmodellow; - Model drawmodelclothes; - - bool clothes; - bool spinny; - - GLubyte skinText[512 * 512 * 3]; - int skinsize; - - float checkdelay; - - float longdead; - bool broken; - - int free; - int oldfree; - float freetime; - bool freefall; - - void FindForwards(); - float DoConstraints(XYZ *coords, float *scale); - void DoGravity(float *scale); - void FindRotationJoint(int which); - void FindRotationJointSameTwist(int which); - void FindRotationMuscle(int which, int animation); - void Load(const std::string& fileName, const std::string& lowfileName, const std::string& clothesfileName, const std::string& modelfileName, const std::string& model2fileName, const std::string& model3fileName, const std::string& model4fileName, const std::string& model5fileNamee, const std::string& model6fileName, const std::string& model7fileName, const std::string& modellowfileName, const std::string& modelclothesfileName, bool aclothes); - - /* - // unused - void FindForwardsfirst(); - void Draw(int muscleview); - void AddJoint(float x, float y, float z, int which); - void SetJoint(float x, float y, float z, int which, int whichjoint); - void DeleteJoint(int whichjoint); - void AddMuscle(int attach1, int attach2, float maxlength, float minlength, int type); - void DeleteMuscle(int whichmuscle); - void DoBalance(); - void MusclesSet(); - */ - - Skeleton(); - ~Skeleton(); - -private: - // convenience functions - // only for Skeleton.cpp - inline Joint& joint(int bodypart) { return joints[jointlabels[bodypart]]; } - inline XYZ& jointPos(int bodypart) { return joint(bodypart).position; } - inline XYZ& jointVel(int bodypart) { return joint(bodypart).velocity; } - -}; - -#endif diff --git a/Source/Weapons.cpp b/Source/Weapons.cpp index 7b694a1..35f73c2 100644 --- a/Source/Weapons.cpp +++ b/Source/Weapons.cpp @@ -23,7 +23,7 @@ along with Lugaru. If not, see . /**> HEADER FILES <**/ #include "Weapons.h" #include "openal_wrapper.h" -#include "Animation.h" +#include "Animation/Animation.h" #include "Sounds.h" #include "Game.h" #include "Awards.h" @@ -271,7 +271,7 @@ void Weapon::DoStuff(int i) emit_sound_at(fleshstabsound, position, 128.); - if (animation[Person::players[0]->animTarget].height == highheight) + if (Animation::animations[Person::players[0]->animTarget].height == highheight) award_bonus(0, ninja); else award_bonus(0, Bullseyebonus); diff --git a/Source/Weapons.h b/Source/Weapons.h index 5954d8f..7472541 100644 --- a/Source/Weapons.h +++ b/Source/Weapons.h @@ -25,7 +25,7 @@ along with Lugaru. If not, see . #include "gamegl.h" #include "Quaternions.h" -#include "Skeleton.h" +#include "Animation/Skeleton.h" #include "Models.h" #include "Terrain.h" #include "Sprite.h"