/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see .
*
*/
#ifndef TWP_SCENEGRAPH_H
#define TWP_SCENEGRAPH_H
#include "common/array.h"
#include "common/str.h"
#include "math/vector2d.h"
#include "math/matrix4.h"
#include "twp/gfx.h"
#include "twp/rectf.h"
#include "twp/font.h"
#include "twp/spritesheet.h"
#define NUMOBJECTS 8
namespace Twp {
class Motor;
// Represents a node in a scene graph.
class Node {
public:
Node(const Common::String &name, const Math::Vector2d &scale = Math::Vector2d(1, 1), const Color &color = Color());
virtual ~Node();
void setName(const Common::String &name) { _name = name; }
const Common::String &getName() const { return _name; }
virtual void setVisible(bool visible) { _visible = visible; }
bool isVisible() const { return _visible; }
// Adds new child in current node.
//
// Arguments:
// - `child`: child node to add.
void addChild(Node *child);
void removeChild(Node *node);
void clear();
// Removes this node from its parent.
void remove();
const Common::Array &getChildren() const { return _children; }
Node *getParent() const { return _parent; }
const Node *getRoot() const;
// Finds a node in its children and returns its position.
int find(Node *other);
// Gets the local position for this node (relative to its parent)
void setPos(const Math::Vector2d &pos) { _pos = pos; }
Math::Vector2d getPos() const { return _pos; }
void setOffset(const Math::Vector2d &offset) { _offset = offset; }
Math::Vector2d getOffset() const { return _offset; }
void setShakeOffset(const Math::Vector2d &offset) { _shakeOffset = offset; }
Math::Vector2d getShakeOffset() const { return _shakeOffset; }
void setRenderOffset(const Math::Vector2d &offset) { _renderOffset = offset; }
Math::Vector2d getRenderOffset() const { return _renderOffset; }
void setScale(const Math::Vector2d &scale) { _scale = scale; }
virtual Math::Vector2d getScale() const { return _scale; }
// Gets the absolute position for this node.
Math::Vector2d getAbsPos() const;
// Gets the full transformation for this node.
virtual Math::Matrix4 getTrsf(const Math::Matrix4 &parentTrsf);
void setColor(const Color &color);
Color getColor() const { return _color; }
Color getComputedColor() const { return _computedColor; }
void setAlpha(float alpha);
float getAlpha() const { return _color.rgba.a; }
void setZSort(int zsort) { _zOrder = zsort; }
virtual int getZSort() const { return _zOrder; }
void setRotation(float rotation) { _rotation = rotation; }
float getRotation() const { return _rotation; }
void setRotationOffset(float rotationOffset) { _rotationOffset = rotationOffset; }
float getRotationOffset() const { return _rotationOffset; }
void setAnchor(const Math::Vector2d &anchor);
void setAnchorNorm(const Math::Vector2d &anchorNorm);
void setSize(const Math::Vector2d &size);
Math::Vector2d getSize() const { return _size; }
virtual Rectf getRect() const;
void draw(const Math::Matrix4 &parent = Math::Matrix4());
protected:
virtual void onDrawChildren(const Math::Matrix4 &trsf);
virtual void onColorUpdated(const Color &c) {}
virtual void drawCore(const Math::Matrix4 &trsf) {}
private:
// Gets the location transformation = translation * rotation * scale.
Math::Matrix4 getLocalTrsf();
void updateColor();
void updateColor(const Color &parentColor);
void updateAlpha();
void updateAlpha(float parentAlpha);
protected:
Common::String _name;
Math::Vector2d _pos;
int _zOrder = 0;
Node *_parent = nullptr;
Common::Array _children;
Math::Vector2d _offset, _shakeOffset, _renderOffset, _anchor, _anchorNorm, _scale, _size;
Color _color, _computedColor;
bool _visible = true;
float _rotation = 0.f;
float _rotationOffset = 0.f;
};
class ParallaxNode final : public Node {
public:
ParallaxNode(const Math::Vector2d ¶llax, const Common::String &sheet, const Common::StringArray &frames);
virtual ~ParallaxNode();
Math::Matrix4 getTrsf(const Math::Matrix4 &parentTrsf) override final;
protected:
void onDrawChildren(const Math::Matrix4 &trsf) override;
void drawCore(const Math::Matrix4 &trsf) override final;
private:
Math::Vector2d _parallax;
Common::String _sheet;
Common::StringArray _frames;
};
struct ObjectAnimation;
class Object;
class Anim : public Node {
public:
Anim(Object *obj);
void clearFrames();
void setAnim(const ObjectAnimation *anim, float fps = 0.f, bool loop = false, bool instant = false);
void update(float elapsed);
void disable() { _disabled = true; }
void trigSound();
private:
virtual void drawCore(const Math::Matrix4 &trsf) override final;
public:
const ObjectAnimation *_anim = nullptr;
bool _disabled = false;
private:
Common::String _sheet;
Common::Array _frames;
size_t _frameIndex = 0;
float _elapsed = 0.f;
float _frameDuration = 0.f;
bool _loop = false;
bool _instant = false;
Object *_obj = nullptr;
Common::Array > _anims;
};
class ActorNode final : public Node {
public:
ActorNode(Common::SharedPtr