void akGeometryDeformer::LBSkinning( const btAlignedObjectArray<akMatrix4>* mpalette, const UTsize vtxCount, const float* weights, const UTsize weightsStride, const UTuint8* indices, const UTsize indicesStride, const akVector3* vtxSrc, const UTsize vtxSrcStride, akVector3* vtxDst, const UTsize vtxDstStride, const akVector3* normSrc, const UTsize normSrcStride, akVector3* normDst, const UTsize normDstStride) { const btAlignedObjectArray<akMatrix4>& matrices = *mpalette; for(unsigned int i=0; i<vtxCount; i++) { akMatrix4 mat(matrices[indices[0]] * weights[0]); if (weights[1]) mat += matrices[indices[1]] * weights[1]; if (weights[2]) mat += matrices[indices[2]] * weights[2]; if (weights[3]) mat += matrices[indices[3]] * weights[3]; // position *vtxDst = (mat * akVector4(*vtxSrc, 1.f)).getXYZ(); // normal inverseTranspose(mat); *normDst = (mat * akVector4(*normSrc, 0.0f)).getXYZ(); *normDst = normalize(*normDst); akAdvancePointer(normSrc, normSrcStride); akAdvancePointer(normDst, normDstStride); akAdvancePointer(weights, weightsStride); akAdvancePointer(indices, indicesStride); akAdvancePointer(vtxSrc, vtxSrcStride); akAdvancePointer(vtxDst, vtxDstStride); } }
const mat3 & Camera::normal() const { if (m_dirty) update(); if (!m_normal.isValid()) m_normal.setValue(inverseTranspose(mat3(view()))); return m_normal.value(); }
void Scene::createVertexNode() { _vgeode = new osg::Geode; _vgeode->setDataVariance(osg::Object::DYNAMIC); osg::Vec3f lightDir(1.0f, 1.0f, 1.0f); lightDir.normalize(); auto offsets = new osg::Uniform(osg::Uniform::FLOAT_VEC3, "offsets", Scene::VertexInstances); offsets->setDataVariance(osg::Object::DYNAMIC); auto stateSet = _vgeode->getOrCreateStateSet(); stateSet->setAttributeAndModes(_instancedProgram, osg::StateAttribute::ON); stateSet->addUniform(new osg::Uniform("ecLightDirection", lightDir)); stateSet->addUniform(new osg::Uniform("lightColor", osg::Vec3(1.0f, 1.0f, 1.0f))); stateSet->addUniform(offsets); osg::Vec3 scale(1.0f, 1.0f, 1.0f); osg::Vec4 color(0.25f, 0.25f, 0.25f, 1.0f); auto vertexMatrix = osg::Matrixf::scale(scale * 0.125f * 0.25f); auto normalMatrix = inverseTranspose(vertexMatrix); _vgeometry = new osgKaleido::PolyhedronGeometry("#27"); _vgeometry->setUseDisplayList(false); _vgeometry->setUseVertexBufferObjects(true); _vgeometry->update(nullptr); // Force geometry generation auto vertices = dynamic_cast<osg::Vec3Array*>(_vgeometry->getVertexArray()); if (vertices != nullptr) { transform(*vertices, vertexMatrix); } auto normals = dynamic_cast<osg::Vec3Array*>(_vgeometry->getNormalArray()); if (normals != nullptr) { transform(*normals, normalMatrix); } auto colors = dynamic_cast<osg::Vec4Array*>(_vgeometry->getColorArray()); if (colors != nullptr) { fill(*colors, color); } makeInstanced(_vgeometry, Scene::VertexInstances); auto size = 1.0f; osg::BoundingBox bb(-size, -size, -size, +size, +size, +size); _vgeometry->setInitialBound(bb); _vgeode->addDrawable(_vgeometry); addChild(_vgeode); }
void akGeometryDeformer::DLBSkinning( const btAlignedObjectArray<akMatrix4>* mpalette, const btAlignedObjectArray<akDualQuat>* dqpalette, const UTsize vtxCount, const float* weights, const UTsize weightsStride, const UTuint8* indices, const UTsize indicesStride, const akVector3* vtxSrc, const UTsize vtxSrcStride, akVector3* vtxDst, const UTsize vtxDstStride, const akVector3* normSrc, const UTsize normSrcStride, akVector3* normDst, const UTsize normDstStride) { const btAlignedObjectArray<akMatrix4>& matrices = *mpalette; const btAlignedObjectArray<akDualQuat>& dquats = *dqpalette; for(unsigned int i=0; i<vtxCount; i++) { // position 1st pass for non rigid part of the transformation using matrices akMatrix4 mat(matrices[indices[0]] * weights[0]); if (weights[1]) mat += matrices[indices[1]] * weights[1]; if (weights[2]) mat += matrices[indices[2]] * weights[2]; if (weights[3]) mat += matrices[indices[3]] * weights[3]; akVector3 tmpPos = (mat * akVector4(*vtxSrc, 1.f)).getXYZ(); // position 2nd pass for rigid transformation (rotaion & location) using dual quats akDualQuat dq = dquats[indices[0]] * weights[0]; if (weights[1]) dq += dquats[indices[1]] * weights[1]; if (weights[2]) dq += dquats[indices[2]] * weights[2]; if (weights[3]) dq += dquats[indices[3]] * weights[3]; dq /= length(dq.n); akVector3 ndxyz(dq.n.getXYZ()); akVector3 dxyz(dq.d.getXYZ()); *vtxDst = tmpPos + 2.0 * cross( ndxyz, cross(ndxyz, tmpPos) + dq.n.getW() * tmpPos ) + 2.0 * ( dq.n.getW() * dxyz - dq.d.getW() * ndxyz + cross(ndxyz, dxyz) ); // normal 1st pass inverseTranspose(mat); akVector3 tmpNorm = (mat * akVector4(*normSrc, 0.0f)).getXYZ(); // normal 2nd pass *normDst = tmpNorm + 2.0 * cross( ndxyz, cross(ndxyz, tmpNorm) + dq.n.getW() * tmpNorm ); *normDst = normalize(*normDst); akAdvancePointer(normSrc, normSrcStride); akAdvancePointer(normDst, normDstStride); akAdvancePointer(weights, weightsStride); akAdvancePointer(indices, indicesStride); akAdvancePointer(vtxSrc, vtxSrcStride); akAdvancePointer(vtxDst, vtxDstStride); } }
Sphere::Sphere(const Material &material, const vec3 ¢er, float radius, const mat4 &trans) : m(material), c(center), r(radius), t(trans) { inv_t = inverse(t); normal_mat = inverseTranspose(mat3(t)); }
/*------------------------------------------------------------------------------- * 関数説明 * モデルデータを描画します。 * 予めモデルデータを「FileDataLoad」関数で読み込んでおく必要があります。 * * ※本関数では描画のみしか実行しません * 「glClearColor, glClear, glViewport」などの設定は関数コール前に必要に応じて行ってください。 * 引数 * p_ModelViewMat :[I/ ] 描画に使用するモデルビューマトリクス * p_ProjectionMat :[I/ ] 描画に使用するプロジェクションマトリクス * 戻り値 * なし *-------------------------------------------------------------------------------*/ void ModelManager::DataDraw(const mat4 &p_ModelViewMat, const mat4 &p_ProjectionMat) { if (ModelFormat::UNDEFINED == m_ModelInfo.ModelFormat) { ERROR_MESSAGE("モデルデータを読み込んでいない状態で描画しようとしました。\n"\ "モデルデータの読み込みを行ってから描画を実行してください。"); return; } // シェーダープログラムの利用を開始する m_ModelShader->UseProgram(); //バッファーを有効化 glBindBuffer(GL_ARRAY_BUFFER, m_ModelInfo.BufferObj_v); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ModelInfo.BufferObj_i); ////////////////////////////////// // 必ず送る変数を先に設定 //頂点座標設定 m_ModelShader->EnableVertexAttribArray(m_attr_Position); m_ModelShader->VertexAttribPointer(m_attr_Position, m_ModelInfo.Position.size, m_ModelInfo.Position.type, m_ModelInfo.Position.normalized, m_ModelInfo.Position.stride, m_ModelInfo.Position.pointer); //モデルデータのフォーマットを設定 m_ModelShader->UniformXi(m_unif_ModelFormat, 1, static_cast<GLint>(m_ModelInfo.ModelFormat), 0, 0, 0); //モデルビューマトリクスを設定 m_ModelShader->UniformMatrixXfv(m_unif_ModelViewMat, 4, 1, GL_FALSE, &p_ModelViewMat); //プロジェクションマトリクスを設定 m_ModelShader->UniformMatrixXfv(m_unif_ProjectionMat, 4, 1, GL_FALSE, &p_ProjectionMat); //モデルビューマトリクスから回転成分を算出する mat4 RotateMat = inverseTranspose(p_ModelViewMat); //回転行列を設定 m_ModelShader->UniformMatrixXfv(m_unif_RotateMat, 4, 1, GL_FALSE, &RotateMat); ////////////////////////////////// // 残りの変数の初期値を設定 //法線 m_ModelShader->DisableVertexAttribArray(m_attr_Normal); m_ModelShader->VertexAttribXf(m_attr_Normal, 3, 0.0f, 0.0f, 0.0f, 0.0f); //カラー m_ModelShader->DisableVertexAttribArray(m_attr_Color); m_ModelShader->VertexAttribXf(m_attr_Color, 4, 0.0f, 0.0f, 0.0f, 0.0f); //テクスチャ座標 m_ModelShader->DisableVertexAttribArray(m_attr_TexCoord); m_ModelShader->VertexAttribXf(m_attr_TexCoord, 2, 0.0f, 0.0f, 0.0f, 0.0f); //カラー関連の係数 m_ModelShader->UniformXi(m_unif_Ambient, 1, 0, 0, 0, 0); m_ModelShader->UniformXi(m_unif_Diffuse, 1, 0, 0, 0, 0); m_ModelShader->UniformXi(m_unif_Specular, 1, 0, 0, 0, 0); m_ModelShader->UniformXi(m_unif_Shininess, 1, 0, 0, 0, 0); m_ModelShader->UniformXi(m_unif_Alpha, 1, 0, 0, 0, 0); //テクスチャフラグとテクスチャ m_ModelShader->UniformXi(m_unif_AmbientTexFlag, 1, 0, 0, 0, 0); m_ModelShader->UniformXi(m_unif_DiffuseTexFlag, 1, 0, 0, 0, 0); m_ModelShader->UniformXi(m_unif_SpecularTexFlag, 1, 0, 0, 0, 0); m_ModelShader->UniformXi(m_unif_BumpMapTexFlag, 1, 0, 0, 0, 0); m_ModelShader->UniformXi(m_unif_AmbientTex, 1, 0, 0, 0, 0); m_ModelShader->UniformXi(m_unif_DiffuseTex, 1, 0, 0, 0, 0); m_ModelShader->UniformXi(m_unif_SpecularTex, 1, 0, 0, 0, 0); m_ModelShader->UniformXi(m_unif_BumpMapTex, 1, 0, 0, 0, 0); ////////////////////////////////// // 以下のロケーションの設定はファイルフォーマットによって個別設定する必要あり // m_attr_Normal //法線 // m_attr_Color //カラー // m_attr_TexCoord //テクスチャ座標 // m_unif_xxxxx //カラー関連の係数 // m_unif_xxxxxTexFlag //テクスチャ有り・無しフラグ // m_unif_xxxxxTex //テクスチャ //深度テストを有効 glEnable(GL_DEPTH_TEST); //シェーダーへの設定(モデルファイルのフォーマットによって処理を分岐) switch (m_ModelInfo.ModelFormat) { //OBJファイル case ModelFormat::OBJ: //法線設定 m_ModelShader->EnableVertexAttribArray(m_attr_Normal); m_ModelShader->VertexAttribPointer(m_attr_Normal, m_ModelInfo.Normal.size, m_ModelInfo.Normal.type, m_ModelInfo.Normal.normalized, m_ModelInfo.Normal.stride, m_ModelInfo.Normal.pointer); //テクスチャ座標設定 m_ModelShader->EnableVertexAttribArray(m_attr_TexCoord); m_ModelShader->VertexAttribPointer(m_attr_TexCoord, m_ModelInfo.TexCoord.size, m_ModelInfo.TexCoord.type, m_ModelInfo.TexCoord.normalized, m_ModelInfo.TexCoord.stride, m_ModelInfo.TexCoord.pointer); break; //オリジナルフォーマットで穴あきのキューブデータ(エッジ有り) case ModelFormat::ORIGINAL_PIERCED_CUBE: //カラー設定 m_ModelShader->EnableVertexAttribArray(m_attr_Color); m_ModelShader->VertexAttribPointer(m_attr_Color, m_ModelInfo.Color.size, m_ModelInfo.Color.type, m_ModelInfo.Color.normalized, m_ModelInfo.Color.stride, m_ModelInfo.Color.pointer); break; //オリジナルフォーマットで穴あきのキューブデータ(エッジ有り) case ModelFormat::ORIGINAL_PIERCED_CUBE2: //カラー設定 m_ModelShader->EnableVertexAttribArray(m_attr_Color); m_ModelShader->VertexAttribPointer(m_attr_Color, m_ModelInfo.Color.size, m_ModelInfo.Color.type, m_ModelInfo.Color.normalized, m_ModelInfo.Color.stride, m_ModelInfo.Color.pointer); break; default: break; } //描画実行 for (auto &DrawElements : m_ModelInfo.DrawElements) { //描画実行(モデルファイルのフォーマットによって処理を分岐) switch (m_ModelInfo.ModelFormat) { //OBJファイル case ModelFormat::OBJ: { //テクスチャ(アンビエント)がある場合は設定する if (0 != m_ModelInfo.Material[DrawElements.MaterialIndex].ambientTexObj) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_ModelInfo.Material[DrawElements.MaterialIndex].ambientTexObj); m_ModelShader->UniformXi(m_unif_AmbientTexFlag, 1, 1, 0, 0, 0); m_ModelShader->UniformXi(m_unif_AmbientTex, 1, 0, 0, 0, 0); } else { m_ModelShader->UniformXi(m_unif_AmbientTexFlag, 1, 0, 0, 0, 0); } //テクスチャ(ディフューズ)がある場合は設定する if (0 != m_ModelInfo.Material[DrawElements.MaterialIndex].diffuseTexObj) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, m_ModelInfo.Material[DrawElements.MaterialIndex].diffuseTexObj); m_ModelShader->UniformXi(m_unif_DiffuseTexFlag, 1, 1, 0, 0, 0); m_ModelShader->UniformXi(m_unif_DiffuseTex, 1, 1, 0, 0, 0); } else { m_ModelShader->UniformXi(m_unif_DiffuseTexFlag, 1, 0, 0, 0, 0); } //テクスチャ(スペキュラ)がある場合は設定する if (0 != m_ModelInfo.Material[DrawElements.MaterialIndex].specularTexObj) { glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, m_ModelInfo.Material[DrawElements.MaterialIndex].specularTexObj); m_ModelShader->UniformXi(m_unif_SpecularTexFlag, 1, 1, 0, 0, 0); m_ModelShader->UniformXi(m_unif_SpecularTex, 1, 2, 0, 0, 0); } else { m_ModelShader->UniformXi(m_unif_SpecularTexFlag, 1, 0, 0, 0, 0); } //テクスチャ(バンプマップ)がある場合は設定する if (0 != m_ModelInfo.Material[DrawElements.MaterialIndex].bumpMapTexObj) { glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, m_ModelInfo.Material[DrawElements.MaterialIndex].bumpMapTexObj); m_ModelShader->UniformXi(m_unif_BumpMapTexFlag, 1, 1, 0, 0, 0); m_ModelShader->UniformXi(m_unif_BumpMapTex, 1, 3, 0, 0, 0); } else { m_ModelShader->UniformXi(m_unif_BumpMapTexFlag, 1, 0, 0, 0, 0); } //カラー関連の係数設定 m_ModelShader->UniformXf(m_unif_Ambient, 3, m_ModelInfo.Material[DrawElements.MaterialIndex].ambient.r, m_ModelInfo.Material[DrawElements.MaterialIndex].ambient.g, m_ModelInfo.Material[DrawElements.MaterialIndex].ambient.b, 0); m_ModelShader->UniformXf(m_unif_Diffuse, 3, m_ModelInfo.Material[DrawElements.MaterialIndex].diffuse.r, m_ModelInfo.Material[DrawElements.MaterialIndex].diffuse.g, m_ModelInfo.Material[DrawElements.MaterialIndex].diffuse.b, 0); m_ModelShader->UniformXf(m_unif_Specular, 3, m_ModelInfo.Material[DrawElements.MaterialIndex].specular.r, m_ModelInfo.Material[DrawElements.MaterialIndex].specular.g, m_ModelInfo.Material[DrawElements.MaterialIndex].specular.b, 0); m_ModelShader->UniformXf(m_unif_Shininess, 1, m_ModelInfo.Material[DrawElements.MaterialIndex].shininess, 0 ,0, 0); m_ModelShader->UniformXf(m_unif_Alpha, 1, m_ModelInfo.Material[DrawElements.MaterialIndex].alpha, 0, 0, 0); break; } default: break; } glDrawElements(DrawElements.mode, DrawElements.count, DrawElements.type, DrawElements.indices); } //シェーダーの変数を無効化 m_ModelShader->DisableVertexAttribArray(m_attr_Position); m_ModelShader->DisableVertexAttribArray(m_attr_Normal); m_ModelShader->DisableVertexAttribArray(m_attr_Color); m_ModelShader->DisableVertexAttribArray(m_attr_TexCoord); //バッファーを無効化 glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //テクスチャユニットフォデフォルトに戻す glActiveTexture(GL_TEXTURE0); //テクスチャを解除 glBindTexture(GL_TEXTURE_2D, 0); }