blob: 28247b6b6c29b296039518d1020f585b8cb80be7 [file] [log] [blame]
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef NimaActor_DEFINED
#define NimaActor_DEFINED
#include <nima/Actor.hpp>
#include <nima/ActorImage.hpp>
#include <nima/Vec2D.hpp>
#include "SkCanvas.h"
#include "SkData.h"
#include "SkImage.h"
#include <string>
class NimaActor;
class NimaActorImage;
enum RenderFlags {
kImmediate_RenderFlag = 0x1,
kCache_RenderFlag = 0x2,
kBounds_RenderFlag = 0x4,
};
/** \class NimaActor
NimaActor acts as a breidge between Skia and a nima::Actor object.
The Actor object essentially is a set of bones and textures.
NimaActor knows how to draw itself (the Actor) to an SkCanvas
at various time stamps.
NimaActor is also aware of the different animation types the
Actor has and coordinates switching between them. For example,
an animation might have an "idle" and a "jump" animation it can
switch between.
*/
class NimaActor : public nima::Actor {
public:
NimaActor(std::string nimaPath, std::string texturePath);
NimaActor(sk_sp<SkData> nimaBytes, sk_sp<SkData> textureBytes);
~NimaActor() = default;
/**
* Render draws itself to the given canvas, at whatever
* the current time position is (see seek).
*/
void render(SkCanvas* canvas, uint32_t renderFlags = 0);
/**
* Updates the animation state to be at time t.
* This does not re-draw anything, another call to render() is required.
*
* @param t - number of second in (modulo total duration)
*
*/
void seek(SkScalar t);
/**
* Returns the duration of the current Actor's animation in seconds.
*/
SkScalar duration() const;
/**
* Sets the animation type based on the index given. The default
* animation index is 0. If index is invalid, nothing changes.
*/
void setAnimation(uint8_t index);
/**
* Sets the animation type to be one that matches the provided
* name. If the name does not match any of the existing animation
* types, nothing changes.
*/
void setAnimation(std::string name);
/**
* Returns all possible animation names. Use with setAnimation().
*/
const std::vector<std::string>& getAnimationNames() const {
return fAnimationNames;
}
private:
void init();
sk_sp<SkImage> fTexture;
std::vector<NimaActorImage> fActorImages;
std::unique_ptr<SkPaint> fPaint;
std::vector<std::string> fAnimationNames;
nima::ActorAnimationInstance* fAnimationInstance;
uint8_t fAnimationIndex;
typedef nima::Actor INHERITED;
};
// A wrapper class that handles rendering of ActorImages (renderable components NIMA Actors).
class NimaActorImage {
public:
NimaActorImage(nima::ActorImage* actorImage, SkImage* texture, SkPaint* paint);
~NimaActorImage() = default;
void render(SkCanvas* canvas, uint32_t renderFlags);
int drawOrder() const { return fActorImage->drawOrder(); }
private:
nima::ActorImage* fActorImage;
SkImage* fTexture;
SkPaint* fPaint;
bool fSkinned;
std::vector<SkPoint> fPositions;
std::vector<SkPoint> fTexs;
std::vector<SkVertices::BoneIndices> fBoneIdx;
std::vector<SkVertices::BoneWeights> fBoneWgt;
std::vector<uint16_t> fIndices;
std::vector<SkVertices::Bone> fBones;
sk_sp<SkVertices> fVertices;
uint32_t fRenderFlags;
void updateVertices(bool isVolatile);
void updateBones();
void drawVerticesObject(SkVertices* vertices, SkCanvas* canvas, bool useBones) const;
};
#endif