//----------------------------------------------------------------------------- // Torque Game Engine // Copyright (C) GarageGames.com, Inc. //----------------------------------------------------------------------------- #ifndef _DETAILMANAGER_H_ #define _DETAILMANAGER_H_ #ifndef _PLATFORMASSERT_H_ #include "platform/platformAssert.h" #endif #ifndef _MMATH_H_ #include "math/mMath.h" #endif #ifndef _TVECTOR_H_ #include "core/tVector.h" #endif #define MAX_BUMP 4 class TSShapeInstance; class TSPartInstance; class DetailManager { public: struct DetailData { S32 tag; TSShapeInstance * shapeInstance; // either this TSPartInstance * partInstance; // or this S16 bump[MAX_BUMP]; S16 dls[MAX_BUMP]; S32 dl; F32 intraDL; S32 prevDL; F32 pixelSize; F32 priority; }; struct DetailProfile { S32 skipFirst; // for how many rounds do we want to skip "bumping" first detail S32 skipMiddle; // for how many rounds do we want to skip "bumping" every middle detail S32 skipLast; // for how many rounds do we want to skip "bumping" last detail }; static DetailProfile smDefaultProfile; private: static DetailManager * smDetailManager; static DetailManager * get() { AssertFatal(smDetailManager,"DetailManager::get"); return smDetailManager; } S32 mTag; S32 mPolyLimit; // our poly budget...computed at the start of each frame based on detail scale bool mInPrepRender; S32 mPolyCount; // current poly count S32 mBumpPolyCount[MAX_BUMP]; // number of polys we save at each "bump" level Vector mDetailData; Vector mFreeDetailData; void begin(); void end(); void selectPotential(TSShapeInstance * si, F32 dist, F32 invScale, const DetailProfile * dp = &smDefaultProfile); bool selectCurrent(TSShapeInstance * si); void selectPotential(TSPartInstance * pi, F32 dist, F32 invScale, const DetailProfile * dp = &smDefaultProfile); bool selectCurrent(TSPartInstance * pi); void bumpOne(DetailData*, S32 bump); void bumpAll(S32 bump); void computePriority(DetailData *, S32 bump); DetailData * getNewDetailData(); public: DetailManager(); ~DetailManager(); static F32 smDetailScale; // user can adjust this static S32 smMaxPolyLimit; // app sets this once -- or uses default value static S32 smMinPolyLimit; // app sets this once -- or uses default value static S32 smLimitRange; // app sets this once -- or uses default value static S32 smPolysTriedToRender; // not used here, but can be read for misc. uses static S32 smPolysDidRender; // not used here, but can be read for misc. uses static void init() { AssertFatal(!smDetailManager,"DetailManger::init"); smDetailManager = new DetailManager; } static void shutdown() { delete smDetailManager; smDetailManager = NULL; } static void beginPrepRender() { get()->begin(); } static void endPrepRender() { get()->end(); } static void selectPotentialDetails(TSShapeInstance * si, F32 dist, F32 invScale) { get()->selectPotential(si,dist,invScale); } static bool selectCurrentDetail(TSShapeInstance * si) { return get()->selectCurrent(si); } static void selectPotentialDetails(TSPartInstance * pi, F32 dist, F32 invScale) { get()->selectPotential(pi,dist,invScale); } static bool selectCurrentDetail(TSPartInstance * pi) { return get()->selectCurrent(pi); } }; #endif