Crapell游戏引擎设计简介
可以将整个或部分max场景导出到单一文件,也可导出到单独文件。包含关键帧动画、uv动画、粒子动画、骨骼动画、顶点动画导出插件。c++ opengl 、d3d9两种渲染方式。avi贴图,粒子特效(灵活的发射器和粒子形状,路径,模型附着,模型发射,碰撞板),lod及变形修改器。后期延迟渲染可以对ui和场景使用独立的渲染通道。shader选择了cg(实现了一些例子:水纹,特效扭曲, hdr,流体雾,体积光,shdowmap阴影,motion blur),可以方便扩充到和glsl和hlsl。
uv动画建议使用uvXform修改器。骨骼动画可以用biped或基本骨骼。顶点动画可以直接修改或使用melt融化修改器等。新加入了布料动画,可以给布料刚性点设置关键帧或将其绑定到人物骨骼。
MovieClip是一切模型的基类,派生出MC_Frame、MC_Partile、MC_Skeleton、MC_Vertex、MC_Light、MC_Camera、MC_Cloth、MC_Billboard、MC_Strip。分别负责关键帧动画、粒子动画、骨骼动画、顶点动画、灯光动画、视野动画、布料动画、公告板动画、尾光动画。
//========================================================
/**
* Brief: MovieClip RendCore
* Author: LouLei
* Email: [email protected]
*
* Get what you see in 3dsmax.
* MovieClip tween morph:pos,scale,rot,alpha,material,skinbones.
* MovieClip self morph:texture,vertex.
* export patricle(super spray), light
* key mouse event:press click drag...
* Dynamic 3d mask: draw the point only if it is in the dumy_mask_mesh movieclip.
* implete like shadow volume stensil buf generation.
* Collide:collide with tray or tray box,this can be useful on movable zone.
* rts collide base on cells,fps collide base on mesh.Use tree space partion.
* Navigation graph:
* Refrence instance: use dumy for export dumplicate instance in max.
* refrence instance in c++,a ref mesh or ref movieclip.
* Reattach:texture,mesh,bone or keys.
*/
//========================================================
/*
#ifndef MovieClip_H
#define MovieClip_H
#include "Render/Texture.h"
#include "Render/Particle.h"
#include
#include
#include "General/ScriptMgr.h"
#include "General/ResPtr.h"
#include "General/Thread.h"
#include "General/String.h"
class MeshOcTree;
class MeshBspTree;
class VertexBuffer;
class IndexBuffer;
class CallBacks;
class Light;
class SoftObject;
namespace RendSys
{
class Mesh;
class MovieClip;
class Skeleton;
class FrameLine;
typedef ResPtr MeshPtr;
typedef ResPtr MovieClipPtr;
typedef ResPtr SkeletonPtr;
typedef ResPtr FrameLinePtr;
#define G_MeshMgr (MeshMgr::GetSingleton())
#define G_MovieClipMgr (MovieClipMgr::GetSingleton())
#define G_SkeletonMgr (SkeletonMgr::GetSingleton())
struct RayMovieCollideRes:public RayCollideRes
{
RayMovieCollideRes(vec3& vStart_,vec3& vEnd_);
RayMovieCollideRes();
MovieClip* lastclip;
};
class CollideAABBox
{
public:
CollideAABBox();
virtual void CalBound(){}
void Indentity();
void Merge( const vec3& point );
bool Intersect(vec3& v);
bool TraceRay(vec3& vStart, vec3& vEnd,vec3& res);
//vec3 TraceSphere(vec3& vStart, vec3& vEnd, float radius)
//vec3 TraceBox(vec3& vStart, vec3& vEnd, vec3& vMin, vec3& vMax)
void RendBox();
//protected:
vec3 m_min;
vec3 m_max;
vec3 m_center;
float m_radius;
};
enum COORDSYS
{
COORD_NONE = 0,
COORD_3DMAX,
COORD_OGL,
COORD_MAYA,
COORD_D3D,
};
#define AccordantVertexUtil
#define AccordantVertexUtil
//construct fun of Vertex make new Vertex[] slow down
//deconstruct fun make delete Vertex[] slow down
//member fun has no effect
class Mesh
{
public:
struct Vertex
{
//Vertex();
float x, y, z;
//float u, v, w;
float nx, ny, nz;
};
struct TVertex
{
//TVertex();
float u, v, w;
};
//struct NVertex
//{
// float nx, ny, nz;
//};
struct BoneWeight
{
//BoneWeight();
int boneId;
//String boneName;//canot memcpy Vertex,and load slow
//char boneName[]; //cost mem but exact than id
float weight;
float x, y, z;
float nx, ny, nz;
};
struct VertexWeight
{
//VertexWeight();
int boneNum;
//BoneWeight* boneWeight;//canot memcpy Vertex,and load slow need operator=
std::vector boneWeight;//canot memcpy Vertex too
//BoneWeight boneWeight[8]; //memory more?
void Free();
};
struct Trigon
{
//Trigon();
int vIndex[3];
};
#ifdef AccordantVertexUtil
struct TrigonAccordant
{
//TrigonAccordant();
int tIndex[3];
};
#endif
Mesh();
virtual ~Mesh(){Free();}
virtual void Free();
void Render();
void EditRender();
void RenderOutline();
bool LoadMesh(File& filein);
bool SaveMesh(File& fileout);
bool LoadSingleMovieMeshWeight(File& filein);
bool SaveSingleMovieMeshWeight(File& fileout);
void CoordConvert(COORDSYS totype);
void LoadedProcess(bool genAABB,bool genBuff,bool accordant);
#ifdef AccordantVertexUtil
void AccordantVertex();
#endif
/*virtual */void CalBound();
bool TraceRay(RayCollideRes& res);
void Expand(int vVertexNum,int tVertexNum,int trigonNum);
//质心正方包围盒
void GetMassCube(vec3& outCenter,vec3& outExtent);
void GetBoundCube(vec3& outCenter,vec3& outExtent);
void CreateBuff();
void BuildTree();
int m_trigonNum;
int m_vVertexNum;
int m_tVertexNum;
Vertex* m_vVertexs;
TVertex* m_tVertexs;
Trigon* m_trigons;
#ifdef AccordantVertexUtil
TrigonAccordant* m_accordantTrigons;
#endif
VertexWeight* m_vertexWeights;
VertexWeight (*m_debugVertexWeights)[5000];
CollideAABBox m_collideAABBox;
COORDSYS m_coordSys;
VertexBuffer* m_verterBuffer;
VertexBuffer* m_tVerterBuffer0;
VertexBuffer* m_tVerterBuffer1;
VertexBuffer* m_tVerterBuffer2;
VertexBuffer* m_tVerterBuffer3;
IndexBuffer* m_indexBuffer;
MeshOcTree* m_octree;
MeshBspTree* m_bsptree;
bool m_genAABB;
bool m_gpuAdvance;
};
class MixMesh:public Mesh
{
public:
enum MeshCloneType
{
MCT_NULL = 0,
MCT_VERTEX = 1,
MCT_TRIGION = 1<<1,
};
MixMesh();
~MixMesh();
void CloneFrom(Mesh* mesh,MeshCloneType type = MCT_VERTEX);
//const MixMesh& operator= (/*const*/ MixMesh& other);
virtual void Free();
bool TraceRay(vec3& vStart, vec3& vEnd,vec3& respos,vec3& resnorml);
void MapVertexBuffer();
MeshPtr m_srcMesh ;
//Mesh::Vertex* m_mixVertexs;
Mesh::Vertex (*m_debugMixVertexs)[5000];
MeshCloneType m_cloneType;
//VertexBuffer* m_verterBuffer;
//IndexBuffer* m_indexBuffer;
};
//product hair
//class Modifier
//{
//};
//now just one modifier
class ModifierSys
{
public:
enum ModifierType
{
MT_NONE = 0,
MT_TWIST,
MT_WAVE,
MT_SPRING,
MT_LOD,
MT_NUM
};
ModifierType m_mdType;
ModifierSys()
:m_movie(NULL)
,angleDegMax(90.0f)
,m_mdType(MT_NONE)
{}
void SetSrcMovie(MovieClip* movie) { m_movie = movie;}
void DoModify(float time);
void SetModifyType(ModifierType type){m_mdType = type;}
void SetTwistMaxAngle(float angle) { angleDegMax = angle; }
private:
void DoTwist(float time);
void DoWave(float time);
void DoSpring(float time);
void DoLod(float lodPersent);
MovieClip* m_movie;
float angleDegMax;
};
//real time shadow 最多八盏灯
class VolumeShadowSys
{
public:
VolumeShadowSys();
VolumeShadowSys(VolumeShadowSys& other) { *this = other;};
const VolumeShadowSys& operator= (const VolumeShadowSys& other);
// length of shadow volume
#define INFINITY 100
// ax + by + cz + d = 0
struct Plane
{
float a,b,c,d;
};
struct ShadowTrigon
{
Plane plane;
// neighbor face index which have a same edge
unsigned int neighbor[3];
// is facing the light
BOOL bVisible;
};
ShadowTrigon* m_pPlanes;
Mesh* m_mesh;
void Free();
void SetMesh(Mesh* mesh);
//call CalConnectivity() when init to find the neighbors of all the faces,
//call CalPlane() when the points of the mesh dynamic change
void CalConnectivity();
void CalPlane();
void DrawShadowVolume(float lp[]);
//mul to transform the vector
static void vMatMult(float M[], float v[]);
//gen after the terrain rended
void GenShadowStencil(float lp[]);
static void RenderShadow();
};
class Frame
{
public:
enum InterType
{
Inter,
Smooth,
Bezier,
};
Frame();
int m_time;
vec3 m_pos;
vec3 m_scale;
vec3 m_rot;
quat m_quat;
mat4 m_matrix;
float __declspec(align(16)) m_matrixSIMD[16];
float m_uOffset;
float m_vOffset;
float m_uTile;
float m_vTile;
bool m_visible;
Color m_color;
InterType m_interType;
//vertex anim
Mesh* m_mesh;
//shader Material
//modifier
//reactor
//Frame& operator=(Frame& rhs);
//MatrixF* setMatrix( MatrixF * mat ) const;
void Format(char* buf);
void EditRender();
void CoordConvert(COORDSYS totype);
void CalQuatMatrixFromRot();
void CalFromMatrix();
void SetPos(vec3& pos);
static void Slerp(Frame* befter,Frame* after,float beforefactor,Frame* res);
static void Muti(Frame& parent,Frame& sub,Frame& res);
COORDSYS m_coordSys;
};
//frameLine of mc maybe just a pointer to another mc
class FrameLine
{
public:
FrameLine();
virtual ~FrameLine();
void Free();
//be able to share with ohers
void GenMixFrame(Frame& frame,float time,bool bInterplate = true);
bool LoadSingleMovieFrame(File& filein);
bool SaveSingleMovieFrame(File& fileout);
bool SaveSingleMovieFrame(File& fileout,const char* space);
void AddFrame(Frame& frame);
void ClearFrame(int frameNum);
const char* GetFrameName();
int GetFrameNum();
float GetMaxTime();
//pick and edit
void EditRender();
MovieClip* Intersect(vec3& pos);
void IntersectImp(vec3& pos,MovieClip*& lastclip,float& lastlen);
void CoordConvert(COORDSYS totype);
FrameLine& operator=(FrameLine& other);
void ConvertToRelative();
String m_frameLineName;
Frame* m_frames;
Frame m_firstInverse;
//protected:
int m_frameNum;
Frame (*m_debugFrames)[100];
float m_maxTime;
//script ctrl
class FpsCmdBase
{
public:
enum FpsCmdType
{
GOTOANDSTOP = 0,
GOTOANDPLAY,
REMOVETHIS,
PAUSE,
PLAY,
REPORTEVENT,
//ADDCOMMAND,
};
float time;
FpsCmdType commandType;
void* parm;
virtual void Execute();
};
friend inline bool operator<(const FpsCmdBase& t1, const FpsCmdBase& t2)
{
return (t1.time < t2.time);
}
class PcdCmdSelect:public FpsCmdBase
{
public:
virtual void Execute();
};
class PcdCmdTransform:public FpsCmdBase
{
public:
virtual void Execute();
};
std::list m_cmds;
void Execute();
void AddFpsCmdBase(FpsCmdBase* command);
void Test();
};
class PlayHead
{
public:
PlayHead();
virtual ~PlayHead();
virtual void Advance();
//loop from flag ‘runbegin’to ‘runend’
void SetPlayLoop(int begin,int end);
void SetPause(bool pause);
float GetCurTime();
void SetCurTime(float time);
void ReStart();
virtual void OnFrame(const char* framename);
//protected:
bool m_isLooping;
bool m_isPause;
int m_beginFrame;
int m_endFrame;
float m_curTime;
float m_maxTime;
float m_speed;
bool m_onFrameEnable;
//frame tags
//std::list<>;
};
class FrameHead:public PlayHead
{
public:
FrameHead(MovieClip* owner);
void Advance();
void SetFrameLine(FrameLine* frameLine);
FrameLine* GetFrameLine() const;
void EditRenderMixFrame();
Frame& GetMixFrame();
virtual void OnFrame(const char* framename);
bool GetInterplate() const;
void SetInterplate(bool val);
Frame m_mixFrame;
private:
FrameLine* m_frameLine;
MovieClip* m_owner;
bool m_bInterplate;
};
struct Bone
{
int boneID;
//int parentBoneID;
String boneName;
FrameLine m_frameLine;
//FrameLine m_frameLineRelative;
};
class Skeleton
{
public:
Skeleton();
~Skeleton();
void Free();
bool LoadSingleMovieSkeleton(const char* filename);
bool LoadSingleMovieSkeleton(File& filein);
bool SaveSingleMovieSkeleton(File& fileout);
virtual void CoordConvert(COORDSYS totype);
float GetMaxTime() { return m_maxTime;}
int m_boneNum;
Bone* m_bones;
Bone (*m_debugBones)[100];
//Bone* operator[](int id);
Bone* GetBone(int id);
inline int GetBoneIndex(int id){return m_indexs[id];}
int GetBoneIndex(const char* boneName);
float m_maxTime;
//private:
//fast
std::vector m_indexs;
};
class MixSkeleton:public PlayHead
{
public:
MixSkeleton(MovieClip* owner=NULL);
MixSkeleton(MovieClip* owner,MixSkeleton& bone);
~MixSkeleton();
const MixSkeleton& operator= (/*const*/ MixSkeleton& other);
void Advance();
void Free();
void SetSkeleton(Skeleton* skeleton);
void EditRender();
inline Frame* GetMixFrame(int boneId);
Frame* GetMixFrame(const char* boneName);
virtual void OnFrame(const char* framename);
Frame* m_mixFrameArr;
Frame* m_mixFrameRelativeArr;
Skeleton* m_skeleton;
float m_blendTime;
Skeleton* m_lastSkeleton;
MovieClip* m_owner;
};
/**
* Get what you see in 3dsmax.
* MovieClip tween morph:pos,scale,rot,alpha,material,skinbones.
* MovieClip self morph:texture,vertex.
* key mouse event:press click drag...
* Dynamic 3d mask: draw the point only if it is in it's dumy_mask_mesh movieclip.
* implete as shadow volume stensil buf gen.
* Collide:collide with tray or tray box,this can be useful on movable zone.
* rts collide base on cells,fps collide base on mesh.
* Refrence instance: use dumy for export dumplicate instance in max.
* refrence instance in c++,a ref mesh or ref movieclip.
* Reattach:texture,mesh,bone or keys.
* modify sys: some modifiers.
* procedural sys: create meshs and animations randly.
* call back: frame event call back.
* static mesh 优化 版本升级时格式兼容 分成(string)标记块读写
* save script fun for every obj
*/
typedef std::list MovieClipArr;
typedef std::list::iterator MovieClipIter;
typedef std::list::const_iterator MovieClipConstIter;
class MovieClip:public ScriptObject
{
public:
enum MovieType
{
MT_UNKNOW = 0, //enum_objtype_unknow = 0
MT_FRAMEMOVIE, //enum_objtype_mesh = 1
MT_CAMERA, //enum_objtype_camera = 2
MT_LIGHT, //enum_objtype_light = 3
MT_BONEMESH, //enum_objtype_bonemesh = 4
MT_BONE, //enum_objtype_bone = 5
MT_PARTICLE, //enum_objtype_particle = 6
MT_FRAMEBILLBOARDMOVIE,//enum_objtype_billboardmesh = 7
MT_BONEBILLBOARDMOVIE, //enum_objtype_billboardbonemesh = 8
MT_VERTEXANIMMOVIE, //enum_objtype_vertexanimmesh = 9
MT_STRIPTAIL, //enum_objtype_striptailmesh = 10
MT_BONESTRIPTAIL, //enum_objtype_striptailbonemesh = 11
MT_BONECLOTH, //enum_objtype_boneclothmesh = 12
MT_WITHBONEMOVIE, //enum_objtype_withbonemovie = 13
MT_MASK, //dynamic mask box
MT_INSTANCE,
MT_CONTAINER
};
enum RendOption
{
RO_ALL = 0,
RO_RECEIVESHADOW,
RO_AFTERGENSHADOW,
RO_WATER,
RO_WATERREFLECT,
RO_GenShadowMap,
RO_UseShadowMap,
};
enum CloneType
{
CT_REF = 0,
CT_INSTANCE,
CT_COPY,
CT_NUM
};
MovieClip();
virtual ~MovieClip();
virtual void CalBound();
MovieClip* Intersect(vec3& pos);
//recursive
void IntersectImp(vec3& pos,MovieClip*& lastclip,float& lastlen);
MovieClip* IntersectTray(RayMovieCollideRes& res);
virtual void IntersectTrayImp(RayMovieCollideRes& res);
//dynamic change
void ReAttachMesh(Mesh* mesh);
void ReAttachTexture(const char* textureName);
void ReAttachTexture(Texture* texture);
MovieClip* GetRoot();
MovieClip* GetMovieClip(const char* movieName);
void AddMovieClip(MovieClip* movie);
void RemoveMovieClip(MovieClip* movie,bool free = true);
void StartDrag(bool center);
void StopDrag ();
bool LoadMovieFromFile(const char* fileName,bool genAABB=false,bool genBuff=true);
virtual void FreeMovie();
virtual void Advance();
virtual void AdvanceThread();
virtual void RendClip(int option=RO_ALL);
virtual void GenShadow();
//pick edit and debug
virtual void EditRender();;
void RendTransArrow(vec3& pos);
//protected:
virtual bool LoadMovie(File& filein);
virtual bool SaveMovie(File& fileout);
virtual bool LoadSingleMovie(File& filein);
virtual bool SaveSingleMovie(File& fileout);
virtual void CoordConvert(COORDSYS totype);
virtual void LoadedProcess(bool genAABB,bool genBuff,bool accordant);
virtual void AssignSkeleton(Skeleton* skeleton);
//attation: when src mc be free,instance mc need not be free; because share res use ptr.
virtual MovieClip* Clone(CloneType type = CT_REF);
virtual void OnFrame(const char* framename);
virtual bool UseThisLight();
bool AlphaSort();
bool MaterialSort();
//bool unproject( const vec3 &pt, vec3 *dest ) const;
/*const*/ Frame& GetProgramFrame() /*const*/;
void SetProgramFrame(Frame& frame);
const char* GetMovieName();
void SetMovieName(const char* name);
const char* GetTextureName();
const char* GetFilePath();
MovieType GetMovieType();
/*const */MovieClipArr& GetSubMovieArr();
Frame* GetFinalFrame();
void SetLoadComplete(bool finish);;
bool GetLoadComplete();;
void SetPickable(bool able,bool recursive = false);
void SetPicked(bool picked,bool recursive = false);
bool GetPicked();
void SetVisible(bool able,bool recursive = false);
bool GetVisible();
bool GetInFrustum();
void SetFogEffect(bool fogEnable,bool recursive = false);
void SetReceiveShadow(bool receive,bool recursive = false);
int GetAlphaSortPriority();
void SetAlphaSortPriority(int priority,bool recursive = false);
//max set sort by alpha and name,this resort by dist to camera.
int GetAlphaSortEnable();
void SetAlphaSortEnable(bool alphaSort,bool recursive = false);
void SetFrustumSkipEnable(bool able,bool recursive = false);
bool GetWaterLike() const;
void SetWaterLike(bool val);
bool GetDepthMask() const;
void SetDepthMask(bool val,bool recursive = false);
bool GetBoneMixFrame(const char* boneName,Frame* frame);
Mesh* GetMesh();
void SetMesh(Mesh* mesh);
MixMesh* GetMixMesh();
VolumeShadowSys& GetShadowSys();
ModifierSys* GetModifierSys();
void SetModefierSys(ModifierSys* modifer);
CollideAABBox& GetCollideSys();
CallBacks* GetCallBacks();
Texture* GetTexture();
//static CallBacks* GetCallBacks(){ return &m_callBacks;}
//debug
int GetTotalTrigonNum();
enum ThreadAdvanceFlag
{
TO_Init,
TO_ThreadAdvance,
TO_RenderAdvance,
};
/*volatile*/ ThreadAdvanceFlag m_threadAdvanceFlag;
protected:
enum SkipType{Skip_None,Skip_Self,Skip_All};
virtual SkipType CanSkipRend(int option);
//res shared to clones
//a Movieclip has only one Mesh,what be nested is mc not the mesh
MeshPtr m_mesh;
TexturePtr m_texture;
TexturePtr m_detailTexture;
int m_opacityType;
//to do recurrent play.
static MovieClip* m_curCamera;
protected:
Frame m_programFrame;
Frame m_finalFrame;
Frame m_finalFrameInverse;
bool m_doCasterShadow;
bool m_doReceiveShadow;
bool m_doReflectedByWater;
bool m_bWaterLike;
bool m_doPickAble;
bool m_doCollodeAble;
bool m_visible;
bool m_picked;
int m_alphaSortPriority;
bool m_doAlphaSort;
bool m_loadComplete;
bool m_doFogEffect;
bool m_advanceDirty;
bool m_bInFrustum;
bool m_doFrustumSkip;
bool m_bLensFlare;
bool m_doDepthMask;
MovieClip* m_parentMovie;
MovieClip* m_maskMovie;
MovieClipArr m_movieClips;
String m_movieName;
String m_filePath;
VolumeShadowSys m_shadowSys;
ModifierSys* m_mdSys;
MixMesh* m_mixMesh;
CollideAABBox m_collideAABBox;
CallBacks* m_callBacks;
String m_textureName;
//keep one ptr at least in order to hold the resource.
MovieType m_type;
//shader Material
//reactor
float m_extra;
protected:
public:
//instance movies
void AddRefMovie(MovieClip* movie);
void RelseaeRefMovie(MovieClip* movie);
MovieClipArr m_refMovies;
void RendSubClip(int option=RO_ALL);
void AdvanceSubClip();
void CaculFinalFrame();
protected:
MovieClip(const MovieClip &);
virtual MovieClip& operator=(const MovieClip&);
};
class MC_Frame:public MovieClip
{
public:
typedef MovieClip Parent;
MC_Frame();
void ReAttachFrameLine(FrameLine* framesys);
virtual void RendClip(int option=RO_ALL);
virtual void GenShadow();
virtual void EditRender();
virtual void Advance();
virtual void FreeMovie();
virtual void CalBound();
virtual bool LoadSingleMovie(File& fp);
virtual bool SaveSingleMovie(File& fp);
virtual void CoordConvert(COORDSYS totype);
virtual void LoadedProcess(bool genAABB,bool genBuff,bool accordant);
virtual vec3 GetPos();
virtual MovieClip* Clone(CloneType type = CT_REF);
virtual SkipType CanSkipRend(int option);
void BeginCommonRendState(int option);
void EndCommonRendState();
virtual MovieClip& operator=(const MovieClip& other);
FrameLinePtr m_frameLine;
FrameHead m_frameHead;
};
//可以附着子物体 比如3d gui ,snow particles
class MC_Camera:public MC_Frame
{
public:
MC_Camera();
virtual void EditRender();
virtual void Advance();
virtual bool LoadSingleMovie(File& fp);
virtual bool SaveSingleMovie(File& fp);
virtual void CoordConvert(COORDSYS totype);
virtual void LoadedProcess(bool genAABB,bool genBuff,bool accordant);
virtual MovieClip* Clone(CloneType type = CT_REF);
void UseThisCamera();
private:
int m_fov;
bool m_isOrtho;
int m_nearPlane;
int m_farPlane;
vec3 m_lookFrom;
vec3 m_lookTo;
vec3 m_up;
vec3 m_coners[8];
};
class MC_Particle:public MC_Frame
{
public:
MC_Particle();
~MC_Particle();
virtual void RendClip(int option=RO_ALL);
virtual void GenShadow();
virtual void EditRender();
virtual void Advance();
virtual void AdvanceThread();
virtual void FreeMovie();
virtual void CalBound();
virtual bool LoadSingleMovie(File& fp);
virtual bool SaveSingleMovie(File& fp);
virtual void CoordConvert(COORDSYS totype);
virtual void LoadedProcess(bool genAABB,bool genBuff,bool accordant);
virtual MovieClip* Clone(CloneType type = CT_REF);
virtual SkipType CanSkipRend(int option);
virtual MovieClip& operator=(const MovieClip&);
EmitterDef* m_emitterDef;
ParticleEmitter* m_emitter;
MovieClip* m_attachedModel;
String m_attachedModelName;
String m_emitterdefName;
//MixSkeleton m_mixBone;
//bind bone
int m_parentBoneID;
vec3 m_offset;
};
//each face is a billboard,center is pos,point to center is radius,
class MC_FrameBillboard:public MC_Frame
{
public:
MC_FrameBillboard();
~MC_FrameBillboard();
virtual void RendClip(int option=RO_ALL);
virtual void GenShadow();
virtual void EditRender();
virtual void Advance();
virtual void AdvanceThread();
virtual void FreeMovie();
virtual void CalBound();
virtual bool LoadSingleMovie(File& fp);
virtual bool SaveSingleMovie(File& fp);
virtual MovieClip* Clone(CloneType type = CT_REF);
virtual SkipType CanSkipRend(int option);
virtual MovieClip& operator=(const MovieClip& other_);
virtual void LoadedProcess(bool genAABB,bool genBuff,bool accordant);
private:
vec3* m_vVertex;
vec2* m_tVertex;
};
class MC_FrameVertex:public MC_Frame
{
public:
MC_FrameVertex();
~MC_FrameVertex();
virtual void RendClip(int option=RO_ALL);
virtual void GenShadow();
virtual void EditRender();
virtual void Advance();
virtual void AdvanceThread();
virtual void FreeMovie();
virtual void CalBound();
virtual bool LoadSingleMovie(File& fp);
virtual bool SaveSingleMovie(File& fp);
virtual MovieClip* Clone(CloneType type = CT_REF);
virtual SkipType CanSkipRend(int option);
};
class MC_FrameStripTail:public MC_Frame
{
public:
MC_FrameStripTail();
~MC_FrameStripTail();
virtual void RendClip(int option=RO_ALL);
virtual void GenShadow();
virtual void EditRender();
virtual void Advance();
virtual void AdvanceThread();
virtual void FreeMovie();
virtual void CalBound();
virtual bool LoadSingleMovie(File& fp);
virtual bool SaveSingleMovie(File& fp);
virtual void CoordConvert(COORDSYS totype);
virtual void LoadedProcess(bool genAABB,bool genBuff,bool accordant);
virtual MovieClip* Clone(CloneType type = CT_REF);
virtual SkipType CanSkipRend(int option);
virtual MovieClip& operator=(const MovieClip&);
StripTail* m_tail;
};
class MC_Light:public MC_Frame
{
public:
MC_Light();
~MC_Light();
virtual void RendClip(int option=RO_ALL);
virtual void GenShadow();
virtual void EditRender();
virtual void Advance();
virtual void FreeMovie();
virtual void CalBound();
virtual bool LoadSingleMovie(File& fp);
virtual bool SaveSingleMovie(File& fp);
virtual MovieClip* Clone(CloneType type = CT_REF);
virtual bool UseThisLight();
MixSkeleton m_mixBone;
//bind bone
int m_parentBoneID;
Light* m_light;
};
class MC_Skeleton:public MC_Frame
{
public:
typedef MC_Frame Parent;
MC_Skeleton();
~MC_Skeleton();
virtual void RendClip(int option=RO_ALL);
virtual void GenShadow();
virtual void EditRender();
virtual void Advance();
virtual void AdvanceThread();
virtual void FreeMovie();
virtual void CalBound();
virtual bool LoadSingleMovie(File& fp);
virtual bool SaveSingleMovie(File& fp);
virtual void CoordConvert(COORDSYS totype);
virtual void LoadedProcess(bool genAABB,bool genBuff,bool accordant);
virtual void AssignSkeleton(Skeleton* skeleton);
virtual MovieClip* Clone(CloneType type = CT_REF);
virtual void IntersectTrayImp(RayMovieCollideRes& res);
virtual SkipType CanSkipRend(int option);
MixSkeleton m_mixSkeleton;
bool m_gpuAdvance;
};
class MC_SkeletonSoftObj:public MC_Skeleton
{
public:
MC_SkeletonSoftObj();
~MC_SkeletonSoftObj();
virtual void RendClip(int option=RO_ALL);
virtual void GenShadow();
//virtual void EditRender();
virtual void Advance();
virtual void AdvanceThread();
virtual void FreeMovie();
virtual void CalBound();
//virtual bool LoadSingleMovie(File& fp);
//virtual bool SaveSingleMovie(File& fp);
//virtual void CoordConvert(COORDSYS totype);
virtual void LoadedProcess(bool genAABB,bool genBuff,bool accordant);
//virtual MovieClip* Clone(CloneType type = CT_REF);
virtual SkipType CanSkipRend(int option);
SoftObject* m_softObj;
};
class MC_SkeletonBillboard:public MC_Skeleton
{
public:
MC_SkeletonBillboard();
~MC_SkeletonBillboard();
virtual void RendClip(int option=RO_ALL);
virtual void GenShadow();
//virtual void EditRender();
virtual void Advance();
virtual void AdvanceThread();
virtual void FreeMovie();
virtual void CalBound();
virtual bool LoadSingleMovie(File& fp);
//virtual bool SaveSingleMovie(File& fp);
//virtual void CoordConvert(COORDSYS totype);
virtual void LoadedProcess(bool genAABB,bool genBuff,bool accordant);
//virtual MovieClip* Clone(CloneType type = CT_REF);
virtual SkipType CanSkipRend(int option);
};
class MC_SkeletonStripTail:public MC_Skeleton
{
public:
MC_SkeletonStripTail();
~MC_SkeletonStripTail();
virtual void RendClip(int option=RO_ALL);
virtual void GenShadow();
//virtual void EditRender();
virtual void Advance();
virtual void AdvanceThread();
virtual void FreeMovie();
virtual void CalBound();
virtual bool LoadSingleMovie(File& fp);
//virtual bool SaveSingleMovie(File& fp);
//virtual void CoordConvert(COORDSYS totype);
virtual void LoadedProcess(bool genAABB,bool genBuff,bool accordant);
//virtual MovieClip* Clone(CloneType type = CT_REF);
virtual SkipType CanSkipRend(int option);
virtual MovieClip& operator=(const MovieClip&);
StripTail* m_tail;
};
class MeshMgr:public MemberSingleton,public ResPtrMgr
{
public:
bool AddMesh(MeshPtr& ptr,const char* refName="");
};
class MovieClipMgr:public MemberSingleton,public ResPtrMgr
{
public:
bool AddMovieClip(MovieClipPtr& ptr,const char* fileName,const char* refName="",bool genAABB=true);
};
class SkeletonMgr:public MemberSingleton,public ResPtrMgr
{
public:
bool AddSkeleton(SkeletonPtr& ptr,const char* fileName,const char* refName="");
};
#define G_MovieThreadLoader MovieClipThreadLoader::GetSingleton()
//是否封装一个线程安全的vector 影响太大
//多线程调用临时对象的虚函数run时对象已析构,发现多态不起作用 调到了基类的run中
//ogl create buf 和 freeimage 不支持多线程
class MovieClipThreadLoader:public ScriptObject,public SingleTaskThread,public Singleton
{
public:
MovieClipThreadLoader();
//~MovieClipThreadLoader()
//{}
struct MovieLoadTask:public Task
{
MovieLoadTask(MovieClip* movie,const char* fileName)
:m_movie(movie)
,m_fileName(fileName)
{
m_movie->SetLoadComplete(false);
}
virtual void Excute();
MovieClip* m_movie;
String m_fileName;
};
virtual bool Run(ThreadParm* pData);
void PushTask(MovieClip* movie,const char* fileName);
};
#define G_SkeletonMovieAdvancer SkeletonMovieAdvancer::GetSingleton()
//是否封装一个线程安全的vector 影响太大
//多线程调用临时对象的虚函数run时对象已析构,发现多态不起作用 调到了基类的run中
//ogl create buf 和 freeimage 不支持多线程
class SkeletonMovieAdvancer:public SingleTaskThread,public Singleton
{
public:
SkeletonMovieAdvancer();
//~SkeletonMovieAdvancer()
//{}
struct SkeletonMovieAdvanceTask:public Task
{
SkeletonMovieAdvanceTask();
virtual void Excute();
MovieClip* m_movie;
};
virtual bool Run(ThreadParm* pData);
void PushTask(MovieClip* movie);
void RemoveTask(MovieClip* movie);
virtual Task* GetTaskObj();
CriticalSection m_freeMovieLock;
bool m_enable;
bool m_bLock;
};
//Procedural modeling and texturing and key
class ProceduralSys:public Singleton
{
public:
enum SelectType
{
ST_NONE = 0,
ST_POINT,
ST_EDGE,
ST_FACE,
ST_OUTLINE,
};
ProceduralSys();
~ProceduralSys();
void SetOperateMovie(MovieClip* movie);
void GenRandMesh();
void GenCone();
void GenTorus();
void GenSphere();
void GenSylinder();
// The shape must be closed ,The path must have three points at least and cannot be closed.
bool GenLoft();
CCurve& GetPathCurve();
CCurve& GetShapeCurve();
CCurve& GetScaleCurve();
CCurve& GetTwistCurve();
void SetUVRect(vec4& rect);
protected:
// 计算shape的变换矩阵
void GetShapeMatrix( vec3& shapeNorm, vec3& slice, const vec3& pathPnt,const vec3& pathScale, mat4& finalMat);
void GetRayAndPlaneIntersetPnt(const vec3& rayOrig, const vec3& rayDir,
const vec3& planeNorm, const vec3& planePnt, vec3& point);
void ConvertUV(float& u,float& v);
CCurve* m_shapeCurve;
CCurve* m_pathCurve;
CCurve* m_scaleCurve;
CCurve* m_twistCurve;
vec4 m_uvRect;
class Edge
{
public:
int indexStart;
int indexEnd;
};
class SelectRes
{
public:
int m_trigonNum;
int m_vVertexNum;
int m_vEdgeNum;
int* m_vertexsIndex;
int* m_trigonsIndex;
Edge* m_edges;
};
MovieClip* m_movie;
static const int MaxTrigonNum = 1000;
static const int MaxVVertexNum = 1000;
static const int MaxTVertexNum = 1000;
//void SelectSlice(SelectType type/*,Shape& shape*/);
//void ReverceSelect();
//void TransSelect();
//void SpringTransSelect();
//clone selections then extrude them and select the new creation
//void Extrude();
//void RefranceCopy();
//void Merge();
//void Weild();
//void Remove();
//void AddSmoth();
// smoth增面 减面 分形
// city 蜗牛赛道
//void RendSelect();
};
//
class ProTreeDef
{
friend class Particle;
public:
ProTreeDef();
static const int MaxDepth = 6;
String m_defName;
String m_texture;
//每一层最大叶子数
int m_maxLeaves;//[MaxDepth];
//叶与主干夹角
float m_leafStemAngle;//[MaxDepth];
float m_leafSize;//[MaxDepth];
//每一层分枝数
int m_subTreeNum[MaxDepth];
//分枝与主干长度比
float m_subLenMult[MaxDepth];
//分枝与主干半径比
float m_subRadiusMult[MaxDepth];
//分枝与主干夹角
float m_subStemAngle;//[MaxDepth];
//分枝最小高度
float m_minSubOffset[MaxDepth];
//初始长度
float m_mainStemLen;
//初始底部半径
float m_mainStemRadius;
//主干顶端和底部半径比
float m_stemFac[MaxDepth];;
int m_depth;
//树叶类型: 十字放样 或 mesh
//BillBoard m_billboard;
//RendSys::MovieClip* m_movie;
//bool SetMovie(const char* fileName);
//bool SetMovie(const RendSys::MovieClip* movie);
void Load(File& file);
void Save(File& file);
};
class ProTreeDefMgr:public MemberSingleton
{
public:
~ProTreeDefMgr();
int Init();
void Free();
ProTreeDef* AddProTreeDef(const char* fileName,const char* refName="");
ProTreeDef* GetProTreeDef(const char* refName);
};
class TreeProceduralSys:public ProceduralSys,public Singleton
{
public:
TreeProceduralSys();
void GenRandTree(ProTreeDef* def);
void GenRandTree(const char* def);
private:
void GenRandTree(ProTreeDef* def,int depth,mat4 mat);
virtual void drawFoliage(float s);
};
#define G_TreeProceduralSys TreeProceduralSys::Singleton::GetSingleton()
#define G_ProTreeDefMgr ProTreeDefMgr::GetSingleton()
}
using namespace RendSys;
//test config
#define USEBUFFER
//亮度闪烁(diffuse设置为0即正常了)=>法线不对=>drawcall正确=>buffer错误
//#define DRAWCALL
//#define INDEXARRAY //OpenGL 1.1
#define VERTEXBUFFER
//#define MESHOZCOLLIDE
//#define MESHOCTREE
#define MESHBSPTREE
//#define SHADOWVALUME
#define USEMATRIX
#endif