1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 THE SOFTWARE.
25 -----------------------------------------------------------------------------
26 */
27 #ifndef _ShaderExHardwareSkinning_
28 #define _ShaderExHardwareSkinning_
29 
30 #include "OgreShaderPrerequisites.h"
31 
32 #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS
33 #include "OgreShaderSubRenderState.h"
34 
35 #define HS_MAX_WEIGHT_COUNT 4
36 
37 namespace Ogre {
38 namespace RTShader {
39 
40     class HardwareSkinningFactory;
41     class DualQuaternionSkinning;
42     class HardwareSkinningTechnique;
43     class LinearSkinning;
44 
45 /** \addtogroup Optional
46 *  @{
47 */
48 /** \addtogroup RTShader
49 *  @{
50 */
51 
52 /** Implement a sub render state which performs hardware skinning.
53 Meaning, this sub render states adds calculations which multiply
54 the points and normals by their assigned bone matricies.
55 */
56 class _OgreRTSSExport HardwareSkinning : public SubRenderState
57 {
58 public:
59     struct SkinningData
60     {
SkinningDataSkinningData61         SkinningData() :
62             isValid(true), maxBoneCount(0), maxWeightCount(0), skinningType(ST_LINEAR), correctAntipodalityHandling(false), scalingShearingSupport(false)
63         {}
64 
65         bool isValid;
66         ushort maxBoneCount;
67         ushort maxWeightCount;
68         SkinningType skinningType;
69         bool correctAntipodalityHandling;
70         bool scalingShearingSupport;
71     };
72 
73 // Interface.
74 public:
75     /** Class default constructor */
76     HardwareSkinning();
77 
78     /**
79     @see SubRenderState::getType.
80     */
81     virtual const String& getType() const;
82 
83     /**
84     @see SubRenderState::getType.
85     */
86     virtual int getExecutionOrder() const;
87 
88     /**
89     @see SubRenderState::copyFrom.
90     */
91     virtual void copyFrom(const SubRenderState& rhs);
92 
93     /**
94     Set the hardware skinning parameters.
95     @param boneCount The maximum number of bones in the model this material
96          is assigned to. Note that this parameter can be higher but not
97          lower than the actual number of bones.
98     @param weightCount The maximum number of weights/bones affecting a vertex.
99     @param skinningType The type of skinning desired.
100     @param correctAntipodalityHandling If correct antipodality handling should be utilized (Only applicable for dual quaternion skinning).
101     @param scalingShearingSupport If scaling and shearing support should be enabled (Only applicable for dual quaternion skinning).
102     */
103     void setHardwareSkinningParam(ushort boneCount, ushort weightCount, SkinningType skinningType = ST_LINEAR,  bool correctAntipodalityHandling = false, bool scalingShearingSupport = false);
104 
105     /**
106     Returns the number of bones in the model assigned to the material.
107     @see setHardwareSkinningParam()
108     */
109     ushort getBoneCount();
110 
111     /**
112     Returns the number of weights/bones affecting a vertex.
113     @see setHardwareSkinningParam()
114     */
115     ushort getWeightCount();
116 
117     /**
118     Returns the current skinning type in use.
119     @see setHardwareSkinningParam()
120      */
121     SkinningType getSkinningType();
122 
123     /**
124     Only applicable for dual quaternion skinning.
125     @see setHardwareSkinningParam()
126     */
127     bool hasCorrectAntipodalityHandling();
128 
129     /**
130     Only applicable for dual quaternion skinning.
131     @see setHardwareSkinningParam()
132     */
133     bool hasScalingShearingSupport();
134 
135     /**
136     @see SubRenderState::preAddToRenderState.
137     */
138     virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass);
139 
140     /**
141     Set the factory which created this sub render state
142     */
_setCreator(const HardwareSkinningFactory * pCreator)143     void _setCreator(const HardwareSkinningFactory* pCreator) { mCreator = pCreator; }
144 
145     static String Type;
146 
147 // Protected methods
148 protected:
149     /**
150     @see SubRenderState::resolveParameters.
151     */
152     virtual bool resolveParameters(ProgramSet* programSet);
153 
154     /**
155     @see SubRenderState::resolveDependencies.
156     */
157     virtual bool resolveDependencies(ProgramSet* programSet);
158 
159     /**
160     @see SubRenderState::addFunctionInvocations.
161     */
162     virtual bool addFunctionInvocations(ProgramSet* programSet);
163 
164     SharedPtr<LinearSkinning> mLinear;
165     SharedPtr<DualQuaternionSkinning> mDualQuat;
166     SharedPtr<HardwareSkinningTechnique> mActiveTechnique;
167 
168     ///The factory which created this sub render state
169     const HardwareSkinningFactory* mCreator;
170     SkinningType mSkinningType;
171 };
172 
173 _OgreRTSSExport void operator<<(std::ostream& o, const HardwareSkinning::SkinningData& data);
174 
175 /**
176 A factory that enables creation of HardwareSkinning instances.
177 @remarks Sub class of SubRenderStateFactory
178 */
179 class _OgreRTSSExport HardwareSkinningFactory : public SubRenderStateFactory,
180     public Singleton<HardwareSkinningFactory>
181 {
182 public:
183     HardwareSkinningFactory();
184     ~HardwareSkinningFactory();
185 
186     /**
187     @see SubRenderStateFactory::getType.
188     */
189     virtual const String& getType() const;
190 
191     /**
192     @see SubRenderStateFactory::createInstance.
193     */
194     virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator);
195 
196     /**
197     @see SubRenderStateFactory::writeInstance.
198     */
199     virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass);
200 
201     /**
202     Sets the list of custom shadow caster materials
203     */
204     virtual void setCustomShadowCasterMaterials(const SkinningType skinningType, const MaterialPtr& caster1Weight, const MaterialPtr& caster2Weight,
205         const MaterialPtr& caster3Weight, const MaterialPtr& caster4Weight);
206 
207     /**
208     Sets the list of custom shadow receiver materials
209     */
210     virtual void setCustomShadowReceiverMaterials(const SkinningType skinningType, const MaterialPtr& receiver1Weight, const MaterialPtr& receiver2Weight,
211         const MaterialPtr& receiver3Weight, const MaterialPtr& receiver4Weight);
212 
213     /**
214     Returns the name of a custom shadow caster material for a given number of weights
215     */
216     const MaterialPtr& getCustomShadowCasterMaterial(const SkinningType skinningType, ushort index) const;
217 
218     /**
219     Returns the name of a custom shadow receiver material for a given number of weights
220     */
221     const MaterialPtr& getCustomShadowReceiverMaterial(const SkinningType skinningType, ushort index) const;
222 
223     /**
224         @brief
225             Prepares an entity's material for use in the hardware skinning (HS).
226 
227         This function prepares an entity's material for use by the HS sub-render
228         state. This function scans the entity and extracts the information of the amount
229         of bones and weights in the entity. This function replaces the need specify in
230         the material script the  amount of bones and weights needed to make the HS work.
231 
232         Note that this class does not save the the bone and weight count information
233         internally. Rather this information is stored in the entity's materials as a
234         user binded object.
235 
236         @param pEntity A pointer to an entity who's materials need preparing.
237     */
238     void prepareEntityForSkinning(const Entity* pEntity, SkinningType skinningType = ST_LINEAR, bool correctAntidpodalityHandling = false, bool shearScale = false);
239 
240     /**
241         @brief
242             The maximum number of bones for which hardware skinning is performed.
243 
244         This number should be limited to avoid problems of using to many parameters
245         in a shader. For example, in pixel shader 3 this should be around 70-90
246         dependent on other sub-render states in the shader.
247 
248         The default value for this property is 70 which correspond to pixel shader model 3 limitations
249     */
getMaxCalculableBoneCount()250     ushort getMaxCalculableBoneCount() const {
251         return mMaxCalculableBoneCount; }
252     /**
253         Sets the maximum number of bones for which hardware skinning is performed.
254         @see getMaxCalculableBoneCount()
255     */
setMaxCalculableBoneCount(ushort count)256     void setMaxCalculableBoneCount(ushort count) {
257         mMaxCalculableBoneCount = count; }
258 
259     /**
260     Override standard Singleton retrieval.
261 
262     @remarks Why do we do this? Well, it's because the Singleton
263         implementation is in a .h file, which means it gets compiled
264         into anybody who includes it. This is needed for the
265         Singleton template to work, but we actually only want it
266         compiled into the implementation of the class based on the
267         Singleton, not all of them. If we don't change this, we get
268         link errors when trying to use the Singleton-based class from
269         an outside dll.
270 
271     @par
272         This method just delegates to the template version anyway,
273         but the implementation stays in this single compilation unit,
274         preventing link errors.
275     */
276     static HardwareSkinningFactory& getSingleton(void);
277 
278     /// @copydoc Singleton::getSingleton()
279     static HardwareSkinningFactory* getSingletonPtr(void);
280 
281 protected:
282     /**
283         @brief
284             Extracts the maximum amount of bones and weights used in an specific subentity of given entity.
285 
286         @param pEntity The entity from which the information needs to be extracted.
287         @param subEntityIndex The index of subentity from which the information needs to be extracted.
288         @param boneCount The maximum number of bones used by the entity.
289         @param weightCount The maximum number of weights used by the entity.
290         @return Returns true if the entity can use HS. False if not.
291     */
292     bool extractSkeletonData(const Entity* pEntity, size_t subEntityIndex,
293         ushort& boneCount, ushort& weightCount);
294 
295     /**
296         @brief
297             Updates an entity's the skeleton data onto one of it's materials.
298 
299         @param pMaterial The material to update with the information.
300         @param isValid Tells if the material can be used with HS.
301         @param boneCount The maximum number of bones used by the entity.
302         @param weightCount The maximum number of weights used by the entity.
303         @return Returns true if the data was updated on the material. False if not.
304     */
305     bool imprintSkeletonData(const MaterialPtr& pMaterial, bool isValid,
306         ushort boneCount, ushort weightCount, SkinningType skinningType, bool correctAntidpodalityHandling, bool scalingShearingSupport);
307 
308 protected:
309 
310     /**
311     @see SubRenderStateFactory::createInstanceImpl.
312     */
313     virtual SubRenderState* createInstanceImpl();
314 
315     /// A set of custom shadow caster materials
316     MaterialPtr mCustomShadowCasterMaterialsLinear[HS_MAX_WEIGHT_COUNT];
317     MaterialPtr mCustomShadowCasterMaterialsDualQuaternion[HS_MAX_WEIGHT_COUNT];
318 
319     /// A set of custom shadow receiver materials
320     MaterialPtr mCustomShadowReceiverMaterialsLinear[HS_MAX_WEIGHT_COUNT];
321     MaterialPtr mCustomShadowReceiverMaterialsDualQuaternion[HS_MAX_WEIGHT_COUNT];
322 
323     ///The maximum number of bones for which hardware skinning is performed.
324     ///@see getMaxCalculableBoneCount()
325     ushort mMaxCalculableBoneCount;
326 };
327 
328 /** @} */
329 /** @} */
330 
331 
332 }
333 }
334 
335 #endif
336 #endif
337 
338