9061 lines
337 KiB
C++
9061 lines
337 KiB
C++
#include "Scripting/Mono/MonoScriptRuntime.h"
|
|
|
|
#include "Components/CameraComponent.h"
|
|
#include "Components/GameObject.h"
|
|
#include "Components/LightComponent.h"
|
|
#include "Components/MeshFilterComponent.h"
|
|
#include "Components/MeshRendererComponent.h"
|
|
#include "Components/RigidbodyComponent.h"
|
|
#include "Components/TransformComponent.h"
|
|
#include "Debug/Logger.h"
|
|
#include "Input/InputManager.h"
|
|
#include "Physics/PhysicsWorld.h"
|
|
#include "Rendering/Caches/DirectionalShadowSurfaceCache.h"
|
|
#include "Rendering/Execution/CameraFramePlan.h"
|
|
#include "Rendering/Execution/DirectionalShadowExecutionState.h"
|
|
#include "Rendering/Execution/CameraFrameRenderGraphFrameData.h"
|
|
#include "Rendering/Execution/Internal/CameraFrameGraph/SurfaceUtils.h"
|
|
#include "Rendering/Graph/RenderGraph.h"
|
|
#include "Rendering/Graph/RenderGraphRecordingContext.h"
|
|
#include "Rendering/GraphicsSettingsState.h"
|
|
#include "Rendering/Internal/RenderPipelineFactory.h"
|
|
#include "Rendering/Passes/BuiltinFinalColorPass.h"
|
|
#include "Rendering/Passes/BuiltinVectorFullscreenPass.h"
|
|
#include "Rendering/Planning/FullscreenPassDesc.h"
|
|
#include "Rendering/Planning/SceneRenderRequestPlanner.h"
|
|
#include "Rendering/Pipelines/NativeSceneRecorder.h"
|
|
#include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h"
|
|
#include "Rendering/RenderPassGraphContract.h"
|
|
#include "Rendering/RenderPipeline.h"
|
|
#include "Rendering/RenderPipelineAsset.h"
|
|
#include "Rendering/RenderPipelineStageGraphContract.h"
|
|
#include "Resources/BuiltinResources.h"
|
|
#include "Core/Asset/ResourceManager.h"
|
|
#include "Scene/Scene.h"
|
|
#include "Scripting/ScriptComponent.h"
|
|
#include "Scripting/ScriptEngine.h"
|
|
|
|
#include <mono/jit/jit.h>
|
|
#include <mono/metadata/appdomain.h>
|
|
#include <mono/metadata/assembly.h>
|
|
#include <mono/metadata/attrdefs.h>
|
|
#include <mono/metadata/blob.h>
|
|
#include <mono/metadata/class.h>
|
|
#include <mono/metadata/image.h>
|
|
#include <mono/metadata/loader.h>
|
|
#include <mono/metadata/metadata.h>
|
|
#include <mono/metadata/mono-config.h>
|
|
#include <mono/metadata/object.h>
|
|
#include <mono/metadata/reflection.h>
|
|
|
|
#include <algorithm>
|
|
#include <cctype>
|
|
#include <cstdlib>
|
|
#include <fstream>
|
|
#include <limits>
|
|
#include <unordered_set>
|
|
#include <utility>
|
|
|
|
namespace XCEngine {
|
|
namespace Scripting {
|
|
|
|
namespace {
|
|
|
|
constexpr const char* kManagedRenderingNamespace = "XCEngine.Rendering";
|
|
|
|
struct MonoRootState {
|
|
MonoDomain* rootDomain = nullptr;
|
|
bool initialized = false;
|
|
bool cleanupRegistered = false;
|
|
};
|
|
|
|
enum class ManagedComponentKind {
|
|
Unknown,
|
|
Script,
|
|
Transform,
|
|
Rigidbody,
|
|
Camera,
|
|
Light,
|
|
MeshFilter,
|
|
MeshRenderer,
|
|
};
|
|
|
|
struct ManagedComponentTypeInfo {
|
|
ManagedComponentKind kind = ManagedComponentKind::Unknown;
|
|
MonoClass* monoClass = nullptr;
|
|
std::string assemblyName;
|
|
std::string namespaceName;
|
|
std::string className;
|
|
};
|
|
|
|
MonoRootState& GetMonoRootState() {
|
|
static MonoRootState state;
|
|
return state;
|
|
}
|
|
|
|
Components::Scene*& GetInternalCallScene() {
|
|
static Components::Scene* scene = nullptr;
|
|
return scene;
|
|
}
|
|
|
|
float& GetInternalCallDeltaTime() {
|
|
static float deltaTime = 0.0f;
|
|
return deltaTime;
|
|
}
|
|
|
|
bool& GetInternalCallRegistrationState() {
|
|
static bool registered = false;
|
|
return registered;
|
|
}
|
|
|
|
struct ManagedScriptableRenderContextState {
|
|
uint64_t handle = 0;
|
|
Rendering::CameraFrameStage stage = Rendering::CameraFrameStage::MainScene;
|
|
const Rendering::RenderPipelineStageRenderGraphContext* graphContext = nullptr;
|
|
Rendering::Pipelines::NativeSceneRecorder* sceneRecorder = nullptr;
|
|
struct RasterPassRecordRequest {
|
|
Containers::String passName = {};
|
|
Rendering::FullscreenPassDesc passDesc = {};
|
|
Rendering::RenderGraphTextureHandle sourceColorTexture = {};
|
|
std::vector<Rendering::RenderGraphTextureHandle> readTextures = {};
|
|
std::vector<Rendering::RenderGraphTextureHandle> readDepthTextures = {};
|
|
std::vector<Rendering::RenderPassGraphTextureBindingRequest>
|
|
textureBindings = {};
|
|
std::vector<Rendering::RenderGraphTextureHandle> colorTargets = {};
|
|
Rendering::RenderGraphTextureHandle depthTarget = {};
|
|
};
|
|
uint64_t nextPendingRasterPassHandle = 1u;
|
|
std::unordered_map<uint64_t, RasterPassRecordRequest>
|
|
pendingRasterPassRequests = {};
|
|
std::vector<RasterPassRecordRequest> rasterPassRequests = {};
|
|
};
|
|
|
|
struct ManagedCameraRenderRequestContextState {
|
|
uint64_t handle = 0;
|
|
Rendering::CameraRenderRequest* request = nullptr;
|
|
size_t renderedBaseCameraCount = 0u;
|
|
size_t renderedRequestCount = 0u;
|
|
Rendering::DirectionalShadowPlanningSettings
|
|
directionalShadowPlanningSettings = {};
|
|
bool suppressDirectionalShadow = false;
|
|
};
|
|
|
|
struct ManagedRenderSceneSetupContextState {
|
|
uint64_t handle = 0;
|
|
const Rendering::CameraFramePlan* plan = nullptr;
|
|
Rendering::RenderSceneData* sceneData = nullptr;
|
|
bool explicitlyConfigured = false;
|
|
};
|
|
|
|
struct ManagedDirectionalShadowExecutionContextState {
|
|
uint64_t handle = 0;
|
|
const Rendering::CameraFramePlan* plan = nullptr;
|
|
const Rendering::DirectionalShadowSurfaceAllocation*
|
|
shadowAllocation = nullptr;
|
|
Rendering::DirectionalShadowExecutionState* shadowState =
|
|
nullptr;
|
|
bool explicitlyConfigured = false;
|
|
};
|
|
|
|
struct ManagedScriptableRenderPipelinePlanningContextState {
|
|
uint64_t handle = 0;
|
|
Rendering::CameraFramePlan* plan = nullptr;
|
|
};
|
|
|
|
uint64_t& GetManagedScriptableRenderContextNextHandle() {
|
|
static uint64_t nextHandle = 1;
|
|
return nextHandle;
|
|
}
|
|
|
|
std::unordered_map<uint64_t, ManagedScriptableRenderContextState*>&
|
|
GetManagedScriptableRenderContextRegistry() {
|
|
static std::unordered_map<uint64_t, ManagedScriptableRenderContextState*> registry;
|
|
return registry;
|
|
}
|
|
|
|
ManagedScriptableRenderContextState* FindManagedScriptableRenderContextState(
|
|
uint64_t handle) {
|
|
const auto it = GetManagedScriptableRenderContextRegistry().find(handle);
|
|
return it != GetManagedScriptableRenderContextRegistry().end()
|
|
? it->second
|
|
: nullptr;
|
|
}
|
|
|
|
ManagedScriptableRenderContextState::RasterPassRecordRequest*
|
|
FindPendingManagedRasterPassRecordRequest(
|
|
ManagedScriptableRenderContextState* state,
|
|
uint64_t rasterPassHandle) {
|
|
if (state == nullptr || rasterPassHandle == 0u) {
|
|
return nullptr;
|
|
}
|
|
|
|
const auto it =
|
|
state->pendingRasterPassRequests.find(rasterPassHandle);
|
|
return it != state->pendingRasterPassRequests.end()
|
|
? &it->second
|
|
: nullptr;
|
|
}
|
|
|
|
uint64_t RegisterManagedScriptableRenderContextState(
|
|
ManagedScriptableRenderContextState& state) {
|
|
uint64_t handle = GetManagedScriptableRenderContextNextHandle()++;
|
|
if (handle == 0) {
|
|
handle = GetManagedScriptableRenderContextNextHandle()++;
|
|
}
|
|
|
|
state.handle = handle;
|
|
GetManagedScriptableRenderContextRegistry()[handle] = &state;
|
|
return handle;
|
|
}
|
|
|
|
void UnregisterManagedScriptableRenderContextState(uint64_t handle) {
|
|
if (handle == 0) {
|
|
return;
|
|
}
|
|
|
|
GetManagedScriptableRenderContextRegistry().erase(handle);
|
|
}
|
|
|
|
const Rendering::RenderCameraData& ResolveManagedScriptableRenderContextCameraData(
|
|
const ManagedScriptableRenderContextState* state) {
|
|
if (state != nullptr &&
|
|
state->graphContext != nullptr) {
|
|
return state->graphContext->sceneData.cameraData;
|
|
}
|
|
|
|
static const Rendering::RenderCameraData kDefaultCameraData = {};
|
|
return kDefaultCameraData;
|
|
}
|
|
|
|
const Rendering::RenderLightingData& ResolveManagedScriptableRenderContextLightingData(
|
|
const ManagedScriptableRenderContextState* state) {
|
|
if (state != nullptr &&
|
|
state->graphContext != nullptr) {
|
|
return state->graphContext->sceneData.lighting;
|
|
}
|
|
|
|
static const Rendering::RenderLightingData kDefaultLightingData = {};
|
|
return kDefaultLightingData;
|
|
}
|
|
|
|
const Rendering::RenderEnvironmentData&
|
|
ResolveManagedScriptableRenderContextEnvironmentData(
|
|
const ManagedScriptableRenderContextState* state) {
|
|
if (state != nullptr &&
|
|
state->graphContext != nullptr) {
|
|
return state->graphContext->sceneData.environment;
|
|
}
|
|
|
|
static const Rendering::RenderEnvironmentData kDefaultEnvironmentData = {};
|
|
return kDefaultEnvironmentData;
|
|
}
|
|
|
|
const Rendering::ResolvedFinalColorPolicy&
|
|
ResolveManagedScriptableRenderContextFinalColorPolicy(
|
|
const ManagedScriptableRenderContextState* state) {
|
|
if (state != nullptr &&
|
|
state->graphContext != nullptr) {
|
|
return state->graphContext->finalColorPolicy;
|
|
}
|
|
|
|
static const Rendering::ResolvedFinalColorPolicy
|
|
kDefaultFinalColorPolicy = {};
|
|
return kDefaultFinalColorPolicy;
|
|
}
|
|
|
|
Rendering::CameraFrameColorSource
|
|
ResolveManagedScriptableRenderContextStageColorSource(
|
|
const ManagedScriptableRenderContextState* state) {
|
|
if (state != nullptr &&
|
|
state->graphContext != nullptr) {
|
|
return state->graphContext->stageColorSource;
|
|
}
|
|
|
|
return Rendering::CameraFrameColorSource::ExplicitSurface;
|
|
}
|
|
|
|
bool ResolveManagedScriptableRenderContextUsesGraphManagedOutputColor(
|
|
const ManagedScriptableRenderContextState* state) {
|
|
return state != nullptr &&
|
|
state->graphContext != nullptr &&
|
|
state->graphContext->usesGraphManagedOutputColor;
|
|
}
|
|
|
|
int32_t EncodeManagedRenderGraphTextureHandle(
|
|
Rendering::RenderGraphTextureHandle handle) {
|
|
return handle.IsValid()
|
|
? static_cast<int32_t>(handle.index)
|
|
: -1;
|
|
}
|
|
|
|
Rendering::RenderGraphTextureHandle
|
|
DecodeManagedRenderGraphTextureHandle(
|
|
int32_t handleValue) {
|
|
Rendering::RenderGraphTextureHandle handle = {};
|
|
if (handleValue < 0) {
|
|
return handle;
|
|
}
|
|
|
|
handle.index = static_cast<Core::uint32>(handleValue);
|
|
return handle;
|
|
}
|
|
|
|
Rendering::RenderGraphTextureHandle
|
|
ResolveManagedScriptableRenderContextSourceColorTexture(
|
|
const ManagedScriptableRenderContextState* state) {
|
|
if (state == nullptr ||
|
|
state->graphContext == nullptr) {
|
|
return {};
|
|
}
|
|
|
|
if (state->graphContext->sourceColorTexture.IsValid()) {
|
|
return state->graphContext->sourceColorTexture;
|
|
}
|
|
|
|
const Rendering::CameraFrameRenderGraphResources* const resources =
|
|
Rendering::TryGetCameraFrameRenderGraphResources(
|
|
state->graphContext->blackboard);
|
|
if (resources == nullptr) {
|
|
return {};
|
|
}
|
|
|
|
switch (state->stage) {
|
|
case Rendering::CameraFrameStage::PostProcess:
|
|
return resources->mainScene.color;
|
|
case Rendering::CameraFrameStage::FinalOutput:
|
|
return resources->postProcess.color.IsValid()
|
|
? resources->postProcess.color
|
|
: resources->mainScene.color;
|
|
default:
|
|
return {};
|
|
}
|
|
}
|
|
|
|
Rendering::RenderGraphTextureHandle
|
|
ResolveManagedPrimaryColorTarget(
|
|
const std::vector<Rendering::RenderGraphTextureHandle>& colorTargets) {
|
|
const auto it =
|
|
std::find_if(
|
|
colorTargets.begin(),
|
|
colorTargets.end(),
|
|
[](Rendering::RenderGraphTextureHandle handle) {
|
|
return handle.IsValid();
|
|
});
|
|
return it != colorTargets.end()
|
|
? *it
|
|
: Rendering::RenderGraphTextureHandle{};
|
|
}
|
|
|
|
Rendering::RenderGraphTextureHandle
|
|
ResolveManagedScriptableRenderContextPrimaryColorTarget(
|
|
const ManagedScriptableRenderContextState* state) {
|
|
if (state == nullptr ||
|
|
state->graphContext == nullptr) {
|
|
return {};
|
|
}
|
|
|
|
return ResolveManagedPrimaryColorTarget(
|
|
state->graphContext->colorTargets);
|
|
}
|
|
|
|
Rendering::RenderGraphTextureHandle
|
|
ResolveManagedScriptableRenderContextDepthTarget(
|
|
const ManagedScriptableRenderContextState* state) {
|
|
return state != nullptr &&
|
|
state->graphContext != nullptr
|
|
? state->graphContext->depthTarget
|
|
: Rendering::RenderGraphTextureHandle{};
|
|
}
|
|
|
|
Rendering::RenderGraphTextureDesc
|
|
BuildManagedFullscreenTransientDepthTextureDesc(
|
|
const Rendering::RenderSurface& surface) {
|
|
Rendering::RenderGraphTextureDesc desc = {};
|
|
desc.width =
|
|
surface.GetWidth() > 0u
|
|
? surface.GetWidth()
|
|
: surface.GetRenderAreaWidth();
|
|
desc.height =
|
|
surface.GetHeight() > 0u
|
|
? surface.GetHeight()
|
|
: surface.GetRenderAreaHeight();
|
|
desc.format = static_cast<Core::uint32>(
|
|
RHI::Format::D24_UNorm_S8_UInt);
|
|
desc.textureType = static_cast<Core::uint32>(
|
|
RHI::TextureType::Texture2D);
|
|
desc.sampleCount = 1u;
|
|
desc.sampleQuality = 0u;
|
|
return desc;
|
|
}
|
|
|
|
Rendering::RenderGraphRecordingSourceBinding
|
|
BuildManagedScriptableRenderContextSourceBinding(
|
|
const Rendering::RenderPipelineStageRenderGraphContext& context,
|
|
Rendering::RenderGraphTextureHandle sourceColorTexture) {
|
|
if (!sourceColorTexture.IsValid()) {
|
|
return {};
|
|
}
|
|
|
|
Rendering::RenderGraphRecordingSourceBinding binding =
|
|
Rendering::MakeRenderGraphRecordingSourceBinding(
|
|
context.sourceSurface,
|
|
context.sourceColorView,
|
|
context.sourceColorState,
|
|
sourceColorTexture);
|
|
const bool usesContextSource =
|
|
context.sourceColorTexture.IsValid() &&
|
|
context.sourceColorTexture.index == sourceColorTexture.index;
|
|
if (!usesContextSource) {
|
|
binding.sourceColorView = nullptr;
|
|
binding.sourceColorState =
|
|
RHI::ResourceStates::PixelShaderResource;
|
|
}
|
|
|
|
if (binding.sourceSurface == nullptr) {
|
|
binding.sourceSurface = &context.surfaceTemplate;
|
|
}
|
|
|
|
return binding;
|
|
}
|
|
|
|
bool RecordManagedFullscreenRasterPass(
|
|
const Rendering::RenderPipelineStageRenderGraphContext& stageContext,
|
|
Rendering::RenderPass& pass,
|
|
Rendering::RenderGraphTextureHandle sourceColorTexture,
|
|
std::vector<Rendering::RenderGraphTextureHandle> colorTargets,
|
|
std::vector<Rendering::RenderGraphTextureHandle> additionalReadTextures,
|
|
std::vector<Rendering::RenderGraphTextureHandle> additionalReadDepthTextures,
|
|
std::vector<Rendering::RenderPassGraphTextureBindingRequest>
|
|
textureBindings,
|
|
Rendering::RenderGraphTextureHandle depthTarget,
|
|
const Containers::String& passName) {
|
|
if (!Rendering::IsCameraFrameFullscreenSequenceStage(stageContext.stage) ||
|
|
!sourceColorTexture.IsValid() ||
|
|
!ResolveManagedPrimaryColorTarget(colorTargets).IsValid()) {
|
|
return false;
|
|
}
|
|
|
|
const Rendering::RenderGraphRecordingContext baseContext =
|
|
Rendering::BuildRenderGraphRecordingContext(
|
|
stageContext);
|
|
Rendering::RenderGraphRecordingContextBuildParams params = {};
|
|
if (!passName.Empty()) {
|
|
params.passName = &passName;
|
|
}
|
|
params.overrideSourceBinding = true;
|
|
params.sourceBinding =
|
|
BuildManagedScriptableRenderContextSourceBinding(
|
|
stageContext,
|
|
sourceColorTexture);
|
|
params.overrideColorTargets = true;
|
|
params.colorTargets = std::move(colorTargets);
|
|
params.overrideDepthTarget = true;
|
|
params.depthTarget = depthTarget;
|
|
|
|
const Rendering::RenderGraphRecordingContext recordingContext =
|
|
Rendering::BuildRenderGraphRecordingContext(
|
|
baseContext,
|
|
std::move(params));
|
|
const Rendering::RenderPassRenderGraphContext renderGraphContext =
|
|
Rendering::BuildRenderPassRenderGraphContext(recordingContext);
|
|
Rendering::RenderPass* const passPtr = &pass;
|
|
Rendering::RenderPassGraphIO io =
|
|
Rendering::BuildSourceColorFullscreenRasterPassGraphIO();
|
|
io.writeDepth = depthTarget.IsValid();
|
|
return Rendering::RecordCallbackRasterRenderPass(
|
|
renderGraphContext,
|
|
io,
|
|
[passPtr](const Rendering::RenderPassContext& passContext) {
|
|
return passPtr != nullptr &&
|
|
passPtr->Execute(passContext);
|
|
},
|
|
std::move(additionalReadTextures),
|
|
std::move(additionalReadDepthTextures),
|
|
std::move(textureBindings));
|
|
}
|
|
|
|
bool RecordManagedFullscreenPassToTexture(
|
|
const Rendering::RenderPipelineStageRenderGraphContext& stageContext,
|
|
Rendering::RenderPass& pass,
|
|
Rendering::RenderGraphTextureHandle sourceColorTexture,
|
|
Rendering::RenderGraphTextureHandle outputColorTexture,
|
|
const Containers::String& passName) {
|
|
return RecordManagedFullscreenRasterPass(
|
|
stageContext,
|
|
pass,
|
|
sourceColorTexture,
|
|
{ outputColorTexture },
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
passName);
|
|
}
|
|
|
|
const Rendering::DirectionalShadowRenderPlan&
|
|
ResolveManagedScriptableRenderContextDirectionalShadowPlan(
|
|
const ManagedScriptableRenderContextState* state) {
|
|
if (state != nullptr &&
|
|
state->graphContext != nullptr) {
|
|
return state->graphContext->directionalShadowPlan;
|
|
}
|
|
|
|
static const Rendering::DirectionalShadowRenderPlan
|
|
kDefaultDirectionalShadowPlan = {};
|
|
return kDefaultDirectionalShadowPlan;
|
|
}
|
|
|
|
uint64_t& GetManagedCameraRenderRequestContextNextHandle() {
|
|
static uint64_t nextHandle = 1;
|
|
return nextHandle;
|
|
}
|
|
|
|
std::unordered_map<uint64_t, ManagedCameraRenderRequestContextState*>&
|
|
GetManagedCameraRenderRequestContextRegistry() {
|
|
static std::unordered_map<uint64_t, ManagedCameraRenderRequestContextState*>
|
|
registry;
|
|
return registry;
|
|
}
|
|
|
|
ManagedCameraRenderRequestContextState*
|
|
FindManagedCameraRenderRequestContextState(
|
|
uint64_t handle) {
|
|
const auto it =
|
|
GetManagedCameraRenderRequestContextRegistry().find(handle);
|
|
return it != GetManagedCameraRenderRequestContextRegistry().end()
|
|
? it->second
|
|
: nullptr;
|
|
}
|
|
|
|
uint64_t RegisterManagedCameraRenderRequestContextState(
|
|
ManagedCameraRenderRequestContextState& state) {
|
|
uint64_t handle =
|
|
GetManagedCameraRenderRequestContextNextHandle()++;
|
|
if (handle == 0) {
|
|
handle =
|
|
GetManagedCameraRenderRequestContextNextHandle()++;
|
|
}
|
|
|
|
state.handle = handle;
|
|
GetManagedCameraRenderRequestContextRegistry()[handle] =
|
|
&state;
|
|
return handle;
|
|
}
|
|
|
|
void UnregisterManagedCameraRenderRequestContextState(
|
|
uint64_t handle) {
|
|
if (handle == 0) {
|
|
return;
|
|
}
|
|
|
|
GetManagedCameraRenderRequestContextRegistry().erase(handle);
|
|
}
|
|
|
|
uint64_t& GetManagedRenderSceneSetupContextNextHandle() {
|
|
static uint64_t nextHandle = 1;
|
|
return nextHandle;
|
|
}
|
|
|
|
std::unordered_map<uint64_t, ManagedRenderSceneSetupContextState*>&
|
|
GetManagedRenderSceneSetupContextRegistry() {
|
|
static std::unordered_map<uint64_t, ManagedRenderSceneSetupContextState*>
|
|
registry;
|
|
return registry;
|
|
}
|
|
|
|
ManagedRenderSceneSetupContextState*
|
|
FindManagedRenderSceneSetupContextState(
|
|
uint64_t handle) {
|
|
const auto it =
|
|
GetManagedRenderSceneSetupContextRegistry().find(handle);
|
|
return it != GetManagedRenderSceneSetupContextRegistry().end()
|
|
? it->second
|
|
: nullptr;
|
|
}
|
|
|
|
uint64_t RegisterManagedRenderSceneSetupContextState(
|
|
ManagedRenderSceneSetupContextState& state) {
|
|
uint64_t handle =
|
|
GetManagedRenderSceneSetupContextNextHandle()++;
|
|
if (handle == 0) {
|
|
handle =
|
|
GetManagedRenderSceneSetupContextNextHandle()++;
|
|
}
|
|
|
|
state.handle = handle;
|
|
GetManagedRenderSceneSetupContextRegistry()[handle] =
|
|
&state;
|
|
return handle;
|
|
}
|
|
|
|
void UnregisterManagedRenderSceneSetupContextState(
|
|
uint64_t handle) {
|
|
if (handle == 0) {
|
|
return;
|
|
}
|
|
|
|
GetManagedRenderSceneSetupContextRegistry().erase(handle);
|
|
}
|
|
|
|
uint64_t& GetManagedDirectionalShadowExecutionContextNextHandle() {
|
|
static uint64_t nextHandle = 1;
|
|
return nextHandle;
|
|
}
|
|
|
|
std::unordered_map<
|
|
uint64_t,
|
|
ManagedDirectionalShadowExecutionContextState*>&
|
|
GetManagedDirectionalShadowExecutionContextRegistry() {
|
|
static std::unordered_map<
|
|
uint64_t,
|
|
ManagedDirectionalShadowExecutionContextState*>
|
|
registry;
|
|
return registry;
|
|
}
|
|
|
|
ManagedDirectionalShadowExecutionContextState*
|
|
FindManagedDirectionalShadowExecutionContextState(
|
|
uint64_t handle) {
|
|
const auto it =
|
|
GetManagedDirectionalShadowExecutionContextRegistry().find(
|
|
handle);
|
|
return it !=
|
|
GetManagedDirectionalShadowExecutionContextRegistry()
|
|
.end()
|
|
? it->second
|
|
: nullptr;
|
|
}
|
|
|
|
uint64_t RegisterManagedDirectionalShadowExecutionContextState(
|
|
ManagedDirectionalShadowExecutionContextState& state) {
|
|
uint64_t handle =
|
|
GetManagedDirectionalShadowExecutionContextNextHandle()++;
|
|
if (handle == 0) {
|
|
handle =
|
|
GetManagedDirectionalShadowExecutionContextNextHandle()++;
|
|
}
|
|
|
|
state.handle = handle;
|
|
GetManagedDirectionalShadowExecutionContextRegistry()[handle] =
|
|
&state;
|
|
return handle;
|
|
}
|
|
|
|
void UnregisterManagedDirectionalShadowExecutionContextState(
|
|
uint64_t handle) {
|
|
if (handle == 0) {
|
|
return;
|
|
}
|
|
|
|
GetManagedDirectionalShadowExecutionContextRegistry().erase(
|
|
handle);
|
|
}
|
|
|
|
uint64_t& GetManagedScriptableRenderPipelinePlanningContextNextHandle() {
|
|
static uint64_t nextHandle = 1;
|
|
return nextHandle;
|
|
}
|
|
|
|
std::unordered_map<uint64_t, ManagedScriptableRenderPipelinePlanningContextState*>&
|
|
GetManagedScriptableRenderPipelinePlanningContextRegistry() {
|
|
static std::unordered_map<
|
|
uint64_t,
|
|
ManagedScriptableRenderPipelinePlanningContextState*> registry;
|
|
return registry;
|
|
}
|
|
|
|
ManagedScriptableRenderPipelinePlanningContextState*
|
|
FindManagedScriptableRenderPipelinePlanningContextState(
|
|
uint64_t handle) {
|
|
const auto it =
|
|
GetManagedScriptableRenderPipelinePlanningContextRegistry().find(
|
|
handle);
|
|
return it !=
|
|
GetManagedScriptableRenderPipelinePlanningContextRegistry().end()
|
|
? it->second
|
|
: nullptr;
|
|
}
|
|
|
|
uint64_t RegisterManagedScriptableRenderPipelinePlanningContextState(
|
|
ManagedScriptableRenderPipelinePlanningContextState& state) {
|
|
uint64_t handle =
|
|
GetManagedScriptableRenderPipelinePlanningContextNextHandle()++;
|
|
if (handle == 0) {
|
|
handle =
|
|
GetManagedScriptableRenderPipelinePlanningContextNextHandle()++;
|
|
}
|
|
|
|
state.handle = handle;
|
|
GetManagedScriptableRenderPipelinePlanningContextRegistry()[handle] =
|
|
&state;
|
|
return handle;
|
|
}
|
|
|
|
void UnregisterManagedScriptableRenderPipelinePlanningContextState(
|
|
uint64_t handle) {
|
|
if (handle == 0) {
|
|
return;
|
|
}
|
|
|
|
GetManagedScriptableRenderPipelinePlanningContextRegistry().erase(handle);
|
|
}
|
|
|
|
bool TryResolveManagedCameraFrameStage(
|
|
int32_t value,
|
|
Rendering::CameraFrameStage& outStage) {
|
|
switch (value) {
|
|
case static_cast<int32_t>(Rendering::CameraFrameStage::PreScenePasses):
|
|
outStage = Rendering::CameraFrameStage::PreScenePasses;
|
|
return true;
|
|
case static_cast<int32_t>(Rendering::CameraFrameStage::ShadowCaster):
|
|
outStage = Rendering::CameraFrameStage::ShadowCaster;
|
|
return true;
|
|
case static_cast<int32_t>(Rendering::CameraFrameStage::DepthOnly):
|
|
outStage = Rendering::CameraFrameStage::DepthOnly;
|
|
return true;
|
|
case static_cast<int32_t>(Rendering::CameraFrameStage::MainScene):
|
|
outStage = Rendering::CameraFrameStage::MainScene;
|
|
return true;
|
|
case static_cast<int32_t>(Rendering::CameraFrameStage::PostProcess):
|
|
outStage = Rendering::CameraFrameStage::PostProcess;
|
|
return true;
|
|
case static_cast<int32_t>(Rendering::CameraFrameStage::FinalOutput):
|
|
outStage = Rendering::CameraFrameStage::FinalOutput;
|
|
return true;
|
|
case static_cast<int32_t>(Rendering::CameraFrameStage::PostScenePasses):
|
|
outStage = Rendering::CameraFrameStage::PostScenePasses;
|
|
return true;
|
|
case static_cast<int32_t>(Rendering::CameraFrameStage::OverlayPasses):
|
|
outStage = Rendering::CameraFrameStage::OverlayPasses;
|
|
return true;
|
|
default:
|
|
outStage = Rendering::CameraFrameStage::MainScene;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void CleanupMonoRootDomainAtExit() {
|
|
MonoRootState& rootState = GetMonoRootState();
|
|
if (!rootState.rootDomain) {
|
|
return;
|
|
}
|
|
|
|
mono_domain_set(rootState.rootDomain, true);
|
|
mono_jit_cleanup(rootState.rootDomain);
|
|
rootState.rootDomain = nullptr;
|
|
rootState.initialized = false;
|
|
GetInternalCallRegistrationState() = false;
|
|
}
|
|
|
|
std::string BuildFullClassName(const std::string& namespaceName, const std::string& className) {
|
|
return namespaceName.empty() ? className : namespaceName + "." + className;
|
|
}
|
|
|
|
std::string BuildClassKey(
|
|
const std::string& assemblyName,
|
|
const std::string& namespaceName,
|
|
const std::string& className) {
|
|
return assemblyName + "|" + BuildFullClassName(namespaceName, className);
|
|
}
|
|
|
|
std::string SafeString(const char* value) {
|
|
return value ? std::string(value) : std::string();
|
|
}
|
|
|
|
std::string TrimAssemblyName(const std::string& assemblyName) {
|
|
constexpr const char* kDllSuffix = ".dll";
|
|
if (assemblyName.size() >= 4u &&
|
|
assemblyName.substr(assemblyName.size() - 4u) == kDllSuffix) {
|
|
return assemblyName.substr(0u, assemblyName.size() - 4u);
|
|
}
|
|
|
|
return assemblyName;
|
|
}
|
|
|
|
std::string TrimWhitespace(std::string value) {
|
|
auto isWhitespace = [](unsigned char ch) {
|
|
return std::isspace(ch) != 0;
|
|
};
|
|
|
|
value.erase(
|
|
value.begin(),
|
|
std::find_if(
|
|
value.begin(),
|
|
value.end(),
|
|
[&](char ch) {
|
|
return !isWhitespace(static_cast<unsigned char>(ch));
|
|
}));
|
|
value.erase(
|
|
std::find_if(
|
|
value.rbegin(),
|
|
value.rend(),
|
|
[&](char ch) {
|
|
return !isWhitespace(static_cast<unsigned char>(ch));
|
|
}).base(),
|
|
value.end());
|
|
return value;
|
|
}
|
|
|
|
bool NormalizeManagedAssemblyDescriptor(
|
|
MonoScriptRuntime::ManagedAssemblyDescriptor& descriptor,
|
|
const std::filesystem::path& assemblyDirectory,
|
|
std::unordered_set<std::string>& ioAssemblyNames,
|
|
std::string* outError) {
|
|
descriptor.name = TrimAssemblyName(TrimWhitespace(descriptor.name));
|
|
if (descriptor.name.empty() && !descriptor.path.empty()) {
|
|
descriptor.name =
|
|
TrimAssemblyName(descriptor.path.stem().string());
|
|
}
|
|
|
|
if (descriptor.name.empty()) {
|
|
if (outError != nullptr) {
|
|
*outError = "Managed engine assembly name is empty.";
|
|
}
|
|
return false;
|
|
}
|
|
|
|
if (descriptor.path.empty() && !assemblyDirectory.empty()) {
|
|
descriptor.path = assemblyDirectory / (descriptor.name + ".dll");
|
|
}
|
|
|
|
if (!descriptor.path.empty()) {
|
|
descriptor.path = descriptor.path.lexically_normal();
|
|
}
|
|
|
|
if (!ioAssemblyNames.insert(descriptor.name).second) {
|
|
if (outError != nullptr) {
|
|
*outError =
|
|
"Managed engine assembly name is duplicated: " +
|
|
descriptor.name;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool LoadManagedAssemblyManifest(
|
|
const std::filesystem::path& assemblyDirectory,
|
|
const std::filesystem::path& manifestPath,
|
|
std::vector<MonoScriptRuntime::ManagedAssemblyDescriptor>& outAssemblies,
|
|
std::string* outError) {
|
|
outAssemblies.clear();
|
|
|
|
std::error_code ec;
|
|
if (manifestPath.empty() ||
|
|
!std::filesystem::exists(manifestPath, ec)) {
|
|
return true;
|
|
}
|
|
|
|
std::ifstream input(manifestPath);
|
|
if (!input.is_open()) {
|
|
if (outError != nullptr) {
|
|
*outError =
|
|
"Failed to open managed engine assembly manifest: " +
|
|
manifestPath.string();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
std::unordered_set<std::string> assemblyNames;
|
|
std::string line;
|
|
size_t lineNumber = 0u;
|
|
while (std::getline(input, line)) {
|
|
++lineNumber;
|
|
|
|
const size_t commentStart = line.find('#');
|
|
if (commentStart != std::string::npos) {
|
|
line.erase(commentStart);
|
|
}
|
|
|
|
line = TrimWhitespace(std::move(line));
|
|
if (line.empty()) {
|
|
continue;
|
|
}
|
|
|
|
MonoScriptRuntime::ManagedAssemblyDescriptor descriptor;
|
|
const size_t separator = line.find('=');
|
|
if (separator == std::string::npos) {
|
|
descriptor.name = line;
|
|
} else {
|
|
descriptor.name = line.substr(0u, separator);
|
|
std::string relativePath =
|
|
TrimWhitespace(line.substr(separator + 1u));
|
|
if (!relativePath.empty()) {
|
|
descriptor.path =
|
|
(assemblyDirectory / relativePath).lexically_normal();
|
|
}
|
|
}
|
|
|
|
if (!NormalizeManagedAssemblyDescriptor(
|
|
descriptor,
|
|
assemblyDirectory,
|
|
assemblyNames,
|
|
outError)) {
|
|
if (outError != nullptr && !outError->empty()) {
|
|
*outError +=
|
|
" Manifest: " + manifestPath.string() +
|
|
" line " + std::to_string(lineNumber) + ".";
|
|
}
|
|
return false;
|
|
}
|
|
|
|
outAssemblies.push_back(std::move(descriptor));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool DiscoverManagedAssembliesByConvention(
|
|
const MonoScriptRuntime::Settings& settings,
|
|
std::vector<MonoScriptRuntime::ManagedAssemblyDescriptor>& outAssemblies) {
|
|
outAssemblies.clear();
|
|
|
|
std::error_code ec;
|
|
if (settings.assemblyDirectory.empty() ||
|
|
!std::filesystem::exists(settings.assemblyDirectory, ec)) {
|
|
return true;
|
|
}
|
|
|
|
const std::string coreAssemblyName =
|
|
TrimAssemblyName(settings.coreAssemblyName);
|
|
const std::string appAssemblyName =
|
|
TrimAssemblyName(settings.appAssemblyName);
|
|
std::unordered_set<std::string> reservedNames = {
|
|
coreAssemblyName,
|
|
appAssemblyName,
|
|
"mscorlib"};
|
|
|
|
for (std::filesystem::directory_iterator it(
|
|
settings.assemblyDirectory,
|
|
ec), end;
|
|
it != end && !ec;
|
|
it.increment(ec)) {
|
|
if (ec || !it->is_regular_file(ec)) {
|
|
continue;
|
|
}
|
|
|
|
const std::filesystem::path path = it->path();
|
|
if (path.extension() != ".dll") {
|
|
continue;
|
|
}
|
|
|
|
const std::string assemblyName =
|
|
TrimAssemblyName(path.stem().string());
|
|
if (assemblyName.rfind("XCEngine.", 0u) != 0u ||
|
|
reservedNames.contains(assemblyName)) {
|
|
continue;
|
|
}
|
|
|
|
outAssemblies.push_back(
|
|
MonoScriptRuntime::ManagedAssemblyDescriptor{
|
|
assemblyName,
|
|
path.lexically_normal()});
|
|
}
|
|
|
|
std::sort(
|
|
outAssemblies.begin(),
|
|
outAssemblies.end(),
|
|
[](const MonoScriptRuntime::ManagedAssemblyDescriptor& lhs,
|
|
const MonoScriptRuntime::ManagedAssemblyDescriptor& rhs) {
|
|
return lhs.name < rhs.name;
|
|
});
|
|
return true;
|
|
}
|
|
|
|
MonoScriptRuntime::ManagedAssemblyDescriptor BuildManagedAssemblyDescriptor(
|
|
const std::string& assemblyName,
|
|
const std::filesystem::path& assemblyPath) {
|
|
return MonoScriptRuntime::ManagedAssemblyDescriptor{
|
|
assemblyName,
|
|
assemblyPath};
|
|
}
|
|
|
|
bool IsMonoClassOrSubclass(MonoClass* monoClass, MonoClass* potentialBaseClass) {
|
|
if (!monoClass || !potentialBaseClass) {
|
|
return false;
|
|
}
|
|
|
|
return monoClass == potentialBaseClass
|
|
|| mono_class_is_subclass_of(monoClass, potentialBaseClass, 0) != 0;
|
|
}
|
|
|
|
std::string MonoStringToUtf8(MonoString* stringObject) {
|
|
if (!stringObject) {
|
|
return std::string();
|
|
}
|
|
|
|
char* utf8 = mono_string_to_utf8(stringObject);
|
|
std::string result = utf8 ? std::string(utf8) : std::string();
|
|
if (utf8) {
|
|
mono_free(utf8);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
MonoScriptRuntime* GetActiveMonoScriptRuntime() {
|
|
return dynamic_cast<MonoScriptRuntime*>(ScriptEngine::Get().GetRuntime());
|
|
}
|
|
|
|
void ClearManagedRenderPipelineSelection(MonoScriptRuntime* runtime) {
|
|
const Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor descriptor =
|
|
Rendering::GetGraphicsSettingsState()
|
|
.GetConfiguredRenderPipelineAssetDescriptor();
|
|
if (runtime != nullptr && descriptor.managedAssetHandle != 0u) {
|
|
runtime->ReleaseExternalManagedObject(descriptor.managedAssetHandle);
|
|
}
|
|
|
|
Rendering::GetGraphicsSettingsState()
|
|
.ClearConfiguredRenderPipelineAssetDescriptor();
|
|
}
|
|
|
|
bool TryUnboxManagedBoolean(MonoObject* boxedValue, bool& outValue) {
|
|
outValue = false;
|
|
if (!boxedValue) {
|
|
return false;
|
|
}
|
|
|
|
void* const rawValue = mono_object_unbox(boxedValue);
|
|
if (!rawValue) {
|
|
return false;
|
|
}
|
|
|
|
outValue = (*static_cast<mono_bool*>(rawValue)) != 0;
|
|
return true;
|
|
}
|
|
|
|
bool TryUnboxManagedInt32(MonoObject* boxedValue, int32_t& outValue) {
|
|
outValue = 0;
|
|
if (!boxedValue) {
|
|
return false;
|
|
}
|
|
|
|
void* const rawValue = mono_object_unbox(boxedValue);
|
|
if (!rawValue) {
|
|
return false;
|
|
}
|
|
|
|
outValue = *static_cast<int32_t*>(rawValue);
|
|
return true;
|
|
}
|
|
|
|
struct ManagedFinalColorSettingsData {
|
|
uint8_t outputTransferMode = 0;
|
|
uint8_t exposureMode = 0;
|
|
uint16_t exposurePadding = 0;
|
|
float exposureValue = 1.0f;
|
|
uint8_t toneMappingMode = 0;
|
|
uint8_t toneMappingPadding[3] = {};
|
|
XCEngine::Math::Vector4 finalColorScale = XCEngine::Math::Vector4::One();
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedFinalColorSettingsData) ==
|
|
sizeof(Rendering::FinalColorSettings),
|
|
"Managed final color bridge layout must match native FinalColorSettings.");
|
|
|
|
struct ManagedFinalColorOverrideSettingsData {
|
|
uint8_t overrideOutputTransferMode = 0u;
|
|
uint8_t outputTransferMode = 0u;
|
|
uint8_t overrideExposureMode = 0u;
|
|
uint8_t exposureMode = 0u;
|
|
uint8_t overrideExposureValue = 0u;
|
|
uint8_t exposureValuePadding[3] = {};
|
|
float exposureValue = 1.0f;
|
|
uint8_t overrideToneMappingMode = 0u;
|
|
uint8_t toneMappingMode = 0u;
|
|
uint8_t overrideFinalColorScale = 0u;
|
|
uint8_t finalColorScalePadding = 0u;
|
|
XCEngine::Math::Vector4 finalColorScale = XCEngine::Math::Vector4::One();
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedFinalColorOverrideSettingsData) ==
|
|
sizeof(Rendering::FinalColorOverrideSettings),
|
|
"Managed final color override bridge layout must match native FinalColorOverrideSettings.");
|
|
|
|
struct ManagedRenderGraphTextureDescData {
|
|
uint32_t width = 0u;
|
|
uint32_t height = 0u;
|
|
uint32_t format = 0u;
|
|
uint32_t textureType = 0u;
|
|
uint32_t sampleCount = 0u;
|
|
uint32_t sampleQuality = 0u;
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedRenderGraphTextureDescData) ==
|
|
sizeof(Rendering::RenderGraphTextureDesc),
|
|
"Managed render graph texture desc bridge layout must match native RenderGraphTextureDesc.");
|
|
|
|
struct ManagedDirectionalShadowSamplingSettingsData {
|
|
float receiverDepthBias = 0.0010f;
|
|
float normalBiasScale = 2.0f;
|
|
float shadowStrength = 0.85f;
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedDirectionalShadowSamplingSettingsData) ==
|
|
sizeof(Rendering::DirectionalShadowSamplingSettings),
|
|
"Managed directional shadow sampling bridge layout must match native DirectionalShadowSamplingSettings.");
|
|
|
|
struct ManagedDirectionalShadowCasterBiasSettingsData {
|
|
float depthBiasFactor = 2.5f;
|
|
int32_t depthBiasUnits = 4;
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedDirectionalShadowCasterBiasSettingsData) ==
|
|
sizeof(Rendering::DirectionalShadowCasterBiasSettings),
|
|
"Managed directional shadow caster bias bridge layout must match native DirectionalShadowCasterBiasSettings.");
|
|
|
|
struct ManagedDirectionalShadowPlanningSettingsData {
|
|
uint32_t mapDimension = 2048u;
|
|
float minFocusDistance = 5.0f;
|
|
float maxFocusDistance = 32.0f;
|
|
float perspectiveFocusFactor = 1.0f;
|
|
float orthographicFocusFactor = 2.0f;
|
|
float minDepthRange = 20.0f;
|
|
float boundsPadding = 0.5f;
|
|
float minDepthPadding = 2.0f;
|
|
ManagedDirectionalShadowSamplingSettingsData sampling = {};
|
|
ManagedDirectionalShadowCasterBiasSettingsData casterBias = {};
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedDirectionalShadowPlanningSettingsData) ==
|
|
sizeof(Rendering::DirectionalShadowPlanningSettings),
|
|
"Managed directional shadow planning bridge layout must match native DirectionalShadowPlanningSettings.");
|
|
|
|
struct ManagedFilteringSettingsData {
|
|
int32_t renderQueueMin = std::numeric_limits<int32_t>::lowest();
|
|
int32_t renderQueueMax = std::numeric_limits<int32_t>::max();
|
|
uint32_t renderLayerMask = std::numeric_limits<uint32_t>::max();
|
|
uint8_t requireShadowCasting = 0u;
|
|
uint8_t reservedEditorObjectIdFilter = 0u;
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedFilteringSettingsData) ==
|
|
sizeof(Rendering::FilteringSettings),
|
|
"Managed filtering settings bridge layout must match native FilteringSettings.");
|
|
|
|
struct ManagedSortingSettingsData {
|
|
uint32_t sortMode = 0u;
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedSortingSettingsData) ==
|
|
sizeof(Rendering::SortingSettings),
|
|
"Managed sorting settings bridge layout must match native SortingSettings.");
|
|
|
|
struct ManagedRendererListDescData {
|
|
uint32_t type = 0u;
|
|
ManagedFilteringSettingsData filtering = {};
|
|
ManagedSortingSettingsData sorting = {};
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedRendererListDescData) ==
|
|
sizeof(Rendering::RendererListDesc),
|
|
"Managed renderer list desc bridge layout must match native RendererListDesc.");
|
|
|
|
struct ManagedDepthStateData {
|
|
uint8_t writeEnabled = 1u;
|
|
uint8_t compareFunction =
|
|
static_cast<uint8_t>(Resources::MaterialComparisonFunc::Less);
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedDepthStateData) ==
|
|
sizeof(Rendering::DepthState),
|
|
"Managed depth state bridge layout must match native DepthState.");
|
|
|
|
struct ManagedStencilFaceStateData {
|
|
uint8_t failOperation =
|
|
static_cast<uint8_t>(Resources::MaterialStencilOp::Keep);
|
|
uint8_t passOperation =
|
|
static_cast<uint8_t>(Resources::MaterialStencilOp::Keep);
|
|
uint8_t depthFailOperation =
|
|
static_cast<uint8_t>(Resources::MaterialStencilOp::Keep);
|
|
uint8_t compareFunction =
|
|
static_cast<uint8_t>(Resources::MaterialComparisonFunc::Always);
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedStencilFaceStateData) ==
|
|
sizeof(Rendering::StencilFaceState),
|
|
"Managed stencil face state bridge layout must match native StencilFaceState.");
|
|
|
|
struct ManagedStencilStateData {
|
|
uint8_t enabled = 0u;
|
|
uint8_t readMask = 0xFFu;
|
|
uint8_t writeMask = 0xFFu;
|
|
ManagedStencilFaceStateData frontFace = {};
|
|
ManagedStencilFaceStateData backFace = {};
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedStencilStateData) ==
|
|
sizeof(Rendering::StencilState),
|
|
"Managed stencil state bridge layout must match native StencilState.");
|
|
|
|
struct ManagedRenderStateBlockData {
|
|
uint32_t mask = 0u;
|
|
ManagedDepthStateData depthState = {};
|
|
ManagedStencilStateData stencilState = {};
|
|
uint8_t stencilReference = 0u;
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(ManagedRenderStateBlockData) ==
|
|
sizeof(Rendering::RenderStateBlock),
|
|
"Managed render state block bridge layout must match native RenderStateBlock.");
|
|
|
|
Rendering::FinalColorOutputTransferMode ResolveManagedFinalColorOutputTransferMode(
|
|
uint8_t value) {
|
|
switch (value) {
|
|
case 1:
|
|
return Rendering::FinalColorOutputTransferMode::LinearToSRGB;
|
|
default:
|
|
return Rendering::FinalColorOutputTransferMode::Disabled;
|
|
}
|
|
}
|
|
|
|
Rendering::FinalColorExposureMode ResolveManagedFinalColorExposureMode(
|
|
uint8_t value) {
|
|
switch (value) {
|
|
case 1:
|
|
return Rendering::FinalColorExposureMode::Fixed;
|
|
default:
|
|
return Rendering::FinalColorExposureMode::Disabled;
|
|
}
|
|
}
|
|
|
|
Rendering::FinalColorToneMappingMode ResolveManagedFinalColorToneMappingMode(
|
|
uint8_t value) {
|
|
switch (value) {
|
|
case 1:
|
|
return Rendering::FinalColorToneMappingMode::Neutral;
|
|
case 2:
|
|
return Rendering::FinalColorToneMappingMode::ACES;
|
|
default:
|
|
return Rendering::FinalColorToneMappingMode::Disabled;
|
|
}
|
|
}
|
|
|
|
Resources::MaterialComparisonFunc ResolveManagedMaterialComparisonFunc(
|
|
uint8_t value) {
|
|
switch (value) {
|
|
case static_cast<uint8_t>(Resources::MaterialComparisonFunc::Never):
|
|
return Resources::MaterialComparisonFunc::Never;
|
|
case static_cast<uint8_t>(Resources::MaterialComparisonFunc::Equal):
|
|
return Resources::MaterialComparisonFunc::Equal;
|
|
case static_cast<uint8_t>(Resources::MaterialComparisonFunc::LessEqual):
|
|
return Resources::MaterialComparisonFunc::LessEqual;
|
|
case static_cast<uint8_t>(Resources::MaterialComparisonFunc::Greater):
|
|
return Resources::MaterialComparisonFunc::Greater;
|
|
case static_cast<uint8_t>(Resources::MaterialComparisonFunc::NotEqual):
|
|
return Resources::MaterialComparisonFunc::NotEqual;
|
|
case static_cast<uint8_t>(Resources::MaterialComparisonFunc::GreaterEqual):
|
|
return Resources::MaterialComparisonFunc::GreaterEqual;
|
|
case static_cast<uint8_t>(Resources::MaterialComparisonFunc::Always):
|
|
return Resources::MaterialComparisonFunc::Always;
|
|
case static_cast<uint8_t>(Resources::MaterialComparisonFunc::Less):
|
|
default:
|
|
return Resources::MaterialComparisonFunc::Less;
|
|
}
|
|
}
|
|
|
|
Resources::MaterialStencilOp ResolveManagedMaterialStencilOp(
|
|
uint8_t value) {
|
|
switch (value) {
|
|
case static_cast<uint8_t>(Resources::MaterialStencilOp::Zero):
|
|
return Resources::MaterialStencilOp::Zero;
|
|
case static_cast<uint8_t>(Resources::MaterialStencilOp::Replace):
|
|
return Resources::MaterialStencilOp::Replace;
|
|
case static_cast<uint8_t>(Resources::MaterialStencilOp::IncrSat):
|
|
return Resources::MaterialStencilOp::IncrSat;
|
|
case static_cast<uint8_t>(Resources::MaterialStencilOp::DecrSat):
|
|
return Resources::MaterialStencilOp::DecrSat;
|
|
case static_cast<uint8_t>(Resources::MaterialStencilOp::Invert):
|
|
return Resources::MaterialStencilOp::Invert;
|
|
case static_cast<uint8_t>(Resources::MaterialStencilOp::IncrWrap):
|
|
return Resources::MaterialStencilOp::IncrWrap;
|
|
case static_cast<uint8_t>(Resources::MaterialStencilOp::DecrWrap):
|
|
return Resources::MaterialStencilOp::DecrWrap;
|
|
case static_cast<uint8_t>(Resources::MaterialStencilOp::Keep):
|
|
default:
|
|
return Resources::MaterialStencilOp::Keep;
|
|
}
|
|
}
|
|
|
|
Rendering::RenderStateMask ResolveManagedRenderStateMask(
|
|
uint32_t value) {
|
|
const uint32_t knownMask =
|
|
Rendering::ToRenderStateMaskBits(Rendering::RenderStateMask::Depth) |
|
|
Rendering::ToRenderStateMaskBits(Rendering::RenderStateMask::Stencil);
|
|
return static_cast<Rendering::RenderStateMask>(
|
|
value & knownMask);
|
|
}
|
|
|
|
bool TryResolveManagedRendererListType(
|
|
uint32_t value,
|
|
Rendering::RendererListType& outType) {
|
|
switch (value) {
|
|
case static_cast<uint32_t>(Rendering::RendererListType::AllVisible):
|
|
outType = Rendering::RendererListType::AllVisible;
|
|
return true;
|
|
case static_cast<uint32_t>(Rendering::RendererListType::Opaque):
|
|
outType = Rendering::RendererListType::Opaque;
|
|
return true;
|
|
case static_cast<uint32_t>(Rendering::RendererListType::Transparent):
|
|
outType = Rendering::RendererListType::Transparent;
|
|
return true;
|
|
case static_cast<uint32_t>(Rendering::RendererListType::ShadowCaster):
|
|
outType = Rendering::RendererListType::ShadowCaster;
|
|
return true;
|
|
default:
|
|
outType = Rendering::RendererListType::AllVisible;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Rendering::RendererSortMode ResolveManagedRendererSortMode(
|
|
uint32_t value) {
|
|
switch (value) {
|
|
case static_cast<uint32_t>(Rendering::RendererSortMode::FrontToBack):
|
|
return Rendering::RendererSortMode::FrontToBack;
|
|
case static_cast<uint32_t>(Rendering::RendererSortMode::BackToFront):
|
|
return Rendering::RendererSortMode::BackToFront;
|
|
case static_cast<uint32_t>(Rendering::RendererSortMode::None):
|
|
default:
|
|
return Rendering::RendererSortMode::None;
|
|
}
|
|
}
|
|
|
|
Rendering::FilteringSettings BuildManagedFilteringSettings(
|
|
const ManagedFilteringSettingsData& filteringData) {
|
|
Rendering::FilteringSettings filteringSettings = {};
|
|
filteringSettings.renderQueueMin = filteringData.renderQueueMin;
|
|
filteringSettings.renderQueueMax = filteringData.renderQueueMax;
|
|
filteringSettings.renderLayerMask = filteringData.renderLayerMask;
|
|
filteringSettings.requireShadowCasting =
|
|
filteringData.requireShadowCasting != 0u;
|
|
return filteringSettings;
|
|
}
|
|
|
|
Rendering::SortingSettings BuildManagedSortingSettings(
|
|
const ManagedSortingSettingsData& sortingData) {
|
|
Rendering::SortingSettings sortingSettings = {};
|
|
sortingSettings.sortMode =
|
|
ResolveManagedRendererSortMode(
|
|
sortingData.sortMode);
|
|
return sortingSettings;
|
|
}
|
|
|
|
bool TryBuildManagedRendererListDesc(
|
|
const ManagedRendererListDescData& rendererListDescData,
|
|
Rendering::RendererListDesc& outRendererListDesc) {
|
|
outRendererListDesc = {};
|
|
if (!TryResolveManagedRendererListType(
|
|
rendererListDescData.type,
|
|
outRendererListDesc.type)) {
|
|
return false;
|
|
}
|
|
|
|
outRendererListDesc.filtering =
|
|
BuildManagedFilteringSettings(
|
|
rendererListDescData.filtering);
|
|
outRendererListDesc.sorting =
|
|
BuildManagedSortingSettings(
|
|
rendererListDescData.sorting);
|
|
return true;
|
|
}
|
|
|
|
Rendering::DepthState BuildManagedDepthState(
|
|
const ManagedDepthStateData& depthStateData) {
|
|
Rendering::DepthState depthState = {};
|
|
depthState.writeEnabled = depthStateData.writeEnabled != 0u;
|
|
depthState.compareFunction =
|
|
ResolveManagedMaterialComparisonFunc(
|
|
depthStateData.compareFunction);
|
|
return depthState;
|
|
}
|
|
|
|
Rendering::StencilFaceState BuildManagedStencilFaceState(
|
|
const ManagedStencilFaceStateData& stencilFaceData) {
|
|
Rendering::StencilFaceState stencilFaceState = {};
|
|
stencilFaceState.failOp =
|
|
ResolveManagedMaterialStencilOp(
|
|
stencilFaceData.failOperation);
|
|
stencilFaceState.passOp =
|
|
ResolveManagedMaterialStencilOp(
|
|
stencilFaceData.passOperation);
|
|
stencilFaceState.depthFailOp =
|
|
ResolveManagedMaterialStencilOp(
|
|
stencilFaceData.depthFailOperation);
|
|
stencilFaceState.compareFunction =
|
|
ResolveManagedMaterialComparisonFunc(
|
|
stencilFaceData.compareFunction);
|
|
return stencilFaceState;
|
|
}
|
|
|
|
Rendering::StencilState BuildManagedStencilState(
|
|
const ManagedStencilStateData& stencilStateData) {
|
|
Rendering::StencilState stencilState = {};
|
|
stencilState.enabled = stencilStateData.enabled != 0u;
|
|
stencilState.readMask = stencilStateData.readMask;
|
|
stencilState.writeMask = stencilStateData.writeMask;
|
|
stencilState.frontFace =
|
|
BuildManagedStencilFaceState(
|
|
stencilStateData.frontFace);
|
|
stencilState.backFace =
|
|
BuildManagedStencilFaceState(
|
|
stencilStateData.backFace);
|
|
return stencilState;
|
|
}
|
|
|
|
Rendering::RenderStateBlock BuildManagedRenderStateBlock(
|
|
const ManagedRenderStateBlockData& renderStateBlockData) {
|
|
Rendering::RenderStateBlock renderStateBlock = {};
|
|
renderStateBlock.mask =
|
|
ResolveManagedRenderStateMask(
|
|
renderStateBlockData.mask);
|
|
renderStateBlock.depthState =
|
|
BuildManagedDepthState(
|
|
renderStateBlockData.depthState);
|
|
renderStateBlock.stencilState =
|
|
BuildManagedStencilState(
|
|
renderStateBlockData.stencilState);
|
|
renderStateBlock.stencilReference =
|
|
renderStateBlockData.stencilReference;
|
|
return renderStateBlock;
|
|
}
|
|
|
|
bool TryUnboxManagedFinalColorSettings(
|
|
MonoObject* boxedValue,
|
|
Rendering::FinalColorSettings& outSettings) {
|
|
outSettings = {};
|
|
outSettings.exposureValue = 1.0f;
|
|
outSettings.finalColorScale = XCEngine::Math::Vector4::One();
|
|
if (!boxedValue) {
|
|
return false;
|
|
}
|
|
|
|
void* const rawValue = mono_object_unbox(boxedValue);
|
|
if (!rawValue) {
|
|
return false;
|
|
}
|
|
|
|
const auto* const managedSettings =
|
|
static_cast<const ManagedFinalColorSettingsData*>(rawValue);
|
|
outSettings.outputTransferMode =
|
|
ResolveManagedFinalColorOutputTransferMode(
|
|
managedSettings->outputTransferMode);
|
|
outSettings.exposureMode =
|
|
ResolveManagedFinalColorExposureMode(
|
|
managedSettings->exposureMode);
|
|
outSettings.exposureValue = managedSettings->exposureValue;
|
|
outSettings.toneMappingMode =
|
|
ResolveManagedFinalColorToneMappingMode(
|
|
managedSettings->toneMappingMode);
|
|
outSettings.finalColorScale = managedSettings->finalColorScale;
|
|
return true;
|
|
}
|
|
|
|
Rendering::FinalColorSettings BuildManagedFinalColorSettings(
|
|
const ManagedFinalColorSettingsData& managedSettings) {
|
|
Rendering::FinalColorSettings settings = {};
|
|
settings.exposureValue = 1.0f;
|
|
settings.finalColorScale = XCEngine::Math::Vector4::One();
|
|
settings.outputTransferMode =
|
|
ResolveManagedFinalColorOutputTransferMode(
|
|
managedSettings.outputTransferMode);
|
|
settings.exposureMode =
|
|
ResolveManagedFinalColorExposureMode(
|
|
managedSettings.exposureMode);
|
|
settings.exposureValue = managedSettings.exposureValue;
|
|
settings.toneMappingMode =
|
|
ResolveManagedFinalColorToneMappingMode(
|
|
managedSettings.toneMappingMode);
|
|
settings.finalColorScale = managedSettings.finalColorScale;
|
|
return settings;
|
|
}
|
|
|
|
ManagedFinalColorOverrideSettingsData BuildManagedFinalColorOverrideSettings(
|
|
const Rendering::FinalColorOverrideSettings& nativeSettings) {
|
|
ManagedFinalColorOverrideSettingsData managedSettings = {};
|
|
managedSettings.overrideOutputTransferMode =
|
|
nativeSettings.overrideOutputTransferMode
|
|
? 1u
|
|
: 0u;
|
|
managedSettings.outputTransferMode =
|
|
static_cast<uint8_t>(nativeSettings.outputTransferMode);
|
|
managedSettings.overrideExposureMode =
|
|
nativeSettings.overrideExposureMode
|
|
? 1u
|
|
: 0u;
|
|
managedSettings.exposureMode =
|
|
static_cast<uint8_t>(nativeSettings.exposureMode);
|
|
managedSettings.overrideExposureValue =
|
|
nativeSettings.overrideExposureValue
|
|
? 1u
|
|
: 0u;
|
|
managedSettings.exposureValue =
|
|
nativeSettings.exposureValue;
|
|
managedSettings.overrideToneMappingMode =
|
|
nativeSettings.overrideToneMappingMode
|
|
? 1u
|
|
: 0u;
|
|
managedSettings.toneMappingMode =
|
|
static_cast<uint8_t>(nativeSettings.toneMappingMode);
|
|
managedSettings.overrideFinalColorScale =
|
|
nativeSettings.overrideFinalColorScale
|
|
? 1u
|
|
: 0u;
|
|
managedSettings.finalColorScale =
|
|
nativeSettings.finalColorScale;
|
|
return managedSettings;
|
|
}
|
|
|
|
bool SupportsManagedRenderPipelineStageGraphRecording(
|
|
Rendering::CameraFrameStage stage) {
|
|
return Rendering::SupportsCameraFramePipelineGraphRecording(stage) ||
|
|
Rendering::IsCameraFrameFullscreenSequenceStage(stage) ||
|
|
Rendering::IsCameraFrameScenePassRequestStage(stage);
|
|
}
|
|
|
|
bool SupportsManagedScriptableRenderContextSceneRecordingStage(
|
|
Rendering::CameraFrameStage stage) {
|
|
return stage == Rendering::CameraFrameStage::MainScene ||
|
|
Rendering::IsCameraFrameScenePassRequestStage(stage);
|
|
}
|
|
|
|
Rendering::RenderPass* ConfigureManagedFullscreenPass(
|
|
std::vector<std::unique_ptr<Rendering::RenderPass>>& passPool,
|
|
size_t passIndex,
|
|
const Rendering::FullscreenPassDesc& passDesc) {
|
|
while (passPool.size() <= passIndex) {
|
|
passPool.push_back(nullptr);
|
|
}
|
|
|
|
std::unique_ptr<Rendering::RenderPass>& passSlot = passPool[passIndex];
|
|
|
|
switch (passDesc.type) {
|
|
case Rendering::FullscreenPassType::ColorScale: {
|
|
Rendering::Passes::BuiltinVectorFullscreenPass* fullscreenPass =
|
|
dynamic_cast<Rendering::Passes::BuiltinVectorFullscreenPass*>(
|
|
passSlot.get());
|
|
if (fullscreenPass == nullptr) {
|
|
passSlot =
|
|
std::make_unique<Rendering::Passes::BuiltinVectorFullscreenPass>();
|
|
fullscreenPass =
|
|
static_cast<Rendering::Passes::BuiltinVectorFullscreenPass*>(
|
|
passSlot.get());
|
|
}
|
|
fullscreenPass->SetShaderPath(
|
|
Resources::GetBuiltinColorScalePostProcessShaderPath());
|
|
fullscreenPass->SetPreferredPassName("ColorScale");
|
|
fullscreenPass->SetVectorPayload(passDesc.colorScale.scale);
|
|
return fullscreenPass;
|
|
}
|
|
case Rendering::FullscreenPassType::ShaderVector: {
|
|
Rendering::Passes::BuiltinVectorFullscreenPass* fullscreenPass =
|
|
dynamic_cast<Rendering::Passes::BuiltinVectorFullscreenPass*>(
|
|
passSlot.get());
|
|
if (fullscreenPass == nullptr) {
|
|
passSlot =
|
|
std::make_unique<Rendering::Passes::BuiltinVectorFullscreenPass>();
|
|
fullscreenPass =
|
|
static_cast<Rendering::Passes::BuiltinVectorFullscreenPass*>(
|
|
passSlot.get());
|
|
}
|
|
fullscreenPass->SetShaderPath(passDesc.shaderVector.shaderPath);
|
|
fullscreenPass->SetPreferredPassName(passDesc.shaderVector.passName);
|
|
fullscreenPass->SetVectorPayload(passDesc.shaderVector.vectorPayload);
|
|
return fullscreenPass;
|
|
}
|
|
case Rendering::FullscreenPassType::FinalColor: {
|
|
Rendering::Passes::BuiltinFinalColorPass* finalColorPass =
|
|
dynamic_cast<Rendering::Passes::BuiltinFinalColorPass*>(
|
|
passSlot.get());
|
|
if (finalColorPass == nullptr) {
|
|
passSlot =
|
|
std::make_unique<Rendering::Passes::BuiltinFinalColorPass>();
|
|
finalColorPass =
|
|
static_cast<Rendering::Passes::BuiltinFinalColorPass*>(
|
|
passSlot.get());
|
|
}
|
|
|
|
finalColorPass->SetShaderPath(
|
|
Resources::GetBuiltinFinalColorShaderPath());
|
|
finalColorPass->SetSettings(passDesc.finalColor.settings);
|
|
return finalColorPass;
|
|
}
|
|
default:
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
class MonoManagedRenderPipelineAssetRuntime final
|
|
: public Rendering::Pipelines::ManagedRenderPipelineAssetRuntime
|
|
, public std::enable_shared_from_this<MonoManagedRenderPipelineAssetRuntime> {
|
|
public:
|
|
MonoManagedRenderPipelineAssetRuntime(
|
|
MonoScriptRuntime* runtime,
|
|
std::weak_ptr<void> runtimeLifetime,
|
|
Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor descriptor)
|
|
: m_runtime(runtime)
|
|
, m_runtimeLifetime(std::move(runtimeLifetime))
|
|
, m_descriptor(std::move(descriptor)) {
|
|
}
|
|
|
|
~MonoManagedRenderPipelineAssetRuntime() override {
|
|
ReleaseManagedAsset();
|
|
}
|
|
|
|
std::unique_ptr<Rendering::RenderPipelineStageRecorder> CreateStageRecorder() const override;
|
|
|
|
void ConfigureCameraRenderRequest(
|
|
Rendering::CameraRenderRequest& request,
|
|
size_t renderedBaseCameraCount,
|
|
size_t renderedRequestCount,
|
|
const Rendering::DirectionalShadowPlanningSettings&
|
|
directionalShadowSettings) const override;
|
|
void ConfigureCameraFramePlan(
|
|
Rendering::CameraFramePlan& plan) const override;
|
|
bool ConfigureRenderSceneSetup(
|
|
const Rendering::CameraFramePlan& plan,
|
|
Rendering::RenderSceneData& sceneData) const override;
|
|
bool ConfigureDirectionalShadowExecutionState(
|
|
const Rendering::CameraFramePlan& plan,
|
|
const Rendering::DirectionalShadowSurfaceAllocation&
|
|
shadowAllocation,
|
|
Rendering::DirectionalShadowExecutionState& shadowState)
|
|
const override;
|
|
|
|
bool TryGetDefaultFinalColorSettings(
|
|
Rendering::FinalColorSettings& settings) const override;
|
|
std::shared_ptr<const Rendering::RenderPipelineAsset>
|
|
GetPipelineRendererAsset() const override;
|
|
Rendering::Pipelines::ManagedPipelineRendererAssetPolicy
|
|
GetPipelineRendererAssetPolicy() const override;
|
|
|
|
MonoScriptRuntime* GetRuntime() const {
|
|
return m_runtime;
|
|
}
|
|
|
|
bool IsRuntimeAlive() const {
|
|
return m_runtime != nullptr &&
|
|
!m_runtimeLifetime.expired() &&
|
|
m_runtime->m_initialized;
|
|
}
|
|
|
|
bool AcquireManagedPipelineHandle(uint32_t& outPipelineHandle) const;
|
|
|
|
private:
|
|
bool EnsureManagedAsset() const;
|
|
bool SyncManagedAssetRuntimeState() const;
|
|
bool TryGetManagedRuntimeResourceVersion(int32_t& outVersion) const;
|
|
void ReleaseManagedPipeline() const;
|
|
void ReleaseManagedAsset() const;
|
|
MonoObject* GetManagedAssetObject() const;
|
|
MonoMethod* ResolveDisposePipelineMethod(MonoObject* pipelineObject) const;
|
|
MonoMethod* ResolveCreatePipelineMethod(MonoObject* assetObject) const;
|
|
MonoMethod* ResolveConfigureCameraRenderRequestMethod(
|
|
MonoObject* assetObject) const;
|
|
MonoMethod* ResolveConfigureCameraFramePlanMethod(
|
|
MonoObject* assetObject) const;
|
|
MonoMethod* ResolveGetDefaultFinalColorSettingsMethod(
|
|
MonoObject* assetObject) const;
|
|
MonoMethod* ResolveGetRuntimeResourceVersionMethod(
|
|
MonoObject* assetObject) const;
|
|
MonoMethod* ResolveConfigureRenderSceneSetupMethod(
|
|
MonoObject* assetObject) const;
|
|
MonoMethod* ResolveConfigureDirectionalShadowExecutionStateMethod(
|
|
MonoObject* assetObject) const;
|
|
MonoMethod* ResolveReleaseRuntimeResourcesMethod(
|
|
MonoObject* assetObject) const;
|
|
|
|
MonoScriptRuntime* m_runtime = nullptr;
|
|
std::weak_ptr<void> m_runtimeLifetime;
|
|
Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor m_descriptor;
|
|
mutable uint32_t m_assetHandle = 0;
|
|
mutable MonoMethod* m_disposePipelineMethod = nullptr;
|
|
mutable MonoMethod* m_createPipelineMethod = nullptr;
|
|
mutable MonoMethod* m_configureCameraRenderRequestMethod = nullptr;
|
|
mutable MonoMethod* m_configureCameraFramePlanMethod = nullptr;
|
|
mutable MonoMethod* m_getDefaultFinalColorSettingsMethod = nullptr;
|
|
mutable MonoMethod* m_getRuntimeResourceVersionMethod = nullptr;
|
|
mutable MonoMethod* m_configureRenderSceneSetupMethod =
|
|
nullptr;
|
|
mutable MonoMethod*
|
|
m_configureDirectionalShadowExecutionStateMethod = nullptr;
|
|
mutable MonoMethod* m_releaseRuntimeResourcesMethod = nullptr;
|
|
mutable bool m_ownsManagedAssetHandle = false;
|
|
mutable bool m_assetCreationAttempted = false;
|
|
mutable bool m_runtimeResourceVersionResolved = false;
|
|
mutable int32_t m_runtimeResourceVersion = 0;
|
|
mutable uint32_t m_pipelineHandle = 0;
|
|
mutable bool m_pipelineCreationAttempted = false;
|
|
};
|
|
|
|
class MonoManagedRenderPipelineStageRecorder final
|
|
: public Rendering::RenderPipelineStageRecorder {
|
|
public:
|
|
explicit MonoManagedRenderPipelineStageRecorder(
|
|
std::shared_ptr<const MonoManagedRenderPipelineAssetRuntime> assetRuntime)
|
|
: m_assetRuntime(std::move(assetRuntime))
|
|
, m_runtime(
|
|
m_assetRuntime != nullptr
|
|
? m_assetRuntime->GetRuntime()
|
|
: nullptr) {
|
|
}
|
|
|
|
~MonoManagedRenderPipelineStageRecorder() override {
|
|
Shutdown();
|
|
}
|
|
|
|
bool Initialize(const Rendering::RenderContext&) override {
|
|
return GetManagedPipelineObject() != nullptr;
|
|
}
|
|
|
|
void Shutdown() override {
|
|
for (std::unique_ptr<Rendering::RenderPass>& pass :
|
|
m_fullscreenPassPool) {
|
|
if (pass != nullptr) {
|
|
pass->Shutdown();
|
|
}
|
|
}
|
|
m_fullscreenPassPool.clear();
|
|
if (m_ownedSceneDrawBackend != nullptr) {
|
|
m_ownedSceneDrawBackend->Shutdown();
|
|
}
|
|
m_ownedSharedPipelineBackendAsset.reset();
|
|
m_supportsStageContextualMethod = nullptr;
|
|
m_supportsStageMethod = nullptr;
|
|
m_recordStageMethod = nullptr;
|
|
m_resolvedPipelineHandle = 0;
|
|
m_boundSceneDrawBackend = nullptr;
|
|
}
|
|
|
|
void SetPipelineBackend(
|
|
Rendering::RenderPipelineBackend* pipelineBackend) override {
|
|
m_boundSceneDrawBackend =
|
|
dynamic_cast<Rendering::SceneDrawBackend*>(pipelineBackend);
|
|
}
|
|
|
|
bool SupportsStageRenderGraph(Rendering::CameraFrameStage stage) const override {
|
|
return SupportsStageRenderGraph(
|
|
Rendering::RenderPipelineStageSupportContext{
|
|
stage,
|
|
-1 });
|
|
}
|
|
|
|
bool SupportsStageRenderGraph(
|
|
const Rendering::RenderPipelineStageSupportContext& context) const override {
|
|
if (!SupportsManagedRenderPipelineStageGraphRecording(context.stage) ||
|
|
!IsRuntimeAlive()) {
|
|
return false;
|
|
}
|
|
|
|
MonoObject* const pipelineObject = GetManagedPipelineObject();
|
|
if (!pipelineObject) {
|
|
return false;
|
|
}
|
|
|
|
MonoMethod* const contextualMethod =
|
|
ResolveSupportsStageContextualMethod(
|
|
pipelineObject);
|
|
if (contextualMethod != nullptr) {
|
|
int32_t managedStage =
|
|
static_cast<int32_t>(context.stage);
|
|
int32_t rendererIndex =
|
|
context.rendererIndex;
|
|
void* args[2] = {
|
|
&managedStage,
|
|
&rendererIndex };
|
|
MonoObject* result = nullptr;
|
|
if (!m_runtime->InvokeManagedMethod(
|
|
pipelineObject,
|
|
contextualMethod,
|
|
args,
|
|
&result)) {
|
|
return false;
|
|
}
|
|
|
|
bool supportsStage = false;
|
|
return TryUnboxManagedBoolean(
|
|
result,
|
|
supportsStage) &&
|
|
supportsStage;
|
|
}
|
|
|
|
return SupportsStageRenderGraphFallback(
|
|
pipelineObject,
|
|
context.stage);
|
|
}
|
|
|
|
private:
|
|
bool SupportsStageRenderGraphFallback(
|
|
MonoObject* pipelineObject,
|
|
Rendering::CameraFrameStage stage) const {
|
|
if (!SupportsManagedRenderPipelineStageGraphRecording(stage) ||
|
|
!IsRuntimeAlive()) {
|
|
return false;
|
|
}
|
|
|
|
MonoMethod* const method = ResolveSupportsStageMethod(pipelineObject);
|
|
if (!pipelineObject || !method) {
|
|
return false;
|
|
}
|
|
|
|
int32_t managedStage = static_cast<int32_t>(stage);
|
|
void* args[1] = { &managedStage };
|
|
MonoObject* result = nullptr;
|
|
if (!m_runtime->InvokeManagedMethod(
|
|
pipelineObject,
|
|
method,
|
|
args,
|
|
&result)) {
|
|
return false;
|
|
}
|
|
|
|
bool supportsStage = false;
|
|
return TryUnboxManagedBoolean(result, supportsStage) && supportsStage;
|
|
}
|
|
|
|
public:
|
|
bool RecordStageRenderGraph(
|
|
const Rendering::RenderPipelineStageRenderGraphContext& context) override {
|
|
if (!IsRuntimeAlive()) {
|
|
return false;
|
|
}
|
|
|
|
MonoObject* const pipelineObject = GetManagedPipelineObject();
|
|
MonoMethod* const method = ResolveRecordStageMethod(pipelineObject);
|
|
if (!pipelineObject || !method) {
|
|
return false;
|
|
}
|
|
|
|
ManagedScriptableRenderContextState managedContextState = {};
|
|
managedContextState.stage = context.stage;
|
|
managedContextState.graphContext = &context;
|
|
Rendering::SceneDrawBackend* const sceneDrawBackend =
|
|
ResolveSceneDrawBackend();
|
|
if (sceneDrawBackend == nullptr) {
|
|
return false;
|
|
}
|
|
Rendering::Pipelines::NativeSceneRecorder sceneRecorder(
|
|
*sceneDrawBackend,
|
|
context);
|
|
managedContextState.sceneRecorder = &sceneRecorder;
|
|
const uint64_t managedContextHandle =
|
|
RegisterManagedScriptableRenderContextState(managedContextState);
|
|
MonoObject* const managedContextObject =
|
|
m_runtime->CreateManagedScriptableRenderContext(managedContextHandle);
|
|
if (managedContextObject == nullptr) {
|
|
UnregisterManagedScriptableRenderContextState(managedContextHandle);
|
|
return false;
|
|
}
|
|
|
|
void* args[1] = { managedContextObject };
|
|
MonoObject* result = nullptr;
|
|
const bool invokeSucceeded = m_runtime->InvokeManagedMethod(
|
|
pipelineObject,
|
|
method,
|
|
args,
|
|
&result);
|
|
UnregisterManagedScriptableRenderContextState(managedContextHandle);
|
|
if (!invokeSucceeded) {
|
|
return false;
|
|
}
|
|
|
|
bool recorded = false;
|
|
if (!(TryUnboxManagedBoolean(result, recorded) && recorded)) {
|
|
return false;
|
|
}
|
|
|
|
return FlushManagedRasterPasses(
|
|
context,
|
|
managedContextState);
|
|
}
|
|
|
|
private:
|
|
bool IsRuntimeAlive() const {
|
|
return m_assetRuntime != nullptr &&
|
|
m_assetRuntime->IsRuntimeAlive() &&
|
|
m_runtime != nullptr;
|
|
}
|
|
|
|
MonoObject* GetManagedPipelineObject() const {
|
|
if (!IsRuntimeAlive()) {
|
|
return nullptr;
|
|
}
|
|
|
|
uint32_t pipelineHandle = 0;
|
|
if (!m_assetRuntime->AcquireManagedPipelineHandle(pipelineHandle) ||
|
|
pipelineHandle == 0) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (pipelineHandle != m_resolvedPipelineHandle) {
|
|
m_supportsStageContextualMethod = nullptr;
|
|
m_supportsStageMethod = nullptr;
|
|
m_recordStageMethod = nullptr;
|
|
m_resolvedPipelineHandle = pipelineHandle;
|
|
}
|
|
|
|
return m_runtime->GetManagedObject(pipelineHandle);
|
|
}
|
|
|
|
MonoMethod* ResolveSupportsStageContextualMethod(
|
|
MonoObject* pipelineObject) const {
|
|
if (m_supportsStageContextualMethod == nullptr) {
|
|
m_supportsStageContextualMethod =
|
|
m_runtime->ResolveManagedMethod(
|
|
pipelineObject,
|
|
"SupportsStageRenderGraphContextual",
|
|
2);
|
|
}
|
|
|
|
return m_supportsStageContextualMethod;
|
|
}
|
|
|
|
MonoMethod* ResolveSupportsStageMethod(MonoObject* pipelineObject) const {
|
|
if (m_supportsStageMethod == nullptr) {
|
|
m_supportsStageMethod =
|
|
m_runtime->ResolveManagedMethod(
|
|
pipelineObject,
|
|
"SupportsStageRenderGraph",
|
|
1);
|
|
}
|
|
|
|
return m_supportsStageMethod;
|
|
}
|
|
|
|
MonoMethod* ResolveRecordStageMethod(MonoObject* pipelineObject) const {
|
|
if (m_recordStageMethod == nullptr) {
|
|
m_recordStageMethod =
|
|
m_runtime->ResolveManagedMethod(
|
|
pipelineObject,
|
|
"RecordStageRenderGraph",
|
|
1);
|
|
}
|
|
|
|
return m_recordStageMethod;
|
|
}
|
|
|
|
bool FlushManagedRasterPasses(
|
|
const Rendering::RenderPipelineStageRenderGraphContext& context,
|
|
const ManagedScriptableRenderContextState& managedContextState) {
|
|
if (managedContextState.rasterPassRequests.empty()) {
|
|
return true;
|
|
}
|
|
if (!Rendering::IsCameraFrameFullscreenSequenceStage(context.stage)) {
|
|
return false;
|
|
}
|
|
|
|
Rendering::RenderGraphTextureHandle currentSourceColor =
|
|
ResolveManagedScriptableRenderContextSourceColorTexture(
|
|
&managedContextState);
|
|
const Rendering::RenderGraphTextureHandle finalOutputColor =
|
|
ResolveManagedScriptableRenderContextPrimaryColorTarget(
|
|
&managedContextState);
|
|
if (!currentSourceColor.IsValid() ||
|
|
!finalOutputColor.IsValid()) {
|
|
return false;
|
|
}
|
|
|
|
for (size_t passIndex = 0u;
|
|
passIndex < managedContextState.rasterPassRequests.size();
|
|
++passIndex) {
|
|
const ManagedScriptableRenderContextState::RasterPassRecordRequest&
|
|
request = managedContextState.rasterPassRequests[passIndex];
|
|
Rendering::RenderPass* const pass =
|
|
ConfigureManagedFullscreenPass(
|
|
m_fullscreenPassPool,
|
|
passIndex,
|
|
request.passDesc);
|
|
if (pass == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
const Containers::String resolvedPassName =
|
|
!request.passName.Empty()
|
|
? request.passName
|
|
: managedContextState.rasterPassRequests.size() == 1u
|
|
? context.passName
|
|
: Rendering::BuildRenderGraphSequencePassName(
|
|
context.passName,
|
|
passIndex);
|
|
const Rendering::RenderGraphTextureHandle resolvedSourceColor =
|
|
request.sourceColorTexture.IsValid()
|
|
? request.sourceColorTexture
|
|
: currentSourceColor;
|
|
std::vector<Rendering::RenderGraphTextureHandle>
|
|
resolvedColorTargets =
|
|
request.colorTargets;
|
|
if (!ResolveManagedPrimaryColorTarget(resolvedColorTargets)
|
|
.IsValid()) {
|
|
const bool isLastPass =
|
|
passIndex + 1u ==
|
|
managedContextState.rasterPassRequests.size();
|
|
const Rendering::RenderGraphTextureHandle resolvedOutputColor =
|
|
isLastPass
|
|
? finalOutputColor
|
|
: context.graphBuilder.CreateTransientTexture(
|
|
resolvedPassName + ".Color",
|
|
Rendering::BuildFullscreenTransientTextureDesc(
|
|
context.surfaceTemplate));
|
|
resolvedColorTargets = { resolvedOutputColor };
|
|
}
|
|
if (!RecordManagedFullscreenRasterPass(
|
|
context,
|
|
*pass,
|
|
resolvedSourceColor,
|
|
resolvedColorTargets,
|
|
request.readTextures,
|
|
request.readDepthTextures,
|
|
request.textureBindings,
|
|
request.depthTarget,
|
|
resolvedPassName)) {
|
|
return false;
|
|
}
|
|
|
|
currentSourceColor =
|
|
ResolveManagedPrimaryColorTarget(
|
|
resolvedColorTargets);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
Rendering::SceneDrawBackend* ResolveSceneDrawBackend() {
|
|
if (m_boundSceneDrawBackend != nullptr) {
|
|
return m_boundSceneDrawBackend;
|
|
}
|
|
|
|
const bool useDefaultNativeBackend =
|
|
m_assetRuntime != nullptr &&
|
|
m_assetRuntime->GetPipelineRendererAssetPolicy() ==
|
|
Rendering::Pipelines::ManagedPipelineRendererAssetPolicy::
|
|
DefaultNativeBackend;
|
|
const std::shared_ptr<const Rendering::RenderPipelineAsset>
|
|
resolvedPipelineBackendAsset =
|
|
m_assetRuntime == nullptr
|
|
? nullptr
|
|
: useDefaultNativeBackend
|
|
? Rendering::Internal::CreateDefaultPipelineBackendAsset()
|
|
: m_assetRuntime->GetSharedPipelineBackendAsset();
|
|
if (resolvedPipelineBackendAsset == nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (m_ownedSceneDrawBackend == nullptr ||
|
|
resolvedPipelineBackendAsset !=
|
|
m_ownedSharedPipelineBackendAsset) {
|
|
if (m_ownedSceneDrawBackend != nullptr) {
|
|
m_ownedSceneDrawBackend->Shutdown();
|
|
}
|
|
m_ownedSceneDrawBackend =
|
|
useDefaultNativeBackend
|
|
? Rendering::Internal::CreateDefaultSceneDrawBackend()
|
|
: Rendering::Internal::CreateSceneDrawBackendFromAsset(
|
|
resolvedPipelineBackendAsset);
|
|
m_ownedSharedPipelineBackendAsset =
|
|
resolvedPipelineBackendAsset;
|
|
}
|
|
|
|
return m_ownedSceneDrawBackend.get();
|
|
}
|
|
|
|
std::shared_ptr<const MonoManagedRenderPipelineAssetRuntime> m_assetRuntime;
|
|
MonoScriptRuntime* m_runtime = nullptr;
|
|
mutable MonoMethod* m_supportsStageContextualMethod = nullptr;
|
|
mutable MonoMethod* m_supportsStageMethod = nullptr;
|
|
mutable MonoMethod* m_recordStageMethod = nullptr;
|
|
mutable uint32_t m_resolvedPipelineHandle = 0;
|
|
std::vector<std::unique_ptr<Rendering::RenderPass>> m_fullscreenPassPool = {};
|
|
Rendering::SceneDrawBackend* m_boundSceneDrawBackend = nullptr;
|
|
std::shared_ptr<const Rendering::RenderPipelineAsset>
|
|
m_ownedSharedPipelineBackendAsset = nullptr;
|
|
std::unique_ptr<Rendering::SceneDrawBackend> m_ownedSceneDrawBackend =
|
|
nullptr;
|
|
};
|
|
|
|
std::unique_ptr<Rendering::RenderPipelineStageRecorder>
|
|
MonoManagedRenderPipelineAssetRuntime::CreateStageRecorder() const {
|
|
if (!IsRuntimeAlive() || !m_descriptor.IsValid()) {
|
|
return nullptr;
|
|
}
|
|
|
|
return std::make_unique<MonoManagedRenderPipelineStageRecorder>(
|
|
shared_from_this());
|
|
}
|
|
|
|
void MonoManagedRenderPipelineAssetRuntime::ConfigureCameraRenderRequest(
|
|
Rendering::CameraRenderRequest& request,
|
|
size_t renderedBaseCameraCount,
|
|
size_t renderedRequestCount,
|
|
const Rendering::DirectionalShadowPlanningSettings&
|
|
directionalShadowSettings) const {
|
|
if (!EnsureManagedAsset()) {
|
|
request.directionalShadow = {};
|
|
Rendering::ApplyDefaultRenderPipelineAssetCameraRenderRequestPolicy(
|
|
request,
|
|
renderedBaseCameraCount,
|
|
renderedRequestCount,
|
|
directionalShadowSettings);
|
|
return;
|
|
}
|
|
|
|
MonoObject* const assetObject = GetManagedAssetObject();
|
|
MonoMethod* const method =
|
|
ResolveConfigureCameraRenderRequestMethod(assetObject);
|
|
if (assetObject == nullptr || method == nullptr) {
|
|
request.directionalShadow = {};
|
|
Rendering::ApplyDefaultRenderPipelineAssetCameraRenderRequestPolicy(
|
|
request,
|
|
renderedBaseCameraCount,
|
|
renderedRequestCount,
|
|
directionalShadowSettings);
|
|
return;
|
|
}
|
|
|
|
ManagedCameraRenderRequestContextState requestContextState =
|
|
{};
|
|
requestContextState.request = &request;
|
|
requestContextState.renderedBaseCameraCount = renderedBaseCameraCount;
|
|
requestContextState.renderedRequestCount = renderedRequestCount;
|
|
requestContextState.directionalShadowPlanningSettings =
|
|
directionalShadowSettings;
|
|
const uint64_t requestContextHandle =
|
|
RegisterManagedCameraRenderRequestContextState(
|
|
requestContextState);
|
|
MonoObject* const requestContextObject =
|
|
m_runtime->CreateManagedCameraRenderRequestContext(
|
|
requestContextHandle);
|
|
if (requestContextObject == nullptr) {
|
|
UnregisterManagedCameraRenderRequestContextState(
|
|
requestContextHandle);
|
|
request.directionalShadow = {};
|
|
Rendering::ApplyDefaultRenderPipelineAssetCameraRenderRequestPolicy(
|
|
request,
|
|
renderedBaseCameraCount,
|
|
renderedRequestCount,
|
|
directionalShadowSettings);
|
|
return;
|
|
}
|
|
|
|
void* args[1] = { requestContextObject };
|
|
m_runtime->InvokeManagedMethod(
|
|
assetObject,
|
|
method,
|
|
args,
|
|
nullptr);
|
|
request.directionalShadow = {};
|
|
if (requestContextState.suppressDirectionalShadow) {
|
|
} else {
|
|
Rendering::ApplyDefaultRenderPipelineAssetCameraRenderRequestPolicy(
|
|
request,
|
|
renderedBaseCameraCount,
|
|
renderedRequestCount,
|
|
requestContextState.directionalShadowPlanningSettings);
|
|
}
|
|
UnregisterManagedCameraRenderRequestContextState(
|
|
requestContextHandle);
|
|
}
|
|
|
|
void MonoManagedRenderPipelineAssetRuntime::ConfigureCameraFramePlan(
|
|
Rendering::CameraFramePlan& plan) const {
|
|
if (!EnsureManagedAsset()) {
|
|
return;
|
|
}
|
|
|
|
MonoObject* const assetObject = GetManagedAssetObject();
|
|
MonoMethod* const method =
|
|
ResolveConfigureCameraFramePlanMethod(assetObject);
|
|
if (assetObject == nullptr || method == nullptr) {
|
|
return;
|
|
}
|
|
|
|
ManagedScriptableRenderPipelinePlanningContextState
|
|
planningContextState = {};
|
|
planningContextState.plan = &plan;
|
|
const uint64_t planningContextHandle =
|
|
RegisterManagedScriptableRenderPipelinePlanningContextState(
|
|
planningContextState);
|
|
MonoObject* const planningContextObject =
|
|
m_runtime->CreateManagedScriptableRenderPipelinePlanningContext(
|
|
planningContextHandle);
|
|
if (planningContextObject == nullptr) {
|
|
UnregisterManagedScriptableRenderPipelinePlanningContextState(
|
|
planningContextHandle);
|
|
return;
|
|
}
|
|
|
|
void* args[1] = { planningContextObject };
|
|
m_runtime->InvokeManagedMethod(
|
|
assetObject,
|
|
method,
|
|
args,
|
|
nullptr);
|
|
UnregisterManagedScriptableRenderPipelinePlanningContextState(
|
|
planningContextHandle);
|
|
}
|
|
|
|
bool MonoManagedRenderPipelineAssetRuntime::ConfigureRenderSceneSetup(
|
|
const Rendering::CameraFramePlan& plan,
|
|
Rendering::RenderSceneData& sceneData) const {
|
|
if (!EnsureManagedAsset()) {
|
|
return false;
|
|
}
|
|
|
|
MonoObject* const assetObject = GetManagedAssetObject();
|
|
MonoMethod* const method =
|
|
ResolveConfigureRenderSceneSetupMethod(assetObject);
|
|
if (assetObject == nullptr || method == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
ManagedRenderSceneSetupContextState setupContextState = {};
|
|
setupContextState.plan = &plan;
|
|
setupContextState.sceneData = &sceneData;
|
|
const uint64_t setupContextHandle =
|
|
RegisterManagedRenderSceneSetupContextState(
|
|
setupContextState);
|
|
MonoObject* const setupContextObject =
|
|
m_runtime->CreateManagedRenderSceneSetupContext(
|
|
setupContextHandle);
|
|
if (setupContextObject == nullptr) {
|
|
UnregisterManagedRenderSceneSetupContextState(
|
|
setupContextHandle);
|
|
return false;
|
|
}
|
|
|
|
void* args[1] = { setupContextObject };
|
|
m_runtime->InvokeManagedMethod(
|
|
assetObject,
|
|
method,
|
|
args,
|
|
nullptr);
|
|
UnregisterManagedRenderSceneSetupContextState(
|
|
setupContextHandle);
|
|
return setupContextState.explicitlyConfigured;
|
|
}
|
|
|
|
bool MonoManagedRenderPipelineAssetRuntime::
|
|
ConfigureDirectionalShadowExecutionState(
|
|
const Rendering::CameraFramePlan& plan,
|
|
const Rendering::DirectionalShadowSurfaceAllocation&
|
|
shadowAllocation,
|
|
Rendering::DirectionalShadowExecutionState& shadowState) const {
|
|
if (!EnsureManagedAsset()) {
|
|
return false;
|
|
}
|
|
|
|
MonoObject* const assetObject = GetManagedAssetObject();
|
|
MonoMethod* const method =
|
|
ResolveConfigureDirectionalShadowExecutionStateMethod(
|
|
assetObject);
|
|
if (assetObject == nullptr || method == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
ManagedDirectionalShadowExecutionContextState executionState =
|
|
{};
|
|
executionState.plan = &plan;
|
|
executionState.shadowAllocation = &shadowAllocation;
|
|
executionState.shadowState = &shadowState;
|
|
const uint64_t executionContextHandle =
|
|
RegisterManagedDirectionalShadowExecutionContextState(
|
|
executionState);
|
|
MonoObject* const executionContextObject =
|
|
m_runtime->CreateManagedDirectionalShadowExecutionContext(
|
|
executionContextHandle);
|
|
if (executionContextObject == nullptr) {
|
|
UnregisterManagedDirectionalShadowExecutionContextState(
|
|
executionContextHandle);
|
|
return false;
|
|
}
|
|
|
|
void* args[1] = { executionContextObject };
|
|
m_runtime->InvokeManagedMethod(
|
|
assetObject,
|
|
method,
|
|
args,
|
|
nullptr);
|
|
UnregisterManagedDirectionalShadowExecutionContextState(
|
|
executionContextHandle);
|
|
return executionState.explicitlyConfigured;
|
|
}
|
|
|
|
bool MonoManagedRenderPipelineAssetRuntime::TryGetDefaultFinalColorSettings(
|
|
Rendering::FinalColorSettings& settings) const {
|
|
settings = {};
|
|
settings.exposureValue = 1.0f;
|
|
settings.finalColorScale = XCEngine::Math::Vector4::One();
|
|
if (!EnsureManagedAsset()) {
|
|
return false;
|
|
}
|
|
|
|
MonoObject* const assetObject = GetManagedAssetObject();
|
|
MonoMethod* const method =
|
|
ResolveGetDefaultFinalColorSettingsMethod(assetObject);
|
|
if (assetObject == nullptr || method == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
MonoObject* managedSettings = nullptr;
|
|
if (!m_runtime->InvokeManagedMethod(
|
|
assetObject,
|
|
method,
|
|
nullptr,
|
|
&managedSettings)) {
|
|
return false;
|
|
}
|
|
|
|
return TryUnboxManagedFinalColorSettings(
|
|
managedSettings,
|
|
settings);
|
|
}
|
|
|
|
std::shared_ptr<const Rendering::RenderPipelineAsset>
|
|
MonoManagedRenderPipelineAssetRuntime::GetPipelineRendererAsset() const {
|
|
if (!SyncManagedAssetRuntimeState()) {
|
|
return nullptr;
|
|
}
|
|
|
|
// Current Mono-backed SRP assets do not materialize a shared native
|
|
// backend asset. They bind the engine default native backend explicitly
|
|
// through DefaultNativeBackend.
|
|
return nullptr;
|
|
}
|
|
|
|
Rendering::Pipelines::ManagedPipelineRendererAssetPolicy
|
|
MonoManagedRenderPipelineAssetRuntime::GetPipelineRendererAssetPolicy() const {
|
|
return SyncManagedAssetRuntimeState()
|
|
? Rendering::Pipelines::ManagedPipelineRendererAssetPolicy::DefaultNativeBackend
|
|
: Rendering::Pipelines::ManagedPipelineRendererAssetPolicy::Unspecified;
|
|
}
|
|
|
|
bool MonoManagedRenderPipelineAssetRuntime::AcquireManagedPipelineHandle(
|
|
uint32_t& outPipelineHandle) const {
|
|
if (!SyncManagedAssetRuntimeState()) {
|
|
outPipelineHandle = 0;
|
|
return false;
|
|
}
|
|
|
|
if (m_pipelineHandle != 0) {
|
|
outPipelineHandle = m_pipelineHandle;
|
|
return true;
|
|
}
|
|
if (m_pipelineCreationAttempted) {
|
|
outPipelineHandle = 0;
|
|
return false;
|
|
}
|
|
|
|
m_pipelineCreationAttempted = true;
|
|
|
|
MonoObject* const assetObject = GetManagedAssetObject();
|
|
MonoMethod* const createPipelineMethod =
|
|
ResolveCreatePipelineMethod(assetObject);
|
|
if (assetObject == nullptr || createPipelineMethod == nullptr) {
|
|
outPipelineHandle = 0;
|
|
return false;
|
|
}
|
|
|
|
MonoObject* pipelineObject = nullptr;
|
|
if (!m_runtime->InvokeManagedMethod(
|
|
assetObject,
|
|
createPipelineMethod,
|
|
nullptr,
|
|
&pipelineObject) ||
|
|
pipelineObject == nullptr) {
|
|
outPipelineHandle = 0;
|
|
return false;
|
|
}
|
|
|
|
if (!IsMonoClassOrSubclass(
|
|
mono_object_get_class(pipelineObject),
|
|
m_runtime->m_scriptableRenderPipelineClass)) {
|
|
m_runtime->SetError(
|
|
"Managed render pipeline asset returned a non-ScriptableRenderPipeline instance: " +
|
|
m_descriptor.GetFullName() + ".");
|
|
outPipelineHandle = 0;
|
|
return false;
|
|
}
|
|
|
|
m_pipelineHandle = m_runtime->RetainExternalManagedObject(pipelineObject);
|
|
outPipelineHandle = m_pipelineHandle;
|
|
return m_pipelineHandle != 0;
|
|
}
|
|
|
|
bool MonoManagedRenderPipelineAssetRuntime::EnsureManagedAsset() const {
|
|
if (m_assetHandle != 0) {
|
|
return true;
|
|
}
|
|
if (m_assetCreationAttempted || !IsRuntimeAlive() || !m_descriptor.IsValid()) {
|
|
return false;
|
|
}
|
|
|
|
m_assetCreationAttempted = true;
|
|
|
|
if (m_descriptor.HasManagedAssetHandle()) {
|
|
MonoObject* const assetObject =
|
|
m_runtime->GetExternalManagedObject(
|
|
m_descriptor.managedAssetHandle);
|
|
MonoClass* const assetClass =
|
|
assetObject != nullptr
|
|
? mono_object_get_class(assetObject)
|
|
: nullptr;
|
|
if (assetClass == nullptr) {
|
|
m_runtime->SetError(
|
|
"Managed render pipeline asset handle is no longer valid: " +
|
|
m_descriptor.GetFullName() + ".");
|
|
return false;
|
|
}
|
|
|
|
if (!IsMonoClassOrSubclass(
|
|
assetClass,
|
|
m_runtime->m_scriptableRenderPipelineAssetClass)) {
|
|
m_runtime->SetError(
|
|
"Managed render pipeline asset must derive from ScriptableRenderPipelineAsset: " +
|
|
m_descriptor.GetFullName() + ".");
|
|
return false;
|
|
}
|
|
|
|
m_assetHandle = m_descriptor.managedAssetHandle;
|
|
m_ownsManagedAssetHandle = false;
|
|
return true;
|
|
}
|
|
|
|
MonoClass* assetClass = nullptr;
|
|
if (!m_runtime->ResolveManagedClass(
|
|
m_descriptor.assemblyName,
|
|
m_descriptor.namespaceName,
|
|
m_descriptor.className,
|
|
assetClass) ||
|
|
assetClass == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsMonoClassOrSubclass(
|
|
assetClass,
|
|
m_runtime->m_scriptableRenderPipelineAssetClass)) {
|
|
m_runtime->SetError(
|
|
"Managed render pipeline asset must derive from ScriptableRenderPipelineAsset: " +
|
|
m_descriptor.GetFullName() + ".");
|
|
return false;
|
|
}
|
|
|
|
m_ownsManagedAssetHandle =
|
|
m_runtime->CreateExternalManagedObject(assetClass, m_assetHandle) &&
|
|
m_assetHandle != 0;
|
|
return m_ownsManagedAssetHandle;
|
|
}
|
|
|
|
bool MonoManagedRenderPipelineAssetRuntime::SyncManagedAssetRuntimeState() const {
|
|
if (!EnsureManagedAsset()) {
|
|
return false;
|
|
}
|
|
|
|
int32_t runtimeResourceVersion = 0;
|
|
if (!TryGetManagedRuntimeResourceVersion(runtimeResourceVersion)) {
|
|
return false;
|
|
}
|
|
|
|
if (!m_runtimeResourceVersionResolved) {
|
|
m_runtimeResourceVersion = runtimeResourceVersion;
|
|
m_runtimeResourceVersionResolved = true;
|
|
return true;
|
|
}
|
|
|
|
if (runtimeResourceVersion == m_runtimeResourceVersion) {
|
|
return true;
|
|
}
|
|
|
|
ReleaseManagedPipeline();
|
|
m_runtimeResourceVersion = runtimeResourceVersion;
|
|
return true;
|
|
}
|
|
|
|
bool MonoManagedRenderPipelineAssetRuntime::TryGetManagedRuntimeResourceVersion(
|
|
int32_t& outVersion) const {
|
|
outVersion = 0;
|
|
if (!EnsureManagedAsset()) {
|
|
return false;
|
|
}
|
|
|
|
MonoObject* const assetObject = GetManagedAssetObject();
|
|
MonoMethod* const method =
|
|
ResolveGetRuntimeResourceVersionMethod(assetObject);
|
|
if (assetObject == nullptr || method == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
MonoObject* managedVersion = nullptr;
|
|
if (!m_runtime->InvokeManagedMethod(
|
|
assetObject,
|
|
method,
|
|
nullptr,
|
|
&managedVersion)) {
|
|
return false;
|
|
}
|
|
|
|
return TryUnboxManagedInt32(managedVersion, outVersion);
|
|
}
|
|
|
|
void MonoManagedRenderPipelineAssetRuntime::ReleaseManagedPipeline() const {
|
|
m_pipelineCreationAttempted = false;
|
|
m_disposePipelineMethod = nullptr;
|
|
|
|
if (!IsRuntimeAlive()) {
|
|
m_pipelineHandle = 0;
|
|
return;
|
|
}
|
|
|
|
if (m_pipelineHandle != 0) {
|
|
MonoObject* const pipelineObject =
|
|
m_runtime->GetManagedObject(m_pipelineHandle);
|
|
MonoMethod* const disposeMethod =
|
|
ResolveDisposePipelineMethod(pipelineObject);
|
|
if (pipelineObject != nullptr && disposeMethod != nullptr) {
|
|
m_runtime->InvokeManagedMethod(
|
|
pipelineObject,
|
|
disposeMethod,
|
|
nullptr,
|
|
nullptr);
|
|
}
|
|
|
|
m_runtime->DestroyExternalManagedObject(m_pipelineHandle);
|
|
m_pipelineHandle = 0;
|
|
}
|
|
}
|
|
|
|
void MonoManagedRenderPipelineAssetRuntime::ReleaseManagedAsset() const {
|
|
ReleaseManagedPipeline();
|
|
m_releaseRuntimeResourcesMethod = nullptr;
|
|
m_createPipelineMethod = nullptr;
|
|
m_configureCameraRenderRequestMethod = nullptr;
|
|
m_configureCameraFramePlanMethod = nullptr;
|
|
m_getDefaultFinalColorSettingsMethod = nullptr;
|
|
m_getRuntimeResourceVersionMethod = nullptr;
|
|
m_configureRenderSceneSetupMethod = nullptr;
|
|
m_configureDirectionalShadowExecutionStateMethod = nullptr;
|
|
m_runtimeResourceVersionResolved = false;
|
|
m_runtimeResourceVersion = 0;
|
|
const bool ownsManagedAssetHandle = m_ownsManagedAssetHandle;
|
|
m_ownsManagedAssetHandle = false;
|
|
m_assetCreationAttempted = false;
|
|
|
|
if (!IsRuntimeAlive()) {
|
|
m_assetHandle = 0;
|
|
return;
|
|
}
|
|
|
|
MonoObject* const assetObject = GetManagedAssetObject();
|
|
MonoMethod* const releaseRuntimeResourcesMethod =
|
|
ResolveReleaseRuntimeResourcesMethod(assetObject);
|
|
if (assetObject != nullptr && releaseRuntimeResourcesMethod != nullptr) {
|
|
m_runtime->InvokeManagedMethod(
|
|
assetObject,
|
|
releaseRuntimeResourcesMethod,
|
|
nullptr,
|
|
nullptr);
|
|
}
|
|
|
|
if (m_assetHandle != 0 && ownsManagedAssetHandle) {
|
|
m_runtime->DestroyExternalManagedObject(m_assetHandle);
|
|
}
|
|
|
|
m_assetHandle = 0;
|
|
}
|
|
|
|
MonoObject* MonoManagedRenderPipelineAssetRuntime::GetManagedAssetObject() const {
|
|
return m_assetHandle != 0
|
|
? m_runtime->GetManagedObject(m_assetHandle)
|
|
: nullptr;
|
|
}
|
|
|
|
MonoMethod* MonoManagedRenderPipelineAssetRuntime::ResolveDisposePipelineMethod(
|
|
MonoObject* pipelineObject) const {
|
|
if (m_disposePipelineMethod == nullptr) {
|
|
m_disposePipelineMethod =
|
|
m_runtime->ResolveManagedMethod(
|
|
pipelineObject,
|
|
"DisposeInstance",
|
|
0);
|
|
}
|
|
|
|
return m_disposePipelineMethod;
|
|
}
|
|
|
|
MonoMethod* MonoManagedRenderPipelineAssetRuntime::ResolveCreatePipelineMethod(
|
|
MonoObject* assetObject) const {
|
|
if (m_createPipelineMethod == nullptr) {
|
|
m_createPipelineMethod =
|
|
m_runtime->ResolveManagedMethod(
|
|
assetObject,
|
|
"CreatePipeline",
|
|
0);
|
|
}
|
|
|
|
return m_createPipelineMethod;
|
|
}
|
|
|
|
MonoMethod*
|
|
MonoManagedRenderPipelineAssetRuntime::ResolveConfigureCameraRenderRequestMethod(
|
|
MonoObject* assetObject) const {
|
|
if (m_configureCameraRenderRequestMethod == nullptr) {
|
|
m_configureCameraRenderRequestMethod =
|
|
m_runtime->ResolveManagedMethod(
|
|
assetObject,
|
|
"ConfigureCameraRenderRequest",
|
|
1);
|
|
}
|
|
|
|
return m_configureCameraRenderRequestMethod;
|
|
}
|
|
|
|
MonoMethod*
|
|
MonoManagedRenderPipelineAssetRuntime::ResolveConfigureCameraFramePlanMethod(
|
|
MonoObject* assetObject) const {
|
|
if (m_configureCameraFramePlanMethod == nullptr) {
|
|
m_configureCameraFramePlanMethod =
|
|
m_runtime->ResolveManagedMethod(
|
|
assetObject,
|
|
"ConfigureCameraFramePlanInstance",
|
|
1);
|
|
}
|
|
|
|
return m_configureCameraFramePlanMethod;
|
|
}
|
|
|
|
MonoMethod*
|
|
MonoManagedRenderPipelineAssetRuntime::ResolveGetDefaultFinalColorSettingsMethod(
|
|
MonoObject* assetObject) const {
|
|
if (m_getDefaultFinalColorSettingsMethod == nullptr) {
|
|
m_getDefaultFinalColorSettingsMethod =
|
|
m_runtime->ResolveManagedMethod(
|
|
assetObject,
|
|
"GetDefaultFinalColorSettings",
|
|
0);
|
|
}
|
|
|
|
return m_getDefaultFinalColorSettingsMethod;
|
|
}
|
|
|
|
MonoMethod*
|
|
MonoManagedRenderPipelineAssetRuntime::ResolveGetRuntimeResourceVersionMethod(
|
|
MonoObject* assetObject) const {
|
|
if (m_getRuntimeResourceVersionMethod == nullptr) {
|
|
m_getRuntimeResourceVersionMethod =
|
|
m_runtime->ResolveManagedMethod(
|
|
assetObject,
|
|
"GetRuntimeResourceVersionInstance",
|
|
0);
|
|
}
|
|
|
|
return m_getRuntimeResourceVersionMethod;
|
|
}
|
|
|
|
MonoMethod*
|
|
MonoManagedRenderPipelineAssetRuntime::
|
|
ResolveConfigureRenderSceneSetupMethod(
|
|
MonoObject* assetObject) const {
|
|
if (m_configureRenderSceneSetupMethod == nullptr) {
|
|
m_configureRenderSceneSetupMethod =
|
|
m_runtime->ResolveManagedMethod(
|
|
assetObject,
|
|
"ConfigureRenderSceneSetupInstance",
|
|
1);
|
|
}
|
|
|
|
return m_configureRenderSceneSetupMethod;
|
|
}
|
|
|
|
MonoMethod*
|
|
MonoManagedRenderPipelineAssetRuntime::
|
|
ResolveConfigureDirectionalShadowExecutionStateMethod(
|
|
MonoObject* assetObject) const {
|
|
if (m_configureDirectionalShadowExecutionStateMethod ==
|
|
nullptr) {
|
|
m_configureDirectionalShadowExecutionStateMethod =
|
|
m_runtime->ResolveManagedMethod(
|
|
assetObject,
|
|
"ConfigureDirectionalShadowExecutionStateInstance",
|
|
1);
|
|
}
|
|
|
|
return m_configureDirectionalShadowExecutionStateMethod;
|
|
}
|
|
|
|
MonoMethod*
|
|
MonoManagedRenderPipelineAssetRuntime::ResolveReleaseRuntimeResourcesMethod(
|
|
MonoObject* assetObject) const {
|
|
if (m_releaseRuntimeResourcesMethod == nullptr) {
|
|
m_releaseRuntimeResourcesMethod =
|
|
m_runtime->ResolveManagedMethod(
|
|
assetObject,
|
|
"ReleaseRuntimeResourcesInstance",
|
|
0);
|
|
}
|
|
|
|
return m_releaseRuntimeResourcesMethod;
|
|
}
|
|
|
|
class MonoManagedRenderPipelineBridge final
|
|
: public Rendering::Pipelines::ManagedRenderPipelineBridge {
|
|
public:
|
|
MonoManagedRenderPipelineBridge(
|
|
MonoScriptRuntime* runtime,
|
|
std::weak_ptr<void> runtimeLifetime)
|
|
: m_runtime(runtime)
|
|
, m_runtimeLifetime(std::move(runtimeLifetime)) {
|
|
}
|
|
|
|
std::shared_ptr<const Rendering::Pipelines::ManagedRenderPipelineAssetRuntime>
|
|
CreateAssetRuntime(
|
|
const Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor& descriptor)
|
|
const override {
|
|
if (!IsRuntimeAlive() || !descriptor.IsValid()) {
|
|
return nullptr;
|
|
}
|
|
|
|
return std::make_shared<MonoManagedRenderPipelineAssetRuntime>(
|
|
m_runtime,
|
|
m_runtimeLifetime,
|
|
descriptor);
|
|
}
|
|
|
|
private:
|
|
bool IsRuntimeAlive() const {
|
|
return m_runtime != nullptr &&
|
|
!m_runtimeLifetime.expired() &&
|
|
m_runtime->m_initialized;
|
|
}
|
|
|
|
MonoScriptRuntime* m_runtime = nullptr;
|
|
std::weak_ptr<void> m_runtimeLifetime;
|
|
};
|
|
|
|
namespace {
|
|
|
|
ManagedComponentTypeInfo ResolveManagedComponentTypeInfo(MonoClass* monoClass) {
|
|
ManagedComponentTypeInfo typeInfo;
|
|
if (!monoClass) {
|
|
return typeInfo;
|
|
}
|
|
|
|
typeInfo.monoClass = monoClass;
|
|
typeInfo.namespaceName = SafeString(mono_class_get_namespace(monoClass));
|
|
typeInfo.className = SafeString(mono_class_get_name(monoClass));
|
|
|
|
if (typeInfo.namespaceName == "XCEngine" && typeInfo.className == "Transform") {
|
|
typeInfo.kind = ManagedComponentKind::Transform;
|
|
return typeInfo;
|
|
}
|
|
if (typeInfo.namespaceName == "XCEngine" && typeInfo.className == "Rigidbody") {
|
|
typeInfo.kind = ManagedComponentKind::Rigidbody;
|
|
return typeInfo;
|
|
}
|
|
if (typeInfo.namespaceName == "XCEngine" && typeInfo.className == "Camera") {
|
|
typeInfo.kind = ManagedComponentKind::Camera;
|
|
return typeInfo;
|
|
}
|
|
if (typeInfo.namespaceName == "XCEngine" && typeInfo.className == "Light") {
|
|
typeInfo.kind = ManagedComponentKind::Light;
|
|
return typeInfo;
|
|
}
|
|
if (typeInfo.namespaceName == "XCEngine" && typeInfo.className == "MeshFilter") {
|
|
typeInfo.kind = ManagedComponentKind::MeshFilter;
|
|
return typeInfo;
|
|
}
|
|
if (typeInfo.namespaceName == "XCEngine" && typeInfo.className == "MeshRenderer") {
|
|
typeInfo.kind = ManagedComponentKind::MeshRenderer;
|
|
return typeInfo;
|
|
}
|
|
|
|
MonoScriptRuntime* runtime = GetActiveMonoScriptRuntime();
|
|
if (runtime
|
|
&& runtime->IsClassAvailable(
|
|
runtime->GetSettings().appAssemblyName,
|
|
typeInfo.namespaceName,
|
|
typeInfo.className)) {
|
|
typeInfo.kind = ManagedComponentKind::Script;
|
|
typeInfo.assemblyName = runtime->GetSettings().appAssemblyName;
|
|
}
|
|
|
|
return typeInfo;
|
|
}
|
|
|
|
ManagedComponentTypeInfo ResolveManagedComponentTypeInfo(MonoReflectionType* reflectionType) {
|
|
if (!reflectionType) {
|
|
return {};
|
|
}
|
|
|
|
MonoType* monoType = mono_reflection_type_get_type(reflectionType);
|
|
if (!monoType) {
|
|
return {};
|
|
}
|
|
|
|
return ResolveManagedComponentTypeInfo(mono_class_from_mono_type(monoType));
|
|
}
|
|
|
|
Components::GameObject* FindGameObjectByUUIDRecursive(Components::GameObject* gameObject, uint64_t uuid) {
|
|
if (!gameObject) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (gameObject->GetUUID() == uuid) {
|
|
return gameObject;
|
|
}
|
|
|
|
for (Components::GameObject* child : gameObject->GetChildren()) {
|
|
if (Components::GameObject* found = FindGameObjectByUUIDRecursive(child, uuid)) {
|
|
return found;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
ScriptComponent* FindScriptComponentByUUIDRecursive(Components::GameObject* gameObject, uint64_t scriptComponentUUID) {
|
|
if (!gameObject || scriptComponentUUID == 0) {
|
|
return nullptr;
|
|
}
|
|
|
|
for (ScriptComponent* component : gameObject->GetComponents<ScriptComponent>()) {
|
|
if (component && component->GetScriptComponentUUID() == scriptComponentUUID) {
|
|
return component;
|
|
}
|
|
}
|
|
|
|
for (Components::GameObject* child : gameObject->GetChildren()) {
|
|
if (ScriptComponent* found = FindScriptComponentByUUIDRecursive(child, scriptComponentUUID)) {
|
|
return found;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
Components::GameObject* FindGameObjectByUUID(uint64_t uuid) {
|
|
Components::Scene* scene = GetInternalCallScene();
|
|
if (!scene || uuid == 0) {
|
|
return nullptr;
|
|
}
|
|
|
|
for (Components::GameObject* root : scene->GetRootGameObjects()) {
|
|
if (Components::GameObject* found = FindGameObjectByUUIDRecursive(root, uuid)) {
|
|
return found;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
ScriptComponent* FindScriptComponentByUUID(uint64_t scriptComponentUUID) {
|
|
Components::Scene* scene = GetInternalCallScene();
|
|
if (!scene || scriptComponentUUID == 0) {
|
|
return nullptr;
|
|
}
|
|
|
|
for (Components::GameObject* root : scene->GetRootGameObjects()) {
|
|
if (ScriptComponent* found = FindScriptComponentByUUIDRecursive(root, scriptComponentUUID)) {
|
|
return found;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
Components::Component* FindNativeComponent(Components::GameObject* gameObject, ManagedComponentKind componentKind) {
|
|
if (!gameObject) {
|
|
return nullptr;
|
|
}
|
|
|
|
switch (componentKind) {
|
|
case ManagedComponentKind::Transform:
|
|
return gameObject->GetTransform();
|
|
case ManagedComponentKind::Rigidbody:
|
|
return gameObject->GetComponent<Components::RigidbodyComponent>();
|
|
case ManagedComponentKind::Camera:
|
|
return gameObject->GetComponent<Components::CameraComponent>();
|
|
case ManagedComponentKind::Light:
|
|
return gameObject->GetComponent<Components::LightComponent>();
|
|
case ManagedComponentKind::MeshFilter:
|
|
return gameObject->GetComponent<Components::MeshFilterComponent>();
|
|
case ManagedComponentKind::MeshRenderer:
|
|
return gameObject->GetComponent<Components::MeshRendererComponent>();
|
|
case ManagedComponentKind::Script:
|
|
case ManagedComponentKind::Unknown:
|
|
return nullptr;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
bool HasNativeComponent(Components::GameObject* gameObject, ManagedComponentKind componentKind) {
|
|
return FindNativeComponent(gameObject, componentKind) != nullptr;
|
|
}
|
|
|
|
bool IsMatchingScriptComponent(const ScriptComponent* component, const ManagedComponentTypeInfo& typeInfo) {
|
|
return component
|
|
&& component->HasScriptClass()
|
|
&& typeInfo.kind == ManagedComponentKind::Script
|
|
&& component->GetAssemblyName() == typeInfo.assemblyName
|
|
&& component->GetNamespaceName() == typeInfo.namespaceName
|
|
&& component->GetClassName() == typeInfo.className;
|
|
}
|
|
|
|
Components::Component* AddOrGetNativeComponent(Components::GameObject* gameObject, ManagedComponentKind componentKind) {
|
|
if (!gameObject) {
|
|
return nullptr;
|
|
}
|
|
|
|
switch (componentKind) {
|
|
case ManagedComponentKind::Transform:
|
|
return gameObject->GetTransform();
|
|
case ManagedComponentKind::Rigidbody:
|
|
return gameObject->GetComponent<Components::RigidbodyComponent>()
|
|
? static_cast<Components::Component*>(gameObject->GetComponent<Components::RigidbodyComponent>())
|
|
: static_cast<Components::Component*>(gameObject->AddComponent<Components::RigidbodyComponent>());
|
|
case ManagedComponentKind::Camera:
|
|
return gameObject->GetComponent<Components::CameraComponent>()
|
|
? static_cast<Components::Component*>(gameObject->GetComponent<Components::CameraComponent>())
|
|
: static_cast<Components::Component*>(gameObject->AddComponent<Components::CameraComponent>());
|
|
case ManagedComponentKind::Light:
|
|
return gameObject->GetComponent<Components::LightComponent>()
|
|
? static_cast<Components::Component*>(gameObject->GetComponent<Components::LightComponent>())
|
|
: static_cast<Components::Component*>(gameObject->AddComponent<Components::LightComponent>());
|
|
case ManagedComponentKind::MeshFilter:
|
|
return gameObject->GetComponent<Components::MeshFilterComponent>()
|
|
? static_cast<Components::Component*>(gameObject->GetComponent<Components::MeshFilterComponent>())
|
|
: static_cast<Components::Component*>(gameObject->AddComponent<Components::MeshFilterComponent>());
|
|
case ManagedComponentKind::MeshRenderer:
|
|
return gameObject->GetComponent<Components::MeshRendererComponent>()
|
|
? static_cast<Components::Component*>(gameObject->GetComponent<Components::MeshRendererComponent>())
|
|
: static_cast<Components::Component*>(gameObject->AddComponent<Components::MeshRendererComponent>());
|
|
case ManagedComponentKind::Script:
|
|
case ManagedComponentKind::Unknown:
|
|
return nullptr;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
ScriptComponent* FindMatchingScriptComponent(
|
|
Components::GameObject* gameObject,
|
|
const ManagedComponentTypeInfo& typeInfo) {
|
|
if (!gameObject || typeInfo.kind != ManagedComponentKind::Script) {
|
|
return nullptr;
|
|
}
|
|
|
|
for (ScriptComponent* component : gameObject->GetComponents<ScriptComponent>()) {
|
|
if (IsMatchingScriptComponent(component, typeInfo)) {
|
|
return component;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
ScriptComponent* FindMatchingScriptComponentInChildren(
|
|
Components::GameObject* gameObject,
|
|
const ManagedComponentTypeInfo& typeInfo) {
|
|
if (!gameObject) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (ScriptComponent* component = FindMatchingScriptComponent(gameObject, typeInfo)) {
|
|
return component;
|
|
}
|
|
|
|
for (Components::GameObject* child : gameObject->GetChildren()) {
|
|
if (ScriptComponent* component = FindMatchingScriptComponentInChildren(child, typeInfo)) {
|
|
return component;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
ScriptComponent* FindMatchingScriptComponentInParent(
|
|
Components::GameObject* gameObject,
|
|
const ManagedComponentTypeInfo& typeInfo) {
|
|
while (gameObject) {
|
|
if (ScriptComponent* component = FindMatchingScriptComponent(gameObject, typeInfo)) {
|
|
return component;
|
|
}
|
|
|
|
gameObject = gameObject->GetParent();
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
Components::Component* FindNativeComponentInChildren(
|
|
Components::GameObject* gameObject,
|
|
ManagedComponentKind componentKind) {
|
|
if (!gameObject) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (Components::Component* component = FindNativeComponent(gameObject, componentKind)) {
|
|
return component;
|
|
}
|
|
|
|
for (Components::GameObject* child : gameObject->GetChildren()) {
|
|
if (Components::Component* component = FindNativeComponentInChildren(child, componentKind)) {
|
|
return component;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
Components::Component* FindNativeComponentInParent(
|
|
Components::GameObject* gameObject,
|
|
ManagedComponentKind componentKind) {
|
|
while (gameObject) {
|
|
if (Components::Component* component = FindNativeComponent(gameObject, componentKind)) {
|
|
return component;
|
|
}
|
|
|
|
gameObject = gameObject->GetParent();
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
bool DestroyNativeComponentInstance(Components::GameObject* gameObject, Components::Component* component) {
|
|
if (!gameObject || !component || component == gameObject->GetTransform()) {
|
|
return false;
|
|
}
|
|
|
|
if (component->IsEnabled() && gameObject->IsActiveInHierarchy()) {
|
|
component->OnDisable();
|
|
}
|
|
|
|
component->OnDestroy();
|
|
return gameObject->RemoveComponent(component);
|
|
}
|
|
|
|
Components::CameraComponent* FindCameraComponent(uint64_t gameObjectUUID) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
return gameObject ? gameObject->GetComponent<Components::CameraComponent>() : nullptr;
|
|
}
|
|
|
|
Components::LightComponent* FindLightComponent(uint64_t gameObjectUUID) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
return gameObject ? gameObject->GetComponent<Components::LightComponent>() : nullptr;
|
|
}
|
|
|
|
Components::MeshFilterComponent* FindMeshFilterComponent(uint64_t gameObjectUUID) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
return gameObject ? gameObject->GetComponent<Components::MeshFilterComponent>() : nullptr;
|
|
}
|
|
|
|
Components::MeshRendererComponent* FindMeshRendererComponent(uint64_t gameObjectUUID) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
return gameObject ? gameObject->GetComponent<Components::MeshRendererComponent>() : nullptr;
|
|
}
|
|
|
|
Components::RigidbodyComponent* FindRigidbodyComponent(uint64_t gameObjectUUID) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
return gameObject ? gameObject->GetComponent<Components::RigidbodyComponent>() : nullptr;
|
|
}
|
|
|
|
Components::Space ResolveManagedSpace(int32_t value) {
|
|
return value == static_cast<int32_t>(Components::Space::World)
|
|
? Components::Space::World
|
|
: Components::Space::Self;
|
|
}
|
|
|
|
Physics::PhysicsBodyType ResolveManagedPhysicsBodyType(int32_t value) {
|
|
switch (value) {
|
|
case static_cast<int32_t>(Physics::PhysicsBodyType::Static):
|
|
return Physics::PhysicsBodyType::Static;
|
|
case static_cast<int32_t>(Physics::PhysicsBodyType::Kinematic):
|
|
return Physics::PhysicsBodyType::Kinematic;
|
|
case static_cast<int32_t>(Physics::PhysicsBodyType::Dynamic):
|
|
default:
|
|
return Physics::PhysicsBodyType::Dynamic;
|
|
}
|
|
}
|
|
|
|
Physics::PhysicsForceMode ResolveManagedForceMode(int32_t value) {
|
|
switch (value) {
|
|
case static_cast<int32_t>(Physics::PhysicsForceMode::Acceleration):
|
|
return Physics::PhysicsForceMode::Acceleration;
|
|
case static_cast<int32_t>(Physics::PhysicsForceMode::Impulse):
|
|
return Physics::PhysicsForceMode::Impulse;
|
|
case static_cast<int32_t>(Physics::PhysicsForceMode::VelocityChange):
|
|
return Physics::PhysicsForceMode::VelocityChange;
|
|
case static_cast<int32_t>(Physics::PhysicsForceMode::Force):
|
|
default:
|
|
return Physics::PhysicsForceMode::Force;
|
|
}
|
|
}
|
|
|
|
Physics::PhysicsWorld* FindRuntimePhysicsWorld() {
|
|
return ScriptEngine::Get().GetRuntimePhysicsWorld();
|
|
}
|
|
|
|
MonoArray* CreateManagedComponentArray(MonoClass* componentClass, const std::vector<MonoObject*>& components) {
|
|
if (!componentClass) {
|
|
return nullptr;
|
|
}
|
|
|
|
MonoDomain* domain = mono_domain_get();
|
|
if (!domain) {
|
|
return nullptr;
|
|
}
|
|
|
|
MonoArray* array = mono_array_new(domain, componentClass, static_cast<uintptr_t>(components.size()));
|
|
if (!array) {
|
|
return nullptr;
|
|
}
|
|
|
|
for (uintptr_t index = 0; index < components.size(); ++index) {
|
|
mono_array_setref(array, index, components[index]);
|
|
}
|
|
|
|
return array;
|
|
}
|
|
|
|
void LogManagedMessage(
|
|
XCEngine::Debug::LogLevel level,
|
|
MonoString* message,
|
|
MonoString* file,
|
|
int32_t line,
|
|
MonoString* member) {
|
|
const std::string messageText = MonoStringToUtf8(message);
|
|
const std::string fileText = MonoStringToUtf8(file);
|
|
const std::string memberText = MonoStringToUtf8(member);
|
|
XCEngine::Debug::Logger::Get().Log(
|
|
level,
|
|
XCEngine::Debug::LogCategory::Scripting,
|
|
XCEngine::Containers::String(messageText.c_str()),
|
|
fileText.c_str(),
|
|
line,
|
|
memberText.c_str());
|
|
}
|
|
|
|
void InternalCall_Debug_Log(MonoString* message, MonoString* file, int32_t line, MonoString* member) {
|
|
LogManagedMessage(XCEngine::Debug::LogLevel::Info, message, file, line, member);
|
|
}
|
|
|
|
void InternalCall_Debug_LogWarning(MonoString* message, MonoString* file, int32_t line, MonoString* member) {
|
|
LogManagedMessage(XCEngine::Debug::LogLevel::Warning, message, file, line, member);
|
|
}
|
|
|
|
void InternalCall_Debug_LogError(MonoString* message, MonoString* file, int32_t line, MonoString* member) {
|
|
LogManagedMessage(XCEngine::Debug::LogLevel::Error, message, file, line, member);
|
|
}
|
|
|
|
float InternalCall_Time_GetDeltaTime() {
|
|
return GetInternalCallDeltaTime();
|
|
}
|
|
|
|
float InternalCall_Time_GetFixedDeltaTime() {
|
|
return ScriptEngine::Get().GetRuntimeFixedDeltaTime();
|
|
}
|
|
|
|
mono_bool InternalCall_Input_GetKey(int32_t keyCode) {
|
|
return XCEngine::Input::InputManager::Get().IsKeyDown(
|
|
static_cast<XCEngine::Input::KeyCode>(keyCode)) ? 1 : 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Input_GetKeyDown(int32_t keyCode) {
|
|
return XCEngine::Input::InputManager::Get().IsKeyPressed(
|
|
static_cast<XCEngine::Input::KeyCode>(keyCode)) ? 1 : 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Input_GetKeyUp(int32_t keyCode) {
|
|
return XCEngine::Input::InputManager::Get().IsKeyReleased(
|
|
static_cast<XCEngine::Input::KeyCode>(keyCode)) ? 1 : 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Input_GetMouseButton(int32_t button) {
|
|
return XCEngine::Input::InputManager::Get().IsMouseButtonDown(
|
|
static_cast<XCEngine::Input::MouseButton>(button)) ? 1 : 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Input_GetMouseButtonDown(int32_t button) {
|
|
return XCEngine::Input::InputManager::Get().IsMouseButtonClicked(
|
|
static_cast<XCEngine::Input::MouseButton>(button)) ? 1 : 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Input_GetMouseButtonUp(int32_t button) {
|
|
return XCEngine::Input::InputManager::Get().IsMouseButtonReleased(
|
|
static_cast<XCEngine::Input::MouseButton>(button)) ? 1 : 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Input_GetButton(MonoString* buttonName) {
|
|
return XCEngine::Input::InputManager::Get().GetButton(
|
|
XCEngine::Containers::String(MonoStringToUtf8(buttonName).c_str())) ? 1 : 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Input_GetButtonDown(MonoString* buttonName) {
|
|
return XCEngine::Input::InputManager::Get().GetButtonDown(
|
|
XCEngine::Containers::String(MonoStringToUtf8(buttonName).c_str())) ? 1 : 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Input_GetButtonUp(MonoString* buttonName) {
|
|
return XCEngine::Input::InputManager::Get().GetButtonUp(
|
|
XCEngine::Containers::String(MonoStringToUtf8(buttonName).c_str())) ? 1 : 0;
|
|
}
|
|
|
|
float InternalCall_Input_GetAxis(MonoString* axisName) {
|
|
return XCEngine::Input::InputManager::Get().GetAxis(
|
|
XCEngine::Containers::String(MonoStringToUtf8(axisName).c_str()));
|
|
}
|
|
|
|
float InternalCall_Input_GetAxisRaw(MonoString* axisName) {
|
|
return XCEngine::Input::InputManager::Get().GetAxisRaw(
|
|
XCEngine::Containers::String(MonoStringToUtf8(axisName).c_str()));
|
|
}
|
|
|
|
mono_bool InternalCall_Input_GetAnyKey() {
|
|
return XCEngine::Input::InputManager::Get().IsAnyKeyDown() ? 1 : 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Input_GetAnyKeyDown() {
|
|
return XCEngine::Input::InputManager::Get().IsAnyKeyPressed() ? 1 : 0;
|
|
}
|
|
|
|
void InternalCall_Input_GetMousePosition(XCEngine::Math::Vector3* outPosition) {
|
|
if (!outPosition) {
|
|
return;
|
|
}
|
|
|
|
const XCEngine::Math::Vector2 position = XCEngine::Input::InputManager::Get().GetMousePosition();
|
|
*outPosition = XCEngine::Math::Vector3(position.x, position.y, 0.0f);
|
|
}
|
|
|
|
void InternalCall_Input_GetMouseScrollDelta(XCEngine::Math::Vector2* outDelta) {
|
|
if (!outDelta) {
|
|
return;
|
|
}
|
|
|
|
*outDelta = XCEngine::Math::Vector2(
|
|
0.0f,
|
|
XCEngine::Input::InputManager::Get().GetMouseScrollDelta());
|
|
}
|
|
|
|
MonoString* InternalCall_GameObject_GetName(uint64_t gameObjectUUID) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
return mono_string_new(
|
|
mono_domain_get(),
|
|
gameObject ? gameObject->GetName().c_str() : "");
|
|
}
|
|
|
|
void InternalCall_GameObject_SetName(uint64_t gameObjectUUID, MonoString* name) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject) {
|
|
return;
|
|
}
|
|
|
|
gameObject->SetName(MonoStringToUtf8(name));
|
|
}
|
|
|
|
MonoString* InternalCall_GameObject_GetTag(uint64_t gameObjectUUID) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
return mono_string_new(
|
|
mono_domain_get(),
|
|
gameObject ? gameObject->GetTag().c_str() : "");
|
|
}
|
|
|
|
void InternalCall_GameObject_SetTag(uint64_t gameObjectUUID, MonoString* tag) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject) {
|
|
return;
|
|
}
|
|
|
|
gameObject->SetTag(MonoStringToUtf8(tag));
|
|
}
|
|
|
|
mono_bool InternalCall_GameObject_CompareTag(uint64_t gameObjectUUID, MonoString* tag) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
return (gameObject && gameObject->CompareTag(MonoStringToUtf8(tag))) ? 1 : 0;
|
|
}
|
|
|
|
int32_t InternalCall_GameObject_GetLayer(uint64_t gameObjectUUID) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
return gameObject ? static_cast<int32_t>(gameObject->GetLayer()) : 0;
|
|
}
|
|
|
|
void InternalCall_GameObject_SetLayer(uint64_t gameObjectUUID, int32_t layer) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject) {
|
|
return;
|
|
}
|
|
|
|
gameObject->SetLayer(static_cast<uint8_t>(std::clamp(layer, 0, 31)));
|
|
}
|
|
|
|
mono_bool InternalCall_GameObject_GetActiveSelf(uint64_t gameObjectUUID) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
return (gameObject && gameObject->IsActive()) ? 1 : 0;
|
|
}
|
|
|
|
mono_bool InternalCall_GameObject_GetActiveInHierarchy(uint64_t gameObjectUUID) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
return (gameObject && gameObject->IsActiveInHierarchy()) ? 1 : 0;
|
|
}
|
|
|
|
void InternalCall_GameObject_SetActive(uint64_t gameObjectUUID, mono_bool active) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject) {
|
|
return;
|
|
}
|
|
|
|
gameObject->SetActive(active != 0);
|
|
}
|
|
|
|
mono_bool InternalCall_GameObject_HasComponent(uint64_t gameObjectUUID, MonoReflectionType* componentType) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
const ManagedComponentTypeInfo typeInfo = ResolveManagedComponentTypeInfo(componentType);
|
|
if (typeInfo.kind == ManagedComponentKind::Script) {
|
|
return FindMatchingScriptComponent(gameObject, typeInfo) ? 1 : 0;
|
|
}
|
|
|
|
return HasNativeComponent(gameObject, typeInfo.kind) ? 1 : 0;
|
|
}
|
|
|
|
MonoObject* InternalCall_GameObject_GetComponent(uint64_t gameObjectUUID, MonoReflectionType* componentType) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject) {
|
|
return nullptr;
|
|
}
|
|
|
|
MonoScriptRuntime* runtime = GetActiveMonoScriptRuntime();
|
|
if (!runtime) {
|
|
return nullptr;
|
|
}
|
|
|
|
const ManagedComponentTypeInfo typeInfo = ResolveManagedComponentTypeInfo(componentType);
|
|
if (typeInfo.kind == ManagedComponentKind::Script) {
|
|
ScriptComponent* component = FindMatchingScriptComponent(gameObject, typeInfo);
|
|
if (!component) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (!runtime->HasManagedInstance(component)) {
|
|
ScriptEngine::Get().OnScriptComponentEnabled(component);
|
|
}
|
|
|
|
return runtime->GetManagedInstanceObject(component);
|
|
}
|
|
|
|
if (!HasNativeComponent(gameObject, typeInfo.kind) || !typeInfo.monoClass) {
|
|
return nullptr;
|
|
}
|
|
|
|
return runtime->CreateManagedComponentWrapper(typeInfo.monoClass, gameObjectUUID);
|
|
}
|
|
|
|
MonoArray* InternalCall_GameObject_GetComponents(uint64_t gameObjectUUID, MonoReflectionType* componentType) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject) {
|
|
return nullptr;
|
|
}
|
|
|
|
MonoScriptRuntime* runtime = GetActiveMonoScriptRuntime();
|
|
if (!runtime) {
|
|
return nullptr;
|
|
}
|
|
|
|
const ManagedComponentTypeInfo typeInfo = ResolveManagedComponentTypeInfo(componentType);
|
|
if (!typeInfo.monoClass) {
|
|
return nullptr;
|
|
}
|
|
|
|
std::vector<MonoObject*> managedComponents;
|
|
auto appendNativeComponents = [&](const auto& nativeComponents) {
|
|
for (const auto* component : nativeComponents) {
|
|
if (!component || !component->GetGameObject()) {
|
|
continue;
|
|
}
|
|
|
|
if (MonoObject* managedObject =
|
|
runtime->CreateManagedComponentWrapper(typeInfo.monoClass, component->GetGameObject()->GetUUID())) {
|
|
managedComponents.push_back(managedObject);
|
|
}
|
|
}
|
|
};
|
|
|
|
switch (typeInfo.kind) {
|
|
case ManagedComponentKind::Script:
|
|
for (ScriptComponent* component : gameObject->GetComponents<ScriptComponent>()) {
|
|
if (!IsMatchingScriptComponent(component, typeInfo)) {
|
|
continue;
|
|
}
|
|
|
|
if (!runtime->HasManagedInstance(component)) {
|
|
ScriptEngine::Get().OnScriptComponentEnabled(component);
|
|
}
|
|
|
|
if (MonoObject* managedObject = runtime->GetManagedInstanceObject(component)) {
|
|
managedComponents.push_back(managedObject);
|
|
}
|
|
}
|
|
break;
|
|
case ManagedComponentKind::Transform:
|
|
appendNativeComponents(gameObject->GetComponents<Components::TransformComponent>());
|
|
break;
|
|
case ManagedComponentKind::Rigidbody:
|
|
appendNativeComponents(gameObject->GetComponents<Components::RigidbodyComponent>());
|
|
break;
|
|
case ManagedComponentKind::Camera:
|
|
appendNativeComponents(gameObject->GetComponents<Components::CameraComponent>());
|
|
break;
|
|
case ManagedComponentKind::Light:
|
|
appendNativeComponents(gameObject->GetComponents<Components::LightComponent>());
|
|
break;
|
|
case ManagedComponentKind::MeshFilter:
|
|
appendNativeComponents(gameObject->GetComponents<Components::MeshFilterComponent>());
|
|
break;
|
|
case ManagedComponentKind::MeshRenderer:
|
|
appendNativeComponents(gameObject->GetComponents<Components::MeshRendererComponent>());
|
|
break;
|
|
case ManagedComponentKind::Unknown:
|
|
return nullptr;
|
|
}
|
|
|
|
return CreateManagedComponentArray(typeInfo.monoClass, managedComponents);
|
|
}
|
|
|
|
MonoObject* InternalCall_GameObject_GetComponentInChildren(uint64_t gameObjectUUID, MonoReflectionType* componentType) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject) {
|
|
return nullptr;
|
|
}
|
|
|
|
MonoScriptRuntime* runtime = GetActiveMonoScriptRuntime();
|
|
if (!runtime) {
|
|
return nullptr;
|
|
}
|
|
|
|
const ManagedComponentTypeInfo typeInfo = ResolveManagedComponentTypeInfo(componentType);
|
|
if (typeInfo.kind == ManagedComponentKind::Script) {
|
|
ScriptComponent* component = FindMatchingScriptComponentInChildren(gameObject, typeInfo);
|
|
if (!component) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (!runtime->HasManagedInstance(component)) {
|
|
ScriptEngine::Get().OnScriptComponentEnabled(component);
|
|
}
|
|
|
|
return runtime->GetManagedInstanceObject(component);
|
|
}
|
|
|
|
Components::Component* component = FindNativeComponentInChildren(gameObject, typeInfo.kind);
|
|
if (!component || !typeInfo.monoClass) {
|
|
return nullptr;
|
|
}
|
|
|
|
return runtime->CreateManagedComponentWrapper(typeInfo.monoClass, component->GetGameObject()->GetUUID());
|
|
}
|
|
|
|
MonoObject* InternalCall_GameObject_GetComponentInParent(uint64_t gameObjectUUID, MonoReflectionType* componentType) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject) {
|
|
return nullptr;
|
|
}
|
|
|
|
MonoScriptRuntime* runtime = GetActiveMonoScriptRuntime();
|
|
if (!runtime) {
|
|
return nullptr;
|
|
}
|
|
|
|
const ManagedComponentTypeInfo typeInfo = ResolveManagedComponentTypeInfo(componentType);
|
|
if (typeInfo.kind == ManagedComponentKind::Script) {
|
|
ScriptComponent* component = FindMatchingScriptComponentInParent(gameObject, typeInfo);
|
|
if (!component) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (!runtime->HasManagedInstance(component)) {
|
|
ScriptEngine::Get().OnScriptComponentEnabled(component);
|
|
}
|
|
|
|
return runtime->GetManagedInstanceObject(component);
|
|
}
|
|
|
|
Components::Component* component = FindNativeComponentInParent(gameObject, typeInfo.kind);
|
|
if (!component || !typeInfo.monoClass) {
|
|
return nullptr;
|
|
}
|
|
|
|
return runtime->CreateManagedComponentWrapper(typeInfo.monoClass, component->GetGameObject()->GetUUID());
|
|
}
|
|
|
|
MonoObject* InternalCall_GameObject_AddComponent(uint64_t gameObjectUUID, MonoReflectionType* componentType) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject) {
|
|
return nullptr;
|
|
}
|
|
|
|
MonoScriptRuntime* runtime = GetActiveMonoScriptRuntime();
|
|
if (!runtime) {
|
|
return nullptr;
|
|
}
|
|
|
|
const ManagedComponentTypeInfo typeInfo = ResolveManagedComponentTypeInfo(componentType);
|
|
if (typeInfo.kind == ManagedComponentKind::Script) {
|
|
ScriptComponent* component = gameObject->AddComponent<ScriptComponent>();
|
|
component->SetScriptClass(typeInfo.assemblyName, typeInfo.namespaceName, typeInfo.className);
|
|
return runtime->GetManagedInstanceObject(component);
|
|
}
|
|
|
|
if (!AddOrGetNativeComponent(gameObject, typeInfo.kind) || !typeInfo.monoClass) {
|
|
return nullptr;
|
|
}
|
|
|
|
return runtime->CreateManagedComponentWrapper(typeInfo.monoClass, gameObjectUUID);
|
|
}
|
|
|
|
uint64_t InternalCall_GameObject_Find(MonoString* name) {
|
|
Components::Scene* scene = GetInternalCallScene();
|
|
if (!scene) {
|
|
return 0;
|
|
}
|
|
|
|
Components::GameObject* gameObject = scene->Find(MonoStringToUtf8(name));
|
|
return gameObject ? gameObject->GetUUID() : 0;
|
|
}
|
|
|
|
uint64_t InternalCall_GameObject_Create(MonoString* name, uint64_t parentGameObjectUUID) {
|
|
Components::Scene* scene = GetInternalCallScene();
|
|
if (!scene) {
|
|
return 0;
|
|
}
|
|
|
|
Components::GameObject* parent = nullptr;
|
|
if (parentGameObjectUUID != 0) {
|
|
parent = FindGameObjectByUUID(parentGameObjectUUID);
|
|
if (!parent || parent->GetScene() != scene) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
std::string objectName = MonoStringToUtf8(name);
|
|
if (objectName.empty()) {
|
|
objectName = "GameObject";
|
|
}
|
|
|
|
Components::GameObject* created = scene->CreateGameObject(objectName, parent);
|
|
return created ? created->GetUUID() : 0;
|
|
}
|
|
|
|
void InternalCall_GameObject_Destroy(uint64_t gameObjectUUID) {
|
|
Components::Scene* scene = GetInternalCallScene();
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!scene || !gameObject || gameObject->GetScene() != scene) {
|
|
return;
|
|
}
|
|
|
|
scene->DestroyGameObject(gameObject);
|
|
}
|
|
|
|
void InternalCall_Object_Destroy(MonoObject* object) {
|
|
MonoScriptRuntime* runtime = GetActiveMonoScriptRuntime();
|
|
if (!runtime || !object) {
|
|
return;
|
|
}
|
|
|
|
runtime->DestroyManagedObject(object);
|
|
}
|
|
|
|
mono_bool InternalCall_Behaviour_GetEnabled(uint64_t scriptComponentUUID) {
|
|
ScriptComponent* component = FindScriptComponentByUUID(scriptComponentUUID);
|
|
return (component && component->IsEnabled()) ? 1 : 0;
|
|
}
|
|
|
|
void InternalCall_Behaviour_SetEnabled(uint64_t scriptComponentUUID, mono_bool enabled) {
|
|
ScriptComponent* component = FindScriptComponentByUUID(scriptComponentUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetEnabled(enabled != 0);
|
|
}
|
|
|
|
void InternalCall_Transform_GetLocalPosition(uint64_t gameObjectUUID, XCEngine::Math::Vector3* outPosition) {
|
|
if (!outPosition) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outPosition = XCEngine::Math::Vector3::Zero();
|
|
return;
|
|
}
|
|
|
|
*outPosition = gameObject->GetTransform()->GetLocalPosition();
|
|
}
|
|
|
|
void InternalCall_Transform_SetLocalPosition(uint64_t gameObjectUUID, XCEngine::Math::Vector3* position) {
|
|
if (!position) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
return;
|
|
}
|
|
|
|
gameObject->GetTransform()->SetLocalPosition(*position);
|
|
}
|
|
|
|
void InternalCall_Transform_GetLocalRotation(uint64_t gameObjectUUID, XCEngine::Math::Quaternion* outRotation) {
|
|
if (!outRotation) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outRotation = XCEngine::Math::Quaternion::Identity();
|
|
return;
|
|
}
|
|
|
|
*outRotation = gameObject->GetTransform()->GetLocalRotation();
|
|
}
|
|
|
|
void InternalCall_Transform_SetLocalRotation(uint64_t gameObjectUUID, XCEngine::Math::Quaternion* rotation) {
|
|
if (!rotation) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
return;
|
|
}
|
|
|
|
gameObject->GetTransform()->SetLocalRotation(*rotation);
|
|
}
|
|
|
|
void InternalCall_Transform_GetLocalScale(uint64_t gameObjectUUID, XCEngine::Math::Vector3* outScale) {
|
|
if (!outScale) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outScale = XCEngine::Math::Vector3::One();
|
|
return;
|
|
}
|
|
|
|
*outScale = gameObject->GetTransform()->GetLocalScale();
|
|
}
|
|
|
|
void InternalCall_Transform_SetLocalScale(uint64_t gameObjectUUID, XCEngine::Math::Vector3* scale) {
|
|
if (!scale) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
return;
|
|
}
|
|
|
|
gameObject->GetTransform()->SetLocalScale(*scale);
|
|
}
|
|
|
|
void InternalCall_Transform_GetLocalEulerAngles(uint64_t gameObjectUUID, XCEngine::Math::Vector3* outEulerAngles) {
|
|
if (!outEulerAngles) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outEulerAngles = XCEngine::Math::Vector3::Zero();
|
|
return;
|
|
}
|
|
|
|
*outEulerAngles = gameObject->GetTransform()->GetLocalEulerAngles();
|
|
}
|
|
|
|
void InternalCall_Transform_SetLocalEulerAngles(uint64_t gameObjectUUID, XCEngine::Math::Vector3* eulerAngles) {
|
|
if (!eulerAngles) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
return;
|
|
}
|
|
|
|
gameObject->GetTransform()->SetLocalEulerAngles(*eulerAngles);
|
|
}
|
|
|
|
void InternalCall_Transform_GetPosition(uint64_t gameObjectUUID, XCEngine::Math::Vector3* outPosition) {
|
|
if (!outPosition) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outPosition = XCEngine::Math::Vector3::Zero();
|
|
return;
|
|
}
|
|
|
|
*outPosition = gameObject->GetTransform()->GetPosition();
|
|
}
|
|
|
|
void InternalCall_Transform_SetPosition(uint64_t gameObjectUUID, XCEngine::Math::Vector3* position) {
|
|
if (!position) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
return;
|
|
}
|
|
|
|
gameObject->GetTransform()->SetPosition(*position);
|
|
}
|
|
|
|
void InternalCall_Transform_GetRotation(uint64_t gameObjectUUID, XCEngine::Math::Quaternion* outRotation) {
|
|
if (!outRotation) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outRotation = XCEngine::Math::Quaternion::Identity();
|
|
return;
|
|
}
|
|
|
|
*outRotation = gameObject->GetTransform()->GetRotation();
|
|
}
|
|
|
|
void InternalCall_Transform_SetRotation(uint64_t gameObjectUUID, XCEngine::Math::Quaternion* rotation) {
|
|
if (!rotation) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
return;
|
|
}
|
|
|
|
gameObject->GetTransform()->SetRotation(*rotation);
|
|
}
|
|
|
|
void InternalCall_Transform_GetScale(uint64_t gameObjectUUID, XCEngine::Math::Vector3* outScale) {
|
|
if (!outScale) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outScale = XCEngine::Math::Vector3::One();
|
|
return;
|
|
}
|
|
|
|
*outScale = gameObject->GetTransform()->GetScale();
|
|
}
|
|
|
|
void InternalCall_Transform_SetScale(uint64_t gameObjectUUID, XCEngine::Math::Vector3* scale) {
|
|
if (!scale) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
return;
|
|
}
|
|
|
|
gameObject->GetTransform()->SetScale(*scale);
|
|
}
|
|
|
|
void InternalCall_Transform_GetForward(uint64_t gameObjectUUID, XCEngine::Math::Vector3* outForward) {
|
|
if (!outForward) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outForward = XCEngine::Math::Vector3::Forward();
|
|
return;
|
|
}
|
|
|
|
*outForward = gameObject->GetTransform()->GetForward();
|
|
}
|
|
|
|
void InternalCall_Transform_GetRight(uint64_t gameObjectUUID, XCEngine::Math::Vector3* outRight) {
|
|
if (!outRight) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outRight = XCEngine::Math::Vector3::Right();
|
|
return;
|
|
}
|
|
|
|
*outRight = gameObject->GetTransform()->GetRight();
|
|
}
|
|
|
|
void InternalCall_Transform_GetUp(uint64_t gameObjectUUID, XCEngine::Math::Vector3* outUp) {
|
|
if (!outUp) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outUp = XCEngine::Math::Vector3::Up();
|
|
return;
|
|
}
|
|
|
|
*outUp = gameObject->GetTransform()->GetUp();
|
|
}
|
|
|
|
void InternalCall_Transform_Translate(uint64_t gameObjectUUID, XCEngine::Math::Vector3* translation, int32_t relativeTo) {
|
|
if (!translation) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
return;
|
|
}
|
|
|
|
gameObject->GetTransform()->Translate(*translation, ResolveManagedSpace(relativeTo));
|
|
}
|
|
|
|
void InternalCall_Transform_Rotate(uint64_t gameObjectUUID, XCEngine::Math::Vector3* eulers, int32_t relativeTo) {
|
|
if (!eulers) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
return;
|
|
}
|
|
|
|
gameObject->GetTransform()->Rotate(*eulers, ResolveManagedSpace(relativeTo));
|
|
}
|
|
|
|
void InternalCall_Transform_RotateAxisAngle(
|
|
uint64_t gameObjectUUID,
|
|
XCEngine::Math::Vector3* axis,
|
|
float angle,
|
|
int32_t relativeTo) {
|
|
if (!axis) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
return;
|
|
}
|
|
|
|
gameObject->GetTransform()->Rotate(*axis, angle, ResolveManagedSpace(relativeTo));
|
|
}
|
|
|
|
void InternalCall_Transform_LookAt(uint64_t gameObjectUUID, XCEngine::Math::Vector3* target) {
|
|
if (!target) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
return;
|
|
}
|
|
|
|
gameObject->GetTransform()->LookAt(*target);
|
|
}
|
|
|
|
void InternalCall_Transform_LookAtWithUp(
|
|
uint64_t gameObjectUUID,
|
|
XCEngine::Math::Vector3* target,
|
|
XCEngine::Math::Vector3* up) {
|
|
if (!target || !up) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
return;
|
|
}
|
|
|
|
gameObject->GetTransform()->LookAt(*target, *up);
|
|
}
|
|
|
|
void InternalCall_Transform_TransformPoint(uint64_t gameObjectUUID, XCEngine::Math::Vector3* point, XCEngine::Math::Vector3* outPoint) {
|
|
if (!point || !outPoint) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outPoint = *point;
|
|
return;
|
|
}
|
|
|
|
*outPoint = gameObject->GetTransform()->TransformPoint(*point);
|
|
}
|
|
|
|
void InternalCall_Transform_InverseTransformPoint(uint64_t gameObjectUUID, XCEngine::Math::Vector3* point, XCEngine::Math::Vector3* outPoint) {
|
|
if (!point || !outPoint) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outPoint = *point;
|
|
return;
|
|
}
|
|
|
|
*outPoint = gameObject->GetTransform()->InverseTransformPoint(*point);
|
|
}
|
|
|
|
void InternalCall_Transform_TransformDirection(uint64_t gameObjectUUID, XCEngine::Math::Vector3* direction, XCEngine::Math::Vector3* outDirection) {
|
|
if (!direction || !outDirection) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outDirection = *direction;
|
|
return;
|
|
}
|
|
|
|
*outDirection = gameObject->GetTransform()->TransformDirection(*direction);
|
|
}
|
|
|
|
void InternalCall_Transform_InverseTransformDirection(uint64_t gameObjectUUID, XCEngine::Math::Vector3* direction, XCEngine::Math::Vector3* outDirection) {
|
|
if (!direction || !outDirection) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetTransform()) {
|
|
*outDirection = *direction;
|
|
return;
|
|
}
|
|
|
|
*outDirection = gameObject->GetTransform()->InverseTransformDirection(*direction);
|
|
}
|
|
|
|
uint64_t InternalCall_Transform_GetParent(uint64_t gameObjectUUID) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || !gameObject->GetParent()) {
|
|
return 0;
|
|
}
|
|
|
|
return gameObject->GetParent()->GetUUID();
|
|
}
|
|
|
|
void InternalCall_Transform_SetParent(uint64_t gameObjectUUID, uint64_t parentGameObjectUUID, mono_bool worldPositionStays) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject) {
|
|
return;
|
|
}
|
|
|
|
Components::GameObject* parent = parentGameObjectUUID != 0 ? FindGameObjectByUUID(parentGameObjectUUID) : nullptr;
|
|
gameObject->SetParent(parent, worldPositionStays != 0);
|
|
}
|
|
|
|
int32_t InternalCall_Transform_GetChildCount(uint64_t gameObjectUUID) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
return gameObject ? static_cast<int32_t>(gameObject->GetChildCount()) : 0;
|
|
}
|
|
|
|
uint64_t InternalCall_Transform_GetChild(uint64_t gameObjectUUID, int32_t index) {
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject || index < 0) {
|
|
return 0;
|
|
}
|
|
|
|
Components::GameObject* child = gameObject->GetChild(static_cast<size_t>(index));
|
|
return child ? child->GetUUID() : 0;
|
|
}
|
|
|
|
float InternalCall_Camera_GetFieldOfView(uint64_t gameObjectUUID) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
return component ? component->GetFieldOfView() : 0.0f;
|
|
}
|
|
|
|
void InternalCall_Camera_SetFieldOfView(uint64_t gameObjectUUID, float value) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetFieldOfView(value);
|
|
}
|
|
|
|
float InternalCall_Camera_GetNearClipPlane(uint64_t gameObjectUUID) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
return component ? component->GetNearClipPlane() : 0.0f;
|
|
}
|
|
|
|
void InternalCall_Camera_SetNearClipPlane(uint64_t gameObjectUUID, float value) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetNearClipPlane(value);
|
|
}
|
|
|
|
float InternalCall_Camera_GetFarClipPlane(uint64_t gameObjectUUID) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
return component ? component->GetFarClipPlane() : 0.0f;
|
|
}
|
|
|
|
void InternalCall_Camera_SetFarClipPlane(uint64_t gameObjectUUID, float value) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetFarClipPlane(value);
|
|
}
|
|
|
|
float InternalCall_Camera_GetDepth(uint64_t gameObjectUUID) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
return component ? component->GetDepth() : 0.0f;
|
|
}
|
|
|
|
void InternalCall_Camera_SetDepth(uint64_t gameObjectUUID, float value) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetDepth(value);
|
|
}
|
|
|
|
mono_bool InternalCall_Camera_GetPrimary(uint64_t gameObjectUUID) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
return (component && component->IsPrimary()) ? 1 : 0;
|
|
}
|
|
|
|
void InternalCall_Camera_SetPrimary(uint64_t gameObjectUUID, mono_bool value) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetPrimary(value != 0);
|
|
}
|
|
|
|
int32_t InternalCall_Camera_GetClearMode(uint64_t gameObjectUUID) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
return component != nullptr
|
|
? static_cast<int32_t>(component->GetClearMode())
|
|
: 0;
|
|
}
|
|
|
|
void InternalCall_Camera_SetClearMode(uint64_t gameObjectUUID, int32_t value) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetClearMode(
|
|
static_cast<Components::CameraClearMode>(value));
|
|
}
|
|
|
|
int32_t InternalCall_Camera_GetStackType(uint64_t gameObjectUUID) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
return component != nullptr
|
|
? static_cast<int32_t>(component->GetStackType())
|
|
: 0;
|
|
}
|
|
|
|
void InternalCall_Camera_SetStackType(uint64_t gameObjectUUID, int32_t value) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetStackType(
|
|
static_cast<Components::CameraStackType>(value));
|
|
}
|
|
|
|
int32_t InternalCall_Camera_GetProjectionType(uint64_t gameObjectUUID) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
return component != nullptr
|
|
? static_cast<int32_t>(component->GetProjectionType())
|
|
: 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Camera_GetSkyboxEnabled(uint64_t gameObjectUUID) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
return (component && component->IsSkyboxEnabled()) ? 1 : 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Camera_GetHasSkyboxMaterial(uint64_t gameObjectUUID) {
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
return (component && component->GetSkyboxMaterial() != nullptr) ? 1 : 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Camera_GetHasFinalColorOverrides(
|
|
uint64_t gameObjectUUID) {
|
|
Components::CameraComponent* component =
|
|
FindCameraComponent(gameObjectUUID);
|
|
return (component &&
|
|
component->GetFinalColorOverrides().HasOverrides())
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
void InternalCall_Camera_GetFinalColorOverrideSettings(
|
|
uint64_t gameObjectUUID,
|
|
ManagedFinalColorOverrideSettingsData* outSettings) {
|
|
if (outSettings == nullptr) {
|
|
return;
|
|
}
|
|
|
|
Components::CameraComponent* component =
|
|
FindCameraComponent(gameObjectUUID);
|
|
const Rendering::FinalColorOverrideSettings sourceSettings =
|
|
component != nullptr
|
|
? component->GetFinalColorOverrides()
|
|
: Rendering::FinalColorOverrideSettings{};
|
|
*outSettings =
|
|
BuildManagedFinalColorOverrideSettings(
|
|
sourceSettings);
|
|
}
|
|
|
|
void InternalCall_Camera_GetSkyboxTopColor(
|
|
uint64_t gameObjectUUID,
|
|
XCEngine::Math::Color* outColor) {
|
|
if (outColor == nullptr) {
|
|
return;
|
|
}
|
|
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
*outColor = component != nullptr
|
|
? component->GetSkyboxTopColor()
|
|
: XCEngine::Math::Color();
|
|
}
|
|
|
|
void InternalCall_Camera_GetSkyboxHorizonColor(
|
|
uint64_t gameObjectUUID,
|
|
XCEngine::Math::Color* outColor) {
|
|
if (outColor == nullptr) {
|
|
return;
|
|
}
|
|
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
*outColor = component != nullptr
|
|
? component->GetSkyboxHorizonColor()
|
|
: XCEngine::Math::Color();
|
|
}
|
|
|
|
void InternalCall_Camera_GetSkyboxBottomColor(
|
|
uint64_t gameObjectUUID,
|
|
XCEngine::Math::Color* outColor) {
|
|
if (outColor == nullptr) {
|
|
return;
|
|
}
|
|
|
|
Components::CameraComponent* component = FindCameraComponent(gameObjectUUID);
|
|
*outColor = component != nullptr
|
|
? component->GetSkyboxBottomColor()
|
|
: XCEngine::Math::Color();
|
|
}
|
|
|
|
float InternalCall_Light_GetIntensity(uint64_t gameObjectUUID) {
|
|
Components::LightComponent* component = FindLightComponent(gameObjectUUID);
|
|
return component ? component->GetIntensity() : 0.0f;
|
|
}
|
|
|
|
void InternalCall_Light_SetIntensity(uint64_t gameObjectUUID, float value) {
|
|
Components::LightComponent* component = FindLightComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetIntensity(value);
|
|
}
|
|
|
|
float InternalCall_Light_GetRange(uint64_t gameObjectUUID) {
|
|
Components::LightComponent* component = FindLightComponent(gameObjectUUID);
|
|
return component ? component->GetRange() : 0.0f;
|
|
}
|
|
|
|
void InternalCall_Light_SetRange(uint64_t gameObjectUUID, float value) {
|
|
Components::LightComponent* component = FindLightComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetRange(value);
|
|
}
|
|
|
|
float InternalCall_Light_GetSpotAngle(uint64_t gameObjectUUID) {
|
|
Components::LightComponent* component = FindLightComponent(gameObjectUUID);
|
|
return component ? component->GetSpotAngle() : 0.0f;
|
|
}
|
|
|
|
void InternalCall_Light_SetSpotAngle(uint64_t gameObjectUUID, float value) {
|
|
Components::LightComponent* component = FindLightComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetSpotAngle(value);
|
|
}
|
|
|
|
mono_bool InternalCall_Light_GetCastsShadows(uint64_t gameObjectUUID) {
|
|
Components::LightComponent* component = FindLightComponent(gameObjectUUID);
|
|
return (component && component->GetCastsShadows()) ? 1 : 0;
|
|
}
|
|
|
|
void InternalCall_Light_SetCastsShadows(uint64_t gameObjectUUID, mono_bool value) {
|
|
Components::LightComponent* component = FindLightComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetCastsShadows(value != 0);
|
|
}
|
|
|
|
MonoString* InternalCall_MeshFilter_GetMeshPath(uint64_t gameObjectUUID) {
|
|
Components::MeshFilterComponent* component = FindMeshFilterComponent(gameObjectUUID);
|
|
return mono_string_new(
|
|
mono_domain_get(),
|
|
component ? component->GetMeshPath().c_str() : "");
|
|
}
|
|
|
|
void InternalCall_MeshFilter_SetMeshPath(uint64_t gameObjectUUID, MonoString* path) {
|
|
Components::MeshFilterComponent* component = FindMeshFilterComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetMeshPath(MonoStringToUtf8(path));
|
|
}
|
|
|
|
int32_t InternalCall_MeshRenderer_GetMaterialCount(uint64_t gameObjectUUID) {
|
|
Components::MeshRendererComponent* component = FindMeshRendererComponent(gameObjectUUID);
|
|
return component ? static_cast<int32_t>(component->GetMaterialCount()) : 0;
|
|
}
|
|
|
|
MonoString* InternalCall_MeshRenderer_GetMaterialPath(uint64_t gameObjectUUID, int32_t index) {
|
|
Components::MeshRendererComponent* component = FindMeshRendererComponent(gameObjectUUID);
|
|
const std::string path =
|
|
(component && index >= 0) ? component->GetMaterialPath(static_cast<size_t>(index)) : std::string();
|
|
return mono_string_new(mono_domain_get(), path.c_str());
|
|
}
|
|
|
|
void InternalCall_MeshRenderer_SetMaterialPath(uint64_t gameObjectUUID, int32_t index, MonoString* path) {
|
|
Components::MeshRendererComponent* component = FindMeshRendererComponent(gameObjectUUID);
|
|
if (!component || index < 0) {
|
|
return;
|
|
}
|
|
|
|
component->SetMaterialPath(static_cast<size_t>(index), MonoStringToUtf8(path));
|
|
}
|
|
|
|
void InternalCall_MeshRenderer_ClearMaterials(uint64_t gameObjectUUID) {
|
|
Components::MeshRendererComponent* component = FindMeshRendererComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->ClearMaterials();
|
|
}
|
|
|
|
mono_bool InternalCall_MeshRenderer_GetCastShadows(uint64_t gameObjectUUID) {
|
|
Components::MeshRendererComponent* component = FindMeshRendererComponent(gameObjectUUID);
|
|
return (component && component->GetCastShadows()) ? 1 : 0;
|
|
}
|
|
|
|
void InternalCall_MeshRenderer_SetCastShadows(uint64_t gameObjectUUID, mono_bool value) {
|
|
Components::MeshRendererComponent* component = FindMeshRendererComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetCastShadows(value != 0);
|
|
}
|
|
|
|
mono_bool InternalCall_MeshRenderer_GetReceiveShadows(uint64_t gameObjectUUID) {
|
|
Components::MeshRendererComponent* component = FindMeshRendererComponent(gameObjectUUID);
|
|
return (component && component->GetReceiveShadows()) ? 1 : 0;
|
|
}
|
|
|
|
void InternalCall_MeshRenderer_SetReceiveShadows(uint64_t gameObjectUUID, mono_bool value) {
|
|
Components::MeshRendererComponent* component = FindMeshRendererComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetReceiveShadows(value != 0);
|
|
}
|
|
|
|
int32_t InternalCall_MeshRenderer_GetRenderLayer(uint64_t gameObjectUUID) {
|
|
Components::MeshRendererComponent* component = FindMeshRendererComponent(gameObjectUUID);
|
|
return component ? static_cast<int32_t>(component->GetRenderLayer()) : 0;
|
|
}
|
|
|
|
void InternalCall_MeshRenderer_SetRenderLayer(uint64_t gameObjectUUID, int32_t value) {
|
|
Components::MeshRendererComponent* component = FindMeshRendererComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetRenderLayer(static_cast<uint32_t>(std::max(value, 0)));
|
|
}
|
|
|
|
int32_t InternalCall_Rigidbody_GetBodyType(uint64_t gameObjectUUID) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
return component
|
|
? static_cast<int32_t>(component->GetBodyType())
|
|
: static_cast<int32_t>(Physics::PhysicsBodyType::Dynamic);
|
|
}
|
|
|
|
void InternalCall_Rigidbody_SetBodyType(uint64_t gameObjectUUID, int32_t value) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetBodyType(ResolveManagedPhysicsBodyType(value));
|
|
}
|
|
|
|
float InternalCall_Rigidbody_GetMass(uint64_t gameObjectUUID) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
return component ? component->GetMass() : 1.0f;
|
|
}
|
|
|
|
void InternalCall_Rigidbody_SetMass(uint64_t gameObjectUUID, float value) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetMass(value);
|
|
}
|
|
|
|
float InternalCall_Rigidbody_GetLinearDamping(uint64_t gameObjectUUID) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
return component ? component->GetLinearDamping() : 0.0f;
|
|
}
|
|
|
|
void InternalCall_Rigidbody_SetLinearDamping(uint64_t gameObjectUUID, float value) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetLinearDamping(value);
|
|
}
|
|
|
|
float InternalCall_Rigidbody_GetAngularDamping(uint64_t gameObjectUUID) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
return component ? component->GetAngularDamping() : 0.05f;
|
|
}
|
|
|
|
void InternalCall_Rigidbody_SetAngularDamping(uint64_t gameObjectUUID, float value) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetAngularDamping(value);
|
|
}
|
|
|
|
void InternalCall_Rigidbody_GetLinearVelocity(uint64_t gameObjectUUID, XCEngine::Math::Vector3* outVelocity) {
|
|
if (!outVelocity) {
|
|
return;
|
|
}
|
|
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
*outVelocity = component ? component->GetLinearVelocity() : XCEngine::Math::Vector3::Zero();
|
|
}
|
|
|
|
void InternalCall_Rigidbody_SetLinearVelocity(uint64_t gameObjectUUID, XCEngine::Math::Vector3* velocity) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
if (!component || !velocity) {
|
|
return;
|
|
}
|
|
|
|
component->SetLinearVelocity(*velocity);
|
|
}
|
|
|
|
void InternalCall_Rigidbody_GetAngularVelocity(uint64_t gameObjectUUID, XCEngine::Math::Vector3* outVelocity) {
|
|
if (!outVelocity) {
|
|
return;
|
|
}
|
|
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
*outVelocity = component ? component->GetAngularVelocity() : XCEngine::Math::Vector3::Zero();
|
|
}
|
|
|
|
void InternalCall_Rigidbody_SetAngularVelocity(uint64_t gameObjectUUID, XCEngine::Math::Vector3* velocity) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
if (!component || !velocity) {
|
|
return;
|
|
}
|
|
|
|
component->SetAngularVelocity(*velocity);
|
|
}
|
|
|
|
mono_bool InternalCall_Rigidbody_GetUseGravity(uint64_t gameObjectUUID) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
return (component && component->GetUseGravity()) ? 1 : 0;
|
|
}
|
|
|
|
void InternalCall_Rigidbody_SetUseGravity(uint64_t gameObjectUUID, mono_bool value) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetUseGravity(value != 0);
|
|
}
|
|
|
|
mono_bool InternalCall_Rigidbody_GetEnableCCD(uint64_t gameObjectUUID) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
return (component && component->GetEnableCCD()) ? 1 : 0;
|
|
}
|
|
|
|
void InternalCall_Rigidbody_SetEnableCCD(uint64_t gameObjectUUID, mono_bool value) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->SetEnableCCD(value != 0);
|
|
}
|
|
|
|
void InternalCall_Rigidbody_AddForce(uint64_t gameObjectUUID, XCEngine::Math::Vector3* force, int32_t forceMode) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
if (!component || !force) {
|
|
return;
|
|
}
|
|
|
|
component->AddForce(*force, ResolveManagedForceMode(forceMode));
|
|
}
|
|
|
|
void InternalCall_Rigidbody_ClearForces(uint64_t gameObjectUUID) {
|
|
Components::RigidbodyComponent* component = FindRigidbodyComponent(gameObjectUUID);
|
|
if (!component) {
|
|
return;
|
|
}
|
|
|
|
component->ClearForces();
|
|
}
|
|
|
|
mono_bool InternalCall_Physics_Raycast(
|
|
XCEngine::Math::Vector3* origin,
|
|
XCEngine::Math::Vector3* direction,
|
|
float maxDistance,
|
|
uint64_t* outHitGameObjectUUID,
|
|
XCEngine::Math::Vector3* outHitPoint,
|
|
XCEngine::Math::Vector3* outHitNormal,
|
|
float* outHitDistance,
|
|
int32_t* outHitIsTrigger) {
|
|
if (outHitGameObjectUUID) {
|
|
*outHitGameObjectUUID = 0;
|
|
}
|
|
if (outHitPoint) {
|
|
*outHitPoint = XCEngine::Math::Vector3::Zero();
|
|
}
|
|
if (outHitNormal) {
|
|
*outHitNormal = XCEngine::Math::Vector3::Zero();
|
|
}
|
|
if (outHitDistance) {
|
|
*outHitDistance = 0.0f;
|
|
}
|
|
if (outHitIsTrigger) {
|
|
*outHitIsTrigger = 0;
|
|
}
|
|
|
|
Physics::PhysicsWorld* physicsWorld = FindRuntimePhysicsWorld();
|
|
if (!physicsWorld || !origin || !direction) {
|
|
return 0;
|
|
}
|
|
|
|
Physics::RaycastHit hit;
|
|
if (!physicsWorld->Raycast(*origin, *direction, maxDistance, hit)) {
|
|
return 0;
|
|
}
|
|
|
|
if (outHitGameObjectUUID) {
|
|
*outHitGameObjectUUID = hit.gameObject ? hit.gameObject->GetUUID() : 0;
|
|
}
|
|
if (outHitPoint) {
|
|
*outHitPoint = hit.point;
|
|
}
|
|
if (outHitNormal) {
|
|
*outHitNormal = hit.normal;
|
|
}
|
|
if (outHitDistance) {
|
|
*outHitDistance = hit.distance;
|
|
}
|
|
if (outHitIsTrigger) {
|
|
*outHitIsTrigger = hit.isTrigger ? 1 : 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void InternalCall_Rendering_SetRenderPipelineAsset(MonoObject* assetObject) {
|
|
MonoScriptRuntime* const runtime = GetActiveMonoScriptRuntime();
|
|
const Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor currentDescriptor =
|
|
Rendering::GetGraphicsSettingsState()
|
|
.GetConfiguredRenderPipelineAssetDescriptor();
|
|
|
|
if (assetObject == nullptr) {
|
|
ClearManagedRenderPipelineSelection(runtime);
|
|
return;
|
|
}
|
|
|
|
MonoClass* const monoClass = mono_object_get_class(assetObject);
|
|
if (monoClass == nullptr) {
|
|
return;
|
|
}
|
|
|
|
if (runtime != nullptr &&
|
|
!runtime->IsScriptableRenderPipelineAssetObject(assetObject)) {
|
|
return;
|
|
}
|
|
|
|
MonoImage* image = mono_class_get_image(monoClass);
|
|
Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = {};
|
|
descriptor.assemblyName =
|
|
TrimAssemblyName(SafeString(image != nullptr ? mono_image_get_name(image) : nullptr));
|
|
descriptor.namespaceName = SafeString(mono_class_get_namespace(monoClass));
|
|
descriptor.className = SafeString(mono_class_get_name(monoClass));
|
|
descriptor.managedAssetHandle =
|
|
runtime != nullptr
|
|
? runtime->RetainExternalManagedObjectReference(assetObject)
|
|
: 0u;
|
|
if (!descriptor.IsValid() ||
|
|
descriptor.managedAssetHandle == 0u) {
|
|
if (runtime != nullptr &&
|
|
descriptor.managedAssetHandle != 0u) {
|
|
runtime->ReleaseExternalManagedObject(
|
|
descriptor.managedAssetHandle);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (runtime != nullptr &&
|
|
currentDescriptor.managedAssetHandle != 0u &&
|
|
currentDescriptor.managedAssetHandle != descriptor.managedAssetHandle) {
|
|
runtime->ReleaseExternalManagedObject(
|
|
currentDescriptor.managedAssetHandle);
|
|
}
|
|
|
|
Rendering::GetGraphicsSettingsState()
|
|
.SetConfiguredRenderPipelineAssetDescriptor(descriptor);
|
|
}
|
|
|
|
MonoObject* InternalCall_Rendering_GetRenderPipelineAsset() {
|
|
MonoScriptRuntime* const runtime = GetActiveMonoScriptRuntime();
|
|
if (runtime == nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor descriptor =
|
|
Rendering::GetGraphicsSettingsState()
|
|
.GetConfiguredRenderPipelineAssetDescriptor();
|
|
if (!descriptor.IsValid()) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (descriptor.managedAssetHandle == 0u) {
|
|
if (!runtime->TryEnsureManagedRenderPipelineAssetHandle(descriptor)) {
|
|
return nullptr;
|
|
}
|
|
|
|
Rendering::GetGraphicsSettingsState()
|
|
.SetConfiguredRenderPipelineAssetDescriptor(descriptor);
|
|
}
|
|
|
|
return runtime->GetExternalManagedObject(
|
|
descriptor.managedAssetHandle);
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetStage(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return state != nullptr
|
|
? static_cast<int32_t>(state->stage)
|
|
: static_cast<int32_t>(Rendering::CameraFrameStage::MainScene);
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetRendererIndex(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->graphContext != nullptr
|
|
? state->graphContext->rendererIndex
|
|
: -1;
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetSourceColorTextureHandle(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return EncodeManagedRenderGraphTextureHandle(
|
|
ResolveManagedScriptableRenderContextSourceColorTexture(
|
|
state));
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetPrimaryColorTargetHandle(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return EncodeManagedRenderGraphTextureHandle(
|
|
ResolveManagedScriptableRenderContextPrimaryColorTarget(
|
|
state));
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetDepthTargetHandle(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return EncodeManagedRenderGraphTextureHandle(
|
|
ResolveManagedScriptableRenderContextDepthTarget(
|
|
state));
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_CreateTransientTexture(
|
|
uint64_t nativeHandle,
|
|
MonoString* name,
|
|
ManagedRenderGraphTextureDescData* descData) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->graphContext == nullptr ||
|
|
descData == nullptr) {
|
|
return -1;
|
|
}
|
|
|
|
const auto* const desc =
|
|
reinterpret_cast<const Rendering::RenderGraphTextureDesc*>(
|
|
descData);
|
|
if (!desc->IsValid()) {
|
|
return -1;
|
|
}
|
|
|
|
const Rendering::RenderGraphTextureHandle handle =
|
|
state->graphContext->graphBuilder.CreateTransientTexture(
|
|
Containers::String(MonoStringToUtf8(name).c_str()),
|
|
*desc);
|
|
return EncodeManagedRenderGraphTextureHandle(handle);
|
|
}
|
|
|
|
int32_t
|
|
InternalCall_Rendering_ScriptableRenderContext_CreateFullscreenTransientColorTexture(
|
|
uint64_t nativeHandle,
|
|
MonoString* name) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->graphContext == nullptr) {
|
|
return -1;
|
|
}
|
|
|
|
const Rendering::RenderGraphTextureHandle handle =
|
|
state->graphContext->graphBuilder.CreateTransientTexture(
|
|
Containers::String(MonoStringToUtf8(name).c_str()),
|
|
Rendering::BuildFullscreenTransientTextureDesc(
|
|
state->graphContext->surfaceTemplate));
|
|
return EncodeManagedRenderGraphTextureHandle(handle);
|
|
}
|
|
|
|
int32_t
|
|
InternalCall_Rendering_ScriptableRenderContext_CreateFullscreenTransientDepthTexture(
|
|
uint64_t nativeHandle,
|
|
MonoString* name) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->graphContext == nullptr) {
|
|
return -1;
|
|
}
|
|
|
|
const Rendering::RenderGraphTextureHandle handle =
|
|
state->graphContext->graphBuilder.CreateTransientTexture(
|
|
Containers::String(MonoStringToUtf8(name).c_str()),
|
|
BuildManagedFullscreenTransientDepthTextureDesc(
|
|
state->graphContext->surfaceTemplate));
|
|
return EncodeManagedRenderGraphTextureHandle(handle);
|
|
}
|
|
|
|
uint64_t InternalCall_Rendering_ScriptableRenderContext_BeginRasterPass(
|
|
uint64_t nativeHandle,
|
|
MonoString* passName) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->graphContext == nullptr ||
|
|
!Rendering::IsCameraFrameFullscreenSequenceStage(state->stage)) {
|
|
return 0u;
|
|
}
|
|
|
|
const Containers::String passNameString(
|
|
MonoStringToUtf8(passName).c_str());
|
|
if (passNameString.Empty()) {
|
|
return 0u;
|
|
}
|
|
|
|
uint64_t rasterPassHandle =
|
|
state->nextPendingRasterPassHandle++;
|
|
if (rasterPassHandle == 0u) {
|
|
rasterPassHandle =
|
|
state->nextPendingRasterPassHandle++;
|
|
}
|
|
|
|
ManagedScriptableRenderContextState::RasterPassRecordRequest
|
|
request = {};
|
|
request.passName = passNameString;
|
|
state->pendingRasterPassRequests[rasterPassHandle] =
|
|
std::move(request);
|
|
return rasterPassHandle;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_SetRasterPassSourceColorTexture(
|
|
uint64_t nativeHandle,
|
|
uint64_t rasterPassHandle,
|
|
int32_t sourceTextureHandle) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
ManagedScriptableRenderContextState::RasterPassRecordRequest*
|
|
const request =
|
|
FindPendingManagedRasterPassRecordRequest(
|
|
state,
|
|
rasterPassHandle);
|
|
if (request == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
const Rendering::RenderGraphTextureHandle sourceColorTexture =
|
|
DecodeManagedRenderGraphTextureHandle(
|
|
sourceTextureHandle);
|
|
if (!sourceColorTexture.IsValid()) {
|
|
return 0;
|
|
}
|
|
|
|
request->sourceColorTexture = sourceColorTexture;
|
|
return 1;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_AddRasterPassReadTexture(
|
|
uint64_t nativeHandle,
|
|
uint64_t rasterPassHandle,
|
|
int32_t textureHandle) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
ManagedScriptableRenderContextState::RasterPassRecordRequest*
|
|
const request =
|
|
FindPendingManagedRasterPassRecordRequest(
|
|
state,
|
|
rasterPassHandle);
|
|
if (request == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
const Rendering::RenderGraphTextureHandle readTexture =
|
|
DecodeManagedRenderGraphTextureHandle(
|
|
textureHandle);
|
|
if (!readTexture.IsValid()) {
|
|
return 0;
|
|
}
|
|
|
|
request->readTextures.push_back(readTexture);
|
|
return 1;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_AddRasterPassReadDepthTexture(
|
|
uint64_t nativeHandle,
|
|
uint64_t rasterPassHandle,
|
|
int32_t textureHandle) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
ManagedScriptableRenderContextState::RasterPassRecordRequest*
|
|
const request =
|
|
FindPendingManagedRasterPassRecordRequest(
|
|
state,
|
|
rasterPassHandle);
|
|
if (request == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
const Rendering::RenderGraphTextureHandle readDepthTexture =
|
|
DecodeManagedRenderGraphTextureHandle(
|
|
textureHandle);
|
|
if (!readDepthTexture.IsValid()) {
|
|
return 0;
|
|
}
|
|
|
|
request->readDepthTextures.push_back(readDepthTexture);
|
|
return 1;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_AddRasterPassTextureBinding(
|
|
uint64_t nativeHandle,
|
|
uint64_t rasterPassHandle,
|
|
MonoString* shaderResourceName,
|
|
int32_t textureHandle,
|
|
mono_bool isDepth) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
ManagedScriptableRenderContextState::RasterPassRecordRequest*
|
|
const request =
|
|
FindPendingManagedRasterPassRecordRequest(
|
|
state,
|
|
rasterPassHandle);
|
|
if (request == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
const Containers::String shaderResourceNameString(
|
|
MonoStringToUtf8(shaderResourceName).c_str());
|
|
if (shaderResourceNameString.Empty()) {
|
|
return 0;
|
|
}
|
|
|
|
const Rendering::RenderGraphTextureHandle texture =
|
|
DecodeManagedRenderGraphTextureHandle(
|
|
textureHandle);
|
|
if (!texture.IsValid()) {
|
|
return 0;
|
|
}
|
|
|
|
Rendering::RenderPassGraphTextureBindingRequest
|
|
bindingRequest = {};
|
|
bindingRequest.resourceName =
|
|
shaderResourceNameString;
|
|
bindingRequest.texture = texture;
|
|
bindingRequest.aspect =
|
|
isDepth != 0
|
|
? Rendering::RenderGraphTextureAspect::Depth
|
|
: Rendering::RenderGraphTextureAspect::Color;
|
|
|
|
auto existingBinding =
|
|
std::find_if(
|
|
request->textureBindings.begin(),
|
|
request->textureBindings.end(),
|
|
[&shaderResourceNameString](
|
|
const Rendering::RenderPassGraphTextureBindingRequest&
|
|
existingRequest) {
|
|
return existingRequest.resourceName ==
|
|
shaderResourceNameString;
|
|
});
|
|
if (existingBinding != request->textureBindings.end()) {
|
|
*existingBinding = std::move(bindingRequest);
|
|
} else {
|
|
request->textureBindings.push_back(
|
|
std::move(bindingRequest));
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_SetRasterPassColorAttachment(
|
|
uint64_t nativeHandle,
|
|
uint64_t rasterPassHandle,
|
|
int32_t colorAttachmentIndex,
|
|
int32_t textureHandle) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
ManagedScriptableRenderContextState::RasterPassRecordRequest*
|
|
const request =
|
|
FindPendingManagedRasterPassRecordRequest(
|
|
state,
|
|
rasterPassHandle);
|
|
if (request == nullptr ||
|
|
colorAttachmentIndex < 0) {
|
|
return 0;
|
|
}
|
|
|
|
const Rendering::RenderGraphTextureHandle colorAttachment =
|
|
DecodeManagedRenderGraphTextureHandle(
|
|
textureHandle);
|
|
if (!colorAttachment.IsValid()) {
|
|
return 0;
|
|
}
|
|
|
|
if (request->colorTargets.size() <=
|
|
static_cast<size_t>(colorAttachmentIndex)) {
|
|
request->colorTargets.resize(
|
|
static_cast<size_t>(colorAttachmentIndex) + 1u);
|
|
}
|
|
|
|
request->colorTargets[static_cast<size_t>(colorAttachmentIndex)] =
|
|
colorAttachment;
|
|
return 1;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_SetRasterPassDepthAttachment(
|
|
uint64_t nativeHandle,
|
|
uint64_t rasterPassHandle,
|
|
int32_t textureHandle) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
ManagedScriptableRenderContextState::RasterPassRecordRequest*
|
|
const request =
|
|
FindPendingManagedRasterPassRecordRequest(
|
|
state,
|
|
rasterPassHandle);
|
|
if (request == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
const Rendering::RenderGraphTextureHandle depthAttachment =
|
|
DecodeManagedRenderGraphTextureHandle(
|
|
textureHandle);
|
|
if (!depthAttachment.IsValid()) {
|
|
return 0;
|
|
}
|
|
|
|
request->depthTarget = depthAttachment;
|
|
return 1;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_SetRasterPassColorScaleFullscreenExecution(
|
|
uint64_t nativeHandle,
|
|
uint64_t rasterPassHandle,
|
|
XCEngine::Math::Vector4* vectorPayload) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
ManagedScriptableRenderContextState::RasterPassRecordRequest*
|
|
const request =
|
|
FindPendingManagedRasterPassRecordRequest(
|
|
state,
|
|
rasterPassHandle);
|
|
if (request == nullptr ||
|
|
vectorPayload == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
request->passDesc =
|
|
Rendering::FullscreenPassDesc::MakeColorScale(
|
|
*vectorPayload);
|
|
return 1;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_SetRasterPassShaderVectorFullscreenExecution(
|
|
uint64_t nativeHandle,
|
|
uint64_t rasterPassHandle,
|
|
MonoString* shaderPath,
|
|
MonoString* shaderPassName,
|
|
XCEngine::Math::Vector4* vectorPayload) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
ManagedScriptableRenderContextState::RasterPassRecordRequest*
|
|
const request =
|
|
FindPendingManagedRasterPassRecordRequest(
|
|
state,
|
|
rasterPassHandle);
|
|
if (request == nullptr ||
|
|
vectorPayload == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
const Containers::String shaderPathString(
|
|
MonoStringToUtf8(shaderPath).c_str());
|
|
if (shaderPathString.Empty()) {
|
|
return 0;
|
|
}
|
|
|
|
request->passDesc =
|
|
Rendering::FullscreenPassDesc::MakeShaderVector(
|
|
shaderPathString,
|
|
*vectorPayload,
|
|
Containers::String(MonoStringToUtf8(shaderPassName).c_str()));
|
|
return request->passDesc.IsValid()
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_SetRasterPassFinalColorFullscreenExecution(
|
|
uint64_t nativeHandle,
|
|
uint64_t rasterPassHandle,
|
|
ManagedFinalColorSettingsData* settingsData) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
ManagedScriptableRenderContextState::RasterPassRecordRequest*
|
|
const request =
|
|
FindPendingManagedRasterPassRecordRequest(
|
|
state,
|
|
rasterPassHandle);
|
|
if (request == nullptr ||
|
|
settingsData == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
request->passDesc =
|
|
Rendering::FullscreenPassDesc::MakeFinalColor(
|
|
BuildManagedFinalColorSettings(
|
|
*settingsData));
|
|
return request->passDesc.IsValid()
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool InternalCall_Rendering_ScriptableRenderContext_CommitRasterPass(
|
|
uint64_t nativeHandle,
|
|
uint64_t rasterPassHandle) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->graphContext == nullptr ||
|
|
!Rendering::IsCameraFrameFullscreenSequenceStage(state->stage)) {
|
|
return 0;
|
|
}
|
|
|
|
auto it =
|
|
state->pendingRasterPassRequests.find(
|
|
rasterPassHandle);
|
|
if (it == state->pendingRasterPassRequests.end()) {
|
|
return 0;
|
|
}
|
|
|
|
ManagedScriptableRenderContextState::RasterPassRecordRequest
|
|
request = std::move(it->second);
|
|
state->pendingRasterPassRequests.erase(it);
|
|
if (!request.passDesc.IsValid() ||
|
|
!ResolveManagedPrimaryColorTarget(request.colorTargets)
|
|
.IsValid()) {
|
|
return 0;
|
|
}
|
|
|
|
state->rasterPassRequests.push_back(std::move(request));
|
|
return 1;
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetStageColorSource(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return static_cast<int32_t>(
|
|
ResolveManagedScriptableRenderContextStageColorSource(state));
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_GetStageUsesGraphManagedOutputColor(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextUsesGraphManagedOutputColor(
|
|
state)
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowEnabled(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.enabled
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowViewProjection(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Matrix4x4* outViewProjection) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outViewProjection =
|
|
ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.cameraData.viewProjection;
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowOrthographicHalfExtent(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.orthographicHalfExtent;
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowNearClipPlane(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.nearClipPlane;
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowFarClipPlane(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.farClipPlane;
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowMapWidth(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return static_cast<int32_t>(
|
|
ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.mapWidth);
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowMapHeight(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return static_cast<int32_t>(
|
|
ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.mapHeight);
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowWorldTexelSize(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.texelWorldSize;
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowReceiverDepthBias(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.sampling.receiverDepthBias;
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowNormalBiasScale(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.sampling.normalBiasScale;
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowStrength(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.sampling.shadowStrength;
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowDepthBiasFactor(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.casterBias.depthBiasFactor;
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowDepthBiasUnits(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextDirectionalShadowPlan(state)
|
|
.casterBias.depthBiasUnits;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetCameraView(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Matrix4x4* outView) {
|
|
if (outView == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outView =
|
|
ResolveManagedScriptableRenderContextCameraData(state).view;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetCameraProjection(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Matrix4x4* outProjection) {
|
|
if (outProjection == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outProjection =
|
|
ResolveManagedScriptableRenderContextCameraData(state).projection;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetCameraViewProjection(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Matrix4x4* outViewProjection) {
|
|
if (outViewProjection == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outViewProjection =
|
|
ResolveManagedScriptableRenderContextCameraData(state).viewProjection;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetCameraWorldPosition(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Vector3* outWorldPosition) {
|
|
if (outWorldPosition == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outWorldPosition =
|
|
ResolveManagedScriptableRenderContextCameraData(state).worldPosition;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetCameraWorldRight(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Vector3* outWorldRight) {
|
|
if (outWorldRight == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outWorldRight =
|
|
ResolveManagedScriptableRenderContextCameraData(state).worldRight;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetCameraWorldUp(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Vector3* outWorldUp) {
|
|
if (outWorldUp == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outWorldUp =
|
|
ResolveManagedScriptableRenderContextCameraData(state).worldUp;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetCameraWorldForward(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Vector3* outWorldForward) {
|
|
if (outWorldForward == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outWorldForward =
|
|
ResolveManagedScriptableRenderContextCameraData(state).worldForward;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetCameraClearColor(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Color* outClearColor) {
|
|
if (outClearColor == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outClearColor =
|
|
ResolveManagedScriptableRenderContextCameraData(state).clearColor;
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetCameraClearFlags(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return static_cast<int32_t>(
|
|
ResolveManagedScriptableRenderContextCameraData(state).clearFlags);
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_GetCameraPerspectiveProjection(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextCameraData(state)
|
|
.perspectiveProjection
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetCameraVerticalFovRadians(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextCameraData(state)
|
|
.verticalFovRadians;
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetCameraOrthographicSize(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextCameraData(state)
|
|
.orthographicSize;
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetCameraAspectRatio(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextCameraData(state)
|
|
.aspectRatio;
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetCameraNearClipPlane(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextCameraData(state)
|
|
.nearClipPlane;
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetCameraFarClipPlane(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextCameraData(state)
|
|
.farClipPlane;
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetCameraViewportWidth(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return static_cast<int32_t>(
|
|
ResolveManagedScriptableRenderContextCameraData(state).viewportWidth);
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetCameraViewportHeight(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return static_cast<int32_t>(
|
|
ResolveManagedScriptableRenderContextCameraData(state).viewportHeight);
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalLightEnabled(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextLightingData(state)
|
|
.mainDirectionalLight.enabled
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalLightCastsShadows(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextLightingData(state)
|
|
.mainDirectionalLight.castsShadows
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalLightDirection(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Vector3* outDirection) {
|
|
if (outDirection == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outDirection = ResolveManagedScriptableRenderContextLightingData(state)
|
|
.mainDirectionalLight.direction;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalLightColor(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Color* outColor) {
|
|
if (outColor == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outColor = ResolveManagedScriptableRenderContextLightingData(state)
|
|
.mainDirectionalLight.color;
|
|
}
|
|
|
|
float
|
|
InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalLightIntensity(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextLightingData(state)
|
|
.mainDirectionalLight.intensity;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_GetHasMainDirectionalShadow(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextLightingData(state)
|
|
.HasMainDirectionalShadow()
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetAdditionalLightCount(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return static_cast<int32_t>(
|
|
ResolveManagedScriptableRenderContextLightingData(state)
|
|
.additionalLightCount);
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_ScriptableRenderContext_GetEnvironmentMode(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return static_cast<int32_t>(
|
|
ResolveManagedScriptableRenderContextEnvironmentData(state).mode);
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetEnvironmentSkyboxTopColor(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Color* outColor) {
|
|
if (outColor == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outColor = ResolveManagedScriptableRenderContextEnvironmentData(state)
|
|
.skybox.topColor;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetEnvironmentSkyboxHorizonColor(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Color* outColor) {
|
|
if (outColor == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outColor = ResolveManagedScriptableRenderContextEnvironmentData(state)
|
|
.skybox.horizonColor;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetEnvironmentSkyboxBottomColor(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Color* outColor) {
|
|
if (outColor == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outColor = ResolveManagedScriptableRenderContextEnvironmentData(state)
|
|
.skybox.bottomColor;
|
|
}
|
|
|
|
int32_t
|
|
InternalCall_Rendering_ScriptableRenderContext_GetFinalColorOutputTransferMode(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return static_cast<int32_t>(
|
|
ResolveManagedScriptableRenderContextFinalColorPolicy(state)
|
|
.outputTransferMode);
|
|
}
|
|
|
|
int32_t
|
|
InternalCall_Rendering_ScriptableRenderContext_GetFinalColorExposureMode(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return static_cast<int32_t>(
|
|
ResolveManagedScriptableRenderContextFinalColorPolicy(state)
|
|
.exposureMode);
|
|
}
|
|
|
|
float InternalCall_Rendering_ScriptableRenderContext_GetFinalColorExposureValue(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextFinalColorPolicy(state)
|
|
.exposureValue;
|
|
}
|
|
|
|
int32_t
|
|
InternalCall_Rendering_ScriptableRenderContext_GetFinalColorToneMappingMode(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return static_cast<int32_t>(
|
|
ResolveManagedScriptableRenderContextFinalColorPolicy(state)
|
|
.toneMappingMode);
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderContext_GetFinalColorScale(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Vector4* outScale) {
|
|
if (outScale == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
*outScale = ResolveManagedScriptableRenderContextFinalColorPolicy(state)
|
|
.finalColorScale;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_GetFinalColorHasPipelineDefaults(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextFinalColorPolicy(state)
|
|
.hasPipelineDefaults
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_GetFinalColorHasCameraOverrides(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
return ResolveManagedScriptableRenderContextFinalColorPolicy(state)
|
|
.hasCameraOverrides
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_RecordScenePhase(
|
|
uint64_t nativeHandle,
|
|
int32_t scenePhase) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->graphContext == nullptr ||
|
|
state->sceneRecorder == nullptr ||
|
|
!SupportsManagedScriptableRenderContextSceneRecordingStage(
|
|
state->stage)) {
|
|
return 0;
|
|
}
|
|
|
|
return state->sceneRecorder->RecordScenePhase(
|
|
static_cast<Rendering::ScenePhase>(scenePhase))
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_RecordSceneInjectionPoint(
|
|
uint64_t nativeHandle,
|
|
int32_t injectionPoint) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->graphContext == nullptr ||
|
|
state->sceneRecorder == nullptr ||
|
|
state->stage != Rendering::CameraFrameStage::MainScene) {
|
|
return 0;
|
|
}
|
|
|
|
return state->sceneRecorder->RecordInjectionPoint(
|
|
static_cast<Rendering::SceneRenderInjectionPoint>(injectionPoint))
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_RecordNativeSceneFeaturePass(
|
|
uint64_t nativeHandle,
|
|
int32_t featurePassId) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->graphContext == nullptr ||
|
|
state->sceneRecorder == nullptr ||
|
|
state->stage != Rendering::CameraFrameStage::MainScene) {
|
|
return 0;
|
|
}
|
|
|
|
const Rendering::NativeSceneFeaturePassId
|
|
resolvedFeaturePassId =
|
|
static_cast<Rendering::NativeSceneFeaturePassId>(
|
|
featurePassId);
|
|
if (resolvedFeaturePassId ==
|
|
Rendering::NativeSceneFeaturePassId::Invalid) {
|
|
return 0;
|
|
}
|
|
|
|
return state->sceneRecorder->RecordFeaturePass(
|
|
resolvedFeaturePassId)
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderContext_DrawRenderersByDesc(
|
|
uint64_t nativeHandle,
|
|
int32_t scenePhase,
|
|
ManagedRendererListDescData* rendererListDescData,
|
|
MonoString* overrideMaterialPath,
|
|
MonoString* shaderPassName,
|
|
ManagedRenderStateBlockData* renderStateBlockData) {
|
|
ManagedScriptableRenderContextState* const state =
|
|
FindManagedScriptableRenderContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->graphContext == nullptr ||
|
|
state->sceneRecorder == nullptr ||
|
|
!SupportsManagedScriptableRenderContextSceneRecordingStage(
|
|
state->stage) ||
|
|
rendererListDescData == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
Rendering::DrawSettings drawSettings = {};
|
|
drawSettings.scenePhase =
|
|
static_cast<Rendering::ScenePhase>(scenePhase);
|
|
if (!TryBuildManagedRendererListDesc(
|
|
*rendererListDescData,
|
|
drawSettings.rendererListDesc)) {
|
|
Debug::Logger::Get().Error(
|
|
Debug::LogCategory::Rendering,
|
|
"ScriptableRenderContext DrawRenderers received an unsupported renderer-list type");
|
|
return 0;
|
|
}
|
|
const std::string overrideMaterialPathUtf8 =
|
|
MonoStringToUtf8(overrideMaterialPath);
|
|
if (!overrideMaterialPathUtf8.empty()) {
|
|
drawSettings.overrideMaterial =
|
|
Resources::ResourceManager::Get().Load<Resources::Material>(
|
|
overrideMaterialPathUtf8.c_str());
|
|
if (!drawSettings.overrideMaterial.IsValid()) {
|
|
Debug::Logger::Get().Error(
|
|
Debug::LogCategory::Rendering,
|
|
(Containers::String(
|
|
"ScriptableRenderContext DrawRenderers failed to load override material: ") +
|
|
Containers::String(overrideMaterialPathUtf8.c_str()))
|
|
.CStr());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
const std::string shaderPassNameUtf8 =
|
|
MonoStringToUtf8(shaderPassName);
|
|
if (!shaderPassNameUtf8.empty()) {
|
|
drawSettings.shaderPassName =
|
|
Containers::String(shaderPassNameUtf8.c_str());
|
|
}
|
|
if (renderStateBlockData != nullptr) {
|
|
drawSettings.renderStateBlock =
|
|
BuildManagedRenderStateBlock(
|
|
*renderStateBlockData);
|
|
}
|
|
|
|
return state->sceneRecorder->RecordSceneDrawSettings(
|
|
drawSettings)
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
int32_t
|
|
InternalCall_Rendering_CameraRenderRequestContext_GetRenderedBaseCameraCount(
|
|
uint64_t nativeHandle) {
|
|
const ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
return state != nullptr
|
|
? static_cast<int32_t>(state->renderedBaseCameraCount)
|
|
: 0;
|
|
}
|
|
|
|
int32_t
|
|
InternalCall_Rendering_CameraRenderRequestContext_GetRenderedRequestCount(
|
|
uint64_t nativeHandle) {
|
|
const ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
return state != nullptr
|
|
? static_cast<int32_t>(state->renderedRequestCount)
|
|
: 0;
|
|
}
|
|
|
|
uint64_t
|
|
InternalCall_Rendering_CameraRenderRequestContext_GetCameraGameObjectUUID(
|
|
uint64_t nativeHandle) {
|
|
const ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->request == nullptr ||
|
|
state->request->camera == nullptr ||
|
|
state->request->camera->GetGameObject() == nullptr) {
|
|
return 0u;
|
|
}
|
|
|
|
return state->request->camera->GetGameObject()->GetUUID();
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_CameraRenderRequestContext_GetRendererIndex(
|
|
uint64_t nativeHandle) {
|
|
const ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->request != nullptr
|
|
? state->request->rendererIndex
|
|
: -1;
|
|
}
|
|
|
|
void InternalCall_Rendering_CameraRenderRequestContext_SetRendererIndex(
|
|
uint64_t nativeHandle,
|
|
int32_t rendererIndex) {
|
|
ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
if (state == nullptr || state->request == nullptr) {
|
|
return;
|
|
}
|
|
|
|
state->request->rendererIndex = rendererIndex;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_CameraRenderRequestContext_GetHasDirectionalShadow(
|
|
uint64_t nativeHandle) {
|
|
const ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->request != nullptr &&
|
|
state->request->directionalShadow.IsValid()
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
void
|
|
InternalCall_Rendering_CameraRenderRequestContext_GetDirectionalShadowPlanningSettings(
|
|
uint64_t nativeHandle,
|
|
ManagedDirectionalShadowPlanningSettingsData* outSettings) {
|
|
const ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
if (outSettings == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const Rendering::DirectionalShadowPlanningSettings sourceSettings =
|
|
state != nullptr
|
|
? state->directionalShadowPlanningSettings
|
|
: Rendering::DirectionalShadowPlanningSettings();
|
|
*outSettings =
|
|
*reinterpret_cast<const ManagedDirectionalShadowPlanningSettingsData*>(
|
|
&sourceSettings);
|
|
}
|
|
|
|
void
|
|
InternalCall_Rendering_CameraRenderRequestContext_SetDirectionalShadowPlanningSettings(
|
|
uint64_t nativeHandle,
|
|
ManagedDirectionalShadowPlanningSettingsData* settings) {
|
|
ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
settings == nullptr) {
|
|
return;
|
|
}
|
|
|
|
state->directionalShadowPlanningSettings =
|
|
*reinterpret_cast<const Rendering::DirectionalShadowPlanningSettings*>(
|
|
settings);
|
|
}
|
|
|
|
void InternalCall_Rendering_CameraRenderRequestContext_ClearDirectionalShadow(
|
|
uint64_t nativeHandle) {
|
|
ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
if (state == nullptr || state->request == nullptr) {
|
|
return;
|
|
}
|
|
|
|
state->request->directionalShadow = {};
|
|
state->suppressDirectionalShadow = true;
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_CameraRenderRequestContext_GetClearFlags(
|
|
uint64_t nativeHandle) {
|
|
const ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->request != nullptr
|
|
? static_cast<int32_t>(state->request->clearFlags)
|
|
: static_cast<int32_t>(Rendering::RenderClearFlags::All);
|
|
}
|
|
|
|
void InternalCall_Rendering_CameraRenderRequestContext_SetClearFlags(
|
|
uint64_t nativeHandle,
|
|
int32_t clearFlags) {
|
|
ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
if (state == nullptr || state->request == nullptr) {
|
|
return;
|
|
}
|
|
|
|
state->request->clearFlags =
|
|
static_cast<Rendering::RenderClearFlags>(clearFlags);
|
|
}
|
|
|
|
void InternalCall_Rendering_CameraRenderRequestContext_SetResolvedFinalColorPolicy(
|
|
uint64_t nativeHandle,
|
|
ManagedFinalColorSettingsData* settings,
|
|
mono_bool hasPipelineDefaults,
|
|
mono_bool hasCameraOverrides) {
|
|
ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->request == nullptr ||
|
|
settings == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const Rendering::FinalColorSettings resolvedSettings =
|
|
BuildManagedFinalColorSettings(*settings);
|
|
Rendering::ResolvedFinalColorPolicy resolvedPolicy = {};
|
|
resolvedPolicy.outputTransferMode =
|
|
resolvedSettings.outputTransferMode;
|
|
resolvedPolicy.exposureMode =
|
|
resolvedSettings.exposureMode;
|
|
resolvedPolicy.exposureValue =
|
|
resolvedSettings.exposureValue;
|
|
resolvedPolicy.toneMappingMode =
|
|
resolvedSettings.toneMappingMode;
|
|
resolvedPolicy.finalColorScale =
|
|
resolvedSettings.finalColorScale;
|
|
resolvedPolicy.hasPipelineDefaults =
|
|
hasPipelineDefaults != 0;
|
|
resolvedPolicy.hasCameraOverrides =
|
|
hasCameraOverrides != 0;
|
|
state->request->finalColorPolicy =
|
|
resolvedPolicy;
|
|
}
|
|
|
|
void InternalCall_Rendering_CameraRenderRequestContext_ClearFinalColorPolicy(
|
|
uint64_t nativeHandle) {
|
|
ManagedCameraRenderRequestContextState* const state =
|
|
FindManagedCameraRenderRequestContextState(nativeHandle);
|
|
if (state == nullptr || state->request == nullptr) {
|
|
return;
|
|
}
|
|
|
|
state->request->finalColorPolicy = {};
|
|
}
|
|
|
|
int32_t
|
|
InternalCall_Rendering_RenderSceneSetupContext_GetRendererIndex(
|
|
uint64_t nativeHandle) {
|
|
const ManagedRenderSceneSetupContextState* const state =
|
|
FindManagedRenderSceneSetupContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->plan != nullptr
|
|
? state->plan->request.rendererIndex
|
|
: -1;
|
|
}
|
|
|
|
uint64_t
|
|
InternalCall_Rendering_RenderSceneSetupContext_GetCameraGameObjectUUID(
|
|
uint64_t nativeHandle) {
|
|
const ManagedRenderSceneSetupContextState* const state =
|
|
FindManagedRenderSceneSetupContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->plan == nullptr ||
|
|
state->plan->request.camera == nullptr ||
|
|
state->plan->request.camera->GetGameObject() == nullptr) {
|
|
return 0u;
|
|
}
|
|
|
|
return state->plan->request.camera->GetGameObject()->GetUUID();
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_RenderSceneSetupContext_GetIsConfigured(
|
|
uint64_t nativeHandle) {
|
|
const ManagedRenderSceneSetupContextState* const state =
|
|
FindManagedRenderSceneSetupContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->explicitlyConfigured
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
int32_t InternalCall_Rendering_RenderSceneSetupContext_GetClearFlags(
|
|
uint64_t nativeHandle) {
|
|
const ManagedRenderSceneSetupContextState* const state =
|
|
FindManagedRenderSceneSetupContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->plan != nullptr
|
|
? static_cast<int32_t>(state->plan->request.clearFlags)
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_RenderSceneSetupContext_GetHasMainSceneDepthAttachment(
|
|
uint64_t nativeHandle) {
|
|
const ManagedRenderSceneSetupContextState* const state =
|
|
FindManagedRenderSceneSetupContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->plan != nullptr &&
|
|
state->plan->GetMainSceneSurface().GetDepthAttachment() != nullptr
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_RenderSceneSetupContext_GetHasMainDirectionalShadow(
|
|
uint64_t nativeHandle) {
|
|
const ManagedRenderSceneSetupContextState* const state =
|
|
FindManagedRenderSceneSetupContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->sceneData != nullptr &&
|
|
state->sceneData->lighting.HasMainDirectionalShadow()
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
void InternalCall_Rendering_RenderSceneSetupContext_SetEnvironmentNone(
|
|
uint64_t nativeHandle) {
|
|
ManagedRenderSceneSetupContextState* const state =
|
|
FindManagedRenderSceneSetupContextState(nativeHandle);
|
|
if (state == nullptr || state->sceneData == nullptr) {
|
|
return;
|
|
}
|
|
|
|
state->sceneData->environment = {};
|
|
state->explicitlyConfigured = true;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_RenderSceneSetupContext_UseCameraSkyboxMaterial(
|
|
uint64_t nativeHandle) {
|
|
ManagedRenderSceneSetupContextState* const state =
|
|
FindManagedRenderSceneSetupContextState(nativeHandle);
|
|
if (state == nullptr ||
|
|
state->plan == nullptr ||
|
|
state->sceneData == nullptr ||
|
|
state->plan->request.camera == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
const Resources::Material* skyboxMaterial =
|
|
state->plan->request.camera->GetSkyboxMaterial();
|
|
if (skyboxMaterial == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
state->sceneData->environment = {};
|
|
state->sceneData->environment.mode =
|
|
Rendering::RenderEnvironmentMode::MaterialSkybox;
|
|
state->sceneData->environment.materialSkybox.material =
|
|
skyboxMaterial;
|
|
state->explicitlyConfigured = true;
|
|
return 1;
|
|
}
|
|
|
|
void InternalCall_Rendering_RenderSceneSetupContext_SetProceduralSkybox(
|
|
uint64_t nativeHandle,
|
|
XCEngine::Math::Color* topColor,
|
|
XCEngine::Math::Color* horizonColor,
|
|
XCEngine::Math::Color* bottomColor) {
|
|
ManagedRenderSceneSetupContextState* const state =
|
|
FindManagedRenderSceneSetupContextState(nativeHandle);
|
|
if (state == nullptr || state->sceneData == nullptr) {
|
|
return;
|
|
}
|
|
|
|
state->sceneData->environment = {};
|
|
state->sceneData->environment.mode =
|
|
Rendering::RenderEnvironmentMode::ProceduralSkybox;
|
|
state->sceneData->environment.skybox.topColor =
|
|
topColor != nullptr ? *topColor : XCEngine::Math::Color();
|
|
state->sceneData->environment.skybox.horizonColor =
|
|
horizonColor != nullptr ? *horizonColor : XCEngine::Math::Color();
|
|
state->sceneData->environment.skybox.bottomColor =
|
|
bottomColor != nullptr ? *bottomColor : XCEngine::Math::Color();
|
|
state->explicitlyConfigured = true;
|
|
}
|
|
|
|
void
|
|
InternalCall_Rendering_RenderSceneSetupContext_ClearGlobalShaderKeywords(
|
|
uint64_t nativeHandle) {
|
|
ManagedRenderSceneSetupContextState* const state =
|
|
FindManagedRenderSceneSetupContextState(nativeHandle);
|
|
if (state == nullptr || state->sceneData == nullptr) {
|
|
return;
|
|
}
|
|
|
|
state->sceneData->globalShaderKeywords = {};
|
|
state->explicitlyConfigured = true;
|
|
}
|
|
|
|
void InternalCall_Rendering_RenderSceneSetupContext_SetGlobalShaderKeyword(
|
|
uint64_t nativeHandle,
|
|
MonoString* keyword,
|
|
mono_bool enabled) {
|
|
ManagedRenderSceneSetupContextState* const state =
|
|
FindManagedRenderSceneSetupContextState(nativeHandle);
|
|
if (state == nullptr || state->sceneData == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const XCEngine::Containers::String normalizedKeyword =
|
|
Resources::NormalizeShaderKeywordToken(
|
|
XCEngine::Containers::String(
|
|
MonoStringToUtf8(keyword).c_str()));
|
|
if (normalizedKeyword.Empty()) {
|
|
state->explicitlyConfigured = true;
|
|
return;
|
|
}
|
|
|
|
Resources::ShaderKeywordSet& keywordSet =
|
|
state->sceneData->globalShaderKeywords;
|
|
bool foundKeyword = false;
|
|
size_t foundIndex = 0;
|
|
for (size_t keywordIndex = 0;
|
|
keywordIndex < keywordSet.enabledKeywords.Size();
|
|
++keywordIndex) {
|
|
if (keywordSet.enabledKeywords[keywordIndex] ==
|
|
normalizedKeyword) {
|
|
foundKeyword = true;
|
|
foundIndex = keywordIndex;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (enabled != 0) {
|
|
if (!foundKeyword) {
|
|
keywordSet.enabledKeywords.PushBack(normalizedKeyword);
|
|
}
|
|
} else if (foundKeyword) {
|
|
const size_t lastIndex =
|
|
keywordSet.enabledKeywords.Size() - 1;
|
|
if (foundIndex != lastIndex) {
|
|
keywordSet.enabledKeywords[foundIndex] =
|
|
keywordSet.enabledKeywords[lastIndex];
|
|
}
|
|
keywordSet.enabledKeywords.PopBack();
|
|
}
|
|
|
|
Resources::NormalizeShaderKeywordSetInPlace(keywordSet);
|
|
state->explicitlyConfigured = true;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_DirectionalShadowExecutionContext_GetHasPlannedMainDirectionalShadow(
|
|
uint64_t nativeHandle) {
|
|
const ManagedDirectionalShadowExecutionContextState* const state =
|
|
FindManagedDirectionalShadowExecutionContextState(
|
|
nativeHandle);
|
|
return state != nullptr &&
|
|
state->plan != nullptr &&
|
|
state->plan->directionalShadow.IsValid()
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
int32_t
|
|
InternalCall_Rendering_DirectionalShadowExecutionContext_GetRendererIndex(
|
|
uint64_t nativeHandle) {
|
|
const ManagedDirectionalShadowExecutionContextState* const state =
|
|
FindManagedDirectionalShadowExecutionContextState(
|
|
nativeHandle);
|
|
return state != nullptr &&
|
|
state->plan != nullptr
|
|
? state->plan->request.rendererIndex
|
|
: -1;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_DirectionalShadowExecutionContext_GetIsConfigured(
|
|
uint64_t nativeHandle) {
|
|
const ManagedDirectionalShadowExecutionContextState* const state =
|
|
FindManagedDirectionalShadowExecutionContextState(
|
|
nativeHandle);
|
|
return state != nullptr &&
|
|
state->explicitlyConfigured
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_DirectionalShadowExecutionContext_UseDefaultMainDirectionalShadowExecution(
|
|
uint64_t nativeHandle) {
|
|
ManagedDirectionalShadowExecutionContextState* const state =
|
|
FindManagedDirectionalShadowExecutionContextState(
|
|
nativeHandle);
|
|
if (state == nullptr ||
|
|
state->plan == nullptr ||
|
|
state->shadowAllocation == nullptr ||
|
|
state->shadowState == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
Rendering::ApplyDefaultRenderPipelineDirectionalShadowExecutionPolicy(
|
|
*state->plan,
|
|
*state->shadowAllocation,
|
|
*state->shadowState);
|
|
state->explicitlyConfigured = true;
|
|
return state->shadowState->shadowCasterRequest.IsValid() &&
|
|
state->shadowState->shadowData.IsValid()
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
void InternalCall_Rendering_DirectionalShadowExecutionContext_ClearDirectionalShadowExecution(
|
|
uint64_t nativeHandle) {
|
|
ManagedDirectionalShadowExecutionContextState* const state =
|
|
FindManagedDirectionalShadowExecutionContextState(
|
|
nativeHandle);
|
|
if (state == nullptr || state->shadowState == nullptr) {
|
|
return;
|
|
}
|
|
|
|
*state->shadowState = {};
|
|
state->explicitlyConfigured = true;
|
|
}
|
|
|
|
int32_t
|
|
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetRendererIndex(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->plan != nullptr
|
|
? state->plan->request.rendererIndex
|
|
: -1;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_IsStageRequested(
|
|
uint64_t nativeHandle,
|
|
int32_t stage) {
|
|
const ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
if (state == nullptr || state->plan == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
Rendering::CameraFrameStage resolvedStage =
|
|
Rendering::CameraFrameStage::MainScene;
|
|
if (!TryResolveManagedCameraFrameStage(stage, resolvedStage)) {
|
|
return 0;
|
|
}
|
|
|
|
return state->plan->HasFrameStage(resolvedStage) ? 1 : 0;
|
|
}
|
|
|
|
int32_t
|
|
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetStageColorSource(
|
|
uint64_t nativeHandle,
|
|
int32_t stage) {
|
|
const ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
if (state == nullptr || state->plan == nullptr) {
|
|
return static_cast<int32_t>(
|
|
Rendering::CameraFrameColorSource::ExplicitSurface);
|
|
}
|
|
|
|
Rendering::CameraFrameStage resolvedStage =
|
|
Rendering::CameraFrameStage::MainScene;
|
|
if (!TryResolveManagedCameraFrameStage(stage, resolvedStage)) {
|
|
return static_cast<int32_t>(
|
|
Rendering::CameraFrameColorSource::ExplicitSurface);
|
|
}
|
|
|
|
return static_cast<int32_t>(
|
|
state->plan->ResolveStageColorSource(resolvedStage));
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetStageUsesGraphManagedOutputColor(
|
|
uint64_t nativeHandle,
|
|
int32_t stage) {
|
|
const ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
if (state == nullptr || state->plan == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
Rendering::CameraFrameStage resolvedStage =
|
|
Rendering::CameraFrameStage::MainScene;
|
|
if (!TryResolveManagedCameraFrameStage(stage, resolvedStage)) {
|
|
return 0;
|
|
}
|
|
|
|
return state->plan->UsesGraphManagedOutputColor(resolvedStage)
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestFullscreenStage(
|
|
uint64_t nativeHandle,
|
|
int32_t stage,
|
|
int32_t source,
|
|
mono_bool usesGraphManagedOutputColor) {
|
|
ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
if (state == nullptr || state->plan == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
Rendering::CameraFrameStage resolvedStage =
|
|
Rendering::CameraFrameStage::MainScene;
|
|
if (!TryResolveManagedCameraFrameStage(stage, resolvedStage)) {
|
|
return 0;
|
|
}
|
|
|
|
const Rendering::CameraFrameColorSource resolvedSource =
|
|
static_cast<Rendering::CameraFrameColorSource>(source);
|
|
return state->plan->RequestFullscreenStage(
|
|
resolvedStage,
|
|
resolvedSource,
|
|
usesGraphManagedOutputColor != 0,
|
|
true)
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearFullscreenStage(
|
|
uint64_t nativeHandle,
|
|
int32_t stage) {
|
|
ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
if (state == nullptr || state->plan == nullptr) {
|
|
return;
|
|
}
|
|
|
|
Rendering::CameraFrameStage resolvedStage =
|
|
Rendering::CameraFrameStage::MainScene;
|
|
if (!TryResolveManagedCameraFrameStage(stage, resolvedStage)) {
|
|
return;
|
|
}
|
|
|
|
state->plan->ClearFullscreenStage(resolvedStage, true);
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestShadowCasterStage(
|
|
uint64_t nativeHandle) {
|
|
ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->plan != nullptr &&
|
|
state->plan->RequestShadowCasterStage(true)
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearShadowCasterStage(
|
|
uint64_t nativeHandle) {
|
|
ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
if (state == nullptr || state->plan == nullptr) {
|
|
return;
|
|
}
|
|
|
|
state->plan->ClearShadowCasterStage(true);
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetHasExplicitShadowCasterStageConfiguration(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->plan != nullptr &&
|
|
state->plan->HasExplicitShadowCasterStageConfiguration()
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestDepthOnlyStage(
|
|
uint64_t nativeHandle) {
|
|
ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->plan != nullptr &&
|
|
state->plan->RequestDepthOnlyStage(true)
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestCameraDepthOnlyStage(
|
|
uint64_t nativeHandle) {
|
|
ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
if (state == nullptr || state->plan == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
Rendering::DepthOnlyRenderRequest& depthOnlyRequest =
|
|
state->plan->request.depthOnly;
|
|
depthOnlyRequest = {};
|
|
depthOnlyRequest.surface =
|
|
Rendering::CameraFramePlan::BuildCameraDepthOnlySurfaceTemplate(
|
|
state->plan->request.surface);
|
|
depthOnlyRequest.clearFlags =
|
|
Rendering::RenderClearFlags::Depth;
|
|
|
|
if (!depthOnlyRequest.IsValid()) {
|
|
depthOnlyRequest = {};
|
|
state->plan->ClearDepthOnlyStage(true);
|
|
return 0;
|
|
}
|
|
|
|
return state->plan->RequestDepthOnlyStage(true)
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
void InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearDepthOnlyStage(
|
|
uint64_t nativeHandle) {
|
|
ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
if (state == nullptr || state->plan == nullptr) {
|
|
return;
|
|
}
|
|
|
|
state->plan->ClearDepthOnlyStage(true);
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetHasExplicitDepthOnlyStageConfiguration(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->plan != nullptr &&
|
|
state->plan->HasExplicitDepthOnlyStageConfiguration()
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
mono_bool
|
|
InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetHasFinalColorProcessing(
|
|
uint64_t nativeHandle) {
|
|
const ManagedScriptableRenderPipelinePlanningContextState* const state =
|
|
FindManagedScriptableRenderPipelinePlanningContextState(nativeHandle);
|
|
return state != nullptr &&
|
|
state->plan != nullptr &&
|
|
state->plan->finalColorPolicy.RequiresProcessing()
|
|
? 1
|
|
: 0;
|
|
}
|
|
|
|
void RegisterInternalCalls() {
|
|
if (GetInternalCallRegistrationState()) {
|
|
return;
|
|
}
|
|
|
|
mono_add_internal_call("XCEngine.InternalCalls::Debug_Log", reinterpret_cast<const void*>(&InternalCall_Debug_Log));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Debug_LogWarning", reinterpret_cast<const void*>(&InternalCall_Debug_LogWarning));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Debug_LogError", reinterpret_cast<const void*>(&InternalCall_Debug_LogError));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Time_GetDeltaTime", reinterpret_cast<const void*>(&InternalCall_Time_GetDeltaTime));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Time_GetFixedDeltaTime", reinterpret_cast<const void*>(&InternalCall_Time_GetFixedDeltaTime));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetKey", reinterpret_cast<const void*>(&InternalCall_Input_GetKey));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetKeyDown", reinterpret_cast<const void*>(&InternalCall_Input_GetKeyDown));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetKeyUp", reinterpret_cast<const void*>(&InternalCall_Input_GetKeyUp));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetMouseButton", reinterpret_cast<const void*>(&InternalCall_Input_GetMouseButton));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetMouseButtonDown", reinterpret_cast<const void*>(&InternalCall_Input_GetMouseButtonDown));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetMouseButtonUp", reinterpret_cast<const void*>(&InternalCall_Input_GetMouseButtonUp));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetButton", reinterpret_cast<const void*>(&InternalCall_Input_GetButton));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetButtonDown", reinterpret_cast<const void*>(&InternalCall_Input_GetButtonDown));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetButtonUp", reinterpret_cast<const void*>(&InternalCall_Input_GetButtonUp));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetAxis", reinterpret_cast<const void*>(&InternalCall_Input_GetAxis));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetAxisRaw", reinterpret_cast<const void*>(&InternalCall_Input_GetAxisRaw));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetAnyKey", reinterpret_cast<const void*>(&InternalCall_Input_GetAnyKey));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetAnyKeyDown", reinterpret_cast<const void*>(&InternalCall_Input_GetAnyKeyDown));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetMousePosition", reinterpret_cast<const void*>(&InternalCall_Input_GetMousePosition));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Input_GetMouseScrollDelta", reinterpret_cast<const void*>(&InternalCall_Input_GetMouseScrollDelta));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_GetName", reinterpret_cast<const void*>(&InternalCall_GameObject_GetName));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_SetName", reinterpret_cast<const void*>(&InternalCall_GameObject_SetName));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_GetTag", reinterpret_cast<const void*>(&InternalCall_GameObject_GetTag));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_SetTag", reinterpret_cast<const void*>(&InternalCall_GameObject_SetTag));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_CompareTag", reinterpret_cast<const void*>(&InternalCall_GameObject_CompareTag));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_GetLayer", reinterpret_cast<const void*>(&InternalCall_GameObject_GetLayer));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_SetLayer", reinterpret_cast<const void*>(&InternalCall_GameObject_SetLayer));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_GetActiveSelf", reinterpret_cast<const void*>(&InternalCall_GameObject_GetActiveSelf));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_GetActiveInHierarchy", reinterpret_cast<const void*>(&InternalCall_GameObject_GetActiveInHierarchy));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_SetActive", reinterpret_cast<const void*>(&InternalCall_GameObject_SetActive));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_HasComponent", reinterpret_cast<const void*>(&InternalCall_GameObject_HasComponent));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_GetComponent", reinterpret_cast<const void*>(&InternalCall_GameObject_GetComponent));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_GetComponents", reinterpret_cast<const void*>(&InternalCall_GameObject_GetComponents));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_GetComponentInChildren", reinterpret_cast<const void*>(&InternalCall_GameObject_GetComponentInChildren));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_GetComponentInParent", reinterpret_cast<const void*>(&InternalCall_GameObject_GetComponentInParent));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_AddComponent", reinterpret_cast<const void*>(&InternalCall_GameObject_AddComponent));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_Find", reinterpret_cast<const void*>(&InternalCall_GameObject_Find));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_Create", reinterpret_cast<const void*>(&InternalCall_GameObject_Create));
|
|
mono_add_internal_call("XCEngine.InternalCalls::GameObject_Destroy", reinterpret_cast<const void*>(&InternalCall_GameObject_Destroy));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Object_Destroy", reinterpret_cast<const void*>(&InternalCall_Object_Destroy));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Behaviour_GetEnabled", reinterpret_cast<const void*>(&InternalCall_Behaviour_GetEnabled));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Behaviour_SetEnabled", reinterpret_cast<const void*>(&InternalCall_Behaviour_SetEnabled));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetLocalPosition", reinterpret_cast<const void*>(&InternalCall_Transform_GetLocalPosition));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_SetLocalPosition", reinterpret_cast<const void*>(&InternalCall_Transform_SetLocalPosition));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetLocalRotation", reinterpret_cast<const void*>(&InternalCall_Transform_GetLocalRotation));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_SetLocalRotation", reinterpret_cast<const void*>(&InternalCall_Transform_SetLocalRotation));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetLocalScale", reinterpret_cast<const void*>(&InternalCall_Transform_GetLocalScale));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_SetLocalScale", reinterpret_cast<const void*>(&InternalCall_Transform_SetLocalScale));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetLocalEulerAngles", reinterpret_cast<const void*>(&InternalCall_Transform_GetLocalEulerAngles));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_SetLocalEulerAngles", reinterpret_cast<const void*>(&InternalCall_Transform_SetLocalEulerAngles));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetPosition", reinterpret_cast<const void*>(&InternalCall_Transform_GetPosition));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_SetPosition", reinterpret_cast<const void*>(&InternalCall_Transform_SetPosition));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetRotation", reinterpret_cast<const void*>(&InternalCall_Transform_GetRotation));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_SetRotation", reinterpret_cast<const void*>(&InternalCall_Transform_SetRotation));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetScale", reinterpret_cast<const void*>(&InternalCall_Transform_GetScale));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_SetScale", reinterpret_cast<const void*>(&InternalCall_Transform_SetScale));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetForward", reinterpret_cast<const void*>(&InternalCall_Transform_GetForward));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetRight", reinterpret_cast<const void*>(&InternalCall_Transform_GetRight));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetUp", reinterpret_cast<const void*>(&InternalCall_Transform_GetUp));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_Translate", reinterpret_cast<const void*>(&InternalCall_Transform_Translate));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_Rotate", reinterpret_cast<const void*>(&InternalCall_Transform_Rotate));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_RotateAxisAngle", reinterpret_cast<const void*>(&InternalCall_Transform_RotateAxisAngle));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_LookAt", reinterpret_cast<const void*>(&InternalCall_Transform_LookAt));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_LookAtWithUp", reinterpret_cast<const void*>(&InternalCall_Transform_LookAtWithUp));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_TransformPoint", reinterpret_cast<const void*>(&InternalCall_Transform_TransformPoint));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_InverseTransformPoint", reinterpret_cast<const void*>(&InternalCall_Transform_InverseTransformPoint));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_TransformDirection", reinterpret_cast<const void*>(&InternalCall_Transform_TransformDirection));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_InverseTransformDirection", reinterpret_cast<const void*>(&InternalCall_Transform_InverseTransformDirection));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetParent", reinterpret_cast<const void*>(&InternalCall_Transform_GetParent));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_SetParent", reinterpret_cast<const void*>(&InternalCall_Transform_SetParent));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetChildCount", reinterpret_cast<const void*>(&InternalCall_Transform_GetChildCount));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Transform_GetChild", reinterpret_cast<const void*>(&InternalCall_Transform_GetChild));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetFieldOfView", reinterpret_cast<const void*>(&InternalCall_Camera_GetFieldOfView));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_SetFieldOfView", reinterpret_cast<const void*>(&InternalCall_Camera_SetFieldOfView));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetNearClipPlane", reinterpret_cast<const void*>(&InternalCall_Camera_GetNearClipPlane));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_SetNearClipPlane", reinterpret_cast<const void*>(&InternalCall_Camera_SetNearClipPlane));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetFarClipPlane", reinterpret_cast<const void*>(&InternalCall_Camera_GetFarClipPlane));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_SetFarClipPlane", reinterpret_cast<const void*>(&InternalCall_Camera_SetFarClipPlane));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetDepth", reinterpret_cast<const void*>(&InternalCall_Camera_GetDepth));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_SetDepth", reinterpret_cast<const void*>(&InternalCall_Camera_SetDepth));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetPrimary", reinterpret_cast<const void*>(&InternalCall_Camera_GetPrimary));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_SetPrimary", reinterpret_cast<const void*>(&InternalCall_Camera_SetPrimary));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetClearMode", reinterpret_cast<const void*>(&InternalCall_Camera_GetClearMode));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_SetClearMode", reinterpret_cast<const void*>(&InternalCall_Camera_SetClearMode));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetStackType", reinterpret_cast<const void*>(&InternalCall_Camera_GetStackType));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_SetStackType", reinterpret_cast<const void*>(&InternalCall_Camera_SetStackType));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetProjectionType", reinterpret_cast<const void*>(&InternalCall_Camera_GetProjectionType));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetSkyboxEnabled", reinterpret_cast<const void*>(&InternalCall_Camera_GetSkyboxEnabled));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetHasSkyboxMaterial", reinterpret_cast<const void*>(&InternalCall_Camera_GetHasSkyboxMaterial));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetHasFinalColorOverrides", reinterpret_cast<const void*>(&InternalCall_Camera_GetHasFinalColorOverrides));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetFinalColorOverrideSettings", reinterpret_cast<const void*>(&InternalCall_Camera_GetFinalColorOverrideSettings));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetSkyboxTopColor", reinterpret_cast<const void*>(&InternalCall_Camera_GetSkyboxTopColor));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetSkyboxHorizonColor", reinterpret_cast<const void*>(&InternalCall_Camera_GetSkyboxHorizonColor));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Camera_GetSkyboxBottomColor", reinterpret_cast<const void*>(&InternalCall_Camera_GetSkyboxBottomColor));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Light_GetIntensity", reinterpret_cast<const void*>(&InternalCall_Light_GetIntensity));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Light_SetIntensity", reinterpret_cast<const void*>(&InternalCall_Light_SetIntensity));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Light_GetRange", reinterpret_cast<const void*>(&InternalCall_Light_GetRange));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Light_SetRange", reinterpret_cast<const void*>(&InternalCall_Light_SetRange));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Light_GetSpotAngle", reinterpret_cast<const void*>(&InternalCall_Light_GetSpotAngle));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Light_SetSpotAngle", reinterpret_cast<const void*>(&InternalCall_Light_SetSpotAngle));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Light_GetCastsShadows", reinterpret_cast<const void*>(&InternalCall_Light_GetCastsShadows));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Light_SetCastsShadows", reinterpret_cast<const void*>(&InternalCall_Light_SetCastsShadows));
|
|
mono_add_internal_call("XCEngine.InternalCalls::MeshFilter_GetMeshPath", reinterpret_cast<const void*>(&InternalCall_MeshFilter_GetMeshPath));
|
|
mono_add_internal_call("XCEngine.InternalCalls::MeshFilter_SetMeshPath", reinterpret_cast<const void*>(&InternalCall_MeshFilter_SetMeshPath));
|
|
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_GetMaterialCount", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_GetMaterialCount));
|
|
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_GetMaterialPath", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_GetMaterialPath));
|
|
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_SetMaterialPath", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_SetMaterialPath));
|
|
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_ClearMaterials", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_ClearMaterials));
|
|
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_GetCastShadows", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_GetCastShadows));
|
|
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_SetCastShadows", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_SetCastShadows));
|
|
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_GetReceiveShadows", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_GetReceiveShadows));
|
|
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_SetReceiveShadows", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_SetReceiveShadows));
|
|
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_GetRenderLayer", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_GetRenderLayer));
|
|
mono_add_internal_call("XCEngine.InternalCalls::MeshRenderer_SetRenderLayer", reinterpret_cast<const void*>(&InternalCall_MeshRenderer_SetRenderLayer));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_GetBodyType", reinterpret_cast<const void*>(&InternalCall_Rigidbody_GetBodyType));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_SetBodyType", reinterpret_cast<const void*>(&InternalCall_Rigidbody_SetBodyType));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_GetMass", reinterpret_cast<const void*>(&InternalCall_Rigidbody_GetMass));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_SetMass", reinterpret_cast<const void*>(&InternalCall_Rigidbody_SetMass));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_GetLinearDamping", reinterpret_cast<const void*>(&InternalCall_Rigidbody_GetLinearDamping));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_SetLinearDamping", reinterpret_cast<const void*>(&InternalCall_Rigidbody_SetLinearDamping));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_GetAngularDamping", reinterpret_cast<const void*>(&InternalCall_Rigidbody_GetAngularDamping));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_SetAngularDamping", reinterpret_cast<const void*>(&InternalCall_Rigidbody_SetAngularDamping));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_GetLinearVelocity", reinterpret_cast<const void*>(&InternalCall_Rigidbody_GetLinearVelocity));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_SetLinearVelocity", reinterpret_cast<const void*>(&InternalCall_Rigidbody_SetLinearVelocity));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_GetAngularVelocity", reinterpret_cast<const void*>(&InternalCall_Rigidbody_GetAngularVelocity));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_SetAngularVelocity", reinterpret_cast<const void*>(&InternalCall_Rigidbody_SetAngularVelocity));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_GetUseGravity", reinterpret_cast<const void*>(&InternalCall_Rigidbody_GetUseGravity));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_SetUseGravity", reinterpret_cast<const void*>(&InternalCall_Rigidbody_SetUseGravity));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_GetEnableCCD", reinterpret_cast<const void*>(&InternalCall_Rigidbody_GetEnableCCD));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_SetEnableCCD", reinterpret_cast<const void*>(&InternalCall_Rigidbody_SetEnableCCD));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_AddForce", reinterpret_cast<const void*>(&InternalCall_Rigidbody_AddForce));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rigidbody_ClearForces", reinterpret_cast<const void*>(&InternalCall_Rigidbody_ClearForces));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Physics_Raycast", reinterpret_cast<const void*>(&InternalCall_Physics_Raycast));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_SetRenderPipelineAsset", reinterpret_cast<const void*>(&InternalCall_Rendering_SetRenderPipelineAsset));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_GetRenderPipelineAsset", reinterpret_cast<const void*>(&InternalCall_Rendering_GetRenderPipelineAsset));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetStage));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetRendererIndex", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetRendererIndex));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetSourceColorTextureHandle", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetSourceColorTextureHandle));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetPrimaryColorTargetHandle", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetPrimaryColorTargetHandle));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetDepthTargetHandle", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetDepthTargetHandle));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_CreateTransientTexture", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_CreateTransientTexture));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_CreateFullscreenTransientColorTexture", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_CreateFullscreenTransientColorTexture));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_CreateFullscreenTransientDepthTexture", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_CreateFullscreenTransientDepthTexture));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_BeginRasterPass", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_BeginRasterPass));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_SetRasterPassSourceColorTexture", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_SetRasterPassSourceColorTexture));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_AddRasterPassReadTexture", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_AddRasterPassReadTexture));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_AddRasterPassReadDepthTexture", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_AddRasterPassReadDepthTexture));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_AddRasterPassTextureBinding", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_AddRasterPassTextureBinding));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_SetRasterPassColorAttachment", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_SetRasterPassColorAttachment));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_SetRasterPassDepthAttachment", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_SetRasterPassDepthAttachment));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_SetRasterPassColorScaleFullscreenExecution", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_SetRasterPassColorScaleFullscreenExecution));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_SetRasterPassShaderVectorFullscreenExecution", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_SetRasterPassShaderVectorFullscreenExecution));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_SetRasterPassFinalColorFullscreenExecution", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_SetRasterPassFinalColorFullscreenExecution));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_CommitRasterPass", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_CommitRasterPass));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetStageColorSource", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetStageColorSource));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetStageUsesGraphManagedOutputColor", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetStageUsesGraphManagedOutputColor));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowEnabled", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowEnabled));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowViewProjection", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowViewProjection));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowOrthographicHalfExtent", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowOrthographicHalfExtent));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowNearClipPlane", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowNearClipPlane));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowFarClipPlane", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowFarClipPlane));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowMapWidth", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowMapWidth));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowMapHeight", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowMapHeight));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowWorldTexelSize", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowWorldTexelSize));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowReceiverDepthBias", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowReceiverDepthBias));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowNormalBiasScale", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowNormalBiasScale));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowStrength", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowStrength));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowDepthBiasFactor", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowDepthBiasFactor));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalShadowDepthBiasUnits", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalShadowDepthBiasUnits));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraView", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraView));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraProjection", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraProjection));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraViewProjection", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraViewProjection));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraWorldPosition", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraWorldPosition));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraWorldRight", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraWorldRight));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraWorldUp", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraWorldUp));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraWorldForward", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraWorldForward));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraClearColor", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraClearColor));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraClearFlags", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraClearFlags));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraPerspectiveProjection", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraPerspectiveProjection));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraVerticalFovRadians", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraVerticalFovRadians));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraOrthographicSize", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraOrthographicSize));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraAspectRatio", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraAspectRatio));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraNearClipPlane", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraNearClipPlane));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraFarClipPlane", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraFarClipPlane));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraViewportWidth", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraViewportWidth));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetCameraViewportHeight", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetCameraViewportHeight));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalLightEnabled", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalLightEnabled));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalLightCastsShadows", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalLightCastsShadows));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalLightDirection", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalLightDirection));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalLightColor", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalLightColor));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetMainDirectionalLightIntensity", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetMainDirectionalLightIntensity));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetHasMainDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetHasMainDirectionalShadow));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetAdditionalLightCount", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetAdditionalLightCount));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetEnvironmentMode", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetEnvironmentMode));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetEnvironmentSkyboxTopColor", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetEnvironmentSkyboxTopColor));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetEnvironmentSkyboxHorizonColor", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetEnvironmentSkyboxHorizonColor));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetEnvironmentSkyboxBottomColor", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetEnvironmentSkyboxBottomColor));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetFinalColorOutputTransferMode", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetFinalColorOutputTransferMode));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetFinalColorExposureMode", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetFinalColorExposureMode));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetFinalColorExposureValue", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetFinalColorExposureValue));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetFinalColorToneMappingMode", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetFinalColorToneMappingMode));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetFinalColorScale", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetFinalColorScale));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetFinalColorHasPipelineDefaults", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetFinalColorHasPipelineDefaults));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_GetFinalColorHasCameraOverrides", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_GetFinalColorHasCameraOverrides));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordScenePhase", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_RecordScenePhase));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_DrawRenderersByDesc", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_DrawRenderersByDesc));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordSceneInjectionPoint", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_RecordSceneInjectionPoint));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderContext_RecordNativeSceneFeaturePass", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderContext_RecordNativeSceneFeaturePass));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_GetRendererIndex", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetRendererIndex));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_IsStageRequested", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_IsStageRequested));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_GetStageColorSource", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetStageColorSource));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_GetStageUsesGraphManagedOutputColor", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetStageUsesGraphManagedOutputColor));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_RequestFullscreenStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestFullscreenStage));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_ClearFullscreenStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearFullscreenStage));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_RequestShadowCasterStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestShadowCasterStage));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_ClearShadowCasterStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearShadowCasterStage));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_GetHasExplicitShadowCasterStageConfiguration", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetHasExplicitShadowCasterStageConfiguration));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_RequestDepthOnlyStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestDepthOnlyStage));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_RequestCameraDepthOnlyStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_RequestCameraDepthOnlyStage));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_ClearDepthOnlyStage", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_ClearDepthOnlyStage));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_GetHasExplicitDepthOnlyStageConfiguration", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetHasExplicitDepthOnlyStageConfiguration));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_ScriptableRenderPipelinePlanningContext_GetHasFinalColorProcessing", reinterpret_cast<const void*>(&InternalCall_Rendering_ScriptableRenderPipelinePlanningContext_GetHasFinalColorProcessing));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_GetRenderedBaseCameraCount", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_GetRenderedBaseCameraCount));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_GetRenderedRequestCount", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_GetRenderedRequestCount));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_GetCameraGameObjectUUID", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_GetCameraGameObjectUUID));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_GetRendererIndex", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_GetRendererIndex));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_SetRendererIndex", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_SetRendererIndex));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_GetHasDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_GetHasDirectionalShadow));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_GetDirectionalShadowPlanningSettings", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_GetDirectionalShadowPlanningSettings));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_SetDirectionalShadowPlanningSettings", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_SetDirectionalShadowPlanningSettings));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_ClearDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_ClearDirectionalShadow));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_GetClearFlags", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_GetClearFlags));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_SetClearFlags", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_SetClearFlags));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_SetResolvedFinalColorPolicy", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_SetResolvedFinalColorPolicy));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_CameraRenderRequestContext_ClearFinalColorPolicy", reinterpret_cast<const void*>(&InternalCall_Rendering_CameraRenderRequestContext_ClearFinalColorPolicy));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_GetRendererIndex", reinterpret_cast<const void*>(&InternalCall_Rendering_RenderSceneSetupContext_GetRendererIndex));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_GetCameraGameObjectUUID", reinterpret_cast<const void*>(&InternalCall_Rendering_RenderSceneSetupContext_GetCameraGameObjectUUID));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_GetIsConfigured", reinterpret_cast<const void*>(&InternalCall_Rendering_RenderSceneSetupContext_GetIsConfigured));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_GetClearFlags", reinterpret_cast<const void*>(&InternalCall_Rendering_RenderSceneSetupContext_GetClearFlags));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_GetHasMainSceneDepthAttachment", reinterpret_cast<const void*>(&InternalCall_Rendering_RenderSceneSetupContext_GetHasMainSceneDepthAttachment));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_GetHasMainDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_RenderSceneSetupContext_GetHasMainDirectionalShadow));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_SetEnvironmentNone", reinterpret_cast<const void*>(&InternalCall_Rendering_RenderSceneSetupContext_SetEnvironmentNone));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_UseCameraSkyboxMaterial", reinterpret_cast<const void*>(&InternalCall_Rendering_RenderSceneSetupContext_UseCameraSkyboxMaterial));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_SetProceduralSkybox", reinterpret_cast<const void*>(&InternalCall_Rendering_RenderSceneSetupContext_SetProceduralSkybox));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_ClearGlobalShaderKeywords", reinterpret_cast<const void*>(&InternalCall_Rendering_RenderSceneSetupContext_ClearGlobalShaderKeywords));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_SetGlobalShaderKeyword", reinterpret_cast<const void*>(&InternalCall_Rendering_RenderSceneSetupContext_SetGlobalShaderKeyword));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_GetHasPlannedMainDirectionalShadow", reinterpret_cast<const void*>(&InternalCall_Rendering_DirectionalShadowExecutionContext_GetHasPlannedMainDirectionalShadow));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_GetRendererIndex", reinterpret_cast<const void*>(&InternalCall_Rendering_DirectionalShadowExecutionContext_GetRendererIndex));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_GetIsConfigured", reinterpret_cast<const void*>(&InternalCall_Rendering_DirectionalShadowExecutionContext_GetIsConfigured));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_UseDefaultMainDirectionalShadowExecution", reinterpret_cast<const void*>(&InternalCall_Rendering_DirectionalShadowExecutionContext_UseDefaultMainDirectionalShadowExecution));
|
|
mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_ClearDirectionalShadowExecution", reinterpret_cast<const void*>(&InternalCall_Rendering_DirectionalShadowExecutionContext_ClearDirectionalShadowExecution));
|
|
|
|
GetInternalCallRegistrationState() = true;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
MonoScriptRuntime::MonoScriptRuntime(Settings settings)
|
|
: m_settings(std::move(settings)) {
|
|
ResolveSettings();
|
|
}
|
|
|
|
MonoScriptRuntime::~MonoScriptRuntime() {
|
|
Shutdown();
|
|
}
|
|
|
|
bool MonoScriptRuntime::Initialize() {
|
|
m_lastError.clear();
|
|
if (!ResolveSettings()) {
|
|
return false;
|
|
}
|
|
|
|
if (m_initialized) {
|
|
return true;
|
|
}
|
|
|
|
if (!InitializeRootDomain()) {
|
|
return false;
|
|
}
|
|
|
|
if (!CreateAppDomain()) {
|
|
return false;
|
|
}
|
|
|
|
if (!LoadAssemblies()) {
|
|
DestroyAppDomain();
|
|
return false;
|
|
}
|
|
|
|
if (!DiscoverScriptClasses()) {
|
|
DestroyAppDomain();
|
|
return false;
|
|
}
|
|
|
|
m_runtimeLifetimeToken = std::make_shared<int>(0);
|
|
m_initialized = true;
|
|
Rendering::Pipelines::SetManagedRenderPipelineBridge(
|
|
std::make_shared<MonoManagedRenderPipelineBridge>(
|
|
this,
|
|
m_runtimeLifetimeToken));
|
|
return true;
|
|
}
|
|
|
|
void MonoScriptRuntime::Shutdown() {
|
|
Rendering::Pipelines::ClearManagedRenderPipelineBridge();
|
|
ClearManagedRenderPipelineSelection(this);
|
|
GetManagedScriptableRenderContextRegistry().clear();
|
|
GetManagedScriptableRenderContextNextHandle() = 1;
|
|
GetManagedCameraRenderRequestContextRegistry().clear();
|
|
GetManagedCameraRenderRequestContextNextHandle() = 1;
|
|
GetManagedRenderSceneSetupContextRegistry().clear();
|
|
GetManagedRenderSceneSetupContextNextHandle() = 1;
|
|
GetManagedDirectionalShadowExecutionContextRegistry().clear();
|
|
GetManagedDirectionalShadowExecutionContextNextHandle() = 1;
|
|
GetManagedScriptableRenderPipelinePlanningContextRegistry().clear();
|
|
GetManagedScriptableRenderPipelinePlanningContextNextHandle() = 1;
|
|
ClearManagedInstances();
|
|
ClearExternalManagedObjects();
|
|
ClearClassCache();
|
|
|
|
m_coreAssembly = nullptr;
|
|
m_appAssembly = nullptr;
|
|
m_coreImage = nullptr;
|
|
m_appImage = nullptr;
|
|
m_loadedManagedAssemblies.clear();
|
|
m_componentClass = nullptr;
|
|
m_behaviourClass = nullptr;
|
|
m_gameObjectClass = nullptr;
|
|
m_monoBehaviourClass = nullptr;
|
|
m_scriptableRenderPipelineAssetClass = nullptr;
|
|
m_scriptableRenderPipelineClass = nullptr;
|
|
m_scriptableRenderContextClass = nullptr;
|
|
m_cameraRenderRequestContextClass = nullptr;
|
|
m_renderSceneSetupContextClass = nullptr;
|
|
m_directionalShadowExecutionContextClass = nullptr;
|
|
m_scriptableRenderPipelinePlanningContextClass = nullptr;
|
|
m_serializeFieldAttributeClass = nullptr;
|
|
m_gameObjectConstructor = nullptr;
|
|
m_scriptableRenderContextConstructor = nullptr;
|
|
m_cameraRenderRequestContextConstructor = nullptr;
|
|
m_renderSceneSetupContextConstructor = nullptr;
|
|
m_directionalShadowExecutionContextConstructor = nullptr;
|
|
m_scriptableRenderPipelinePlanningContextConstructor = nullptr;
|
|
m_managedGameObjectUUIDField = nullptr;
|
|
m_gameObjectUUIDField = nullptr;
|
|
m_scriptComponentUUIDField = nullptr;
|
|
|
|
DestroyAppDomain();
|
|
|
|
m_activeScene = nullptr;
|
|
GetInternalCallScene() = nullptr;
|
|
GetInternalCallDeltaTime() = 0.0f;
|
|
m_runtimeLifetimeToken.reset();
|
|
m_initialized = false;
|
|
}
|
|
|
|
bool MonoScriptRuntime::IsClassAvailable(
|
|
const std::string& assemblyName,
|
|
const std::string& namespaceName,
|
|
const std::string& className) const {
|
|
return FindClassMetadata(assemblyName, namespaceName, className) != nullptr;
|
|
}
|
|
|
|
bool MonoScriptRuntime::TryGetAvailableScriptClasses(
|
|
std::vector<ScriptClassDescriptor>& outClasses) const {
|
|
outClasses.clear();
|
|
if (!m_initialized) {
|
|
return false;
|
|
}
|
|
|
|
outClasses.reserve(m_classes.size());
|
|
for (const auto& [key, metadata] : m_classes) {
|
|
(void)key;
|
|
outClasses.push_back(
|
|
ScriptClassDescriptor{
|
|
metadata.assemblyName,
|
|
metadata.namespaceName,
|
|
metadata.className
|
|
});
|
|
}
|
|
|
|
std::sort(
|
|
outClasses.begin(),
|
|
outClasses.end(),
|
|
[](const ScriptClassDescriptor& lhs, const ScriptClassDescriptor& rhs) {
|
|
if (lhs.assemblyName != rhs.assemblyName) {
|
|
return lhs.assemblyName < rhs.assemblyName;
|
|
}
|
|
if (lhs.namespaceName != rhs.namespaceName) {
|
|
return lhs.namespaceName < rhs.namespaceName;
|
|
}
|
|
return lhs.className < rhs.className;
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
bool MonoScriptRuntime::TryGetAvailableRenderPipelineAssetClasses(
|
|
std::vector<ScriptClassDescriptor>& outClasses) const {
|
|
outClasses.clear();
|
|
if (!m_initialized) {
|
|
return false;
|
|
}
|
|
|
|
outClasses = m_renderPipelineAssetClasses;
|
|
std::sort(
|
|
outClasses.begin(),
|
|
outClasses.end(),
|
|
[](const ScriptClassDescriptor& lhs, const ScriptClassDescriptor& rhs) {
|
|
if (lhs.assemblyName != rhs.assemblyName) {
|
|
return lhs.assemblyName < rhs.assemblyName;
|
|
}
|
|
if (lhs.namespaceName != rhs.namespaceName) {
|
|
return lhs.namespaceName < rhs.namespaceName;
|
|
}
|
|
return lhs.className < rhs.className;
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
std::vector<std::string> MonoScriptRuntime::GetScriptClassNames(const std::string& assemblyName) const {
|
|
std::vector<ScriptClassDescriptor> classes;
|
|
if (!TryGetAvailableScriptClasses(classes)) {
|
|
return {};
|
|
}
|
|
|
|
std::vector<std::string> classNames;
|
|
classNames.reserve(classes.size());
|
|
|
|
for (const ScriptClassDescriptor& descriptor : classes) {
|
|
if (!assemblyName.empty() && descriptor.assemblyName != assemblyName) {
|
|
continue;
|
|
}
|
|
|
|
classNames.push_back(descriptor.GetFullName());
|
|
}
|
|
|
|
return classNames;
|
|
}
|
|
|
|
bool MonoScriptRuntime::TryGetClassFieldMetadata(
|
|
const std::string& assemblyName,
|
|
const std::string& namespaceName,
|
|
const std::string& className,
|
|
std::vector<ScriptFieldMetadata>& outFields) const {
|
|
outFields.clear();
|
|
|
|
const ClassMetadata* metadata = FindClassMetadata(assemblyName, namespaceName, className);
|
|
if (!metadata) {
|
|
return false;
|
|
}
|
|
|
|
outFields.reserve(metadata->fields.size());
|
|
for (const auto& [fieldName, fieldMetadata] : metadata->fields) {
|
|
outFields.push_back(ScriptFieldMetadata{fieldName, fieldMetadata.type});
|
|
}
|
|
|
|
std::sort(
|
|
outFields.begin(),
|
|
outFields.end(),
|
|
[](const ScriptFieldMetadata& lhs, const ScriptFieldMetadata& rhs) {
|
|
return lhs.name < rhs.name;
|
|
});
|
|
return true;
|
|
}
|
|
|
|
bool MonoScriptRuntime::TryGetClassFieldDefaultValues(
|
|
const std::string& assemblyName,
|
|
const std::string& namespaceName,
|
|
const std::string& className,
|
|
std::vector<ScriptFieldDefaultValue>& outFields) const {
|
|
outFields.clear();
|
|
|
|
const ClassMetadata* metadata = FindClassMetadata(assemblyName, namespaceName, className);
|
|
if (!metadata) {
|
|
return false;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoObject* instance = mono_object_new(m_appDomain, metadata->monoClass);
|
|
if (!instance) {
|
|
return false;
|
|
}
|
|
|
|
mono_runtime_object_init(instance);
|
|
|
|
outFields.reserve(metadata->fields.size());
|
|
for (const auto& [fieldName, fieldMetadata] : metadata->fields) {
|
|
ScriptFieldValue value;
|
|
if (!TryReadFieldValue(instance, fieldMetadata, value)) {
|
|
outFields.clear();
|
|
return false;
|
|
}
|
|
|
|
outFields.push_back(ScriptFieldDefaultValue{fieldName, fieldMetadata.type, value});
|
|
}
|
|
|
|
std::sort(
|
|
outFields.begin(),
|
|
outFields.end(),
|
|
[](const ScriptFieldDefaultValue& lhs, const ScriptFieldDefaultValue& rhs) {
|
|
return lhs.fieldName < rhs.fieldName;
|
|
});
|
|
return true;
|
|
}
|
|
|
|
bool MonoScriptRuntime::HasManagedInstance(const ScriptComponent* component) const {
|
|
const InstanceData* instanceData = FindInstance(component);
|
|
return instanceData != nullptr && GetManagedObject(*instanceData) != nullptr;
|
|
}
|
|
|
|
MonoObject* MonoScriptRuntime::GetManagedInstanceObject(const ScriptComponent* component) const {
|
|
const InstanceData* instanceData = FindInstance(component);
|
|
return instanceData ? GetManagedObject(*instanceData) : nullptr;
|
|
}
|
|
|
|
bool MonoScriptRuntime::TryGetFieldValue(
|
|
const ScriptComponent* component,
|
|
const std::string& fieldName,
|
|
ScriptFieldValue& outValue) const {
|
|
const InstanceData* instanceData = FindInstance(component);
|
|
if (!instanceData || !instanceData->classMetadata) {
|
|
return false;
|
|
}
|
|
|
|
const auto fieldIt = instanceData->classMetadata->fields.find(fieldName);
|
|
if (fieldIt == instanceData->classMetadata->fields.end()) {
|
|
return false;
|
|
}
|
|
|
|
MonoObject* instance = GetManagedObject(*instanceData);
|
|
if (!instance) {
|
|
return false;
|
|
}
|
|
|
|
return TryReadFieldValue(instance, fieldIt->second, outValue);
|
|
}
|
|
|
|
void MonoScriptRuntime::OnRuntimeStart(Components::Scene* scene) {
|
|
m_activeScene = nullptr;
|
|
GetInternalCallDeltaTime() = 0.0f;
|
|
if (Initialize()) {
|
|
m_activeScene = scene;
|
|
GetInternalCallScene() = scene;
|
|
}
|
|
}
|
|
|
|
void MonoScriptRuntime::OnRuntimeStop(Components::Scene* scene) {
|
|
if (scene != nullptr) {
|
|
ClearManagedRenderPipelineSelection(this);
|
|
}
|
|
ClearManagedInstances();
|
|
m_activeScene = nullptr;
|
|
GetInternalCallScene() = nullptr;
|
|
GetInternalCallDeltaTime() = 0.0f;
|
|
}
|
|
|
|
bool MonoScriptRuntime::TrySetManagedFieldValue(
|
|
const ScriptRuntimeContext& context,
|
|
const std::string& fieldName,
|
|
const ScriptFieldValue& value) {
|
|
const InstanceData* instanceData = FindInstance(context);
|
|
if (!instanceData || !instanceData->classMetadata) {
|
|
return false;
|
|
}
|
|
|
|
const auto metadataIt = instanceData->classMetadata->fields.find(fieldName);
|
|
if (metadataIt == instanceData->classMetadata->fields.end()) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsScriptFieldValueCompatible(metadataIt->second.type, value)) {
|
|
return false;
|
|
}
|
|
|
|
MonoObject* instance = GetManagedObject(*instanceData);
|
|
if (!instance) {
|
|
return false;
|
|
}
|
|
|
|
return TrySetFieldValue(instance, metadataIt->second, value);
|
|
}
|
|
|
|
bool MonoScriptRuntime::TryGetManagedFieldValue(
|
|
const ScriptRuntimeContext& context,
|
|
const std::string& fieldName,
|
|
ScriptFieldValue& outValue) const {
|
|
const InstanceData* instanceData = FindInstance(context);
|
|
if (!instanceData || !instanceData->classMetadata) {
|
|
return false;
|
|
}
|
|
|
|
const auto metadataIt = instanceData->classMetadata->fields.find(fieldName);
|
|
if (metadataIt == instanceData->classMetadata->fields.end()) {
|
|
return false;
|
|
}
|
|
|
|
MonoObject* instance = GetManagedObject(*instanceData);
|
|
if (!instance) {
|
|
return false;
|
|
}
|
|
|
|
return TryReadFieldValue(instance, metadataIt->second, outValue);
|
|
}
|
|
|
|
void MonoScriptRuntime::SyncManagedFieldsToStorage(const ScriptRuntimeContext& context) {
|
|
if (!context.component) {
|
|
return;
|
|
}
|
|
|
|
const InstanceData* instanceData = FindInstance(context);
|
|
if (!instanceData || !instanceData->classMetadata) {
|
|
return;
|
|
}
|
|
|
|
MonoObject* instance = GetManagedObject(*instanceData);
|
|
if (!instance) {
|
|
return;
|
|
}
|
|
|
|
ScriptFieldStorage& fieldStorage = context.component->GetFieldStorage();
|
|
const std::vector<std::string> fieldNames = fieldStorage.GetFieldNames();
|
|
for (const std::string& fieldName : fieldNames) {
|
|
StoredScriptField* storedField = fieldStorage.FindField(fieldName);
|
|
if (!storedField) {
|
|
continue;
|
|
}
|
|
|
|
const auto metadataIt = instanceData->classMetadata->fields.find(fieldName);
|
|
if (metadataIt == instanceData->classMetadata->fields.end() || storedField->type != metadataIt->second.type) {
|
|
continue;
|
|
}
|
|
|
|
ScriptFieldValue value;
|
|
if (!TryReadFieldValue(instance, metadataIt->second, value)) {
|
|
continue;
|
|
}
|
|
|
|
fieldStorage.SetFieldValue(fieldName, storedField->type, value);
|
|
}
|
|
}
|
|
|
|
bool MonoScriptRuntime::CreateScriptInstance(const ScriptRuntimeContext& context) {
|
|
if (!context.component) {
|
|
SetError("Cannot create a managed script instance without a ScriptComponent.");
|
|
return false;
|
|
}
|
|
|
|
if (FindInstance(context)) {
|
|
return true;
|
|
}
|
|
|
|
if (!Initialize()) {
|
|
return false;
|
|
}
|
|
|
|
const std::string assemblyName = context.component->GetAssemblyName().empty()
|
|
? m_settings.appAssemblyName
|
|
: context.component->GetAssemblyName();
|
|
|
|
const ClassMetadata* classMetadata = FindClassMetadata(
|
|
assemblyName,
|
|
context.component->GetNamespaceName(),
|
|
context.component->GetClassName());
|
|
if (!classMetadata) {
|
|
SetError("Managed script class was not found: " + assemblyName + "|" + context.component->GetFullClassName());
|
|
return false;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoObject* instance = mono_object_new(m_appDomain, classMetadata->monoClass);
|
|
if (!instance) {
|
|
SetError("Mono failed to allocate a managed object for " + classMetadata->fullName + ".");
|
|
return false;
|
|
}
|
|
|
|
mono_runtime_object_init(instance);
|
|
|
|
if (!ApplyContextFields(context, instance) || !ApplyStoredFields(context, *classMetadata, instance)) {
|
|
return false;
|
|
}
|
|
|
|
const uint32_t gcHandle = mono_gchandle_new(instance, false);
|
|
const InstanceKey key{context.gameObjectUUID, context.scriptComponentUUID};
|
|
m_instances[key] = InstanceData{classMetadata, gcHandle};
|
|
return true;
|
|
}
|
|
|
|
void MonoScriptRuntime::DestroyScriptInstance(const ScriptRuntimeContext& context) {
|
|
InstanceData* instanceData = FindInstance(context);
|
|
if (!instanceData) {
|
|
return;
|
|
}
|
|
|
|
if (instanceData->gcHandle != 0) {
|
|
mono_gchandle_free(instanceData->gcHandle);
|
|
}
|
|
|
|
m_instances.erase(InstanceKey{context.gameObjectUUID, context.scriptComponentUUID});
|
|
}
|
|
|
|
void MonoScriptRuntime::InvokeMethod(
|
|
const ScriptRuntimeContext& context,
|
|
ScriptLifecycleMethod method,
|
|
float deltaTime) {
|
|
const InstanceData* instanceData = FindInstance(context);
|
|
if (!instanceData || !instanceData->classMetadata) {
|
|
return;
|
|
}
|
|
|
|
MonoMethod* managedMethod = instanceData->classMetadata->lifecycleMethods[static_cast<size_t>(method)];
|
|
if (!managedMethod) {
|
|
return;
|
|
}
|
|
|
|
MonoObject* instance = GetManagedObject(*instanceData);
|
|
if (!instance) {
|
|
return;
|
|
}
|
|
|
|
const float previousDeltaTime = GetInternalCallDeltaTime();
|
|
GetInternalCallDeltaTime() = deltaTime;
|
|
InvokeManagedMethod(instance, managedMethod, nullptr);
|
|
GetInternalCallDeltaTime() = previousDeltaTime;
|
|
}
|
|
|
|
void MonoScriptRuntime::InvokePhysicsMessage(
|
|
const ScriptRuntimeContext& context,
|
|
ScriptPhysicsMessage message,
|
|
Components::GameObject* other) {
|
|
const InstanceData* instanceData = FindInstance(context);
|
|
if (!instanceData || !instanceData->classMetadata) {
|
|
return;
|
|
}
|
|
|
|
const PhysicsMessageMethods& methods =
|
|
instanceData->classMetadata->physicsMessageMethods[static_cast<size_t>(message)];
|
|
MonoMethod* managedMethod = methods.withGameObject ? methods.withGameObject : methods.withoutArgs;
|
|
if (!managedMethod) {
|
|
return;
|
|
}
|
|
|
|
MonoObject* instance = GetManagedObject(*instanceData);
|
|
if (!instance) {
|
|
return;
|
|
}
|
|
|
|
if (methods.withGameObject) {
|
|
MonoObject* managedOther = other ? CreateManagedGameObject(other->GetUUID()) : nullptr;
|
|
if (other && !managedOther) {
|
|
return;
|
|
}
|
|
|
|
void* args[1];
|
|
args[0] = managedOther;
|
|
InvokeManagedMethod(instance, managedMethod, args);
|
|
return;
|
|
}
|
|
|
|
InvokeManagedMethod(instance, managedMethod, nullptr);
|
|
}
|
|
|
|
size_t MonoScriptRuntime::InstanceKeyHasher::operator()(const InstanceKey& key) const {
|
|
const size_t h1 = std::hash<uint64_t>{}(key.gameObjectUUID);
|
|
const size_t h2 = std::hash<uint64_t>{}(key.scriptComponentUUID);
|
|
return h1 ^ (h2 + 0x9e3779b97f4a7c15ULL + (h1 << 6) + (h1 >> 2));
|
|
}
|
|
|
|
std::filesystem::path MonoScriptRuntime::GetEngineAssemblyManifestPath(
|
|
const std::filesystem::path& assemblyDirectory) {
|
|
return assemblyDirectory / EngineAssemblyManifestFileName;
|
|
}
|
|
|
|
bool MonoScriptRuntime::DiscoverEngineAssemblies(
|
|
Settings& ioSettings,
|
|
std::string* outError) {
|
|
if (!ioSettings.engineAssemblies.empty()) {
|
|
std::unordered_set<std::string> assemblyNames;
|
|
for (ManagedAssemblyDescriptor& assembly :
|
|
ioSettings.engineAssemblies) {
|
|
if (!NormalizeManagedAssemblyDescriptor(
|
|
assembly,
|
|
ioSettings.assemblyDirectory,
|
|
assemblyNames,
|
|
outError)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (ioSettings.assemblyDirectory.empty()) {
|
|
return true;
|
|
}
|
|
|
|
std::vector<ManagedAssemblyDescriptor> discoveredAssemblies;
|
|
const std::filesystem::path manifestPath =
|
|
GetEngineAssemblyManifestPath(ioSettings.assemblyDirectory);
|
|
if (!LoadManagedAssemblyManifest(
|
|
ioSettings.assemblyDirectory,
|
|
manifestPath,
|
|
discoveredAssemblies,
|
|
outError)) {
|
|
return false;
|
|
}
|
|
|
|
if (discoveredAssemblies.empty() &&
|
|
!DiscoverManagedAssembliesByConvention(
|
|
ioSettings,
|
|
discoveredAssemblies)) {
|
|
if (outError != nullptr) {
|
|
*outError =
|
|
"Failed to discover managed engine assemblies in " +
|
|
ioSettings.assemblyDirectory.string();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
ioSettings.engineAssemblies = std::move(discoveredAssemblies);
|
|
return true;
|
|
}
|
|
|
|
bool MonoScriptRuntime::ResolveSettings() {
|
|
if (!m_settings.coreAssemblyPath.empty() && m_settings.assemblyDirectory.empty()) {
|
|
m_settings.assemblyDirectory = m_settings.coreAssemblyPath.parent_path();
|
|
}
|
|
|
|
if (!m_settings.appAssemblyPath.empty() && m_settings.assemblyDirectory.empty()) {
|
|
m_settings.assemblyDirectory = m_settings.appAssemblyPath.parent_path();
|
|
}
|
|
|
|
if (m_settings.coreAssemblyPath.empty() && !m_settings.assemblyDirectory.empty()) {
|
|
m_settings.coreAssemblyPath = m_settings.assemblyDirectory / (m_settings.coreAssemblyName + ".dll");
|
|
}
|
|
|
|
if (m_settings.appAssemblyPath.empty() && !m_settings.assemblyDirectory.empty()) {
|
|
m_settings.appAssemblyPath = m_settings.assemblyDirectory / (m_settings.appAssemblyName + ".dll");
|
|
}
|
|
|
|
if (m_settings.corlibDirectory.empty()) {
|
|
if (!m_settings.assemblyDirectory.empty()) {
|
|
m_settings.corlibDirectory = m_settings.assemblyDirectory;
|
|
} else if (!m_settings.coreAssemblyPath.empty()) {
|
|
m_settings.corlibDirectory = m_settings.coreAssemblyPath.parent_path();
|
|
}
|
|
}
|
|
|
|
std::string discoveryError;
|
|
if (!DiscoverEngineAssemblies(m_settings, &discoveryError)) {
|
|
SetError(discoveryError);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool MonoScriptRuntime::InitializeRootDomain() {
|
|
MonoRootState& rootState = GetMonoRootState();
|
|
if (rootState.initialized) {
|
|
return true;
|
|
}
|
|
|
|
if (!m_settings.corlibDirectory.empty()) {
|
|
const std::string corlibDirectory = m_settings.corlibDirectory.string();
|
|
mono_set_assemblies_path(corlibDirectory.c_str());
|
|
}
|
|
|
|
mono_config_parse(nullptr);
|
|
|
|
rootState.rootDomain = mono_jit_init_version("XCEngineRootDomain", "v4.0.30319");
|
|
if (!rootState.rootDomain) {
|
|
SetError("Failed to initialize the Mono root domain.");
|
|
return false;
|
|
}
|
|
|
|
mono_domain_set(rootState.rootDomain, true);
|
|
RegisterInternalCalls();
|
|
rootState.initialized = true;
|
|
if (!rootState.cleanupRegistered) {
|
|
std::atexit(&CleanupMonoRootDomainAtExit);
|
|
rootState.cleanupRegistered = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool MonoScriptRuntime::CreateAppDomain() {
|
|
if (m_appDomain) {
|
|
return true;
|
|
}
|
|
|
|
MonoRootState& rootState = GetMonoRootState();
|
|
if (!rootState.rootDomain) {
|
|
SetError("Mono root domain is not initialized.");
|
|
return false;
|
|
}
|
|
|
|
mono_domain_set(rootState.rootDomain, true);
|
|
m_appDomain = mono_domain_create_appdomain(const_cast<char*>("XCEngineScriptDomain"), nullptr);
|
|
if (!m_appDomain) {
|
|
SetError("Failed to create the Mono app domain.");
|
|
return false;
|
|
}
|
|
|
|
mono_domain_set(m_appDomain, true);
|
|
return true;
|
|
}
|
|
|
|
void MonoScriptRuntime::DestroyAppDomain() {
|
|
if (!m_appDomain) {
|
|
return;
|
|
}
|
|
|
|
MonoRootState& rootState = GetMonoRootState();
|
|
if (rootState.rootDomain) {
|
|
mono_domain_set(rootState.rootDomain, true);
|
|
}
|
|
|
|
mono_domain_unload(m_appDomain);
|
|
m_appDomain = nullptr;
|
|
|
|
if (rootState.rootDomain) {
|
|
mono_domain_set(rootState.rootDomain, true);
|
|
}
|
|
}
|
|
|
|
void MonoScriptRuntime::SetCurrentDomain() const {
|
|
if (m_appDomain) {
|
|
mono_domain_set(m_appDomain, true);
|
|
}
|
|
}
|
|
|
|
bool MonoScriptRuntime::LoadAssemblies() {
|
|
if (m_settings.coreAssemblyPath.empty() || m_settings.appAssemblyPath.empty()) {
|
|
SetError("Managed assembly paths are not configured.");
|
|
return false;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
m_loadedManagedAssemblies.clear();
|
|
|
|
if (!LoadAssemblyImage(
|
|
BuildManagedAssemblyDescriptor(
|
|
m_settings.coreAssemblyName,
|
|
m_settings.coreAssemblyPath),
|
|
"script core",
|
|
m_coreAssembly,
|
|
m_coreImage)) {
|
|
return false;
|
|
}
|
|
|
|
for (const ManagedAssemblyDescriptor& assembly :
|
|
m_settings.engineAssemblies) {
|
|
MonoAssembly* loadedAssembly = nullptr;
|
|
MonoImage* loadedImage = nullptr;
|
|
if (!LoadAssemblyImage(
|
|
assembly,
|
|
"engine",
|
|
loadedAssembly,
|
|
loadedImage)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!LoadAssemblyImage(
|
|
BuildManagedAssemblyDescriptor(
|
|
m_settings.appAssemblyName,
|
|
m_settings.appAssemblyPath),
|
|
"game scripts",
|
|
m_appAssembly,
|
|
m_appImage)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool MonoScriptRuntime::LoadAssemblyImage(
|
|
const ManagedAssemblyDescriptor& descriptor,
|
|
const char* roleLabel,
|
|
MonoAssembly*& outAssembly,
|
|
MonoImage*& outImage) {
|
|
outAssembly = nullptr;
|
|
outImage = nullptr;
|
|
|
|
if (descriptor.name.empty() || descriptor.path.empty()) {
|
|
SetError(
|
|
"Managed " + std::string(roleLabel) +
|
|
" assembly descriptor is incomplete.");
|
|
return false;
|
|
}
|
|
|
|
if (!std::filesystem::exists(descriptor.path)) {
|
|
SetError(
|
|
"Managed " + std::string(roleLabel) +
|
|
" assembly does not exist: " + descriptor.path.string());
|
|
return false;
|
|
}
|
|
|
|
if (m_loadedManagedAssemblies.contains(descriptor.name)) {
|
|
SetError(
|
|
"Managed assembly name is loaded more than once: " +
|
|
descriptor.name);
|
|
return false;
|
|
}
|
|
|
|
outAssembly = mono_domain_assembly_open(
|
|
m_appDomain,
|
|
descriptor.path.string().c_str());
|
|
if (!outAssembly) {
|
|
SetError(
|
|
"Failed to load managed " + std::string(roleLabel) +
|
|
" assembly: " + descriptor.path.string());
|
|
return false;
|
|
}
|
|
|
|
outImage = mono_assembly_get_image(outAssembly);
|
|
if (!outImage) {
|
|
SetError(
|
|
"Failed to access the managed " + std::string(roleLabel) +
|
|
" image: " + descriptor.path.string());
|
|
return false;
|
|
}
|
|
|
|
m_loadedManagedAssemblies.emplace(
|
|
descriptor.name,
|
|
LoadedManagedAssemblyData{outAssembly, outImage});
|
|
return true;
|
|
}
|
|
|
|
bool MonoScriptRuntime::DiscoverScriptClasses() {
|
|
ClearClassCache();
|
|
|
|
m_componentClass = mono_class_from_name(
|
|
m_coreImage,
|
|
m_settings.baseNamespace.c_str(),
|
|
"Component");
|
|
if (!m_componentClass) {
|
|
SetError("Failed to locate the managed Component base type.");
|
|
return false;
|
|
}
|
|
|
|
m_behaviourClass = mono_class_from_name(
|
|
m_coreImage,
|
|
m_settings.baseNamespace.c_str(),
|
|
"Behaviour");
|
|
if (!m_behaviourClass) {
|
|
SetError("Failed to locate the managed Behaviour base type.");
|
|
return false;
|
|
}
|
|
|
|
m_gameObjectClass = mono_class_from_name(
|
|
m_coreImage,
|
|
m_settings.baseNamespace.c_str(),
|
|
"GameObject");
|
|
if (!m_gameObjectClass) {
|
|
SetError("Failed to locate the managed GameObject wrapper type.");
|
|
return false;
|
|
}
|
|
|
|
m_gameObjectConstructor = mono_class_get_method_from_name(m_gameObjectClass, ".ctor", 1);
|
|
m_managedGameObjectUUIDField = mono_class_get_field_from_name(m_gameObjectClass, "m_uuid");
|
|
if (!m_gameObjectConstructor || !m_managedGameObjectUUIDField) {
|
|
SetError("Failed to locate the managed GameObject constructor or UUID field.");
|
|
return false;
|
|
}
|
|
|
|
m_monoBehaviourClass = mono_class_from_name(
|
|
m_coreImage,
|
|
m_settings.baseNamespace.c_str(),
|
|
m_settings.baseClassName.c_str());
|
|
if (!m_monoBehaviourClass) {
|
|
SetError("Failed to locate the managed base type " + BuildFullClassName(m_settings.baseNamespace, m_settings.baseClassName) + ".");
|
|
return false;
|
|
}
|
|
|
|
m_scriptableRenderPipelineAssetClass = mono_class_from_name(
|
|
m_coreImage,
|
|
kManagedRenderingNamespace,
|
|
"ScriptableRenderPipelineAsset");
|
|
if (!m_scriptableRenderPipelineAssetClass) {
|
|
SetError("Failed to locate the managed ScriptableRenderPipelineAsset base type.");
|
|
return false;
|
|
}
|
|
|
|
m_scriptableRenderPipelineClass = mono_class_from_name(
|
|
m_coreImage,
|
|
kManagedRenderingNamespace,
|
|
"ScriptableRenderPipeline");
|
|
if (!m_scriptableRenderPipelineClass) {
|
|
SetError("Failed to locate the managed ScriptableRenderPipeline base type.");
|
|
return false;
|
|
}
|
|
|
|
m_scriptableRenderContextClass = mono_class_from_name(
|
|
m_coreImage,
|
|
kManagedRenderingNamespace,
|
|
"ScriptableRenderContext");
|
|
if (!m_scriptableRenderContextClass) {
|
|
SetError("Failed to locate the managed ScriptableRenderContext type.");
|
|
return false;
|
|
}
|
|
|
|
m_scriptableRenderContextConstructor = mono_class_get_method_from_name(
|
|
m_scriptableRenderContextClass,
|
|
".ctor",
|
|
1);
|
|
if (!m_scriptableRenderContextConstructor) {
|
|
SetError(
|
|
"Failed to locate the managed ScriptableRenderContext constructor.");
|
|
return false;
|
|
}
|
|
|
|
m_cameraRenderRequestContextClass = mono_class_from_name(
|
|
m_coreImage,
|
|
kManagedRenderingNamespace,
|
|
"CameraRenderRequestContext");
|
|
if (!m_cameraRenderRequestContextClass) {
|
|
SetError(
|
|
"Failed to locate the managed CameraRenderRequestContext type.");
|
|
return false;
|
|
}
|
|
|
|
m_cameraRenderRequestContextConstructor =
|
|
mono_class_get_method_from_name(
|
|
m_cameraRenderRequestContextClass,
|
|
".ctor",
|
|
1);
|
|
if (!m_cameraRenderRequestContextConstructor) {
|
|
SetError(
|
|
"Failed to locate the managed CameraRenderRequestContext constructor.");
|
|
return false;
|
|
}
|
|
|
|
m_renderSceneSetupContextClass = mono_class_from_name(
|
|
m_coreImage,
|
|
kManagedRenderingNamespace,
|
|
"RenderSceneSetupContext");
|
|
if (!m_renderSceneSetupContextClass) {
|
|
SetError(
|
|
"Failed to locate the managed RenderSceneSetupContext type.");
|
|
return false;
|
|
}
|
|
|
|
m_renderSceneSetupContextConstructor =
|
|
mono_class_get_method_from_name(
|
|
m_renderSceneSetupContextClass,
|
|
".ctor",
|
|
1);
|
|
if (!m_renderSceneSetupContextConstructor) {
|
|
SetError(
|
|
"Failed to locate the managed RenderSceneSetupContext constructor.");
|
|
return false;
|
|
}
|
|
|
|
m_directionalShadowExecutionContextClass = mono_class_from_name(
|
|
m_coreImage,
|
|
kManagedRenderingNamespace,
|
|
"DirectionalShadowExecutionContext");
|
|
if (!m_directionalShadowExecutionContextClass) {
|
|
SetError(
|
|
"Failed to locate the managed DirectionalShadowExecutionContext type.");
|
|
return false;
|
|
}
|
|
|
|
m_directionalShadowExecutionContextConstructor =
|
|
mono_class_get_method_from_name(
|
|
m_directionalShadowExecutionContextClass,
|
|
".ctor",
|
|
1);
|
|
if (!m_directionalShadowExecutionContextConstructor) {
|
|
SetError(
|
|
"Failed to locate the managed DirectionalShadowExecutionContext constructor.");
|
|
return false;
|
|
}
|
|
|
|
m_scriptableRenderPipelinePlanningContextClass = mono_class_from_name(
|
|
m_coreImage,
|
|
kManagedRenderingNamespace,
|
|
"ScriptableRenderPipelinePlanningContext");
|
|
if (!m_scriptableRenderPipelinePlanningContextClass) {
|
|
SetError(
|
|
"Failed to locate the managed ScriptableRenderPipelinePlanningContext type.");
|
|
return false;
|
|
}
|
|
|
|
m_scriptableRenderPipelinePlanningContextConstructor =
|
|
mono_class_get_method_from_name(
|
|
m_scriptableRenderPipelinePlanningContextClass,
|
|
".ctor",
|
|
1);
|
|
if (!m_scriptableRenderPipelinePlanningContextConstructor) {
|
|
SetError(
|
|
"Failed to locate the managed ScriptableRenderPipelinePlanningContext constructor.");
|
|
return false;
|
|
}
|
|
|
|
m_serializeFieldAttributeClass = mono_class_from_name(
|
|
m_coreImage,
|
|
m_settings.baseNamespace.c_str(),
|
|
"SerializeField");
|
|
if (!m_serializeFieldAttributeClass) {
|
|
SetError("Failed to locate the managed SerializeField attribute type.");
|
|
return false;
|
|
}
|
|
|
|
m_gameObjectUUIDField = mono_class_get_field_from_name(m_componentClass, "m_gameObjectUUID");
|
|
m_scriptComponentUUIDField = mono_class_get_field_from_name(m_behaviourClass, "m_scriptComponentUUID");
|
|
if (!m_gameObjectUUIDField || !m_scriptComponentUUIDField) {
|
|
SetError("Failed to locate the managed context fields for Component/Behaviour.");
|
|
return false;
|
|
}
|
|
|
|
DiscoverScriptClassesInImage(m_settings.appAssemblyName, m_appImage);
|
|
DiscoverRenderPipelineAssetClassesInImage(
|
|
m_settings.coreAssemblyName,
|
|
m_coreImage);
|
|
for (const ManagedAssemblyDescriptor& assembly :
|
|
m_settings.engineAssemblies) {
|
|
DiscoverRenderPipelineAssetClassesInImage(
|
|
assembly.name,
|
|
FindLoadedAssemblyImage(assembly.name));
|
|
}
|
|
DiscoverRenderPipelineAssetClassesInImage(
|
|
m_settings.appAssemblyName,
|
|
m_appImage);
|
|
return true;
|
|
}
|
|
|
|
void MonoScriptRuntime::DiscoverScriptClassesInImage(const std::string& assemblyName, MonoImage* image) {
|
|
if (!image) {
|
|
return;
|
|
}
|
|
|
|
const int typeCount = mono_image_get_table_rows(image, MONO_TABLE_TYPEDEF);
|
|
for (int index = 1; index <= typeCount; ++index) {
|
|
const uint32_t typeToken = mono_metadata_make_token(MONO_TABLE_TYPEDEF, index);
|
|
MonoClass* monoClass = mono_class_get(image, typeToken);
|
|
if (!monoClass || !IsMonoBehaviourSubclass(monoClass)) {
|
|
continue;
|
|
}
|
|
|
|
if ((mono_class_get_flags(monoClass) & MONO_TYPE_ATTR_ABSTRACT) != 0) {
|
|
continue;
|
|
}
|
|
|
|
ClassMetadata metadata;
|
|
metadata.assemblyName = assemblyName;
|
|
metadata.namespaceName = SafeString(mono_class_get_namespace(monoClass));
|
|
metadata.className = SafeString(mono_class_get_name(monoClass));
|
|
metadata.fullName = BuildFullClassName(metadata.namespaceName, metadata.className);
|
|
metadata.monoClass = monoClass;
|
|
|
|
for (size_t methodIndex = 0; methodIndex < LifecycleMethodCount; ++methodIndex) {
|
|
metadata.lifecycleMethods[methodIndex] = mono_class_get_method_from_name(
|
|
monoClass,
|
|
ToLifecycleMethodName(static_cast<ScriptLifecycleMethod>(methodIndex)),
|
|
0);
|
|
}
|
|
|
|
for (size_t methodIndex = 0; methodIndex < PhysicsMessageCount; ++methodIndex) {
|
|
PhysicsMessageMethods& methods = metadata.physicsMessageMethods[methodIndex];
|
|
methods.withGameObject = mono_class_get_method_from_name(
|
|
monoClass,
|
|
ToPhysicsMessageMethodName(static_cast<ScriptPhysicsMessage>(methodIndex)),
|
|
1);
|
|
methods.withoutArgs = mono_class_get_method_from_name(
|
|
monoClass,
|
|
ToPhysicsMessageMethodName(static_cast<ScriptPhysicsMessage>(methodIndex)),
|
|
0);
|
|
}
|
|
|
|
void* fieldIterator = nullptr;
|
|
while (MonoClassField* field = mono_class_get_fields(monoClass, &fieldIterator)) {
|
|
const uint32_t fieldFlags = mono_field_get_flags(field);
|
|
if ((fieldFlags & MONO_FIELD_ATTR_STATIC) != 0
|
|
|| (fieldFlags & MONO_FIELD_ATTR_LITERAL) != 0
|
|
|| (fieldFlags & MONO_FIELD_ATTR_INIT_ONLY) != 0) {
|
|
continue;
|
|
}
|
|
|
|
const bool isPublicField = (fieldFlags & MONO_FIELD_ATTR_PUBLIC) != 0;
|
|
if (!isPublicField && !HasSerializeFieldAttribute(field)) {
|
|
continue;
|
|
}
|
|
|
|
FieldMetadata fieldMetadata = BuildFieldMetadata(field);
|
|
if (fieldMetadata.type == ScriptFieldType::None) {
|
|
continue;
|
|
}
|
|
|
|
metadata.fields.emplace(mono_field_get_name(field), std::move(fieldMetadata));
|
|
}
|
|
|
|
m_classes.emplace(
|
|
BuildClassKey(metadata.assemblyName, metadata.namespaceName, metadata.className),
|
|
std::move(metadata));
|
|
}
|
|
}
|
|
|
|
void MonoScriptRuntime::DiscoverRenderPipelineAssetClassesInImage(
|
|
const std::string& assemblyName,
|
|
MonoImage* image) {
|
|
if (!image || m_scriptableRenderPipelineAssetClass == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const int typeCount = mono_image_get_table_rows(image, MONO_TABLE_TYPEDEF);
|
|
for (int index = 1; index <= typeCount; ++index) {
|
|
const uint32_t typeToken =
|
|
mono_metadata_make_token(MONO_TABLE_TYPEDEF, index);
|
|
MonoClass* monoClass = mono_class_get(image, typeToken);
|
|
if (monoClass == nullptr ||
|
|
monoClass == m_scriptableRenderPipelineAssetClass ||
|
|
!IsMonoClassOrSubclass(
|
|
monoClass,
|
|
m_scriptableRenderPipelineAssetClass)) {
|
|
continue;
|
|
}
|
|
|
|
if ((mono_class_get_flags(monoClass) & MONO_TYPE_ATTR_ABSTRACT) != 0) {
|
|
continue;
|
|
}
|
|
|
|
const ScriptClassDescriptor descriptor{
|
|
assemblyName,
|
|
SafeString(mono_class_get_namespace(monoClass)),
|
|
SafeString(mono_class_get_name(monoClass))};
|
|
if (std::find(
|
|
m_renderPipelineAssetClasses.begin(),
|
|
m_renderPipelineAssetClasses.end(),
|
|
descriptor) == m_renderPipelineAssetClasses.end()) {
|
|
m_renderPipelineAssetClasses.push_back(descriptor);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool MonoScriptRuntime::IsMonoBehaviourSubclass(MonoClass* monoClass) const {
|
|
if (!monoClass || !m_monoBehaviourClass || monoClass == m_monoBehaviourClass) {
|
|
return false;
|
|
}
|
|
|
|
MonoClass* current = monoClass;
|
|
while (current) {
|
|
if (current == m_monoBehaviourClass) {
|
|
return true;
|
|
}
|
|
|
|
current = mono_class_get_parent(current);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool MonoScriptRuntime::IsSupportedComponentFieldClass(MonoClass* monoClass) const {
|
|
if (!IsMonoClassOrSubclass(monoClass, m_componentClass)) {
|
|
return false;
|
|
}
|
|
|
|
if (monoClass == m_componentClass || monoClass == m_behaviourClass || monoClass == m_monoBehaviourClass) {
|
|
return false;
|
|
}
|
|
|
|
if (IsScriptComponentFieldClass(monoClass)) {
|
|
return true;
|
|
}
|
|
|
|
const std::string namespaceName = SafeString(mono_class_get_namespace(monoClass));
|
|
const std::string className = SafeString(mono_class_get_name(monoClass));
|
|
if (namespaceName != m_settings.baseNamespace) {
|
|
return false;
|
|
}
|
|
|
|
return className == "Transform"
|
|
|| className == "Rigidbody"
|
|
|| className == "Camera"
|
|
|| className == "Light"
|
|
|| className == "MeshFilter"
|
|
|| className == "MeshRenderer";
|
|
}
|
|
|
|
bool MonoScriptRuntime::IsScriptComponentFieldClass(MonoClass* monoClass) const {
|
|
if (!monoClass || monoClass == m_monoBehaviourClass) {
|
|
return false;
|
|
}
|
|
|
|
return IsMonoClassOrSubclass(monoClass, m_monoBehaviourClass);
|
|
}
|
|
|
|
bool MonoScriptRuntime::HasSerializeFieldAttribute(MonoClassField* field) const {
|
|
if (!field || !m_serializeFieldAttributeClass) {
|
|
return false;
|
|
}
|
|
|
|
MonoClass* ownerClass = mono_field_get_parent(field);
|
|
if (!ownerClass) {
|
|
return false;
|
|
}
|
|
|
|
MonoCustomAttrInfo* attributes = mono_custom_attrs_from_field(ownerClass, field);
|
|
if (!attributes) {
|
|
return false;
|
|
}
|
|
|
|
const mono_bool hasAttribute = mono_custom_attrs_has_attr(attributes, m_serializeFieldAttributeClass);
|
|
mono_custom_attrs_free(attributes);
|
|
return hasAttribute != 0;
|
|
}
|
|
|
|
MonoScriptRuntime::FieldMetadata MonoScriptRuntime::BuildFieldMetadata(MonoClassField* field) const {
|
|
FieldMetadata metadata;
|
|
metadata.field = field;
|
|
if (!field) {
|
|
return metadata;
|
|
}
|
|
|
|
MonoType* monoType = mono_field_get_type(field);
|
|
if (!monoType) {
|
|
return metadata;
|
|
}
|
|
|
|
switch (mono_type_get_type(monoType)) {
|
|
case MONO_TYPE_R4:
|
|
metadata.type = ScriptFieldType::Float;
|
|
return metadata;
|
|
case MONO_TYPE_R8:
|
|
metadata.type = ScriptFieldType::Double;
|
|
return metadata;
|
|
case MONO_TYPE_BOOLEAN:
|
|
metadata.type = ScriptFieldType::Bool;
|
|
return metadata;
|
|
case MONO_TYPE_I4:
|
|
metadata.type = ScriptFieldType::Int32;
|
|
return metadata;
|
|
case MONO_TYPE_U8:
|
|
metadata.type = ScriptFieldType::UInt64;
|
|
return metadata;
|
|
case MONO_TYPE_STRING:
|
|
metadata.type = ScriptFieldType::String;
|
|
return metadata;
|
|
case MONO_TYPE_CLASS: {
|
|
MonoClass* referenceClass = mono_class_from_mono_type(monoType);
|
|
if (!referenceClass) {
|
|
return metadata;
|
|
}
|
|
|
|
const std::string namespaceName = SafeString(mono_class_get_namespace(referenceClass));
|
|
const std::string className = SafeString(mono_class_get_name(referenceClass));
|
|
if (namespaceName == m_settings.baseNamespace && className == "GameObject") {
|
|
metadata.type = ScriptFieldType::GameObject;
|
|
return metadata;
|
|
}
|
|
|
|
if (IsSupportedComponentFieldClass(referenceClass)) {
|
|
metadata.type = ScriptFieldType::Component;
|
|
metadata.componentClass = referenceClass;
|
|
}
|
|
|
|
return metadata;
|
|
}
|
|
case MONO_TYPE_VALUETYPE: {
|
|
MonoClass* valueTypeClass = mono_class_from_mono_type(monoType);
|
|
if (!valueTypeClass) {
|
|
return metadata;
|
|
}
|
|
|
|
if (mono_class_is_enum(valueTypeClass) != 0) {
|
|
MonoType* underlyingType = mono_class_enum_basetype(valueTypeClass);
|
|
if (!underlyingType) {
|
|
return metadata;
|
|
}
|
|
|
|
switch (mono_type_get_type(underlyingType)) {
|
|
case MONO_TYPE_I1:
|
|
case MONO_TYPE_U1:
|
|
case MONO_TYPE_I2:
|
|
case MONO_TYPE_U2:
|
|
case MONO_TYPE_I4:
|
|
case MONO_TYPE_U4:
|
|
metadata.type = ScriptFieldType::Int32;
|
|
metadata.isEnum = true;
|
|
metadata.enumUnderlyingType = static_cast<int32_t>(mono_type_get_type(underlyingType));
|
|
return metadata;
|
|
default:
|
|
return metadata;
|
|
}
|
|
}
|
|
|
|
const std::string namespaceName = SafeString(mono_class_get_namespace(valueTypeClass));
|
|
const std::string className = SafeString(mono_class_get_name(valueTypeClass));
|
|
if (namespaceName != m_settings.baseNamespace) {
|
|
return metadata;
|
|
}
|
|
|
|
if (className == "Vector2") {
|
|
metadata.type = ScriptFieldType::Vector2;
|
|
return metadata;
|
|
}
|
|
if (className == "Vector3") {
|
|
metadata.type = ScriptFieldType::Vector3;
|
|
return metadata;
|
|
}
|
|
if (className == "Vector4") {
|
|
metadata.type = ScriptFieldType::Vector4;
|
|
return metadata;
|
|
}
|
|
return metadata;
|
|
}
|
|
default:
|
|
return metadata;
|
|
}
|
|
}
|
|
|
|
const char* MonoScriptRuntime::ToLifecycleMethodName(ScriptLifecycleMethod method) {
|
|
switch (method) {
|
|
case ScriptLifecycleMethod::Awake: return "Awake";
|
|
case ScriptLifecycleMethod::OnEnable: return "OnEnable";
|
|
case ScriptLifecycleMethod::Start: return "Start";
|
|
case ScriptLifecycleMethod::FixedUpdate: return "FixedUpdate";
|
|
case ScriptLifecycleMethod::Update: return "Update";
|
|
case ScriptLifecycleMethod::LateUpdate: return "LateUpdate";
|
|
case ScriptLifecycleMethod::OnDisable: return "OnDisable";
|
|
case ScriptLifecycleMethod::OnDestroy: return "OnDestroy";
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
const char* MonoScriptRuntime::ToPhysicsMessageMethodName(ScriptPhysicsMessage message) {
|
|
switch (message) {
|
|
case ScriptPhysicsMessage::CollisionEnter: return "OnCollisionEnter";
|
|
case ScriptPhysicsMessage::CollisionStay: return "OnCollisionStay";
|
|
case ScriptPhysicsMessage::CollisionExit: return "OnCollisionExit";
|
|
case ScriptPhysicsMessage::TriggerEnter: return "OnTriggerEnter";
|
|
case ScriptPhysicsMessage::TriggerStay: return "OnTriggerStay";
|
|
case ScriptPhysicsMessage::TriggerExit: return "OnTriggerExit";
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
const MonoScriptRuntime::ClassMetadata* MonoScriptRuntime::FindClassMetadata(
|
|
const std::string& assemblyName,
|
|
const std::string& namespaceName,
|
|
const std::string& className) const {
|
|
const auto it = m_classes.find(BuildClassKey(assemblyName, namespaceName, className));
|
|
return it != m_classes.end() ? &it->second : nullptr;
|
|
}
|
|
|
|
bool MonoScriptRuntime::ResolveManagedClass(
|
|
const std::string& assemblyName,
|
|
const std::string& namespaceName,
|
|
const std::string& className,
|
|
MonoClass*& outClass) const {
|
|
outClass = nullptr;
|
|
if (!m_initialized || assemblyName.empty() || className.empty()) {
|
|
return false;
|
|
}
|
|
|
|
MonoImage* image = FindLoadedAssemblyImage(assemblyName);
|
|
if (!image) {
|
|
return false;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
outClass = mono_class_from_name(
|
|
image,
|
|
namespaceName.c_str(),
|
|
className.c_str());
|
|
return outClass != nullptr;
|
|
}
|
|
|
|
bool MonoScriptRuntime::CreateExternalManagedObject(
|
|
const std::string& assemblyName,
|
|
const std::string& namespaceName,
|
|
const std::string& className,
|
|
uint32_t& outHandle) {
|
|
outHandle = 0;
|
|
|
|
MonoClass* monoClass = nullptr;
|
|
if (!ResolveManagedClass(
|
|
assemblyName,
|
|
namespaceName,
|
|
className,
|
|
monoClass)) {
|
|
SetError(
|
|
"Managed class was not found: " +
|
|
assemblyName + "|" +
|
|
BuildFullClassName(namespaceName, className));
|
|
return false;
|
|
}
|
|
|
|
return CreateExternalManagedObject(monoClass, outHandle);
|
|
}
|
|
|
|
bool MonoScriptRuntime::CreateExternalManagedObject(
|
|
MonoClass* monoClass,
|
|
uint32_t& outHandle) {
|
|
outHandle = 0;
|
|
if (!m_initialized || !monoClass) {
|
|
return false;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoObject* const instance = mono_object_new(m_appDomain, monoClass);
|
|
if (!instance) {
|
|
SetError(
|
|
"Mono failed to allocate a managed object for " +
|
|
BuildFullClassName(
|
|
SafeString(mono_class_get_namespace(monoClass)),
|
|
SafeString(mono_class_get_name(monoClass))) + ".");
|
|
return false;
|
|
}
|
|
|
|
mono_runtime_object_init(instance);
|
|
outHandle = RetainExternalManagedObject(instance);
|
|
return outHandle != 0;
|
|
}
|
|
|
|
uint32_t MonoScriptRuntime::RetainExternalManagedObject(MonoObject* instance) {
|
|
if (!m_initialized || !instance) {
|
|
return 0;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
const uint32_t gcHandle = mono_gchandle_new(instance, false);
|
|
if (gcHandle == 0) {
|
|
return 0;
|
|
}
|
|
|
|
m_externalManagedObjects[gcHandle] = ExternalManagedObjectData{
|
|
mono_object_get_class(instance),
|
|
gcHandle
|
|
};
|
|
return gcHandle;
|
|
}
|
|
|
|
MonoObject* MonoScriptRuntime::GetExternalManagedObject(uint32_t gcHandle) const {
|
|
return GetManagedObject(gcHandle);
|
|
}
|
|
|
|
uint32_t MonoScriptRuntime::RetainExternalManagedObjectReference(
|
|
MonoObject* managedObject) {
|
|
return RetainExternalManagedObject(managedObject);
|
|
}
|
|
|
|
void MonoScriptRuntime::ReleaseExternalManagedObject(uint32_t gcHandle) {
|
|
DestroyExternalManagedObject(gcHandle);
|
|
}
|
|
|
|
bool MonoScriptRuntime::IsScriptableRenderPipelineAssetObject(
|
|
MonoObject* managedObject) const {
|
|
return managedObject != nullptr &&
|
|
m_scriptableRenderPipelineAssetClass != nullptr &&
|
|
IsMonoClassOrSubclass(
|
|
mono_object_get_class(managedObject),
|
|
m_scriptableRenderPipelineAssetClass);
|
|
}
|
|
|
|
bool MonoScriptRuntime::TryEnsureManagedRenderPipelineAssetHandle(
|
|
Rendering::Pipelines::ManagedRenderPipelineAssetDescriptor& ioDescriptor) {
|
|
if (!m_initialized || !ioDescriptor.IsValid()) {
|
|
return false;
|
|
}
|
|
|
|
if (ioDescriptor.managedAssetHandle != 0u) {
|
|
MonoObject* const assetObject =
|
|
GetExternalManagedObject(ioDescriptor.managedAssetHandle);
|
|
if (IsScriptableRenderPipelineAssetObject(assetObject)) {
|
|
return true;
|
|
}
|
|
|
|
ioDescriptor.managedAssetHandle = 0u;
|
|
}
|
|
|
|
MonoClass* assetClass = nullptr;
|
|
if (!ResolveManagedClass(
|
|
ioDescriptor.assemblyName,
|
|
ioDescriptor.namespaceName,
|
|
ioDescriptor.className,
|
|
assetClass) ||
|
|
assetClass == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsMonoClassOrSubclass(
|
|
assetClass,
|
|
m_scriptableRenderPipelineAssetClass)) {
|
|
SetError(
|
|
"Managed render pipeline asset must derive from ScriptableRenderPipelineAsset: " +
|
|
ioDescriptor.GetFullName() + ".");
|
|
return false;
|
|
}
|
|
|
|
return CreateExternalManagedObject(assetClass, ioDescriptor.managedAssetHandle) &&
|
|
ioDescriptor.managedAssetHandle != 0u;
|
|
}
|
|
|
|
void MonoScriptRuntime::DestroyExternalManagedObject(uint32_t gcHandle) {
|
|
if (gcHandle == 0) {
|
|
return;
|
|
}
|
|
|
|
const auto it = m_externalManagedObjects.find(gcHandle);
|
|
if (it == m_externalManagedObjects.end()) {
|
|
return;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
mono_gchandle_free(gcHandle);
|
|
m_externalManagedObjects.erase(it);
|
|
}
|
|
|
|
MonoObject* MonoScriptRuntime::CreateManagedScriptableRenderContext(
|
|
uint64_t nativeHandle) {
|
|
if (!m_initialized ||
|
|
nativeHandle == 0 ||
|
|
m_scriptableRenderContextClass == nullptr ||
|
|
m_scriptableRenderContextConstructor == nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoObject* const contextObject =
|
|
mono_object_new(m_appDomain, m_scriptableRenderContextClass);
|
|
if (contextObject == nullptr) {
|
|
SetError(
|
|
"Mono failed to allocate a managed ScriptableRenderContext.");
|
|
return nullptr;
|
|
}
|
|
|
|
void* args[1];
|
|
uint64_t nativeHandleArgument = nativeHandle;
|
|
args[0] = &nativeHandleArgument;
|
|
|
|
MonoObject* exception = nullptr;
|
|
mono_runtime_invoke(
|
|
m_scriptableRenderContextConstructor,
|
|
contextObject,
|
|
args,
|
|
&exception);
|
|
if (exception != nullptr) {
|
|
RecordException(exception);
|
|
return nullptr;
|
|
}
|
|
|
|
return contextObject;
|
|
}
|
|
|
|
MonoObject*
|
|
MonoScriptRuntime::CreateManagedCameraRenderRequestContext(
|
|
uint64_t nativeHandle) {
|
|
if (!m_initialized ||
|
|
nativeHandle == 0 ||
|
|
m_cameraRenderRequestContextClass == nullptr ||
|
|
m_cameraRenderRequestContextConstructor == nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoObject* const contextObject =
|
|
mono_object_new(
|
|
m_appDomain,
|
|
m_cameraRenderRequestContextClass);
|
|
if (contextObject == nullptr) {
|
|
SetError(
|
|
"Mono failed to allocate a managed CameraRenderRequestContext.");
|
|
return nullptr;
|
|
}
|
|
|
|
void* args[1];
|
|
uint64_t nativeHandleArgument = nativeHandle;
|
|
args[0] = &nativeHandleArgument;
|
|
|
|
MonoObject* exception = nullptr;
|
|
mono_runtime_invoke(
|
|
m_cameraRenderRequestContextConstructor,
|
|
contextObject,
|
|
args,
|
|
&exception);
|
|
if (exception != nullptr) {
|
|
RecordException(exception);
|
|
return nullptr;
|
|
}
|
|
|
|
return contextObject;
|
|
}
|
|
|
|
MonoObject*
|
|
MonoScriptRuntime::CreateManagedRenderSceneSetupContext(
|
|
uint64_t nativeHandle) {
|
|
if (!m_initialized ||
|
|
nativeHandle == 0 ||
|
|
m_renderSceneSetupContextClass == nullptr ||
|
|
m_renderSceneSetupContextConstructor == nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoObject* const contextObject =
|
|
mono_object_new(
|
|
m_appDomain,
|
|
m_renderSceneSetupContextClass);
|
|
if (contextObject == nullptr) {
|
|
SetError(
|
|
"Mono failed to allocate a managed RenderSceneSetupContext.");
|
|
return nullptr;
|
|
}
|
|
|
|
void* args[1];
|
|
uint64_t nativeHandleArgument = nativeHandle;
|
|
args[0] = &nativeHandleArgument;
|
|
|
|
MonoObject* exception = nullptr;
|
|
mono_runtime_invoke(
|
|
m_renderSceneSetupContextConstructor,
|
|
contextObject,
|
|
args,
|
|
&exception);
|
|
if (exception != nullptr) {
|
|
RecordException(exception);
|
|
return nullptr;
|
|
}
|
|
|
|
return contextObject;
|
|
}
|
|
|
|
MonoObject*
|
|
MonoScriptRuntime::CreateManagedDirectionalShadowExecutionContext(
|
|
uint64_t nativeHandle) {
|
|
if (!m_initialized ||
|
|
nativeHandle == 0 ||
|
|
m_directionalShadowExecutionContextClass == nullptr ||
|
|
m_directionalShadowExecutionContextConstructor == nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoObject* const contextObject =
|
|
mono_object_new(
|
|
m_appDomain,
|
|
m_directionalShadowExecutionContextClass);
|
|
if (contextObject == nullptr) {
|
|
SetError(
|
|
"Mono failed to allocate a managed DirectionalShadowExecutionContext.");
|
|
return nullptr;
|
|
}
|
|
|
|
void* args[1];
|
|
uint64_t nativeHandleArgument = nativeHandle;
|
|
args[0] = &nativeHandleArgument;
|
|
|
|
MonoObject* exception = nullptr;
|
|
mono_runtime_invoke(
|
|
m_directionalShadowExecutionContextConstructor,
|
|
contextObject,
|
|
args,
|
|
&exception);
|
|
if (exception != nullptr) {
|
|
RecordException(exception);
|
|
return nullptr;
|
|
}
|
|
|
|
return contextObject;
|
|
}
|
|
|
|
MonoObject*
|
|
MonoScriptRuntime::CreateManagedScriptableRenderPipelinePlanningContext(
|
|
uint64_t nativeHandle) {
|
|
if (!m_initialized ||
|
|
nativeHandle == 0 ||
|
|
m_scriptableRenderPipelinePlanningContextClass == nullptr ||
|
|
m_scriptableRenderPipelinePlanningContextConstructor == nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoObject* const contextObject =
|
|
mono_object_new(
|
|
m_appDomain,
|
|
m_scriptableRenderPipelinePlanningContextClass);
|
|
if (contextObject == nullptr) {
|
|
SetError(
|
|
"Mono failed to allocate a managed ScriptableRenderPipelinePlanningContext.");
|
|
return nullptr;
|
|
}
|
|
|
|
void* args[1];
|
|
uint64_t nativeHandleArgument = nativeHandle;
|
|
args[0] = &nativeHandleArgument;
|
|
|
|
MonoObject* exception = nullptr;
|
|
mono_runtime_invoke(
|
|
m_scriptableRenderPipelinePlanningContextConstructor,
|
|
contextObject,
|
|
args,
|
|
&exception);
|
|
if (exception != nullptr) {
|
|
RecordException(exception);
|
|
return nullptr;
|
|
}
|
|
|
|
return contextObject;
|
|
}
|
|
|
|
MonoScriptRuntime::InstanceData* MonoScriptRuntime::FindInstance(const ScriptRuntimeContext& context) {
|
|
const auto it = m_instances.find(InstanceKey{context.gameObjectUUID, context.scriptComponentUUID});
|
|
return it != m_instances.end() ? &it->second : nullptr;
|
|
}
|
|
|
|
const MonoScriptRuntime::InstanceData* MonoScriptRuntime::FindInstance(const ScriptRuntimeContext& context) const {
|
|
const auto it = m_instances.find(InstanceKey{context.gameObjectUUID, context.scriptComponentUUID});
|
|
return it != m_instances.end() ? &it->second : nullptr;
|
|
}
|
|
|
|
const MonoScriptRuntime::InstanceData* MonoScriptRuntime::FindInstance(const ScriptComponent* component) const {
|
|
if (!component || !component->GetGameObject()) {
|
|
return nullptr;
|
|
}
|
|
|
|
const auto it = m_instances.find(InstanceKey{
|
|
component->GetGameObject()->GetUUID(),
|
|
component->GetScriptComponentUUID()
|
|
});
|
|
return it != m_instances.end() ? &it->second : nullptr;
|
|
}
|
|
|
|
MonoObject* MonoScriptRuntime::GetManagedObject(const InstanceData& instanceData) const {
|
|
if (instanceData.gcHandle == 0) {
|
|
return nullptr;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
return mono_gchandle_get_target(instanceData.gcHandle);
|
|
}
|
|
|
|
MonoObject* MonoScriptRuntime::GetManagedObject(uint32_t gcHandle) const {
|
|
if (gcHandle == 0 ||
|
|
m_externalManagedObjects.find(gcHandle) == m_externalManagedObjects.end()) {
|
|
return nullptr;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
return mono_gchandle_get_target(gcHandle);
|
|
}
|
|
|
|
MonoMethod* MonoScriptRuntime::ResolveManagedMethod(
|
|
MonoClass* monoClass,
|
|
const char* methodName,
|
|
int parameterCount) const {
|
|
if (!monoClass || !methodName) {
|
|
return nullptr;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
for (MonoClass* currentClass = monoClass;
|
|
currentClass != nullptr;
|
|
currentClass = mono_class_get_parent(currentClass)) {
|
|
if (MonoMethod* const method =
|
|
mono_class_get_method_from_name(
|
|
currentClass,
|
|
methodName,
|
|
parameterCount);
|
|
method != nullptr) {
|
|
return method;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
MonoMethod* MonoScriptRuntime::ResolveManagedMethod(
|
|
MonoObject* instance,
|
|
const char* methodName,
|
|
int parameterCount) const {
|
|
return instance != nullptr
|
|
? ResolveManagedMethod(
|
|
mono_object_get_class(instance),
|
|
methodName,
|
|
parameterCount)
|
|
: nullptr;
|
|
}
|
|
|
|
bool MonoScriptRuntime::ApplyContextFields(const ScriptRuntimeContext& context, MonoObject* instance) {
|
|
if (!instance) {
|
|
return false;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
if (m_gameObjectUUIDField) {
|
|
uint64_t gameObjectUUID = context.gameObjectUUID;
|
|
mono_field_set_value(instance, m_gameObjectUUIDField, &gameObjectUUID);
|
|
}
|
|
|
|
if (m_scriptComponentUUIDField) {
|
|
uint64_t scriptComponentUUID = context.scriptComponentUUID;
|
|
mono_field_set_value(instance, m_scriptComponentUUIDField, &scriptComponentUUID);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool MonoScriptRuntime::ApplyStoredFields(
|
|
const ScriptRuntimeContext& context,
|
|
const ClassMetadata& metadata,
|
|
MonoObject* instance) {
|
|
if (!context.component || !instance) {
|
|
return false;
|
|
}
|
|
|
|
const ScriptFieldStorage& fieldStorage = context.component->GetFieldStorage();
|
|
for (const std::string& fieldName : fieldStorage.GetFieldNames()) {
|
|
const StoredScriptField* storedField = fieldStorage.FindField(fieldName);
|
|
if (!storedField) {
|
|
continue;
|
|
}
|
|
|
|
const auto metadataIt = metadata.fields.find(fieldName);
|
|
if (metadataIt == metadata.fields.end() || storedField->type != metadataIt->second.type) {
|
|
continue;
|
|
}
|
|
|
|
if (!TrySetFieldValue(instance, metadataIt->second, storedField->value)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
MonoObject* MonoScriptRuntime::CreateManagedComponentWrapper(MonoClass* componentClass, uint64_t gameObjectUUID) {
|
|
if (!m_initialized || !componentClass || gameObjectUUID == 0) {
|
|
return nullptr;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoMethod* constructor = mono_class_get_method_from_name(componentClass, ".ctor", 1);
|
|
if (!constructor) {
|
|
return nullptr;
|
|
}
|
|
|
|
MonoObject* managedObject = mono_object_new(m_appDomain, componentClass);
|
|
if (!managedObject) {
|
|
return nullptr;
|
|
}
|
|
|
|
void* args[1];
|
|
uint64_t uuidArgument = gameObjectUUID;
|
|
args[0] = &uuidArgument;
|
|
|
|
MonoObject* exception = nullptr;
|
|
mono_runtime_invoke(constructor, managedObject, args, &exception);
|
|
if (exception) {
|
|
RecordException(exception);
|
|
return nullptr;
|
|
}
|
|
|
|
return managedObject;
|
|
}
|
|
|
|
MonoObject* MonoScriptRuntime::CreateManagedGameObject(uint64_t gameObjectUUID) {
|
|
if (gameObjectUUID == 0 || !m_gameObjectClass || !m_gameObjectConstructor) {
|
|
return nullptr;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoObject* managedObject = mono_object_new(m_appDomain, m_gameObjectClass);
|
|
if (!managedObject) {
|
|
return nullptr;
|
|
}
|
|
|
|
void* args[1];
|
|
uint64_t uuidArgument = gameObjectUUID;
|
|
args[0] = &uuidArgument;
|
|
|
|
MonoObject* exception = nullptr;
|
|
mono_runtime_invoke(m_gameObjectConstructor, managedObject, args, &exception);
|
|
if (exception) {
|
|
RecordException(exception);
|
|
return nullptr;
|
|
}
|
|
|
|
return managedObject;
|
|
}
|
|
|
|
bool MonoScriptRuntime::TryExtractComponentReference(
|
|
MonoObject* managedObject,
|
|
ComponentReference& outReference) const {
|
|
outReference = ComponentReference{};
|
|
if (!managedObject) {
|
|
return true;
|
|
}
|
|
|
|
if (!m_componentClass || !m_gameObjectUUIDField) {
|
|
return false;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoClass* monoClass = mono_object_get_class(managedObject);
|
|
if (!IsMonoClassOrSubclass(monoClass, m_componentClass)) {
|
|
return false;
|
|
}
|
|
|
|
uint64_t gameObjectUUID = 0;
|
|
mono_field_get_value(managedObject, m_gameObjectUUIDField, &gameObjectUUID);
|
|
if (gameObjectUUID == 0) {
|
|
return false;
|
|
}
|
|
|
|
uint64_t scriptComponentUUID = 0;
|
|
if (m_scriptComponentUUIDField && IsMonoClassOrSubclass(monoClass, m_behaviourClass)) {
|
|
mono_field_get_value(managedObject, m_scriptComponentUUIDField, &scriptComponentUUID);
|
|
}
|
|
|
|
outReference = ComponentReference{gameObjectUUID, scriptComponentUUID};
|
|
return true;
|
|
}
|
|
|
|
bool MonoScriptRuntime::DestroyManagedObject(MonoObject* managedObject) {
|
|
if (!m_initialized || !managedObject) {
|
|
return false;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoClass* monoClass = mono_object_get_class(managedObject);
|
|
if (!monoClass) {
|
|
return false;
|
|
}
|
|
|
|
if (monoClass == m_gameObjectClass) {
|
|
uint64_t gameObjectUUID = 0;
|
|
mono_field_get_value(managedObject, m_managedGameObjectUUIDField, &gameObjectUUID);
|
|
|
|
Components::Scene* scene = GetInternalCallScene();
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!scene || !gameObject || gameObject->GetScene() != scene) {
|
|
return false;
|
|
}
|
|
|
|
scene->DestroyGameObject(gameObject);
|
|
return true;
|
|
}
|
|
|
|
if (monoClass != m_componentClass && !mono_class_is_subclass_of(monoClass, m_componentClass, false)) {
|
|
return false;
|
|
}
|
|
|
|
uint64_t gameObjectUUID = 0;
|
|
mono_field_get_value(managedObject, m_gameObjectUUIDField, &gameObjectUUID);
|
|
|
|
Components::GameObject* gameObject = FindGameObjectByUUID(gameObjectUUID);
|
|
if (!gameObject) {
|
|
return false;
|
|
}
|
|
|
|
if (monoClass == m_behaviourClass || mono_class_is_subclass_of(monoClass, m_behaviourClass, false)) {
|
|
uint64_t scriptComponentUUID = 0;
|
|
mono_field_get_value(managedObject, m_scriptComponentUUIDField, &scriptComponentUUID);
|
|
|
|
if (scriptComponentUUID != 0) {
|
|
ScriptComponent* component = FindScriptComponentByUUID(scriptComponentUUID);
|
|
return DestroyNativeComponentInstance(gameObject, component);
|
|
}
|
|
}
|
|
|
|
const ManagedComponentTypeInfo typeInfo = ResolveManagedComponentTypeInfo(monoClass);
|
|
switch (typeInfo.kind) {
|
|
case ManagedComponentKind::Rigidbody:
|
|
return DestroyNativeComponentInstance(gameObject, gameObject->GetComponent<Components::RigidbodyComponent>());
|
|
case ManagedComponentKind::Camera:
|
|
return DestroyNativeComponentInstance(gameObject, gameObject->GetComponent<Components::CameraComponent>());
|
|
case ManagedComponentKind::Light:
|
|
return DestroyNativeComponentInstance(gameObject, gameObject->GetComponent<Components::LightComponent>());
|
|
case ManagedComponentKind::MeshFilter:
|
|
return DestroyNativeComponentInstance(gameObject, gameObject->GetComponent<Components::MeshFilterComponent>());
|
|
case ManagedComponentKind::MeshRenderer:
|
|
return DestroyNativeComponentInstance(gameObject, gameObject->GetComponent<Components::MeshRendererComponent>());
|
|
case ManagedComponentKind::Transform:
|
|
case ManagedComponentKind::Script:
|
|
case ManagedComponentKind::Unknown:
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool MonoScriptRuntime::TryExtractGameObjectReference(
|
|
MonoObject* managedObject,
|
|
GameObjectReference& outReference) const {
|
|
outReference = GameObjectReference{};
|
|
if (!managedObject) {
|
|
return true;
|
|
}
|
|
|
|
if (!m_gameObjectClass || !m_managedGameObjectUUIDField) {
|
|
return false;
|
|
}
|
|
|
|
if (mono_object_get_class(managedObject) != m_gameObjectClass) {
|
|
return false;
|
|
}
|
|
|
|
uint64_t gameObjectUUID = 0;
|
|
mono_field_get_value(managedObject, m_managedGameObjectUUIDField, &gameObjectUUID);
|
|
outReference = GameObjectReference{gameObjectUUID};
|
|
return true;
|
|
}
|
|
|
|
bool MonoScriptRuntime::TrySetFieldValue(
|
|
MonoObject* instance,
|
|
const FieldMetadata& fieldMetadata,
|
|
const ScriptFieldValue& value) {
|
|
if (!instance || !fieldMetadata.field) {
|
|
return false;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
if (fieldMetadata.isEnum) {
|
|
if (!std::holds_alternative<int32_t>(value)) {
|
|
return false;
|
|
}
|
|
|
|
const int32_t storedValue = std::get<int32_t>(value);
|
|
switch (fieldMetadata.enumUnderlyingType) {
|
|
case MONO_TYPE_I1: {
|
|
if (storedValue < std::numeric_limits<int8_t>::min()
|
|
|| storedValue > std::numeric_limits<int8_t>::max()) {
|
|
return false;
|
|
}
|
|
|
|
int8_t nativeValue = static_cast<int8_t>(storedValue);
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case MONO_TYPE_U1: {
|
|
if (storedValue < 0 || storedValue > std::numeric_limits<uint8_t>::max()) {
|
|
return false;
|
|
}
|
|
|
|
uint8_t nativeValue = static_cast<uint8_t>(storedValue);
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case MONO_TYPE_I2: {
|
|
if (storedValue < std::numeric_limits<int16_t>::min()
|
|
|| storedValue > std::numeric_limits<int16_t>::max()) {
|
|
return false;
|
|
}
|
|
|
|
int16_t nativeValue = static_cast<int16_t>(storedValue);
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case MONO_TYPE_U2: {
|
|
if (storedValue < 0 || storedValue > std::numeric_limits<uint16_t>::max()) {
|
|
return false;
|
|
}
|
|
|
|
uint16_t nativeValue = static_cast<uint16_t>(storedValue);
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case MONO_TYPE_I4: {
|
|
int32_t nativeValue = storedValue;
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case MONO_TYPE_U4: {
|
|
if (storedValue < 0) {
|
|
return false;
|
|
}
|
|
|
|
uint32_t nativeValue = static_cast<uint32_t>(storedValue);
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
switch (fieldMetadata.type) {
|
|
case ScriptFieldType::Float: {
|
|
float nativeValue = std::get<float>(value);
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Double: {
|
|
double nativeValue = std::get<double>(value);
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Bool: {
|
|
mono_bool nativeValue = std::get<bool>(value) ? 1 : 0;
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Int32: {
|
|
int32_t nativeValue = std::get<int32_t>(value);
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case ScriptFieldType::UInt64: {
|
|
uint64_t nativeValue = std::get<uint64_t>(value);
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case ScriptFieldType::String: {
|
|
MonoString* managedString = mono_string_new(m_appDomain, std::get<std::string>(value).c_str());
|
|
mono_field_set_value(instance, fieldMetadata.field, managedString);
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Vector2: {
|
|
Math::Vector2 nativeValue = std::get<Math::Vector2>(value);
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Vector3: {
|
|
Math::Vector3 nativeValue = std::get<Math::Vector3>(value);
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Vector4: {
|
|
Math::Vector4 nativeValue = std::get<Math::Vector4>(value);
|
|
mono_field_set_value(instance, fieldMetadata.field, &nativeValue);
|
|
return true;
|
|
}
|
|
case ScriptFieldType::GameObject: {
|
|
const GameObjectReference reference = std::get<GameObjectReference>(value);
|
|
MonoObject* managedGameObject = CreateManagedGameObject(reference.gameObjectUUID);
|
|
if (reference.gameObjectUUID != 0 && !managedGameObject) {
|
|
return false;
|
|
}
|
|
mono_field_set_value(instance, fieldMetadata.field, managedGameObject);
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Component: {
|
|
const ComponentReference reference = std::get<ComponentReference>(value);
|
|
if (reference.gameObjectUUID == 0 && reference.scriptComponentUUID == 0) {
|
|
mono_field_set_value(instance, fieldMetadata.field, nullptr);
|
|
return true;
|
|
}
|
|
|
|
if (!fieldMetadata.componentClass) {
|
|
return false;
|
|
}
|
|
|
|
MonoObject* managedComponent = nullptr;
|
|
if (IsScriptComponentFieldClass(fieldMetadata.componentClass)) {
|
|
if (reference.gameObjectUUID == 0 || reference.scriptComponentUUID == 0) {
|
|
return false;
|
|
}
|
|
|
|
ScriptComponent* component = FindScriptComponentByUUID(reference.scriptComponentUUID);
|
|
if (!component
|
|
|| !component->GetGameObject()
|
|
|| component->GetGameObject()->GetUUID() != reference.gameObjectUUID
|
|
|| component->GetAssemblyName() != m_settings.appAssemblyName
|
|
|| component->GetNamespaceName() != SafeString(mono_class_get_namespace(fieldMetadata.componentClass))
|
|
|| component->GetClassName() != SafeString(mono_class_get_name(fieldMetadata.componentClass))) {
|
|
return false;
|
|
}
|
|
|
|
if (!HasManagedInstance(component)) {
|
|
ScriptEngine::Get().OnScriptComponentEnabled(component);
|
|
}
|
|
|
|
managedComponent = GetManagedInstanceObject(component);
|
|
if (!managedComponent) {
|
|
return false;
|
|
}
|
|
} else {
|
|
if (reference.gameObjectUUID == 0 || reference.scriptComponentUUID != 0) {
|
|
return false;
|
|
}
|
|
|
|
Components::GameObject* targetObject = FindGameObjectByUUID(reference.gameObjectUUID);
|
|
if (!targetObject) {
|
|
return false;
|
|
}
|
|
|
|
const std::string namespaceName = SafeString(mono_class_get_namespace(fieldMetadata.componentClass));
|
|
const std::string className = SafeString(mono_class_get_name(fieldMetadata.componentClass));
|
|
if (namespaceName != m_settings.baseNamespace) {
|
|
return false;
|
|
}
|
|
|
|
bool hasComponent = false;
|
|
if (className == "Transform") {
|
|
hasComponent = targetObject->GetTransform() != nullptr;
|
|
} else if (className == "Rigidbody") {
|
|
hasComponent = targetObject->GetComponent<Components::RigidbodyComponent>() != nullptr;
|
|
} else if (className == "Camera") {
|
|
hasComponent = targetObject->GetComponent<Components::CameraComponent>() != nullptr;
|
|
} else if (className == "Light") {
|
|
hasComponent = targetObject->GetComponent<Components::LightComponent>() != nullptr;
|
|
} else if (className == "MeshFilter") {
|
|
hasComponent = targetObject->GetComponent<Components::MeshFilterComponent>() != nullptr;
|
|
} else if (className == "MeshRenderer") {
|
|
hasComponent = targetObject->GetComponent<Components::MeshRendererComponent>() != nullptr;
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
if (!hasComponent) {
|
|
return false;
|
|
}
|
|
|
|
managedComponent = CreateManagedComponentWrapper(fieldMetadata.componentClass, reference.gameObjectUUID);
|
|
if (!managedComponent) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
mono_field_set_value(instance, fieldMetadata.field, managedComponent);
|
|
return true;
|
|
}
|
|
case ScriptFieldType::None:
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool MonoScriptRuntime::TryReadFieldValue(
|
|
MonoObject* instance,
|
|
const FieldMetadata& fieldMetadata,
|
|
ScriptFieldValue& outValue) const {
|
|
if (!instance || !fieldMetadata.field) {
|
|
return false;
|
|
}
|
|
|
|
if (fieldMetadata.isEnum) {
|
|
switch (fieldMetadata.enumUnderlyingType) {
|
|
case MONO_TYPE_I1: {
|
|
int8_t nativeValue = 0;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = static_cast<int32_t>(nativeValue);
|
|
return true;
|
|
}
|
|
case MONO_TYPE_U1: {
|
|
uint8_t nativeValue = 0;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = static_cast<int32_t>(nativeValue);
|
|
return true;
|
|
}
|
|
case MONO_TYPE_I2: {
|
|
int16_t nativeValue = 0;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = static_cast<int32_t>(nativeValue);
|
|
return true;
|
|
}
|
|
case MONO_TYPE_U2: {
|
|
uint16_t nativeValue = 0;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = static_cast<int32_t>(nativeValue);
|
|
return true;
|
|
}
|
|
case MONO_TYPE_I4: {
|
|
int32_t nativeValue = 0;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = nativeValue;
|
|
return true;
|
|
}
|
|
case MONO_TYPE_U4: {
|
|
uint32_t nativeValue = 0;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
if (nativeValue > static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) {
|
|
return false;
|
|
}
|
|
|
|
outValue = static_cast<int32_t>(nativeValue);
|
|
return true;
|
|
}
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
switch (fieldMetadata.type) {
|
|
case ScriptFieldType::Float: {
|
|
float nativeValue = 0.0f;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = nativeValue;
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Double: {
|
|
double nativeValue = 0.0;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = nativeValue;
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Bool: {
|
|
mono_bool nativeValue = 0;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = (nativeValue != 0);
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Int32: {
|
|
int32_t nativeValue = 0;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = nativeValue;
|
|
return true;
|
|
}
|
|
case ScriptFieldType::UInt64: {
|
|
uint64_t nativeValue = 0;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = nativeValue;
|
|
return true;
|
|
}
|
|
case ScriptFieldType::String: {
|
|
MonoObject* managedObject = mono_field_get_value_object(m_appDomain, fieldMetadata.field, instance);
|
|
if (!managedObject) {
|
|
outValue = std::string();
|
|
return true;
|
|
}
|
|
|
|
MonoString* managedString = reinterpret_cast<MonoString*>(managedObject);
|
|
char* utf8 = mono_string_to_utf8(managedString);
|
|
outValue = utf8 ? std::string(utf8) : std::string();
|
|
if (utf8) {
|
|
mono_free(utf8);
|
|
}
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Vector2: {
|
|
Math::Vector2 nativeValue;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = nativeValue;
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Vector3: {
|
|
Math::Vector3 nativeValue;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = nativeValue;
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Vector4: {
|
|
Math::Vector4 nativeValue;
|
|
mono_field_get_value(instance, fieldMetadata.field, &nativeValue);
|
|
outValue = nativeValue;
|
|
return true;
|
|
}
|
|
case ScriptFieldType::GameObject: {
|
|
MonoObject* managedObject = mono_field_get_value_object(m_appDomain, fieldMetadata.field, instance);
|
|
GameObjectReference reference;
|
|
if (!TryExtractGameObjectReference(managedObject, reference)) {
|
|
return false;
|
|
}
|
|
|
|
outValue = reference;
|
|
return true;
|
|
}
|
|
case ScriptFieldType::Component: {
|
|
MonoObject* managedObject = mono_field_get_value_object(m_appDomain, fieldMetadata.field, instance);
|
|
ComponentReference reference;
|
|
if (!TryExtractComponentReference(managedObject, reference)) {
|
|
return false;
|
|
}
|
|
|
|
outValue = reference;
|
|
return true;
|
|
}
|
|
case ScriptFieldType::None:
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void MonoScriptRuntime::ClearManagedInstances() {
|
|
for (auto& [key, instanceData] : m_instances) {
|
|
(void)key;
|
|
if (instanceData.gcHandle != 0) {
|
|
mono_gchandle_free(instanceData.gcHandle);
|
|
}
|
|
}
|
|
|
|
m_instances.clear();
|
|
}
|
|
|
|
void MonoScriptRuntime::ClearExternalManagedObjects() {
|
|
for (auto& [gcHandle, objectData] : m_externalManagedObjects) {
|
|
(void)objectData;
|
|
if (gcHandle != 0) {
|
|
mono_gchandle_free(gcHandle);
|
|
}
|
|
}
|
|
|
|
m_externalManagedObjects.clear();
|
|
}
|
|
|
|
void MonoScriptRuntime::ClearClassCache() {
|
|
m_classes.clear();
|
|
m_renderPipelineAssetClasses.clear();
|
|
}
|
|
|
|
MonoImage* MonoScriptRuntime::FindLoadedAssemblyImage(
|
|
const std::string& assemblyName) const {
|
|
const auto it = m_loadedManagedAssemblies.find(assemblyName);
|
|
return it != m_loadedManagedAssemblies.end()
|
|
? it->second.image
|
|
: nullptr;
|
|
}
|
|
|
|
bool MonoScriptRuntime::InvokeManagedMethod(
|
|
MonoObject* instance,
|
|
MonoMethod* method,
|
|
void** args,
|
|
MonoObject** outReturnValue) {
|
|
if (!instance || !method) {
|
|
if (outReturnValue) {
|
|
*outReturnValue = nullptr;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
SetCurrentDomain();
|
|
|
|
MonoObject* exception = nullptr;
|
|
MonoObject* returnValue = mono_runtime_invoke(method, instance, args, &exception);
|
|
if (exception) {
|
|
if (outReturnValue) {
|
|
*outReturnValue = nullptr;
|
|
}
|
|
RecordException(exception);
|
|
return false;
|
|
}
|
|
|
|
if (outReturnValue) {
|
|
*outReturnValue = returnValue;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void MonoScriptRuntime::RecordException(MonoObject* exception) {
|
|
m_lastError = "Managed exception";
|
|
if (!exception) {
|
|
return;
|
|
}
|
|
|
|
MonoObject* secondaryException = nullptr;
|
|
MonoString* exceptionString = mono_object_to_string(exception, &secondaryException);
|
|
if (!exceptionString || secondaryException) {
|
|
return;
|
|
}
|
|
|
|
char* utf8 = mono_string_to_utf8(exceptionString);
|
|
if (!utf8) {
|
|
return;
|
|
}
|
|
|
|
m_lastError = utf8;
|
|
mono_free(utf8);
|
|
}
|
|
|
|
void MonoScriptRuntime::SetError(const std::string& error) {
|
|
m_lastError = error;
|
|
}
|
|
|
|
} // namespace Scripting
|
|
} // namespace XCEngine
|