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);
    }
}
Пример #2
0
const mat3 & Camera::normal() const
{
    if (m_dirty)
        update();

    if (!m_normal.isValid())
        m_normal.setValue(inverseTranspose(mat3(view())));

    return m_normal.value();
}
Пример #3
0
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);
    }
}
Пример #5
0
Sphere::Sphere(const Material &material,
    const vec3 &center, float radius,
    const mat4 &trans) : m(material), c(center), r(radius), t(trans) {
    inv_t = inverse(t);
    normal_mat = inverseTranspose(mat3(t));
}
Пример #6
0
/*-------------------------------------------------------------------------------
*	関数説明
*	 モデルデータを描画します。
*	 予めモデルデータを「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);
}