1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "util/scene_util.h"
17
18 #include <3d/ecs/components/animation_component.h>
19 #include <3d/ecs/components/animation_output_component.h>
20 #include <3d/ecs/components/animation_track_component.h>
21 #include <3d/ecs/components/camera_component.h>
22 #include <3d/ecs/components/light_component.h>
23 #include <3d/ecs/components/local_matrix_component.h>
24 #include <3d/ecs/components/material_component.h>
25 #include <3d/ecs/components/mesh_component.h>
26 #include <3d/ecs/components/name_component.h>
27 #include <3d/ecs/components/node_component.h>
28 #include <3d/ecs/components/planar_reflection_component.h>
29 #include <3d/ecs/components/render_handle_component.h>
30 #include <3d/ecs/components/render_mesh_component.h>
31 #include <3d/ecs/components/skin_joints_component.h>
32 #include <3d/ecs/components/transform_component.h>
33 #include <3d/ecs/components/uri_component.h>
34 #include <3d/ecs/components/world_matrix_component.h>
35 #include <3d/ecs/systems/intf_animation_system.h>
36 #include <3d/intf_graphics_context.h>
37 #include <3d/render/default_material_constants.h>
38 #include <3d/util/intf_mesh_util.h>
39 #include <base/containers/fixed_string.h>
40 #include <core/ecs/intf_ecs.h>
41 #include <core/ecs/intf_entity_manager.h>
42 #include <core/intf_engine.h>
43 #include <core/namespace.h>
44 #include <core/property/intf_property_handle.h>
45 #include <render/device/intf_gpu_resource_manager.h>
46 #include <render/device/intf_shader_manager.h>
47 #include <render/intf_render_context.h>
48
49 #include "uri_lookup.h"
50 #include "util/component_util_functions.h"
51 #include "util/string_util.h"
52
53 CORE3D_BEGIN_NAMESPACE()
54 using namespace BASE_NS;
55 using namespace CORE_NS;
56 using namespace RENDER_NS;
57
SceneUtil(IGraphicsContext & graphicsContext)58 SceneUtil::SceneUtil(IGraphicsContext& graphicsContext) : graphicsContext_(graphicsContext) {}
59
CreateCamera(IEcs & ecs,const Math::Vec3 & position,const Math::Quat & rotation,float zNear,float zFar,float fovDegrees) const60 Entity SceneUtil::CreateCamera(
61 IEcs& ecs, const Math::Vec3& position, const Math::Quat& rotation, float zNear, float zFar, float fovDegrees) const
62 {
63 IEntityManager& em = ecs.GetEntityManager();
64 const Entity camera = em.Create();
65
66 auto lmm = GetManager<ILocalMatrixComponentManager>(ecs);
67 lmm->Create(camera);
68
69 auto wmm = GetManager<IWorldMatrixComponentManager>(ecs);
70 wmm->Create(camera);
71
72 auto ncm = GetManager<INodeComponentManager>(ecs);
73 ncm->Create(camera);
74
75 auto tcm = GetManager<ITransformComponentManager>(ecs);
76 TransformComponent tc;
77 tc.position = position;
78 tc.rotation = rotation;
79 tcm->Set(camera, tc);
80
81 auto ccm = GetManager<ICameraComponentManager>(ecs);
82 CameraComponent cc;
83 cc.sceneFlags |= CameraComponent::SceneFlagBits::ACTIVE_RENDER_BIT;
84 cc.projection = CameraComponent::Projection::PERSPECTIVE;
85 cc.yFov = Math::DEG2RAD * fovDegrees;
86 cc.zNear = zNear;
87 cc.zFar = zFar;
88 ccm->Set(camera, cc);
89
90 return camera;
91 }
92
UpdateCameraViewport(IEcs & ecs,Entity entity,const Math::UVec2 & renderResolution) const93 void SceneUtil::UpdateCameraViewport(IEcs& ecs, Entity entity, const Math::UVec2& renderResolution) const
94 {
95 auto ccm = GetManager<ICameraComponentManager>(ecs);
96 if (ccm && CORE_NS::EntityUtil::IsValid(entity)) {
97 CameraComponent cameraComponent = ccm->Get(entity);
98 cameraComponent.aspect =
99 (renderResolution.y > 0) ? (static_cast<float>(renderResolution.x) / renderResolution.y) : 1.0f;
100 cameraComponent.renderResolution[0] = renderResolution.x;
101 cameraComponent.renderResolution[1] = renderResolution.y;
102
103 ccm->Set(entity, cameraComponent);
104 }
105 }
106
UpdateCameraViewport(IEcs & ecs,Entity entity,const Math::UVec2 & renderResolution,bool autoAspect,float fovY,float orthoScale) const107 void SceneUtil::UpdateCameraViewport(
108 IEcs& ecs, Entity entity, const Math::UVec2& renderResolution, bool autoAspect, float fovY, float orthoScale) const
109 {
110 auto ccm = GetManager<ICameraComponentManager>(ecs);
111 if (ccm && CORE_NS::EntityUtil::IsValid(entity)) {
112 CameraComponent cameraComponent = ccm->Get(entity);
113 if (autoAspect) {
114 const float aspectRatio =
115 (renderResolution.y > 0) ? (static_cast<float>(renderResolution.x) / renderResolution.y) : 1.0f;
116
117 // Using the fov value as xfov on portrait screens to keep the object
118 // better in the frame.
119 const float yFov = (aspectRatio > 1.0f) ? fovY : (2.0f * Math::atan(Math::tan(fovY * 0.5f) / aspectRatio));
120
121 // Update the camera parameters.
122 cameraComponent.aspect = aspectRatio;
123 cameraComponent.yFov = yFov;
124
125 // The camera can also be in ortho mode. Using a separate zoom value.
126 cameraComponent.yMag = orthoScale;
127 cameraComponent.xMag = cameraComponent.yMag * aspectRatio;
128 }
129
130 cameraComponent.renderResolution[0] = renderResolution.x;
131 cameraComponent.renderResolution[1] = renderResolution.y;
132
133 ccm->Set(entity, cameraComponent);
134 }
135 }
136
CreateLight(IEcs & ecs,const LightComponent & lightComponent,const Math::Vec3 & position,const Math::Quat & rotation) const137 Entity SceneUtil::CreateLight(
138 IEcs& ecs, const LightComponent& lightComponent, const Math::Vec3& position, const Math::Quat& rotation) const
139 {
140 IEntityManager& em = ecs.GetEntityManager();
141 const Entity light = em.Create();
142
143 auto lmm = GetManager<ILocalMatrixComponentManager>(ecs);
144 lmm->Create(light);
145
146 auto wmm = GetManager<IWorldMatrixComponentManager>(ecs);
147 wmm->Create(light);
148
149 auto ncm = GetManager<INodeComponentManager>(ecs);
150 ncm->Create(light);
151
152 auto nameM = GetManager<INameComponentManager>(ecs);
153 nameM->Create(light);
154 constexpr string_view lightName("Light");
155 nameM->Write(light)->name = lightName;
156
157 auto tcm = GetManager<ITransformComponentManager>(ecs);
158 TransformComponent tc;
159 tc.position = position;
160 tc.rotation = rotation;
161 tcm->Set(light, tc);
162
163 auto lcm = GetManager<ILightComponentManager>(ecs);
164 LightComponent lc = lightComponent;
165 lc.shadowEnabled = (lc.type == LightComponent::Type::POINT) ? false : lc.shadowEnabled;
166 lc.range = ComponentUtilFunctions::CalculateSafeLightRange(lc.range, lc.intensity);
167 lcm->Set(light, lc);
168
169 return light;
170 }
171
172 // reflection plane helpers
173 namespace {
174 // default size, updated in render system based on main scene camera
175 constexpr Math::UVec2 DEFAULT_PLANE_TARGET_SIZE { 2u, 2u };
176
CreateReflectionPlaneGpuImage(IGpuResourceManager & gpuResourceMgr,IRenderHandleComponentManager & handleManager,INameComponentManager & nameManager,const string_view name,const Format format,const ImageUsageFlags usageFlags)177 EntityReference CreateReflectionPlaneGpuImage(IGpuResourceManager& gpuResourceMgr,
178 IRenderHandleComponentManager& handleManager, INameComponentManager& nameManager, const string_view name,
179 const Format format, const ImageUsageFlags usageFlags)
180 {
181 const auto entity = handleManager.GetEcs().GetEntityManager().CreateReferenceCounted();
182 handleManager.Create(entity);
183
184 GpuImageDesc desc;
185 desc.width = DEFAULT_PLANE_TARGET_SIZE.x;
186 desc.height = DEFAULT_PLANE_TARGET_SIZE.y;
187 desc.depth = 1;
188 desc.format = format;
189 desc.memoryPropertyFlags = MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
190 desc.usageFlags = usageFlags;
191 desc.imageType = ImageType::CORE_IMAGE_TYPE_2D;
192 desc.imageTiling = ImageTiling::CORE_IMAGE_TILING_OPTIMAL;
193 desc.imageViewType = ImageViewType::CORE_IMAGE_VIEW_TYPE_2D;
194 desc.engineCreationFlags = EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS;
195 handleManager.Write(entity)->reference = gpuResourceMgr.Create(name, desc);
196
197 nameManager.Create(entity);
198 nameManager.Write(entity)->name = name;
199 return entity;
200 }
201
CreateReflectionPlaneObjectFromEntity(IEcs & ecs,IGraphicsContext & graphicsContext,const Entity & nodeEntity)202 SceneUtil::ReflectionPlane CreateReflectionPlaneObjectFromEntity(
203 IEcs& ecs, IGraphicsContext& graphicsContext, const Entity& nodeEntity)
204 {
205 SceneUtil::ReflectionPlane plane;
206 IRenderMeshComponentManager* renderMeshCM = GetManager<IRenderMeshComponentManager>(ecs);
207 IMeshComponentManager* meshCM = GetManager<IMeshComponentManager>(ecs);
208 IMaterialComponentManager* matCM = GetManager<IMaterialComponentManager>(ecs);
209 IRenderHandleComponentManager* gpuHandleCM = GetManager<IRenderHandleComponentManager>(ecs);
210
211 INameComponentManager* nameCM = GetManager<INameComponentManager>(ecs);
212 if (!(renderMeshCM && meshCM && matCM && gpuHandleCM && nameCM)) {
213 return plane;
214 }
215
216 auto& device = graphicsContext.GetRenderContext().GetDevice();
217 auto& gpuResourceMgr = device.GetGpuResourceManager();
218 plane.entity = nodeEntity;
219 plane.colorTarget = CreateReflectionPlaneGpuImage(gpuResourceMgr, *gpuHandleCM, *nameCM,
220 DefaultMaterialCameraConstants::CAMERA_COLOR_PREFIX_NAME + to_hex(nodeEntity.id),
221 Format::BASE_FORMAT_R8G8B8A8_SRGB,
222 ImageUsageFlagBits::CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | ImageUsageFlagBits::CORE_IMAGE_USAGE_SAMPLED_BIT);
223
224 // NOTE: uses transient attachement usage flag and cannot be read.
225 plane.depthTarget = CreateReflectionPlaneGpuImage(gpuResourceMgr, *gpuHandleCM, *nameCM,
226 DefaultMaterialCameraConstants::CAMERA_DEPTH_PREFIX_NAME + to_hex(nodeEntity.id), Format::BASE_FORMAT_D16_UNORM,
227 ImageUsageFlagBits::CORE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
228 ImageUsageFlagBits::CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT);
229
230 if (const auto rmcHandle = renderMeshCM->Read(nodeEntity); rmcHandle) {
231 const RenderMeshComponent& rmc = *rmcHandle;
232 if (const auto meshHandle = meshCM->Read(rmc.mesh); meshHandle) {
233 const MeshComponent& meshComponent = *meshHandle;
234 if (!meshComponent.submeshes.empty()) {
235 if (auto matHandle = matCM->Write(meshComponent.submeshes[0].material); matHandle) {
236 MaterialComponent& matComponent = *matHandle;
237 auto* uriCM = GetManager<IUriComponentManager>(ecs);
238 auto* renderHandleCM = GetManager<IRenderHandleComponentManager>(ecs);
239 constexpr const string_view uri = "3dshaders://shader/core3d_dm_fw_reflection_plane.shader";
240 auto shaderEntity = LookupResourceByUri(uri, *uriCM, *renderHandleCM);
241 if (!EntityUtil::IsValid(shaderEntity)) {
242 shaderEntity = ecs.GetEntityManager().Create();
243 renderHandleCM->Create(shaderEntity);
244 renderHandleCM->Write(shaderEntity)->reference = device.GetShaderManager().GetShaderHandle(uri);
245 uriCM->Create(shaderEntity);
246 uriCM->Write(shaderEntity)->uri = uri;
247 }
248 matComponent.materialShader.shader = ecs.GetEntityManager().GetReferenceCounted(shaderEntity);
249 matComponent.textures[MaterialComponent::TextureIndex::SHEEN].image = plane.colorTarget;
250 matComponent.extraRenderingFlags = MaterialComponent::ExtraRenderingFlagBits::DISCARD_BIT;
251 }
252 }
253 }
254 }
255
256 return plane;
257 }
258 } // namespace
259
CreateReflectionPlaneComponent(IEcs & ecs,const Entity & nodeEntity)260 void SceneUtil::CreateReflectionPlaneComponent(IEcs& ecs, const Entity& nodeEntity)
261 {
262 SceneUtil::ReflectionPlane plane = CreateReflectionPlaneObjectFromEntity(ecs, graphicsContext_, nodeEntity);
263 if (EntityUtil::IsValid(plane.entity)) {
264 auto prcm = GetManager<IPlanarReflectionComponentManager>(ecs);
265 PlanarReflectionComponent prc;
266 prc.colorRenderTarget = plane.colorTarget;
267 prc.depthRenderTarget = plane.depthTarget;
268 prc.renderTargetResolution[0] = DEFAULT_PLANE_TARGET_SIZE.x;
269 prc.renderTargetResolution[1] = DEFAULT_PLANE_TARGET_SIZE.y;
270 prcm->Set(plane.entity, prc);
271 }
272 }
273
CalculateScalingFactor(IEcs & ecs,Entity targetEntity,Entity sourceEntity)274 float CalculateScalingFactor(IEcs& ecs, Entity targetEntity, Entity sourceEntity)
275 {
276 float scale = 1.f;
277 auto renderMeshManager = GetManager<IRenderMeshComponentManager>(ecs);
278 auto meshManager = GetManager<IMeshComponentManager>(ecs);
279 auto transformManager = GetManager<ITransformComponentManager>(ecs);
280 if (!renderMeshManager || !meshManager || !transformManager) {
281 return scale;
282 }
283
284 Entity dstMeshEntity;
285 Entity srcMeshEntity;
286 if (auto renderMeshComponent = renderMeshManager->Read(targetEntity); renderMeshComponent) {
287 dstMeshEntity = renderMeshComponent->mesh;
288 }
289 if (auto renderMeshComponent = renderMeshManager->Read(sourceEntity); renderMeshComponent) {
290 srcMeshEntity = renderMeshComponent->mesh;
291 }
292 if (!EntityUtil::IsValid(dstMeshEntity) || !EntityUtil::IsValid(srcMeshEntity)) {
293 return scale;
294 }
295 auto getMeshHeight = [](IMeshComponentManager& meshManager, Entity entity) {
296 if (auto meshComponent = meshManager.Read(entity); meshComponent) {
297 return (meshComponent->aabbMax.y - meshComponent->aabbMin.y);
298 }
299 return 0.f;
300 };
301
302 const float dstHeight = getMeshHeight(*meshManager, dstMeshEntity);
303 const float srcHeight = getMeshHeight(*meshManager, srcMeshEntity);
304 if ((dstHeight == 0.f) || (srcHeight == 0.f)) {
305 return scale;
306 }
307
308 auto dstMeshScale = transformManager->Get(targetEntity).scale;
309 auto srcMeshScale = transformManager->Get(sourceEntity).scale;
310 const auto dstSize = dstHeight * dstMeshScale.y;
311 const auto srcSize = srcHeight * srcMeshScale.y;
312 if (srcSize == 0.f) {
313 return scale;
314 }
315 scale = dstSize / srcSize;
316 return scale;
317 }
318
CreateJointMapping(IEcs & ecs,array_view<const Entity> dstJointEntities,array_view<const Entity> srcJointEntities)319 vector<Entity> CreateJointMapping(
320 IEcs& ecs, array_view<const Entity> dstJointEntities, array_view<const Entity> srcJointEntities)
321 {
322 vector<Entity> srcToDstJointMapping;
323
324 auto getName = [nameManager = GetManager<INameComponentManager>(ecs)](const Entity& jointEntity) -> string_view {
325 if (auto nameComponent = nameManager->Read(jointEntity); nameComponent) {
326 return nameComponent->name;
327 }
328 return {};
329 };
330
331 vector<string_view> dstJointNames;
332 dstJointNames.reserve(dstJointEntities.size());
333 std::transform(dstJointEntities.begin(), dstJointEntities.end(), std::back_inserter(dstJointNames), getName);
334
335 vector<string_view> srcJointNames;
336 srcJointNames.reserve(srcJointEntities.size());
337 std::transform(srcJointEntities.begin(), srcJointEntities.end(), std::back_inserter(srcJointNames), getName);
338
339 srcToDstJointMapping.reserve(srcJointEntities.size());
340
341 const auto dstJointNamesBegin = dstJointNames.cbegin();
342 const auto dstJointNamesEnd = dstJointNames.cend();
343 for (const auto& srcJointName : srcJointNames) {
344 const auto pos = std::find(dstJointNamesBegin, dstJointNamesEnd, srcJointName);
345 srcToDstJointMapping.push_back(
346 (pos != dstJointNamesEnd) ? dstJointEntities[static_cast<size_t>(std::distance(dstJointNamesBegin, pos))]
347 : Entity {});
348 if (pos == dstJointNamesEnd) {
349 CORE_LOG_W("Target skin missing joint %s", srcJointName.data());
350 }
351 }
352 return srcToDstJointMapping;
353 }
354
UpdateTracks(IEcs & ecs,array_view<EntityReference> targetTracks,array_view<const EntityReference> sourceTracks,array_view<const Entity> srcJointEntities,array_view<const Entity> srcToDstJointMapping,float scale)355 vector<Entity> UpdateTracks(IEcs& ecs, array_view<EntityReference> targetTracks,
356 array_view<const EntityReference> sourceTracks, array_view<const Entity> srcJointEntities,
357 array_view<const Entity> srcToDstJointMapping, float scale)
358 {
359 vector<Entity> trackTargets;
360 trackTargets.reserve(sourceTracks.size());
361 auto& entityManager = ecs.GetEntityManager();
362 auto animationTrackManager = GetManager<IAnimationTrackComponentManager>(ecs);
363 auto animationOutputManager = GetManager<IAnimationOutputComponentManager>(ecs);
364 // update tracks to point to target skin's joints.
365 std::transform(sourceTracks.begin(), sourceTracks.end(), targetTracks.begin(),
366 [&entityManager, animationTrackManager, animationOutputManager, &srcJointEntities, &srcToDstJointMapping,
367 &trackTargets, scale](const EntityReference& srcTrackEntity) {
368 const auto srcTargetEntity = animationTrackManager->Read(srcTrackEntity)->target;
369 // check that the src track target is one of the src joints
370 if (const auto pos = std::find(srcJointEntities.begin(), srcJointEntities.end(), srcTargetEntity);
371 pos != srcJointEntities.end()) {
372 auto dstTrackEntity = entityManager.CreateReferenceCounted();
373 animationTrackManager->Create(dstTrackEntity);
374 auto dstTrack = animationTrackManager->Write(dstTrackEntity);
375 auto srcTrack = animationTrackManager->Read(srcTrackEntity);
376 *dstTrack = *srcTrack;
377 const auto jointIndex = (pos - srcJointEntities.begin());
378 trackTargets.push_back(srcToDstJointMapping[jointIndex]);
379 dstTrack->target = {};
380
381 // joint position track needs to be offset
382 if ((dstTrack->component == ITransformComponentManager::UID) && (dstTrack->property == "position")) {
383 // create new animation output with original position corrected by the scale.
384 dstTrack->data = entityManager.CreateReferenceCounted();
385 animationOutputManager->Create(dstTrack->data);
386 const auto dstOutput = animationOutputManager->Write(dstTrack->data);
387 const auto srcOutput = animationOutputManager->Read(srcTrack->data);
388 dstOutput->type = srcOutput->type;
389 auto& dst = dstOutput->data;
390 const auto& src = srcOutput->data;
391 dst.resize(src.size());
392 const auto count = dst.size() / sizeof(Math::Vec3);
393 const auto srcPositions = array_view(reinterpret_cast<const Math::Vec3*>(src.data()), count);
394 auto dstPositions = array_view(reinterpret_cast<Math::Vec3*>(dst.data()), count);
395 std::transform(srcPositions.begin(), srcPositions.end(), dstPositions.begin(),
396 [scale](const Math::Vec3 position) { return position * scale; });
397 }
398 return dstTrackEntity;
399 }
400 return srcTrackEntity;
401 });
402 return trackTargets;
403 }
404
RetargetSkinAnimation(IEcs & ecs,Entity targetEntity,Entity sourceEntity,Entity animationEntity) const405 IAnimationPlayback* SceneUtil::RetargetSkinAnimation(
406 IEcs& ecs, Entity targetEntity, Entity sourceEntity, Entity animationEntity) const
407 {
408 auto jointsManager = GetManager<ISkinJointsComponentManager>(ecs);
409 auto dstJointsComponent = jointsManager->Read(targetEntity);
410 auto srcJointsComponent = jointsManager->Read(sourceEntity);
411 if (!dstJointsComponent || !srcJointsComponent) {
412 return nullptr;
413 }
414 if (!GetManager<IAnimationComponentManager>(ecs)->HasComponent(animationEntity)) {
415 return nullptr;
416 }
417
418 auto dstJointEntities = array_view(dstJointsComponent->jointEntities, dstJointsComponent->count);
419 auto srcJointEntities = array_view(srcJointsComponent->jointEntities, srcJointsComponent->count);
420
421 const vector<Entity> srcToDstJointMapping = CreateJointMapping(ecs, dstJointEntities, srcJointEntities);
422
423 // calculate a scaling factor based on mesh heights
424 const auto scale = CalculateScalingFactor(ecs, targetEntity, sourceEntity);
425
426 // compensate difference in root joint positions.
427 // synchronize initial pose by copying src joint rotations to dst joints.
428 {
429 auto transformManager = GetManager<ITransformComponentManager>(ecs);
430 auto srcIt = srcJointEntities.begin();
431 for (const auto& dstE : srcToDstJointMapping) {
432 auto srcTransform = transformManager->Read(*srcIt);
433 auto dstTransform = transformManager->Write(dstE);
434 if (srcTransform && dstTransform) {
435 dstTransform->position = srcTransform->position * scale;
436 dstTransform->rotation = srcTransform->rotation;
437 }
438 ++srcIt;
439 }
440 }
441
442 auto& entityManager = ecs.GetEntityManager();
443 const auto dstAnimationEntity = entityManager.Create();
444 {
445 INameComponentManager* nameManager = GetManager<INameComponentManager>(ecs);
446 nameManager->Create(dstAnimationEntity);
447 nameManager->Write(dstAnimationEntity)->name = nameManager->Read(animationEntity)->name + " retargeted";
448 }
449
450 vector<Entity> trackTargets;
451 {
452 auto animationManager = GetManager<IAnimationComponentManager>(ecs);
453 animationManager->Create(dstAnimationEntity);
454 auto dstAnimationComponent = animationManager->Write(dstAnimationEntity);
455 auto srcAnimationComponent = animationManager->Read(animationEntity);
456 if (!srcAnimationComponent) {
457 return nullptr;
458 }
459 // copy the src animation.
460 *dstAnimationComponent = *srcAnimationComponent;
461 trackTargets = UpdateTracks(ecs, dstAnimationComponent->tracks, srcAnimationComponent->tracks, srcJointEntities,
462 srcToDstJointMapping, scale);
463 }
464 auto animationSystem = GetSystem<IAnimationSystem>(ecs);
465 return animationSystem->CreatePlayback(dstAnimationEntity, trackTargets);
466 }
467
GetDefaultMaterialShaderData(IEcs & ecs,const ISceneUtil::MaterialShaderInfo & info,MaterialComponent::Shader & materialShader,MaterialComponent::Shader & depthShader) const468 void SceneUtil::GetDefaultMaterialShaderData(IEcs& ecs, const ISceneUtil::MaterialShaderInfo& info,
469 MaterialComponent::Shader& materialShader, MaterialComponent::Shader& depthShader) const
470 {
471 IRenderHandleComponentManager* renderHandleMgr = GetManager<IRenderHandleComponentManager>(ecs);
472 if (renderHandleMgr) {
473 IEntityManager& entityMgr = ecs.GetEntityManager();
474 const IShaderManager& shaderMgr = graphicsContext_.GetRenderContext().GetDevice().GetShaderManager();
475 {
476 const uint32_t renderSlotId =
477 (info.alphaBlend)
478 ? shaderMgr.GetRenderSlotId(DefaultMaterialShaderConstants::RENDER_SLOT_FORWARD_TRANSLUCENT)
479 : shaderMgr.GetRenderSlotId(DefaultMaterialShaderConstants::RENDER_SLOT_FORWARD_OPAQUE);
480
481 const IShaderManager::RenderSlotData rsd = shaderMgr.GetRenderSlotData(renderSlotId);
482 materialShader.shader = GetOrCreateEntityReference(entityMgr, *renderHandleMgr, rsd.shader);
483 RENDER_NS::GraphicsState gs = shaderMgr.GetGraphicsState(rsd.graphicsState);
484 gs.rasterizationState.cullModeFlags = info.cullModeFlags;
485 gs.rasterizationState.frontFace = info.frontFace;
486 const uint64_t gsHash = shaderMgr.HashGraphicsState(gs);
487 const RenderHandleReference gsHandle = shaderMgr.GetGraphicsStateHandleByHash(gsHash);
488 if (gsHandle) {
489 materialShader.graphicsState = GetOrCreateEntityReference(entityMgr, *renderHandleMgr, gsHandle);
490 }
491 }
492 if (!info.alphaBlend) {
493 const uint32_t renderSlotId = shaderMgr.GetRenderSlotId(DefaultMaterialShaderConstants::RENDER_SLOT_DEPTH);
494 const IShaderManager::RenderSlotData rsd = shaderMgr.GetRenderSlotData(renderSlotId);
495 depthShader.shader = GetOrCreateEntityReference(entityMgr, *renderHandleMgr, rsd.shader);
496 RENDER_NS::GraphicsState gs = shaderMgr.GetGraphicsState(rsd.graphicsState);
497 gs.rasterizationState.cullModeFlags = info.cullModeFlags;
498 gs.rasterizationState.frontFace = info.frontFace;
499 const uint64_t gsHash = shaderMgr.HashGraphicsState(gs);
500 const RenderHandleReference gsHandle = shaderMgr.GetGraphicsStateHandleByHash(gsHash);
501 if (gsHandle) {
502 depthShader.graphicsState = GetOrCreateEntityReference(entityMgr, *renderHandleMgr, gsHandle);
503 }
504 }
505 }
506 }
507
GetDefaultMaterialShaderData(IEcs & ecs,const ISceneUtil::MaterialShaderInfo & info,const string_view renderSlot,MaterialComponent::Shader & shader) const508 void SceneUtil::GetDefaultMaterialShaderData(IEcs& ecs, const ISceneUtil::MaterialShaderInfo& info,
509 const string_view renderSlot, MaterialComponent::Shader& shader) const
510 {
511 IRenderHandleComponentManager* renderHandleMgr = GetManager<IRenderHandleComponentManager>(ecs);
512 if (renderHandleMgr) {
513 IEntityManager& entityMgr = ecs.GetEntityManager();
514 const IShaderManager& shaderMgr = graphicsContext_.GetRenderContext().GetDevice().GetShaderManager();
515 const uint32_t renderSlotId = shaderMgr.GetRenderSlotId(renderSlot);
516 if (renderSlotId != ~0u) {
517 const IShaderManager::RenderSlotData rsd = shaderMgr.GetRenderSlotData(renderSlotId);
518 if (rsd.shader) {
519 shader.shader = GetOrCreateEntityReference(entityMgr, *renderHandleMgr, rsd.shader);
520 } else {
521 CORE_LOG_D("SceneUtil: render slot base shader not found (%s)", renderSlot.data());
522 }
523 if (rsd.graphicsState) {
524 RENDER_NS::GraphicsState gs = shaderMgr.GetGraphicsState(rsd.graphicsState);
525 gs.rasterizationState.cullModeFlags = info.cullModeFlags;
526 gs.rasterizationState.frontFace = info.frontFace;
527 const uint64_t gsHash = shaderMgr.HashGraphicsState(gs);
528 const RenderHandleReference gsHandle = shaderMgr.GetGraphicsStateHandleByHash(gsHash);
529 shader.graphicsState = GetOrCreateEntityReference(entityMgr, *renderHandleMgr, gsHandle);
530 } else {
531 CORE_LOG_D("SceneUtil: render slot base graphics state not found (%s)", renderSlot.data());
532 }
533 } else {
534 CORE_LOG_W("SceneUtil: render slot id not found (%s)", renderSlot.data());
535 }
536 }
537 }
538 CORE3D_END_NAMESPACE()
539