// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef NL_U_INSTANCE_H #define NL_U_INSTANCE_H #include "nel/misc/types_nl.h" #include "u_transform.h" #include "u_instance_material.h" #include "u_shape.h" #include "nel/misc/aabbox.h" namespace NL3D { class UInstanceMaterial; // *************************************************************************** /** * Game interface for manipulating Objects, animations etc... * \author Lionel Berenguier * \author Nevrax France * \date 2001 */ class UInstance : public UTransform { public: /** Get the untransformed AABBox of the mesh. NULL (gtSize()==0) if no mesh. */ void getShapeAABBox(NLMISC::CAABBox &bbox) const; /** * Set the blend shape factor for this instance * blendShapeName is the name of the blendshape we want to set * factor the blendshape percentage from -100.0 to 100.0 * dynamic tells the optimizer if the blendshape have to change in real time */ void setBlendShapeFactor (const std::string &blendShapeName, float factor, bool dynamic); /// \name Material access. // @{ /// return number of materials this mesh instance use. uint getNumMaterials() const; /// return a local access on a material, to change its values. (NB: overwrite, if animated). UInstanceMaterial getMaterial(uint materialId); /** Select textures of material among several sets (if available) * NB: if success and if getAsyncTextureMode()==true, then setAsyncTextureDirty(true) is called */ void selectTextureSet(uint id); // @} /** Change MRM Distance setup. Only for mesh which support MRM. NB MeshMultiLod apply it only on Lod0 * (if Lod0 is a MRM). * NB: This apply to the shape directly!! ie All instances using same shape will be affected * NB: no-op if distanceFinest<0, distanceMiddle<=distanceFinest or if distanceCoarsest<=distanceMiddle. * \param distanceFinest The MRM has its max faces when dist<=distanceFinest. * \param distanceMiddle The MRM has 50% of its faces at dist==distanceMiddle. * \param distanceCoarsest The MRM has faces/Divisor (ie near 0) when dist>=distanceCoarsest. */ void changeMRMDistanceSetup(float distanceFinest, float distanceMiddle, float distanceCoarsest); /** Change Max Display distance. After this distance the shape won't be displayed. * setting <0 means -1 and so means DistMax = infinite (default in meshs but multilod meshes). * NB: This apply to the shape directly!! ie All instances using same shape will be affected * * Note: If the instance is skinned/sticked to a skeleton, this setup is not taken into account. But you can * call USkeleton::setShapeDistMax() to have same effect. * * Note (complex): All instances of the same shape which are freezeHRC()-ed and are linked to the * QuadGridClipManager (ie not linked to a cluster) may not be updated correctly. * In other words, you should setup this value only at beginning of program, just after creating your * instance (more exactly before UScene::render()), and all instances of the same shape should be setuped * with same value (or don't call setShapeDistMax() for subsequent instances). * If you don't do this, QuadGridClipManager may clip such instances nearer than they should */ void setShapeDistMax(float distMax); /// see setShapeDistMax() float getShapeDistMax() const; /// Test if there is a start/stop caps in the objects (some fxs such as remanence) bool canStartStop(); // For instance that have a start/stop caps void start(); // For instance that have a start/stop caps void stop() ; // For instance that have a start/stop caps bool isStarted() const; // Get the model distmax. float getDistMax() const; // Set the model distmax. void setDistMax(float distMax); // If the model has a coarse mesh, it set its dist. Set to -1 to keep default void setCoarseMeshDist(float dist); // If the model has a coarse mesh, it returns its distance if it has been set, or -1 if default is used (or if no coarse mesh present) float getCoarseMeshDist() const; /// \name Async Texture Loading /** All those methods no-op or return 0/false if the instance is not a CMeshBaseInstance. * isAsyncTextyreReady() return true if the instance is not a CMeshBaseInstance. */ // @{ /** if true, the instance is said in "AsyncTextureMode". Ie user must fill AsyncTextures field with name of the * textures to load. At each startAsyncTextureLoading(), the system start to load async them. * Then, isAsyncTextureReady() should be test each frame, to know if loading has completed. * By default, AsyncTextureMode=false. * When it swap from false to true, each texture file in Materials are replaced with * "blank.tga", and true fileNames are copied into AsyncTextures. * When it swap from true to false, the inverse is applied. * NB: calling enableAsyncTextureMode(true) calls setAsyncTextureDirty(true) */ void enableAsyncTextureMode(bool enable); bool getAsyncTextureMode() const; /** Start to load all textures in AsyncTextures array (if needed) * NB: old setup is kept in Material => instance is still rendered with "coherent" textures, until new textures * are ready * no op if not in async texture mode. */ void startAsyncTextureLoading(); /** return true if all the async textures of the instances are uploaded. * if was not ready before, this swap the upload textures into the rendered ones so they are rendered * return always true if not in async texture mode, or if startAsyncTextureLoading() has not been called * since last enableAsyncTextureMode(true) */ bool isAsyncTextureReady(); /** For Lod of texture, and load balancing, set the approximate distance of the instance to the camera. */ void setAsyncTextureDistance(float dist); /** \see setAsyncTextureDistance() */ float getAsyncTextureDistance() const; /** User is free to flag this state, to know if startAsyncTextureLoading() should be called. * Internal system don't use this flag. * Default is false */ void setAsyncTextureDirty(bool flag); /// see dirtAsyncTextureState() bool isAsyncTextureDirty() const; // @} /** Trails specific. Set the slice time (period used to sample the trail pos) * If the object is not a trail, this has no effect */ // @{ void setSliceTime(float duration); float getSliceTime() const; // @} /** Test if driver support rendering of all material of that shape. * \param forceBaseCaps When true, the driver is considered to have the most basic required caps (2 stages hardwares, no pixelShader), so that any fancy material will fail the test. */ bool supportMaterialRendering(UDriver &drv, bool forceBaseCaps); /// get the shape. NULL if no instance bound UShape getShape() const; // get the shape name. empty if no instance bound const std::string &getShapeName() const; // dynamic cast from a transform. empty if cast fail void cast(UTransform object); /// \name access default position. Valid only for CMeshBaseInstance /// NB: return false if the instance is not a CMeshBaseInstance (value not modified) // @{ bool getDefaultPos (CVector &) const; bool getDefaultRotQuat (CQuat &) const; bool getDefaultScale (CVector &) const; /** Set a scale relative to the default exported matrix * NB: really useful for instance if you want to scale an instance relatively to the scale * exported from the artist (if he had not set a "reset XForm") * NB: no op if the object is not a CMeshBaseInstance */ void setRelativeScale (const CVector &rs); // @} /// Proxy interface /// Constructors UInstance() { _Object = NULL; }; UInstance(class CTransformShape *object) { _Object = (ITransformable*)object; }; /// Attach an object to this proxy void attach(class CTransformShape *object) { _Object = (ITransformable*)object; } /// Detach the object void detach() { _Object = NULL; } /// Return true if the proxy is empty() (not attached) bool empty() const {return _Object==NULL;} /// For advanced usage, get the internal object ptr class CTransformShape *getObjectPtr() const {return (CTransformShape*)_Object;} }; } // NL3D #endif // NL_U_INSTANCE_H /* End of u_instance.h */