changed: gcc8 base update
[opensg.git] / Source / System / Dynamics / Skeleton / OSGGPUSkinningAlgorithm.cpp
bloba7ae6a379acf4cacdac8a520cc5594953d1b6c0d
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2006 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 // Includes
41 //---------------------------------------------------------------------------
43 #include <cstdlib>
44 #include <cstdio>
46 #include <OSGConfig.h>
48 #include "OSGGPUSkinningAlgorithm.h"
49 #include "OSGGPUSkinningDataAttachment.h"
50 #include "OSGSkeleton.h"
51 #include "OSGShaderProgram.h"
53 #include <boost/cast.hpp>
55 OSG_BEGIN_NAMESPACE
57 // Documentation for this class is emitted in the
58 // OSGGPUSkinningAlgorithmBase.cpp file.
59 // To modify it, please change the .fcd file (OSGGPUSkinningAlgorithm.fcd) and
60 // regenerate the base file.
62 /***************************************************************************\
63 * Class variables *
64 \***************************************************************************/
66 const std::string GPUSkinningAlgorithm::_vpVertexSkinning(
67 "#version 120\n"
68 "\n"
69 "uniform mat4 matBindShape;\n"
70 "uniform mat4 matJoints[70];\n"
72 "void calcSkin(inout vec4 vertPos, inout vec3 vertNorm,\n"
73 " in vec4 jointIdx, in vec4 jointWeight)\n"
74 "{\n"
75 " float sumWinv = 1. / dot(jointWeight, vec4(1., 1., 1., 1.));\n"
76 " vec4 inNorm = vec4(vertNorm, 0.);\n"
77 " vec4 tmpPos = vec4(0., 0., 0., 0.);\n"
78 " vec4 tmpNorm = vec4(0., 0., 0., 0.);\n"
79 "\n"
80 " for(int i = 0; i < 4; ++i)\n"
81 " {\n"
82 " int idxJ = int(jointIdx[i]);\n"
83 "\n"
84 " if(idxJ >= 0)\n"
85 " {\n"
86 " mat4 matJ = matJoints[idxJ] * matBindShape;\n"
87 "\n"
88 " tmpPos += jointWeight[i] * (matJ * vertPos);\n"
89 " tmpNorm += jointWeight[i] * (matJ * inNorm);\n"
90 " }\n"
91 " }\n"
92 "\n"
93 " vertPos = sumWinv * tmpPos;\n"
94 " vertNorm = sumWinv * tmpNorm.xyz;\n"
95 "}\n"
96 "\n"
97 "void calcSkin(inout vec4 vertPos, inout vec3 vertNorm,\n"
98 " inout vec3 vertTangent,\n"
99 " in vec4 jointIdx, in vec4 jointWeight )\n"
100 "{\n"
101 " float sumWinv = 1. / dot(jointWeight, vec4(1., 1., 1., 1.));\n"
102 " vec4 inNorm = vec4(vertNorm, 0.);\n"
103 " vec4 inTangent = vec4(vertTangent, 0.);\n"
104 " vec4 tmpPos = vec4(0., 0., 0., 0.);\n"
105 " vec4 tmpNorm = vec4(0., 0., 0., 0.);\n"
106 " vec4 tmpTangent = vec4(0., 0., 0., 0.);\n"
107 "\n"
108 " for(int i = 0; i < 4; ++i)\n"
109 " {\n"
110 " int idxJ = int(jointIdx[i]);\n"
111 "\n"
112 " if(idxJ >= 0)\n"
113 " {\n"
114 " mat4 matJ = matJoints[idxJ] * matBindShape;\n"
115 "\n"
116 " tmpPos += jointWeight[i] * (matJ * vertPos);\n"
117 " tmpNorm += jointWeight[i] * (matJ * inNorm);\n"
118 " tmpTangent += jointWeight[i] * (matJ * inTangent);\n"
119 " }\n"
120 " }\n"
121 "\n"
122 " vertPos = sumWinv * tmpPos;\n"
123 " vertNorm = sumWinv * tmpNorm.xyz;\n"
124 " vertTangent = sumWinv * tmpTangent.xyz;\n"
125 "}\n"
126 "\n"
127 "void calcSkin(inout vec4 vertPos, inout vec3 vertNorm,\n"
128 " inout vec3 vertTangent, inout vec3 vertBinormal,\n"
129 " in vec4 jointIdx, in vec4 jointWeight )\n"
130 "{\n"
131 " float sumWinv = 1. / dot(jointWeight, vec4(1., 1., 1., 1.));\n"
132 " vec4 inNorm = vec4(vertNorm, 0.);\n"
133 " vec4 inTangent = vec4(vertTangent, 0.);\n"
134 " vec4 inBinormal = vec4(vertBinormal, 0.);\n"
135 " vec4 tmpPos = vec4(0., 0., 0., 0.);\n"
136 " vec4 tmpNorm = vec4(0., 0., 0., 0.);\n"
137 " vec4 tmpTangent = vec4(0., 0., 0., 0.);\n"
138 " vec4 tmpBinormal = vec4(0., 0., 0., 0.);\n"
139 "\n"
140 " for(int i = 0; i < 4; ++i)\n"
141 " {\n"
142 " int idxJ = int(jointIdx[i]);\n"
143 "\n"
144 " if(idxJ >= 0)\n"
145 " {\n"
146 " mat4 matJ = matJoints[idxJ] * matBindShape;\n"
147 "\n"
148 " tmpPos += jointWeight[i] * (matJ * vertPos);\n"
149 " tmpNorm += jointWeight[i] * (matJ * inNorm);\n"
150 " tmpTangent += jointWeight[i] * (matJ * inTangent);\n"
151 " tmpBinormal += jointWeight[i] * (matJ * inBinormal);\n"
152 " }\n"
153 " }\n"
154 "\n"
155 " vertPos = sumWinv * tmpPos;\n"
156 " vertNorm = sumWinv * tmpNorm.xyz;\n"
157 " vertTangent = sumWinv * tmpTangent.xyz;\n"
158 " vertBinormal = sumWinv * tmpBinormal.xyz;\n"
159 "}\n"
162 /***************************************************************************\
163 * Class methods *
164 \***************************************************************************/
166 void GPUSkinningAlgorithm::initMethod(InitPhase ePhase)
168 Inherited::initMethod(ePhase);
170 if(ePhase == TypeObject::SystemPost)
176 /***************************************************************************\
177 * Instance methods *
178 \***************************************************************************/
180 /*-------------------------------------------------------------------------*\
181 - private -
182 \*-------------------------------------------------------------------------*/
184 /*----------------------- constructors & destructors ----------------------*/
186 GPUSkinningAlgorithm::GPUSkinningAlgorithm(void) :
187 Inherited()
191 GPUSkinningAlgorithm::GPUSkinningAlgorithm(const GPUSkinningAlgorithm &source) :
192 Inherited(source)
196 GPUSkinningAlgorithm::~GPUSkinningAlgorithm(void)
200 /*----------------------------- class specific ----------------------------*/
202 void
203 GPUSkinningAlgorithm::adjustVolume(Volume &volume)
205 if(_sfSkeleton.getValue() != NULL)
206 _sfSkeleton.getValue()->adjustVolume(volume);
209 Action::ResultE
210 GPUSkinningAlgorithm::renderEnter(Action *action)
212 Action::ResultE res = Action::Continue;
213 SkinnedGeometry *skinGeo = getSkin ();
214 Skeleton *skel = getSkeleton();
215 RenderAction *ract =
216 boost::polymorphic_downcast<RenderAction *>(action);
218 OSG_ASSERT(skinGeo != NULL);
219 OSG_ASSERT(skel != NULL);
221 GPUSkinningDataAttachmentUnrecPtr data = getGPUSkinningData(skel);
223 if(data == NULL)
225 data = GPUSkinningDataAttachment::create();
226 skel->addAttachment(data);
229 skel->renderEnter(action, skinGeo);
231 ShaderProgramChunkUnrecPtr shCode = data->getShaderCode();
233 if(shCode == NULL)
235 shCode = ShaderProgramChunk::create();
236 data->setShaderCode(shCode);
238 ShaderProgramUnrecPtr vp = ShaderProgram::createVertexShader();
239 vp->setProgram(_vpVertexSkinning);
241 shCode->addShader(vp);
243 vp->addUniformVariable(
244 "matJoints", (*skel->getMFJointMatrices()));
245 vp->addUniformVariable(
246 "matBindShape", skinGeo->getBindShapeMatrix());
248 else if(data->getDataValid() == false)
250 ShaderProgram *vp = shCode->getVertexShader(0);
251 OSG_ASSERT(vp != NULL);
253 vp->updateUniformVariable(
254 "matJoints", (*skel->getMFJointMatrices()));
255 vp->updateUniformVariable(
256 "matBindShape", skinGeo->getBindShapeMatrix());
258 data->setDataValid(true);
259 commitChanges();
262 ract->pushState();
264 ract->addOverride(ShaderProgramChunk::getStaticClassId(),
265 shCode );
267 res = skinGeo->SkinnedGeometry::Inherited::renderEnter(ract);
269 ract->popState ();
271 return res;
274 Action::ResultE
275 GPUSkinningAlgorithm::renderLeave(Action *action)
277 Action::ResultE res = Action::Continue;
278 SkinnedGeometry *skinGeo = getSkin();
279 Skeleton *skel = getSkeleton();
281 skel->renderLeave(action, skinGeo);
283 res = skinGeo->SkinnedGeometry::Inherited::renderLeave(action);
285 return res;
288 Action::ResultE
289 GPUSkinningAlgorithm::intersectEnter(Action *action)
291 SkinnedGeometry *skinGeo = getSkin();
293 return skinGeo->SkinnedGeometry::Inherited::intersectEnter(action);
296 GPUSkinningAlgorithm::RenderModeE
297 GPUSkinningAlgorithm::getRenderMode(void) const
299 return SkinnedGeometry::RMSkinnedGPU;
302 void GPUSkinningAlgorithm::changed(ConstFieldMaskArg whichField,
303 UInt32 origin,
304 BitVector details)
306 if((SkeletonFieldMask & whichField) != 0 &&
307 _sfSkeleton.getValue() != NULL )
309 if(_sfSkeleton.getValue()->hasChangedFunctor(boost::bind(
310 &GPUSkinningAlgorithm::skeletonChanged,
311 this, _1, _2, _3 )) == false)
313 _sfSkeleton.getValue()->addChangedFunctor(boost::bind(
314 &GPUSkinningAlgorithm::skeletonChanged,
315 this, _1, _2, _3 ),
316 "GPUSkinningAlgorithm::skeletonChanged");
320 Inherited::changed(whichField, origin, details);
323 void GPUSkinningAlgorithm::dump( UInt32 ,
324 const BitVector ) const
326 SLOG << "Dump GPUSkinningAlgorithm NI" << std::endl;
329 void
330 GPUSkinningAlgorithm::skeletonChanged(FieldContainer *fc,
331 ConstFieldMaskArg whichField,
332 UInt32 origin )
334 // if the skeleton was changed by a sync we don't invalidate
335 // the data - it either is updated by the same sync or
336 // the sync marks it as invalid.
338 if(//origin != ChangedOrigin::Sync &&
339 ((Skeleton::JointMatricesFieldMask |
340 Skeleton::JointsChangedFieldMask |
341 Skeleton::JointNormalMatricesFieldMask) & whichField) != 0)
343 OSG_ASSERT(fc == _sfSkeleton.getValue());
345 GPUSkinningDataAttachment *data =
346 getGPUSkinningData(_sfSkeleton.getValue());
348 if(data != NULL)
349 data->setDataValid(false);
353 void
354 GPUSkinningAlgorithm::resolveLinks(void)
356 if(_sfSkeleton.getValue() != NULL)
358 _sfSkeleton.getValue()->subChangedFunctor(boost::bind(
359 &GPUSkinningAlgorithm::skeletonChanged,
360 this, _1, _2, _3 ));
363 Inherited::resolveLinks();
366 #if 0
367 // renderEnter code that does not work because of problems with the
368 // way ProgVars are handled and how uniform locations are invalidated
370 ShaderProgramChunkUnrecPtr shCode = getShaderCode();
371 ShaderProgramVariableChunkUnrecPtr shData = getShaderData();
373 if(shCode == NULL)
375 shCode = ShaderProgramChunk::create();
376 setShaderCode(shCode);
378 ShaderProgramUnrecPtr vp = ShaderProgram::createVertexShader();
379 vp->setProgram(_vpVertexSkinning);
381 shCode->addShader(vp);
383 vp->addUniformVariable(
384 "matBindShape", skinGeo->getBindShapeMatrix());
385 vp->addUniformVariable(
386 "matJoints", (*skel->getMFJointMatrices()));
388 else
390 ShaderProgram *vp = shCode->getVertexShader(0);
392 vp->updateUniformVariable(
393 "matBindShape", skinGeo->getBindShapeMatrix());
394 vp->updateUniformVariable(
395 "matJoints", (*skel->getMFJointMatrices()));
398 #if 0
399 if(shData == NULL)
401 shData = ShaderProgramVariableChunk::create();
402 setShaderData(shData);
404 shData->addUniformVariable(
405 "matBindShape", skinGeo->getBindShapeMatrix());
406 shData->addUniformVariable(
407 "matJoints", (*skel->getMFJointMatrices()));
409 else
411 shData->updateUniformVariable(
412 "matBindShape", skinGeo->getBindShapeMatrix());
413 shData->updateUniformVariable(
414 "matJoints", (*skel->getMFJointMatrices()));
416 #endif
417 #endif
419 OSG_END_NAMESPACE