#include <dali-scene3d/internal/model-components/model-primitive-impl.h>
// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/image-loading.h>
+#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/public-api/object/type-registry.h>
-#include <dali/devel-api/adaptor-framework/image-loading.h>
// INTERNAL INCLUDES
+#include <dali-scene3d/internal/light/light-impl.h>
#include <dali-scene3d/internal/model-components/material-impl.h>
#include <dali-scene3d/public-api/loader/environment-definition.h>
+#include <dali/integration-api/debug.h>
+
namespace Dali
{
namespace Scene3D
DALI_TYPE_REGISTRATION_BEGIN(Scene3D::ModelPrimitive, Dali::BaseHandle, Create);
DALI_TYPE_REGISTRATION_END()
-constexpr std::string_view MORPH_KEYWORD = "MORPH";
-constexpr std::string_view MORPH_POSITION_KEYWORD = "MORPH_POSITION";
-constexpr std::string_view MORPH_NORMAL_KEYWORD = "MORPH_NORMAL";
-constexpr std::string_view MORPH_TANGENT_KEYWORD = "MORPH_TANGENT";
-constexpr std::string_view MORPH_VERSION_2_0_KEYWORD = "MORPH_VERSION_2_0";
+static constexpr uint32_t INDEX_FOR_LIGHT_CONSTRAINT_TAG = 10;
+
+Texture MakeEmptyTexture()
+{
+ PixelData pixelData = PixelData::New(new uint8_t[3]{0xff, 0xff, 0xff}, 3, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY);
+ Texture texture = Texture::New(TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight());
+ texture.Upload(pixelData, 0, 0, 0, 0, pixelData.GetWidth(), pixelData.GetHeight());
+
+ return texture;
+}
} // unnamed namespace
ModelPrimitivePtr ModelPrimitive::New()
}
ModelPrimitive::ModelPrimitive()
+: mShaderManager(new Scene3D::Loader::ShaderManager())
{
}
ApplyMaterialToRenderer();
}
}
+ UpdateShadowMapTexture();
UpdateImageBasedLightTexture();
}
}
mObservers.erase(observer);
}
+void ModelPrimitive::SetShadowMapTexture(Dali::Texture shadowMapTexture)
+{
+ mShadowMapTexture = shadowMapTexture;
+
+ UpdateShadowMapTexture();
+}
+
void ModelPrimitive::SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float iblScaleFactor, uint32_t specularMipmapLevels)
{
mDiffuseTexture = diffuseTexture;
}
}
+void ModelPrimitive::UpdateShader(Scene3D::Loader::ShaderManagerPtr shaderManager)
+{
+ if(mShaderManager != shaderManager)
+ {
+ mShaderManager = (shaderManager) ? shaderManager : new Scene3D::Loader::ShaderManager();
+ if(mMaterial && GetImplementation(mMaterial).IsResourceReady())
+ {
+ ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag::SHADER);
+ }
+ }
+}
+
void ModelPrimitive::SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeData& data)
{
mBlendShapeData = std::move(data);
- Scene3D::Loader::BlendShapes::ConfigureProperties(mBlendShapeData, mShader);
+ Scene3D::Loader::BlendShapes::ConfigureProperties(mBlendShapeData, mRenderer);
}
void ModelPrimitive::SetBlendShapeGeometry(Dali::Texture blendShapeGeometry)
mBlendShapeGeometry = blendShapeGeometry;
}
-void ModelPrimitive::SetBlendShapeOptions(bool hasPositions, bool hasNormals, bool hasTangents)
+void ModelPrimitive::SetBlendShapeOptions(bool hasPositions, bool hasNormals, bool hasTangents, Scene3D::Loader::BlendShapes::Version version)
{
- mHasPositions = hasPositions;
- mHasNormals = hasNormals;
- mHasTangents = hasTangents;
+ mHasPositions = hasPositions;
+ mHasNormals = hasNormals;
+ mHasTangents = hasTangents;
+ mBlendShapeVersion = version;
}
void ModelPrimitive::SetSkinned(bool isSkinned)
void ModelPrimitive::ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag flag)
{
+ if(!mMaterial)
+ {
+ return;
+ }
+
uint32_t shaderFlag = (flag & static_cast<uint32_t>(MaterialModifyObserver::ModifyFlag::SHADER));
if(mIsMaterialChanged || shaderFlag == static_cast<uint32_t>(MaterialModifyObserver::ModifyFlag::SHADER))
{
- std::string vertexShader = GetImplementation(mMaterial).GetVertexShader();
- std::string fragmentShader = GetImplementation(mMaterial).GetFragmentShader();
+ Scene3D::Loader::ShaderOption shaderOption = GetImplementation(mMaterial).GetShaderOption();
- std::vector<std::string> defines;
- defines.push_back("VEC4_TANGENT");
+ shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::VEC4_TANGENT);
if(mHasSkinning)
{
- defines.push_back("SKINNING");
+ shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::SKINNING);
}
if(mHasPositions || mHasNormals || mHasTangents)
{
if(mHasPositions)
{
- defines.push_back(MORPH_POSITION_KEYWORD.data());
+ shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::MORPH_POSITION);
}
if(mHasNormals)
{
- defines.push_back(MORPH_NORMAL_KEYWORD.data());
+ shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::MORPH_NORMAL);
}
if(mHasTangents)
{
- defines.push_back(MORPH_TANGENT_KEYWORD.data());
+ shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::MORPH_TANGENT);
}
- defines.push_back(MORPH_KEYWORD.data());
- if(mBlendShapeData.version == Scene3D::Loader::BlendShapes::Version::VERSION_2_0)
+ if(mBlendShapeVersion == Scene3D::Loader::BlendShapes::Version::VERSION_2_0)
{
- defines.push_back(MORPH_VERSION_2_0_KEYWORD.data());
+ shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::MORPH_VERSION_2_0);
}
}
- for(const auto& define : defines)
- {
- Scene3D::Loader::ShaderDefinition::ApplyDefine(vertexShader, define);
- }
mShader.Reset();
- mShader = Shader::New(vertexShader, fragmentShader);
- if(mBlendShapeData.version != Scene3D::Loader::BlendShapes::Version::INVALID && mBlendShapeData.mActor.GetHandle())
- {
- Scene3D::Loader::BlendShapes::ConfigureProperties(mBlendShapeData, mShader);
- }
+ mShader = mShaderManager->ProduceShader(shaderOption);
if(!mRenderer)
{
}
uint32_t textureCount = mTextureSet.GetTextureCount();
- Texture brdfTexture = Scene3D::Loader::EnvironmentDefinition::GetBrdfTexture();
+
+ if(!mShadowMapTexture)
+ {
+ mShadowMapTexture = MakeEmptyTexture();
+ }
+ mTextureSet.SetTexture(textureCount++, mShadowMapTexture);
+
+ Texture brdfTexture = Scene3D::Loader::EnvironmentDefinition::GetBrdfTexture();
if(!mSpecularTexture || !mDiffuseTexture)
{
Scene3D::Loader::EnvironmentMapData environmentMapData;
mRenderer = Renderer::New(mGeometry, mShader);
mRenderer.SetTextures(mTextureSet);
UpdateRendererUniform();
+
for(auto* observer : mObservers)
{
observer->OnRendererCreated(mRenderer);
}
}
+void ModelPrimitive::UpdateShadowMapTexture()
+{
+ if(mRenderer && mMaterial)
+ {
+ Dali::TextureSet textures = mRenderer.GetTextures();
+ if(!textures)
+ {
+ return;
+ }
+
+ uint32_t textureCount = textures.GetTextureCount();
+ if(mShadowMapTexture &&
+ textureCount >= GetImplementation(mMaterial).GetShadowMapTextureOffset() &&
+ textures.GetTexture(textureCount - GetImplementation(mMaterial).GetShadowMapTextureOffset()) != mShadowMapTexture)
+ {
+ Dali::TextureSet newTextures = Dali::TextureSet::New();
+
+ for(uint32_t index = 0u; index < textureCount; ++index)
+ {
+ Dali::Texture texture = textures.GetTexture(index);
+ if(index == textureCount - GetImplementation(mMaterial).GetShadowMapTextureOffset())
+ {
+ texture = (!!mShadowMapTexture) ? mShadowMapTexture : MakeEmptyTexture();
+ }
+
+ newTextures.SetTexture(index, texture);
+ newTextures.SetSampler(index, textures.GetSampler(index));
+ }
+
+ mRenderer.SetTextures(newTextures);
+ }
+ }
+}
+
void ModelPrimitive::UpdateImageBasedLightTexture()
{
if(mRenderer && mMaterial)
mRenderer.SetTextures(newTextures);
}
- mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightScaleFactorName() .data(), mIblScaleFactor);
+ mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightScaleFactorName().data(), mIblScaleFactor);
mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightMaxLodUniformName().data(), static_cast<float>(mSpecularMipmapLevels));
}
}
void ModelPrimitive::UpdateRendererUniform()
{
- mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightScaleFactorName().data(), mIblScaleFactor);
- mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightMaxLodUniformName().data(), static_cast<float>(mSpecularMipmapLevels));
- GetImplementation(mMaterial).SetRendererUniform(mRenderer);
+ if(mMaterial)
+ {
+ mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightScaleFactorName().data(), mIblScaleFactor);
+ mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightMaxLodUniformName().data(), static_cast<float>(mSpecularMipmapLevels));
+ GetImplementation(mMaterial).SetRendererUniform(mRenderer);
+ }
}
} // namespace Internal