/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
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 .
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plMorphSequence_inc
#define plMorphSequence_inc
#include "../pnModifier/plSingleModifier.h"
#include "plMorphArray.h"
class plDrawable;
class plDrawInterface;
class plSharedMesh;
class plMorphSequenceSDLMod;
class plMorphArrayWeights
{
public:
hsTArray fDeltaWeights;
};
class plSharedMeshInfo
{
public:
enum
{
kInfoDirtyMesh = 0x1
};
plSharedMesh* fMesh;
hsTArray fCurrIdx;
plDrawable* fCurrDraw;
hsTArray fArrayWeights;
UInt8 fFlags;
plSharedMeshInfo() : fMesh(nil), fCurrDraw(nil), fFlags(0) {}
};
// Keyed storage class for morph arrays/deltas
// supply your own weights.
class plMorphDataSet : public hsKeyedObject
{
public:
hsTArray fMorphs;
CLASSNAME_REGISTER( plMorphDataSet );
GETINTERFACE_ANY( plMorphDataSet, hsKeyedObject );
virtual void Read(hsStream* s, hsResMgr* mgr);
virtual void Write(hsStream* s, hsResMgr* mgr);
};
// A place to hold incoming state while we're still waiting for the
// mesh and morph data to load.
class plMorphState
{
public:
plKey fSharedMeshKey;
hsTArray fArrayWeights;
};
class plMorphSequence : public plSingleModifier
{
friend class plMorphSequenceSDLMod;
protected:
enum
{
kDirty = 0x1,
kHaveSnap = 0x2,
kHaveShared = 0x4,
kDirtyIndices = 0x8
};
UInt32 fMorphFlags;
hsTArray fMorphs;
//Int32 fActiveMesh; // Doesn't appear to be used.
hsTArray fSharedMeshes;
hsTArray fPendingStates;
plMorphSequenceSDLMod* fMorphSDLMod;
Int8 fGlobalLayerRef;
const plDrawInterface* IGetDrawInterface() const;
virtual hsBool IEval(double secs, hsScalar del, UInt32 dirty) { return false; }
void ISetHaveSnap(hsBool on) { if(on)fMorphFlags |= kHaveSnap; else fMorphFlags &= ~kHaveSnap; }
void ISetDirty(hsBool on);
hsBool IResetShared(int iShare);
void IApplyShared(int iShare);
hsBool IFindIndices(int iShare);
void IReleaseIndices(int iShare);
void IRenormalize(hsTArray& dst) const;
void IResetShared();
void IReleaseIndices(); // Puts everyone inactive
void IFindIndices(); // Refresh Indicies
void IApplyShared(); // Apply whatever morphs are active
Int32 IFindPendingStateIndex(plKey meshKey) const; // Do we have pending state for this mesh?
Int32 IFindSharedMeshIndex(plKey meshKey) const; // What's this mesh's index in our array?
hsBool IIsUsingDrawable(plDrawable *draw); // Are we actively looking at spans in this drawable?
// Internal functions for maintaining that all meshes share the same global weight(s) (fGlobalLayerRef)
void ISetAllSharedToGlobal();
void ISetSingleSharedToGlobal(int idx);
public:
plMorphSequence();
virtual ~plMorphSequence();
CLASSNAME_REGISTER( plMorphSequence );
GETINTERFACE_ANY( plMorphSequence, plSingleModifier );
virtual hsBool MsgReceive(plMessage* msg);
virtual void AddTarget(plSceneObject* so);
virtual void RemoveTarget(plSceneObject* so);
virtual void Read(hsStream* s, hsResMgr* mgr);
virtual void Write(hsStream* s, hsResMgr* mgr);
void Init();
void Activate();
void DeInit();
void DeActivate();
void Apply() const;
void Reset(const plDrawInterface* di=nil) const;
int GetNumLayers(plKey meshKey = nil) const;
void AddLayer(const plMorphArray& ma) { fMorphs.Append(ma); }
int GetNumDeltas(int iLay, plKey meshKey = nil) const;
hsScalar GetWeight(int iLay, int iDel, plKey meshKey = nil) const;
void SetWeight(int iLay, int iDel, hsScalar w, plKey meshKey = nil);
hsBool GetHaveSnap() const { return 0 != (fMorphFlags & kHaveSnap); }
hsBool GetDirty() const { return 0 != (fMorphFlags & kDirty); }
hsBool GetUseSharedMesh() const { return 0 != (fMorphFlags & kHaveShared); }
void SetUseSharedMesh(hsBool on) { if(on)fMorphFlags |= kHaveShared; else fMorphFlags &= ~kHaveShared; }
void AddSharedMesh(plSharedMesh* mesh);
void RemoveSharedMesh(plSharedMesh* mesh);
static void FindMorphMods(const plSceneObject *so, hsTArray &mods);
plMorphSequenceSDLMod *GetSDLMod() const { return fMorphSDLMod; }
};
#endif // plMorphSequence_inc