/*==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==*/ ////////////////////////////////////////////////////////////////////////////// // // // plDrawableSpans Header // // // // The base plDrawable derivative for ice (triangle list) // // drawables. Contains the basic structure for spans and the functions // // to deal with them. // // // //// Version History ///////////////////////////////////////////////////////// // // // 4.3.2001 mcn - Created. // // 5.3.2001 mcn - Completely revamped. Now plDrawableSpans *IS* the group // // of spans, and each span is either an icicle or patch. // // This eliminates the need entirely for separate drawables,// // at the cost of having to do a bit of extra work to // // maintain different types of spans in the same drawable. // // 4.20.2006 bob - Patches are long gone. Only icicle (or particle) spans // // now. // // ////////////////////////////////////////////////////////////////////////////// #ifndef _plDrawableSpans_h #define _plDrawableSpans_h #include "hsBitVector.h" #include "hsTemplates.h" #include "plDrawable.h" #include "hsBounds.h" #include "hsMatrix44.h" #include "plSpanTypes.h" class plPipeline; class plMessage; class hsGMaterial; class plGeometrySpan; class plSpaceTree; class plFogEnvironment; class plLightInfo; class plGBufferGroup; class plParticleCore; class plAccessSpan; class plAccessVtxSpan; class plAccessTriSpan; class plVisMgr; class plVisRegion; class plClusterGroup; //// Class Definition //////////////////////////////////////////////////////// class plDISpanIndex { public: enum { kNone = 0x0, kMatrixOnly = 0x1, kDontTransformSpans = 0x2 // Only used for particle systems right now }; UInt8 fFlags; hsTArray fIndices; hsBool IsMatrixOnly() const { return 0 != (fFlags & kMatrixOnly); } hsBool DontTransform() const { return 0 != ( fFlags & kDontTransformSpans ); } void Append(UInt32 i) { fIndices.Append(i); } void Reset() { fFlags = kNone; fIndices.Reset(); } void SetCountAndZero(int c) { fIndices.SetCountAndZero(c); } UInt32 GetCount() const { return fIndices.GetCount(); } UInt32& operator[](int i) const { return fIndices[i]; } }; struct hsColorRGBA; class plDrawableSpans : public plDrawable { protected: static const UInt32 kSpanTypeMask; static const UInt32 kSpanIDMask; static const UInt32 kSpanTypeIcicle; static const UInt32 kSpanTypeParticleSpan; UInt32 fType; hsBool fReadyToRender; hsBounds3Ext fLocalBounds; hsBounds3Ext fWorldBounds; hsBounds3Ext fMaxWorldBounds; hsMatrix44 fLocalToWorld; hsMatrix44 fWorldToLocal; hsTArray fLocalToWorlds; hsTArray fWorldToLocals; hsTArray fLocalToBones; hsTArray fBoneToLocals; hsTArray fMaterials; mutable plSpaceTree* fSpaceTree; hsBitVector fVisSet; // the or of all our spans visset's. Doesn't have to be exact, just conservative. hsBitVector fVisNot; // same, but for visregions that exclude us. mutable hsBitVector fLastVisSet; // Last vis set we were evaluated against. mutable hsBitVector fLastVisNot; // Last exclusion set we were evaluated agains. hsBitVector fVisCache; // the enabled section of the space tree hsTArray fIcicles; hsTArray fParticleSpans; hsTArray fSpans; // Pointers into the above two arrays hsTArray fSpanSourceIndices; // For volatile drawables only hsTArray fGroups; hsTArray fDIIndices; UInt32 fProps; UInt32 fCriteria; plRenderLevel fRenderLevel; plLoadMask fLoadMask; hsBool fRegisteredForRecreate, fNeedCleanup; hsBool fRegisteredForRender; hsBitVector fParticleSpanVector; hsBitVector fBlendingSpanVector; hsBitVector fFakeBlendingSpanVector; plKey fSceneNode; hsBool fSettingMatIdxLock; UInt32 fSkinTime; /// Export-only members hsTArray fSourceSpans; hsBool fOptimized; virtual void IQuickSpaceTree( void ) const; // Temp placeholder function. See code for comments. void IUpdateMatrixPaletteBoundsHack( ); void ICleanupMatrices(); void IRemoveGarbage( void ); void IAdjustSortData( plGBufferTriangle *triList, UInt32 count, UInt32 threshhold, Int32 delta ); // The following two functions return true if they create a new span, false if it's just an instance hsBool IConvertGeoSpanToVertexSpan( plGeometrySpan *geoSpan, plVertexSpan *span, int lod, plVertexSpan *instancedParent ); hsBool IConvertGeoSpanToIcicle( plGeometrySpan *geoSpan, plIcicle *icicle, int lod, plIcicle *instancedParent = nil ); void IUpdateIcicleFromGeoSpan( plGeometrySpan *geoSpan, plIcicle *icicle ); void IUpdateVertexSpanFromGeoSpan( plGeometrySpan *geoSpan, plVertexSpan *span ); UInt32 IXlateSpanProps( UInt32 props, hsBool xlateToSpan ); UInt32 IAddAMaterial( hsGMaterial *material ); UInt32 IRefMaterial( UInt32 index ); void ICheckToRemoveMaterial( UInt32 materialIdx ); // Annoying to need this, but necessary until materials can test for properties on any of their layers (might add in the future) hsBool ITestMatForSpecularity( hsGMaterial *mat ); void IAssignMatIdxToSpan( plSpan *span, hsGMaterial *mtl ); // Create the sorting data for a given span and flag it as sortable void ICheckSpanForSortable( UInt32 idx ) { if( !(fSpans[idx]->fProps & plSpan::kPropFacesSortable) )IMakeSpanSortable(idx); } void IMakeSpanSortable( UInt32 index ); /// Bit vector build thingies virtual void IBuildVectors( void ); hsBool IBoundsInvalid(const hsBounds3Ext& bnd) const; /// EXPORT-ONLY FUNCTIONS // Packs the span indices void IPackSourceSpans( void ); // Sort the spans void ISortSourceSpans( void ); // Compare two spans for sorting short ICompareSpans( plGeometrySpan *span1, plGeometrySpan *span2 ); // Find a buffer group of the given format (returns its index into fGroups) UInt8 IFindBufferGroup( UInt8 vtxFormat, UInt32 numVertsNeeded, int lod, hsBool vertVolatile, hsBool idxVolatile); // Write a span to a stream void IWriteSpan( hsStream *s, plSpan *span ); /// EXPORT-ONLY FUNCTIONS /// DYNAMIC FUNCTIONS plDISpanIndex *IFindDIIndices( UInt32 &index ); void IRebuildSpanArray( void ); plParticleSpan *ICreateParticleIcicle( hsGMaterial *material, plParticleSet *set ); virtual void SetKey(plKey k); public: plDrawableSpans(); virtual ~plDrawableSpans(); CLASSNAME_REGISTER( plDrawableSpans ); GETINTERFACE_ANY( plDrawableSpans, plDrawable ); virtual void SetNativeTransform(UInt32 idx, const hsMatrix44& l2w, const hsMatrix44& w2l); virtual plDrawable& SetTransform( UInt32 index, const hsMatrix44& l2w, const hsMatrix44& w2l); virtual const hsMatrix44& GetLocalToWorld( UInt32 index = (UInt32)-1 ) const; virtual const hsMatrix44& GetWorldToLocal( UInt32 index = (UInt32)-1 ) const; virtual plDrawable& SetProperty( UInt32 index, int prop, hsBool on ); virtual hsBool GetProperty( UInt32 index, int prop ) const; virtual plDrawable& SetProperty( int prop, hsBool on ); virtual hsBool GetProperty( int prop ) const; virtual plDrawable& SetNativeProperty( int prop, hsBool on ) { if( on ) fProps |= prop; else fProps &= ~prop; return *this; } virtual hsBool GetNativeProperty( int prop ) const { return ( fProps & prop ) ? true : false; } virtual plDrawable& SetNativeProperty( UInt32 index, int prop, hsBool on ); virtual hsBool GetNativeProperty( UInt32 index, int prop ) const; virtual plDrawable& SetSubType( UInt32 index, plSubDrawableType t, hsBool on ); virtual UInt32 GetSubType( UInt32 index ) const; // returns or of all spans with this index (index==-1 is all spans). virtual UInt32 GetType( void ) const { return fType; } virtual void SetType( UInt32 type ) { fType = type; } virtual void SetRenderLevel(const plRenderLevel& l); virtual const plRenderLevel& GetRenderLevel() const; const hsBounds3Ext& GetLocalBounds( UInt32 index = (UInt32)-1 ) const; const hsBounds3Ext& GetWorldBounds( UInt32 index = (UInt32)-1 ) const; const hsBounds3Ext& GetMaxWorldBounds( UInt32 index = (UInt32)-1 ) const; virtual void Read(hsStream* s, hsResMgr* mgr); virtual void Write(hsStream* s, hsResMgr* mgr); virtual plSpaceTree* GetSpaceTree() const { if(!fSpaceTree)IQuickSpaceTree(); return fSpaceTree; } virtual void SetSpaceTree(plSpaceTree* st) const; virtual void SetVisSet(plVisMgr* visMgr); virtual void SetDISpanVisSet(UInt32 diIndex, hsKeyedObject* reg, hsBool on); virtual const plSpan *GetSpan( UInt32 index ) const { return fSpans[ index ]; } virtual const plSpan *GetSpan( UInt32 diIndex, UInt32 index ) const { return fSpans[ (*fDIIndices[ diIndex ])[ index ] ]; } virtual const UInt32 GetNumSpans( void ) const { return fSpans.GetCount(); } virtual const hsTArray &GetSpanArray( void ) const { return fSpans; } hsMatrix44* GetMatrixPalette(int baseMatrix) const { return &fLocalToWorlds[baseMatrix]; } const hsMatrix44& GetPaletteMatrix(int i) const { return fLocalToWorlds[i]; } void SetInitialBone(int i, const hsMatrix44& l2b, const hsMatrix44& b2l); // Get the vertex buffer ref of a given group hsGDeviceRef *GetVertexRef( UInt32 group, UInt32 idx ); // Get the index buffer ref of a given group hsGDeviceRef *GetIndexRef( UInt32 group, UInt32 idx ); // BufferGroups accessed only by Pipeline and it's close personal acquaintances. plGBufferGroup* GetBufferGroup(UInt32 i) const { return fGroups[i]; } UInt32 GetNumBufferGroups() const { return fGroups.GetCount(); } const hsTArray& GetSourceSpans() const { return fSourceSpans; } void DirtyVertexBuffer(UInt32 group, UInt32 idx); void DirtyIndexBuffer(UInt32 group, UInt32 idx); // Prepare all internal data structures for rendering virtual void PrepForRender( plPipeline *p ); void SetNotReadyToRender() { fReadyToRender = false; } virtual hsBool MsgReceive( plMessage* msg ); // These two should only be called by the SceneNode virtual plKey GetSceneNode() const { return fSceneNode; } virtual void SetSceneNode(plKey newNode); // Lookup a material in the material array hsGMaterial *GetMaterial( UInt32 index ) const { return ( ( index == (UInt32)-1 ) ? nil : fMaterials[ index ] ); } UInt32 GetNumMaterials( void ) const { return fMaterials.GetCount(); } // Convert intermediate data into export/run-time-ready data virtual void Optimize( void ); // Called by the sceneNode to determine if we match the criteria virtual hsBool DoIMatch( const plDrawableCriteria& crit ); // To set the criteria that this ice fits void SetCriteria( const plDrawableCriteria& crit ); // Get a bitVector of the spans that are particle spans virtual hsBitVector const &GetParticleSpanVector( void ) const; // Get a bitVector of the spans that are blending (i.e. numMatrices > 0) virtual hsBitVector const &GetBlendingSpanVector( void ) const; // Set a single bit in the bitVector of spans that are blending virtual void SetBlendingSpanVectorBit( UInt32 bitNumber, hsBool on ); // Taking span index. DI Index doesn't make sense here, because one object's DI can dereference into many materials etc. virtual hsGMaterial* GetSubMaterial(int index) const; virtual hsBool GetSubVisDists(int index, hsScalar& minDist, hsScalar& maxDist) const; // return true if span invisible before minDist and/or after maxDist // Used by the pipeline to keep from reskinning on multiple renders per frame. UInt32 GetSkinTime() const { return fSkinTime; } void SetSkinTime(UInt32 t) { fSkinTime = t; } void UnPackCluster(plClusterGroup* cluster); /// EXPORT-ONLY FUNCTIONS virtual UInt32 AddDISpans( hsTArray &spans, UInt32 index = (UInt32)-1); virtual plDISpanIndex& GetDISpans( UInt32 index ) const; // Data Access functions // Runtime hsPoint3& GetPosition(int spanIdx, int vtxIdx); hsVector3& GetNormal(int spanIdx, int vtxIdx); UInt32 GetNumTris(int spanIdx); UInt16* GetIndexList(int spanIdx); // Conversion (before geometryspans get tossed (at write)). UInt32 CvtGetNumVerts(int spanIdx) const; hsPoint3& CvtGetPosition(int spanIdx, int vtxIdx); hsVector3& CvtGetNormal(int spanIdx, int vtxIdx); UInt32 CvtGetNumTris(int spanIdx); UInt16* CvtGetIndexList(int spanIdx); plGeometrySpan* GetGeometrySpan(int spanIdx); /// DYNAMIC FUNCTIONS virtual void RemoveDISpans( UInt32 index ); virtual UInt32 AppendDISpans( hsTArray &spans, UInt32 index = (UInt32)-1, hsBool clearSpansAfterAdd = true, hsBool doNotAddToSource = false, hsBool addToFront = false, int lod = 0 ); virtual UInt32 RefreshDISpans( UInt32 diIndex ); virtual UInt32 RefreshSpan( UInt32 srcSpanIndex ); virtual void RemoveDIMatrixSpans(UInt32 index); virtual UInt32 AppendDIMatrixSpans(int n); virtual UInt32 FindBoneBaseMatrix(const hsTArray& initL2B, hsBool searchAll) const; virtual UInt32 NewDIMatrixIndex(); void SortSpan( UInt32 index, plPipeline *pipe ); void SortVisibleSpans(const hsTArray& visList, plPipeline* pipe); void SortVisibleSpansPartial(const hsTArray& visList, plPipeline* pipe); void CleanUpGarbage( void ) { IRemoveGarbage(); } /// Funky particle system functions virtual UInt32 CreateParticleSystem( UInt32 maxNumEmitters, UInt32 maxNumParticles, hsGMaterial *material ); virtual void ResetParticleSystem( UInt32 index ); virtual void AssignEmitterToParticleSystem( UInt32 index, plParticleEmitter *emitter ); /// SceneViewer only! void GetOrigGeometrySpans( UInt32 diIndex, hsTArray &arrayToFill ); void ClearAndSetMaterialCount(UInt32 count); }; #endif // _plDrawableSpans_h