1 /* ResidualVM - A 3D game interpreter 2 * 3 * ResidualVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef GRIM_ACTOR_H 24 #define GRIM_ACTOR_H 25 26 #include "engines/grim/pool.h" 27 #include "engines/grim/object.h" 28 #include "engines/grim/color.h" 29 #include "math/vector3d.h" 30 #include "math/angle.h" 31 #include "math/quat.h" 32 33 namespace Grim { 34 35 class TextObject; 36 class Sector; 37 class Costume; 38 class LipSync; 39 class Font; 40 class Set; 41 class Material; 42 struct SetShadow; 43 struct Joint; 44 class EMIModel; 45 46 struct Plane { 47 Common::String setName; 48 Sector *sector; 49 }; 50 51 typedef Common::List<Plane> SectorListType; 52 53 #define MAX_SHADOWS 8 54 55 struct Shadow { 56 Shadow(); 57 58 Common::String name; 59 Math::Vector3d pos; 60 SectorListType planeList; 61 byte *shadowMask; 62 int shadowMaskSize; 63 bool active; 64 bool dontNegate; 65 Color color; 66 void *userData; 67 }; 68 69 /** 70 * @class Actor 71 * 72 * @short Actor represents a 3D character on screen. 73 */ 74 class Actor : public PoolObject<Actor> { 75 public: 76 enum CollisionMode { 77 CollisionOff = 0, 78 CollisionBox = 1, 79 CollisionSphere = 2 80 }; 81 82 enum AlphaMode { 83 AlphaOff = -1, 84 AlphaReplace = 2, 85 AlphaModulate = 3 // Seems to be unused 86 }; 87 88 enum LightMode { 89 LightStatic = 0, 90 LightFastDyn = 1, 91 LightNormDyn = 2, 92 LightNone = 3 93 }; 94 95 /** 96 * Builds an actor setting up only the minimal variables. 97 */ 98 Actor(); 99 /** 100 * Destroys the actor. 101 * The actor is automatically removed from the GrimEngine instance. 102 */ 103 ~Actor(); 104 getStaticTag()105 static int32 getStaticTag() { return MKTAG('A', 'C', 'T', 'R'); } 106 107 /** 108 * Saves the actor state. 109 * 110 * @param savedState The save state to which save the actor's state. 111 */ 112 void saveState(SaveGame *savedState) const; 113 /** 114 * Restores the actor state. 115 * 116 * @param savedState The saved state from which the actor will be restored. 117 */ 118 bool restoreState(SaveGame *savedState); 119 120 /** 121 * Returns the name of the actor. 122 */ getName()123 const Common::String &getName() const { return _name; } 124 125 /** 126 * Sets the name of the actor. 127 * 128 * @param name The name. 129 */ setName(const Common::String & name)130 void setName(const Common::String &name) { _name = name; } 131 132 /** 133 * Sets the color of the subtitles of the actor. 134 * 135 * @param color The color. 136 * @see getTalkColor 137 */ setTalkColor(const Color & color)138 void setTalkColor(const Color &color) { _talkColor = color; } 139 /** 140 * Returns the color of the subtitles of the actor. 141 * 142 * @see setTalkColor 143 */ getTalkColor()144 Color getTalkColor() const { return _talkColor; } 145 146 /** 147 * Sets the position of the actor on the 3D scene. 148 * 149 * @param position The position. 150 * @see getPos 151 */ 152 void setPos(const Math::Vector3d &position); 153 /** 154 * Returns the position of the actor on the 3D scene. 155 * 156 * @see setPos 157 */ getPos()158 Math::Vector3d getPos() const { return _pos; } getDestPos()159 inline Math::Vector3d getDestPos() const { return _destPos; } 160 161 /** 162 * Tells the actor to go to the wanted position. 163 * If the actor follows the walkboxes it will find the best 164 * route to go there, otherwise it will walk on a straight line. 165 * 166 * @param position The destination position. 167 * @see stopWalking 168 * @see isWalking 169 */ 170 void walkTo(const Math::Vector3d &position); 171 /** 172 * Stops immediately the actor's walk. 173 * 174 * @see walkTo 175 * @see isWalking 176 */ stopWalking()177 void stopWalking() { _walking = false; } 178 /** 179 * Returns true if the actor is walking to a position. 180 * 181 * @see walkTo 182 * @see stopWalking 183 */ 184 bool isWalking() const; 185 186 /** 187 * Sets the rotation of thes actor in the 3D scene. 188 * The effect is not immediate, the actor will slowly rotate 189 * to the destination orientation. 190 * 191 * @param pitch The rotation of the x axis 192 * @param yaw The rotation of the z axis 193 * @param roll The rotation of the y axis 194 * @param snap If true tells the actor to increate its turn speed. 195 * @see getPitch 196 * @see getYaw 197 * @see getRoll 198 * @see setRot 199 * @see turn 200 * @see isTurning 201 */ 202 void turnTo(const Math::Angle &pitch, const Math::Angle &yaw, const Math::Angle &roll, bool snap = false); 203 /** 204 * Turn the actor towards a point in space. 205 * The effect is not immediate, the actor will slowly rotate 206 * to the destination orientation. 207 * 208 * @param pos The position the actor should turn to. 209 * @param snap If true tells the actor to increate its turn speed. 210 * @see turnTo 211 * @see setRot 212 */ 213 void turnTo(const Math::Vector3d &pos, bool snap = false); 214 /** 215 * Turn the actor towards a point in space, by an amount defined by the turn rate. 216 * This function does not make an actor point at the given position, but it makes 217 * it rotate towards that. 218 * 219 * @param pos The position the actor should turn to. 220 * @return true if the actor has reached the desired orientation 221 * @see turnTo 222 * @see setRot 223 */ 224 bool singleTurnTo(const Math::Vector3d &pos); 225 /** 226 * Returns true if the actor is turning. 227 * 228 * @see turnTo 229 */ 230 bool isTurning() const; 231 /** 232 * Stops the actor from turning 233 */ 234 void stopTurning(); 235 /** 236 * Sets the rotation of the actor in the 3D scene. 237 * The effect is immediate. 238 * 239 * @param pitch The rotation of the x axis 240 * @param yaw The rotation of the z axis 241 * @param roll The rotation of the y axis 242 * @see getPitch 243 * @see getYaw 244 * @see getRoll 245 * @see turnTo 246 * @see turn 247 * @see isTurning 248 */ 249 void setRot(const Math::Angle &pitch, const Math::Angle &yaw, const Math::Angle &roll); 250 /** 251 * Turn the actor towards a point in space. 252 * The effect is immediate. 253 * 254 * @param pos The position the actor should turn to. 255 * @see turnTo 256 * @see setRot 257 */ 258 void setRot(const Math::Vector3d &pos); 259 /** 260 * Turns the actor by the given parameter on the z axis. 261 * The actual movement depends also on the turn rate. 262 * 263 * @param dir The quantity of the movement. 264 * @see getPitch 265 * @see getYaw 266 * @see getRoll 267 * @see setRot 268 * @see turnTo 269 * @see isTurning 270 */ 271 void turn(int dir); 272 /** 273 * Returns the pitch of the actor, which is the rotation 274 * on the x axis. 275 * 276 * @see getYaw 277 * @see getRoll 278 * @see setRot 279 * @see turnTo 280 * @see isTurning 281 */ getPitch()282 Math::Angle getPitch() const { return _pitch; } 283 /** 284 * Returns the yaw of the actor, which is the rotation 285 * on the z axis. 286 * 287 * @see getPitch 288 * @see getRoll 289 * @see setRot 290 * @see turnTo 291 * @see isTurning 292 */ getYaw()293 Math::Angle getYaw() const { return _yaw; } 294 /** 295 * Returns the roll of the actor, which is the rotation 296 * on the y axis. 297 * 298 * @see getPitch 299 * @see getYaw 300 * @see setRot 301 * @see turnTo 302 * @see isTurning 303 */ getRoll()304 Math::Angle getRoll() const { return _roll; } 305 306 /** 307 * Calculates and returns the angle between the direction the 308 * actor is facing and the direction towards another actor. 309 * 310 * @param actor The actor to look at. 311 */ 312 Math::Angle getYawTo(const Actor *actor) const; 313 /** 314 * Calculates and returns the angle between the direction the 315 * actor is facing and the direction towards a point. 316 * 317 * @param actor The point to look at. 318 */ 319 Math::Angle getYawTo(const Math::Vector3d &p) const; 320 321 /** 322 * Sets the actor visibility. 323 * 324 * @param val The value: true if visible, false otherwise. 325 * @see isVisible 326 */ setVisibility(bool val)327 void setVisibility(bool val) { _visible = val; } 328 /** 329 * Returns true if the actor is visible. 330 * 331 * @see setVisibility 332 */ isVisible()333 bool isVisible() const { return _visible; } 334 335 /** 336 * Sets the scale of the actor. 337 * A value of 1 is the natural size. 338 * 339 * @param scale The scale of the actor. 340 */ setScale(float scale)341 void setScale(float scale) { _scale = scale; } getScale()342 float getScale() const { return _scale; } 343 344 /** 345 * Sets the time scale of the actor, used to calculate the 346 * speed of its animations. 347 * A value of 1 is the normal speed. 348 * 349 * @param scale The time scale. 350 * @see getTimeScale 351 */ setTimeScale(float scale)352 void setTimeScale(float scale) { _timeScale = scale; } 353 /** 354 * Returns the time scale of the actor. 355 * 356 * @see setTimeScale 357 */ getTimeScale()358 float getTimeScale() const { return _timeScale; } 359 360 /** 361 * Puts the actor in a set. 362 * 363 * @param setName The name of the set. 364 */ 365 void putInSet(const Common::String &setName); 366 /** 367 * Returns true if the actor is in the given set. 368 * For engine internal use only, do not expose via lua API. 369 * 370 * @param setName The name of the set. 371 */ 372 bool isDrawableInSet(const Common::String &setName) const; 373 /** 374 * Returns true if the actor is in the given set. 375 * Can be exposed via lua API. 376 * 377 * @param setName The name of the set. 378 */ 379 bool isInSet(const Common::String &setName) const; 380 381 /** 382 * Sets the rate of the turning. 383 * 384 * @param rat The wanted rate. 385 * @see getTurnRate 386 */ setTurnRate(float rate)387 void setTurnRate(float rate) { _turnRate = rate; } 388 /** 389 * Returns the turn rate. 390 * 391 * @see setTurnRate 392 */ getTurnRate()393 float getTurnRate() const { return _turnRate; } 394 /** 395 * Sets the rate of the walk movement. 396 * 397 * @param rate The wanted rate. 398 * @see getWalkRate 399 */ setWalkRate(float rate)400 void setWalkRate(float rate) { _walkRate = rate; } 401 /** 402 * Returns the walk rate of the actor. 403 * 404 * @see setWalkRate 405 */ getWalkRate()406 float getWalkRate() const { return _walkRate; } 407 setLooking(bool lookingMode)408 void setLooking(bool lookingMode) { _lookingMode = lookingMode; } 409 410 /** 411 * Makes the actor move forward, the lenght of the movement based 412 * on the walk rate. 413 * If it is following boxes it will not go into not walkable areas. 414 * 415 * @see walkTo 416 */ 417 void walkForward(); 418 void moveTo(const Math::Vector3d &pos); 419 /** 420 * Used to tell the actor if it is running or not. 421 * 422 * @param running The value: true if it is running. 423 */ setRunning(bool running)424 void setRunning(bool running) { _running = running; } setReflection(float angle)425 void setReflection(float angle) { _reflectionAngle = angle; } 426 /** 427 * Returns a vector representing the direction the actor 428 * is facing. 429 */ 430 Math::Vector3d getPuckVector() const; 431 432 void setPuckOrient(bool orient); 433 434 /** 435 * Makes the actor say the given line. 436 * It will show a subtitle and/or play the voice, depending 437 * on the speech mode set in the GrimEngine instance. 438 * 439 * @param msgId The id of the message to say. 440 * @param background ?? actual meaning unknown yet. 441 * @see isTalking 442 * @see shutUp 443 */ 444 void sayLine(const char *msgId, bool background, float x, float y); 445 // When we clean all text objects we don't want the actors to clean their 446 // objects again since they're already freed 447 void lineCleanup(); 448 /** 449 * Makes the actor discard any subtitle and voice. 450 * 451 * @see sayLine 452 * @see isTalking 453 */ 454 void shutUp(); 455 /** 456 * Returns true if the actor is saying something. 457 * 458 * @see sayLine 459 * @see shutUp 460 */ 461 bool isTalking(); 462 463 void setRestChore(int choreNumber, Costume *cost); 464 int getRestChore() const; 465 void setWalkChore(int choreNumber, Costume *cost); 466 void setTurnChores(int left_chore, int right_chore, Costume *cost); 467 void setTalkChore(int index, int choreNumber, Costume *cost); 468 int getTalkChore(int index) const; 469 Costume *getTalkCostume(int index) const; 470 void setMumbleChore(int choreNumber, Costume *cost); 471 void stopAllChores(bool ignoreLoopingChores = false); 472 void setColormap(const char *map); 473 void pushCostume(const char *name); 474 void setCostume(const char *name); 475 void popCostume(); 476 void clearCostumes(); 477 Costume *getCurrentCostume() const; 478 void setLocalAlphaMode(unsigned int vertex, AlphaMode alphamode); 479 void setLocalAlpha(unsigned int vertex, float alpha); 480 bool hasLocalAlpha() const; 481 float getLocalAlpha(unsigned int vertex) const; 482 Costume *findCostume(const Common::String &name); getCostumeStackDepth()483 int getCostumeStackDepth() const { 484 return _costumeStack.size(); 485 } getCostumes()486 const Common::List<Costume *> &getCostumes() const { return _costumeStack; } 487 488 void setActiveShadow(int shadowId); 489 void setShadowPoint(const Math::Vector3d &pos); 490 void setShadowColor(const Color &color); 491 void setShadowPlane(const char *name); 492 void addShadowPlane(const char *name); 493 void clearShadowPlanes(); 494 void clearShadowPlane(int i); 495 void setShadowValid(int); 496 void setActivateShadow(int, bool); 497 498 void setFollowBoxes(bool follow); hasFollowedBoxes()499 bool hasFollowedBoxes() const { return _hasFollowedBoxes; } 500 void update(uint frameTime); 501 /** 502 * Check if the actor is still talking. If it is returns true, otherwise false. 503 */ 504 bool updateTalk(uint frameTime); 505 void draw(); 506 isLookAtVectorZero()507 bool isLookAtVectorZero() { 508 return _lookAtVector.isZero(); 509 } setLookAtVectorZero()510 void setLookAtVectorZero() { 511 _lookAtVector.set(0.f, 0.f, 0.f); 512 _lookAtActor = 0; 513 } setLookAtVector(const Math::Vector3d & vector)514 void setLookAtVector(const Math::Vector3d &vector) { 515 _lookAtVector = vector; 516 _lookAtActor = 0; 517 } getLookAtVector()518 Math::Vector3d getLookAtVector() { 519 return _lookAtVector; 520 } setLookAtActor(Actor * other)521 void setLookAtActor(Actor *other) { _lookAtActor = other->getId(); } 522 void setLookAtRate(float rate); 523 float getLookAtRate() const; 524 void setHead(int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw); 525 void setHead(const char *joint, const Math::Vector3d &offset); 526 void setHeadLimits(float yawRange, float maxPitch, float minPitch); 527 528 void setCollisionMode(CollisionMode mode); 529 void setCollisionScale(float scale); 530 531 bool handleCollisionWith(Actor *actor, CollisionMode mode, Math::Vector3d *vec) const; 532 533 static void saveStaticState(SaveGame *state); 534 static void restoreStaticState(SaveGame *state); 535 isAttached()536 bool isAttached() const { return _attachedActor != 0; } 537 Math::Vector3d getWorldPos() const; 538 void attachToActor(Actor *other, const char *joint); 539 void detach(); 540 Math::Quaternion getRotationQuat() const; 541 const Math::Matrix4 getFinalMatrix() const; 542 Math::Vector3d getHeadPos() const; 543 setInOverworld(bool inOverworld)544 void setInOverworld(bool inOverworld) { _inOverworld = inOverworld; } isInOverworld()545 bool isInOverworld() const { return _inOverworld; } 546 getGlobalAlpha()547 float getGlobalAlpha() const { return _globalAlpha; } getAlphaMode()548 AlphaMode getAlphaMode() const { return _alphaMode; } getEffectiveAlpha()549 float getEffectiveAlpha() const { return _alphaMode != AlphaOff ? _globalAlpha : 1.f; } 550 void setGlobalAlpha(float alpha, const Common::String &mesh); 551 void setAlphaMode(AlphaMode mode, const Common::String &mesh); 552 553 int getSortOrder() const; 554 void setSortOrder(const int order); 555 int getEffectiveSortOrder() const; 556 557 void activateShadow(bool active, const char *shadowName); 558 void activateShadow(bool active, SetShadow *shadow); 559 560 void drawToCleanBuffer(); 561 562 bool isTalkingForeground() const; 563 getLightMode()564 LightMode getLightMode() const { return _lightMode; } setLightMode(LightMode lightMode)565 void setLightMode(LightMode lightMode) { _lightMode = lightMode; } 566 567 ObjectPtr<Material> loadMaterial(const Common::String &name, bool clamp); 568 ObjectPtr<Material> findMaterial(const Common::String &name); 569 570 void getBBoxInfo(Math::Vector3d &bboxPos, Math::Vector3d &bboxSize) const; 571 572 private: 573 void costumeMarkerCallback(int marker); 574 void collisionHandlerCallback(Actor *other) const; 575 void updateWalk(); 576 void addShadowPlane(const char *n, Set *scene, int shadowId); 577 bool shouldDrawShadow(int shadowId); 578 void stopTalking(); 579 bool stopMumbleChore(); 580 void drawCostume(Costume *costume); 581 /** 582 * Given a start point and a destination this function returns a position 583 * that doesn't collide with any actor. 584 */ 585 Math::Vector3d handleCollisionTo(const Math::Vector3d &from, const Math::Vector3d &pos) const; 586 /** 587 * Check if the line from pos to dest collides with this actor's bounding 588 * box, and if yes return a point that, together with pos, defines a line 589 * tangent with the bounding box. 590 */ 591 Math::Vector3d getTangentPos(const Math::Vector3d &pos, const Math::Vector3d &dest) const; 592 593 Math::Vector3d getSimplePuckVector() const; 594 void calculateOrientation(const Math::Vector3d &pos, Math::Angle *pitch, Math::Angle *yaw, Math::Angle *roll); 595 596 bool getSphereInfo(bool adjustZ, float &size, Math::Vector3d &pos) const; 597 EMIModel *findModelWithMesh(const Common::String &mesh); 598 599 Common::String _name; 600 Common::String _setName; // The actual current set 601 602 Color _talkColor; 603 Math::Vector3d _pos; 604 Math::Angle _pitch, _yaw, _roll; 605 float _walkRate, _turnRate; 606 607 bool _followBoxes; // Constrain to walkboxes 608 bool _hasFollowedBoxes; 609 float _reflectionAngle; // Maximum angle to turn by at walls 610 bool _visible; 611 float _scale; 612 float _timeScale; 613 bool _lookingMode; 614 Common::String _talkSoundName; 615 bool _talking; 616 bool _backgroundTalk; 617 ObjectPtr<LipSync> _lipSync; 618 Common::List<Costume *> _costumeStack; 619 620 // Variables for gradual turning 621 bool _turning; 622 bool _singleTurning; 623 // NOTE: The movement direction is separate from the direction 624 // the actor's model is facing. The model's direction is gradually 625 // updated to match the movement direction. This produces a smooth 626 // turning animation while still allowing the actor to move in a 627 // new direction immediately after reflecting off a wall. 628 Math::Angle _moveYaw; 629 Math::Angle _movePitch; 630 Math::Angle _moveRoll; 631 // This is used to increase momentarily the turn rate when needed 632 float _turnRateMultiplier; 633 634 // Variables for walking to a point 635 bool _walking; 636 Math::Vector3d _destPos; 637 638 //chores 639 class ActionChore { 640 public: 641 ActionChore(); 642 ActionChore(Costume *cost, int chore); 643 644 void play(bool fade = false, unsigned int time = fadeTime); 645 void playLooping(bool fade = false, unsigned int time = fadeTime); 646 void stop(bool fade = false, unsigned int time = fadeTime); 647 void setLastFrame(); 648 isValid()649 inline bool isValid() const { return _chore > -1 && _costume != nullptr; } 650 bool isPlaying() const; equals(const Costume * cost,int chore)651 inline bool equals(const Costume *cost, int chore) const { 652 return (_costume == cost && _chore == chore); 653 } 654 655 void saveState(SaveGame *state) const; 656 void restoreState(SaveGame *state, Actor *actor); 657 658 Costume *_costume; 659 int _chore; 660 661 static const unsigned int fadeTime; 662 static const unsigned int talkFadeTime; 663 }; 664 ActionChore _restChore; 665 666 ActionChore _walkChore; 667 bool _walkedLast, _walkedCur; 668 bool _running; 669 670 ActionChore _leftTurnChore, _rightTurnChore; 671 int _lastTurnDir, _currTurnDir; 672 673 ActionChore _talkChore[10]; 674 int _talkAnim; 675 676 ActionChore _mumbleChore; 677 678 Shadow *_shadowArray; 679 int _activeShadowSlot; 680 681 static ObjectPtr<Font> _sayLineFont; 682 int _sayLineText; 683 bool _mustPlaceText; 684 getTurnChore(int dir)685 ActionChore *getTurnChore(int dir) { 686 return (dir > 0 ? &_leftTurnChore : &_rightTurnChore); 687 } 688 689 void freeCostume(Costume *costume); 690 void freeCostumeChore(const Costume *toFree, ActionChore *chore); 691 692 // lookAt 693 Math::Vector3d _lookAtVector; 694 695 // struct used for path finding 696 struct PathNode { 697 Sector *sect; 698 PathNode *parent; 699 Math::Vector3d pos; 700 float dist; 701 float cost; 702 }; 703 Common::List<Math::Vector3d> _path; 704 705 CollisionMode _collisionMode; 706 float _collisionScale; 707 708 bool _puckOrient; 709 710 static bool _isTalkingBackground; 711 int _talkDelay; 712 int _attachedActor; 713 int _lookAtActor; 714 Common::String _attachedJoint; 715 AlphaMode _alphaMode; 716 float _globalAlpha; 717 718 bool _inOverworld; 719 720 int _sortOrder; 721 int _sectorSortOrder; 722 bool _useParentSortOrder; 723 724 bool _fakeUnbound; 725 bool _drawnToClean; 726 727 LightMode _lightMode; 728 729 Common::List<ObjectPtr<Material> > _materials; 730 731 // Highest vertex used in EMI 732 const static unsigned int MAX_LOCAL_ALPHA_VERTICES = 48; 733 Common::Array<float> _localAlpha; 734 Common::Array<int> _localAlphaMode; 735 }; 736 737 } // end of namespace Grim 738 739 #endif 740