mirror of https://github.com/AxioDL/metaforce.git
Merge branch 'shader-refactor'
This commit is contained in:
commit
486c925a45
|
@ -130,6 +130,13 @@ else()
|
||||||
message(STATUS "Building with x87 Vector ISA")
|
message(STATUS "Building with x87 Vector ISA")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
check_cxx_compiler_flag(-fno-plt HAS_NO_PLT)
|
||||||
|
if (HAS_NO_PLT)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-plt")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-plt")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(URDE_MSAN)
|
if(URDE_MSAN)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
|
||||||
-stdlib=libc++ -fsanitize=memory -fsanitize-memory-track-origins -fsanitize-recover=all")
|
-stdlib=libc++ -fsanitize=memory -fsanitize-memory-track-origins -fsanitize-recover=all")
|
||||||
|
@ -138,7 +145,7 @@ else()
|
||||||
endif()
|
endif()
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-multichar -Werror=implicit-fallthrough \
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-multichar -Werror=implicit-fallthrough \
|
||||||
-Wno-unknown-warning-option -Wno-lto-type-mismatch -Wno-unused-variable -Wno-unused-private-field \
|
-Wno-unknown-warning-option -Wno-lto-type-mismatch -Wno-unused-variable -Wno-unused-private-field \
|
||||||
-fno-exceptions -fno-rtti -Werror")
|
-Wno-unused-function -fno-exceptions -fno-rtti -Werror")
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=deprecated-declarations")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=deprecated-declarations")
|
||||||
|
@ -194,6 +201,8 @@ set(HECL_DLPACKAGE ${URDE_DLPACKAGE})
|
||||||
set(BOO_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/hecl/extern/boo/include)
|
set(BOO_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/hecl/extern/boo/include)
|
||||||
set(HECL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/hecl/include
|
set(HECL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/hecl/include
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/hecl/blender)
|
${CMAKE_CURRENT_SOURCE_DIR}/hecl/blender)
|
||||||
|
set(SPECTER_INCLUDE_DIR specter/include specter/freetype2/include)
|
||||||
|
set(ZEUS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/specter/zeus/include)
|
||||||
|
|
||||||
set(DATA_SPEC_LIBS RetroDataSpec amuse)
|
set(DATA_SPEC_LIBS RetroDataSpec amuse)
|
||||||
set(HECL_DATASPEC_DECLS
|
set(HECL_DATASPEC_DECLS
|
||||||
|
@ -222,6 +231,9 @@ set(HECL_DATASPEC_PUSHES
|
||||||
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3);
|
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3);
|
||||||
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3PC);
|
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3PC);
|
||||||
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3ORIG);")
|
hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3ORIG);")
|
||||||
|
add_definitions(-DZE_ATHENA_TYPES=1)
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${SPECTER_INCLUDE_DIR} ${NOD_INCLUDE_DIR}
|
||||||
|
${ZEUS_INCLUDE_DIR})
|
||||||
add_subdirectory(hecl/shaderc)
|
add_subdirectory(hecl/shaderc)
|
||||||
include(hecl/ApplicationTools.cmake)
|
include(hecl/ApplicationTools.cmake)
|
||||||
add_subdirectory(specter/shaders)
|
add_subdirectory(specter/shaders)
|
||||||
|
@ -233,6 +245,20 @@ if(NOT TARGET bintoc)
|
||||||
find_package(hecl-bintoc REQUIRED)
|
find_package(hecl-bintoc REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
bintoc(CModelShaders.common.glsl.cpp Shaders/CModelShaders.common.glsl CMODELSHADERS_COMMON_GLSL)
|
||||||
|
bintoc(CModelShaders.vert.glsl.cpp Shaders/CModelShaders.vert.glsl CMODELSHADERS_VERT_GLSL)
|
||||||
|
bintoc(CModelShaders.frag.glsl.cpp Shaders/CModelShaders.frag.glsl CMODELSHADERS_FRAG_GLSL)
|
||||||
|
bintoc(CModelShaders.common.hlsl.cpp Shaders/CModelShaders.common.hlsl CMODELSHADERS_COMMON_HLSL)
|
||||||
|
bintoc(CModelShaders.vert.hlsl.cpp Shaders/CModelShaders.vert.hlsl CMODELSHADERS_VERT_HLSL)
|
||||||
|
bintoc(CModelShaders.frag.hlsl.cpp Shaders/CModelShaders.frag.hlsl CMODELSHADERS_FRAG_HLSL)
|
||||||
|
bintoc(CModelShaders.common.metal.cpp Shaders/CModelShaders.common.metal CMODELSHADERS_COMMON_METAL)
|
||||||
|
bintoc(CModelShaders.vert.metal.cpp Shaders/CModelShaders.vert.metal CMODELSHADERS_VERT_METAL)
|
||||||
|
bintoc(CModelShaders.frag.metal.cpp Shaders/CModelShaders.frag.metal CMODELSHADERS_FRAG_METAL)
|
||||||
|
add_library(CModelShaders
|
||||||
|
CModelShaders.common.glsl.cpp CModelShaders.vert.glsl.cpp CModelShaders.frag.glsl.cpp
|
||||||
|
CModelShaders.common.hlsl.cpp CModelShaders.vert.hlsl.cpp CModelShaders.frag.hlsl.cpp
|
||||||
|
CModelShaders.common.metal.cpp CModelShaders.vert.metal.cpp CModelShaders.frag.metal.cpp)
|
||||||
|
|
||||||
if(NOT TARGET atdna)
|
if(NOT TARGET atdna)
|
||||||
# Import native atdna if cross-compiling
|
# Import native atdna if cross-compiling
|
||||||
find_package(atdna REQUIRED)
|
find_package(atdna REQUIRED)
|
||||||
|
@ -245,14 +271,11 @@ add_definitions(${BOO_SYS_DEFINES})
|
||||||
include_directories(${BOO_SYS_INCLUDES})
|
include_directories(${BOO_SYS_INCLUDES})
|
||||||
add_subdirectory(amuse)
|
add_subdirectory(amuse)
|
||||||
add_subdirectory(specter)
|
add_subdirectory(specter)
|
||||||
set(SPECTER_INCLUDE_DIR specter/include specter/freetype2/include)
|
|
||||||
add_subdirectory(assetnameparser)
|
add_subdirectory(assetnameparser)
|
||||||
add_definitions(-DZE_ATHENA_TYPES=1)
|
|
||||||
set(ZEUS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/specter/zeus/include)
|
|
||||||
include_directories(${ATHENA_INCLUDE_DIR} ${LOGVISOR_INCLUDE_DIR} ${HECL_INCLUDE_DIR}
|
include_directories(${ATHENA_INCLUDE_DIR} ${LOGVISOR_INCLUDE_DIR} ${HECL_INCLUDE_DIR}
|
||||||
${NOD_INCLUDE_DIR} ${ZEUS_INCLUDE_DIR} ${BOO_INCLUDE_DIR} ${AMUSE_INCLUDE_DIR}
|
${BOO_INCLUDE_DIR} ${AMUSE_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/NESEmulator
|
||||||
${SPECTER_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
|
${ZLIB_INCLUDE_DIR})
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/NESEmulator)
|
add_definitions(-DURDE_ZIP_INPUT_STREAM=1) # Enable CZipInputStream now that zlib header is known
|
||||||
add_subdirectory(NESEmulator)
|
add_subdirectory(NESEmulator)
|
||||||
add_subdirectory(DataSpec)
|
add_subdirectory(DataSpec)
|
||||||
add_subdirectory(kabufuda)
|
add_subdirectory(kabufuda)
|
||||||
|
|
|
@ -2,6 +2,661 @@
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
|
# Root Eevee Nodes
|
||||||
|
|
||||||
|
#0 - RetroShader
|
||||||
|
def make_retro_shader():
|
||||||
|
new_grp = bpy.data.node_groups.new('RetroShader', 'ShaderNodeTree')
|
||||||
|
lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap')
|
||||||
|
lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse')
|
||||||
|
diffuse_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
emissive_input = new_grp.inputs.new('NodeSocketColor', 'Emissive')
|
||||||
|
emissive_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
specular_input = new_grp.inputs.new('NodeSocketColor', 'Specular')
|
||||||
|
specular_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
ext_spec_input = new_grp.inputs.new('NodeSocketColor', 'ExtendedSpecular')
|
||||||
|
ext_spec_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
reflection_input = new_grp.inputs.new('NodeSocketColor', 'Reflection')
|
||||||
|
reflection_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
indirect_tex = new_grp.inputs.new('NodeSocketColor', 'IndirectTex')
|
||||||
|
indirect_tex.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'Alpha')
|
||||||
|
alpha_input.default_value = 1.0
|
||||||
|
alpha_input.min_value = 0.0
|
||||||
|
alpha_input.max_value = 1.0
|
||||||
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
|
# Group inputs
|
||||||
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
|
grp_in.location = (-1280, 27)
|
||||||
|
|
||||||
|
# New shader model
|
||||||
|
new_shader_model = new_grp.nodes.new('ShaderNodeValue')
|
||||||
|
new_shader_model.name = 'NewShaderModel'
|
||||||
|
new_shader_model.label = 'NewShaderModel'
|
||||||
|
new_shader_model.location = (-1280, 118)
|
||||||
|
new_shader_model.outputs[0].default_value = 0.0
|
||||||
|
|
||||||
|
# Principled BSDF (For new shader model)
|
||||||
|
principled_bsdf = new_grp.nodes.new('ShaderNodeBsdfPrincipled')
|
||||||
|
principled_bsdf.location = (-1038, 874)
|
||||||
|
principled_bsdf.inputs['Metallic'].default_value = 0.5
|
||||||
|
|
||||||
|
# Invert (for roughness)
|
||||||
|
invert = new_grp.nodes.new('ShaderNodeInvert')
|
||||||
|
invert.location = (-1256, 492)
|
||||||
|
invert.inputs[0].default_value = 1.0
|
||||||
|
|
||||||
|
# Gamma (for roughness)
|
||||||
|
gamma = new_grp.nodes.new('ShaderNodeGamma')
|
||||||
|
gamma.location = (-1256, 640)
|
||||||
|
gamma.inputs[1].default_value = 10.0
|
||||||
|
|
||||||
|
# Diffuse BSDF (Multiplies dynamic lighting with diffuse)
|
||||||
|
diffuse_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse')
|
||||||
|
diffuse_bdsf.location = (-945, 293)
|
||||||
|
|
||||||
|
# Mix shader (interpolates Principled and Diffuse BSDF)
|
||||||
|
new_shader_model_mix1 = new_grp.nodes.new('ShaderNodeMixShader')
|
||||||
|
new_shader_model_mix1.location = (-760, 340)
|
||||||
|
|
||||||
|
# Multiply (Multiplies static lightmap with diffuse)
|
||||||
|
lightmap_mult = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
lightmap_mult.location = (-944, 122)
|
||||||
|
lightmap_mult.blend_type = 'MULTIPLY'
|
||||||
|
lightmap_mult.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Multiplies specular with reflection)
|
||||||
|
specular_mult = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
specular_mult.location = (-940, -105)
|
||||||
|
specular_mult.blend_type = 'MULTIPLY'
|
||||||
|
specular_mult.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Multiplies extended specular with reflection)
|
||||||
|
extended_specular_mult = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
extended_specular_mult.location = (-941, -304)
|
||||||
|
extended_specular_mult.blend_type = 'MULTIPLY'
|
||||||
|
extended_specular_mult.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Add Shader (Adds dynamic diffuse with static diffuse)
|
||||||
|
diffuse_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
diffuse_add_shader.location = (-587, 209)
|
||||||
|
|
||||||
|
# Mix shader (interpolates resolved reflection with nothing)
|
||||||
|
new_shader_model_mix2 = new_grp.nodes.new('ShaderNodeMixShader')
|
||||||
|
new_shader_model_mix2.location = (-512, -38)
|
||||||
|
|
||||||
|
# Add Shader (Adds emissive with resolved reflection)
|
||||||
|
emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
emissive_add_shader.location = (-320, 8)
|
||||||
|
|
||||||
|
# Add Shader (Adds specular and extended specular reflections)
|
||||||
|
specular_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
specular_add_shader.location = (-734, -81)
|
||||||
|
|
||||||
|
# Diffuse BDSF (Multiplies extended specular with dynamic lighting)
|
||||||
|
extended_specular_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse')
|
||||||
|
extended_specular_bdsf.location = (-738, -280)
|
||||||
|
|
||||||
|
# Add shader (Adds diffuse with all emissive sources)
|
||||||
|
final_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
final_add_shader.location = (-184, 234)
|
||||||
|
|
||||||
|
# Transparent BDSF (Provides alpha)
|
||||||
|
transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent')
|
||||||
|
transparent_bdsf.location = (-224, -160)
|
||||||
|
transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0)
|
||||||
|
|
||||||
|
# Mix Shader (Applies alpha proportion)
|
||||||
|
alpha_mix = new_grp.nodes.new('ShaderNodeMixShader')
|
||||||
|
alpha_mix.location = (-40, -112)
|
||||||
|
|
||||||
|
# Material Output (Final output)
|
||||||
|
mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial')
|
||||||
|
mat_out.location = (150, -88)
|
||||||
|
|
||||||
|
# Links
|
||||||
|
new_grp.links.new(grp_in.outputs['Lightmap'], lightmap_mult.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Diffuse'], lightmap_mult.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Diffuse'], diffuse_bdsf.inputs['Color'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Diffuse'], principled_bsdf.inputs['Base Color'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Emissive'], emissive_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs['Specular'], specular_mult.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Specular'], principled_bsdf.inputs['Specular'])
|
||||||
|
new_grp.links.new(grp_in.outputs['ExtendedSpecular'], extended_specular_mult.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Reflection'], specular_mult.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Reflection'], extended_specular_mult.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Alpha'], alpha_mix.inputs['Fac'])
|
||||||
|
new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix1.inputs[0])
|
||||||
|
new_grp.links.new(diffuse_bdsf.outputs['BSDF'], new_shader_model_mix1.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs['Specular'], invert.inputs['Color'])
|
||||||
|
new_grp.links.new(invert.outputs['Color'], gamma.inputs['Color'])
|
||||||
|
new_grp.links.new(gamma.outputs['Color'], principled_bsdf.inputs['Roughness'])
|
||||||
|
new_grp.links.new(principled_bsdf.outputs['BSDF'], new_shader_model_mix1.inputs[2])
|
||||||
|
new_grp.links.new(new_shader_model_mix1.outputs['Shader'], diffuse_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(lightmap_mult.outputs['Color'], diffuse_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(specular_mult.outputs['Color'], specular_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(extended_specular_mult.outputs['Color'], extended_specular_bdsf.inputs['Color'])
|
||||||
|
new_grp.links.new(extended_specular_bdsf.outputs['BSDF'], specular_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix2.inputs[0])
|
||||||
|
new_grp.links.new(specular_add_shader.outputs['Shader'], new_shader_model_mix2.inputs[1])
|
||||||
|
new_grp.links.new(new_shader_model_mix2.outputs['Shader'], emissive_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(diffuse_add_shader.outputs['Shader'], final_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(emissive_add_shader.outputs['Shader'], final_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(transparent_bdsf.outputs['BSDF'], alpha_mix.inputs[1])
|
||||||
|
new_grp.links.new(final_add_shader.outputs['Shader'], alpha_mix.inputs[2])
|
||||||
|
new_grp.links.new(alpha_mix.outputs['Shader'], mat_out.inputs['Surface'])
|
||||||
|
|
||||||
|
def make_retro_dynamic_shader():
|
||||||
|
new_grp = bpy.data.node_groups.new('RetroDynamicShader', 'ShaderNodeTree')
|
||||||
|
lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap')
|
||||||
|
lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse')
|
||||||
|
diffuse_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
emissive_input = new_grp.inputs.new('NodeSocketColor', 'Emissive')
|
||||||
|
emissive_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
specular_input = new_grp.inputs.new('NodeSocketColor', 'Specular')
|
||||||
|
specular_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
ext_spec_input = new_grp.inputs.new('NodeSocketColor', 'ExtendedSpecular')
|
||||||
|
ext_spec_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
reflection_input = new_grp.inputs.new('NodeSocketColor', 'Reflection')
|
||||||
|
reflection_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
indirect_tex = new_grp.inputs.new('NodeSocketColor', 'IndirectTex')
|
||||||
|
indirect_tex.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'Alpha')
|
||||||
|
alpha_input.default_value = 1.0
|
||||||
|
alpha_input.min_value = 0.0
|
||||||
|
alpha_input.max_value = 1.0
|
||||||
|
dynamic_input = new_grp.inputs.new('NodeSocketColor', 'DynamicTest')
|
||||||
|
dynamic_input.default_value = (1.0, 1.0, 1.0, 1.0)
|
||||||
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
|
# Group inputs
|
||||||
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
|
grp_in.location = (-1460, 27)
|
||||||
|
|
||||||
|
# Multiply (Lightmap dynamic)
|
||||||
|
lightmap_dynamic = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
lightmap_dynamic.location = (-1174, 158)
|
||||||
|
lightmap_dynamic.blend_type = 'MULTIPLY'
|
||||||
|
lightmap_dynamic.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Diffuse dynamic)
|
||||||
|
diffuse_dynamic = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
diffuse_dynamic.location = (-1174, -32)
|
||||||
|
diffuse_dynamic.blend_type = 'MULTIPLY'
|
||||||
|
diffuse_dynamic.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Emissive dynamic)
|
||||||
|
emissive_dynamic = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
emissive_dynamic.location = (-1174, -222)
|
||||||
|
emissive_dynamic.blend_type = 'MULTIPLY'
|
||||||
|
emissive_dynamic.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# New shader model
|
||||||
|
new_shader_model = new_grp.nodes.new('ShaderNodeValue')
|
||||||
|
new_shader_model.name = 'NewShaderModel'
|
||||||
|
new_shader_model.label = 'NewShaderModel'
|
||||||
|
new_shader_model.location = (-1460, 118)
|
||||||
|
new_shader_model.outputs[0].default_value = 0.0
|
||||||
|
|
||||||
|
# Principled BSDF (For new shader model)
|
||||||
|
principled_bsdf = new_grp.nodes.new('ShaderNodeBsdfPrincipled')
|
||||||
|
principled_bsdf.location = (-1038, 874)
|
||||||
|
principled_bsdf.inputs['Metallic'].default_value = 0.5
|
||||||
|
|
||||||
|
# Invert (for roughness)
|
||||||
|
invert = new_grp.nodes.new('ShaderNodeInvert')
|
||||||
|
invert.location = (-1256, 492)
|
||||||
|
invert.inputs[0].default_value = 1.0
|
||||||
|
|
||||||
|
# Gamma (for roughness)
|
||||||
|
gamma = new_grp.nodes.new('ShaderNodeGamma')
|
||||||
|
gamma.location = (-1256, 640)
|
||||||
|
gamma.inputs[1].default_value = 10.0
|
||||||
|
|
||||||
|
# Diffuse BSDF (Multiplies dynamic lighting with diffuse)
|
||||||
|
diffuse_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse')
|
||||||
|
diffuse_bdsf.location = (-945, 293)
|
||||||
|
|
||||||
|
# Mix shader (interpolates Principled and Diffuse BSDF)
|
||||||
|
new_shader_model_mix1 = new_grp.nodes.new('ShaderNodeMixShader')
|
||||||
|
new_shader_model_mix1.location = (-760, 340)
|
||||||
|
|
||||||
|
# Multiply (Multiplies static lightmap with diffuse)
|
||||||
|
lightmap_mult = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
lightmap_mult.location = (-944, 122)
|
||||||
|
lightmap_mult.blend_type = 'MULTIPLY'
|
||||||
|
lightmap_mult.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Multiplies specular with reflection)
|
||||||
|
specular_mult = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
specular_mult.location = (-940, -105)
|
||||||
|
specular_mult.blend_type = 'MULTIPLY'
|
||||||
|
specular_mult.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Multiplies extended specular with reflection)
|
||||||
|
extended_specular_mult = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
extended_specular_mult.location = (-941, -304)
|
||||||
|
extended_specular_mult.blend_type = 'MULTIPLY'
|
||||||
|
extended_specular_mult.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Add Shader (Adds dynamic diffuse with static diffuse)
|
||||||
|
diffuse_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
diffuse_add_shader.location = (-587, 209)
|
||||||
|
|
||||||
|
# Mix shader (interpolates resolved reflection with nothing)
|
||||||
|
new_shader_model_mix2 = new_grp.nodes.new('ShaderNodeMixShader')
|
||||||
|
new_shader_model_mix2.location = (-512, -38)
|
||||||
|
|
||||||
|
# Add Shader (Adds emissive with resolved reflection)
|
||||||
|
emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
emissive_add_shader.location = (-320, 8)
|
||||||
|
|
||||||
|
# Add Shader (Adds specular and extended specular reflections)
|
||||||
|
specular_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
specular_add_shader.location = (-734, -81)
|
||||||
|
|
||||||
|
# Diffuse BDSF (Multiplies extended specular with dynamic lighting)
|
||||||
|
extended_specular_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse')
|
||||||
|
extended_specular_bdsf.location = (-738, -280)
|
||||||
|
|
||||||
|
# Add shader (Adds diffuse with all emissive sources)
|
||||||
|
final_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
final_add_shader.location = (-184, 234)
|
||||||
|
|
||||||
|
# Transparent BDSF (Provides alpha)
|
||||||
|
transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent')
|
||||||
|
transparent_bdsf.location = (-224, -160)
|
||||||
|
transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0)
|
||||||
|
|
||||||
|
# Mix Shader (Applies alpha proportion)
|
||||||
|
alpha_mix = new_grp.nodes.new('ShaderNodeMixShader')
|
||||||
|
alpha_mix.location = (-40, -112)
|
||||||
|
|
||||||
|
# Material Output (Final output)
|
||||||
|
mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial')
|
||||||
|
mat_out.location = (150, -88)
|
||||||
|
|
||||||
|
# Links
|
||||||
|
new_grp.links.new(grp_in.outputs['Lightmap'], lightmap_dynamic.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['DynamicTest'], lightmap_dynamic.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Diffuse'], diffuse_dynamic.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['DynamicTest'], diffuse_dynamic.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Emissive'], emissive_dynamic.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['DynamicTest'], emissive_dynamic.inputs['Color2'])
|
||||||
|
new_grp.links.new(lightmap_dynamic.outputs['Color'], lightmap_mult.inputs['Color1'])
|
||||||
|
new_grp.links.new(diffuse_dynamic.outputs['Color'], lightmap_mult.inputs['Color2'])
|
||||||
|
new_grp.links.new(diffuse_dynamic.outputs['Color'], diffuse_bdsf.inputs['Color'])
|
||||||
|
new_grp.links.new(diffuse_dynamic.outputs['Color'], principled_bsdf.inputs['Base Color'])
|
||||||
|
new_grp.links.new(emissive_dynamic.outputs['Color'], emissive_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs['Specular'], specular_mult.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Specular'], principled_bsdf.inputs['Specular'])
|
||||||
|
new_grp.links.new(grp_in.outputs['ExtendedSpecular'], extended_specular_mult.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Reflection'], specular_mult.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Reflection'], extended_specular_mult.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Alpha'], alpha_mix.inputs['Fac'])
|
||||||
|
new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix1.inputs[0])
|
||||||
|
new_grp.links.new(diffuse_bdsf.outputs['BSDF'], new_shader_model_mix1.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs['Specular'], invert.inputs['Color'])
|
||||||
|
new_grp.links.new(invert.outputs['Color'], gamma.inputs['Color'])
|
||||||
|
new_grp.links.new(gamma.outputs['Color'], principled_bsdf.inputs['Roughness'])
|
||||||
|
new_grp.links.new(principled_bsdf.outputs['BSDF'], new_shader_model_mix1.inputs[2])
|
||||||
|
new_grp.links.new(new_shader_model_mix1.outputs['Shader'], diffuse_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(lightmap_mult.outputs['Color'], diffuse_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(specular_mult.outputs['Color'], specular_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(extended_specular_mult.outputs['Color'], extended_specular_bdsf.inputs['Color'])
|
||||||
|
new_grp.links.new(extended_specular_bdsf.outputs['BSDF'], specular_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix2.inputs[0])
|
||||||
|
new_grp.links.new(specular_add_shader.outputs['Shader'], new_shader_model_mix2.inputs[1])
|
||||||
|
new_grp.links.new(new_shader_model_mix2.outputs['Shader'], emissive_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(diffuse_add_shader.outputs['Shader'], final_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(emissive_add_shader.outputs['Shader'], final_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(transparent_bdsf.outputs['BSDF'], alpha_mix.inputs[1])
|
||||||
|
new_grp.links.new(final_add_shader.outputs['Shader'], alpha_mix.inputs[2])
|
||||||
|
new_grp.links.new(alpha_mix.outputs['Shader'], mat_out.inputs['Surface'])
|
||||||
|
|
||||||
|
def make_retro_dynamic_alpha_shader():
|
||||||
|
new_grp = bpy.data.node_groups.new('RetroDynamicAlphaShader', 'ShaderNodeTree')
|
||||||
|
lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap')
|
||||||
|
lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse')
|
||||||
|
diffuse_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
emissive_input = new_grp.inputs.new('NodeSocketColor', 'Emissive')
|
||||||
|
emissive_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
specular_input = new_grp.inputs.new('NodeSocketColor', 'Specular')
|
||||||
|
specular_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
ext_spec_input = new_grp.inputs.new('NodeSocketColor', 'ExtendedSpecular')
|
||||||
|
ext_spec_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
reflection_input = new_grp.inputs.new('NodeSocketColor', 'Reflection')
|
||||||
|
reflection_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
indirect_tex = new_grp.inputs.new('NodeSocketColor', 'IndirectTex')
|
||||||
|
indirect_tex.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'Alpha')
|
||||||
|
alpha_input.default_value = 1.0
|
||||||
|
alpha_input.min_value = 0.0
|
||||||
|
alpha_input.max_value = 1.0
|
||||||
|
dynamic_input = new_grp.inputs.new('NodeSocketColor', 'DynamicTest')
|
||||||
|
dynamic_input.default_value = (1.0, 1.0, 1.0, 1.0)
|
||||||
|
dynamic_alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'DynamicAlphaTest')
|
||||||
|
dynamic_alpha_input.default_value = 1.0
|
||||||
|
dynamic_alpha_input.min_value = 0.0
|
||||||
|
dynamic_alpha_input.max_value = 1.0
|
||||||
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
|
# Group inputs
|
||||||
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
|
grp_in.location = (-1460, 27)
|
||||||
|
|
||||||
|
# Multiply (Lightmap dynamic)
|
||||||
|
lightmap_dynamic = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
lightmap_dynamic.location = (-1174, 158)
|
||||||
|
lightmap_dynamic.blend_type = 'MULTIPLY'
|
||||||
|
lightmap_dynamic.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Diffuse dynamic)
|
||||||
|
diffuse_dynamic = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
diffuse_dynamic.location = (-1174, -32)
|
||||||
|
diffuse_dynamic.blend_type = 'MULTIPLY'
|
||||||
|
diffuse_dynamic.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Emissive dynamic)
|
||||||
|
emissive_dynamic = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
emissive_dynamic.location = (-1174, -222)
|
||||||
|
emissive_dynamic.blend_type = 'MULTIPLY'
|
||||||
|
emissive_dynamic.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Alpha dynamic)
|
||||||
|
alpha_dynamic = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
alpha_dynamic.location = (-1174, -410)
|
||||||
|
alpha_dynamic.operation = 'MULTIPLY'
|
||||||
|
|
||||||
|
# New shader model
|
||||||
|
new_shader_model = new_grp.nodes.new('ShaderNodeValue')
|
||||||
|
new_shader_model.name = 'NewShaderModel'
|
||||||
|
new_shader_model.label = 'NewShaderModel'
|
||||||
|
new_shader_model.location = (-1460, 118)
|
||||||
|
new_shader_model.outputs[0].default_value = 0.0
|
||||||
|
|
||||||
|
# Principled BSDF (For new shader model)
|
||||||
|
principled_bsdf = new_grp.nodes.new('ShaderNodeBsdfPrincipled')
|
||||||
|
principled_bsdf.location = (-1038, 874)
|
||||||
|
principled_bsdf.inputs['Metallic'].default_value = 0.5
|
||||||
|
|
||||||
|
# Invert (for roughness)
|
||||||
|
invert = new_grp.nodes.new('ShaderNodeInvert')
|
||||||
|
invert.location = (-1256, 492)
|
||||||
|
invert.inputs[0].default_value = 1.0
|
||||||
|
|
||||||
|
# Gamma (for roughness)
|
||||||
|
gamma = new_grp.nodes.new('ShaderNodeGamma')
|
||||||
|
gamma.location = (-1256, 640)
|
||||||
|
gamma.inputs[1].default_value = 10.0
|
||||||
|
|
||||||
|
# Diffuse BSDF (Multiplies dynamic lighting with diffuse)
|
||||||
|
diffuse_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse')
|
||||||
|
diffuse_bdsf.location = (-945, 293)
|
||||||
|
|
||||||
|
# Mix shader (interpolates Principled and Diffuse BSDF)
|
||||||
|
new_shader_model_mix1 = new_grp.nodes.new('ShaderNodeMixShader')
|
||||||
|
new_shader_model_mix1.location = (-760, 340)
|
||||||
|
|
||||||
|
# Multiply (Multiplies static lightmap with diffuse)
|
||||||
|
lightmap_mult = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
lightmap_mult.location = (-944, 122)
|
||||||
|
lightmap_mult.blend_type = 'MULTIPLY'
|
||||||
|
lightmap_mult.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Multiplies specular with reflection)
|
||||||
|
specular_mult = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
specular_mult.location = (-940, -105)
|
||||||
|
specular_mult.blend_type = 'MULTIPLY'
|
||||||
|
specular_mult.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Multiplies extended specular with reflection)
|
||||||
|
extended_specular_mult = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
extended_specular_mult.location = (-941, -304)
|
||||||
|
extended_specular_mult.blend_type = 'MULTIPLY'
|
||||||
|
extended_specular_mult.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Add Shader (Adds dynamic diffuse with static diffuse)
|
||||||
|
diffuse_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
diffuse_add_shader.location = (-587, 209)
|
||||||
|
|
||||||
|
# Mix shader (interpolates resolved reflection with nothing)
|
||||||
|
new_shader_model_mix2 = new_grp.nodes.new('ShaderNodeMixShader')
|
||||||
|
new_shader_model_mix2.location = (-512, -38)
|
||||||
|
|
||||||
|
# Add Shader (Adds emissive with resolved reflection)
|
||||||
|
emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
emissive_add_shader.location = (-320, 8)
|
||||||
|
|
||||||
|
# Add Shader (Adds specular and extended specular reflections)
|
||||||
|
specular_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
specular_add_shader.location = (-734, -81)
|
||||||
|
|
||||||
|
# Diffuse BDSF (Multiplies extended specular with dynamic lighting)
|
||||||
|
extended_specular_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse')
|
||||||
|
extended_specular_bdsf.location = (-738, -280)
|
||||||
|
|
||||||
|
# Add shader (Adds diffuse with all emissive sources)
|
||||||
|
final_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
final_add_shader.location = (-184, 234)
|
||||||
|
|
||||||
|
# Transparent BDSF (Provides alpha)
|
||||||
|
transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent')
|
||||||
|
transparent_bdsf.location = (-224, -160)
|
||||||
|
transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0)
|
||||||
|
|
||||||
|
# Mix Shader (Applies alpha proportion)
|
||||||
|
alpha_mix = new_grp.nodes.new('ShaderNodeMixShader')
|
||||||
|
alpha_mix.location = (-40, -112)
|
||||||
|
|
||||||
|
# Material Output (Final output)
|
||||||
|
mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial')
|
||||||
|
mat_out.location = (150, -88)
|
||||||
|
|
||||||
|
# Links
|
||||||
|
new_grp.links.new(grp_in.outputs['Lightmap'], lightmap_dynamic.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['DynamicTest'], lightmap_dynamic.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Diffuse'], diffuse_dynamic.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['DynamicTest'], diffuse_dynamic.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Emissive'], emissive_dynamic.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['DynamicTest'], emissive_dynamic.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Alpha'], alpha_dynamic.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs['DynamicAlphaTest'], alpha_dynamic.inputs[1])
|
||||||
|
new_grp.links.new(lightmap_dynamic.outputs['Color'], lightmap_mult.inputs['Color1'])
|
||||||
|
new_grp.links.new(diffuse_dynamic.outputs['Color'], lightmap_mult.inputs['Color2'])
|
||||||
|
new_grp.links.new(diffuse_dynamic.outputs['Color'], diffuse_bdsf.inputs['Color'])
|
||||||
|
new_grp.links.new(diffuse_dynamic.outputs['Color'], principled_bsdf.inputs['Base Color'])
|
||||||
|
new_grp.links.new(emissive_dynamic.outputs['Color'], emissive_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs['Specular'], specular_mult.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Specular'], principled_bsdf.inputs['Specular'])
|
||||||
|
new_grp.links.new(grp_in.outputs['ExtendedSpecular'], extended_specular_mult.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Reflection'], specular_mult.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Reflection'], extended_specular_mult.inputs['Color2'])
|
||||||
|
new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix1.inputs[0])
|
||||||
|
new_grp.links.new(diffuse_bdsf.outputs['BSDF'], new_shader_model_mix1.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs['Specular'], invert.inputs['Color'])
|
||||||
|
new_grp.links.new(invert.outputs['Color'], gamma.inputs['Color'])
|
||||||
|
new_grp.links.new(gamma.outputs['Color'], principled_bsdf.inputs['Roughness'])
|
||||||
|
new_grp.links.new(principled_bsdf.outputs['BSDF'], new_shader_model_mix1.inputs[2])
|
||||||
|
new_grp.links.new(new_shader_model_mix1.outputs['Shader'], diffuse_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(alpha_dynamic.outputs['Value'], alpha_mix.inputs['Fac'])
|
||||||
|
new_grp.links.new(lightmap_mult.outputs['Color'], diffuse_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(specular_mult.outputs['Color'], specular_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(extended_specular_mult.outputs['Color'], extended_specular_bdsf.inputs['Color'])
|
||||||
|
new_grp.links.new(extended_specular_bdsf.outputs['BSDF'], specular_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix2.inputs[0])
|
||||||
|
new_grp.links.new(specular_add_shader.outputs['Shader'], new_shader_model_mix2.inputs[1])
|
||||||
|
new_grp.links.new(new_shader_model_mix2.outputs['Shader'], emissive_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(diffuse_add_shader.outputs['Shader'], final_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(emissive_add_shader.outputs['Shader'], final_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(transparent_bdsf.outputs['BSDF'], alpha_mix.inputs[1])
|
||||||
|
new_grp.links.new(final_add_shader.outputs['Shader'], alpha_mix.inputs[2])
|
||||||
|
new_grp.links.new(alpha_mix.outputs['Shader'], mat_out.inputs['Surface'])
|
||||||
|
|
||||||
|
def make_retro_dynamic_character_shader():
|
||||||
|
new_grp = bpy.data.node_groups.new('RetroDynamicCharacterShader', 'ShaderNodeTree')
|
||||||
|
lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap')
|
||||||
|
lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse')
|
||||||
|
diffuse_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
emissive_input = new_grp.inputs.new('NodeSocketColor', 'Emissive')
|
||||||
|
emissive_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
specular_input = new_grp.inputs.new('NodeSocketColor', 'Specular')
|
||||||
|
specular_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
ext_spec_input = new_grp.inputs.new('NodeSocketColor', 'ExtendedSpecular')
|
||||||
|
ext_spec_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
reflection_input = new_grp.inputs.new('NodeSocketColor', 'Reflection')
|
||||||
|
reflection_input.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
indirect_tex = new_grp.inputs.new('NodeSocketColor', 'IndirectTex')
|
||||||
|
indirect_tex.default_value = (0.0, 0.0, 0.0, 0.0)
|
||||||
|
alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'Alpha')
|
||||||
|
alpha_input.default_value = 1.0
|
||||||
|
alpha_input.min_value = 0.0
|
||||||
|
alpha_input.max_value = 1.0
|
||||||
|
dynamic_input = new_grp.inputs.new('NodeSocketColor', 'DynamicTest')
|
||||||
|
dynamic_input.default_value = (1.0, 1.0, 1.0, 1.0)
|
||||||
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
|
# Group inputs
|
||||||
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
|
grp_in.location = (-1460, 27)
|
||||||
|
|
||||||
|
# Multiply (Emissive dynamic)
|
||||||
|
emissive_dynamic = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
emissive_dynamic.location = (-1174, -32)
|
||||||
|
emissive_dynamic.blend_type = 'MULTIPLY'
|
||||||
|
emissive_dynamic.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# New shader model
|
||||||
|
new_shader_model = new_grp.nodes.new('ShaderNodeValue')
|
||||||
|
new_shader_model.name = 'NewShaderModel'
|
||||||
|
new_shader_model.label = 'NewShaderModel'
|
||||||
|
new_shader_model.location = (-1460, 118)
|
||||||
|
new_shader_model.outputs[0].default_value = 0.0
|
||||||
|
|
||||||
|
# Principled BSDF (For new shader model)
|
||||||
|
principled_bsdf = new_grp.nodes.new('ShaderNodeBsdfPrincipled')
|
||||||
|
principled_bsdf.location = (-1038, 874)
|
||||||
|
principled_bsdf.inputs['Metallic'].default_value = 0.5
|
||||||
|
|
||||||
|
# Invert (for roughness)
|
||||||
|
invert = new_grp.nodes.new('ShaderNodeInvert')
|
||||||
|
invert.location = (-1256, 492)
|
||||||
|
invert.inputs[0].default_value = 1.0
|
||||||
|
|
||||||
|
# Gamma (for roughness)
|
||||||
|
gamma = new_grp.nodes.new('ShaderNodeGamma')
|
||||||
|
gamma.location = (-1256, 640)
|
||||||
|
gamma.inputs[1].default_value = 10.0
|
||||||
|
|
||||||
|
# Diffuse BSDF (Multiplies dynamic lighting with diffuse)
|
||||||
|
diffuse_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse')
|
||||||
|
diffuse_bdsf.location = (-945, 293)
|
||||||
|
|
||||||
|
# Mix shader (interpolates Principled and Diffuse BSDF)
|
||||||
|
new_shader_model_mix1 = new_grp.nodes.new('ShaderNodeMixShader')
|
||||||
|
new_shader_model_mix1.location = (-760, 340)
|
||||||
|
|
||||||
|
# Multiply (Multiplies static lightmap with diffuse)
|
||||||
|
lightmap_mult = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
lightmap_mult.location = (-944, 122)
|
||||||
|
lightmap_mult.blend_type = 'MULTIPLY'
|
||||||
|
lightmap_mult.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Multiplies specular with reflection)
|
||||||
|
specular_mult = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
specular_mult.location = (-940, -105)
|
||||||
|
specular_mult.blend_type = 'MULTIPLY'
|
||||||
|
specular_mult.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Multiply (Multiplies extended specular with reflection)
|
||||||
|
extended_specular_mult = new_grp.nodes.new('ShaderNodeMixRGB')
|
||||||
|
extended_specular_mult.location = (-941, -304)
|
||||||
|
extended_specular_mult.blend_type = 'MULTIPLY'
|
||||||
|
extended_specular_mult.inputs['Fac'].default_value = 1.0
|
||||||
|
|
||||||
|
# Add Shader (Adds dynamic diffuse with static diffuse)
|
||||||
|
diffuse_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
diffuse_add_shader.location = (-587, 209)
|
||||||
|
|
||||||
|
# Mix shader (interpolates resolved reflection with nothing)
|
||||||
|
new_shader_model_mix2 = new_grp.nodes.new('ShaderNodeMixShader')
|
||||||
|
new_shader_model_mix2.location = (-512, -38)
|
||||||
|
|
||||||
|
# Add Shader (Adds emissive with resolved reflection)
|
||||||
|
emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
emissive_add_shader.location = (-320, 8)
|
||||||
|
|
||||||
|
# Add Shader (Adds specular and extended specular reflections)
|
||||||
|
specular_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
specular_add_shader.location = (-734, -81)
|
||||||
|
|
||||||
|
# Diffuse BDSF (Multiplies extended specular with dynamic lighting)
|
||||||
|
extended_specular_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse')
|
||||||
|
extended_specular_bdsf.location = (-738, -280)
|
||||||
|
|
||||||
|
# Add shader (Adds diffuse with all emissive sources)
|
||||||
|
final_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
|
||||||
|
final_add_shader.location = (-184, 234)
|
||||||
|
|
||||||
|
# Transparent BDSF (Provides alpha)
|
||||||
|
transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent')
|
||||||
|
transparent_bdsf.location = (-224, -160)
|
||||||
|
transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0)
|
||||||
|
|
||||||
|
# Mix Shader (Applies alpha proportion)
|
||||||
|
alpha_mix = new_grp.nodes.new('ShaderNodeMixShader')
|
||||||
|
alpha_mix.location = (-40, -112)
|
||||||
|
|
||||||
|
# Material Output (Final output)
|
||||||
|
mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial')
|
||||||
|
mat_out.location = (150, -88)
|
||||||
|
|
||||||
|
# Links
|
||||||
|
new_grp.links.new(grp_in.outputs['Emissive'], emissive_dynamic.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['DynamicTest'], emissive_dynamic.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Lightmap'], lightmap_mult.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Diffuse'], lightmap_mult.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Diffuse'], diffuse_bdsf.inputs['Color'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Diffuse'], principled_bsdf.inputs['Base Color'])
|
||||||
|
new_grp.links.new(emissive_dynamic.outputs['Color'], emissive_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(grp_in.outputs['Specular'], specular_mult.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Specular'], principled_bsdf.inputs['Specular'])
|
||||||
|
new_grp.links.new(grp_in.outputs['ExtendedSpecular'], extended_specular_mult.inputs['Color1'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Reflection'], specular_mult.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Reflection'], extended_specular_mult.inputs['Color2'])
|
||||||
|
new_grp.links.new(grp_in.outputs['Alpha'], alpha_mix.inputs['Fac'])
|
||||||
|
new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix1.inputs[0])
|
||||||
|
new_grp.links.new(diffuse_bdsf.outputs['BSDF'], new_shader_model_mix1.inputs[1])
|
||||||
|
new_grp.links.new(grp_in.outputs['Specular'], invert.inputs['Color'])
|
||||||
|
new_grp.links.new(invert.outputs['Color'], gamma.inputs['Color'])
|
||||||
|
new_grp.links.new(gamma.outputs['Color'], principled_bsdf.inputs['Roughness'])
|
||||||
|
new_grp.links.new(principled_bsdf.outputs['BSDF'], new_shader_model_mix1.inputs[2])
|
||||||
|
new_grp.links.new(new_shader_model_mix1.outputs['Shader'], diffuse_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(lightmap_mult.outputs['Color'], diffuse_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(specular_mult.outputs['Color'], specular_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(extended_specular_mult.outputs['Color'], extended_specular_bdsf.inputs['Color'])
|
||||||
|
new_grp.links.new(extended_specular_bdsf.outputs['BSDF'], specular_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix2.inputs[0])
|
||||||
|
new_grp.links.new(specular_add_shader.outputs['Shader'], new_shader_model_mix2.inputs[1])
|
||||||
|
new_grp.links.new(new_shader_model_mix2.outputs['Shader'], emissive_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(diffuse_add_shader.outputs['Shader'], final_add_shader.inputs[0])
|
||||||
|
new_grp.links.new(emissive_add_shader.outputs['Shader'], final_add_shader.inputs[1])
|
||||||
|
new_grp.links.new(transparent_bdsf.outputs['BSDF'], alpha_mix.inputs[1])
|
||||||
|
new_grp.links.new(final_add_shader.outputs['Shader'], alpha_mix.inputs[2])
|
||||||
|
new_grp.links.new(alpha_mix.outputs['Shader'], mat_out.inputs['Surface'])
|
||||||
|
|
||||||
|
ROOT_SHADER_GROUPS = (
|
||||||
|
make_retro_shader,
|
||||||
|
make_retro_dynamic_shader,
|
||||||
|
make_retro_dynamic_alpha_shader,
|
||||||
|
make_retro_dynamic_character_shader
|
||||||
|
)
|
||||||
|
|
||||||
# UV animation nodes:
|
# UV animation nodes:
|
||||||
# http://www.metroid2002.com/retromodding/wiki/Materials_(Metroid_Prime)#UV_Animations
|
# http://www.metroid2002.com/retromodding/wiki/Materials_(Metroid_Prime)#UV_Animations
|
||||||
|
|
||||||
|
@ -18,17 +673,28 @@ def make_uva0():
|
||||||
|
|
||||||
# Group outputs
|
# Group outputs
|
||||||
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||||
grp_out.location = (500, 0)
|
grp_out.location = (1000, 0)
|
||||||
|
|
||||||
# UV vertical-flip (to match GameCube's UV-coordinate space)
|
# Vector Transform to bring world space into camera space
|
||||||
v_flip = new_grp.nodes.new('ShaderNodeMapping')
|
vec_xf = new_grp.nodes.new('ShaderNodeVectorTransform')
|
||||||
v_flip.location = (100, 0)
|
vec_xf.location = (100, 0)
|
||||||
v_flip.vector_type = 'TEXTURE'
|
vec_xf.vector_type = 'NORMAL'
|
||||||
v_flip.scale[1] = -1.0
|
vec_xf.convert_from = 'WORLD'
|
||||||
|
vec_xf.convert_to = 'CAMERA'
|
||||||
|
|
||||||
|
# UV scale (to match GameCube's UV-coordinate space)
|
||||||
|
uv_scale = new_grp.nodes.new('ShaderNodeMapping')
|
||||||
|
uv_scale.location = (400, -400)
|
||||||
|
uv_scale.vector_type = 'TEXTURE'
|
||||||
|
uv_scale.scale[0] = 2.0
|
||||||
|
uv_scale.scale[1] = 2.0
|
||||||
|
uv_scale.translation[0] = 1.0
|
||||||
|
uv_scale.translation[1] = 1.0
|
||||||
|
|
||||||
# Links
|
# Links
|
||||||
new_grp.links.new(grp_in.outputs[0], v_flip.inputs[0])
|
new_grp.links.new(grp_in.outputs[0], vec_xf.inputs[0])
|
||||||
new_grp.links.new(v_flip.outputs[0], grp_out.inputs[0])
|
new_grp.links.new(vec_xf.outputs[0], uv_scale.inputs[0])
|
||||||
|
new_grp.links.new(uv_scale.outputs[0], grp_out.inputs[0])
|
||||||
|
|
||||||
# 1 - Modelview Inverse
|
# 1 - Modelview Inverse
|
||||||
def make_uva1():
|
def make_uva1():
|
||||||
|
@ -36,42 +702,17 @@ def make_uva1():
|
||||||
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
new_grp.inputs.new('NodeSocketVector', 'UV In')
|
||||||
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
new_grp.outputs.new('NodeSocketVector', 'UV Out')
|
||||||
new_grp.use_fake_user = True
|
new_grp.use_fake_user = True
|
||||||
|
|
||||||
# Group inputs
|
# Group inputs
|
||||||
grp_in = new_grp.nodes.new('NodeGroupInput')
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
grp_in.location = (-300, 0)
|
grp_in.location = (-300, 0)
|
||||||
|
|
||||||
# Group outputs
|
# Group outputs
|
||||||
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||||
grp_out.location = (500, 0)
|
grp_out.location = (500, 0)
|
||||||
|
|
||||||
# Geometry input
|
|
||||||
geom_in = new_grp.nodes.new('ShaderNodeGeometry')
|
|
||||||
geom_in.location = (-700, 0)
|
|
||||||
|
|
||||||
# View flip
|
|
||||||
view_flip = new_grp.nodes.new('ShaderNodeMapping')
|
|
||||||
view_flip.location = (-500, -100)
|
|
||||||
view_flip.vector_type = 'TEXTURE'
|
|
||||||
view_flip.scale = (-1.0, -1.0, 1.0)
|
|
||||||
|
|
||||||
# Normal/translation add
|
|
||||||
adder = new_grp.nodes.new('ShaderNodeVectorMath')
|
|
||||||
adder.location = (-100, 0)
|
|
||||||
adder.operation = 'ADD'
|
|
||||||
|
|
||||||
# UV vertical-flip (to match GameCube's UV-coordinate space)
|
|
||||||
v_flip = new_grp.nodes.new('ShaderNodeMapping')
|
|
||||||
v_flip.location = (100, 0)
|
|
||||||
v_flip.vector_type = 'TEXTURE'
|
|
||||||
v_flip.scale[1] = -1.0
|
|
||||||
|
|
||||||
# Links
|
# Links
|
||||||
new_grp.links.new(grp_in.outputs[0], adder.inputs[0])
|
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||||
new_grp.links.new(geom_in.outputs['View'], view_flip.inputs[0])
|
|
||||||
new_grp.links.new(view_flip.outputs[0], adder.inputs[1])
|
|
||||||
new_grp.links.new(adder.outputs[0], v_flip.inputs[0])
|
|
||||||
new_grp.links.new(v_flip.outputs[0], grp_out.inputs[0])
|
|
||||||
|
|
||||||
# 2 - UV Scroll
|
# 2 - UV Scroll
|
||||||
def make_uva2():
|
def make_uva2():
|
||||||
|
@ -84,11 +725,18 @@ def make_uva2():
|
||||||
|
|
||||||
# Group inputs
|
# Group inputs
|
||||||
grp_in = new_grp.nodes.new('NodeGroupInput')
|
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||||
grp_in.location = (-100, 0)
|
grp_in.location = (-457, 22)
|
||||||
|
|
||||||
# Group outputs
|
# Group outputs
|
||||||
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||||
grp_out.location = (500, 0)
|
grp_out.location = (500, 0)
|
||||||
|
|
||||||
|
# Mapping
|
||||||
|
mapping = new_grp.nodes.new('ShaderNodeMapping')
|
||||||
|
mapping.location = (-235, 125)
|
||||||
|
drvs = mapping.driver_add('scale')
|
||||||
|
for drv in drvs:
|
||||||
|
drv.driver.expression = 'frame/60'
|
||||||
|
|
||||||
# Adder1
|
# Adder1
|
||||||
adder1 = new_grp.nodes.new('ShaderNodeVectorMath')
|
adder1 = new_grp.nodes.new('ShaderNodeVectorMath')
|
||||||
|
@ -103,7 +751,8 @@ def make_uva2():
|
||||||
# Links
|
# Links
|
||||||
new_grp.links.new(grp_in.outputs[0], adder2.inputs[0])
|
new_grp.links.new(grp_in.outputs[0], adder2.inputs[0])
|
||||||
new_grp.links.new(grp_in.outputs[1], adder1.inputs[0])
|
new_grp.links.new(grp_in.outputs[1], adder1.inputs[0])
|
||||||
new_grp.links.new(grp_in.outputs[2], adder1.inputs[1])
|
new_grp.links.new(grp_in.outputs[2], mapping.inputs[0])
|
||||||
|
new_grp.links.new(mapping.outputs[0], adder1.inputs[1])
|
||||||
new_grp.links.new(adder1.outputs[0], adder2.inputs[1])
|
new_grp.links.new(adder1.outputs[0], adder2.inputs[1])
|
||||||
new_grp.links.new(adder2.outputs[0], grp_out.inputs[0])
|
new_grp.links.new(adder2.outputs[0], grp_out.inputs[0])
|
||||||
|
|
||||||
|
@ -128,11 +777,19 @@ def make_uva3():
|
||||||
add1 = new_grp.nodes.new('ShaderNodeMath')
|
add1 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
add1.operation = 'ADD'
|
add1.operation = 'ADD'
|
||||||
add1.location = (500, 0)
|
add1.location = (500, 0)
|
||||||
|
|
||||||
|
# Multiply
|
||||||
|
mult = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
mult.operation = 'MULTIPLY'
|
||||||
|
mult.location = (230, -112)
|
||||||
|
drv = mult.inputs[1].driver_add('default_value')
|
||||||
|
drv.driver.expression = 'frame/60'
|
||||||
|
|
||||||
# Links
|
# Links
|
||||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||||
new_grp.links.new(grp_in.outputs[1], add1.inputs[0])
|
new_grp.links.new(grp_in.outputs[1], add1.inputs[0])
|
||||||
new_grp.links.new(grp_in.outputs[2], add1.inputs[1])
|
new_grp.links.new(grp_in.outputs[2], mult.inputs[0])
|
||||||
|
new_grp.links.new(mult.outputs[0], add1.inputs[1])
|
||||||
|
|
||||||
# 4 - Horizontal Filmstrip Animation
|
# 4 - Horizontal Filmstrip Animation
|
||||||
def make_uva4():
|
def make_uva4():
|
||||||
|
@ -166,7 +823,7 @@ def make_uva4():
|
||||||
# Modulo
|
# Modulo
|
||||||
mod1 = new_grp.nodes.new('ShaderNodeMath')
|
mod1 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
mod1.operation = 'MODULO'
|
mod1.operation = 'MODULO'
|
||||||
mod1.inputs[1].default_value = 900.0
|
mod1.inputs[1].default_value = 1.0
|
||||||
mod1.location = (-400, 0)
|
mod1.location = (-400, 0)
|
||||||
|
|
||||||
# Multiply3
|
# Multiply3
|
||||||
|
@ -188,6 +845,19 @@ def make_uva4():
|
||||||
add1 = new_grp.nodes.new('ShaderNodeVectorMath')
|
add1 = new_grp.nodes.new('ShaderNodeVectorMath')
|
||||||
add1.operation = 'ADD'
|
add1.operation = 'ADD'
|
||||||
add1.location = (600, 0)
|
add1.location = (600, 0)
|
||||||
|
|
||||||
|
# Timing Add
|
||||||
|
time_add = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
time_add.operation = 'ADD'
|
||||||
|
time_add.location = (-802, -180)
|
||||||
|
drv = time_add.inputs[1].driver_add('default_value')
|
||||||
|
drv.driver.expression = 'frame/60'
|
||||||
|
|
||||||
|
# Floor
|
||||||
|
floor = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
floor.operation = 'FLOOR'
|
||||||
|
floor.location = (-204, -180)
|
||||||
|
floor.inputs[1].default_value = 0.0
|
||||||
|
|
||||||
# Links
|
# Links
|
||||||
new_grp.links.new(grp_in.outputs[0], add1.inputs[1])
|
new_grp.links.new(grp_in.outputs[0], add1.inputs[1])
|
||||||
|
@ -195,11 +865,13 @@ def make_uva4():
|
||||||
new_grp.links.new(grp_in.outputs[2], mult3.inputs[1])
|
new_grp.links.new(grp_in.outputs[2], mult3.inputs[1])
|
||||||
new_grp.links.new(grp_in.outputs[3], mult4.inputs[1])
|
new_grp.links.new(grp_in.outputs[3], mult4.inputs[1])
|
||||||
new_grp.links.new(grp_in.outputs[3], mult1.inputs[0])
|
new_grp.links.new(grp_in.outputs[3], mult1.inputs[0])
|
||||||
new_grp.links.new(grp_in.outputs[4], mult2.inputs[1])
|
new_grp.links.new(grp_in.outputs[4], time_add.inputs[0])
|
||||||
|
new_grp.links.new(time_add.outputs[0], mult2.inputs[1])
|
||||||
new_grp.links.new(mult1.outputs[0], mult2.inputs[0])
|
new_grp.links.new(mult1.outputs[0], mult2.inputs[0])
|
||||||
new_grp.links.new(mult2.outputs[0], mod1.inputs[0])
|
new_grp.links.new(mult2.outputs[0], mod1.inputs[0])
|
||||||
new_grp.links.new(mod1.outputs[0], mult3.inputs[0])
|
new_grp.links.new(mod1.outputs[0], mult3.inputs[0])
|
||||||
new_grp.links.new(mult3.outputs[0], mult4.inputs[0])
|
new_grp.links.new(mult3.outputs[0], floor.inputs[0])
|
||||||
|
new_grp.links.new(floor.outputs[0], mult4.inputs[0])
|
||||||
new_grp.links.new(mult4.outputs[0], map1.inputs[0])
|
new_grp.links.new(mult4.outputs[0], map1.inputs[0])
|
||||||
new_grp.links.new(map1.outputs[0], add1.inputs[0])
|
new_grp.links.new(map1.outputs[0], add1.inputs[0])
|
||||||
new_grp.links.new(add1.outputs[0], grp_out.inputs[0])
|
new_grp.links.new(add1.outputs[0], grp_out.inputs[0])
|
||||||
|
@ -236,7 +908,7 @@ def make_uva5():
|
||||||
# Modulo
|
# Modulo
|
||||||
mod1 = new_grp.nodes.new('ShaderNodeMath')
|
mod1 = new_grp.nodes.new('ShaderNodeMath')
|
||||||
mod1.operation = 'MODULO'
|
mod1.operation = 'MODULO'
|
||||||
mod1.inputs[1].default_value = 900.0
|
mod1.inputs[1].default_value = 1.0
|
||||||
mod1.location = (-400, 0)
|
mod1.location = (-400, 0)
|
||||||
|
|
||||||
# Multiply3
|
# Multiply3
|
||||||
|
@ -258,6 +930,19 @@ def make_uva5():
|
||||||
add1 = new_grp.nodes.new('ShaderNodeVectorMath')
|
add1 = new_grp.nodes.new('ShaderNodeVectorMath')
|
||||||
add1.operation = 'ADD'
|
add1.operation = 'ADD'
|
||||||
add1.location = (600, 0)
|
add1.location = (600, 0)
|
||||||
|
|
||||||
|
# Timing Add
|
||||||
|
time_add = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
time_add.operation = 'ADD'
|
||||||
|
time_add.location = (-802, -180)
|
||||||
|
drv = time_add.inputs[1].driver_add('default_value')
|
||||||
|
drv.driver.expression = 'frame/60'
|
||||||
|
|
||||||
|
# Floor
|
||||||
|
floor = new_grp.nodes.new('ShaderNodeMath')
|
||||||
|
floor.operation = 'FLOOR'
|
||||||
|
floor.location = (-204, -180)
|
||||||
|
floor.inputs[1].default_value = 0.0
|
||||||
|
|
||||||
# Links
|
# Links
|
||||||
new_grp.links.new(grp_in.outputs[0], add1.inputs[1])
|
new_grp.links.new(grp_in.outputs[0], add1.inputs[1])
|
||||||
|
@ -265,11 +950,13 @@ def make_uva5():
|
||||||
new_grp.links.new(grp_in.outputs[2], mult3.inputs[1])
|
new_grp.links.new(grp_in.outputs[2], mult3.inputs[1])
|
||||||
new_grp.links.new(grp_in.outputs[3], mult4.inputs[1])
|
new_grp.links.new(grp_in.outputs[3], mult4.inputs[1])
|
||||||
new_grp.links.new(grp_in.outputs[3], mult1.inputs[0])
|
new_grp.links.new(grp_in.outputs[3], mult1.inputs[0])
|
||||||
new_grp.links.new(grp_in.outputs[4], mult2.inputs[1])
|
new_grp.links.new(grp_in.outputs[4], time_add.inputs[0])
|
||||||
|
new_grp.links.new(time_add.outputs[0], mult2.inputs[1])
|
||||||
new_grp.links.new(mult1.outputs[0], mult2.inputs[0])
|
new_grp.links.new(mult1.outputs[0], mult2.inputs[0])
|
||||||
new_grp.links.new(mult2.outputs[0], mod1.inputs[0])
|
new_grp.links.new(mult2.outputs[0], mod1.inputs[0])
|
||||||
new_grp.links.new(mod1.outputs[0], mult3.inputs[0])
|
new_grp.links.new(mod1.outputs[0], mult3.inputs[0])
|
||||||
new_grp.links.new(mult3.outputs[0], mult4.inputs[0])
|
new_grp.links.new(mult3.outputs[0], floor.inputs[0])
|
||||||
|
new_grp.links.new(floor.outputs[0], mult4.inputs[0])
|
||||||
new_grp.links.new(mult4.outputs[0], map1.inputs[0])
|
new_grp.links.new(mult4.outputs[0], map1.inputs[0])
|
||||||
new_grp.links.new(map1.outputs[0], add1.inputs[0])
|
new_grp.links.new(map1.outputs[0], add1.inputs[0])
|
||||||
new_grp.links.new(add1.outputs[0], grp_out.inputs[0])
|
new_grp.links.new(add1.outputs[0], grp_out.inputs[0])
|
||||||
|
@ -290,7 +977,7 @@ def make_uva6():
|
||||||
grp_out.location = (300, 0)
|
grp_out.location = (300, 0)
|
||||||
|
|
||||||
# Geometry input
|
# Geometry input
|
||||||
geom_in = new_grp.nodes.new('ShaderNodeGeometry')
|
geom_in = new_grp.nodes.new('ShaderNodeTexCoord')
|
||||||
geom_in.location = (-300, 0)
|
geom_in.location = (-300, 0)
|
||||||
|
|
||||||
# Adder1
|
# Adder1
|
||||||
|
@ -300,7 +987,7 @@ def make_uva6():
|
||||||
|
|
||||||
# Links
|
# Links
|
||||||
new_grp.links.new(grp_in.outputs[0], adder1.inputs[0])
|
new_grp.links.new(grp_in.outputs[0], adder1.inputs[0])
|
||||||
new_grp.links.new(geom_in.outputs['Global'], adder1.inputs[1])
|
new_grp.links.new(geom_in.outputs['Object'], adder1.inputs[1])
|
||||||
new_grp.links.new(adder1.outputs[0], grp_out.inputs[0])
|
new_grp.links.new(adder1.outputs[0], grp_out.inputs[0])
|
||||||
|
|
||||||
# 7 - Mode Who Must Not Be Named
|
# 7 - Mode Who Must Not Be Named
|
||||||
|
@ -321,7 +1008,7 @@ def make_uva7():
|
||||||
grp_out.location = (0, 0)
|
grp_out.location = (0, 0)
|
||||||
|
|
||||||
# Geometry input
|
# Geometry input
|
||||||
geom_in = new_grp.nodes.new('ShaderNodeGeometry')
|
geom_in = new_grp.nodes.new('ShaderNodeTexCoord')
|
||||||
geom_in.location = (-1000, 0)
|
geom_in.location = (-1000, 0)
|
||||||
|
|
||||||
# View flip
|
# View flip
|
||||||
|
@ -382,7 +1069,7 @@ def make_uva7():
|
||||||
|
|
||||||
# Links
|
# Links
|
||||||
new_grp.links.new(grp_in.outputs[0], add2.inputs[0])
|
new_grp.links.new(grp_in.outputs[0], add2.inputs[0])
|
||||||
new_grp.links.new(geom_in.outputs['View'], view_flip.inputs[0])
|
new_grp.links.new(geom_in.outputs['Window'], view_flip.inputs[0])
|
||||||
new_grp.links.new(view_flip.outputs[0], sep1.inputs[0])
|
new_grp.links.new(view_flip.outputs[0], sep1.inputs[0])
|
||||||
new_grp.links.new(grp_in.outputs[1], comb2.inputs[0])
|
new_grp.links.new(grp_in.outputs[1], comb2.inputs[0])
|
||||||
new_grp.links.new(grp_in.outputs[1], comb2.inputs[1])
|
new_grp.links.new(grp_in.outputs[1], comb2.inputs[1])
|
||||||
|
@ -850,6 +1537,8 @@ MP3_PASS_GROUPS = (
|
||||||
)
|
)
|
||||||
|
|
||||||
def make_master_shader_library():
|
def make_master_shader_library():
|
||||||
|
for shad in ROOT_SHADER_GROUPS:
|
||||||
|
shad()
|
||||||
for uva in UV_ANIMATION_GROUPS:
|
for uva in UV_ANIMATION_GROUPS:
|
||||||
uva()
|
uva()
|
||||||
for aPass in MP3_PASS_GROUPS:
|
for aPass in MP3_PASS_GROUPS:
|
||||||
|
|
|
@ -100,14 +100,9 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
|
||||||
"bpy.context.scene.name = '%s'\n"
|
"bpy.context.scene.name = '%s'\n"
|
||||||
"bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n"
|
"bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n"
|
||||||
"\n"
|
"\n"
|
||||||
"# Using 'Blender Game'\n"
|
|
||||||
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
|
|
||||||
"\n"
|
|
||||||
"# Clear Scene\n"
|
"# Clear Scene\n"
|
||||||
"for ob in bpy.data.objects:\n"
|
"if 'Collection 1' in bpy.data.collections:\n"
|
||||||
" if ob.type != 'LAMP' and ob.type != 'CAMERA':\n"
|
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||||
" bpy.context.scene.objects.unlink(ob)\n"
|
|
||||||
" bpy.data.objects.remove(ob)\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"actor_data = bpy.context.scene.hecl_sact_data\n"
|
"actor_data = bpy.context.scene.hecl_sact_data\n"
|
||||||
"arm_obj = None\n",
|
"arm_obj = None\n",
|
||||||
|
@ -143,7 +138,7 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
|
||||||
|
|
||||||
/* Attach CMDL to CINF */
|
/* Attach CMDL to CINF */
|
||||||
os << "if obj.name not in bpy.context.scene.objects:\n"
|
os << "if obj.name not in bpy.context.scene.objects:\n"
|
||||||
" bpy.context.scene.objects.link(obj)\n"
|
" bpy.context.scene.collection.objects.link(obj)\n"
|
||||||
"obj.parent = arm_obj\n"
|
"obj.parent = arm_obj\n"
|
||||||
"obj.parent_type = 'ARMATURE'\n"
|
"obj.parent_type = 'ARMATURE'\n"
|
||||||
"actor_subtype.linked_mesh = obj.name\n\n";
|
"actor_subtype.linked_mesh = obj.name\n\n";
|
||||||
|
@ -162,7 +157,7 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
|
||||||
|
|
||||||
/* Attach CMDL to CINF */
|
/* Attach CMDL to CINF */
|
||||||
os << "if obj.name not in bpy.context.scene.objects:\n"
|
os << "if obj.name not in bpy.context.scene.objects:\n"
|
||||||
" bpy.context.scene.objects.link(obj)\n"
|
" bpy.context.scene.collection.objects.link(obj)\n"
|
||||||
"obj.parent = arm_obj\n"
|
"obj.parent = arm_obj\n"
|
||||||
"obj.parent_type = 'ARMATURE'\n"
|
"obj.parent_type = 'ARMATURE'\n"
|
||||||
"overlay.linked_mesh = obj.name\n\n";
|
"overlay.linked_mesh = obj.name\n\n";
|
||||||
|
@ -202,7 +197,7 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
|
||||||
|
|
||||||
/* Attach CMDL to CINF */
|
/* Attach CMDL to CINF */
|
||||||
os << "if obj.name not in bpy.context.scene.objects:\n"
|
os << "if obj.name not in bpy.context.scene.objects:\n"
|
||||||
" bpy.context.scene.objects.link(obj)\n"
|
" bpy.context.scene.collection.objects.link(obj)\n"
|
||||||
"obj.parent = arm_obj\n"
|
"obj.parent = arm_obj\n"
|
||||||
"obj.parent_type = 'ARMATURE'\n"
|
"obj.parent_type = 'ARMATURE'\n"
|
||||||
"attachment.linked_mesh = obj.name\n\n";
|
"attachment.linked_mesh = obj.name\n\n";
|
||||||
|
|
|
@ -18,42 +18,42 @@ void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLi
|
||||||
return;
|
return;
|
||||||
case BabeDeadLight::LightType::Directional:
|
case BabeDeadLight::LightType::Directional:
|
||||||
os.format(
|
os.format(
|
||||||
"lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'SUN')\n"
|
"lamp = bpy.data.lights.new('LAMP_%01u_%03u', 'SUN')\n"
|
||||||
"lamp.color = (%f,%f,%f)\n"
|
"lamp.color = (%f,%f,%f)\n"
|
||||||
"lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n"
|
"lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n"
|
||||||
"lamp_obj.rotation_mode = 'QUATERNION'\n"
|
"lamp_obj.rotation_mode = 'QUATERNION'\n"
|
||||||
"lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector((%f,%f,%f)))\n"
|
"lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector((%f,%f,%f)))\n"
|
||||||
"lamp.shadow_method = '%s'\n"
|
"lamp.use_shadow = %s\n"
|
||||||
"\n",
|
"\n",
|
||||||
s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], light.direction.simd[0],
|
s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], light.direction.simd[0],
|
||||||
light.direction.simd[1], light.direction.simd[2], light.castShadows ? "RAY_SHADOW" : "NOSHADOW");
|
light.direction.simd[1], light.direction.simd[2], light.castShadows ? "True" : "False");
|
||||||
return;
|
return;
|
||||||
case BabeDeadLight::LightType::Custom:
|
case BabeDeadLight::LightType::Custom:
|
||||||
os.format(
|
os.format(
|
||||||
"lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'POINT')\n"
|
"lamp = bpy.data.lights.new('LAMP_%01u_%03u', 'POINT')\n"
|
||||||
"lamp.color = (%f,%f,%f)\n"
|
"lamp.color = (%f,%f,%f)\n"
|
||||||
"lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n"
|
"lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n"
|
||||||
"lamp.shadow_soft_size = 1.0\n"
|
"lamp.shadow_soft_size = 1.0\n"
|
||||||
"lamp.shadow_method = '%s'\n"
|
"lamp.use_shadow = %s\n"
|
||||||
"\n",
|
"\n",
|
||||||
s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2],
|
s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2],
|
||||||
light.castShadows ? "RAY_SHADOW" : "NOSHADOW");
|
light.castShadows ? "True" : "False");
|
||||||
break;
|
break;
|
||||||
case BabeDeadLight::LightType::Spot:
|
case BabeDeadLight::LightType::Spot:
|
||||||
case BabeDeadLight::LightType::Spot2:
|
case BabeDeadLight::LightType::Spot2:
|
||||||
os.format(
|
os.format(
|
||||||
"lamp = bpy.data.lamps.new('LAMP_%01u_%03u', 'SPOT')\n"
|
"lamp = bpy.data.lights.new('LAMP_%01u_%03u', 'SPOT')\n"
|
||||||
"lamp.color = (%f,%f,%f)\n"
|
"lamp.color = (%f,%f,%f)\n"
|
||||||
"lamp.spot_size = %.6g\n"
|
"lamp.spot_size = %.6g\n"
|
||||||
"lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n"
|
"lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n"
|
||||||
"lamp_obj.rotation_mode = 'QUATERNION'\n"
|
"lamp_obj.rotation_mode = 'QUATERNION'\n"
|
||||||
"lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector((%f,%f,%f)))\n"
|
"lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector((%f,%f,%f)))\n"
|
||||||
"lamp.shadow_soft_size = 0.5\n"
|
"lamp.shadow_soft_size = 0.5\n"
|
||||||
"lamp.shadow_method = '%s'\n"
|
"lamp.use_shadow = %s\n"
|
||||||
"\n",
|
"\n",
|
||||||
s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], zeus::degToRad(light.spotCutoff),
|
s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], zeus::degToRad(light.spotCutoff),
|
||||||
light.direction.simd[0], light.direction.simd[1], light.direction.simd[2],
|
light.direction.simd[0], light.direction.simd[1], light.direction.simd[2],
|
||||||
light.castShadows ? "RAY_SHADOW" : "NOSHADOW");
|
light.castShadows ? "True" : "False");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
@ -73,7 +73,7 @@ void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLi
|
||||||
"hue_sat_node.inputs[4].default_value = (%f,%f,%f,1.0)\n"
|
"hue_sat_node.inputs[4].default_value = (%f,%f,%f,1.0)\n"
|
||||||
"lamp.node_tree.links.new(hue_sat_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[0])\n"
|
"lamp.node_tree.links.new(hue_sat_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[0])\n"
|
||||||
"lamp_obj.location = (%f,%f,%f)\n"
|
"lamp_obj.location = (%f,%f,%f)\n"
|
||||||
"bpy.context.scene.objects.link(lamp_obj)\n"
|
"bpy.context.scene.collection.objects.link(lamp_obj)\n"
|
||||||
"\n",
|
"\n",
|
||||||
s, light.lightType, light.q / 8.f, light.color.simd[0], light.color.simd[1], light.color.simd[2],
|
s, light.lightType, light.q / 8.f, light.color.simd[0], light.color.simd[1], light.color.simd[2],
|
||||||
light.position.simd[0], light.position.simd[1], light.position.simd[2]);
|
light.position.simd[0], light.position.simd[1], light.position.simd[2]);
|
||||||
|
|
|
@ -80,15 +80,12 @@ void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os, const Material
|
||||||
hecl::SystemString resPath = pakRouter.getResourceRelativePath(entry, tex);
|
hecl::SystemString resPath = pakRouter.getResourceRelativePath(entry, tex);
|
||||||
hecl::SystemUTF8Conv resPathView(resPath);
|
hecl::SystemUTF8Conv resPathView(resPath);
|
||||||
os.format(
|
os.format(
|
||||||
"if '%s' in bpy.data.textures:\n"
|
"if '%s' in bpy.data.images:\n"
|
||||||
" image = bpy.data.images['%s']\n"
|
" image = bpy.data.images['%s']\n"
|
||||||
" texture = bpy.data.textures[image.name]\n"
|
|
||||||
"else:\n"
|
"else:\n"
|
||||||
" image = bpy.data.images.load('''//%s''')\n"
|
" image = bpy.data.images.load('''//%s''')\n"
|
||||||
" image.name = '%s'\n"
|
" image.name = '%s'\n"
|
||||||
" texture = bpy.data.textures.new(image.name, 'IMAGE')\n"
|
"texmap_list.append(image)\n"
|
||||||
" texture.image = image\n"
|
|
||||||
"texmap_list.append(texture)\n"
|
|
||||||
"\n",
|
"\n",
|
||||||
texName.c_str(), texName.c_str(), resPathView.c_str(), texName.c_str());
|
texName.c_str(), texName.c_str(), resPathView.c_str(), texName.c_str());
|
||||||
}
|
}
|
||||||
|
@ -375,19 +372,13 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath,
|
void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath) {
|
||||||
bool solidShading) {
|
|
||||||
os << "import math\n"
|
os << "import math\n"
|
||||||
"from mathutils import Vector\n"
|
"from mathutils import Vector\n"
|
||||||
"\n"
|
"\n"
|
||||||
"# Using 'Blender Game'\n"
|
|
||||||
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
|
|
||||||
"\n"
|
|
||||||
"# Clear Scene\n"
|
"# Clear Scene\n"
|
||||||
"for ob in bpy.data.objects:\n"
|
"if 'Collection 1' in bpy.data.collections:\n"
|
||||||
" if ob.type != 'LAMP' and ob.type != 'CAMERA':\n"
|
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||||
" bpy.context.scene.objects.unlink(ob)\n"
|
|
||||||
" bpy.data.objects.remove(ob)\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"def loop_from_facevert(bm, face, vert_idx):\n"
|
"def loop_from_facevert(bm, face, vert_idx):\n"
|
||||||
" for loop in face.loops:\n"
|
" for loop in face.loops:\n"
|
||||||
|
@ -422,7 +413,7 @@ void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectP
|
||||||
" if od_entry is None:\n"
|
" if od_entry is None:\n"
|
||||||
" bm_cpy = bm.copy()\n"
|
" bm_cpy = bm.copy()\n"
|
||||||
" od_entry = {'material':mat_nr, 'bm':bm_cpy}\n"
|
" od_entry = {'material':mat_nr, 'bm':bm_cpy}\n"
|
||||||
" bmesh.ops.delete(od_entry['bm'], geom=od_entry['bm'].faces, context=3)\n"
|
" bmesh.ops.delete(od_entry['bm'], geom=od_entry['bm'].faces, context='FACES_ONLY')\n"
|
||||||
" od_list.append(od_entry)\n"
|
" od_list.append(od_entry)\n"
|
||||||
" od_entry['bm'].verts.ensure_lookup_table()\n"
|
" od_entry['bm'].verts.ensure_lookup_table()\n"
|
||||||
" verts = [od_entry['bm'].verts[i] for i in vert_indices]\n"
|
" verts = [od_entry['bm'].verts[i] for i in vert_indices]\n"
|
||||||
|
@ -469,13 +460,6 @@ void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectP
|
||||||
" return result\n"
|
" return result\n"
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
if (solidShading) {
|
|
||||||
os << "for ar in bpy.context.screen.areas:\n"
|
|
||||||
" for sp in ar.spaces:\n"
|
|
||||||
" if sp.type == 'VIEW_3D':\n"
|
|
||||||
" sp.viewport_shade = 'SOLID'\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Link master shader library */
|
/* Link master shader library */
|
||||||
os.format(
|
os.format(
|
||||||
"# Master shader library\n"
|
"# Master shader library\n"
|
||||||
|
@ -486,26 +470,27 @@ void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectP
|
||||||
}
|
}
|
||||||
|
|
||||||
void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx) {
|
void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx) {
|
||||||
if (meshIdx < 0)
|
os << "if 'Render' not in bpy.data.collections:\n"
|
||||||
os.format(
|
" coll = bpy.data.collections.new('Render')\n"
|
||||||
"mesh = bpy.data.meshes.new(bpy.context.scene.name)\n"
|
" bpy.context.scene.collection.children.link(coll)\n"
|
||||||
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
|
"else:\n"
|
||||||
"obj.show_transparent = True\n"
|
" coll = bpy.data.collections['Render']\n";
|
||||||
"bpy.context.scene.objects.link(obj)\n"
|
if (meshIdx < 0) {
|
||||||
"mesh.hecl_material_count = %u\n",
|
os << "mesh = bpy.data.meshes.new(bpy.context.scene.name)\n"
|
||||||
matSetCount);
|
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
|
||||||
else
|
"obj.show_transparent = True\n"
|
||||||
os.format(
|
"coll.objects.link(obj)\n";
|
||||||
"mesh = bpy.data.meshes.new(bpy.context.scene.name + '_%03d')\n"
|
os.format("mesh.hecl_material_count = %u\n", matSetCount);
|
||||||
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
|
} else {
|
||||||
"obj.show_transparent = True\n"
|
os.format("mesh = bpy.data.meshes.new(bpy.context.scene.name + '_%03d')\n", meshIdx);
|
||||||
"bpy.context.scene.objects.link(obj)\n"
|
os << "obj = bpy.data.objects.new(mesh.name, mesh)\n"
|
||||||
"mesh.hecl_material_count = %u\n",
|
"obj.show_transparent = True\n"
|
||||||
meshIdx, matSetCount);
|
"coll.objects.link(obj)\n";
|
||||||
|
os.format("mesh.hecl_material_count = %u\n", matSetCount);
|
||||||
|
}
|
||||||
|
|
||||||
os << "mesh.use_auto_smooth = True\n"
|
os << "mesh.use_auto_smooth = True\n"
|
||||||
"mesh.auto_smooth_angle = math.pi\n"
|
"mesh.auto_smooth_angle = math.pi\n"
|
||||||
"mesh.show_edge_sharp = True\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"for material in materials:\n"
|
"for material in materials:\n"
|
||||||
" mesh.materials.append(material)\n"
|
" mesh.materials.append(material)\n"
|
||||||
|
@ -549,7 +534,7 @@ void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int
|
||||||
"for v in bm.verts:\n"
|
"for v in bm.verts:\n"
|
||||||
" if len(v.link_faces) == 0:\n"
|
" if len(v.link_faces) == 0:\n"
|
||||||
" verts_to_del.append(v)\n"
|
" verts_to_del.append(v)\n"
|
||||||
"bmesh.ops.delete(bm, geom=verts_to_del, context=1)\n"
|
"bmesh.ops.delete(bm, geom=verts_to_del, context='VERTS')\n"
|
||||||
"\n"
|
"\n"
|
||||||
"for edge in bm.edges:\n"
|
"for edge in bm.edges:\n"
|
||||||
" if edge.is_manifold:\n"
|
" if edge.is_manifold:\n"
|
||||||
|
@ -1037,7 +1022,7 @@ bool ReadCMDLToBlender(hecl::blender::Connection& conn, athena::io::IStreamReade
|
||||||
"bpy.context.scene.name = '%s'\n"
|
"bpy.context.scene.name = '%s'\n"
|
||||||
"bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n",
|
"bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n",
|
||||||
pakRouter.getBestEntryName(entry).c_str());
|
pakRouter.getBestEntryName(entry).c_str());
|
||||||
InitGeomBlenderContext(os, dataspec.getMasterShaderPath(), false);
|
InitGeomBlenderContext(os, dataspec.getMasterShaderPath());
|
||||||
MaterialSet::RegisterMaterialProps(os);
|
MaterialSet::RegisterMaterialProps(os);
|
||||||
|
|
||||||
os << "# Materials\n"
|
os << "# Materials\n"
|
||||||
|
@ -1142,9 +1127,9 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
|
||||||
|
|
||||||
/* Build material sets */
|
/* Build material sets */
|
||||||
std::vector<MaterialSet> matSets;
|
std::vector<MaterialSet> matSets;
|
||||||
|
#if 0
|
||||||
matSets.reserve(mesh.materialSets.size());
|
matSets.reserve(mesh.materialSets.size());
|
||||||
{
|
{
|
||||||
hecl::Frontend::Frontend FE;
|
|
||||||
for (const std::vector<Material>& mset : mesh.materialSets) {
|
for (const std::vector<Material>& mset : mesh.materialSets) {
|
||||||
matSets.emplace_back();
|
matSets.emplace_back();
|
||||||
MaterialSet& targetMSet = matSets.back();
|
MaterialSet& targetMSet = matSets.back();
|
||||||
|
@ -1191,6 +1176,7 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
|
||||||
paddingSizes.push_back(secSz32 - secSz);
|
paddingSizes.push_back(secSz32 - secSz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Vertex Positions */
|
/* Vertex Positions */
|
||||||
size_t secSz = mesh.pos.size() * 12;
|
size_t secSz = mesh.pos.size() * 12;
|
||||||
|
@ -1435,44 +1421,24 @@ bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& in
|
||||||
/* Build material sets */
|
/* Build material sets */
|
||||||
std::vector<MaterialSet> matSets;
|
std::vector<MaterialSet> matSets;
|
||||||
matSets.reserve(mesh.materialSets.size());
|
matSets.reserve(mesh.materialSets.size());
|
||||||
{
|
|
||||||
hecl::Frontend::Frontend FE;
|
|
||||||
for (const std::vector<Material>& mset : mesh.materialSets) {
|
|
||||||
matSets.emplace_back();
|
|
||||||
MaterialSet& targetMSet = matSets.back();
|
|
||||||
std::vector<hecl::ProjectPath> texPaths;
|
|
||||||
texPaths.reserve(mset.size() * 4);
|
|
||||||
for (const Material& mat : mset) {
|
|
||||||
for (const hecl::ProjectPath& path : mat.texs) {
|
|
||||||
bool found = false;
|
|
||||||
for (const hecl::ProjectPath& ePath : texPaths) {
|
|
||||||
if (path == ePath) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
texPaths.push_back(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t endOff = 0;
|
for (const std::vector<Material>& mset : mesh.materialSets) {
|
||||||
for (const Material& mat : mset) {
|
matSets.emplace_back();
|
||||||
std::string diagName = hecl::Format("%s:%s", inPath.getLastComponentUTF8().data(), mat.name.c_str());
|
MaterialSet& targetMSet = matSets.back();
|
||||||
targetMSet.materials.emplace_back(FE, diagName, mat, mat.iprops, texPaths);
|
|
||||||
targetMSet.materials.back().binarySize(endOff);
|
|
||||||
targetMSet.head.addMaterialEndOff(endOff);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const hecl::ProjectPath& path : texPaths)
|
size_t endOff = 0;
|
||||||
targetMSet.head.addTexture(path);
|
for (const Material& mat : mset) {
|
||||||
|
++targetMSet.materialCount;
|
||||||
size_t secSz = 0;
|
targetMSet.materials.emplace_back(mat);
|
||||||
targetMSet.binarySize(secSz);
|
targetMSet.materials.back().binarySize(endOff);
|
||||||
size_t secSz32 = ROUND_UP_32(secSz);
|
targetMSet.materialEndOffs.push_back(endOff);
|
||||||
head.secSizes.push_back(secSz32);
|
|
||||||
paddingSizes.push_back(secSz32 - secSz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t secSz = 0;
|
||||||
|
targetMSet.binarySize(secSz);
|
||||||
|
size_t secSz32 = ROUND_UP_32(secSz);
|
||||||
|
head.secSizes.push_back(secSz32);
|
||||||
|
paddingSizes.push_back(secSz32 - secSz);
|
||||||
}
|
}
|
||||||
|
|
||||||
hecl::blender::HMDLBuffers bufs = mesh.getHMDLBuffers(false, poolSkinIndex);
|
hecl::blender::HMDLBuffers bufs = mesh.getHMDLBuffers(false, poolSkinIndex);
|
||||||
|
@ -1614,10 +1580,8 @@ bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::Proje
|
||||||
surfCount += mesh.surfaces.size();
|
surfCount += mesh.surfaces.size();
|
||||||
surfToGlobalMats.reserve(surfCount);
|
surfToGlobalMats.reserve(surfCount);
|
||||||
|
|
||||||
hecl::Frontend::Frontend FE;
|
|
||||||
size_t endOff = 0;
|
size_t endOff = 0;
|
||||||
std::vector<hecl::ProjectPath> texPaths;
|
std::vector<hecl::ProjectPath> texPaths;
|
||||||
std::vector<hecl::Backend::GX> setBackends;
|
|
||||||
for (const Mesh& mesh : meshes) {
|
for (const Mesh& mesh : meshes) {
|
||||||
if (mesh.materialSets.size()) {
|
if (mesh.materialSets.size()) {
|
||||||
std::vector<size_t> meshToGlobalMats;
|
std::vector<size_t> meshToGlobalMats;
|
||||||
|
@ -1630,28 +1594,24 @@ bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::Proje
|
||||||
if (!newMat)
|
if (!newMat)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (const hecl::ProjectPath& path : mat.texs) {
|
for (const auto& chunk : mat.chunks) {
|
||||||
bool found = false;
|
if (auto pass = chunk.get_if<Material::PASS>()) {
|
||||||
for (const hecl::ProjectPath& ePath : texPaths) {
|
bool found = false;
|
||||||
if (path == ePath) {
|
for (const hecl::ProjectPath& ePath : texPaths) {
|
||||||
found = true;
|
if (pass->tex == ePath) {
|
||||||
break;
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (!found)
|
||||||
|
texPaths.push_back(pass->tex);
|
||||||
}
|
}
|
||||||
if (!found)
|
|
||||||
texPaths.push_back(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string diagName = hecl::Format("%s:%s", inPath.getLastComponentUTF8().data(), mat.name.c_str());
|
|
||||||
hecl::Frontend::IR matIR = FE.compileSource(mat.source, diagName);
|
|
||||||
setBackends.emplace_back();
|
|
||||||
hecl::Backend::GX& matGX = setBackends.back();
|
|
||||||
matGX.reset(matIR, FE.getDiagnostics());
|
|
||||||
|
|
||||||
auto lightmapped = mat.iprops.find("retro_lightmapped");
|
auto lightmapped = mat.iprops.find("retro_lightmapped");
|
||||||
bool lm = lightmapped != mat.iprops.cend() && lightmapped->second != 0;
|
bool lm = lightmapped != mat.iprops.cend() && lightmapped->second != 0;
|
||||||
|
|
||||||
matSet.materials.emplace_back(matGX, mat.iprops, mat.texs, texPaths, mesh.colorLayerCount, lm, false);
|
matSet.materials.emplace_back(mat, texPaths, mesh.colorLayerCount, lm, false);
|
||||||
|
|
||||||
matSet.materials.back().binarySize(endOff);
|
matSet.materials.back().binarySize(endOff);
|
||||||
matSet.head.addMaterialEndOff(endOff);
|
matSet.head.addMaterialEndOff(endOff);
|
||||||
|
@ -1917,10 +1877,8 @@ bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::P
|
||||||
surfCount += mesh.surfaces.size();
|
surfCount += mesh.surfaces.size();
|
||||||
surfToGlobalMats.reserve(surfCount);
|
surfToGlobalMats.reserve(surfCount);
|
||||||
|
|
||||||
MaterialSet matSet;
|
MaterialSet matSet = {};
|
||||||
hecl::Frontend::Frontend FE;
|
|
||||||
size_t endOff = 0;
|
size_t endOff = 0;
|
||||||
std::vector<hecl::ProjectPath> texPaths;
|
|
||||||
for (const Mesh& mesh : meshes) {
|
for (const Mesh& mesh : meshes) {
|
||||||
if (mesh.materialSets.size()) {
|
if (mesh.materialSets.size()) {
|
||||||
std::vector<size_t> meshToGlobalMats;
|
std::vector<size_t> meshToGlobalMats;
|
||||||
|
@ -1933,30 +1891,16 @@ bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::P
|
||||||
if (!newMat)
|
if (!newMat)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (const hecl::ProjectPath& path : mat.texs) {
|
++matSet.materialCount;
|
||||||
bool found = false;
|
matSet.materials.emplace_back(mat);
|
||||||
for (const hecl::ProjectPath& ePath : texPaths) {
|
|
||||||
if (path == ePath) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
texPaths.push_back(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string diagName = hecl::Format("%s:%s", inPath.getLastComponentUTF8().data(), mat.name.c_str());
|
|
||||||
matSet.materials.emplace_back(FE, diagName, mat, mat.iprops, texPaths);
|
|
||||||
matSet.materials.back().binarySize(endOff);
|
matSet.materials.back().binarySize(endOff);
|
||||||
matSet.head.addMaterialEndOff(endOff);
|
matSet.materialEndOffs.push_back(endOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const Mesh::Surface& surf : mesh.surfaces)
|
for (const Mesh::Surface& surf : mesh.surfaces)
|
||||||
surfToGlobalMats.push_back(meshToGlobalMats[surf.materialIdx]);
|
surfToGlobalMats.push_back(meshToGlobalMats[surf.materialIdx]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const hecl::ProjectPath& path : texPaths)
|
|
||||||
matSet.head.addTexture(path);
|
|
||||||
|
|
||||||
size_t secSz = 0;
|
size_t secSz = 0;
|
||||||
matSet.binarySize(secSz);
|
matSet.binarySize(secSz);
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "athena/FileWriter.hpp"
|
#include "athena/FileWriter.hpp"
|
||||||
#include "hecl/Frontend.hpp"
|
|
||||||
#include "hecl/Backend/GX.hpp"
|
|
||||||
#include "PAK.hpp"
|
#include "PAK.hpp"
|
||||||
#include "GX.hpp"
|
#include "GX.hpp"
|
||||||
#include "TXTR.hpp"
|
#include "TXTR.hpp"
|
||||||
|
@ -121,8 +119,7 @@ template <class PAKRouter, class MaterialSet>
|
||||||
void ReadMaterialSetToBlender_3(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter,
|
void ReadMaterialSetToBlender_3(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter,
|
||||||
const typename PAKRouter::EntryType& entry, unsigned setIdx);
|
const typename PAKRouter::EntryType& entry, unsigned setIdx);
|
||||||
|
|
||||||
void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath,
|
void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath);
|
||||||
bool solidShading);
|
|
||||||
void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx);
|
void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx);
|
||||||
|
|
||||||
template <class PAKRouter, class MaterialSet, class RigPair, class SurfaceHeader>
|
template <class PAKRouter, class MaterialSet, class RigPair, class SurfaceHeader>
|
||||||
|
|
|
@ -13,7 +13,7 @@ make_dnalist(liblist DNACommon
|
||||||
set(DNACOMMON_SOURCES
|
set(DNACOMMON_SOURCES
|
||||||
DNACommon.hpp DNACommon.cpp
|
DNACommon.hpp DNACommon.cpp
|
||||||
PAK.hpp PAK.cpp
|
PAK.hpp PAK.cpp
|
||||||
GX.hpp
|
GX.hpp GX.cpp
|
||||||
FSM2.hpp FSM2.cpp
|
FSM2.hpp FSM2.cpp
|
||||||
MLVL.hpp MLVL.cpp
|
MLVL.hpp MLVL.cpp
|
||||||
CMDL.cpp
|
CMDL.cpp
|
||||||
|
|
|
@ -75,18 +75,18 @@ void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, b
|
||||||
" mat = material_dict[mat_name]\n"
|
" mat = material_dict[mat_name]\n"
|
||||||
" col_mesh.materials.append(mat)\n"
|
" col_mesh.materials.append(mat)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"bpy.context.scene.objects.link(col_mesh_obj)\n"
|
"if 'Collision' not in bpy.data.collections:\n"
|
||||||
"bpy.context.scene.objects.active = col_mesh_obj\n"
|
" coll = bpy.data.collections.new('Collision')\n"
|
||||||
|
" bpy.context.scene.collection.children.link(coll)\n"
|
||||||
|
"else:\n"
|
||||||
|
" coll = bpy.data.collections['Collision']\n"
|
||||||
|
"coll.objects.link(col_mesh_obj)\n"
|
||||||
|
"bpy.context.view_layer.objects.active = col_mesh_obj\n"
|
||||||
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
||||||
"bpy.ops.mesh.tris_convert_to_quads()\n"
|
"bpy.ops.mesh.tris_convert_to_quads()\n"
|
||||||
"bpy.ops.object.mode_set(mode='OBJECT')\n"
|
"bpy.ops.object.mode_set(mode='OBJECT')\n"
|
||||||
"bpy.context.scene.objects.active = None\n";
|
"bpy.context.view_layer.objects.active = None\n"
|
||||||
if (!isDcln)
|
"col_mesh_obj.display_type = 'SOLID'\n"
|
||||||
os << "col_mesh_obj.layers[1] = True\n"
|
|
||||||
"col_mesh_obj.layers[0] = False\n";
|
|
||||||
|
|
||||||
os << "col_mesh_obj.draw_type = 'SOLID'\n"
|
|
||||||
"col_mesh_obj.game.physics_type = 'STATIC'\n"
|
|
||||||
"\n";
|
"\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#include "GX.hpp"
|
||||||
|
|
||||||
|
namespace GX {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void Color::Enumerate<athena::io::DNA<athena::Big>::Read>(typename Read::StreamT& reader) {
|
||||||
|
reader.readUBytesToBuf(&num, 4);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
void Color::Enumerate<athena::io::DNA<athena::Big>::Write>(typename Write::StreamT& writer) {
|
||||||
|
writer.writeUBytes(reinterpret_cast<const atUint8*>(&num), 4);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
void Color::Enumerate<athena::io::DNA<athena::Big>::BinarySize>(typename BinarySize::StreamT& s) {
|
||||||
|
s += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,296 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "athena/DNA.hpp"
|
||||||
|
|
||||||
|
namespace GX {
|
||||||
|
enum AttrType { NONE, DIRECT, INDEX8, INDEX16 };
|
||||||
|
|
||||||
|
enum TevColorArg {
|
||||||
|
CC_CPREV = 0,
|
||||||
|
CC_APREV = 1,
|
||||||
|
CC_C0 = 2,
|
||||||
|
CC_A0 = 3,
|
||||||
|
CC_C1 = 4,
|
||||||
|
CC_A1 = 5,
|
||||||
|
CC_C2 = 6,
|
||||||
|
CC_A2 = 7,
|
||||||
|
CC_TEXC = 8,
|
||||||
|
CC_TEXA = 9,
|
||||||
|
CC_RASC = 10,
|
||||||
|
CC_RASA = 11,
|
||||||
|
CC_ONE = 12,
|
||||||
|
CC_HALF = 13,
|
||||||
|
CC_KONST = 14,
|
||||||
|
CC_ZERO = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TevAlphaArg {
|
||||||
|
CA_APREV = 0,
|
||||||
|
CA_A0 = 1,
|
||||||
|
CA_A1 = 2,
|
||||||
|
CA_A2 = 3,
|
||||||
|
CA_TEXA = 4,
|
||||||
|
CA_RASA = 5,
|
||||||
|
CA_KONST = 6,
|
||||||
|
CA_ZERO = 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TevKColorSel {
|
||||||
|
TEV_KCSEL_8_8 = 0x00,
|
||||||
|
TEV_KCSEL_7_8 = 0x01,
|
||||||
|
TEV_KCSEL_6_8 = 0x02,
|
||||||
|
TEV_KCSEL_5_8 = 0x03,
|
||||||
|
TEV_KCSEL_4_8 = 0x04,
|
||||||
|
TEV_KCSEL_3_8 = 0x05,
|
||||||
|
TEV_KCSEL_2_8 = 0x06,
|
||||||
|
TEV_KCSEL_1_8 = 0x07,
|
||||||
|
|
||||||
|
TEV_KCSEL_1 = TEV_KCSEL_8_8,
|
||||||
|
TEV_KCSEL_3_4 = TEV_KCSEL_6_8,
|
||||||
|
TEV_KCSEL_1_2 = TEV_KCSEL_4_8,
|
||||||
|
TEV_KCSEL_1_4 = TEV_KCSEL_2_8,
|
||||||
|
|
||||||
|
TEV_KCSEL_K0 = 0x0C,
|
||||||
|
TEV_KCSEL_K1 = 0x0D,
|
||||||
|
TEV_KCSEL_K2 = 0x0E,
|
||||||
|
TEV_KCSEL_K3 = 0x0F,
|
||||||
|
TEV_KCSEL_K0_R = 0x10,
|
||||||
|
TEV_KCSEL_K1_R = 0x11,
|
||||||
|
TEV_KCSEL_K2_R = 0x12,
|
||||||
|
TEV_KCSEL_K3_R = 0x13,
|
||||||
|
TEV_KCSEL_K0_G = 0x14,
|
||||||
|
TEV_KCSEL_K1_G = 0x15,
|
||||||
|
TEV_KCSEL_K2_G = 0x16,
|
||||||
|
TEV_KCSEL_K3_G = 0x17,
|
||||||
|
TEV_KCSEL_K0_B = 0x18,
|
||||||
|
TEV_KCSEL_K1_B = 0x19,
|
||||||
|
TEV_KCSEL_K2_B = 0x1A,
|
||||||
|
TEV_KCSEL_K3_B = 0x1B,
|
||||||
|
TEV_KCSEL_K0_A = 0x1C,
|
||||||
|
TEV_KCSEL_K1_A = 0x1D,
|
||||||
|
TEV_KCSEL_K2_A = 0x1E,
|
||||||
|
TEV_KCSEL_K3_A = 0x1F
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TevKAlphaSel {
|
||||||
|
TEV_KASEL_8_8 = 0x00,
|
||||||
|
TEV_KASEL_7_8 = 0x01,
|
||||||
|
TEV_KASEL_6_8 = 0x02,
|
||||||
|
TEV_KASEL_5_8 = 0x03,
|
||||||
|
TEV_KASEL_4_8 = 0x04,
|
||||||
|
TEV_KASEL_3_8 = 0x05,
|
||||||
|
TEV_KASEL_2_8 = 0x06,
|
||||||
|
TEV_KASEL_1_8 = 0x07,
|
||||||
|
|
||||||
|
TEV_KASEL_1 = TEV_KASEL_8_8,
|
||||||
|
TEV_KASEL_3_4 = TEV_KASEL_6_8,
|
||||||
|
TEV_KASEL_1_2 = TEV_KASEL_4_8,
|
||||||
|
TEV_KASEL_1_4 = TEV_KASEL_2_8,
|
||||||
|
|
||||||
|
TEV_KASEL_K0_R = 0x10,
|
||||||
|
TEV_KASEL_K1_R = 0x11,
|
||||||
|
TEV_KASEL_K2_R = 0x12,
|
||||||
|
TEV_KASEL_K3_R = 0x13,
|
||||||
|
TEV_KASEL_K0_G = 0x14,
|
||||||
|
TEV_KASEL_K1_G = 0x15,
|
||||||
|
TEV_KASEL_K2_G = 0x16,
|
||||||
|
TEV_KASEL_K3_G = 0x17,
|
||||||
|
TEV_KASEL_K0_B = 0x18,
|
||||||
|
TEV_KASEL_K1_B = 0x19,
|
||||||
|
TEV_KASEL_K2_B = 0x1A,
|
||||||
|
TEV_KASEL_K3_B = 0x1B,
|
||||||
|
TEV_KASEL_K0_A = 0x1C,
|
||||||
|
TEV_KASEL_K1_A = 0x1D,
|
||||||
|
TEV_KASEL_K2_A = 0x1E,
|
||||||
|
TEV_KASEL_K3_A = 0x1F
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TevOp {
|
||||||
|
TEV_ADD = 0,
|
||||||
|
TEV_SUB = 1,
|
||||||
|
TEV_COMP_R8_GT = 8,
|
||||||
|
TEV_COMP_R8_EQ = 9,
|
||||||
|
TEV_COMP_GR16_GT = 10,
|
||||||
|
TEV_COMP_GR16_EQ = 11,
|
||||||
|
TEV_COMP_BGR24_GT = 12,
|
||||||
|
TEV_COMP_BGR24_EQ = 13,
|
||||||
|
TEV_COMP_RGB8_GT = 14,
|
||||||
|
TEV_COMP_RGB8_EQ = 15,
|
||||||
|
TEV_COMP_A8_GT = TEV_COMP_RGB8_GT,
|
||||||
|
TEV_COMP_A8_EQ = TEV_COMP_RGB8_EQ
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TevBias {
|
||||||
|
TB_ZERO = 0,
|
||||||
|
TB_ADDHALF = 1,
|
||||||
|
TB_SUBHALF = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TevScale { CS_SCALE_1 = 0, CS_SCALE_2 = 1, CS_SCALE_4 = 2, CS_DIVIDE_2 = 3 };
|
||||||
|
|
||||||
|
enum TexGenType {
|
||||||
|
TG_MTX3x4 = 0,
|
||||||
|
TG_MTX2x4,
|
||||||
|
TG_BUMP0,
|
||||||
|
TG_BUMP1,
|
||||||
|
TG_BUMP2,
|
||||||
|
TG_BUMP3,
|
||||||
|
TG_BUMP4,
|
||||||
|
TG_BUMP5,
|
||||||
|
TG_BUMP6,
|
||||||
|
TG_BUMP7,
|
||||||
|
TG_SRTG
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TexGenSrc {
|
||||||
|
TG_POS = 0,
|
||||||
|
TG_NRM,
|
||||||
|
TG_BINRM,
|
||||||
|
TG_TANGENT,
|
||||||
|
TG_TEX0,
|
||||||
|
TG_TEX1,
|
||||||
|
TG_TEX2,
|
||||||
|
TG_TEX3,
|
||||||
|
TG_TEX4,
|
||||||
|
TG_TEX5,
|
||||||
|
TG_TEX6,
|
||||||
|
TG_TEX7,
|
||||||
|
TG_TEXCOORD0,
|
||||||
|
TG_TEXCOORD1,
|
||||||
|
TG_TEXCOORD2,
|
||||||
|
TG_TEXCOORD3,
|
||||||
|
TG_TEXCOORD4,
|
||||||
|
TG_TEXCOORD5,
|
||||||
|
TG_TEXCOORD6,
|
||||||
|
TG_COLOR0,
|
||||||
|
TG_COLOR1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TexMtx {
|
||||||
|
TEXMTX0 = 30,
|
||||||
|
TEXMTX1 = 33,
|
||||||
|
TEXMTX2 = 36,
|
||||||
|
TEXMTX3 = 39,
|
||||||
|
TEXMTX4 = 42,
|
||||||
|
TEXMTX5 = 45,
|
||||||
|
TEXMTX6 = 48,
|
||||||
|
TEXMTX7 = 51,
|
||||||
|
TEXMTX8 = 54,
|
||||||
|
TEXMTX9 = 57,
|
||||||
|
IDENTITY = 60
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PTTexMtx {
|
||||||
|
PTTEXMTX0 = 64,
|
||||||
|
PTTEXMTX1 = 67,
|
||||||
|
PTTEXMTX2 = 70,
|
||||||
|
PTTEXMTX3 = 73,
|
||||||
|
PTTEXMTX4 = 76,
|
||||||
|
PTTEXMTX5 = 79,
|
||||||
|
PTTEXMTX6 = 82,
|
||||||
|
PTTEXMTX7 = 85,
|
||||||
|
PTTEXMTX8 = 88,
|
||||||
|
PTTEXMTX9 = 91,
|
||||||
|
PTTEXMTX10 = 94,
|
||||||
|
PTTEXMTX11 = 97,
|
||||||
|
PTTEXMTX12 = 100,
|
||||||
|
PTTEXMTX13 = 103,
|
||||||
|
PTTEXMTX14 = 106,
|
||||||
|
PTTEXMTX15 = 109,
|
||||||
|
PTTEXMTX16 = 112,
|
||||||
|
PTTEXMTX17 = 115,
|
||||||
|
PTTEXMTX18 = 118,
|
||||||
|
PTTEXMTX19 = 121,
|
||||||
|
PTIDENTITY = 125
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TevRegID { TEVPREV = 0, TEVREG0 = 1, TEVREG1 = 2, TEVREG2 = 3, TEVLAZY = 5 };
|
||||||
|
|
||||||
|
enum DiffuseFn { DF_NONE = 0, DF_SIGN, DF_CLAMP };
|
||||||
|
|
||||||
|
enum AttnFn { AF_SPEC = 0, AF_SPOT = 1, AF_NONE };
|
||||||
|
|
||||||
|
enum Primitive {
|
||||||
|
POINTS = 0xb8,
|
||||||
|
LINES = 0xa8,
|
||||||
|
LINESTRIP = 0xb0,
|
||||||
|
TRIANGLES = 0x90,
|
||||||
|
TRIANGLESTRIP = 0x98,
|
||||||
|
TRIANGLEFAN = 0xa0,
|
||||||
|
QUADS = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ChannelID {
|
||||||
|
GX_COLOR0,
|
||||||
|
GX_COLOR1,
|
||||||
|
GX_ALPHA0,
|
||||||
|
GX_ALPHA1,
|
||||||
|
GX_COLOR0A0,
|
||||||
|
GX_COLOR1A1,
|
||||||
|
GX_COLOR_ZERO,
|
||||||
|
GX_ALPHA_BUMP,
|
||||||
|
GX_ALPHA_BUMPN,
|
||||||
|
GX_COLOR_NULL = 0xff
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BlendFactor : uint16_t {
|
||||||
|
BL_ZERO,
|
||||||
|
BL_ONE,
|
||||||
|
BL_SRCCLR,
|
||||||
|
BL_INVSRCCLR,
|
||||||
|
BL_SRCALPHA,
|
||||||
|
BL_INVSRCALPHA,
|
||||||
|
BL_DSTALPHA,
|
||||||
|
BL_INVDSTALPHA
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Color : athena::io::DNA<athena::Big> {
|
||||||
|
union {
|
||||||
|
uint8_t color[4];
|
||||||
|
uint32_t num = 0;
|
||||||
|
};
|
||||||
|
Color() = default;
|
||||||
|
Color& operator=(const atVec4f& vec) {
|
||||||
|
athena::simd_floats f(vec.simd);
|
||||||
|
color[0] = uint8_t(std::min(std::max(f[0] * 255.f, 0.f), 255.f));
|
||||||
|
color[1] = uint8_t(std::min(std::max(f[1] * 255.f, 0.f), 255.f));
|
||||||
|
color[2] = uint8_t(std::min(std::max(f[2] * 255.f, 0.f), 255.f));
|
||||||
|
color[3] = uint8_t(std::min(std::max(f[3] * 255.f, 0.f), 255.f));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Color& operator=(const atVec3f& vec) {
|
||||||
|
athena::simd_floats f(vec.simd);
|
||||||
|
color[0] = uint8_t(std::min(std::max(f[0] * 255.f, 0.f), 255.f));
|
||||||
|
color[1] = uint8_t(std::min(std::max(f[1] * 255.f, 0.f), 255.f));
|
||||||
|
color[2] = uint8_t(std::min(std::max(f[2] * 255.f, 0.f), 255.f));
|
||||||
|
color[3] = 0xff;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Color& operator=(uint8_t val) {
|
||||||
|
color[0] = val;
|
||||||
|
color[1] = val;
|
||||||
|
color[2] = val;
|
||||||
|
color[3] = val;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
atVec4f toVec4f() const {
|
||||||
|
atVec4f out;
|
||||||
|
athena::simd_floats f;
|
||||||
|
f[0] = color[0] / 255.f;
|
||||||
|
f[1] = color[1] / 255.f;
|
||||||
|
f[2] = color[2] / 255.f;
|
||||||
|
f[3] = color[3] / 255.f;
|
||||||
|
out.simd.copy_from(f);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
Color(const atVec4f& vec) { *this = vec; }
|
||||||
|
Color(const atVec3f& vec) { *this = vec; }
|
||||||
|
Color(uint8_t val) { *this = val; }
|
||||||
|
bool operator==(const Color& other) const { return num == other.num; }
|
||||||
|
bool operator!=(const Color& other) const { return num != other.num; }
|
||||||
|
uint8_t operator[](size_t idx) const { return color[idx]; }
|
||||||
|
uint8_t& operator[](size_t idx) { return color[idx]; }
|
||||||
|
AT_DECL_EXPLICIT_DNA
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#include "hecl/Backend/GX.hpp"
|
|
||||||
using GX = hecl::Backend::GX;
|
|
||||||
|
|
|
@ -120,16 +120,9 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const
|
||||||
"('MAPSTATIONORVISIT2', 'Map Station or Visit 2', 'Visible after Map Station or Visit', 4)],"
|
"('MAPSTATIONORVISIT2', 'Map Station or Visit 2', 'Visible after Map Station or Visit', 4)],"
|
||||||
"name='Retro: Map Object Visibility Mode')\n"
|
"name='Retro: Map Object Visibility Mode')\n"
|
||||||
"\n"
|
"\n"
|
||||||
"for ar in bpy.context.screen.areas:\n"
|
|
||||||
" for sp in ar.spaces:\n"
|
|
||||||
" if sp.type == 'VIEW_3D':\n"
|
|
||||||
" sp.viewport_shade = 'SOLID'\n"
|
|
||||||
"\n"
|
|
||||||
"# Clear Scene\n"
|
"# Clear Scene\n"
|
||||||
"for ob in bpy.data.objects:\n"
|
"if 'Collection 1' in bpy.data.collections:\n"
|
||||||
" if ob.type != 'CAMERA':\n"
|
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||||
" bpy.context.scene.objects.unlink(ob)\n"
|
|
||||||
" bpy.data.objects.remove(ob)\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"def add_triangle(bm, verts):\n"
|
"def add_triangle(bm, verts):\n"
|
||||||
" verts = [bm.verts[vi] for vi in verts]\n"
|
" verts = [bm.verts[vi] for vi in verts]\n"
|
||||||
|
@ -164,7 +157,7 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const
|
||||||
moMP12->transformMtx[i].simd.copy_to(mtxF[i]);
|
moMP12->transformMtx[i].simd.copy_to(mtxF[i]);
|
||||||
os.format(
|
os.format(
|
||||||
"obj = bpy.data.objects.new('MAPOBJ_%02d', None)\n"
|
"obj = bpy.data.objects.new('MAPOBJ_%02d', None)\n"
|
||||||
"bpy.context.scene.objects.link(obj)\n"
|
"bpy.context.scene.collection.objects.link(obj)\n"
|
||||||
"obj.retro_mappable_type = %d\n"
|
"obj.retro_mappable_type = %d\n"
|
||||||
"obj.retro_mapobj_vis_mode = '%s'\n"
|
"obj.retro_mapobj_vis_mode = '%s'\n"
|
||||||
"obj.retro_mappable_sclyid = '0x%08X'\n"
|
"obj.retro_mappable_sclyid = '0x%08X'\n"
|
||||||
|
@ -185,7 +178,7 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const
|
||||||
moMP3->transformMtx[i].simd.copy_to(mtxF[i]);
|
moMP3->transformMtx[i].simd.copy_to(mtxF[i]);
|
||||||
os.format(
|
os.format(
|
||||||
"obj = bpy.data.objects.new('MAPOBJ_%02d', None)\n"
|
"obj = bpy.data.objects.new('MAPOBJ_%02d', None)\n"
|
||||||
"bpy.context.scene.objects.link(obj)\n"
|
"bpy.context.scene.collection.objects.link(obj)\n"
|
||||||
"obj.retro_mappable_type = %d\n"
|
"obj.retro_mappable_type = %d\n"
|
||||||
"obj.retro_mapobj_vis_mode = '%s'\n"
|
"obj.retro_mapobj_vis_mode = '%s'\n"
|
||||||
"obj.retro_mappable_sclyid = '0x%08X'\n"
|
"obj.retro_mappable_sclyid = '0x%08X'\n"
|
||||||
|
@ -272,10 +265,9 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "mesh = bpy.data.meshes.new('MAP')\n"
|
os << "mesh = bpy.data.meshes.new('MAP')\n"
|
||||||
"mesh.show_edge_seams = True\n"
|
|
||||||
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
|
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
|
||||||
"bm.to_mesh(mesh)\n"
|
"bm.to_mesh(mesh)\n"
|
||||||
"bpy.context.scene.objects.link(obj)\n"
|
"bpy.context.scene.collection.objects.link(obj)\n"
|
||||||
"bm.free()\n";
|
"bm.free()\n";
|
||||||
|
|
||||||
const zeus::CMatrix4f* tmpMtx = pakRouter.lookupMAPATransform(entry.id);
|
const zeus::CMatrix4f* tmpMtx = pakRouter.lookupMAPATransform(entry.id);
|
||||||
|
|
|
@ -21,10 +21,8 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
|
||||||
"from mathutils import Matrix\n"
|
"from mathutils import Matrix\n"
|
||||||
"\n"
|
"\n"
|
||||||
"# Clear Scene\n"
|
"# Clear Scene\n"
|
||||||
"bpy.context.scene.camera = None\n"
|
"if 'Collection 1' in bpy.data.collections:\n"
|
||||||
"for ob in bpy.data.objects:\n"
|
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||||
" bpy.context.scene.objects.unlink(ob)\n"
|
|
||||||
" bpy.data.objects.remove(ob)\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"bpy.types.Object.retro_mapworld_color = bpy.props.FloatVectorProperty(name='Retro: MapWorld Color',"
|
"bpy.types.Object.retro_mapworld_color = bpy.props.FloatVectorProperty(name='Retro: MapWorld Color',"
|
||||||
" description='Sets map world color', subtype='COLOR', size=4, min=0.0, max=1.0)\n"
|
" description='Sets map world color', subtype='COLOR', size=4, min=0.0, max=1.0)\n"
|
||||||
|
@ -53,7 +51,7 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
|
||||||
"wldObj.scale = mtxd[2]\n"
|
"wldObj.scale = mtxd[2]\n"
|
||||||
"wldObj.retro_mapworld_color = (%f, %f, %f, %f)\n"
|
"wldObj.retro_mapworld_color = (%f, %f, %f, %f)\n"
|
||||||
"wldObj.retro_mapworld_path = '''%s'''\n"
|
"wldObj.retro_mapworld_path = '''%s'''\n"
|
||||||
"bpy.context.scene.objects.link(wldObj)\n",
|
"bpy.context.scene.collection.objects.link(wldObj)\n",
|
||||||
wld.name.c_str(), wldXfF[0][0], wldXfF[0][1], wldXfF[0][2], wldXfF[0][3], wldXfF[1][0], wldXfF[1][1],
|
wld.name.c_str(), wldXfF[0][0], wldXfF[0][1], wldXfF[0][2], wldXfF[0][3], wldXfF[1][0], wldXfF[1][1],
|
||||||
wldXfF[1][2], wldXfF[1][3], wldXfF[2][0], wldXfF[2][1], wldXfF[2][2], wldXfF[2][3], hexColorF[0], hexColorF[1],
|
wldXfF[1][2], wldXfF[1][3], wldXfF[2][0], wldXfF[2][1], wldXfF[2][2], wldXfF[2][3], hexColorF[0], hexColorF[1],
|
||||||
hexColorF[2], hexColorF[3], path.getParentPath().getRelativePathUTF8().data());
|
hexColorF[2], hexColorF[3], path.getParentPath().getRelativePathUTF8().data());
|
||||||
|
@ -70,7 +68,7 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
|
||||||
"obj.location = mtxd[0]\n"
|
"obj.location = mtxd[0]\n"
|
||||||
"obj.rotation_quaternion = mtxd[1]\n"
|
"obj.rotation_quaternion = mtxd[1]\n"
|
||||||
"obj.scale = mtxd[2]\n"
|
"obj.scale = mtxd[2]\n"
|
||||||
"bpy.context.scene.objects.link(obj)\n"
|
"bpy.context.scene.collection.objects.link(obj)\n"
|
||||||
"obj.parent = wldObj\n",
|
"obj.parent = wldObj\n",
|
||||||
wld.name.c_str(), idx++, hexXfF[0][0], hexXfF[0][1], hexXfF[0][2], hexXfF[0][3], hexXfF[1][0], hexXfF[1][1],
|
wld.name.c_str(), idx++, hexXfF[0][0], hexXfF[0][1], hexXfF[0][2], hexXfF[0][3], hexXfF[1][0], hexXfF[1][1],
|
||||||
hexXfF[1][2], hexXfF[1][3], hexXfF[2][0], hexXfF[2][1], hexXfF[2][2], hexXfF[2][3]);
|
hexXfF[1][2], hexXfF[1][3], hexXfF[2][0], hexXfF[2][1], hexXfF[2][2], hexXfF[2][3]);
|
||||||
|
@ -81,7 +79,6 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
|
||||||
" for area in screen.areas:\n"
|
" for area in screen.areas:\n"
|
||||||
" for space in area.spaces:\n"
|
" for space in area.spaces:\n"
|
||||||
" if space.type == 'VIEW_3D':\n"
|
" if space.type == 'VIEW_3D':\n"
|
||||||
" space.viewport_shade = 'SOLID'\n"
|
|
||||||
" space.clip_end = 8000.0\n";
|
" space.clip_end = 8000.0\n";
|
||||||
|
|
||||||
os.centerView();
|
os.centerView();
|
||||||
|
|
|
@ -18,18 +18,15 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const
|
||||||
if (!conn.createBlend(blendPath, hecl::blender::BlendType::World))
|
if (!conn.createBlend(blendPath, hecl::blender::BlendType::World))
|
||||||
return false;
|
return false;
|
||||||
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
|
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
|
||||||
os.format(
|
os << "import bpy\n"
|
||||||
"import bpy\n"
|
"import bmesh\n"
|
||||||
"import bmesh\n"
|
"from mathutils import Matrix\n"
|
||||||
"from mathutils import Matrix\n"
|
"\n"
|
||||||
"\n"
|
"bpy.context.scene.name = 'World'\n"
|
||||||
"bpy.context.scene.name = 'World'\n"
|
"\n"
|
||||||
"\n"
|
"# Clear Scene\n"
|
||||||
"# Clear Scene\n"
|
"if 'Collection 1' in bpy.data.collections:\n"
|
||||||
"for ob in bpy.data.objects:\n"
|
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n";
|
||||||
" if ob.type != 'CAMERA':\n"
|
|
||||||
" bpy.context.scene.objects.unlink(ob)\n"
|
|
||||||
" bpy.data.objects.remove(ob)\n");
|
|
||||||
|
|
||||||
/* Insert area empties */
|
/* Insert area empties */
|
||||||
int areaIdx = 0;
|
int areaIdx = 0;
|
||||||
|
@ -46,7 +43,7 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const
|
||||||
"bm.to_mesh(box_mesh)\n"
|
"bm.to_mesh(box_mesh)\n"
|
||||||
"bm.free()\n"
|
"bm.free()\n"
|
||||||
"box = bpy.data.objects.new(box_mesh.name, box_mesh)\n"
|
"box = bpy.data.objects.new(box_mesh.name, box_mesh)\n"
|
||||||
"bpy.context.scene.objects.link(box)\n"
|
"bpy.context.scene.collection.objects.link(box)\n"
|
||||||
"mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n"
|
"mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n"
|
||||||
"mtxd = mtx.decompose()\n"
|
"mtxd = mtx.decompose()\n"
|
||||||
"box.rotation_mode = 'QUATERNION'\n"
|
"box.rotation_mode = 'QUATERNION'\n"
|
||||||
|
@ -78,7 +75,7 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const
|
||||||
os << "bm.edges.new((bm.verts[-1], bm.verts[0]))\n";
|
os << "bm.edges.new((bm.verts[-1], bm.verts[0]))\n";
|
||||||
os.format("dockMesh = bpy.data.meshes.new('DOCK_%02d_%02d')\n", areaIdx, dockIdx);
|
os.format("dockMesh = bpy.data.meshes.new('DOCK_%02d_%02d')\n", areaIdx, dockIdx);
|
||||||
os << "dockObj = bpy.data.objects.new(dockMesh.name, dockMesh)\n"
|
os << "dockObj = bpy.data.objects.new(dockMesh.name, dockMesh)\n"
|
||||||
"bpy.context.scene.objects.link(dockObj)\n"
|
"bpy.context.scene.collection.objects.link(dockObj)\n"
|
||||||
"bm.to_mesh(dockMesh)\n"
|
"bm.to_mesh(dockMesh)\n"
|
||||||
"bm.free()\n"
|
"bm.free()\n"
|
||||||
"dockObj.parent = box\n";
|
"dockObj.parent = box\n";
|
||||||
|
|
|
@ -322,7 +322,7 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCooked(const EntryType* entry) const
|
||||||
auto overrideSearch = m_overrideEntries.find(entry->id);
|
auto overrideSearch = m_overrideEntries.find(entry->id);
|
||||||
if (overrideSearch != m_overrideEntries.end()) {
|
if (overrideSearch != m_overrideEntries.end()) {
|
||||||
return overrideSearch->second.getCookedPath(*m_dataSpec.overrideDataSpec(
|
return overrideSearch->second.getCookedPath(*m_dataSpec.overrideDataSpec(
|
||||||
overrideSearch->second, m_dataSpec.getDataSpecEntry(), hecl::blender::SharedBlenderToken));
|
overrideSearch->second, m_dataSpec.getDataSpecEntry()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const PAKType* pak = m_pak.get();
|
const PAKType* pak = m_pak.get();
|
||||||
|
|
|
@ -34,7 +34,7 @@ void CINF::sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const {
|
||||||
for (atUint32 bid : boneIds) {
|
for (atUint32 bid : boneIds) {
|
||||||
for (const Name& name : names) {
|
for (const Name& name : names) {
|
||||||
if (name.boneId == bid) {
|
if (name.boneId == bid) {
|
||||||
os.format("obj.vertex_groups.new('%s')\n", name.name.c_str());
|
os.format("obj.vertex_groups.new(name='%s')\n", name.name.c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@ void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& c
|
||||||
os.format(
|
os.format(
|
||||||
"arm = bpy.data.armatures.new('CINF_%08X')\n"
|
"arm = bpy.data.armatures.new('CINF_%08X')\n"
|
||||||
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
|
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
|
||||||
"bpy.context.scene.objects.link(arm_obj)\n"
|
"bpy.context.scene.collection.objects.link(arm_obj)\n"
|
||||||
"bpy.context.scene.objects.active = arm_obj\n"
|
"bpy.context.view_layer.objects.active = arm_obj\n"
|
||||||
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
||||||
"arm_bone_table = {}\n",
|
"arm_bone_table = {}\n",
|
||||||
cinfId.toUint32());
|
cinfId.toUint32());
|
||||||
|
@ -72,10 +72,9 @@ void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& c
|
||||||
|
|
||||||
os << "bpy.ops.object.mode_set(mode='OBJECT')\n";
|
os << "bpy.ops.object.mode_set(mode='OBJECT')\n";
|
||||||
|
|
||||||
const char* rotMode = os.getConnection().hasSLERP() ? "QUATERNION_SLERP" : "QUATERNION";
|
|
||||||
for (const DNAANIM::RigInverter<CINF>::Bone& bone : inverter.getBones())
|
for (const DNAANIM::RigInverter<CINF>::Bone& bone : inverter.getBones())
|
||||||
os.format("arm_obj.pose.bones['%s'].rotation_mode = '%s'\n", getBoneNameFromId(bone.m_origBone.id)->c_str(),
|
os.format("arm_obj.pose.bones['%s'].rotation_mode = 'QUATERNION'\n",
|
||||||
rotMode);
|
getBoneNameFromId(bone.m_origBone.id)->c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CINF::GetCINFArmatureName(const UniqueID32& cinfId) { return hecl::Format("CINF_%08X", cinfId.toUint32()); }
|
std::string CINF::GetCINFArmatureName(const UniqueID32& cinfId) { return hecl::Format("CINF_%08X", cinfId.toUint32()); }
|
||||||
|
|
|
@ -67,11 +67,12 @@ bool CMDL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
|
||||||
writer.writeString(boneName);
|
writer.writeString(boneName);
|
||||||
|
|
||||||
writer.writeUint32Big(skinMesh.skins.size());
|
writer.writeUint32Big(skinMesh.skins.size());
|
||||||
for (const std::vector<DNACMDL::Mesh::SkinBind> skin : skinMesh.skins) {
|
for (const auto& skin : skinMesh.skins) {
|
||||||
writer.writeUint32Big(skin.size());
|
size_t numBinds = skinMesh.countSkinBinds(skin);
|
||||||
for (const DNACMDL::Mesh::SkinBind& bind : skin) {
|
writer.writeUint32Big(numBinds);
|
||||||
writer.writeUint32Big(bind.boneIdx);
|
for (size_t i = 0; i < numBinds; ++i) {
|
||||||
writer.writeFloatBig(bind.weight);
|
writer.writeUint32Big(skin[i].vg_idx);
|
||||||
|
writer.writeFloatBig(skin[i].weight);
|
||||||
}
|
}
|
||||||
writer.writeUint32Big(*vertCountIt++);
|
writer.writeUint32Big(*vertCountIt++);
|
||||||
}
|
}
|
||||||
|
@ -103,10 +104,11 @@ bool CMDL::HMDLCook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& i
|
||||||
/* CVirtualBone structure just like original (for CPU skinning) */
|
/* CVirtualBone structure just like original (for CPU skinning) */
|
||||||
writer.writeUint32Big(mesh.skins.size());
|
writer.writeUint32Big(mesh.skins.size());
|
||||||
for (auto& s : mesh.skins) {
|
for (auto& s : mesh.skins) {
|
||||||
writer.writeUint32Big(s.size());
|
size_t numBinds = mesh.countSkinBinds(s);
|
||||||
for (auto& b : s) {
|
writer.writeUint32Big(numBinds);
|
||||||
writer.writeUint32Big(b.boneIdx);
|
for (size_t i = 0; i < numBinds; ++i) {
|
||||||
writer.writeFloatBig(b.weight);
|
writer.writeUint32Big(s[i].vg_idx);
|
||||||
|
writer.writeFloatBig(s[i].weight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,7 @@
|
||||||
#include "DataSpec/DNACommon/GX.hpp"
|
#include "DataSpec/DNACommon/GX.hpp"
|
||||||
#include "DataSpec/DNACommon/CMDL.hpp"
|
#include "DataSpec/DNACommon/CMDL.hpp"
|
||||||
#include "DNAMP1.hpp"
|
#include "DNAMP1.hpp"
|
||||||
|
#include "hecl/Blender/Connection.hpp"
|
||||||
|
|
||||||
namespace DataSpec::DNAMP1 {
|
namespace DataSpec::DNAMP1 {
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ struct MaterialSet : BigDNA {
|
||||||
flags |= atUint32(enabled) << 4;
|
flags |= atUint32(enabled) << 4;
|
||||||
}
|
}
|
||||||
bool alphaTest() const { return (flags & 0x20) != 0; }
|
bool alphaTest() const { return (flags & 0x20) != 0; }
|
||||||
void setPunchthroughAlpha(bool enabled) {
|
void setAlphaTest(bool enabled) {
|
||||||
flags &= ~0x20;
|
flags &= ~0x20;
|
||||||
flags |= atUint32(enabled) << 5;
|
flags |= atUint32(enabled) << 5;
|
||||||
}
|
}
|
||||||
|
@ -468,8 +469,8 @@ struct MaterialSet : BigDNA {
|
||||||
static void AddDynamicAlpha(hecl::blender::PyOutStream& out, unsigned idx);
|
static void AddDynamicAlpha(hecl::blender::PyOutStream& out, unsigned idx);
|
||||||
|
|
||||||
Material() = default;
|
Material() = default;
|
||||||
Material(const hecl::Backend::GX& gx, const std::unordered_map<std::string, int32_t>& iprops,
|
Material(const hecl::blender::Material& material,
|
||||||
const std::vector<hecl::ProjectPath>& texPathsIn, std::vector<hecl::ProjectPath>& texPathsOut,
|
std::vector<hecl::ProjectPath>& texPathsOut,
|
||||||
int colorCount, bool lightmapUVs, bool matrixSkinning);
|
int colorCount, bool lightmapUVs, bool matrixSkinning);
|
||||||
};
|
};
|
||||||
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
|
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
|
||||||
|
@ -528,29 +529,114 @@ struct HMDLMaterialSet : BigDNA {
|
||||||
static constexpr bool OneSection() { return false; }
|
static constexpr bool OneSection() { return false; }
|
||||||
|
|
||||||
AT_DECL_DNA
|
AT_DECL_DNA
|
||||||
MaterialSet::MaterialSetHead head;
|
Value<atUint32> materialCount = 0;
|
||||||
|
Vector<atUint32, AT_DNA_COUNT(materialCount)> materialEndOffs;
|
||||||
|
|
||||||
struct Material : BigDNA {
|
struct Material : BigDNA {
|
||||||
AT_DECL_DNA
|
AT_DECL_DNA
|
||||||
MaterialSet::Material::Flags flags;
|
MaterialSet::Material::Flags flags;
|
||||||
|
|
||||||
Value<atUint32> textureCount = 0;
|
using BlendMaterial = hecl::blender::Material;
|
||||||
Vector<atUint32, AT_DNA_COUNT(textureCount)> textureIdxs;
|
|
||||||
|
|
||||||
Vector<atUint32, AT_DNA_COUNT(flags.samusReflectionIndirectTexture())> indTexSlot;
|
struct PASS : hecl::TypedRecordBigDNA<BlendMaterial::ChunkType::TexturePass> {
|
||||||
|
AT_DECL_EXPLICIT_DNA
|
||||||
|
Value<BlendMaterial::PassType> type;
|
||||||
|
UniqueID32 texId;
|
||||||
|
Value<BlendMaterial::TexCoordSource> source;
|
||||||
|
Value<BlendMaterial::UVAnimType> uvAnimType;
|
||||||
|
Value<float> uvAnimParms[9] = {};
|
||||||
|
Value<bool> alpha;
|
||||||
|
PASS() = default;
|
||||||
|
explicit PASS(const BlendMaterial::PASS& pass)
|
||||||
|
: type(pass.type), texId(pass.tex), source(pass.source), uvAnimType(pass.uvAnimType), alpha(pass.alpha) {
|
||||||
|
std::copy(pass.uvAnimParms.begin(), pass.uvAnimParms.end(), std::begin(uvAnimParms));
|
||||||
|
}
|
||||||
|
bool shouldNormalizeUv() const {
|
||||||
|
switch (uvAnimType) {
|
||||||
|
case BlendMaterial::UVAnimType::MvInvNoTranslation:
|
||||||
|
case BlendMaterial::UVAnimType::MvInv:
|
||||||
|
case BlendMaterial::UVAnimType::Model:
|
||||||
|
case BlendMaterial::UVAnimType::CylinderEnvironment:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t uvAnimParamsCount() const {
|
||||||
|
switch (uvAnimType) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
case BlendMaterial::UVAnimType::Scroll:
|
||||||
|
case BlendMaterial::UVAnimType::HStrip:
|
||||||
|
case BlendMaterial::UVAnimType::VStrip:
|
||||||
|
return 4;
|
||||||
|
case BlendMaterial::UVAnimType::Rotation:
|
||||||
|
case BlendMaterial::UVAnimType::CylinderEnvironment:
|
||||||
|
return 2;
|
||||||
|
case BlendMaterial::UVAnimType::Eight:
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct CLR : hecl::TypedRecordBigDNA<BlendMaterial::ChunkType::ColorPass> {
|
||||||
|
AT_DECL_DNA
|
||||||
|
Value<BlendMaterial::PassType> type;
|
||||||
|
Value<atVec4f> color;
|
||||||
|
CLR() = default;
|
||||||
|
explicit CLR(const BlendMaterial::CLR& clr) : type(clr.type), color(clr.color.val) {}
|
||||||
|
};
|
||||||
|
using Chunk = hecl::TypedVariantBigDNA<PASS, CLR>;
|
||||||
|
|
||||||
Value<atUint32> uvAnimsSize = 4;
|
static unsigned TexMapIdx(BlendMaterial::PassType type) {
|
||||||
Value<atUint32> uvAnimsCount = 0;
|
switch (type) {
|
||||||
Vector<MaterialSet::Material::UVAnimation, AT_DNA_COUNT(uvAnimsCount)> uvAnims;
|
case BlendMaterial::PassType::Lightmap:
|
||||||
|
return 0;
|
||||||
|
case BlendMaterial::PassType::Diffuse:
|
||||||
|
return 1;
|
||||||
|
case BlendMaterial::PassType::Emissive:
|
||||||
|
return 2;
|
||||||
|
case BlendMaterial::PassType::Specular:
|
||||||
|
return 3;
|
||||||
|
case BlendMaterial::PassType::ExtendedSpecular:
|
||||||
|
return 4;
|
||||||
|
case BlendMaterial::PassType::Reflection:
|
||||||
|
return 5;
|
||||||
|
case BlendMaterial::PassType::Alpha:
|
||||||
|
return 6;
|
||||||
|
case BlendMaterial::PassType::IndirectTex:
|
||||||
|
return 7;
|
||||||
|
default:
|
||||||
|
assert(false && "Unknown pass type");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String<-1> heclSource;
|
Value<atUint64> hash;
|
||||||
hecl::Frontend::IR heclIr;
|
Value<BlendMaterial::ShaderType> shaderType;
|
||||||
|
Value<atUint32> chunkCount;
|
||||||
|
Vector<Chunk, AT_DNA_COUNT(chunkCount)> chunks;
|
||||||
|
Value<BlendMaterial::BlendMode> blendMode = BlendMaterial::BlendMode::Opaque;
|
||||||
|
|
||||||
|
std::pair<hecl::Backend::BlendFactor, hecl::Backend::BlendFactor>
|
||||||
|
blendFactors() const {
|
||||||
|
switch (blendMode) {
|
||||||
|
case BlendMaterial::BlendMode::Opaque:
|
||||||
|
default:
|
||||||
|
return {hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::Zero};
|
||||||
|
case BlendMaterial::BlendMode::Alpha:
|
||||||
|
return {hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha};
|
||||||
|
case BlendMaterial::BlendMode::Additive:
|
||||||
|
return {hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Material() = default;
|
Material() = default;
|
||||||
Material(hecl::Frontend::Frontend& FE, const std::string& diagName, const hecl::blender::Material& mat,
|
Material(const hecl::blender::Material& mat);
|
||||||
const std::unordered_map<std::string, int32_t>& iprops, const std::vector<hecl::ProjectPath>& texPaths);
|
|
||||||
};
|
};
|
||||||
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
|
Vector<Material, AT_DNA_COUNT(materialCount)> materials;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace DataSpec::DNAMP1
|
} // namespace DataSpec::DNAMP1
|
||||||
|
|
||||||
|
AT_SPECIALIZE_TYPED_VARIANT_BIGDNA(DataSpec::DNAMP1::HMDLMaterialSet::Material::PASS,
|
||||||
|
DataSpec::DNAMP1::HMDLMaterialSet::Material::CLR)
|
||||||
|
|
|
@ -7,8 +7,8 @@ namespace DataSpec::DNAMP1 {
|
||||||
void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const {
|
void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const {
|
||||||
os.format(
|
os.format(
|
||||||
"obj = bpy.data.objects.new('%s', None)\n"
|
"obj = bpy.data.objects.new('%s', None)\n"
|
||||||
"obj.empty_draw_type = 'CUBE'\n"
|
"obj.empty_display_type = 'CUBE'\n"
|
||||||
"bpy.context.scene.objects.link(obj)\n"
|
"bpy.context.scene.collection.objects.link(obj)\n"
|
||||||
"mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n"
|
"mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n"
|
||||||
"mtxd = mtx.decompose()\n"
|
"mtxd = mtx.decompose()\n"
|
||||||
"obj.rotation_mode = 'QUATERNION'\n"
|
"obj.rotation_mode = 'QUATERNION'\n"
|
||||||
|
@ -27,29 +27,6 @@ void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <class Op>
|
|
||||||
void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s) {
|
|
||||||
Do<Op>({"xf[0]"}, xf[0], s);
|
|
||||||
Do<Op>({"xf[1]"}, xf[1], s);
|
|
||||||
Do<Op>({"xf[2]"}, xf[2], s);
|
|
||||||
Do<Op>({"halfExtent"}, halfExtent, s);
|
|
||||||
Do<Op>({"isLeaf"}, isLeaf, s);
|
|
||||||
if (isLeaf) {
|
|
||||||
if (!leafData)
|
|
||||||
leafData.reset(new LeafData);
|
|
||||||
Do<Op>({"leafData"}, *leafData, s);
|
|
||||||
} else {
|
|
||||||
if (!left)
|
|
||||||
left.reset(new Node);
|
|
||||||
Do<Op>({"left"}, *left, s);
|
|
||||||
if (!right)
|
|
||||||
right.reset(new Node);
|
|
||||||
Do<Op>({"right"}, *right, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AT_SPECIALIZE_DNA(DCLN::Collision::Node)
|
|
||||||
|
|
||||||
void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName) {
|
void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName) {
|
||||||
/* Open Py Stream and read sections */
|
/* Open Py Stream and read sections */
|
||||||
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
|
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
|
||||||
|
@ -60,10 +37,8 @@ void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
|
||||||
"\n"
|
"\n"
|
||||||
"bpy.context.scene.name = '%s'\n"
|
"bpy.context.scene.name = '%s'\n"
|
||||||
"# Clear Scene\n"
|
"# Clear Scene\n"
|
||||||
"for ob in bpy.data.objects:\n"
|
"if 'Collection 1' in bpy.data.collections:\n"
|
||||||
" if ob.type != 'CAMERA':\n"
|
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n",
|
||||||
" bpy.context.scene.objects.unlink(ob)\n"
|
|
||||||
" bpy.data.objects.remove(ob)\n",
|
|
||||||
entryName.data());
|
entryName.data());
|
||||||
|
|
||||||
DeafBabe::BlenderInit(os);
|
DeafBabe::BlenderInit(os);
|
||||||
|
|
|
@ -91,4 +91,27 @@ struct DCLN : BigDNA {
|
||||||
static bool Cook(const hecl::ProjectPath& outPath, const std::vector<Mesh>& meshes);
|
static bool Cook(const hecl::ProjectPath& outPath, const std::vector<Mesh>& meshes);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class Op>
|
||||||
|
void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s) {
|
||||||
|
Do<Op>({"xf[0]"}, xf[0], s);
|
||||||
|
Do<Op>({"xf[1]"}, xf[1], s);
|
||||||
|
Do<Op>({"xf[2]"}, xf[2], s);
|
||||||
|
Do<Op>({"halfExtent"}, halfExtent, s);
|
||||||
|
Do<Op>({"isLeaf"}, isLeaf, s);
|
||||||
|
if (isLeaf) {
|
||||||
|
if (!leafData)
|
||||||
|
leafData.reset(new LeafData);
|
||||||
|
Do<Op>({"leafData"}, *leafData, s);
|
||||||
|
} else {
|
||||||
|
if (!left)
|
||||||
|
left.reset(new Node);
|
||||||
|
Do<Op>({"left"}, *left, s);
|
||||||
|
if (!right)
|
||||||
|
right.reset(new Node);
|
||||||
|
Do<Op>({"right"}, *right, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AT_SPECIALIZE_DNA(DCLN::Collision::Node)
|
||||||
|
|
||||||
} // namespace DataSpec::DNAMP1
|
} // namespace DataSpec::DNAMP1
|
||||||
|
|
|
@ -25,12 +25,15 @@ void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) {
|
||||||
" 'Organic':(0.19, 0.45, 0.2)}\n"
|
" 'Organic':(0.19, 0.45, 0.2)}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"# Diffuse Color Maker\n"
|
"# Diffuse Color Maker\n"
|
||||||
|
"from mathutils import Color\n"
|
||||||
"def make_color(index, mat_type, name):\n"
|
"def make_color(index, mat_type, name):\n"
|
||||||
" new_mat = bpy.data.materials.new(name)\n"
|
" new_mat = bpy.data.materials.new(name)\n"
|
||||||
" if mat_type in TYPE_COLORS:\n"
|
" if mat_type in TYPE_COLORS:\n"
|
||||||
" new_mat.diffuse_color = TYPE_COLORS[mat_type]\n"
|
" new_mat.diffuse_color = TYPE_COLORS[mat_type] + (1.0,)\n"
|
||||||
" else:\n"
|
" else:\n"
|
||||||
" new_mat.diffuse_color.hsv = ((index / 6.0) % 1.0, 1.0-((index // 6) / 6.0), 1)\n"
|
" col = Color()\n"
|
||||||
|
" col.hsv = ((index / 6.0) % 1.0, 1.0-((index // 6) / 6.0), 1)\n"
|
||||||
|
" new_mat.diffuse_color = tuple(col) + (1.0,)\n"
|
||||||
" return new_mat\n"
|
" return new_mat\n"
|
||||||
"\n"
|
"\n"
|
||||||
"bpy.types.Material.retro_unknown = bpy.props.BoolProperty(name='Retro: Unknown (U)')\n"
|
"bpy.types.Material.retro_unknown = bpy.props.BoolProperty(name='Retro: Unknown (U)')\n"
|
||||||
|
@ -189,8 +192,6 @@ void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) {
|
||||||
" return len(material_index)-1\n"
|
" return len(material_index)-1\n"
|
||||||
" else:\n"
|
" else:\n"
|
||||||
" mat = make_color(len(material_dict), mat_type, mat_name)\n"
|
" mat = make_color(len(material_dict), mat_type, mat_name)\n"
|
||||||
" mat.diffuse_intensity = 1.0\n"
|
|
||||||
" mat.specular_intensity = 0.0\n"
|
|
||||||
" mat.retro_unknown = ((data >> 0) & 1)\n"
|
" mat.retro_unknown = ((data >> 0) & 1)\n"
|
||||||
" mat.retro_surface_stone = ((data >> 1) & 1)\n"
|
" mat.retro_surface_stone = ((data >> 1) & 1)\n"
|
||||||
" mat.retro_surface_metal = ((data >> 2) & 1)\n"
|
" mat.retro_surface_metal = ((data >> 2) & 1)\n"
|
||||||
|
|
|
@ -292,10 +292,8 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
os << "import bpy, math, bmesh\n"
|
os << "import bpy, math, bmesh\n"
|
||||||
"from mathutils import Matrix, Quaternion\n"
|
"from mathutils import Matrix, Quaternion\n"
|
||||||
"# Clear Scene\n"
|
"# Clear Scene\n"
|
||||||
"for ob in bpy.data.objects:\n"
|
"if 'Collection 1' in bpy.data.collections:\n"
|
||||||
" if ob.type != 'CAMERA':\n"
|
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||||
" bpy.context.scene.objects.unlink(ob)\n"
|
|
||||||
" bpy.data.objects.remove(ob)\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"def duplicateObject(copy_obj):\n"
|
"def duplicateObject(copy_obj):\n"
|
||||||
" # Create new mesh\n"
|
" # Create new mesh\n"
|
||||||
|
@ -307,16 +305,14 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
" ob_new.scale = copy_obj.scale\n"
|
" ob_new.scale = copy_obj.scale\n"
|
||||||
" ob_new.location = copy_obj.location\n"
|
" ob_new.location = copy_obj.location\n"
|
||||||
" # Link new object to the given scene and select it\n"
|
" # Link new object to the given scene and select it\n"
|
||||||
" bpy.context.scene.objects.link(ob_new)\n"
|
" bpy.context.scene.collection.objects.link(ob_new)\n"
|
||||||
" return ob_new\n";
|
" return ob_new\n";
|
||||||
|
|
||||||
os.format(
|
os.format(
|
||||||
"bpy.context.scene.name = '%s'\n"
|
"bpy.context.scene.name = '%s'\n"
|
||||||
"bpy.context.scene.render.resolution_x = 640\n"
|
"bpy.context.scene.render.resolution_x = 640\n"
|
||||||
"bpy.context.scene.render.resolution_y = 480\n"
|
"bpy.context.scene.render.resolution_y = 480\n"
|
||||||
"bpy.context.scene.render.engine = 'CYCLES'\n"
|
|
||||||
"bpy.context.scene.world.use_nodes = True\n"
|
"bpy.context.scene.world.use_nodes = True\n"
|
||||||
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
|
|
||||||
"bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n"
|
"bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n"
|
||||||
"bg_node.inputs[1].default_value = 0.0\n",
|
"bg_node.inputs[1].default_value = 0.0\n",
|
||||||
pakRouter.getBestEntryName(entry).c_str());
|
pakRouter.getBestEntryName(entry).c_str());
|
||||||
|
@ -377,12 +373,11 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
default: {
|
default: {
|
||||||
zeus::simd_floats colorF(w.header.color.simd);
|
zeus::simd_floats colorF(w.header.color.simd);
|
||||||
os.format(
|
os.format(
|
||||||
"lamp = bpy.data.lamps.new(name='%s', type='POINT')\n"
|
"lamp = bpy.data.lights.new(name='%s', type='POINT')\n"
|
||||||
"lamp.color = (%f, %f, %f)\n"
|
"lamp.color = (%f, %f, %f)\n"
|
||||||
"lamp.falloff_type = 'INVERSE_COEFFICIENTS'\n"
|
"lamp.hecl_falloff_constant = %f\n"
|
||||||
"lamp.constant_coefficient = %f\n"
|
"lamp.hecl_falloff_linear = %f\n"
|
||||||
"lamp.linear_coefficient = %f\n"
|
"lamp.hecl_falloff_quadratic = %f\n"
|
||||||
"lamp.quadratic_coefficient = %f\n"
|
|
||||||
"lamp.retro_light_angle_constant = %f\n"
|
"lamp.retro_light_angle_constant = %f\n"
|
||||||
"lamp.retro_light_angle_linear = %f\n"
|
"lamp.retro_light_angle_linear = %f\n"
|
||||||
"lamp.retro_light_angle_quadratic = %f\n"
|
"lamp.retro_light_angle_quadratic = %f\n"
|
||||||
|
@ -396,7 +391,7 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
"lamp.spot_size = %f\n",
|
"lamp.spot_size = %f\n",
|
||||||
info->cutoff);
|
info->cutoff);
|
||||||
else if (info->type == LITEInfo::ELightType::Directional)
|
else if (info->type == LITEInfo::ELightType::Directional)
|
||||||
os << "lamp.type = 'HEMI'\n";
|
os << "lamp.type = 'SUN'\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,14 +428,15 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
|
|
||||||
os.format(
|
os.format(
|
||||||
"material = bpy.data.materials.new('%s')\n"
|
"material = bpy.data.materials.new('%s')\n"
|
||||||
"material.specular_intensity = 0.0\n"
|
"material.use_nodes = True\n"
|
||||||
"tex_slot = material.texture_slots.add()\n"
|
"new_nodetree = material.node_tree\n"
|
||||||
"tex_slot.texture = bpy.data.textures.new('%s', 'IMAGE')\n"
|
"for n in new_nodetree.nodes:\n"
|
||||||
"tex_slot.texture.image = image\n"
|
" new_nodetree.nodes.remove(n)\n"
|
||||||
"material.active_texture = tex_slot.texture\n"
|
"tex_node = new_nodetree.nodes.new('ShaderNodeTexImage')\n"
|
||||||
|
"tex_node.image = image\n"
|
||||||
"bm = bmesh.new()\n"
|
"bm = bmesh.new()\n"
|
||||||
"verts = []\n",
|
"verts = []\n",
|
||||||
w.header.name.c_str(), w.header.name.c_str());
|
w.header.name.c_str());
|
||||||
|
|
||||||
for (int i = 0; i < info->quadCoordCount; ++i) {
|
for (int i = 0; i < info->quadCoordCount; ++i) {
|
||||||
int ti;
|
int ti;
|
||||||
|
@ -511,12 +507,12 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
os << "print(obj.name)\n"
|
os << "print(obj.name)\n"
|
||||||
"copy_obj = duplicateObject(obj)\n"
|
"copy_obj = duplicateObject(obj)\n"
|
||||||
"copy_obj.parent = frme_obj\n"
|
"copy_obj.parent = frme_obj\n"
|
||||||
"copy_obj.hide = False\n";
|
"copy_obj.hide_set(False)\n";
|
||||||
} else if (w.type == SBIG('CAMR')) {
|
} else if (w.type == SBIG('CAMR')) {
|
||||||
os << "bpy.context.scene.camera = frme_obj\n"
|
os << "bpy.context.scene.camera = frme_obj\n"
|
||||||
"if 'Camera' in bpy.data.objects:\n"
|
"if 'Camera' in bpy.data.objects:\n"
|
||||||
" cam = bpy.data.objects['Camera']\n"
|
" cam = bpy.data.objects['Camera']\n"
|
||||||
" bpy.context.scene.objects.unlink(cam)\n"
|
" #bpy.context.scene.objects.unlink(cam)\n"
|
||||||
" bpy.data.objects.remove(cam)\n";
|
" bpy.data.objects.remove(cam)\n";
|
||||||
} else if (w.type == SBIG('PANE')) {
|
} else if (w.type == SBIG('PANE')) {
|
||||||
using PANEInfo = Widget::PANEInfo;
|
using PANEInfo = Widget::PANEInfo;
|
||||||
|
@ -611,9 +607,9 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
"mtxd = mtx.decompose()\n"
|
"mtxd = mtx.decompose()\n"
|
||||||
"frme_obj.rotation_mode = 'QUATERNION'\n"
|
"frme_obj.rotation_mode = 'QUATERNION'\n"
|
||||||
"frme_obj.location = mtxd[0]\n"
|
"frme_obj.location = mtxd[0]\n"
|
||||||
"frme_obj.rotation_quaternion = mtxd[1] * angle\n"
|
"frme_obj.rotation_quaternion = mtxd[1] @ angle\n"
|
||||||
"frme_obj.scale = mtxd[2]\n"
|
"frme_obj.scale = mtxd[2]\n"
|
||||||
"bpy.context.scene.objects.link(frme_obj)\n",
|
"bpy.context.scene.collection.objects.link(frme_obj)\n",
|
||||||
xfMtxF[0][0], xfMtxF[0][1], xfMtxF[0][2], originF[0], xfMtxF[1][0], xfMtxF[1][1], xfMtxF[1][2], originF[1],
|
xfMtxF[0][0], xfMtxF[0][1], xfMtxF[0][2], originF[0], xfMtxF[1][0], xfMtxF[1][1], xfMtxF[1][2], originF[1],
|
||||||
xfMtxF[2][0], xfMtxF[2][1], xfMtxF[2][2], originF[2]);
|
xfMtxF[2][0], xfMtxF[2][1], xfMtxF[2][2], originF[2]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,7 +298,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
|
||||||
areaOut.depLayers.push_back(areaOut.deps.size());
|
areaOut.depLayers.push_back(areaOut.deps.size());
|
||||||
for (const std::pair<hecl::ProjectPath, bool>& path : layer) {
|
for (const std::pair<hecl::ProjectPath, bool>& path : layer) {
|
||||||
if (path.first) {
|
if (path.first) {
|
||||||
urde::SObjectTag tag = g_curSpec->buildTagFromPath(path.first, btok);
|
urde::SObjectTag tag = g_curSpec->buildTagFromPath(path.first);
|
||||||
if (tag.id.IsValid()) {
|
if (tag.id.IsValid()) {
|
||||||
if (path.second)
|
if (path.second)
|
||||||
areaOut.lazyDeps.emplace_back(tag.id.Value(), tag.type);
|
areaOut.lazyDeps.emplace_back(tag.id.Value(), tag.type);
|
||||||
|
@ -326,7 +326,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
|
||||||
layerResources.addSharedPath(path, false);
|
layerResources.addSharedPath(path, false);
|
||||||
|
|
||||||
for (const std::pair<hecl::ProjectPath, bool>& path : layerResources.sharedPaths) {
|
for (const std::pair<hecl::ProjectPath, bool>& path : layerResources.sharedPaths) {
|
||||||
urde::SObjectTag tag = g_curSpec->buildTagFromPath(path.first, btok);
|
urde::SObjectTag tag = g_curSpec->buildTagFromPath(path.first);
|
||||||
if (tag.id.IsValid()) {
|
if (tag.id.IsValid()) {
|
||||||
if (path.second)
|
if (path.second)
|
||||||
areaOut.lazyDeps.emplace_back(tag.id.Value(), tag.type);
|
areaOut.lazyDeps.emplace_back(tag.id.Value(), tag.type);
|
||||||
|
@ -337,7 +337,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
|
||||||
}
|
}
|
||||||
|
|
||||||
hecl::ProjectPath pathPath(areaPath.getParentPath(), _SYS_STR("!path.blend"));
|
hecl::ProjectPath pathPath(areaPath.getParentPath(), _SYS_STR("!path.blend"));
|
||||||
urde::SObjectTag pathTag = g_curSpec->buildTagFromPath(pathPath, btok);
|
urde::SObjectTag pathTag = g_curSpec->buildTagFromPath(pathPath);
|
||||||
if (pathTag.id.IsValid()) {
|
if (pathTag.id.IsValid()) {
|
||||||
areaOut.deps.emplace_back(pathTag.id.Value(), pathTag.type);
|
areaOut.deps.emplace_back(pathTag.id.Value(), pathTag.type);
|
||||||
areaOut.lazyDeps.emplace_back(0, FOURCC('NONE'));
|
areaOut.lazyDeps.emplace_back(0, FOURCC('NONE'));
|
||||||
|
@ -369,7 +369,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MLVL::CookMAPW(const hecl::ProjectPath& outPath, const World& wld, hecl::blender::Token& btok) {
|
bool MLVL::CookMAPW(const hecl::ProjectPath& outPath, const World& wld) {
|
||||||
std::vector<urde::SObjectTag> mapaTags;
|
std::vector<urde::SObjectTag> mapaTags;
|
||||||
mapaTags.reserve(wld.areas.size());
|
mapaTags.reserve(wld.areas.size());
|
||||||
|
|
||||||
|
@ -380,7 +380,7 @@ bool MLVL::CookMAPW(const hecl::ProjectPath& outPath, const World& wld, hecl::bl
|
||||||
/* Area map */
|
/* Area map */
|
||||||
hecl::ProjectPath mapPath(area.path, _SYS_STR("/!map.blend"));
|
hecl::ProjectPath mapPath(area.path, _SYS_STR("/!map.blend"));
|
||||||
if (mapPath.isFile())
|
if (mapPath.isFile())
|
||||||
mapaTags.push_back(g_curSpec->buildTagFromPath(mapPath, btok));
|
mapaTags.push_back(g_curSpec->buildTagFromPath(mapPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out MAPW */
|
/* Write out MAPW */
|
||||||
|
|
|
@ -136,7 +136,7 @@ struct MLVL : BigDNA {
|
||||||
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld,
|
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld,
|
||||||
hecl::blender::Token& btok);
|
hecl::blender::Token& btok);
|
||||||
|
|
||||||
static bool CookMAPW(const hecl::ProjectPath& outPath, const World& wld, hecl::blender::Token& btok);
|
static bool CookMAPW(const hecl::ProjectPath& outPath, const World& wld);
|
||||||
|
|
||||||
static bool CookSAVW(const hecl::ProjectPath& outPath, const World& wld);
|
static bool CookSAVW(const hecl::ProjectPath& outPath, const World& wld);
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,9 +21,7 @@ void MREA::ReadBabeDeadToBlender_1_2(hecl::blender::PyOutStream& os, athena::io:
|
||||||
atUint32 bdMagic = rs.readUint32Big();
|
atUint32 bdMagic = rs.readUint32Big();
|
||||||
if (bdMagic != 0xBABEDEAD)
|
if (bdMagic != 0xBABEDEAD)
|
||||||
Log.report(logvisor::Fatal, "invalid BABEDEAD magic");
|
Log.report(logvisor::Fatal, "invalid BABEDEAD magic");
|
||||||
os << "bpy.context.scene.render.engine = 'CYCLES'\n"
|
os << "bpy.context.scene.world.use_nodes = True\n"
|
||||||
"bpy.context.scene.world.use_nodes = True\n"
|
|
||||||
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
|
|
||||||
"bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n"
|
"bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n"
|
||||||
"bg_node.inputs[1].default_value = 0.0\n";
|
"bg_node.inputs[1].default_value = 0.0\n";
|
||||||
for (atUint32 s = 0; s < 2; ++s) {
|
for (atUint32 s = 0; s < 2; ++s) {
|
||||||
|
@ -127,10 +125,10 @@ static void OutputOctreeNode(hecl::blender::PyOutStream& os, athena::io::MemoryR
|
||||||
zeus::CVector3f extent = aabb.extents();
|
zeus::CVector3f extent = aabb.extents();
|
||||||
os.format(
|
os.format(
|
||||||
"obj = bpy.data.objects.new('Leaf', None)\n"
|
"obj = bpy.data.objects.new('Leaf', None)\n"
|
||||||
"bpy.context.scene.objects.link(obj)\n"
|
"bpy.context.scene.collection.objects.link(obj)\n"
|
||||||
"obj.location = (%f,%f,%f)\n"
|
"obj.location = (%f,%f,%f)\n"
|
||||||
"obj.scale = (%f,%f,%f)\n"
|
"obj.scale = (%f,%f,%f)\n"
|
||||||
"obj.empty_draw_type = 'CUBE'\n"
|
"obj.empty_display_type = 'CUBE'\n"
|
||||||
"obj.layers[1] = True\n"
|
"obj.layers[1] = True\n"
|
||||||
"obj.layers[0] = False\n",
|
"obj.layers[0] = False\n",
|
||||||
pos.x, pos.y, pos.z, extent.x, extent.y, extent.z);
|
pos.x, pos.y, pos.z, extent.x, extent.y, extent.z);
|
||||||
|
@ -168,10 +166,10 @@ static void OutputOctreeNode(hecl::blender::PyOutStream& os, athena::io::IStream
|
||||||
zeus::CVector3f extent = aabb.extents();
|
zeus::CVector3f extent = aabb.extents();
|
||||||
os.format(
|
os.format(
|
||||||
"obj = bpy.data.objects.new('Leaf', None)\n"
|
"obj = bpy.data.objects.new('Leaf', None)\n"
|
||||||
"bpy.context.scene.objects.link(obj)\n"
|
"bpy.context.scene.collection.objects.link(obj)\n"
|
||||||
"obj.location = (%f,%f,%f)\n"
|
"obj.location = (%f,%f,%f)\n"
|
||||||
"obj.scale = (%f,%f,%f)\n"
|
"obj.scale = (%f,%f,%f)\n"
|
||||||
"obj.empty_draw_type = 'CUBE'\n"
|
"obj.empty_display_type = 'CUBE'\n"
|
||||||
"obj.layers[1] = True\n"
|
"obj.layers[1] = True\n"
|
||||||
"obj.layers[0] = False\n",
|
"obj.layers[0] = False\n",
|
||||||
pos.x, pos.y, pos.z, extent.x, extent.y, extent.z);
|
pos.x, pos.y, pos.z, extent.x, extent.y, extent.z);
|
||||||
|
@ -199,22 +197,21 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
|
|
||||||
/* Open Py Stream and read sections */
|
/* Open Py Stream and read sections */
|
||||||
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
|
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
|
||||||
os.format(
|
os << "import bpy\n"
|
||||||
"import bpy\n"
|
"import bmesh\n"
|
||||||
"import bmesh\n"
|
"from mathutils import Vector\n"
|
||||||
"from mathutils import Vector\n"
|
"bpy.context.scene.render.fps = 60\n"
|
||||||
"\n"
|
"\n";
|
||||||
"bpy.context.scene.name = '%s'\n",
|
os.format("bpy.context.scene.name = '%s'\n",
|
||||||
pakRouter.getBestEntryName(entry, false).c_str());
|
pakRouter.getBestEntryName(entry, false).c_str());
|
||||||
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath(), true);
|
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath());
|
||||||
MaterialSet::RegisterMaterialProps(os);
|
MaterialSet::RegisterMaterialProps(os);
|
||||||
os << "# Clear Scene\n"
|
os << "# Clear Scene\n"
|
||||||
"for ob in bpy.data.objects:\n"
|
"if 'Collection 1' in bpy.data.collections:\n"
|
||||||
" if ob.type != 'CAMERA':\n"
|
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||||
" bpy.context.scene.objects.unlink(ob)\n"
|
"\n"
|
||||||
" bpy.data.objects.remove(ob)\n"
|
"bpy.types.Light.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
|
||||||
"bpy.types.Lamp.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
|
"bpy.types.Light.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n"
|
||||||
"bpy.types.Lamp.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n"
|
|
||||||
"bpy.types.Object.retro_disable_enviro_visor = bpy.props.BoolProperty(name='Retro: Disable in Combat/Scan "
|
"bpy.types.Object.retro_disable_enviro_visor = bpy.props.BoolProperty(name='Retro: Disable in Combat/Scan "
|
||||||
"Visor')\n"
|
"Visor')\n"
|
||||||
"bpy.types.Object.retro_disable_thermal_visor = bpy.props.BoolProperty(name='Retro: Disable in Thermal "
|
"bpy.types.Object.retro_disable_thermal_visor = bpy.props.BoolProperty(name='Retro: Disable in Thermal "
|
||||||
|
@ -310,11 +307,11 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Origins to center of mass */
|
/* Origins to center of mass */
|
||||||
os << "bpy.context.scene.layers[1] = True\n"
|
os << "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = False\n"
|
||||||
"bpy.ops.object.select_by_type(type='MESH')\n"
|
"bpy.ops.object.select_by_type(type='MESH')\n"
|
||||||
"bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n"
|
"bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n"
|
||||||
"bpy.ops.object.select_all(action='DESELECT')\n"
|
"bpy.ops.object.select_all(action='DESELECT')\n"
|
||||||
"bpy.context.scene.layers[1] = False\n";
|
"bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = True\n";
|
||||||
|
|
||||||
/* Link MLVL scene as background */
|
/* Link MLVL scene as background */
|
||||||
os.linkBackground("//../!world.blend", "World");
|
os.linkBackground("//../!world.blend", "World");
|
||||||
|
@ -678,7 +675,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
|
||||||
for (const DNACMDL::Mesh::Surface::Vert& vert : surf.verts)
|
for (const DNACMDL::Mesh::Surface::Vert& vert : surf.verts)
|
||||||
w.writeUint32Big(vert.iPos);
|
w.writeUint32Big(vert.iPos);
|
||||||
const DNACMDL::Material& mat = mesh.materialSets[0][surf.materialIdx];
|
const DNACMDL::Material& mat = mesh.materialSets[0][surf.materialIdx];
|
||||||
w.writeBool(mat.transparent);
|
w.writeBool(mat.blendMode != DNACMDL::Material::BlendMode::Opaque);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,10 @@ static void OutputOctreeNode(hecl::blender::PyOutStream& os, int idx, const zeus
|
||||||
const zeus::CVector3f extent = aabb.extents();
|
const zeus::CVector3f extent = aabb.extents();
|
||||||
os.format(
|
os.format(
|
||||||
"obj = bpy.data.objects.new('Leaf_%d', None)\n"
|
"obj = bpy.data.objects.new('Leaf_%d', None)\n"
|
||||||
"bpy.context.scene.objects.link(obj)\n"
|
"bpy.context.scene.collection.objects.link(obj)\n"
|
||||||
"obj.location = (%f,%f,%f)\n"
|
"obj.location = (%f,%f,%f)\n"
|
||||||
"obj.scale = (%f,%f,%f)\n"
|
"obj.scale = (%f,%f,%f)\n"
|
||||||
"obj.empty_draw_type = 'CUBE'\n"
|
"obj.empty_display_type = 'CUBE'\n"
|
||||||
"obj.layers[1] = True\n"
|
"obj.layers[1] = True\n"
|
||||||
"obj.layers[0] = False\n", idx,
|
"obj.layers[0] = False\n", idx,
|
||||||
pos.x(), pos.y(), pos.z(), extent.x(), extent.y(), extent.z());
|
pos.x(), pos.y(), pos.z(), extent.x(), extent.y(), extent.z());
|
||||||
|
@ -39,15 +39,15 @@ void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
|
||||||
"material_index = []\n"
|
"material_index = []\n"
|
||||||
"def make_ground_material(idxMask):\n"
|
"def make_ground_material(idxMask):\n"
|
||||||
" mat = bpy.data.materials.new('Ground %%X' %% idxMask)\n"
|
" mat = bpy.data.materials.new('Ground %%X' %% idxMask)\n"
|
||||||
" mat.diffuse_color = (0.8, 0.460, 0.194)\n"
|
" mat.diffuse_color = (0.8, 0.460, 0.194, 1.0)\n"
|
||||||
" return mat\n"
|
" return mat\n"
|
||||||
"def make_flyer_material(idxMask):\n"
|
"def make_flyer_material(idxMask):\n"
|
||||||
" mat = bpy.data.materials.new('Flyer %%X' %% idxMask)\n"
|
" mat = bpy.data.materials.new('Flyer %%X' %% idxMask)\n"
|
||||||
" mat.diffuse_color = (0.016, 0.8, 0.8)\n"
|
" mat.diffuse_color = (0.016, 0.8, 0.8, 1.0)\n"
|
||||||
" return mat\n"
|
" return mat\n"
|
||||||
"def make_swimmer_material(idxMask):\n"
|
"def make_swimmer_material(idxMask):\n"
|
||||||
" mat = bpy.data.materials.new('Swimmer %%X' %% idxMask)\n"
|
" mat = bpy.data.materials.new('Swimmer %%X' %% idxMask)\n"
|
||||||
" mat.diffuse_color = (0.074, 0.293, 0.8)\n"
|
" mat.diffuse_color = (0.074, 0.293, 0.8, 1.0)\n"
|
||||||
" return mat\n"
|
" return mat\n"
|
||||||
"def select_material(meshIdxMask, meshTypeMask):\n"
|
"def select_material(meshIdxMask, meshTypeMask):\n"
|
||||||
" key = (meshIdxMask, meshTypeMask)\n"
|
" key = (meshIdxMask, meshTypeMask)\n"
|
||||||
|
@ -71,10 +71,8 @@ void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
|
||||||
"\n"
|
"\n"
|
||||||
"bpy.context.scene.name = '%s'\n"
|
"bpy.context.scene.name = '%s'\n"
|
||||||
"# Clear Scene\n"
|
"# Clear Scene\n"
|
||||||
"for ob in bpy.data.objects:\n"
|
"if 'Collection 1' in bpy.data.collections:\n"
|
||||||
" if ob.type != 'CAMERA':\n"
|
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||||
" bpy.context.scene.objects.unlink(ob)\n"
|
|
||||||
" bpy.data.objects.remove(ob)\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"bm = bmesh.new()\n"
|
"bm = bmesh.new()\n"
|
||||||
"height_lay = bm.faces.layers.float.new('Height')\n",
|
"height_lay = bm.faces.layers.float.new('Height')\n",
|
||||||
|
@ -109,11 +107,11 @@ void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
|
||||||
os.format("aabb = bpy.data.objects.new('AABB', None)\n"
|
os.format("aabb = bpy.data.objects.new('AABB', None)\n"
|
||||||
"aabb.location = (%f,%f,%f)\n"
|
"aabb.location = (%f,%f,%f)\n"
|
||||||
"aabb.scale = (%f,%f,%f)\n"
|
"aabb.scale = (%f,%f,%f)\n"
|
||||||
"aabb.empty_draw_type = 'CUBE'\n"
|
"aabb.empty_display_type = 'CUBE'\n"
|
||||||
"bpy.context.scene.objects.link(aabb)\n"
|
"bpy.context.scene.collection.objects.link(aabb)\n"
|
||||||
"centr = bpy.data.objects.new('Center', None)\n"
|
"centr = bpy.data.objects.new('Center', None)\n"
|
||||||
"centr.location = (%f,%f,%f)\n"
|
"centr.location = (%f,%f,%f)\n"
|
||||||
"bpy.context.scene.objects.link(centr)\n",
|
"bpy.context.scene.collection.objects.link(centr)\n",
|
||||||
aabb.min[0] + (aabb.max[0] - aabb.min[0]) / 2.f,
|
aabb.min[0] + (aabb.max[0] - aabb.min[0]) / 2.f,
|
||||||
aabb.min[1] + (aabb.max[1] - aabb.min[1]) / 2.f,
|
aabb.min[1] + (aabb.max[1] - aabb.min[1]) / 2.f,
|
||||||
aabb.min[2] + (aabb.max[2] - aabb.min[2]) / 2.f,
|
aabb.min[2] + (aabb.max[2] - aabb.min[2]) / 2.f,
|
||||||
|
@ -143,16 +141,10 @@ void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
|
||||||
" mat = material_dict[mat_name]\n"
|
" mat = material_dict[mat_name]\n"
|
||||||
" path_mesh.materials.append(mat)\n"
|
" path_mesh.materials.append(mat)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"bpy.context.scene.objects.link(path_mesh_obj)\n"
|
"bpy.context.scene.collection.objects.link(path_mesh_obj)\n"
|
||||||
"path_mesh_obj.draw_type = 'SOLID'\n"
|
"path_mesh_obj.display_type = 'SOLID'\n"
|
||||||
"path_mesh_obj.game.physics_type = 'STATIC'\n"
|
|
||||||
"path_mesh_obj.layers[1] = True\n"
|
|
||||||
"bpy.context.scene.hecl_path_obj = path_mesh_obj.name\n"
|
"bpy.context.scene.hecl_path_obj = path_mesh_obj.name\n"
|
||||||
"\n"
|
"\n";
|
||||||
"for ar in bpy.context.screen.areas:\n"
|
|
||||||
" for sp in ar.spaces:\n"
|
|
||||||
" if sp.type == 'VIEW_3D':\n"
|
|
||||||
" sp.viewport_shade = 'SOLID'\n";
|
|
||||||
|
|
||||||
if (xf) {
|
if (xf) {
|
||||||
const zeus::CMatrix4f& w = *xf;
|
const zeus::CMatrix4f& w = *xf;
|
||||||
|
|
|
@ -34,7 +34,7 @@ void CINF::sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const {
|
||||||
for (atUint32 bid : boneIds) {
|
for (atUint32 bid : boneIds) {
|
||||||
for (const Name& name : names) {
|
for (const Name& name : names) {
|
||||||
if (name.boneId == bid) {
|
if (name.boneId == bid) {
|
||||||
os.format("obj.vertex_groups.new('%s')\n", name.name.c_str());
|
os.format("obj.vertex_groups.new(name='%s')\n", name.name.c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@ void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& c
|
||||||
os.format(
|
os.format(
|
||||||
"arm = bpy.data.armatures.new('CINF_%08X')\n"
|
"arm = bpy.data.armatures.new('CINF_%08X')\n"
|
||||||
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
|
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
|
||||||
"bpy.context.scene.objects.link(arm_obj)\n"
|
"bpy.context.scene.collection.objects.link(arm_obj)\n"
|
||||||
"bpy.context.scene.objects.active = arm_obj\n"
|
"bpy.context.view_layer.objects.active = arm_obj\n"
|
||||||
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
||||||
"arm_bone_table = {}\n",
|
"arm_bone_table = {}\n",
|
||||||
cinfId.toUint32());
|
cinfId.toUint32());
|
||||||
|
@ -72,10 +72,9 @@ void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& c
|
||||||
|
|
||||||
os << "bpy.ops.object.mode_set(mode='OBJECT')\n";
|
os << "bpy.ops.object.mode_set(mode='OBJECT')\n";
|
||||||
|
|
||||||
const char* rotMode = os.getConnection().hasSLERP() ? "QUATERNION_SLERP" : "QUATERNION";
|
|
||||||
for (const DNAANIM::RigInverter<CINF>::Bone& bone : inverter.getBones())
|
for (const DNAANIM::RigInverter<CINF>::Bone& bone : inverter.getBones())
|
||||||
os.format("arm_obj.pose.bones['%s'].rotation_mode = '%s'\n", getBoneNameFromId(bone.m_origBone.id)->c_str(),
|
os.format("arm_obj.pose.bones['%s'].rotation_mode = 'QUATERNION'\n",
|
||||||
rotMode);
|
getBoneNameFromId(bone.m_origBone.id)->c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CINF::GetCINFArmatureName(const UniqueID32& cinfId) { return hecl::Format("CINF_%08X", cinfId.toUint32()); }
|
std::string CINF::GetCINFArmatureName(const UniqueID32& cinfId) { return hecl::Format("CINF_%08X", cinfId.toUint32()); }
|
||||||
|
|
|
@ -215,8 +215,6 @@ void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) {
|
||||||
" return len(material_index)-1\n"
|
" return len(material_index)-1\n"
|
||||||
" else:\n"
|
" else:\n"
|
||||||
" mat = make_color(len(material_dict), mat_type, mat_name)\n"
|
" mat = make_color(len(material_dict), mat_type, mat_name)\n"
|
||||||
" mat.diffuse_intensity = 1.0\n"
|
|
||||||
" mat.specular_intensity = 0.0\n"
|
|
||||||
" mat.retro_unknown = ((data >> 0) & 1)\n"
|
" mat.retro_unknown = ((data >> 0) & 1)\n"
|
||||||
" mat.retro_surface_stone = ((data >> 1) & 1)\n"
|
" mat.retro_surface_stone = ((data >> 1) & 1)\n"
|
||||||
" mat.retro_surface_metal = ((data >> 2) & 1)\n"
|
" mat.retro_surface_metal = ((data >> 2) & 1)\n"
|
||||||
|
|
|
@ -197,15 +197,14 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
"\n"
|
"\n"
|
||||||
"bpy.context.scene.name = '%s'\n",
|
"bpy.context.scene.name = '%s'\n",
|
||||||
pakRouter.getBestEntryName(entry, false).c_str());
|
pakRouter.getBestEntryName(entry, false).c_str());
|
||||||
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath(), true);
|
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath());
|
||||||
MaterialSet::RegisterMaterialProps(os);
|
MaterialSet::RegisterMaterialProps(os);
|
||||||
os << "# Clear Scene\n"
|
os << "# Clear Scene\n"
|
||||||
"for ob in bpy.data.objects:\n"
|
"if 'Collection 1' in bpy.data.collections:\n"
|
||||||
" if ob.type != 'CAMERA':\n"
|
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||||
" bpy.context.scene.objects.unlink(ob)\n"
|
"\n"
|
||||||
" bpy.data.objects.remove(ob)\n"
|
"bpy.types.Light.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
|
||||||
"bpy.types.Lamp.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
|
"bpy.types.Light.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n"
|
||||||
"bpy.types.Lamp.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n"
|
|
||||||
"bpy.types.Object.retro_disable_enviro_visor = bpy.props.BoolProperty(name='Retro: Disable in Combat/Scan "
|
"bpy.types.Object.retro_disable_enviro_visor = bpy.props.BoolProperty(name='Retro: Disable in Combat/Scan "
|
||||||
"Visor')\n"
|
"Visor')\n"
|
||||||
"bpy.types.Object.retro_disable_thermal_visor = bpy.props.BoolProperty(name='Retro: Disable in Thermal "
|
"bpy.types.Object.retro_disable_thermal_visor = bpy.props.BoolProperty(name='Retro: Disable in Thermal "
|
||||||
|
@ -284,11 +283,11 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
drs.seek(secStart + head.secSizes[curSec++], athena::Begin);
|
drs.seek(secStart + head.secSizes[curSec++], athena::Begin);
|
||||||
|
|
||||||
/* Origins to center of mass */
|
/* Origins to center of mass */
|
||||||
os << "bpy.context.scene.layers[1] = True\n"
|
os << "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = False\n"
|
||||||
"bpy.ops.object.select_by_type(type='MESH')\n"
|
"bpy.ops.object.select_by_type(type='MESH')\n"
|
||||||
"bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n"
|
"bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n"
|
||||||
"bpy.ops.object.select_all(action='DESELECT')\n"
|
"bpy.ops.object.select_all(action='DESELECT')\n"
|
||||||
"bpy.context.scene.layers[1] = False\n";
|
"bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = True\n";
|
||||||
|
|
||||||
os.centerView();
|
os.centerView();
|
||||||
os.close();
|
os.close();
|
||||||
|
|
|
@ -9,8 +9,8 @@ void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID64& c
|
||||||
os.format("arm = bpy.data.armatures.new('CINF_%016" PRIX64
|
os.format("arm = bpy.data.armatures.new('CINF_%016" PRIX64
|
||||||
"')\n"
|
"')\n"
|
||||||
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
|
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
|
||||||
"bpy.context.scene.objects.link(arm_obj)\n"
|
"bpy.context.scene.collection.objects.link(arm_obj)\n"
|
||||||
"bpy.context.scene.objects.active = arm_obj\n"
|
"bpy.context.view_layer.objects.active = arm_obj\n"
|
||||||
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
||||||
"arm_bone_table = {}\n",
|
"arm_bone_table = {}\n",
|
||||||
cinfId.toUint64());
|
cinfId.toUint64());
|
||||||
|
@ -37,10 +37,9 @@ void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID64& c
|
||||||
|
|
||||||
os << "bpy.ops.object.mode_set(mode='OBJECT')\n";
|
os << "bpy.ops.object.mode_set(mode='OBJECT')\n";
|
||||||
|
|
||||||
const char* rotMode = os.getConnection().hasSLERP() ? "QUATERNION_SLERP" : "QUATERNION";
|
|
||||||
for (const DNAANIM::RigInverter<CINF>::Bone& bone : inverter.getBones())
|
for (const DNAANIM::RigInverter<CINF>::Bone& bone : inverter.getBones())
|
||||||
os.format("arm_obj.pose.bones['%s'].rotation_mode = '%s'\n", getBoneNameFromId(bone.m_origBone.id)->c_str(),
|
os.format("arm_obj.pose.bones['%s'].rotation_mode = 'QUATERNION'\n",
|
||||||
rotMode);
|
getBoneNameFromId(bone.m_origBone.id)->c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CINF::GetCINFArmatureName(const UniqueID64& cinfId) {
|
std::string CINF::GetCINFArmatureName(const UniqueID64& cinfId) {
|
||||||
|
|
|
@ -87,8 +87,6 @@ void MaterialSet::ConstructMaterial(Stream& out, const PAKRouter<PAKBridge>& pak
|
||||||
"new_material.use_shadows = True\n"
|
"new_material.use_shadows = True\n"
|
||||||
"new_material.use_transparent_shadows = True\n"
|
"new_material.use_transparent_shadows = True\n"
|
||||||
"new_material.diffuse_color = (1.0,1.0,1.0)\n"
|
"new_material.diffuse_color = (1.0,1.0,1.0)\n"
|
||||||
"new_material.diffuse_intensity = 1.0\n"
|
|
||||||
"new_material.specular_intensity = 0.0\n"
|
|
||||||
"new_material.use_nodes = True\n"
|
"new_material.use_nodes = True\n"
|
||||||
"new_nodetree = new_material.node_tree\n"
|
"new_nodetree = new_material.node_tree\n"
|
||||||
"material_node = new_nodetree.nodes['Material']\n"
|
"material_node = new_nodetree.nodes['Material']\n"
|
||||||
|
@ -112,22 +110,16 @@ void MaterialSet::ConstructMaterial(Stream& out, const PAKRouter<PAKBridge>& pak
|
||||||
out.format(
|
out.format(
|
||||||
"new_material.retro_alpha_test = %s\n"
|
"new_material.retro_alpha_test = %s\n"
|
||||||
"new_material.retro_shadow_occluder = %s\n"
|
"new_material.retro_shadow_occluder = %s\n"
|
||||||
"new_material.game_settings.invisible = %s\n",
|
"new_material.diffuse_color = (1, 1, 1, %s)\n",
|
||||||
material.header.flags.alphaTest() ? "True" : "False",
|
material.header.flags.alphaTest() ? "True" : "False",
|
||||||
material.header.flags.shadowOccluderMesh() ? "True" : "False",
|
material.header.flags.shadowOccluderMesh() ? "True" : "False",
|
||||||
material.header.flags.shadowOccluderMesh() ? "True" : "False");
|
material.header.flags.shadowOccluderMesh() ? "0" : "1");
|
||||||
|
|
||||||
/* Blend factors */
|
/* Blend factors */
|
||||||
if (material.header.flags.alphaBlending())
|
if (material.header.flags.alphaBlending())
|
||||||
out << "new_material.game_settings.alpha_blend = 'ALPHA'\n"
|
out << "new_material.blend_method = 'BLEND'\n";
|
||||||
"new_material.use_transparency = True\n"
|
|
||||||
"new_material.transparency_method = 'RAYTRACE'\n"
|
|
||||||
"new_material.alpha = 1.0\n";
|
|
||||||
else if (material.header.flags.additiveBlending())
|
else if (material.header.flags.additiveBlending())
|
||||||
out << "new_material.game_settings.alpha_blend = 'ADD'\n"
|
out << "new_material.blend_method = 'ADD'\n";
|
||||||
"new_material.use_transparency = True\n"
|
|
||||||
"new_material.transparency_method = 'RAYTRACE'\n"
|
|
||||||
"new_material.alpha = 1.0\n";
|
|
||||||
|
|
||||||
/* Texmap list */
|
/* Texmap list */
|
||||||
out << "tex_maps = []\n"
|
out << "tex_maps = []\n"
|
||||||
|
|
|
@ -43,9 +43,7 @@ void MREA::ReadBabeDeadToBlender_3(hecl::blender::PyOutStream& os, athena::io::I
|
||||||
atUint32 bdMagic = rs.readUint32Big();
|
atUint32 bdMagic = rs.readUint32Big();
|
||||||
if (bdMagic != 0xBABEDEAD)
|
if (bdMagic != 0xBABEDEAD)
|
||||||
Log.report(logvisor::Fatal, "invalid BABEDEAD magic");
|
Log.report(logvisor::Fatal, "invalid BABEDEAD magic");
|
||||||
os << "bpy.context.scene.render.engine = 'CYCLES'\n"
|
os << "bpy.context.scene.world.use_nodes = True\n"
|
||||||
"bpy.context.scene.world.use_nodes = True\n"
|
|
||||||
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
|
|
||||||
"bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n"
|
"bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n"
|
||||||
"bg_node.inputs[1].default_value = 0.0\n";
|
"bg_node.inputs[1].default_value = 0.0\n";
|
||||||
for (atUint32 s = 0; s < 4; ++s) {
|
for (atUint32 s = 0; s < 4; ++s) {
|
||||||
|
@ -102,15 +100,14 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
"\n"
|
"\n"
|
||||||
"bpy.context.scene.name = '%s'\n",
|
"bpy.context.scene.name = '%s'\n",
|
||||||
pakRouter.getBestEntryName(entry, false).c_str());
|
pakRouter.getBestEntryName(entry, false).c_str());
|
||||||
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath(), true);
|
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath());
|
||||||
MaterialSet::RegisterMaterialProps(os);
|
MaterialSet::RegisterMaterialProps(os);
|
||||||
os << "# Clear Scene\n"
|
os << "# Clear Scene\n"
|
||||||
"for ob in bpy.data.objects:\n"
|
"if 'Collection 1' in bpy.data.collections:\n"
|
||||||
" if ob.type != 'CAMERA':\n"
|
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||||
" bpy.context.scene.objects.unlink(ob)\n"
|
"\n"
|
||||||
" bpy.data.objects.remove(ob)\n"
|
"bpy.types.Light.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
|
||||||
"bpy.types.Lamp.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
|
"bpy.types.Light.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n"
|
||||||
"bpy.types.Lamp.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n"
|
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
/* One shared material set for all meshes */
|
/* One shared material set for all meshes */
|
||||||
|
@ -213,11 +210,11 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Origins to center of mass */
|
/* Origins to center of mass */
|
||||||
os << "bpy.context.scene.layers[1] = True\n"
|
os << "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = False\n"
|
||||||
"bpy.ops.object.select_by_type(type='MESH')\n"
|
"bpy.ops.object.select_by_type(type='MESH')\n"
|
||||||
"bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n"
|
"bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n"
|
||||||
"bpy.ops.object.select_all(action='DESELECT')\n"
|
"bpy.ops.object.select_all(action='DESELECT')\n"
|
||||||
"bpy.context.scene.layers[1] = False\n";
|
"bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = True\n";
|
||||||
|
|
||||||
os.centerView();
|
os.centerView();
|
||||||
os.close();
|
os.close();
|
||||||
|
|
|
@ -193,7 +193,7 @@ static bool IsPathSong(const hecl::ProjectPath& path) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpecBase::canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok, int cookPass) {
|
bool SpecBase::canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok) {
|
||||||
if (!checkPathPrefix(path))
|
if (!checkPathPrefix(path))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -205,16 +205,9 @@ bool SpecBase::canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok
|
||||||
|
|
||||||
if (hecl::IsPathBlend(asBlend)) {
|
if (hecl::IsPathBlend(asBlend)) {
|
||||||
hecl::blender::BlendType type = hecl::blender::GetBlendType(asBlend.getAbsolutePath());
|
hecl::blender::BlendType type = hecl::blender::GetBlendType(asBlend.getAbsolutePath());
|
||||||
if (type != hecl::blender::BlendType::None)
|
return type != hecl::blender::BlendType::None;
|
||||||
return cookPass < 0 || (cookPass == 0 && type == hecl::blender::BlendType::Mesh) || // CMDL only
|
|
||||||
(cookPass == 1 && type != hecl::blender::BlendType::Mesh); // Non-CMDL only
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Non-CMDLs shall not pass */
|
|
||||||
if (cookPass == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (hecl::IsPathPNG(path)) {
|
if (hecl::IsPathPNG(path)) {
|
||||||
return true;
|
return true;
|
||||||
} else if (hecl::IsPathYAML(path)) {
|
} else if (hecl::IsPathYAML(path)) {
|
||||||
|
@ -230,8 +223,7 @@ bool SpecBase::canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok
|
||||||
}
|
}
|
||||||
|
|
||||||
const hecl::Database::DataSpecEntry* SpecBase::overrideDataSpec(const hecl::ProjectPath& path,
|
const hecl::Database::DataSpecEntry* SpecBase::overrideDataSpec(const hecl::ProjectPath& path,
|
||||||
const hecl::Database::DataSpecEntry* oldEntry,
|
const hecl::Database::DataSpecEntry* oldEntry) const {
|
||||||
hecl::blender::Token& btok) const {
|
|
||||||
if (!checkPathPrefix(path))
|
if (!checkPathPrefix(path))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
@ -487,7 +479,7 @@ void SpecBase::recursiveBuildResourceList(std::vector<urde::SObjectTag>& listOut
|
||||||
if (hecl::ProjectPath(childPath, _SYS_STR("!project.yaml")).isFile() &&
|
if (hecl::ProjectPath(childPath, _SYS_STR("!project.yaml")).isFile() &&
|
||||||
hecl::ProjectPath(childPath, _SYS_STR("!pool.yaml")).isFile()) {
|
hecl::ProjectPath(childPath, _SYS_STR("!pool.yaml")).isFile()) {
|
||||||
/* Handle AudioGroup case */
|
/* Handle AudioGroup case */
|
||||||
if (urde::SObjectTag tag = tagFromPath(childPath, btok)) {
|
if (urde::SObjectTag tag = tagFromPath(childPath)) {
|
||||||
if (addedTags.find(tag) != addedTags.end())
|
if (addedTags.find(tag) != addedTags.end())
|
||||||
continue;
|
continue;
|
||||||
addedTags.insert(tag);
|
addedTags.insert(tag);
|
||||||
|
@ -501,7 +493,7 @@ void SpecBase::recursiveBuildResourceList(std::vector<urde::SObjectTag>& listOut
|
||||||
std::vector<hecl::ProjectPath> subPaths;
|
std::vector<hecl::ProjectPath> subPaths;
|
||||||
flattenDependencies(childPath, subPaths, btok);
|
flattenDependencies(childPath, subPaths, btok);
|
||||||
for (const auto& subPath : subPaths) {
|
for (const auto& subPath : subPaths) {
|
||||||
if (urde::SObjectTag tag = tagFromPath(subPath, btok)) {
|
if (urde::SObjectTag tag = tagFromPath(subPath)) {
|
||||||
if (addedTags.find(tag) != addedTags.end())
|
if (addedTags.find(tag) != addedTags.end())
|
||||||
continue;
|
continue;
|
||||||
addedTags.insert(tag);
|
addedTags.insert(tag);
|
||||||
|
@ -637,7 +629,7 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
|
||||||
std::unordered_set<urde::SObjectTag> addedTags;
|
std::unordered_set<urde::SObjectTag> addedTags;
|
||||||
std::vector<std::pair<urde::SObjectTag, std::string>> nameList;
|
std::vector<std::pair<urde::SObjectTag, std::string>> nameList;
|
||||||
for (const auto& subPath : subPaths) {
|
for (const auto& subPath : subPaths) {
|
||||||
if (urde::SObjectTag tag = tagFromPath(subPath, btok)) {
|
if (urde::SObjectTag tag = tagFromPath(subPath)) {
|
||||||
if (addedTags.find(tag) != addedTags.end())
|
if (addedTags.find(tag) != addedTags.end())
|
||||||
continue;
|
continue;
|
||||||
addedTags.insert(tag);
|
addedTags.insert(tag);
|
||||||
|
@ -664,21 +656,31 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
|
||||||
if (cp) {
|
if (cp) {
|
||||||
Log.report(logvisor::Info, _SYS_STR("Validating resources"));
|
Log.report(logvisor::Info, _SYS_STR("Validating resources"));
|
||||||
progress.setMainIndeterminate(true);
|
progress.setMainIndeterminate(true);
|
||||||
for (int i = 0; i < entry->m_numCookPasses; ++i) {
|
std::vector<urde::SObjectTag> cookTags;
|
||||||
|
cookTags.reserve(buildList.size());
|
||||||
|
|
||||||
|
/* Ensure CMDLs are enqueued first to minimize synchronous dependency cooking */
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
std::unordered_set<urde::SObjectTag> addedTags;
|
std::unordered_set<urde::SObjectTag> addedTags;
|
||||||
addedTags.reserve(buildList.size());
|
addedTags.reserve(buildList.size());
|
||||||
for (auto& tag : buildList) {
|
for (auto& tag : buildList) {
|
||||||
if (addedTags.find(tag) != addedTags.end())
|
if ((i == 0 && tag.type == FOURCC('CMDL')) ||
|
||||||
continue;
|
(i == 1 && tag.type != FOURCC('CMDL'))) {
|
||||||
addedTags.insert(tag);
|
if (addedTags.find(tag) != addedTags.end())
|
||||||
|
continue;
|
||||||
hecl::ProjectPath depPath = pathFromTag(tag);
|
addedTags.insert(tag);
|
||||||
if (!depPath) {
|
cookTags.push_back(tag);
|
||||||
Log.report(logvisor::Fatal, _SYS_STR("Unable to resolve %.4s %08X"), tag.type.getChars(), tag.id.Value());
|
|
||||||
}
|
}
|
||||||
m_project.cookPath(depPath, progress, false, false, fast, entry, cp, i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cook ordered tags */
|
||||||
|
for (auto& tag : cookTags) {
|
||||||
|
hecl::ProjectPath depPath = pathFromTag(tag);
|
||||||
|
if (!depPath)
|
||||||
|
Log.report(logvisor::Fatal, _SYS_STR("Unable to resolve %.4s %08X"), tag.type.getChars(), tag.id.Value());
|
||||||
|
m_project.cookPath(depPath, progress, false, false, fast, entry, cp);
|
||||||
|
}
|
||||||
progress.setMainIndeterminate(false);
|
progress.setMainIndeterminate(false);
|
||||||
cp->waitUntilComplete();
|
cp->waitUntilComplete();
|
||||||
progress.startNewLine();
|
progress.startNewLine();
|
||||||
|
@ -699,7 +701,7 @@ void SpecBase::interruptCook() { cancelBackgroundIndex(); }
|
||||||
hecl::ProjectPath SpecBase::getCookedPath(const hecl::ProjectPath& working, bool pcTarget) const {
|
hecl::ProjectPath SpecBase::getCookedPath(const hecl::ProjectPath& working, bool pcTarget) const {
|
||||||
const hecl::Database::DataSpecEntry* spec = &getOriginalSpec();
|
const hecl::Database::DataSpecEntry* spec = &getOriginalSpec();
|
||||||
if (pcTarget)
|
if (pcTarget)
|
||||||
spec = overrideDataSpec(working, getDataSpecEntry(), hecl::blender::SharedBlenderToken);
|
spec = overrideDataSpec(working, getDataSpecEntry());
|
||||||
if (!spec)
|
if (!spec)
|
||||||
return {};
|
return {};
|
||||||
return working.getCookedPath(*spec);
|
return working.getCookedPath(*spec);
|
||||||
|
@ -771,11 +773,11 @@ hecl::ProjectPath SpecBase::pathFromTag(const urde::SObjectTag& tag) const {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
urde::SObjectTag SpecBase::tagFromPath(const hecl::ProjectPath& path, hecl::blender::Token& btok) const {
|
urde::SObjectTag SpecBase::tagFromPath(const hecl::ProjectPath& path) const {
|
||||||
auto search = m_pathToTag.find(path.hash());
|
auto search = m_pathToTag.find(path.hash());
|
||||||
if (search != m_pathToTag.cend())
|
if (search != m_pathToTag.cend())
|
||||||
return search->second;
|
return search->second;
|
||||||
return buildTagFromPath(path, btok);
|
return buildTagFromPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpecBase::waitForTagReady(const urde::SObjectTag& tag, const hecl::ProjectPath*& pathOut) {
|
bool SpecBase::waitForTagReady(const urde::SObjectTag& tag, const hecl::ProjectPath*& pathOut) {
|
||||||
|
@ -920,7 +922,7 @@ void SpecBase::readCatalog(const hecl::ProjectPath& catalogPath, athena::io::YAM
|
||||||
}
|
}
|
||||||
if (path.isNone())
|
if (path.isNone())
|
||||||
continue;
|
continue;
|
||||||
urde::SObjectTag pathTag = tagFromPath(path, m_backgroundBlender);
|
urde::SObjectTag pathTag = tagFromPath(path);
|
||||||
if (pathTag) {
|
if (pathTag) {
|
||||||
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
||||||
m_catalogNameToTag[pLower] = pathTag;
|
m_catalogNameToTag[pLower] = pathTag;
|
||||||
|
@ -981,7 +983,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Classify intermediate into tag */
|
/* Classify intermediate into tag */
|
||||||
urde::SObjectTag pathTag = buildTagFromPath(path, m_backgroundBlender);
|
urde::SObjectTag pathTag = buildTagFromPath(path);
|
||||||
if (pathTag) {
|
if (pathTag) {
|
||||||
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
||||||
bool useGlob = false;
|
bool useGlob = false;
|
||||||
|
@ -1004,7 +1006,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
||||||
for (const std::string& arm : armatureNames) {
|
for (const std::string& arm : armatureNames) {
|
||||||
hecl::SystemStringConv sysStr(arm);
|
hecl::SystemStringConv sysStr(arm);
|
||||||
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".CINF"));
|
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".CINF"));
|
||||||
urde::SObjectTag pathTag = buildTagFromPath(subPath, m_backgroundBlender);
|
urde::SObjectTag pathTag = buildTagFromPath(subPath);
|
||||||
m_tagToPath[pathTag] = subPath;
|
m_tagToPath[pathTag] = subPath;
|
||||||
m_pathToTag[subPath.hash()] = pathTag;
|
m_pathToTag[subPath.hash()] = pathTag;
|
||||||
WriteTag(cacheWriter, pathTag, subPath);
|
WriteTag(cacheWriter, pathTag, subPath);
|
||||||
|
@ -1016,7 +1018,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
||||||
for (const std::string& sub : subtypeNames) {
|
for (const std::string& sub : subtypeNames) {
|
||||||
hecl::SystemStringConv sysStr(sub);
|
hecl::SystemStringConv sysStr(sub);
|
||||||
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".CSKR"));
|
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".CSKR"));
|
||||||
urde::SObjectTag pathTag = buildTagFromPath(subPath, m_backgroundBlender);
|
urde::SObjectTag pathTag = buildTagFromPath(subPath);
|
||||||
m_tagToPath[pathTag] = subPath;
|
m_tagToPath[pathTag] = subPath;
|
||||||
m_pathToTag[subPath.hash()] = pathTag;
|
m_pathToTag[subPath.hash()] = pathTag;
|
||||||
WriteTag(cacheWriter, pathTag, subPath);
|
WriteTag(cacheWriter, pathTag, subPath);
|
||||||
|
@ -1029,7 +1031,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
||||||
hecl::SystemStringConv overlaySys(overlay);
|
hecl::SystemStringConv overlaySys(overlay);
|
||||||
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR('.') +
|
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR('.') +
|
||||||
overlaySys.c_str() + _SYS_STR(".CSKR"));
|
overlaySys.c_str() + _SYS_STR(".CSKR"));
|
||||||
urde::SObjectTag pathTag = buildTagFromPath(subPath, m_backgroundBlender);
|
urde::SObjectTag pathTag = buildTagFromPath(subPath);
|
||||||
m_tagToPath[pathTag] = subPath;
|
m_tagToPath[pathTag] = subPath;
|
||||||
m_pathToTag[subPath.hash()] = pathTag;
|
m_pathToTag[subPath.hash()] = pathTag;
|
||||||
WriteTag(cacheWriter, pathTag, subPath);
|
WriteTag(cacheWriter, pathTag, subPath);
|
||||||
|
@ -1044,7 +1046,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
||||||
hecl::SystemStringConv attachmentSys(attachment);
|
hecl::SystemStringConv attachmentSys(attachment);
|
||||||
hecl::ProjectPath subPath =
|
hecl::ProjectPath subPath =
|
||||||
asGlob.ensureAuxInfo(hecl::SystemString(_SYS_STR("ATTACH.")) + attachmentSys.c_str() + _SYS_STR(".CSKR"));
|
asGlob.ensureAuxInfo(hecl::SystemString(_SYS_STR("ATTACH.")) + attachmentSys.c_str() + _SYS_STR(".CSKR"));
|
||||||
urde::SObjectTag pathTag = buildTagFromPath(subPath, m_backgroundBlender);
|
urde::SObjectTag pathTag = buildTagFromPath(subPath);
|
||||||
m_tagToPath[pathTag] = subPath;
|
m_tagToPath[pathTag] = subPath;
|
||||||
m_pathToTag[subPath.hash()] = pathTag;
|
m_pathToTag[subPath.hash()] = pathTag;
|
||||||
WriteTag(cacheWriter, pathTag, subPath);
|
WriteTag(cacheWriter, pathTag, subPath);
|
||||||
|
@ -1056,7 +1058,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
||||||
for (const std::string& act : actionNames) {
|
for (const std::string& act : actionNames) {
|
||||||
hecl::SystemStringConv sysStr(act);
|
hecl::SystemStringConv sysStr(act);
|
||||||
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".ANIM"));
|
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".ANIM"));
|
||||||
urde::SObjectTag pathTag = buildTagFromPath(subPath, m_backgroundBlender);
|
urde::SObjectTag pathTag = buildTagFromPath(subPath);
|
||||||
m_tagToPath[pathTag] = subPath;
|
m_tagToPath[pathTag] = subPath;
|
||||||
m_pathToTag[subPath.hash()] = pathTag;
|
m_pathToTag[subPath.hash()] = pathTag;
|
||||||
WriteTag(cacheWriter, pathTag, subPath);
|
WriteTag(cacheWriter, pathTag, subPath);
|
||||||
|
@ -1070,7 +1072,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
||||||
useGlob = true;
|
useGlob = true;
|
||||||
|
|
||||||
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(_SYS_STR("MAPW"));
|
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(_SYS_STR("MAPW"));
|
||||||
urde::SObjectTag pathTag = buildTagFromPath(subPath, m_backgroundBlender);
|
urde::SObjectTag pathTag = buildTagFromPath(subPath);
|
||||||
m_tagToPath[pathTag] = subPath;
|
m_tagToPath[pathTag] = subPath;
|
||||||
m_pathToTag[subPath.hash()] = pathTag;
|
m_pathToTag[subPath.hash()] = pathTag;
|
||||||
WriteTag(cacheWriter, pathTag, subPath);
|
WriteTag(cacheWriter, pathTag, subPath);
|
||||||
|
@ -1079,7 +1081,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
subPath = asGlob.ensureAuxInfo(_SYS_STR("SAVW"));
|
subPath = asGlob.ensureAuxInfo(_SYS_STR("SAVW"));
|
||||||
pathTag = buildTagFromPath(subPath, m_backgroundBlender);
|
pathTag = buildTagFromPath(subPath);
|
||||||
m_tagToPath[pathTag] = subPath;
|
m_tagToPath[pathTag] = subPath;
|
||||||
m_pathToTag[subPath.hash()] = pathTag;
|
m_pathToTag[subPath.hash()] = pathTag;
|
||||||
WriteTag(cacheWriter, pathTag, subPath);
|
WriteTag(cacheWriter, pathTag, subPath);
|
||||||
|
@ -1216,7 +1218,7 @@ void SpecBase::backgroundIndexProc() {
|
||||||
|
|
||||||
/* Add special original IDs resource if exists (not name-cached to disk) */
|
/* Add special original IDs resource if exists (not name-cached to disk) */
|
||||||
hecl::ProjectPath oidsPath(specRoot, "!original_ids.yaml");
|
hecl::ProjectPath oidsPath(specRoot, "!original_ids.yaml");
|
||||||
urde::SObjectTag oidsTag = buildTagFromPath(oidsPath, m_backgroundBlender);
|
urde::SObjectTag oidsTag = buildTagFromPath(oidsPath);
|
||||||
if (oidsTag) {
|
if (oidsTag) {
|
||||||
m_catalogNameToTag["mp1originalids"] = oidsTag;
|
m_catalogNameToTag["mp1originalids"] = oidsTag;
|
||||||
m_catalogTagToNames[oidsTag].insert("MP1OriginalIDs");
|
m_catalogTagToNames[oidsTag].insert("MP1OriginalIDs");
|
||||||
|
|
|
@ -36,10 +36,9 @@ struct SpecBase : hecl::Database::IDataSpec {
|
||||||
bool canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps);
|
bool canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps);
|
||||||
void doExtract(const ExtractPassInfo& info, const hecl::MultiProgressPrinter& progress);
|
void doExtract(const ExtractPassInfo& info, const hecl::MultiProgressPrinter& progress);
|
||||||
|
|
||||||
bool canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok, int cookPass);
|
bool canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok);
|
||||||
const hecl::Database::DataSpecEntry* overrideDataSpec(const hecl::ProjectPath& path,
|
const hecl::Database::DataSpecEntry* overrideDataSpec(const hecl::ProjectPath& path,
|
||||||
const hecl::Database::DataSpecEntry* oldEntry,
|
const hecl::Database::DataSpecEntry* oldEntry) const;
|
||||||
hecl::blender::Token& btok) const;
|
|
||||||
void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, hecl::blender::Token& btok,
|
void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, hecl::blender::Token& btok,
|
||||||
FCookProgress progress);
|
FCookProgress progress);
|
||||||
|
|
||||||
|
@ -59,7 +58,7 @@ struct SpecBase : hecl::Database::IDataSpec {
|
||||||
virtual bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) = 0;
|
virtual bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) = 0;
|
||||||
|
|
||||||
/* Convert path to object tag */
|
/* Convert path to object tag */
|
||||||
virtual urde::SObjectTag buildTagFromPath(const hecl::ProjectPath& path, hecl::blender::Token& btok) const = 0;
|
virtual urde::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const = 0;
|
||||||
|
|
||||||
/* Even if PC spec is being cooked, this will return the vanilla GCN spec */
|
/* Even if PC spec is being cooked, this will return the vanilla GCN spec */
|
||||||
virtual const hecl::Database::DataSpecEntry& getOriginalSpec() const = 0;
|
virtual const hecl::Database::DataSpecEntry& getOriginalSpec() const = 0;
|
||||||
|
@ -145,7 +144,7 @@ struct SpecBase : hecl::Database::IDataSpec {
|
||||||
void extractRandomStaticEntropy(const uint8_t* buf, const hecl::ProjectPath& noAramPath);
|
void extractRandomStaticEntropy(const uint8_t* buf, const hecl::ProjectPath& noAramPath);
|
||||||
|
|
||||||
/* Tag cache functions */
|
/* Tag cache functions */
|
||||||
urde::SObjectTag tagFromPath(const hecl::ProjectPath& path, hecl::blender::Token& btok) const;
|
urde::SObjectTag tagFromPath(const hecl::ProjectPath& path) const;
|
||||||
hecl::ProjectPath pathFromTag(const urde::SObjectTag& tag) const;
|
hecl::ProjectPath pathFromTag(const urde::SObjectTag& tag) const;
|
||||||
bool waitForTagReady(const urde::SObjectTag& tag, const hecl::ProjectPath*& pathOut);
|
bool waitForTagReady(const urde::SObjectTag& tag, const hecl::ProjectPath*& pathOut);
|
||||||
const urde::SObjectTag* getResourceIdByName(std::string_view name) const;
|
const urde::SObjectTag* getResourceIdByName(std::string_view name) const;
|
||||||
|
|
|
@ -480,7 +480,7 @@ struct SpecMP1 : SpecBase {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
urde::SObjectTag buildTagFromPath(const hecl::ProjectPath& path, hecl::blender::Token& btok) const {
|
urde::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const {
|
||||||
if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CINF")))
|
if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CINF")))
|
||||||
return {SBIG('CINF'), path.hash().val32()};
|
return {SBIG('CINF'), path.hash().val32()};
|
||||||
else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CSKR")))
|
else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CSKR")))
|
||||||
|
@ -655,9 +655,7 @@ struct SpecMP1 : SpecBase {
|
||||||
|
|
||||||
void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
|
void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
|
||||||
hecl::blender::Token& btok, FCookProgress progress) {
|
hecl::blender::Token& btok, FCookProgress progress) {
|
||||||
Mesh mesh =
|
Mesh mesh = ds.compileMesh(fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, m_pc ? 16 : -1);
|
||||||
ds.compileMesh(fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, m_pc ? 16 : -1,
|
|
||||||
[&progress](int surfCount) { progress(hecl::SysFormat(_SYS_STR("%d"), surfCount).c_str()); });
|
|
||||||
|
|
||||||
if (m_pc)
|
if (m_pc)
|
||||||
DNAMP1::CMDL::HMDLCook(out, in, mesh);
|
DNAMP1::CMDL::HMDLCook(out, in, mesh);
|
||||||
|
@ -747,8 +745,7 @@ struct SpecMP1 : SpecBase {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
meshCompiles.push_back(ds.compileMesh(
|
meshCompiles.push_back(ds.compileMesh(
|
||||||
mesh, fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, -1, !m_pc,
|
mesh, fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, -1, !m_pc));
|
||||||
[&](int surfCount) { progress(hecl::SysFormat(_SYS_STR("%s %d"), meshSys.c_str(), surfCount).c_str()); }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!colMesh)
|
if (!colMesh)
|
||||||
|
@ -773,7 +770,7 @@ struct SpecMP1 : SpecBase {
|
||||||
if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR("MAPW"))) {
|
if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR("MAPW"))) {
|
||||||
hecl::blender::World world = ds.compileWorld();
|
hecl::blender::World world = ds.compileWorld();
|
||||||
ds.close();
|
ds.close();
|
||||||
DNAMP1::MLVL::CookMAPW(out, world, btok);
|
DNAMP1::MLVL::CookMAPW(out, world);
|
||||||
} else if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR("SAVW"))) {
|
} else if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR("SAVW"))) {
|
||||||
hecl::blender::World world = ds.compileWorld();
|
hecl::blender::World world = ds.compileWorld();
|
||||||
ds.close();
|
ds.close();
|
||||||
|
@ -1028,7 +1025,7 @@ struct SpecMP1 : SpecBase {
|
||||||
}
|
}
|
||||||
listOut.reserve(count);
|
listOut.reserve(count);
|
||||||
|
|
||||||
urde::SObjectTag worldTag = tagFromPath(worldPath.getWithExtension(_SYS_STR(".*"), true), btok);
|
urde::SObjectTag worldTag = tagFromPath(worldPath.getWithExtension(_SYS_STR(".*"), true));
|
||||||
|
|
||||||
w.writeUint32Big(m_pc ? 0x80030005 : 0x00030005);
|
w.writeUint32Big(m_pc ? 0x80030005 : 0x00030005);
|
||||||
w.writeUint32Big(0);
|
w.writeUint32Big(0);
|
||||||
|
@ -1131,7 +1128,7 @@ struct SpecMP1 : SpecBase {
|
||||||
auto data = btok.getBlenderConnection().beginData();
|
auto data = btok.getBlenderConnection().beginData();
|
||||||
std::vector<hecl::ProjectPath> textures = data.getTextures();
|
std::vector<hecl::ProjectPath> textures = data.getTextures();
|
||||||
for (const auto& tex : textures) {
|
for (const auto& tex : textures) {
|
||||||
urde::SObjectTag texTag = tagFromPath(tex, btok);
|
urde::SObjectTag texTag = tagFromPath(tex);
|
||||||
if (!texTag)
|
if (!texTag)
|
||||||
Log.report(logvisor::Fatal, _SYS_STR("Unable to resolve %s"), tex.getRelativePath().data());
|
Log.report(logvisor::Fatal, _SYS_STR("Unable to resolve %s"), tex.getRelativePath().data());
|
||||||
listOut.push_back(texTag);
|
listOut.push_back(texTag);
|
||||||
|
@ -1270,14 +1267,13 @@ struct SpecMP1 : SpecBase {
|
||||||
};
|
};
|
||||||
|
|
||||||
hecl::Database::DataSpecEntry SpecEntMP1 = {
|
hecl::Database::DataSpecEntry SpecEntMP1 = {
|
||||||
_SYS_STR("MP1"sv), _SYS_STR("Data specification for original Metroid Prime engine"sv), _SYS_STR(".pak"sv), 2,
|
_SYS_STR("MP1"sv), _SYS_STR("Data specification for original Metroid Prime engine"sv), _SYS_STR(".pak"sv),
|
||||||
[](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
[](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
||||||
return std::make_unique<SpecMP1>(&SpecEntMP1, project, false);
|
return std::make_unique<SpecMP1>(&SpecEntMP1, project, false);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
hecl::Database::DataSpecEntry SpecEntMP1PC = {
|
hecl::Database::DataSpecEntry SpecEntMP1PC = {
|
||||||
_SYS_STR("MP1-PC"sv), _SYS_STR("Data specification for PC-optimized Metroid Prime engine"sv), _SYS_STR(".upak"sv),
|
_SYS_STR("MP1-PC"sv), _SYS_STR("Data specification for PC-optimized Metroid Prime engine"sv), _SYS_STR(".upak"sv),
|
||||||
2,
|
|
||||||
[](hecl::Database::Project& project,
|
[](hecl::Database::Project& project,
|
||||||
hecl::Database::DataSpecTool tool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
hecl::Database::DataSpecTool tool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
||||||
if (tool != hecl::Database::DataSpecTool::Extract)
|
if (tool != hecl::Database::DataSpecTool::Extract)
|
||||||
|
@ -1286,5 +1282,5 @@ hecl::Database::DataSpecEntry SpecEntMP1PC = {
|
||||||
}};
|
}};
|
||||||
|
|
||||||
hecl::Database::DataSpecEntry SpecEntMP1ORIG = {
|
hecl::Database::DataSpecEntry SpecEntMP1ORIG = {
|
||||||
_SYS_STR("MP1-ORIG"sv), _SYS_STR("Data specification for unmodified Metroid Prime resources"sv), {}, 2, {}};
|
_SYS_STR("MP1-ORIG"sv), _SYS_STR("Data specification for unmodified Metroid Prime resources"sv), {}, {}};
|
||||||
} // namespace DataSpec
|
} // namespace DataSpec
|
||||||
|
|
|
@ -359,7 +359,7 @@ struct SpecMP2 : SpecBase {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
urde::SObjectTag buildTagFromPath(const hecl::ProjectPath& path, hecl::blender::Token& btok) const { return {}; }
|
urde::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const { return {}; }
|
||||||
|
|
||||||
void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
|
void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
|
||||||
hecl::blender::Token& btok, FCookProgress progress) {}
|
hecl::blender::Token& btok, FCookProgress progress) {}
|
||||||
|
@ -430,14 +430,13 @@ struct SpecMP2 : SpecBase {
|
||||||
};
|
};
|
||||||
|
|
||||||
hecl::Database::DataSpecEntry SpecEntMP2(
|
hecl::Database::DataSpecEntry SpecEntMP2(
|
||||||
_SYS_STR("MP2"sv), _SYS_STR("Data specification for original Metroid Prime 2 engine"sv), _SYS_STR(".pak"sv), 2,
|
_SYS_STR("MP2"sv), _SYS_STR("Data specification for original Metroid Prime 2 engine"sv), _SYS_STR(".pak"sv),
|
||||||
[](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
[](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
||||||
return std::make_unique<SpecMP2>(&SpecEntMP2, project, false);
|
return std::make_unique<SpecMP2>(&SpecEntMP2, project, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
hecl::Database::DataSpecEntry SpecEntMP2PC = {
|
hecl::Database::DataSpecEntry SpecEntMP2PC = {
|
||||||
_SYS_STR("MP2-PC"sv), _SYS_STR("Data specification for PC-optimized Metroid Prime 2 engine"sv), _SYS_STR(".upak"sv),
|
_SYS_STR("MP2-PC"sv), _SYS_STR("Data specification for PC-optimized Metroid Prime 2 engine"sv), _SYS_STR(".upak"sv),
|
||||||
2,
|
|
||||||
[](hecl::Database::Project& project,
|
[](hecl::Database::Project& project,
|
||||||
hecl::Database::DataSpecTool tool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
hecl::Database::DataSpecTool tool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
||||||
if (tool != hecl::Database::DataSpecTool::Extract)
|
if (tool != hecl::Database::DataSpecTool::Extract)
|
||||||
|
@ -446,6 +445,6 @@ hecl::Database::DataSpecEntry SpecEntMP2PC = {
|
||||||
}};
|
}};
|
||||||
|
|
||||||
hecl::Database::DataSpecEntry SpecEntMP2ORIG = {
|
hecl::Database::DataSpecEntry SpecEntMP2ORIG = {
|
||||||
_SYS_STR("MP2-ORIG"sv), _SYS_STR("Data specification for unmodified Metroid Prime 2 resources"sv), {}, 2, {}};
|
_SYS_STR("MP2-ORIG"sv), _SYS_STR("Data specification for unmodified Metroid Prime 2 resources"sv), {}, {}};
|
||||||
|
|
||||||
} // namespace DataSpec
|
} // namespace DataSpec
|
||||||
|
|
|
@ -517,7 +517,7 @@ struct SpecMP3 : SpecBase {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
urde::SObjectTag buildTagFromPath(const hecl::ProjectPath& path, hecl::blender::Token& btok) const { return {}; }
|
urde::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const { return {}; }
|
||||||
|
|
||||||
void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
|
void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
|
||||||
hecl::blender::Token& btok, FCookProgress progress) {}
|
hecl::blender::Token& btok, FCookProgress progress) {}
|
||||||
|
@ -577,14 +577,13 @@ struct SpecMP3 : SpecBase {
|
||||||
};
|
};
|
||||||
|
|
||||||
hecl::Database::DataSpecEntry SpecEntMP3(
|
hecl::Database::DataSpecEntry SpecEntMP3(
|
||||||
_SYS_STR("MP3"sv), _SYS_STR("Data specification for original Metroid Prime 3 engine"sv), _SYS_STR(".pak"sv), 2,
|
_SYS_STR("MP3"sv), _SYS_STR("Data specification for original Metroid Prime 3 engine"sv), _SYS_STR(".pak"sv),
|
||||||
[](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
[](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
||||||
return std::make_unique<SpecMP3>(&SpecEntMP3, project, false);
|
return std::make_unique<SpecMP3>(&SpecEntMP3, project, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
hecl::Database::DataSpecEntry SpecEntMP3PC = {
|
hecl::Database::DataSpecEntry SpecEntMP3PC = {
|
||||||
_SYS_STR("MP3-PC"sv), _SYS_STR("Data specification for PC-optimized Metroid Prime 3 engine"sv), _SYS_STR(".upak"sv),
|
_SYS_STR("MP3-PC"sv), _SYS_STR("Data specification for PC-optimized Metroid Prime 3 engine"sv), _SYS_STR(".upak"sv),
|
||||||
2,
|
|
||||||
[](hecl::Database::Project& project,
|
[](hecl::Database::Project& project,
|
||||||
hecl::Database::DataSpecTool tool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
hecl::Database::DataSpecTool tool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
||||||
if (tool != hecl::Database::DataSpecTool::Extract)
|
if (tool != hecl::Database::DataSpecTool::Extract)
|
||||||
|
@ -593,6 +592,6 @@ hecl::Database::DataSpecEntry SpecEntMP3PC = {
|
||||||
}};
|
}};
|
||||||
|
|
||||||
hecl::Database::DataSpecEntry SpecEntMP3ORIG = {
|
hecl::Database::DataSpecEntry SpecEntMP3ORIG = {
|
||||||
_SYS_STR("MP3-ORIG"sv), _SYS_STR("Data specification for unmodified Metroid Prime 3 resources"sv), {}, 2, {}};
|
_SYS_STR("MP3-ORIG"sv), _SYS_STR("Data specification for unmodified Metroid Prime 3 resources"sv), {}, {}};
|
||||||
|
|
||||||
} // namespace DataSpec
|
} // namespace DataSpec
|
||||||
|
|
|
@ -14,7 +14,7 @@ CToken ProjectResourcePool::GetObj(std::string_view name) {
|
||||||
|
|
||||||
hecl::ProjectPath path(*m_parent.project(), name);
|
hecl::ProjectPath path(*m_parent.project(), name);
|
||||||
SObjectTag tag =
|
SObjectTag tag =
|
||||||
static_cast<ProjectResourceFactoryBase&>(x18_factory).TagFromPath(path, hecl::blender::SharedBlenderToken);
|
static_cast<ProjectResourceFactoryBase&>(x18_factory).TagFromPath(path);
|
||||||
if (tag)
|
if (tag)
|
||||||
return CSimplePool::GetObj(tag);
|
return CSimplePool::GetObj(tag);
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ CToken ProjectResourcePool::GetObj(std::string_view name, const CVParamTransfer&
|
||||||
|
|
||||||
hecl::ProjectPath path(*m_parent.project(), name);
|
hecl::ProjectPath path(*m_parent.project(), name);
|
||||||
SObjectTag tag =
|
SObjectTag tag =
|
||||||
static_cast<ProjectResourceFactoryBase&>(x18_factory).TagFromPath(path, hecl::blender::SharedBlenderToken);
|
static_cast<ProjectResourceFactoryBase&>(x18_factory).TagFromPath(path);
|
||||||
if (tag)
|
if (tag)
|
||||||
return CSimplePool::GetObj(tag, pvxfer);
|
return CSimplePool::GetObj(tag, pvxfer);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ void ProjectResourceFactoryBase::AsyncTask::EnsurePath(const urde::SObjectTag& t
|
||||||
m_cookedPath = path.getCookedPath(*m_parent.m_origSpec);
|
m_cookedPath = path.getCookedPath(*m_parent.m_origSpec);
|
||||||
if (!m_cookedPath.isFile() || m_cookedPath.getModtime() < path.getModtime()) {
|
if (!m_cookedPath.isFile() || m_cookedPath.getModtime() < path.getModtime()) {
|
||||||
/* Last chance type validation */
|
/* Last chance type validation */
|
||||||
urde::SObjectTag verifyTag = m_parent.TagFromPath(path, hecl::blender::SharedBlenderToken);
|
urde::SObjectTag verifyTag = m_parent.TagFromPath(path);
|
||||||
if (verifyTag.type != tag.type) {
|
if (verifyTag.type != tag.type) {
|
||||||
Log.report(logvisor::Error, _SYS_STR("%s: expected type '%.4s', found '%.4s'"), path.getRelativePath().data(),
|
Log.report(logvisor::Error, _SYS_STR("%s: expected type '%.4s', found '%.4s'"), path.getRelativePath().data(),
|
||||||
tag.type.getChars(), verifyTag.type.getChars());
|
tag.type.getChars(), verifyTag.type.getChars());
|
||||||
|
@ -179,7 +179,7 @@ bool ProjectResourceFactoryBase::PrepForReadSync(const SObjectTag& tag, const he
|
||||||
cooked = path.getCookedPath(*m_origSpec);
|
cooked = path.getCookedPath(*m_origSpec);
|
||||||
if (!cooked.isFile() || cooked.getModtime() < path.getModtime()) {
|
if (!cooked.isFile() || cooked.getModtime() < path.getModtime()) {
|
||||||
/* Last chance type validation */
|
/* Last chance type validation */
|
||||||
urde::SObjectTag verifyTag = TagFromPath(path, hecl::blender::SharedBlenderToken);
|
urde::SObjectTag verifyTag = TagFromPath(path);
|
||||||
if (verifyTag.type != tag.type) {
|
if (verifyTag.type != tag.type) {
|
||||||
Log.report(logvisor::Error, _SYS_STR("%s: expected type '%.4s', found '%.4s'"), path.getRelativePath().data(),
|
Log.report(logvisor::Error, _SYS_STR("%s: expected type '%.4s', found '%.4s'"), path.getRelativePath().data(),
|
||||||
tag.type.getChars(), verifyTag.type.getChars());
|
tag.type.getChars(), verifyTag.type.getChars());
|
||||||
|
|
|
@ -96,11 +96,11 @@ protected:
|
||||||
bool WaitForTagReady(const urde::SObjectTag& tag, const hecl::ProjectPath*& pathOut) {
|
bool WaitForTagReady(const urde::SObjectTag& tag, const hecl::ProjectPath*& pathOut) {
|
||||||
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).waitForTagReady(tag, pathOut);
|
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).waitForTagReady(tag, pathOut);
|
||||||
}
|
}
|
||||||
SObjectTag TagFromPath(const hecl::ProjectPath& path, hecl::blender::Token& btok) const {
|
SObjectTag TagFromPath(const hecl::ProjectPath& path) const {
|
||||||
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).tagFromPath(path, btok);
|
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).tagFromPath(path);
|
||||||
}
|
}
|
||||||
SObjectTag BuildTagFromPath(const hecl::ProjectPath& path, hecl::blender::Token& btok) const {
|
SObjectTag BuildTagFromPath(const hecl::ProjectPath& path) const {
|
||||||
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).buildTagFromPath(path, btok);
|
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).buildTagFromPath(path);
|
||||||
}
|
}
|
||||||
void GetTagListForFile(const char* pakName, std::vector<SObjectTag>& out) const {
|
void GetTagListForFile(const char* pakName, std::vector<SObjectTag>& out) const {
|
||||||
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).getTagListForFile(pakName, out);
|
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).getTagListForFile(pakName, out);
|
||||||
|
@ -150,7 +150,7 @@ public:
|
||||||
bool IsBusy() const { return m_asyncLoadMap.size() != 0; }
|
bool IsBusy() const { return m_asyncLoadMap.size() != 0; }
|
||||||
|
|
||||||
SObjectTag TagFromPath(hecl::SystemStringView path) const {
|
SObjectTag TagFromPath(hecl::SystemStringView path) const {
|
||||||
return TagFromPath(hecl::ProjectPath(*(hecl::Database::Project*)m_proj, path), hecl::blender::SharedBlenderToken);
|
return TagFromPath(hecl::ProjectPath(*(hecl::Database::Project*)m_proj, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
~ProjectResourceFactoryBase() { Shutdown(); }
|
~ProjectResourceFactoryBase() { Shutdown(); }
|
||||||
|
|
|
@ -5,7 +5,11 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
macro(runtime_add_list rel_path a_list)
|
macro(runtime_add_list rel_path a_list)
|
||||||
unset(tmp_list)
|
unset(tmp_list)
|
||||||
foreach(path IN LISTS ${a_list})
|
foreach(path IN LISTS ${a_list})
|
||||||
list(APPEND tmp_list "${rel_path}/${path}")
|
if(IS_ABSOLUTE ${path})
|
||||||
|
list(APPEND tmp_list "${path}")
|
||||||
|
else()
|
||||||
|
list(APPEND tmp_list "${rel_path}/${path}")
|
||||||
|
endif()
|
||||||
endforeach(path)
|
endforeach(path)
|
||||||
set(${a_list} "${tmp_list}" PARENT_SCOPE)
|
set(${a_list} "${tmp_list}" PARENT_SCOPE)
|
||||||
endmacro(runtime_add_list)
|
endmacro(runtime_add_list)
|
||||||
|
@ -144,3 +148,5 @@ if(MSVC)
|
||||||
else()
|
else()
|
||||||
add_runtime_common_library(RuntimeCommon ${RUNTIME_SOURCES_A} ${RUNTIME_SOURCES_B})
|
add_runtime_common_library(RuntimeCommon ${RUNTIME_SOURCES_A} ${RUNTIME_SOURCES_B})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(RuntimeCommon CModelShaders)
|
|
@ -339,7 +339,7 @@ float CPlayerState::CalculateHealth() {
|
||||||
return (GetEnergyTankCapacity() * x24_powerups[u32(EItemType::EnergyTanks)].x0_amount) + GetBaseHealthCapacity();
|
return (GetEnergyTankCapacity() * x24_powerups[u32(EItemType::EnergyTanks)].x0_amount) + GetBaseHealthCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerState::InitializePowerUp(CPlayerState::EItemType type, u32 capacity) {
|
void CPlayerState::AddPowerUp(CPlayerState::EItemType type, u32 capacity) {
|
||||||
if (type >= EItemType::Max)
|
if (type >= EItemType::Max)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ void CPlayerState::InitializePowerUp(CPlayerState::EItemType type, u32 capacity)
|
||||||
|
|
||||||
void CPlayerState::ReInitalizePowerUp(CPlayerState::EItemType type, u32 capacity) {
|
void CPlayerState::ReInitalizePowerUp(CPlayerState::EItemType type, u32 capacity) {
|
||||||
x24_powerups[u32(type)].x4_capacity = 0;
|
x24_powerups[u32(type)].x4_capacity = 0;
|
||||||
InitializePowerUp(type, capacity);
|
AddPowerUp(type, capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerState::InitializeScanTimes() {
|
void CPlayerState::InitializeScanTimes() {
|
||||||
|
|
|
@ -160,7 +160,7 @@ public:
|
||||||
static float GetBaseHealthCapacity() { return 99.f; }
|
static float GetBaseHealthCapacity() { return 99.f; }
|
||||||
float CalculateHealth();
|
float CalculateHealth();
|
||||||
void ReInitalizePowerUp(EItemType type, u32 capacity);
|
void ReInitalizePowerUp(EItemType type, u32 capacity);
|
||||||
void InitializePowerUp(EItemType type, u32 capacity);
|
void AddPowerUp(EItemType type, u32 capacity);
|
||||||
u32 GetLogScans() const { return x180_scanCompletionRate.first; }
|
u32 GetLogScans() const { return x180_scanCompletionRate.first; }
|
||||||
u32 GetTotalLogScans() const { return x180_scanCompletionRate.second; }
|
u32 GetTotalLogScans() const { return x180_scanCompletionRate.second; }
|
||||||
void SetScanCompletionRate(const std::pair<u32, u32>& p) { x180_scanCompletionRate = p; }
|
void SetScanCompletionRate(const std::pair<u32, u32>& p) { x180_scanCompletionRate = p; }
|
||||||
|
|
|
@ -2068,7 +2068,7 @@ void CStateManager::InitializeState(CAssetId mlvlId, TAreaId aid, CAssetId mreaI
|
||||||
u32 spawnPu = sp->GetPowerup(iType);
|
u32 spawnPu = sp->GetPowerup(iType);
|
||||||
u32 statePu = x8b8_playerState->GetItemAmount(iType);
|
u32 statePu = x8b8_playerState->GetItemAmount(iType);
|
||||||
if (statePu < spawnPu)
|
if (statePu < spawnPu)
|
||||||
x8b8_playerState->InitializePowerUp(iType, spawnPu - statePu);
|
x8b8_playerState->AddPowerUp(iType, spawnPu - statePu);
|
||||||
|
|
||||||
spawnPu = sp->GetPowerup(iType);
|
spawnPu = sp->GetPowerup(iType);
|
||||||
statePu = x8b8_playerState->GetItemAmount(iType);
|
statePu = x8b8_playerState->GetItemAmount(iType);
|
||||||
|
|
|
@ -168,7 +168,7 @@ void Buckets::Init() {
|
||||||
|
|
||||||
CBooRenderer::CAreaListItem::CAreaListItem(const std::vector<CMetroidModelInstance>* geom,
|
CBooRenderer::CAreaListItem::CAreaListItem(const std::vector<CMetroidModelInstance>* geom,
|
||||||
const CAreaRenderOctTree* octTree,
|
const CAreaRenderOctTree* octTree,
|
||||||
std::vector<TCachedToken<CTexture>>&& textures,
|
std::unordered_map<CAssetId, TCachedToken<CTexture>>&& textures,
|
||||||
std::vector<CBooModel*>&& models, int areaIdx, const SShader* shaderSet)
|
std::vector<CBooModel*>&& models, int areaIdx, const SShader* shaderSet)
|
||||||
: x0_geometry(geom)
|
: x0_geometry(geom)
|
||||||
, x4_octTree(octTree)
|
, x4_octTree(octTree)
|
||||||
|
@ -593,6 +593,22 @@ void CBooRenderer::GenerateScanLinesVBO(boo::IGraphicsDataFactory::Context& ctx)
|
||||||
m_scanLinesOddVBO = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(zeus::CVector3f), verts.size());
|
m_scanLinesOddVBO = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(zeus::CVector3f), verts.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boo::ObjToken<boo::ITexture> CBooRenderer::GetColorTexture(const zeus::CColor& color) {
|
||||||
|
auto search = m_colorTextures.find(color);
|
||||||
|
if (search != m_colorTextures.end())
|
||||||
|
return search->second;
|
||||||
|
u8 pixel[4];
|
||||||
|
color.toRGBA8(pixel[0], pixel[1], pixel[2], pixel[3]);
|
||||||
|
boo::ObjToken<boo::ITexture> tex;
|
||||||
|
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||||
|
tex = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8,
|
||||||
|
boo::TextureClampMode::Repeat, pixel, 4).get();
|
||||||
|
return true;
|
||||||
|
} BooTrace);
|
||||||
|
m_colorTextures.insert(std::make_pair(color, tex));
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
void CBooRenderer::LoadThermoPalette() {
|
void CBooRenderer::LoadThermoPalette() {
|
||||||
m_thermoPaletteTex = xc_store.GetObj("TXTR_ThermoPalette");
|
m_thermoPaletteTex = xc_store.GetObj("TXTR_ThermoPalette");
|
||||||
CTexture* thermoTexObj = m_thermoPaletteTex.GetObj();
|
CTexture* thermoTexObj = m_thermoPaletteTex.GetObj();
|
||||||
|
@ -652,8 +668,7 @@ void CBooRenderer::AddWorldSurfaces(CBooModel& model) {
|
||||||
zeus::CAABox aabb = surf->GetBounds();
|
zeus::CAABox aabb = surf->GetBounds();
|
||||||
zeus::CVector3f pt = aabb.closestPointAlongVector(xb0_viewPlane.normal());
|
zeus::CVector3f pt = aabb.closestPointAlongVector(xb0_viewPlane.normal());
|
||||||
Buckets::Insert(pt, aabb, EDrawableType::WorldSurface, surf, xb0_viewPlane,
|
Buckets::Insert(pt, aabb, EDrawableType::WorldSurface, surf, xb0_viewPlane,
|
||||||
mat.heclIr.m_blendSrc == boo::BlendFactor::SrcAlpha &&
|
mat.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Alpha);
|
||||||
mat.heclIr.m_blendDst == boo::BlendFactor::InvSrcAlpha);
|
|
||||||
surf = surf->m_next;
|
surf = surf->m_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -668,7 +683,7 @@ void CBooRenderer::AddStaticGeometry(const std::vector<CMetroidModelInstance>* g
|
||||||
const CAreaRenderOctTree* octTree, int areaIdx, const SShader* shaderSet) {
|
const CAreaRenderOctTree* octTree, int areaIdx, const SShader* shaderSet) {
|
||||||
auto search = FindStaticGeometry(geometry);
|
auto search = FindStaticGeometry(geometry);
|
||||||
if (search == x1c_areaListItems.end()) {
|
if (search == x1c_areaListItems.end()) {
|
||||||
std::vector<TCachedToken<CTexture>> textures;
|
std::unordered_map<CAssetId, TCachedToken<CTexture>> textures;
|
||||||
std::vector<CBooModel*> models;
|
std::vector<CBooModel*> models;
|
||||||
if (geometry->size()) {
|
if (geometry->size()) {
|
||||||
(*geometry)[0].m_instance->MakeTexturesFromMats(textures, xc_store);
|
(*geometry)[0].m_instance->MakeTexturesFromMats(textures, xc_store);
|
||||||
|
|
|
@ -58,7 +58,7 @@ class CBooRenderer final : public IRenderer {
|
||||||
const std::vector<CMetroidModelInstance>* x0_geometry;
|
const std::vector<CMetroidModelInstance>* x0_geometry;
|
||||||
const CAreaRenderOctTree* x4_octTree;
|
const CAreaRenderOctTree* x4_octTree;
|
||||||
/* originally auto_ptrs of vectors */
|
/* originally auto_ptrs of vectors */
|
||||||
std::vector<TCachedToken<CTexture>> x8_textures;
|
std::unordered_map<CAssetId, TCachedToken<CTexture>> x8_textures;
|
||||||
std::vector<CBooModel*> x10_models;
|
std::vector<CBooModel*> x10_models;
|
||||||
int x18_areaIdx;
|
int x18_areaIdx;
|
||||||
/* Per-area octree-word major, light bits minor */
|
/* Per-area octree-word major, light bits minor */
|
||||||
|
@ -66,8 +66,8 @@ class CBooRenderer final : public IRenderer {
|
||||||
const SShader* m_shaderSet;
|
const SShader* m_shaderSet;
|
||||||
|
|
||||||
CAreaListItem(const std::vector<CMetroidModelInstance>* geom, const CAreaRenderOctTree* octTree,
|
CAreaListItem(const std::vector<CMetroidModelInstance>* geom, const CAreaRenderOctTree* octTree,
|
||||||
std::vector<TCachedToken<CTexture>>&& textures, std::vector<CBooModel*>&& models, int areaIdx,
|
std::unordered_map<CAssetId, TCachedToken<CTexture>>&& textures, std::vector<CBooModel*>&& models,
|
||||||
const SShader* shaderSet);
|
int areaIdx, const SShader* shaderSet);
|
||||||
~CAreaListItem();
|
~CAreaListItem();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,6 +109,7 @@ class CBooRenderer final : public IRenderer {
|
||||||
boo::ObjToken<boo::ITexture> m_clearTexture;
|
boo::ObjToken<boo::ITexture> m_clearTexture;
|
||||||
boo::ObjToken<boo::ITexture> m_blackTexture;
|
boo::ObjToken<boo::ITexture> m_blackTexture;
|
||||||
boo::ObjToken<boo::ITexture> m_whiteTexture;
|
boo::ObjToken<boo::ITexture> m_whiteTexture;
|
||||||
|
std::unordered_map<zeus::CColor, boo::ObjToken<boo::ITexture>> m_colorTextures;
|
||||||
|
|
||||||
boo::ObjToken<boo::ITextureR> x14c_reflectionTex;
|
boo::ObjToken<boo::ITextureR> x14c_reflectionTex;
|
||||||
// boo::ITextureS* x150_mirrorRamp = nullptr;
|
// boo::ITextureS* x150_mirrorRamp = nullptr;
|
||||||
|
@ -278,6 +279,8 @@ public:
|
||||||
const boo::ObjToken<boo::ITexture>& GetBlackTexture() { return m_blackTexture; }
|
const boo::ObjToken<boo::ITexture>& GetBlackTexture() { return m_blackTexture; }
|
||||||
const boo::ObjToken<boo::ITexture>& GetWhiteTexture() { return m_whiteTexture; }
|
const boo::ObjToken<boo::ITexture>& GetWhiteTexture() { return m_whiteTexture; }
|
||||||
|
|
||||||
|
boo::ObjToken<boo::ITexture> GetColorTexture(const zeus::CColor& color);
|
||||||
|
|
||||||
static void BindMainDrawTarget() { CGraphics::g_BooMainCommandQueue->setRenderTarget(CGraphics::g_SpareTexture); }
|
static void BindMainDrawTarget() { CGraphics::g_BooMainCommandQueue->setRenderTarget(CGraphics::g_SpareTexture); }
|
||||||
void BindReflectionDrawTarget() { CGraphics::g_BooMainCommandQueue->setRenderTarget(x14c_reflectionTex); }
|
void BindReflectionDrawTarget() { CGraphics::g_BooMainCommandQueue->setRenderTarget(x14c_reflectionTex); }
|
||||||
void BindBallShadowIdTarget() {
|
void BindBallShadowIdTarget() {
|
||||||
|
|
|
@ -24,7 +24,6 @@ set(GRAPHICS_SOURCES
|
||||||
Shaders/CColoredQuadFilter.hpp Shaders/CColoredQuadFilter.cpp
|
Shaders/CColoredQuadFilter.hpp Shaders/CColoredQuadFilter.cpp
|
||||||
Shaders/CColoredStripShader.hpp Shaders/CColoredStripShader.cpp
|
Shaders/CColoredStripShader.hpp Shaders/CColoredStripShader.cpp
|
||||||
Shaders/CModelShaders.hpp Shaders/CModelShaders.cpp
|
Shaders/CModelShaders.hpp Shaders/CModelShaders.cpp
|
||||||
Shaders/CModelShadersGLSL.cpp Shaders/CModelShadersHLSL.cpp Shaders/CModelShadersMetal.cpp
|
|
||||||
Shaders/CThermalColdFilter.hpp Shaders/CThermalColdFilter.cpp
|
Shaders/CThermalColdFilter.hpp Shaders/CThermalColdFilter.cpp
|
||||||
Shaders/CThermalHotFilter.hpp Shaders/CThermalHotFilter.cpp
|
Shaders/CThermalHotFilter.hpp Shaders/CThermalHotFilter.cpp
|
||||||
Shaders/CSpaceWarpFilter.hpp Shaders/CSpaceWarpFilter.cpp
|
Shaders/CSpaceWarpFilter.hpp Shaders/CSpaceWarpFilter.cpp
|
||||||
|
|
|
@ -75,7 +75,6 @@ struct CBooSurface {
|
||||||
};
|
};
|
||||||
|
|
||||||
using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet;
|
using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet;
|
||||||
using UVAnimation = DataSpec::DNAMP1::MaterialSet::Material::UVAnimation;
|
|
||||||
|
|
||||||
struct GeometryUniformLayout {
|
struct GeometryUniformLayout {
|
||||||
boo::ObjToken<boo::IGraphicsBufferD> m_sharedBuffer[2];
|
boo::ObjToken<boo::IGraphicsBufferD> m_sharedBuffer[2];
|
||||||
|
@ -96,7 +95,7 @@ struct GeometryUniformLayout {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SShader {
|
struct SShader {
|
||||||
std::vector<TCachedToken<CTexture>> x0_textures;
|
std::unordered_map<CAssetId, TCachedToken<CTexture>> x0_textures;
|
||||||
std::unordered_map<int, CModelShaders::ShaderPipelines> m_shaders;
|
std::unordered_map<int, CModelShaders::ShaderPipelines> m_shaders;
|
||||||
MaterialSet m_matSet;
|
MaterialSet m_matSet;
|
||||||
rstl::optional<GeometryUniformLayout> m_geomLayout;
|
rstl::optional<GeometryUniformLayout> m_geomLayout;
|
||||||
|
@ -134,7 +133,7 @@ private:
|
||||||
const GeometryUniformLayout* m_geomLayout;
|
const GeometryUniformLayout* m_geomLayout;
|
||||||
int m_matSetIdx = -1;
|
int m_matSetIdx = -1;
|
||||||
const std::unordered_map<int, CModelShaders::ShaderPipelines>* m_pipelines;
|
const std::unordered_map<int, CModelShaders::ShaderPipelines>* m_pipelines;
|
||||||
std::vector<TCachedToken<CTexture>> x1c_textures;
|
std::unordered_map<CAssetId, TCachedToken<CTexture>> x1c_textures;
|
||||||
zeus::CAABox x20_aabb;
|
zeus::CAABox x20_aabb;
|
||||||
CBooSurface* x38_firstUnsortedSurface = nullptr;
|
CBooSurface* x38_firstUnsortedSurface = nullptr;
|
||||||
CBooSurface* x3c_firstSortedSurface = nullptr;
|
CBooSurface* x3c_firstSortedSurface = nullptr;
|
||||||
|
@ -144,7 +143,7 @@ private:
|
||||||
u32 x44_areaInstanceIdx = -1;
|
u32 x44_areaInstanceIdx = -1;
|
||||||
|
|
||||||
struct UVAnimationBuffer {
|
struct UVAnimationBuffer {
|
||||||
static void ProcessAnimation(u8*& bufOut, const UVAnimation& anim);
|
static void ProcessAnimation(u8*& bufOut, const MaterialSet::Material::PASS& anim);
|
||||||
static void PadOutBuffer(u8*& bufStart, u8*& bufOut);
|
static void PadOutBuffer(u8*& bufStart, u8*& bufOut);
|
||||||
static void Update(u8*& bufOut, const MaterialSet* matSet, const CModelFlags& flags, const CBooModel* parent);
|
static void Update(u8*& bufOut, const MaterialSet* matSet, const CModelFlags& flags, const CBooModel* parent);
|
||||||
};
|
};
|
||||||
|
@ -166,8 +165,6 @@ private:
|
||||||
boo::ObjToken<boo::IGraphicsBufferS> m_staticVbo;
|
boo::ObjToken<boo::IGraphicsBufferS> m_staticVbo;
|
||||||
boo::ObjToken<boo::IGraphicsBufferS> m_staticIbo;
|
boo::ObjToken<boo::IGraphicsBufferS> m_staticIbo;
|
||||||
|
|
||||||
boo::ObjToken<boo::ITexture> m_txtrOverrides[8];
|
|
||||||
|
|
||||||
boo::ObjToken<boo::ITexture> m_lastDrawnShadowMap;
|
boo::ObjToken<boo::ITexture> m_lastDrawnShadowMap;
|
||||||
boo::ObjToken<boo::ITexture> m_lastDrawnOneTexture;
|
boo::ObjToken<boo::ITexture> m_lastDrawnOneTexture;
|
||||||
|
|
||||||
|
@ -192,11 +189,12 @@ public:
|
||||||
~CBooModel();
|
~CBooModel();
|
||||||
CBooModel(TToken<CModel>& token, CModel* parent, std::vector<CBooSurface>* surfaces, SShader& shader,
|
CBooModel(TToken<CModel>& token, CModel* parent, std::vector<CBooSurface>* surfaces, SShader& shader,
|
||||||
const boo::ObjToken<boo::IGraphicsBufferS>& vbo, const boo::ObjToken<boo::IGraphicsBufferS>& ibo,
|
const boo::ObjToken<boo::IGraphicsBufferS>& vbo, const boo::ObjToken<boo::IGraphicsBufferS>& ibo,
|
||||||
const zeus::CAABox& aabb, u8 renderMask, int numInsts, const boo::ObjToken<boo::ITexture> txtrOverrides[8]);
|
const zeus::CAABox& aabb, u8 renderMask, int numInsts);
|
||||||
|
|
||||||
static void MakeTexturesFromMats(const MaterialSet& matSet, std::vector<TCachedToken<CTexture>>& toksOut,
|
static void MakeTexturesFromMats(const MaterialSet& matSet,
|
||||||
|
std::unordered_map<CAssetId, TCachedToken<CTexture>>& toksOut,
|
||||||
IObjectStore& store);
|
IObjectStore& store);
|
||||||
void MakeTexturesFromMats(std::vector<TCachedToken<CTexture>>& toksOut, IObjectStore& store);
|
void MakeTexturesFromMats(std::unordered_map<CAssetId, TCachedToken<CTexture>>& toksOut, IObjectStore& store);
|
||||||
|
|
||||||
bool IsOpaque() const { return x3c_firstSortedSurface == nullptr; }
|
bool IsOpaque() const { return x3c_firstSortedSurface == nullptr; }
|
||||||
void ActivateLights(const std::vector<CLight>& lights);
|
void ActivateLights(const std::vector<CLight>& lights);
|
||||||
|
@ -284,9 +282,7 @@ public:
|
||||||
const zeus::CAABox& GetAABB() const { return m_aabb; }
|
const zeus::CAABox& GetAABB() const { return m_aabb; }
|
||||||
CBooModel& GetInstance() { return *x28_modelInst; }
|
CBooModel& GetInstance() { return *x28_modelInst; }
|
||||||
const CBooModel& GetInstance() const { return *x28_modelInst; }
|
const CBooModel& GetInstance() const { return *x28_modelInst; }
|
||||||
std::unique_ptr<CBooModel> MakeNewInstance(int shaderIdx, int subInsts,
|
std::unique_ptr<CBooModel> MakeNewInstance(int shaderIdx, int subInsts, bool lockParent = true);
|
||||||
const boo::ObjToken<boo::ITexture> txtrOverrides[8] = nullptr,
|
|
||||||
bool lockParent = true);
|
|
||||||
void UpdateLastFrame() const { const_cast<CModel&>(*this).x38_lastFrame = CGraphics::GetFrameCounter(); }
|
void UpdateLastFrame() const { const_cast<CModel&>(*this).x38_lastFrame = CGraphics::GetFrameCounter(); }
|
||||||
|
|
||||||
size_t GetPoolVertexOffset(size_t idx) const;
|
size_t GetPoolVertexOffset(size_t idx) const;
|
||||||
|
|
|
@ -141,8 +141,7 @@ CBooModel::~CBooModel() {
|
||||||
|
|
||||||
CBooModel::CBooModel(TToken<CModel>& token, CModel* parent, std::vector<CBooSurface>* surfaces, SShader& shader,
|
CBooModel::CBooModel(TToken<CModel>& token, CModel* parent, std::vector<CBooSurface>* surfaces, SShader& shader,
|
||||||
const boo::ObjToken<boo::IGraphicsBufferS>& vbo, const boo::ObjToken<boo::IGraphicsBufferS>& ibo,
|
const boo::ObjToken<boo::IGraphicsBufferS>& vbo, const boo::ObjToken<boo::IGraphicsBufferS>& ibo,
|
||||||
const zeus::CAABox& aabb, u8 renderMask, int numInsts,
|
const zeus::CAABox& aabb, u8 renderMask, int numInsts)
|
||||||
const boo::ObjToken<boo::ITexture> txtrOverrides[8])
|
|
||||||
: m_modelTok(token)
|
: m_modelTok(token)
|
||||||
, m_model(parent)
|
, m_model(parent)
|
||||||
, x0_surfaces(surfaces)
|
, x0_surfaces(surfaces)
|
||||||
|
@ -157,10 +156,6 @@ CBooModel::CBooModel(TToken<CModel>& token, CModel* parent, std::vector<CBooSurf
|
||||||
, x41_mask(renderMask)
|
, x41_mask(renderMask)
|
||||||
, m_staticVbo(vbo)
|
, m_staticVbo(vbo)
|
||||||
, m_staticIbo(ibo) {
|
, m_staticIbo(ibo) {
|
||||||
if (txtrOverrides)
|
|
||||||
for (int i = 0; i < 8; ++i)
|
|
||||||
m_txtrOverrides[i] = txtrOverrides[i];
|
|
||||||
|
|
||||||
if (!g_FirstModel)
|
if (!g_FirstModel)
|
||||||
g_FirstModel = this;
|
g_FirstModel = this;
|
||||||
else {
|
else {
|
||||||
|
@ -291,10 +286,6 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
|
||||||
/* Binding for each surface */
|
/* Binding for each surface */
|
||||||
newInst.m_shaderDataBindings.reserve(x0_surfaces->size());
|
newInst.m_shaderDataBindings.reserve(x0_surfaces->size());
|
||||||
|
|
||||||
boo::ObjToken<boo::ITexture> mbShadowTexs[8] = {
|
|
||||||
g_Renderer->m_ballShadowId.get(), g_Renderer->x220_sphereRamp.get(), g_Renderer->m_ballFade.get(),
|
|
||||||
g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(),
|
|
||||||
g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get()};
|
|
||||||
size_t thisOffs[4];
|
size_t thisOffs[4];
|
||||||
size_t thisSizes[4];
|
size_t thisSizes[4];
|
||||||
|
|
||||||
|
@ -306,20 +297,23 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
|
||||||
for (const CBooSurface& surf : *x0_surfaces) {
|
for (const CBooSurface& surf : *x0_surfaces) {
|
||||||
const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx);
|
const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx);
|
||||||
|
|
||||||
boo::ObjToken<boo::ITexture> texs[8] = {g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(),
|
boo::ObjToken<boo::ITexture> texs[12] = {g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(),
|
||||||
g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(),
|
g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(),
|
||||||
g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(),
|
g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(),
|
||||||
g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get()};
|
g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(),
|
||||||
u32 texCount = 0;
|
g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(),
|
||||||
for (atUint32 idx : mat.textureIdxs) {
|
g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get()};
|
||||||
if (boo::ObjToken<boo::ITexture> overtex = m_txtrOverrides[texCount]) {
|
if (!g_DummyTextures) {
|
||||||
texs[texCount++] = overtex;
|
for (const auto& ch : mat.chunks) {
|
||||||
} else if (g_DummyTextures) {
|
if (auto pass = ch.get_if<MaterialSet::Material::PASS>()) {
|
||||||
texs[texCount++] = g_Renderer->x220_sphereRamp.get();
|
auto search = x1c_textures.find(pass->texId.toUint32());
|
||||||
} else {
|
boo::ObjToken<boo::ITexture> btex;
|
||||||
TCachedToken<CTexture>& tex = x1c_textures[idx];
|
if (search != x1c_textures.cend() && (btex = search->second.GetObj()->GetBooTexture()))
|
||||||
if (boo::ObjToken<boo::ITexture> btex = tex.GetObj()->GetBooTexture())
|
texs[MaterialSet::Material::TexMapIdx(pass->type)] = btex;
|
||||||
texs[texCount++] = btex;
|
} else if (auto pass = ch.get_if<MaterialSet::Material::CLR>()) {
|
||||||
|
boo::ObjToken<boo::ITexture> btex = g_Renderer->GetColorTexture(zeus::CColor(pass->color));
|
||||||
|
texs[MaterialSet::Material::TexMapIdx(pass->type)] = btex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,9 +334,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
|
||||||
bool useReflection = mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye();
|
bool useReflection = mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye();
|
||||||
if (useReflection) {
|
if (useReflection) {
|
||||||
if (g_Renderer->x14c_reflectionTex)
|
if (g_Renderer->x14c_reflectionTex)
|
||||||
texs[texCount] = g_Renderer->x14c_reflectionTex.get();
|
texs[11] = g_Renderer->x14c_reflectionTex.get();
|
||||||
else
|
|
||||||
texs[texCount] = g_Renderer->x220_sphereRamp.get();
|
|
||||||
thisOffs[3] = curReflect;
|
thisOffs[3] = curReflect;
|
||||||
curReflect += 256;
|
curReflect += 256;
|
||||||
} else {
|
} else {
|
||||||
|
@ -358,31 +350,25 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (const auto& pipeline : *pipelines) {
|
for (const auto& pipeline : *pipelines) {
|
||||||
boo::ObjToken<boo::ITexture>* ltexs;
|
|
||||||
if (idx == EExtendedShader::Thermal) {
|
if (idx == EExtendedShader::Thermal) {
|
||||||
texs[7] = g_Renderer->x220_sphereRamp.get();
|
texs[8] = g_Renderer->x220_sphereRamp.get();
|
||||||
ltexs = texs;
|
|
||||||
} else if (idx == EExtendedShader::MorphBallShadow) {
|
} else if (idx == EExtendedShader::MorphBallShadow) {
|
||||||
ltexs = mbShadowTexs;
|
texs[8] = g_Renderer->m_ballShadowId.get();
|
||||||
|
texs[9] = g_Renderer->x220_sphereRamp.get();
|
||||||
|
texs[10] = g_Renderer->m_ballFade.get();
|
||||||
} else if (idx == EExtendedShader::WorldShadow) {
|
} else if (idx == EExtendedShader::WorldShadow) {
|
||||||
if (g_shadowMap)
|
if (g_shadowMap)
|
||||||
texs[7] = g_shadowMap;
|
texs[8] = g_shadowMap;
|
||||||
else
|
else
|
||||||
texs[7] = g_Renderer->x220_sphereRamp.get();
|
texs[8] = g_Renderer->x220_sphereRamp.get();
|
||||||
ltexs = texs;
|
|
||||||
} else if (idx == EExtendedShader::Disintegrate) {
|
} else if (idx == EExtendedShader::Disintegrate) {
|
||||||
if (g_disintegrateTexture)
|
if (g_disintegrateTexture)
|
||||||
texs[7] = g_disintegrateTexture;
|
texs[8] = g_disintegrateTexture;
|
||||||
else
|
else
|
||||||
texs[7] = g_Renderer->x220_sphereRamp.get();
|
texs[8] = g_Renderer->x220_sphereRamp.get();
|
||||||
ltexs = texs;
|
|
||||||
} else if (useReflection) {
|
|
||||||
ltexs = texs;
|
|
||||||
} else {
|
|
||||||
ltexs = texs;
|
|
||||||
}
|
}
|
||||||
extendeds.push_back(ctx.newShaderDataBinding(pipeline, newInst.GetBooVBO(*this, ctx), nullptr,
|
extendeds.push_back(ctx.newShaderDataBinding(pipeline, newInst.GetBooVBO(*this, ctx), nullptr,
|
||||||
m_staticIbo.get(), 4, bufs, stages, thisOffs, thisSizes, 8, ltexs,
|
m_staticIbo.get(), 4, bufs, stages, thisOffs, thisSizes, 12, texs,
|
||||||
nullptr, nullptr));
|
nullptr, nullptr));
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
|
@ -393,14 +379,20 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
|
||||||
return &newInst;
|
return &newInst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::MakeTexturesFromMats(const MaterialSet& matSet, std::vector<TCachedToken<CTexture>>& toksOut,
|
void CBooModel::MakeTexturesFromMats(const MaterialSet& matSet,
|
||||||
|
std::unordered_map<CAssetId, TCachedToken<CTexture>>& toksOut,
|
||||||
IObjectStore& store) {
|
IObjectStore& store) {
|
||||||
toksOut.reserve(matSet.head.textureIDs.size());
|
for (const auto& mat : matSet.materials) {
|
||||||
for (const DataSpec::UniqueID32& id : matSet.head.textureIDs)
|
for (const auto& chunk : mat.chunks) {
|
||||||
toksOut.emplace_back(store.GetObj({SBIG('TXTR'), id.toUint32()}));
|
if (auto pass = chunk.get_if<MaterialSet::Material::PASS>()) {
|
||||||
|
toksOut.emplace(std::make_pair(pass->texId.toUint32(), store.GetObj({SBIG('TXTR'), pass->texId.toUint32()})));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::MakeTexturesFromMats(std::vector<TCachedToken<CTexture>>& toksOut, IObjectStore& store) {
|
void CBooModel::MakeTexturesFromMats(std::unordered_map<CAssetId, TCachedToken<CTexture>>& toksOut,
|
||||||
|
IObjectStore& store) {
|
||||||
MakeTexturesFromMats(*x4_matSet, toksOut, store);
|
MakeTexturesFromMats(*x4_matSet, toksOut, store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,9 +437,9 @@ void CBooModel::RemapMaterialData(SShader& shader,
|
||||||
bool CBooModel::TryLockTextures() const {
|
bool CBooModel::TryLockTextures() const {
|
||||||
if (!x40_24_texturesLoaded) {
|
if (!x40_24_texturesLoaded) {
|
||||||
bool allLoad = true;
|
bool allLoad = true;
|
||||||
for (TCachedToken<CTexture>& tex : const_cast<std::vector<TCachedToken<CTexture>>&>(x1c_textures)) {
|
for (auto& tex : const_cast<std::unordered_map<CAssetId, TCachedToken<CTexture>>&>(x1c_textures)) {
|
||||||
tex.Lock();
|
tex.second.Lock();
|
||||||
if (!tex.IsLoaded())
|
if (!tex.second.IsLoaded())
|
||||||
allLoad = false;
|
allLoad = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,15 +451,15 @@ bool CBooModel::TryLockTextures() const {
|
||||||
|
|
||||||
void CBooModel::UnlockTextures() const {
|
void CBooModel::UnlockTextures() const {
|
||||||
const_cast<CBooModel*>(this)->m_instances.clear();
|
const_cast<CBooModel*>(this)->m_instances.clear();
|
||||||
for (TCachedToken<CTexture>& tex : const_cast<std::vector<TCachedToken<CTexture>>&>(x1c_textures))
|
for (auto& tex : const_cast<std::unordered_map<CAssetId, TCachedToken<CTexture>>&>(x1c_textures))
|
||||||
tex.Unlock();
|
tex.second.Unlock();
|
||||||
const_cast<CBooModel*>(this)->x40_24_texturesLoaded = false;
|
const_cast<CBooModel*>(this)->x40_24_texturesLoaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::SyncLoadTextures() const {
|
void CBooModel::SyncLoadTextures() const {
|
||||||
if (!x40_24_texturesLoaded) {
|
if (!x40_24_texturesLoaded) {
|
||||||
for (TCachedToken<CTexture>& tex : const_cast<std::vector<TCachedToken<CTexture>>&>(x1c_textures))
|
for (auto& tex : const_cast<std::unordered_map<CAssetId, TCachedToken<CTexture>>&>(x1c_textures))
|
||||||
tex.GetObj();
|
tex.second.GetObj();
|
||||||
const_cast<CBooModel*>(this)->x40_24_texturesLoaded = true;
|
const_cast<CBooModel*>(this)->x40_24_texturesLoaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -534,7 +526,7 @@ static EExtendedShader ResolveExtendedShader(const MaterialSet::Material& data,
|
||||||
return EExtendedShader::LightingAlphaWrite;
|
return EExtendedShader::LightingAlphaWrite;
|
||||||
else if (g_Renderer->IsThermalVisorActive())
|
else if (g_Renderer->IsThermalVisorActive())
|
||||||
return EExtendedShader::ThermalCold;
|
return EExtendedShader::ThermalCold;
|
||||||
if (data.heclIr.m_blendSrc == boo::BlendFactor::One && data.heclIr.m_blendDst == boo::BlendFactor::Zero) {
|
if (data.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Opaque) {
|
||||||
/* Override shader if originally opaque (typical for FRME models) */
|
/* Override shader if originally opaque (typical for FRME models) */
|
||||||
if (flags.x0_blendMode > 6) {
|
if (flags.x0_blendMode > 6) {
|
||||||
if (flags.m_depthGreater)
|
if (flags.m_depthGreater)
|
||||||
|
@ -555,19 +547,19 @@ static EExtendedShader ResolveExtendedShader(const MaterialSet::Material& data,
|
||||||
}
|
}
|
||||||
} else if (flags.m_noCull && noZWrite) {
|
} else if (flags.m_noCull && noZWrite) {
|
||||||
/* Substitute no-cull,no-zwrite pipeline if available */
|
/* Substitute no-cull,no-zwrite pipeline if available */
|
||||||
if (data.heclIr.m_blendDst == boo::BlendFactor::One)
|
if (data.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Additive)
|
||||||
extended = EExtendedShader::ForcedAdditiveNoCullNoZWrite;
|
extended = EExtendedShader::ForcedAdditiveNoCullNoZWrite;
|
||||||
else
|
else
|
||||||
extended = EExtendedShader::ForcedAlphaNoCullNoZWrite;
|
extended = EExtendedShader::ForcedAlphaNoCullNoZWrite;
|
||||||
} else if (flags.m_noCull) {
|
} else if (flags.m_noCull) {
|
||||||
/* Substitute no-cull pipeline if available */
|
/* Substitute no-cull pipeline if available */
|
||||||
if (data.heclIr.m_blendDst == boo::BlendFactor::One)
|
if (data.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Additive)
|
||||||
extended = EExtendedShader::ForcedAdditiveNoCull;
|
extended = EExtendedShader::ForcedAdditiveNoCull;
|
||||||
else
|
else
|
||||||
extended = EExtendedShader::ForcedAlphaNoCull;
|
extended = EExtendedShader::ForcedAlphaNoCull;
|
||||||
} else if (noZWrite) {
|
} else if (noZWrite) {
|
||||||
/* Substitute no-zwrite pipeline if available */
|
/* Substitute no-zwrite pipeline if available */
|
||||||
if (data.heclIr.m_blendDst == boo::BlendFactor::One)
|
if (data.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Additive)
|
||||||
extended = EExtendedShader::ForcedAdditiveNoZWrite;
|
extended = EExtendedShader::ForcedAdditiveNoZWrite;
|
||||||
else
|
else
|
||||||
extended = EExtendedShader::ForcedAlphaNoZWrite;
|
extended = EExtendedShader::ForcedAlphaNoZWrite;
|
||||||
|
@ -619,21 +611,22 @@ void CBooModel::WarmupDrawSurface(const CBooSurface& surf) const {
|
||||||
return;
|
return;
|
||||||
const ModelInstance& inst = m_instances[m_uniUpdateCount - 1];
|
const ModelInstance& inst = m_instances[m_uniUpdateCount - 1];
|
||||||
|
|
||||||
// Only warmup normal lighting and thermal visor
|
for (auto& binding : inst.m_shaderDataBindings[surf.selfIdx]) {
|
||||||
for (int i = 1; i <= 2; ++i) {
|
|
||||||
auto& binding = inst.m_shaderDataBindings[surf.selfIdx][i];
|
|
||||||
CGraphics::SetShaderDataBinding(binding);
|
CGraphics::SetShaderDataBinding(binding);
|
||||||
CGraphics::DrawArrayIndexed(surf.m_data.idxStart, std::min(u32(3), surf.m_data.idxCount));
|
CGraphics::DrawArrayIndexed(surf.m_data.idxStart, std::min(u32(3), surf.m_data.idxCount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimation& anim) {
|
void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const MaterialSet::Material::PASS& anim) {
|
||||||
|
using UVAnimType = MaterialSet::Material::BlendMaterial::UVAnimType;
|
||||||
|
if (anim.uvAnimType == UVAnimType::Invalid)
|
||||||
|
return;
|
||||||
zeus::CMatrix4f& texMtxOut = reinterpret_cast<zeus::CMatrix4f&>(*bufOut);
|
zeus::CMatrix4f& texMtxOut = reinterpret_cast<zeus::CMatrix4f&>(*bufOut);
|
||||||
zeus::CMatrix4f& postMtxOut = reinterpret_cast<zeus::CMatrix4f&>(*(bufOut + sizeof(zeus::CMatrix4f)));
|
zeus::CMatrix4f& postMtxOut = reinterpret_cast<zeus::CMatrix4f&>(*(bufOut + sizeof(zeus::CMatrix4f)));
|
||||||
texMtxOut = zeus::CMatrix4f();
|
texMtxOut = zeus::CMatrix4f();
|
||||||
postMtxOut = zeus::CMatrix4f();
|
postMtxOut = zeus::CMatrix4f();
|
||||||
switch (anim.mode) {
|
switch (anim.uvAnimType) {
|
||||||
case UVAnimation::Mode::MvInvNoTranslation: {
|
case UVAnimType::MvInvNoTranslation: {
|
||||||
texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
|
texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
|
||||||
texMtxOut[3].w() = 1.f;
|
texMtxOut[3].w() = 1.f;
|
||||||
postMtxOut[0].x() = 0.5f;
|
postMtxOut[0].x() = 0.5f;
|
||||||
|
@ -642,7 +635,7 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimati
|
||||||
postMtxOut[3].y() = 0.5f;
|
postMtxOut[3].y() = 0.5f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UVAnimation::Mode::MvInv: {
|
case UVAnimType::MvInv: {
|
||||||
texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
|
texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
|
||||||
texMtxOut[3] = CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix.origin;
|
texMtxOut[3] = CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix.origin;
|
||||||
texMtxOut[3].w() = 1.f;
|
texMtxOut[3].w() = 1.f;
|
||||||
|
@ -652,13 +645,13 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimati
|
||||||
postMtxOut[3].y() = 0.5f;
|
postMtxOut[3].y() = 0.5f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UVAnimation::Mode::Scroll: {
|
case UVAnimType::Scroll: {
|
||||||
texMtxOut[3].x() = CGraphics::GetSecondsMod900() * anim.vals[2] + anim.vals[0];
|
texMtxOut[3].x() = CGraphics::GetSecondsMod900() * anim.uvAnimParms[2] + anim.uvAnimParms[0];
|
||||||
texMtxOut[3].y() = CGraphics::GetSecondsMod900() * anim.vals[3] + anim.vals[1];
|
texMtxOut[3].y() = CGraphics::GetSecondsMod900() * anim.uvAnimParms[3] + anim.uvAnimParms[1];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UVAnimation::Mode::Rotation: {
|
case UVAnimType::Rotation: {
|
||||||
float angle = CGraphics::GetSecondsMod900() * anim.vals[1] + anim.vals[0];
|
float angle = CGraphics::GetSecondsMod900() * anim.uvAnimParms[1] + anim.uvAnimParms[0];
|
||||||
float acos = std::cos(angle);
|
float acos = std::cos(angle);
|
||||||
float asin = std::sin(angle);
|
float asin = std::sin(angle);
|
||||||
texMtxOut[0].x() = acos;
|
texMtxOut[0].x() = acos;
|
||||||
|
@ -669,17 +662,17 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimati
|
||||||
texMtxOut[3].y() = (1.0f - (asin + acos)) * 0.5f;
|
texMtxOut[3].y() = (1.0f - (asin + acos)) * 0.5f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UVAnimation::Mode::HStrip: {
|
case UVAnimType::HStrip: {
|
||||||
float value = anim.vals[0] * anim.vals[2] * (anim.vals[3] + CGraphics::GetSecondsMod900());
|
float value = anim.uvAnimParms[0] * anim.uvAnimParms[2] * (anim.uvAnimParms[3] + CGraphics::GetSecondsMod900());
|
||||||
texMtxOut[3].x() = std::trunc(anim.vals[1] * fmod(value, 1.0f)) * anim.vals[2];
|
texMtxOut[3].x() = std::trunc(anim.uvAnimParms[1] * fmod(value, 1.0f)) * anim.uvAnimParms[2];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UVAnimation::Mode::VStrip: {
|
case UVAnimType::VStrip: {
|
||||||
float value = anim.vals[0] * anim.vals[2] * (anim.vals[3] + CGraphics::GetSecondsMod900());
|
float value = anim.uvAnimParms[0] * anim.uvAnimParms[2] * (anim.uvAnimParms[3] + CGraphics::GetSecondsMod900());
|
||||||
texMtxOut[3].y() = std::trunc(anim.vals[1] * fmod(value, 1.0f)) * anim.vals[2];
|
texMtxOut[3].y() = std::trunc(anim.uvAnimParms[1] * fmod(value, 1.0f)) * anim.uvAnimParms[2];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UVAnimation::Mode::Model: {
|
case UVAnimType::Model: {
|
||||||
texMtxOut = CGraphics::g_GXModelMatrix.toMatrix4f();
|
texMtxOut = CGraphics::g_GXModelMatrix.toMatrix4f();
|
||||||
texMtxOut[3] = zeus::CVector4f(0.f, 0.f, 0.f, 1.f);
|
texMtxOut[3] = zeus::CVector4f(0.f, 0.f, 0.f, 1.f);
|
||||||
postMtxOut[0].x() = 0.5f;
|
postMtxOut[0].x() = 0.5f;
|
||||||
|
@ -689,16 +682,16 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimati
|
||||||
postMtxOut[3].y() = CGraphics::g_GXModelMatrix.origin.y() * 0.05f;
|
postMtxOut[3].y() = CGraphics::g_GXModelMatrix.origin.y() * 0.05f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UVAnimation::Mode::CylinderEnvironment: {
|
case UVAnimType::CylinderEnvironment: {
|
||||||
texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
|
texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
|
||||||
|
|
||||||
const zeus::CVector3f& viewOrigin = CGraphics::g_ViewMatrix.origin;
|
const zeus::CVector3f& viewOrigin = CGraphics::g_ViewMatrix.origin;
|
||||||
float xy = (viewOrigin.x() + viewOrigin.y()) * 0.025f * anim.vals[1];
|
float xy = (viewOrigin.x() + viewOrigin.y()) * 0.025f * anim.uvAnimParms[1];
|
||||||
xy = (xy - std::trunc(xy));
|
xy = (xy - std::trunc(xy));
|
||||||
float z = (viewOrigin.z()) * 0.05f * anim.vals[1];
|
float z = (viewOrigin.z()) * 0.05f * anim.uvAnimParms[1];
|
||||||
z = (z - std::trunc(z));
|
z = (z - std::trunc(z));
|
||||||
|
|
||||||
float halfA = anim.vals[0] * 0.5f;
|
float halfA = anim.uvAnimParms[0] * 0.5f;
|
||||||
|
|
||||||
postMtxOut =
|
postMtxOut =
|
||||||
zeus::CTransform(zeus::CMatrix3f(halfA, 0.0, 0.0, 0.0, 0.0, halfA, 0.0, 0.0, 0.0), zeus::CVector3f(xy, z, 1.0))
|
zeus::CTransform(zeus::CMatrix3f(halfA, 0.0, 0.0, 0.0, 0.0, halfA, 0.0, 0.0, 0.0), zeus::CVector3f(xy, z, 1.0))
|
||||||
|
@ -808,8 +801,11 @@ void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet
|
||||||
mtxs[7][1] = (*specialMtxOut)[1];
|
mtxs[7][1] = (*specialMtxOut)[1];
|
||||||
}
|
}
|
||||||
u8* bufOrig = bufOut;
|
u8* bufOrig = bufOut;
|
||||||
for (const UVAnimation& anim : mat.uvAnims)
|
for (const auto& chunk : mat.chunks) {
|
||||||
ProcessAnimation(bufOut, anim);
|
if (auto pass = chunk.get_if<MaterialSet::Material::PASS>()) {
|
||||||
|
ProcessAnimation(bufOut, *pass);
|
||||||
|
}
|
||||||
|
}
|
||||||
bufOut = bufOrig + sizeof(zeus::CMatrix4f) * 2 * 8;
|
bufOut = bufOrig + sizeof(zeus::CMatrix4f) * 2 * 8;
|
||||||
PadOutBuffer(start, bufOut);
|
PadOutBuffer(start, bufOut);
|
||||||
}
|
}
|
||||||
|
@ -898,7 +894,7 @@ void GeometryUniformLayout::Update(const CModelFlags& flags, const CSkinRules* c
|
||||||
boo::ObjToken<boo::IGraphicsBufferD> CBooModel::UpdateUniformData(const CModelFlags& flags, const CSkinRules* cskr,
|
boo::ObjToken<boo::IGraphicsBufferD> CBooModel::UpdateUniformData(const CModelFlags& flags, const CSkinRules* cskr,
|
||||||
const CPoseAsTransforms* pose,
|
const CPoseAsTransforms* pose,
|
||||||
int sharedLayoutBuf) const {
|
int sharedLayoutBuf) const {
|
||||||
if (!TryLockTextures())
|
if (!g_DummyTextures && !TryLockTextures())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
/* Invalidate instances if new shadow being drawn */
|
/* Invalidate instances if new shadow being drawn */
|
||||||
|
@ -1046,13 +1042,11 @@ static const u8* MemoryFromPartData(const u8*& dataCur, const u32*& secSizeCur)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CBooModel> CModel::MakeNewInstance(int shaderIdx, int subInsts,
|
std::unique_ptr<CBooModel> CModel::MakeNewInstance(int shaderIdx, int subInsts, bool lockParent) {
|
||||||
const boo::ObjToken<boo::ITexture> txtrOverrides[8],
|
|
||||||
bool lockParent) {
|
|
||||||
if (shaderIdx >= x18_matSets.size())
|
if (shaderIdx >= x18_matSets.size())
|
||||||
shaderIdx = 0;
|
shaderIdx = 0;
|
||||||
auto ret = std::make_unique<CBooModel>(m_selfToken, this, &x8_surfaces, x18_matSets[shaderIdx], m_staticVbo, m_ibo,
|
auto ret = std::make_unique<CBooModel>(m_selfToken, this, &x8_surfaces, x18_matSets[shaderIdx], m_staticVbo, m_ibo,
|
||||||
m_aabb, (m_flags & 0x2) != 0, subInsts, txtrOverrides);
|
m_aabb, (m_flags & 0x2) != 0, subInsts);
|
||||||
if (lockParent)
|
if (lockParent)
|
||||||
ret->LockParent();
|
ret->LockParent();
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1066,9 +1060,9 @@ CModelShaders::ShaderPipelines SShader::BuildShader(const hecl::HMDLMeta& meta,
|
||||||
reflectionType = hecl::Backend::ReflectionType::Simple;
|
reflectionType = hecl::Backend::ReflectionType::Simple;
|
||||||
else
|
else
|
||||||
reflectionType = hecl::Backend::ReflectionType::None;
|
reflectionType = hecl::Backend::ReflectionType::None;
|
||||||
hecl::Backend::ShaderTag tag(mat.heclIr, meta.colorCount, meta.uvCount, meta.weightCount, meta.weightCount * 4,
|
hecl::Backend::ShaderTag tag(mat.hash, meta.colorCount, meta.uvCount, meta.weightCount, meta.weightCount * 4,
|
||||||
boo::Primitive(meta.topology), reflectionType, true, true, true, mat.flags.alphaTest());
|
boo::Primitive(meta.topology), reflectionType, true, true, true, mat.flags.alphaTest());
|
||||||
return CModelShaders::BuildExtendedShader(tag, mat.heclIr);
|
return CModelShaders::BuildExtendedShader(tag, mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SShader::BuildShaders(const hecl::HMDLMeta& meta,
|
void SShader::BuildShaders(const hecl::HMDLMeta& meta,
|
||||||
|
@ -1156,12 +1150,12 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* stor
|
||||||
const float* aabbPtr = reinterpret_cast<const float*>(data.get() + 0xc);
|
const float* aabbPtr = reinterpret_cast<const float*>(data.get() + 0xc);
|
||||||
m_aabb = zeus::CAABox(hecl::SBig(aabbPtr[0]), hecl::SBig(aabbPtr[1]), hecl::SBig(aabbPtr[2]), hecl::SBig(aabbPtr[3]),
|
m_aabb = zeus::CAABox(hecl::SBig(aabbPtr[0]), hecl::SBig(aabbPtr[1]), hecl::SBig(aabbPtr[2]), hecl::SBig(aabbPtr[3]),
|
||||||
hecl::SBig(aabbPtr[4]), hecl::SBig(aabbPtr[5]));
|
hecl::SBig(aabbPtr[4]), hecl::SBig(aabbPtr[5]));
|
||||||
x28_modelInst = MakeNewInstance(0, 1, nullptr, false);
|
x28_modelInst = MakeNewInstance(0, 1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SShader::UnlockTextures() {
|
void SShader::UnlockTextures() {
|
||||||
for (TCachedToken<CTexture>& tex : x0_textures)
|
for (auto& tex : x0_textures)
|
||||||
tex.Unlock();
|
tex.second.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::VerifyCurrentShader(int shaderIdx) {
|
void CBooModel::VerifyCurrentShader(int shaderIdx) {
|
||||||
|
|
|
@ -54,142 +54,136 @@ void CModelShaders::LightingUniform::ActivateLights(const std::vector<CLight>& l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const hecl::Backend::TextureInfo ThermalTextures[] = {{hecl::Backend::TexGenSrc::Normal, 7, 0, 7, true}};
|
using TexCoordSource = hecl::Backend::TexCoordSource;
|
||||||
|
|
||||||
|
static const hecl::Backend::TextureInfo ThermalTextures[] = {{TexCoordSource::Normal, 7, true}};
|
||||||
|
|
||||||
static const hecl::Backend::TextureInfo BallFadeTextures[] = {
|
static const hecl::Backend::TextureInfo BallFadeTextures[] = {
|
||||||
{hecl::Backend::TexGenSrc::Position, 0, 0, 0, false}, // ID tex
|
{TexCoordSource::Position, 0, false}, // ID tex
|
||||||
{hecl::Backend::TexGenSrc::Position, 1, 0, 0, false}, // Sphere ramp
|
{TexCoordSource::Position, 0, false}, // Sphere ramp
|
||||||
{hecl::Backend::TexGenSrc::Position, 2, 0, 1, false} // TXTR_BallFade
|
{TexCoordSource::Position, 1, false} // TXTR_BallFade
|
||||||
};
|
};
|
||||||
|
|
||||||
static const hecl::Backend::TextureInfo WorldShadowTextures[] = {
|
static const hecl::Backend::TextureInfo WorldShadowTextures[] = {
|
||||||
{hecl::Backend::TexGenSrc::Position, 7, 0, 7, false} // Shadow tex
|
{TexCoordSource::Position, 7, false} // Shadow tex
|
||||||
};
|
};
|
||||||
|
|
||||||
static const hecl::Backend::TextureInfo DisintegrateTextures[] = {
|
static const hecl::Backend::TextureInfo DisintegrateTextures[] = {
|
||||||
{hecl::Backend::TexGenSrc::Position, 7, 0, 0, false}, // Ashy tex
|
{TexCoordSource::Position, 0, false}, // Ashy tex
|
||||||
{hecl::Backend::TexGenSrc::Position, 7, 0, 1, false} // Ashy tex
|
{TexCoordSource::Position, 1, false} // Ashy tex
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* BlockNames[] = {"LightingUniform"};
|
|
||||||
static const char* ThermalBlockNames[] = {"ThermalUniform"};
|
|
||||||
static const char* SolidBlockNames[] = {"SolidUniform"};
|
|
||||||
static const char* MBShadowBlockNames[] = {"MBShadowUniform"};
|
|
||||||
static const char* DisintegrateBlockNames[] = {"DisintegrateUniform"};
|
|
||||||
|
|
||||||
static hecl::Backend::ExtensionSlot g_ExtensionSlots[] = {
|
static hecl::Backend::ExtensionSlot g_ExtensionSlots[] = {
|
||||||
/* Default solid shading */
|
/* Default solid shading */
|
||||||
{},
|
{},
|
||||||
/* Normal lit shading */
|
/* Normal lit shading */
|
||||||
{1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
|
{0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
|
||||||
/* Thermal Visor shading */
|
/* Thermal Visor shading */
|
||||||
{1, ThermalBlockNames, 1, ThermalTextures, hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::One,
|
{1, ThermalTextures, hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::One,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, false, true},
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, false, true},
|
||||||
/* Forced alpha shading */
|
/* Forced alpha shading */
|
||||||
{1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
|
||||||
/* Forced additive shading */
|
/* Forced additive shading */
|
||||||
{1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
|
||||||
/* Solid color */
|
/* Solid color */
|
||||||
{1, SolidBlockNames, 0, nullptr, hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::Zero,
|
{0, nullptr, hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::Zero,
|
||||||
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Backface, false, false, false},
|
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Backface, false, false, false},
|
||||||
/* Solid color additive */
|
/* Solid color additive */
|
||||||
{1, SolidBlockNames, 0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
|
||||||
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Backface, true, false, true},
|
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Backface, true, false, true},
|
||||||
/* Alpha-only Solid color frontface cull, LEqual */
|
/* Alpha-only Solid color frontface cull, LEqual */
|
||||||
{1, SolidBlockNames, 0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One,
|
{0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One,
|
||||||
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Frontface, false, true, false},
|
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Frontface, false, true, false},
|
||||||
/* Alpha-only Solid color frontface cull, Always, No Z-write */
|
/* Alpha-only Solid color frontface cull, Always, No Z-write */
|
||||||
{1, SolidBlockNames, 0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One,
|
{0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One,
|
||||||
hecl::Backend::ZTest::None, hecl::Backend::CullMode::Frontface, true, true, false},
|
hecl::Backend::ZTest::None, hecl::Backend::CullMode::Frontface, true, true, false},
|
||||||
/* Alpha-only Solid color backface cull, LEqual */
|
/* Alpha-only Solid color backface cull, LEqual */
|
||||||
{1, SolidBlockNames, 0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One,
|
{0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One,
|
||||||
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Backface, false, true, false},
|
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Backface, false, true, false},
|
||||||
/* Alpha-only Solid color backface cull, Greater, No Z-write */
|
/* Alpha-only Solid color backface cull, Greater, No Z-write */
|
||||||
{1, SolidBlockNames, 0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One,
|
{0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One,
|
||||||
hecl::Backend::ZTest::Greater, hecl::Backend::CullMode::Backface, true, true, false},
|
hecl::Backend::ZTest::Greater, hecl::Backend::CullMode::Backface, true, true, false},
|
||||||
/* MorphBall shadow shading */
|
/* MorphBall shadow shading */
|
||||||
{1, MBShadowBlockNames, 3, BallFadeTextures, hecl::Backend::BlendFactor::SrcAlpha,
|
{3, BallFadeTextures, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
|
||||||
hecl::Backend::BlendFactor::InvSrcAlpha, hecl::Backend::ZTest::Equal, hecl::Backend::CullMode::Backface, false,
|
hecl::Backend::ZTest::Equal, hecl::Backend::CullMode::Backface, false, false, true, false, true},
|
||||||
false, true, false, true},
|
|
||||||
/* World shadow shading (modified lighting) */
|
/* World shadow shading (modified lighting) */
|
||||||
{1, BlockNames, 1, WorldShadowTextures, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
|
{1, WorldShadowTextures, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true},
|
||||||
/* Forced alpha shading without culling */
|
/* Forced alpha shading without culling */
|
||||||
{1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, false, false, true},
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, false, false, true},
|
||||||
/* Forced additive shading without culling */
|
/* Forced additive shading without culling */
|
||||||
{1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, false, false, true},
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, false, false, true},
|
||||||
/* Forced alpha shading without Z-write */
|
/* Forced alpha shading without Z-write */
|
||||||
{1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original, true, false, true},
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original, true, false, true},
|
||||||
/* Forced additive shading without Z-write */
|
/* Forced additive shading without Z-write */
|
||||||
{1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original, true, false, true},
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original, true, false, true},
|
||||||
/* Forced alpha shading without culling or Z-write */
|
/* Forced alpha shading without culling or Z-write */
|
||||||
{1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, true, false, true},
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, true, false, true},
|
||||||
/* Forced additive shading without culling or Z-write */
|
/* Forced additive shading without culling or Z-write */
|
||||||
{1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, true, false, true},
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, true, false, true},
|
||||||
/* Depth GEqual no Z-write */
|
/* Depth GEqual no Z-write */
|
||||||
{1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
|
||||||
hecl::Backend::ZTest::GEqual, hecl::Backend::CullMode::Backface, true, false, true},
|
hecl::Backend::ZTest::GEqual, hecl::Backend::CullMode::Backface, true, false, true},
|
||||||
/* Disintegration */
|
/* Disintegration */
|
||||||
{1, DisintegrateBlockNames, 2, DisintegrateTextures, hecl::Backend::BlendFactor::SrcAlpha,
|
{2, DisintegrateTextures, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha,
|
||||||
hecl::Backend::BlendFactor::InvSrcAlpha, hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Original, false,
|
hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Original, false, false, true, false, false, true},
|
||||||
false, true, false, false, true},
|
|
||||||
/* Forced additive shading without culling or Z-write and greater depth test */
|
/* Forced additive shading without culling or Z-write and greater depth test */
|
||||||
{1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
|
{0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One,
|
||||||
hecl::Backend::ZTest::Greater, hecl::Backend::CullMode::None, true, false, true},
|
hecl::Backend::ZTest::Greater, hecl::Backend::CullMode::None, true, false, true},
|
||||||
/* Thermal cold shading */
|
/* Thermal cold shading */
|
||||||
{0, nullptr, 0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
|
{0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original,
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original,
|
||||||
false, false, true, false, false, false, true},
|
false, false, true, false, false, false, true},
|
||||||
/* Normal lit shading with alpha */
|
/* Normal lit shading with alpha */
|
||||||
{1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
|
{0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original,
|
||||||
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface}};
|
hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface}};
|
||||||
|
|
||||||
extern const hecl::Backend::Function ExtensionLightingFuncsGLSL[];
|
static const char* ShaderMacros[] = {
|
||||||
extern const hecl::Backend::Function ExtensionPostFuncsGLSL[];
|
"URDE_LIGHTING",
|
||||||
extern const hecl::Backend::Function ExtensionLightingFuncsHLSL[];
|
"URDE_LIGHTING",
|
||||||
extern const hecl::Backend::Function ExtensionPostFuncsHLSL[];
|
"URDE_THERMAL_HOT",
|
||||||
extern const hecl::Backend::Function ExtensionLightingFuncsMetal[];
|
"URDE_LIGHTING",
|
||||||
extern const hecl::Backend::Function ExtensionPostFuncsMetal[];
|
"URDE_LIGHTING",
|
||||||
|
"URDE_SOLID",
|
||||||
|
"URDE_SOLID",
|
||||||
|
"URDE_SOLID",
|
||||||
|
"URDE_SOLID",
|
||||||
|
"URDE_SOLID",
|
||||||
|
"URDE_SOLID",
|
||||||
|
"URDE_MB_SHADOW",
|
||||||
|
"URDE_LIGHTING_SHADOW",
|
||||||
|
"URDE_LIGHTING",
|
||||||
|
"URDE_LIGHTING",
|
||||||
|
"URDE_LIGHTING",
|
||||||
|
"URDE_LIGHTING",
|
||||||
|
"URDE_LIGHTING",
|
||||||
|
"URDE_LIGHTING",
|
||||||
|
"URDE_LIGHTING",
|
||||||
|
"URDE_DISINTEGRATE",
|
||||||
|
"URDE_LIGHTING",
|
||||||
|
"URDE_THERMAL_COLD",
|
||||||
|
"URDE_LIGHTING",
|
||||||
|
};
|
||||||
|
|
||||||
void CModelShaders::Initialize() {
|
void CModelShaders::Initialize() {
|
||||||
const hecl::Backend::Function* lightingFuncs;
|
const char** macro = ShaderMacros;
|
||||||
const hecl::Backend::Function* postFuncs;
|
for (auto& ext : g_ExtensionSlots)
|
||||||
switch (CGraphics::g_BooPlatform) {
|
ext.shaderMacro = *macro++;
|
||||||
case boo::IGraphicsDataFactory::Platform::OpenGL:
|
|
||||||
case boo::IGraphicsDataFactory::Platform::Vulkan:
|
|
||||||
case boo::IGraphicsDataFactory::Platform::NX:
|
|
||||||
default:
|
|
||||||
lightingFuncs = ExtensionLightingFuncsGLSL;
|
|
||||||
postFuncs = ExtensionPostFuncsGLSL;
|
|
||||||
break;
|
|
||||||
case boo::IGraphicsDataFactory::Platform::D3D11:
|
|
||||||
lightingFuncs = ExtensionLightingFuncsHLSL;
|
|
||||||
postFuncs = ExtensionPostFuncsHLSL;
|
|
||||||
break;
|
|
||||||
case boo::IGraphicsDataFactory::Platform::Metal:
|
|
||||||
lightingFuncs = ExtensionLightingFuncsMetal;
|
|
||||||
postFuncs = ExtensionPostFuncsMetal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for (auto& ext : g_ExtensionSlots) {
|
|
||||||
ext.lighting = *lightingFuncs++;
|
|
||||||
ext.post = *postFuncs++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModelShaders::Shutdown() { g_ShaderPipelines.clear(); }
|
void CModelShaders::Shutdown() { g_ShaderPipelines.clear(); }
|
||||||
|
|
||||||
CModelShaders::ShaderPipelines CModelShaders::BuildExtendedShader(const hecl::Backend::ShaderTag& tag,
|
CModelShaders::ShaderPipelines CModelShaders::BuildExtendedShader(const hecl::Backend::ShaderTag& tag,
|
||||||
const hecl::Frontend::IR& ir) {
|
const Material& material) {
|
||||||
auto search = g_ShaderPipelines.find(tag.val64());
|
auto search = g_ShaderPipelines.find(tag.val64());
|
||||||
if (search != g_ShaderPipelines.cend())
|
if (search != g_ShaderPipelines.cend())
|
||||||
return search->second;
|
return search->second;
|
||||||
|
@ -199,9 +193,10 @@ CModelShaders::ShaderPipelines CModelShaders::BuildExtendedShader(const hecl::Ba
|
||||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
for (const auto& ext : g_ExtensionSlots)
|
for (const auto& ext : g_ExtensionSlots)
|
||||||
(*newPipelines)[idx++] = hecl::conv->convert(ctx, hecl::HECLIR(ir, tag, ext));
|
(*newPipelines)[idx++] = hecl::conv->convert(ctx, Shader_CModelShaders(SModelShadersInfo(material, tag, ext)));
|
||||||
return true;
|
return true;
|
||||||
} BooTrace);
|
} BooTrace);
|
||||||
return newPipelines;
|
return newPipelines;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "hecl/Runtime.hpp"
|
#include "hecl/Runtime.hpp"
|
||||||
#include "hecl/Backend/Backend.hpp"
|
#include "hecl/Backend.hpp"
|
||||||
#include "optional.hpp"
|
#include "optional.hpp"
|
||||||
#include "zeus/CVector3f.hpp"
|
#include "zeus/CVector3f.hpp"
|
||||||
#include "zeus/CColor.hpp"
|
#include "zeus/CColor.hpp"
|
||||||
#include "Graphics/CGraphics.hpp"
|
#include "Graphics/CGraphics.hpp"
|
||||||
|
#include "DataSpec/DNAMP1/CMDLMaterials.hpp"
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#define URDE_MAX_LIGHTS 8
|
#define URDE_MAX_LIGHTS 8
|
||||||
|
@ -88,7 +89,8 @@ public:
|
||||||
using ShaderPipelinesData = std::array<boo::ObjToken<boo::IShaderPipeline>, EExtendedShader::MAX>;
|
using ShaderPipelinesData = std::array<boo::ObjToken<boo::IShaderPipeline>, EExtendedShader::MAX>;
|
||||||
using ShaderPipelines = std::shared_ptr<ShaderPipelinesData>;
|
using ShaderPipelines = std::shared_ptr<ShaderPipelinesData>;
|
||||||
|
|
||||||
static ShaderPipelines BuildExtendedShader(const hecl::Backend::ShaderTag& tag, const hecl::Frontend::IR& ir);
|
using Material = DataSpec::DNAMP1::HMDLMaterialSet::Material;
|
||||||
|
static ShaderPipelines BuildExtendedShader(const hecl::Backend::ShaderTag& tag, const Material& material);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::unordered_map<uint64_t, ShaderPipelines> g_ShaderPipelines;
|
static std::unordered_map<uint64_t, ShaderPipelines> g_ShaderPipelines;
|
||||||
|
|
|
@ -1,280 +0,0 @@
|
||||||
#include "CModelShaders.hpp"
|
|
||||||
#include "hecl/Backend/GLSL.hpp"
|
|
||||||
|
|
||||||
namespace urde {
|
|
||||||
using namespace std::literals;
|
|
||||||
|
|
||||||
extern const hecl::Backend::Function ExtensionLightingFuncsGLSL[];
|
|
||||||
extern const hecl::Backend::Function ExtensionPostFuncsGLSL[];
|
|
||||||
|
|
||||||
#define FOG_STRUCT_GLSL \
|
|
||||||
"struct Fog\n" \
|
|
||||||
"{\n" \
|
|
||||||
" vec4 color;\n" \
|
|
||||||
" float A;\n" \
|
|
||||||
" float B;\n" \
|
|
||||||
" float C;\n" \
|
|
||||||
" int mode;\n" \
|
|
||||||
"};\n"
|
|
||||||
|
|
||||||
#define FOG_ALGORITHM_GLSL \
|
|
||||||
" float fogZ;\n" \
|
|
||||||
" float fogF = clamp((fog.A / (fog.B - gl_FragCoord.z)) - fog.C, 0.0, 1.0);\n" \
|
|
||||||
" switch (fog.mode)\n" \
|
|
||||||
" {\n" \
|
|
||||||
" case 2:\n" \
|
|
||||||
" fogZ = fogF;\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" case 4:\n" \
|
|
||||||
" fogZ = 1.0 - exp2(-8.0 * fogF);\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" case 5:\n" \
|
|
||||||
" fogZ = 1.0 - exp2(-8.0 * fogF * fogF);\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" case 6:\n" \
|
|
||||||
" fogZ = exp2(-8.0 * (1.0 - fogF));\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" case 7:\n" \
|
|
||||||
" fogF = 1.0 - fogF;\n" \
|
|
||||||
" fogZ = exp2(-8.0 * fogF * fogF);\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" default:\n" \
|
|
||||||
" fogZ = 0.0;\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" }\n" \
|
|
||||||
"#ifdef BLEND_DST_ONE\n" \
|
|
||||||
" return vec4(mix(colorIn, vec4(0.0), clamp(fogZ, 0.0, 1.0)).rgb, colorIn.a);\n" \
|
|
||||||
"#else\n" \
|
|
||||||
" return vec4(mix(colorIn, fog.color, clamp(fogZ, 0.0, 1.0)).rgb, colorIn.a);\n" \
|
|
||||||
"#endif\n"
|
|
||||||
|
|
||||||
static std::string_view LightingGLSL =
|
|
||||||
"struct Light\n"
|
|
||||||
"{\n"
|
|
||||||
" vec4 pos;\n"
|
|
||||||
" vec4 dir;\n"
|
|
||||||
" vec4 color;\n"
|
|
||||||
" vec4 linAtt;\n"
|
|
||||||
" vec4 angAtt;\n"
|
|
||||||
"};\n"
|
|
||||||
FOG_STRUCT_GLSL
|
|
||||||
"\n"
|
|
||||||
"UBINDING2 uniform LightingUniform\n"
|
|
||||||
"{\n"
|
|
||||||
" Light lights[" _XSTR(URDE_MAX_LIGHTS) "];\n"
|
|
||||||
" vec4 ambient;\n"
|
|
||||||
" vec4 colorReg0;\n"
|
|
||||||
" vec4 colorReg1;\n"
|
|
||||||
" vec4 colorReg2;\n"
|
|
||||||
" vec4 mulColor;\n"
|
|
||||||
" vec4 addColor;\n"
|
|
||||||
" Fog fog;\n"
|
|
||||||
"};\n"
|
|
||||||
"\n"
|
|
||||||
"vec4 LightingFunc(vec3 mvPosIn, vec3 mvNormIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" vec4 ret = ambient;\n"
|
|
||||||
" \n"
|
|
||||||
" for (int i=0 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
|
||||||
" {\n"
|
|
||||||
" vec3 delta = mvPosIn - lights[i].pos.xyz;\n"
|
|
||||||
" float dist = length(delta);\n"
|
|
||||||
" vec3 deltaNorm = delta / dist;\n"
|
|
||||||
" float angDot = max(dot(deltaNorm, lights[i].dir.xyz), 0.0);\n"
|
|
||||||
" float att = 1.0 / (lights[i].linAtt[2] * dist * dist +\n"
|
|
||||||
" lights[i].linAtt[1] * dist +\n"
|
|
||||||
" lights[i].linAtt[0]);\n"
|
|
||||||
" float angAtt = lights[i].angAtt[2] * angDot * angDot +\n"
|
|
||||||
" lights[i].angAtt[1] * angDot +\n"
|
|
||||||
" lights[i].angAtt[0];\n"
|
|
||||||
" ret += lights[i].color * angAtt * att * max(dot(-deltaNorm, mvNormIn), 0.0);\n"
|
|
||||||
" }\n"
|
|
||||||
" \n"
|
|
||||||
" return clamp(ret, 0.0, 1.0);\n"
|
|
||||||
"}\n"sv;
|
|
||||||
|
|
||||||
static std::string_view LightingShadowGLSL =
|
|
||||||
"struct Light\n"
|
|
||||||
"{\n"
|
|
||||||
" vec4 pos;\n"
|
|
||||||
" vec4 dir;\n"
|
|
||||||
" vec4 color;\n"
|
|
||||||
" vec4 linAtt;\n"
|
|
||||||
" vec4 angAtt;\n"
|
|
||||||
"};\n"
|
|
||||||
FOG_STRUCT_GLSL
|
|
||||||
"\n"
|
|
||||||
"UBINDING2 uniform LightingUniform\n"
|
|
||||||
"{\n"
|
|
||||||
" Light lights[" _XSTR(URDE_MAX_LIGHTS) "];\n"
|
|
||||||
" vec4 ambient;\n"
|
|
||||||
" vec4 colorReg0;\n"
|
|
||||||
" vec4 colorReg1;\n"
|
|
||||||
" vec4 colorReg2;\n"
|
|
||||||
" vec4 mulColor;\n"
|
|
||||||
" vec4 addColor;\n"
|
|
||||||
" Fog fog;\n"
|
|
||||||
"};\n"
|
|
||||||
"\n"
|
|
||||||
"vec4 LightingShadowFunc(vec3 mvPosIn, vec3 mvNormIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" vec2 shadowUV = vtf.extTcgs[0];\n"
|
|
||||||
" shadowUV.y = 1.0 - shadowUV.y;\n"
|
|
||||||
" \n"
|
|
||||||
" vec4 ret = ambient;\n"
|
|
||||||
" \n"
|
|
||||||
" vec3 delta = mvPosIn - lights[0].pos.xyz;\n"
|
|
||||||
" float dist = length(delta);\n"
|
|
||||||
" vec3 deltaNorm = delta / dist;\n"
|
|
||||||
" float angDot = max(dot(deltaNorm, lights[0].dir.xyz), 0.0);\n"
|
|
||||||
" float att = 1.0 / (lights[0].linAtt[2] * dist * dist +\n"
|
|
||||||
" lights[0].linAtt[1] * dist +\n"
|
|
||||||
" lights[0].linAtt[0]);\n"
|
|
||||||
" float angAtt = lights[0].angAtt[2] * angDot * angDot +\n"
|
|
||||||
" lights[0].angAtt[1] * angDot +\n"
|
|
||||||
" lights[0].angAtt[0];\n"
|
|
||||||
" ret += lights[0].color * angAtt * att * max(dot(-deltaNorm, mvNormIn), 0.0) *\n"
|
|
||||||
" texture(extTex7, shadowUV).r;\n"
|
|
||||||
" \n"
|
|
||||||
" for (int i=1 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
|
||||||
" {\n"
|
|
||||||
" vec3 delta = mvPosIn - lights[i].pos.xyz;\n"
|
|
||||||
" float dist = length(delta);\n"
|
|
||||||
" vec3 deltaNorm = delta / dist;\n"
|
|
||||||
" float angDot = max(dot(deltaNorm, lights[i].dir.xyz), 0.0);\n"
|
|
||||||
" float att = 1.0 / (lights[i].linAtt[2] * dist * dist +\n"
|
|
||||||
" lights[i].linAtt[1] * dist +\n"
|
|
||||||
" lights[i].linAtt[0]);\n"
|
|
||||||
" float angAtt = lights[i].angAtt[2] * angDot * angDot +\n"
|
|
||||||
" lights[i].angAtt[1] * angDot +\n"
|
|
||||||
" lights[i].angAtt[0];\n"
|
|
||||||
" ret += lights[i].color * angAtt * att * max(dot(-deltaNorm, mvNormIn), 0.0);\n"
|
|
||||||
" }\n"
|
|
||||||
" \n"
|
|
||||||
" return clamp(ret, 0.0, 1.0);\n"
|
|
||||||
"}\n"sv;
|
|
||||||
|
|
||||||
static std::string_view MainPostGLSL =
|
|
||||||
"vec4 MainPostFunc(vec4 colorIn)\n"
|
|
||||||
"{\n" FOG_ALGORITHM_GLSL
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view ThermalPostGLSL =
|
|
||||||
"UBINDING2 uniform ThermalUniform\n"
|
|
||||||
"{\n"
|
|
||||||
" vec4 tmulColor;\n"
|
|
||||||
" vec4 taddColor;\n"
|
|
||||||
"};\n"
|
|
||||||
"vec4 ThermalPostFunc(vec4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" return texture(extTex7, vtf.extTcgs[0]).rrrr * tmulColor + taddColor;\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view SolidPostGLSL =
|
|
||||||
"UBINDING2 uniform SolidUniform\n"
|
|
||||||
"{\n"
|
|
||||||
" vec4 solidColor;\n"
|
|
||||||
"};\n"
|
|
||||||
"vec4 SolidPostFunc(vec4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" return solidColor;\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view MBShadowPostGLSL =
|
|
||||||
"UBINDING2 uniform MBShadowUniform\n"
|
|
||||||
"{\n"
|
|
||||||
" vec4 shadowUp;\n"
|
|
||||||
" float shadowId;\n"
|
|
||||||
"};\n"
|
|
||||||
"vec4 MBShadowPostFunc(vec4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" float idTexel = texture(extTex0, vtf.extTcgs[0]).a;\n"
|
|
||||||
" float sphereTexel = texture(extTex1, vtf.extTcgs[1]).a;\n"
|
|
||||||
" float fadeTexel = texture(extTex2, vtf.extTcgs[2]).a;\n"
|
|
||||||
" float val = ((abs(idTexel - shadowId) < 0.001) ?\n"
|
|
||||||
" (dot(vtf.mvNorm.xyz, shadowUp.xyz) * shadowUp.w) : 0.0) *\n"
|
|
||||||
" sphereTexel * fadeTexel;\n"
|
|
||||||
" return vec4(0.0, 0.0, 0.0, val);\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view DisintegratePostGLSL = FOG_STRUCT_GLSL
|
|
||||||
"UBINDING2 uniform DisintegrateUniform\n"
|
|
||||||
"{\n"
|
|
||||||
" vec4 daddColor;\n"
|
|
||||||
" Fog fog;\n"
|
|
||||||
"};\n"
|
|
||||||
"vec4 DisintegratePostFunc(vec4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" vec4 texel0 = texture(extTex7, vtf.extTcgs[0]);\n"
|
|
||||||
" vec4 texel1 = texture(extTex7, vtf.extTcgs[1]);\n"
|
|
||||||
" colorIn = mix(vec4(0.0), texel1, texel0);\n"
|
|
||||||
" colorIn.rgb += daddColor.rgb;\n" FOG_ALGORITHM_GLSL
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view ThermalColdPostGLSL =
|
|
||||||
"vec4 ThermalColdPostFunc(vec4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" return colorIn * vec4(0.75);\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
const hecl::Backend::Function ExtensionLightingFuncsGLSL[] = {
|
|
||||||
{},
|
|
||||||
{LightingGLSL, "LightingFunc"},
|
|
||||||
{},
|
|
||||||
{LightingGLSL, "LightingFunc"},
|
|
||||||
{LightingGLSL, "LightingFunc"},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{LightingShadowGLSL, "LightingShadowFunc"},
|
|
||||||
{LightingGLSL, "LightingFunc"},
|
|
||||||
{LightingGLSL, "LightingFunc"},
|
|
||||||
{LightingGLSL, "LightingFunc"},
|
|
||||||
{LightingGLSL, "LightingFunc"},
|
|
||||||
{LightingGLSL, "LightingFunc"},
|
|
||||||
{LightingGLSL, "LightingFunc"},
|
|
||||||
{LightingGLSL, "LightingFunc"},
|
|
||||||
{},
|
|
||||||
{LightingGLSL, "LightingFunc"},
|
|
||||||
{},
|
|
||||||
{LightingGLSL, "LightingFunc"},
|
|
||||||
};
|
|
||||||
|
|
||||||
const hecl::Backend::Function ExtensionPostFuncsGLSL[] = {
|
|
||||||
{},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
{ThermalPostGLSL, "ThermalPostFunc"},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
{SolidPostGLSL, "SolidPostFunc"},
|
|
||||||
{SolidPostGLSL, "SolidPostFunc"},
|
|
||||||
{SolidPostGLSL, "SolidPostFunc"},
|
|
||||||
{SolidPostGLSL, "SolidPostFunc"},
|
|
||||||
{SolidPostGLSL, "SolidPostFunc"},
|
|
||||||
{SolidPostGLSL, "SolidPostFunc"},
|
|
||||||
{MBShadowPostGLSL, "MBShadowPostFunc"},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
{DisintegratePostGLSL, "DisintegratePostFunc"},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
{ThermalColdPostGLSL, "ThermalColdPostFunc"},
|
|
||||||
{MainPostGLSL, "MainPostFunc"},
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace urde
|
|
|
@ -1,271 +0,0 @@
|
||||||
#include "CModelShaders.hpp"
|
|
||||||
|
|
||||||
namespace urde {
|
|
||||||
using namespace std::literals;
|
|
||||||
|
|
||||||
extern const hecl::Backend::Function ExtensionLightingFuncsHLSL[];
|
|
||||||
extern const hecl::Backend::Function ExtensionPostFuncsHLSL[];
|
|
||||||
|
|
||||||
#define FOG_STRUCT_HLSL \
|
|
||||||
"struct Fog\n" \
|
|
||||||
"{\n" \
|
|
||||||
" float4 color;\n" \
|
|
||||||
" float A;\n" \
|
|
||||||
" float B;\n" \
|
|
||||||
" float C;\n" \
|
|
||||||
" int mode;\n" \
|
|
||||||
"};\n"
|
|
||||||
|
|
||||||
#define FOG_ALGORITHM_HLSL \
|
|
||||||
" float fogZ;\n" \
|
|
||||||
" float fogF = saturate((fog.A / (fog.B - (1.0 - vtf.mvpPos.z))) - fog.C);\n" \
|
|
||||||
" switch (fog.mode)\n" \
|
|
||||||
" {\n" \
|
|
||||||
" case 2:\n" \
|
|
||||||
" fogZ = fogF;\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" case 4:\n" \
|
|
||||||
" fogZ = 1.0 - exp2(-8.0 * fogF);\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" case 5:\n" \
|
|
||||||
" fogZ = 1.0 - exp2(-8.0 * fogF * fogF);\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" case 6:\n" \
|
|
||||||
" fogZ = exp2(-8.0 * (1.0 - fogF));\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" case 7:\n" \
|
|
||||||
" fogF = 1.0 - fogF;\n" \
|
|
||||||
" fogZ = exp2(-8.0 * fogF * fogF);\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" default:\n" \
|
|
||||||
" fogZ = 0.0;\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" }\n" \
|
|
||||||
"#ifdef BLEND_DST_ONE\n" \
|
|
||||||
" return float4(lerp(colorIn, float4(0.0,0.0,0.0,0.0), saturate(fogZ)).rgb, colorIn.a);\n" \
|
|
||||||
"#else\n" \
|
|
||||||
" return float4(lerp(colorIn, fog.color, saturate(fogZ)).rgb, colorIn.a);\n" \
|
|
||||||
"#endif\n"
|
|
||||||
|
|
||||||
static std::string_view LightingHLSL =
|
|
||||||
"struct Light\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 pos;\n"
|
|
||||||
" float4 dir;\n"
|
|
||||||
" float4 color;\n"
|
|
||||||
" float4 linAtt;\n"
|
|
||||||
" float4 angAtt;\n"
|
|
||||||
"};\n"
|
|
||||||
FOG_STRUCT_HLSL
|
|
||||||
"\n"
|
|
||||||
"cbuffer LightingUniform : register(b2)\n"
|
|
||||||
"{\n"
|
|
||||||
" Light lights[" _XSTR(URDE_MAX_LIGHTS) "];\n"
|
|
||||||
" float4 ambient;\n"
|
|
||||||
" float4 colorReg0;\n"
|
|
||||||
" float4 colorReg1;\n"
|
|
||||||
" float4 colorReg2;\n"
|
|
||||||
" float4 mulColor;\n"
|
|
||||||
" float4 addColor;\n"
|
|
||||||
" Fog fog;\n"
|
|
||||||
"};\n"
|
|
||||||
"\n"
|
|
||||||
"static float4 LightingFunc(float3 mvPosIn, float3 mvNormIn, in VertToFrag vtf)\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 ret = ambient;\n"
|
|
||||||
" \n"
|
|
||||||
" for (int i=0 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
|
||||||
" {\n"
|
|
||||||
" float3 delta = mvPosIn - lights[i].pos.xyz;\n"
|
|
||||||
" float dist = length(delta);\n"
|
|
||||||
" float angDot = saturate(dot(normalize(delta), lights[i].dir.xyz));\n"
|
|
||||||
" float att = 1.0 / (lights[i].linAtt[2] * dist * dist +\n"
|
|
||||||
" lights[i].linAtt[1] * dist +\n"
|
|
||||||
" lights[i].linAtt[0]);\n"
|
|
||||||
" float angAtt = lights[i].angAtt[2] * angDot * angDot +\n"
|
|
||||||
" lights[i].angAtt[1] * angDot +\n"
|
|
||||||
" lights[i].angAtt[0];\n"
|
|
||||||
" ret += lights[i].color * angAtt * att * saturate(dot(normalize(-delta), mvNormIn));\n"
|
|
||||||
" }\n"
|
|
||||||
" \n"
|
|
||||||
" return saturate(ret);\n"
|
|
||||||
"}\n"sv;
|
|
||||||
|
|
||||||
static std::string_view LightingShadowHLSL =
|
|
||||||
"struct Light\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 pos;\n"
|
|
||||||
" float4 dir;\n"
|
|
||||||
" float4 color;\n"
|
|
||||||
" float4 linAtt;\n"
|
|
||||||
" float4 angAtt;\n"
|
|
||||||
"};\n"
|
|
||||||
FOG_STRUCT_HLSL
|
|
||||||
"\n"
|
|
||||||
"cbuffer LightingUniform : register(b2)\n"
|
|
||||||
"{\n"
|
|
||||||
" Light lights[" _XSTR(URDE_MAX_LIGHTS) "];\n"
|
|
||||||
" float4 ambient;\n"
|
|
||||||
" float4 colorReg0;\n"
|
|
||||||
" float4 colorReg1;\n"
|
|
||||||
" float4 colorReg2;\n"
|
|
||||||
" float4 mulColor;\n"
|
|
||||||
" float4 addColor;\n"
|
|
||||||
" Fog fog;\n"
|
|
||||||
"};\n"
|
|
||||||
"\n"
|
|
||||||
"static float4 LightingShadowFunc(float3 mvPosIn, float3 mvNormIn, in VertToFrag vtf)\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 ret = ambient;\n"
|
|
||||||
" \n"
|
|
||||||
" float3 delta = mvPosIn - lights[0].pos.xyz;\n"
|
|
||||||
" float dist = length(delta);\n"
|
|
||||||
" float angDot = saturate(dot(normalize(delta), lights[0].dir.xyz));\n"
|
|
||||||
" float att = 1.0 / (lights[0].linAtt[2] * dist * dist +\n"
|
|
||||||
" lights[0].linAtt[1] * dist +\n"
|
|
||||||
" lights[0].linAtt[0]);\n"
|
|
||||||
" float angAtt = lights[0].angAtt[2] * angDot * angDot +\n"
|
|
||||||
" lights[0].angAtt[1] * angDot +\n"
|
|
||||||
" lights[0].angAtt[0];\n"
|
|
||||||
" ret += lights[0].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn)) *\n"
|
|
||||||
" extTex7.Sample(clampSamp, vtf.extTcgs[0]).r;\n"
|
|
||||||
" \n"
|
|
||||||
" for (int i=1 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
|
||||||
" {\n"
|
|
||||||
" float3 delta = mvPosIn - lights[i].pos.xyz;\n"
|
|
||||||
" float dist = length(delta);\n"
|
|
||||||
" float angDot = saturate(dot(normalize(delta), lights[i].dir.xyz));\n"
|
|
||||||
" float att = 1.0 / (lights[i].linAtt[2] * dist * dist +\n"
|
|
||||||
" lights[i].linAtt[1] * dist +\n"
|
|
||||||
" lights[i].linAtt[0]);\n"
|
|
||||||
" float angAtt = lights[i].angAtt[2] * angDot * angDot +\n"
|
|
||||||
" lights[i].angAtt[1] * angDot +\n"
|
|
||||||
" lights[i].angAtt[0];\n"
|
|
||||||
" ret += lights[i].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn));\n"
|
|
||||||
" }\n"
|
|
||||||
" \n"
|
|
||||||
" return ret;\n"
|
|
||||||
"}\n"sv;
|
|
||||||
|
|
||||||
static std::string_view MainPostHLSL =
|
|
||||||
"static float4 MainPostFunc(in VertToFrag vtf, float4 colorIn)\n"
|
|
||||||
"{\n" FOG_ALGORITHM_HLSL
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view ThermalPostHLSL =
|
|
||||||
"cbuffer ThermalUniform : register(b2)\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 tmulColor;\n"
|
|
||||||
" float4 taddColor;\n"
|
|
||||||
"};\n"
|
|
||||||
"static float4 ThermalPostFunc(in VertToFrag vtf, float4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" return extTex7.Sample(samp, vtf.extTcgs[0]).rrrr * tmulColor + taddColor;\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view SolidPostHLSL =
|
|
||||||
"cbuffer SolidUniform : register(b2)\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 solidColor;\n"
|
|
||||||
"};\n"
|
|
||||||
"static float4 SolidPostFunc(in VertToFrag vtf, float4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" return solidColor;\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view MBShadowPostHLSL =
|
|
||||||
"cbuffer MBShadowUniform : register(b2)\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 shadowUp;\n"
|
|
||||||
" float shadowId;\n"
|
|
||||||
"};\n"
|
|
||||||
"static float4 MBShadowPostFunc(in VertToFrag vtf, float4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" float idTexel = extTex0.Sample(samp, vtf.extTcgs[0]).a;\n"
|
|
||||||
" float sphereTexel = extTex1.Sample(samp, vtf.extTcgs[1]).a;\n"
|
|
||||||
" float fadeTexel = extTex2.Sample(samp, vtf.extTcgs[2]).a;\n"
|
|
||||||
" float val = ((abs(idTexel - shadowId) < 0.001) ?\n"
|
|
||||||
" (dot(vtf.mvNorm.xyz, shadowUp.xyz) * shadowUp.w) : 0.0) *\n"
|
|
||||||
" sphereTexel * fadeTexel;\n"
|
|
||||||
" return float4(0.0, 0.0, 0.0, val);\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view DisintegratePostHLSL = FOG_STRUCT_HLSL
|
|
||||||
"cbuffer DisintegrateUniform : register(b2)\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 daddColor;\n"
|
|
||||||
" Fog fog;\n"
|
|
||||||
"};\n"
|
|
||||||
"static float4 DisintegratePostFunc(in VertToFrag vtf, float4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 texel0 = extTex7.Sample(samp, vtf.extTcgs[0]);\n"
|
|
||||||
" float4 texel1 = extTex7.Sample(samp, vtf.extTcgs[1]);\n"
|
|
||||||
" colorIn = lerp(float4(0.0,0.0,0.0,0.0), texel1, texel0);\n"
|
|
||||||
" colorIn.rgb += daddColor.rgb;\n" FOG_ALGORITHM_HLSL
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view ThermalColdPostHLSL =
|
|
||||||
"static float4 ThermalColdPostFunc(in VertToFrag vtf, float4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" return colorIn * float4(0.75, 0.75, 0.75, 0.75);\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
const hecl::Backend::Function ExtensionLightingFuncsHLSL[] = {{},
|
|
||||||
{LightingHLSL, "LightingFunc"},
|
|
||||||
{},
|
|
||||||
{LightingHLSL, "LightingFunc"},
|
|
||||||
{LightingHLSL, "LightingFunc"},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{LightingShadowHLSL, "LightingShadowFunc"},
|
|
||||||
{LightingHLSL, "LightingFunc"},
|
|
||||||
{LightingHLSL, "LightingFunc"},
|
|
||||||
{LightingHLSL, "LightingFunc"},
|
|
||||||
{LightingHLSL, "LightingFunc"},
|
|
||||||
{LightingHLSL, "LightingFunc"},
|
|
||||||
{LightingHLSL, "LightingFunc"},
|
|
||||||
{LightingHLSL, "LightingFunc"},
|
|
||||||
{},
|
|
||||||
{LightingHLSL, "LightingFunc"},
|
|
||||||
{},
|
|
||||||
{LightingHLSL, "LightingFunc"},};
|
|
||||||
|
|
||||||
const hecl::Backend::Function ExtensionPostFuncsHLSL[] = {
|
|
||||||
{},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
{ThermalPostHLSL, "ThermalPostFunc"},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
{SolidPostHLSL, "SolidPostFunc"},
|
|
||||||
{SolidPostHLSL, "SolidPostFunc"},
|
|
||||||
{SolidPostHLSL, "SolidPostFunc"},
|
|
||||||
{SolidPostHLSL, "SolidPostFunc"},
|
|
||||||
{SolidPostHLSL, "SolidPostFunc"},
|
|
||||||
{SolidPostHLSL, "SolidPostFunc"},
|
|
||||||
{MBShadowPostHLSL, "MBShadowPostFunc"},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
{DisintegratePostHLSL, "DisintegratePostFunc"},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
{ThermalColdPostHLSL, "ThermalColdPostFunc"},
|
|
||||||
{MainPostHLSL, "MainPostFunc"},
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace urde
|
|
|
@ -1,276 +0,0 @@
|
||||||
#include "CModelShaders.hpp"
|
|
||||||
|
|
||||||
namespace urde {
|
|
||||||
using namespace std::literals;
|
|
||||||
|
|
||||||
extern const hecl::Backend::Function ExtensionLightingFuncsMetal[];
|
|
||||||
extern const hecl::Backend::Function ExtensionPostFuncsMetal[];
|
|
||||||
|
|
||||||
#define FOG_STRUCT_METAL \
|
|
||||||
"struct Fog\n" \
|
|
||||||
"{\n" \
|
|
||||||
" float4 color;\n" \
|
|
||||||
" float A;\n" \
|
|
||||||
" float B;\n" \
|
|
||||||
" float C;\n" \
|
|
||||||
" int mode;\n" \
|
|
||||||
"};\n"
|
|
||||||
|
|
||||||
#define FOG_ALGORITHM_METAL \
|
|
||||||
" float fogZ;\n" \
|
|
||||||
" float fogF = saturate((lu.fog.A / (lu.fog.B - (1.0 - vtf.mvpPos.z))) - lu.fog.C);\n" \
|
|
||||||
" switch (lu.fog.mode)\n" \
|
|
||||||
" {\n" \
|
|
||||||
" case 2:\n" \
|
|
||||||
" fogZ = fogF;\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" case 4:\n" \
|
|
||||||
" fogZ = 1.0 - exp2(-8.0 * fogF);\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" case 5:\n" \
|
|
||||||
" fogZ = 1.0 - exp2(-8.0 * fogF * fogF);\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" case 6:\n" \
|
|
||||||
" fogZ = exp2(-8.0 * (1.0 - fogF));\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" case 7:\n" \
|
|
||||||
" fogF = 1.0 - fogF;\n" \
|
|
||||||
" fogZ = exp2(-8.0 * fogF * fogF);\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" default:\n" \
|
|
||||||
" fogZ = 0.0;\n" \
|
|
||||||
" break;\n" \
|
|
||||||
" }\n" \
|
|
||||||
"#ifdef BLEND_DST_ONE\n" \
|
|
||||||
" return float4(mix(colorIn, float4(0.0), saturate(fogZ)).rgb, colorIn.a);\n" \
|
|
||||||
"#else\n" \
|
|
||||||
" return float4(mix(colorIn, lu.fog.color, saturate(fogZ)).rgb, colorIn.a);\n" \
|
|
||||||
"#endif\n"
|
|
||||||
|
|
||||||
static std::string_view LightingMetal =
|
|
||||||
"struct Light\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 pos;\n"
|
|
||||||
" float4 dir;\n"
|
|
||||||
" float4 color;\n"
|
|
||||||
" float4 linAtt;\n"
|
|
||||||
" float4 angAtt;\n"
|
|
||||||
"};\n"
|
|
||||||
FOG_STRUCT_METAL
|
|
||||||
"\n"
|
|
||||||
"struct LightingUniform\n"
|
|
||||||
"{\n"
|
|
||||||
" Light lights[" _XSTR(URDE_MAX_LIGHTS) "];\n"
|
|
||||||
" float4 ambient;\n"
|
|
||||||
" float4 colorReg0;\n"
|
|
||||||
" float4 colorReg1;\n"
|
|
||||||
" float4 colorReg2;\n"
|
|
||||||
" float4 mulColor;\n"
|
|
||||||
" float4 addColor;\n"
|
|
||||||
" Fog fog;\n"
|
|
||||||
"};\n"
|
|
||||||
"\n"
|
|
||||||
"static float4 LightingFunc(constant LightingUniform& lu, float3 mvPosIn, float3 mvNormIn, thread VertToFrag& vtf)\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 ret = lu.ambient;\n"
|
|
||||||
" \n"
|
|
||||||
" for (int i=0 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
|
||||||
" {\n"
|
|
||||||
" float3 delta = mvPosIn - lu.lights[i].pos.xyz;\n"
|
|
||||||
" float dist = length(delta);\n"
|
|
||||||
" float angDot = saturate(dot(normalize(delta), lu.lights[i].dir.xyz));\n"
|
|
||||||
" float att = 1.0 / (lu.lights[i].linAtt[2] * dist * dist +\n"
|
|
||||||
" lu.lights[i].linAtt[1] * dist +\n"
|
|
||||||
" lu.lights[i].linAtt[0]);\n"
|
|
||||||
" float angAtt = lu.lights[i].angAtt[2] * angDot * angDot +\n"
|
|
||||||
" lu.lights[i].angAtt[1] * angDot +\n"
|
|
||||||
" lu.lights[i].angAtt[0];\n"
|
|
||||||
" ret += lu.lights[i].color * angAtt * att * saturate(dot(normalize(-delta), mvNormIn));\n"
|
|
||||||
" }\n"
|
|
||||||
" \n"
|
|
||||||
" return saturate(ret);\n"
|
|
||||||
"}\n"sv;
|
|
||||||
|
|
||||||
static std::string_view LightingShadowMetal =
|
|
||||||
"struct Light\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 pos;\n"
|
|
||||||
" float4 dir;\n"
|
|
||||||
" float4 color;\n"
|
|
||||||
" float4 linAtt;\n"
|
|
||||||
" float4 angAtt;\n"
|
|
||||||
"};\n"
|
|
||||||
FOG_STRUCT_METAL
|
|
||||||
"\n"
|
|
||||||
"struct LightingUniform\n"
|
|
||||||
"{\n"
|
|
||||||
" Light lights[" _XSTR(URDE_MAX_LIGHTS) "];\n"
|
|
||||||
" float4 ambient;\n"
|
|
||||||
" float4 colorReg0;\n"
|
|
||||||
" float4 colorReg1;\n"
|
|
||||||
" float4 colorReg2;\n"
|
|
||||||
" float4 mulColor;\n"
|
|
||||||
" float4 addColor;\n"
|
|
||||||
" Fog fog;\n"
|
|
||||||
"};\n"
|
|
||||||
"\n"
|
|
||||||
"static float4 EXTLightingShadowFunc(constant LightingUniform& lu, float3 mvPosIn, float3 mvNormIn,\n"
|
|
||||||
" thread VertToFrag& vtf, sampler samp, sampler clampSamp, texture2d<float> extTex7)\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 ret = lu.ambient;\n"
|
|
||||||
" \n"
|
|
||||||
" float3 delta = mvPosIn - lu.lights[0].pos.xyz;\n"
|
|
||||||
" float dist = length(delta);\n"
|
|
||||||
" float angDot = saturate(dot(normalize(delta), lu.lights[0].dir.xyz));\n"
|
|
||||||
" float att = 1.0 / (lu.lights[0].linAtt[2] * dist * dist +\n"
|
|
||||||
" lu.lights[0].linAtt[1] * dist +\n"
|
|
||||||
" lu.lights[0].linAtt[0]);\n"
|
|
||||||
" float angAtt = lu.lights[0].angAtt[2] * angDot * angDot +\n"
|
|
||||||
" lu.lights[0].angAtt[1] * angDot +\n"
|
|
||||||
" lu.lights[0].angAtt[0];\n"
|
|
||||||
" ret += lu.lights[0].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn)) *\n"
|
|
||||||
" extTex7.sample(clampSamp, vtf.extTcgs0).r;\n"
|
|
||||||
" \n"
|
|
||||||
" for (int i=1 ; i<" _XSTR(URDE_MAX_LIGHTS) " ; ++i)\n"
|
|
||||||
" {\n"
|
|
||||||
" float3 delta = mvPosIn - lu.lights[i].pos.xyz;\n"
|
|
||||||
" float dist = length(delta);\n"
|
|
||||||
" float angDot = saturate(dot(normalize(delta), lu.lights[i].dir.xyz));\n"
|
|
||||||
" float att = 1.0 / (lu.lights[i].linAtt[2] * dist * dist +\n"
|
|
||||||
" lu.lights[i].linAtt[1] * dist +\n"
|
|
||||||
" lu.lights[i].linAtt[0]);\n"
|
|
||||||
" float angAtt = lu.lights[i].angAtt[2] * angDot * angDot +\n"
|
|
||||||
" lu.lights[i].angAtt[1] * angDot +\n"
|
|
||||||
" lu.lights[i].angAtt[0];\n"
|
|
||||||
" ret += lu.lights[i].color * saturate(angAtt) * att * saturate(dot(normalize(-delta), mvNormIn));\n"
|
|
||||||
" }\n"
|
|
||||||
" \n"
|
|
||||||
" return ret;\n"
|
|
||||||
"}\n"sv;
|
|
||||||
|
|
||||||
static std::string_view MainPostMetal =
|
|
||||||
"float4 MainPostFunc(thread VertToFrag& vtf, constant LightingUniform& lu, float4 colorIn)\n"
|
|
||||||
"{\n" FOG_ALGORITHM_METAL
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view ThermalPostMetal =
|
|
||||||
"struct ThermalUniform\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 tmulColor;\n"
|
|
||||||
" float4 taddColor;\n"
|
|
||||||
"};\n"
|
|
||||||
"static float4 EXTThermalPostFunc(thread VertToFrag& vtf, constant ThermalUniform& lu,\n"
|
|
||||||
" sampler samp, sampler clampSamp, texture2d<float> extTex7, float4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" return extTex7.sample(samp, vtf.extTcgs0).rrrr * lu.tmulColor + lu.taddColor;\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view SolidPostMetal =
|
|
||||||
"struct SolidUniform\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 solidColor;\n"
|
|
||||||
"};\n"
|
|
||||||
"static float4 SolidPostFunc(thread VertToFrag& vtf, constant SolidUniform& lu, float4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" return lu.solidColor;\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view MBShadowPostMetal =
|
|
||||||
"struct MBShadowUniform\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 shadowUp;\n"
|
|
||||||
" float shadowId;\n"
|
|
||||||
"};\n"
|
|
||||||
"static float4 EXTMBShadowPostFunc(thread VertToFrag& vtf, constant MBShadowUniform& su, sampler samp,\n"
|
|
||||||
" sampler clampSamp, texture2d<float> extTex0, texture2d<float> extTex1,\n"
|
|
||||||
" texture2d<float> extTex2, float4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" float idTexel = extTex0.sample(samp, vtf.extTcgs0).a;\n"
|
|
||||||
" float sphereTexel = extTex1.sample(samp, vtf.extTcgs1).a;\n"
|
|
||||||
" float fadeTexel = extTex2.sample(samp, vtf.extTcgs2).a;\n"
|
|
||||||
" float val = ((fabs(idTexel - su.shadowId) < 0.001) ?\n"
|
|
||||||
" (dot(vtf.mvNorm.xyz, su.shadowUp.xyz) * su.shadowUp.w) : 0.0) *\n"
|
|
||||||
" sphereTexel * fadeTexel;\n"
|
|
||||||
" return float4(0.0, 0.0, 0.0, val);\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view DisintegratePostMetal = FOG_STRUCT_METAL
|
|
||||||
"struct DisintegrateUniform\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 daddColor;\n"
|
|
||||||
" Fog fog;\n"
|
|
||||||
"};\n"
|
|
||||||
"static float4 EXTDisintegratePostFunc(thread VertToFrag& vtf, constant DisintegrateUniform& lu, sampler samp,\n"
|
|
||||||
" sampler clampSamp, texture2d<float> extTex7, float4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" float4 texel0 = extTex7.sample(samp, vtf.extTcgs0);\n"
|
|
||||||
" float4 texel1 = extTex7.sample(samp, vtf.extTcgs1);\n"
|
|
||||||
" colorIn = mix(float4(0.0), texel1, texel0);\n"
|
|
||||||
" colorIn.rgb += lu.daddColor.rgb;\n" FOG_ALGORITHM_METAL
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
static std::string_view ThermalColdPostMetal =
|
|
||||||
"static float4 ThermalColdPostFunc(thread VertToFrag& vtf, float4 colorIn)\n"
|
|
||||||
"{\n"
|
|
||||||
" return colorIn * float4(0.75, 0.75, 0.75, 0.75);\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"sv;
|
|
||||||
|
|
||||||
const hecl::Backend::Function ExtensionLightingFuncsMetal[] = {{},
|
|
||||||
{LightingMetal, "LightingFunc"},
|
|
||||||
{},
|
|
||||||
{LightingMetal, "LightingFunc"},
|
|
||||||
{LightingMetal, "LightingFunc"},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{LightingShadowMetal, "EXTLightingShadowFunc"},
|
|
||||||
{LightingMetal, "LightingFunc"},
|
|
||||||
{LightingMetal, "LightingFunc"},
|
|
||||||
{LightingMetal, "LightingFunc"},
|
|
||||||
{LightingMetal, "LightingFunc"},
|
|
||||||
{LightingMetal, "LightingFunc"},
|
|
||||||
{LightingMetal, "LightingFunc"},
|
|
||||||
{LightingMetal, "LightingFunc"},
|
|
||||||
{},
|
|
||||||
{LightingMetal, "LightingFunc"},
|
|
||||||
{},
|
|
||||||
{LightingMetal, "LightingFunc"},};
|
|
||||||
|
|
||||||
const hecl::Backend::Function ExtensionPostFuncsMetal[] = {
|
|
||||||
{},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
{ThermalPostMetal, "EXTThermalPostFunc"},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
{SolidPostMetal, "SolidPostFunc"},
|
|
||||||
{SolidPostMetal, "SolidPostFunc"},
|
|
||||||
{SolidPostMetal, "SolidPostFunc"},
|
|
||||||
{SolidPostMetal, "SolidPostFunc"},
|
|
||||||
{SolidPostMetal, "SolidPostFunc"},
|
|
||||||
{SolidPostMetal, "SolidPostFunc"},
|
|
||||||
{MBShadowPostMetal, "EXTMBShadowPostFunc"},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
{DisintegratePostMetal, "EXTDisintegratePostFunc"},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
{ThermalColdPostMetal, "ThermalColdPostFunc"},
|
|
||||||
{MainPostMetal, "MainPostFunc"},
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace urde
|
|
|
@ -1,11 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GCNTypes.hpp"
|
#include "GCNTypes.hpp"
|
||||||
#include <athena/IStreamReader.hpp>
|
#include "athena/IStreamReader.hpp"
|
||||||
#include <athena/IStreamWriter.hpp>
|
#include "athena/IStreamWriter.hpp"
|
||||||
#include <athena/MemoryReader.hpp>
|
#include "athena/MemoryReader.hpp"
|
||||||
#include <athena/MemoryWriter.hpp>
|
#include "athena/MemoryWriter.hpp"
|
||||||
|
#ifdef URDE_ZIP_INPUT_STREAM
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
using CInputStream = athena::io::IStreamReader;
|
using CInputStream = athena::io::IStreamReader;
|
||||||
|
@ -50,6 +52,7 @@ public:
|
||||||
using CMemoryInStream = athena::io::MemoryReader;
|
using CMemoryInStream = athena::io::MemoryReader;
|
||||||
using CMemoryOutStream = athena::io::MemoryWriter;
|
using CMemoryOutStream = athena::io::MemoryWriter;
|
||||||
|
|
||||||
|
#ifdef URDE_ZIP_INPUT_STREAM
|
||||||
class CZipInputStream : public CInputStream {
|
class CZipInputStream : public CInputStream {
|
||||||
std::unique_ptr<u8[]> x24_compBuf;
|
std::unique_ptr<u8[]> x24_compBuf;
|
||||||
std::unique_ptr<CInputStream> x28_strm;
|
std::unique_ptr<CInputStream> x28_strm;
|
||||||
|
@ -63,5 +66,6 @@ public:
|
||||||
atUint64 position() const { return 0; }
|
atUint64 position() const { return 0; }
|
||||||
atUint64 length() const { return 0; }
|
atUint64 length() const { return 0; }
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -1081,7 +1081,7 @@ void CGameArea::FillInStaticGeometry(bool textures) {
|
||||||
|
|
||||||
TToken<CModel> nullModel;
|
TToken<CModel> nullModel;
|
||||||
inst.m_instance = std::make_unique<CBooModel>(nullModel, nullptr, &inst.m_surfaces, matSet, vbo, ibo,
|
inst.m_instance = std::make_unique<CBooModel>(nullModel, nullptr, &inst.m_surfaces, matSet, vbo, ibo,
|
||||||
inst.x34_aabb, inst.x0_visorFlags, 0, nullptr);
|
inst.x34_aabb, inst.x0_visorFlags, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -138,7 +138,7 @@ void CScriptPickup::Touch(CActor& act, CStateManager& mgr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mgr.GetPlayerState()->InitializePowerUp(x258_itemType, x260_capacity);
|
mgr.GetPlayerState()->AddPowerUp(x258_itemType, x260_capacity);
|
||||||
mgr.GetPlayerState()->IncrPickup(x258_itemType, x25c_amount);
|
mgr.GetPlayerState()->IncrPickup(x258_itemType, x25c_amount);
|
||||||
mgr.FreeScriptObject(GetUniqueId());
|
mgr.FreeScriptObject(GetUniqueId());
|
||||||
SendScriptMsgs(EScriptObjectState::Arrived, mgr, EScriptObjectMessage::None);
|
SendScriptMsgs(EScriptObjectState::Arrived, mgr, EScriptObjectMessage::None);
|
||||||
|
|
|
@ -19,7 +19,7 @@ void CScriptPlayerStateChange::Accept(IVisitor& visitor) { visitor.Visit(this);
|
||||||
|
|
||||||
void CScriptPlayerStateChange::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) {
|
void CScriptPlayerStateChange::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) {
|
||||||
if (GetActive() && msg == EScriptObjectMessage::SetToZero) {
|
if (GetActive() && msg == EScriptObjectMessage::SetToZero) {
|
||||||
stateMgr.GetPlayerState()->InitializePowerUp(CPlayerState::EItemType(x34_itemType), x3c_itemCapacity);
|
stateMgr.GetPlayerState()->AddPowerUp(CPlayerState::EItemType(x34_itemType), x3c_itemCapacity);
|
||||||
stateMgr.GetPlayerState()->IncrPickup(CPlayerState::EItemType(x34_itemType), x38_itemCount);
|
stateMgr.GetPlayerState()->IncrPickup(CPlayerState::EItemType(x34_itemType), x38_itemCount);
|
||||||
|
|
||||||
if (x44_ctrlCmdOpt == EControlCommandOption::Filtered && x40_ctrl == EControl::Filtered) {
|
if (x44_ctrlCmdOpt == EControlCommandOption::Filtered && x40_ctrl == EControl::Filtered) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ include_directories(../hecl/include
|
||||||
../hecl/extern/boo/include
|
../hecl/extern/boo/include
|
||||||
../hecl/extern/boo/logvisor/include
|
../hecl/extern/boo/logvisor/include
|
||||||
../hecl/extern/athena/include
|
../hecl/extern/athena/include
|
||||||
../specter/zeus/include
|
../DataSpec
|
||||||
../Runtime)
|
../Runtime)
|
||||||
add_shader(CAABoxShader)
|
add_shader(CAABoxShader)
|
||||||
add_shader(CCameraBlurFilter)
|
add_shader(CCameraBlurFilter)
|
||||||
|
@ -35,3 +35,7 @@ add_special_shader(shader_CFluidPlaneShader
|
||||||
shader_CFluidPlaneShaderGLSL.cpp
|
shader_CFluidPlaneShaderGLSL.cpp
|
||||||
shader_CFluidPlaneShaderHLSL.cpp
|
shader_CFluidPlaneShaderHLSL.cpp
|
||||||
shader_CFluidPlaneShaderMetal.cpp)
|
shader_CFluidPlaneShaderMetal.cpp)
|
||||||
|
add_special_shader(shader_CModelShaders
|
||||||
|
shader_CModelShadersGLSL.cpp
|
||||||
|
shader_CModelShadersHLSL.cpp
|
||||||
|
shader_CModelShadersMetal.cpp)
|
|
@ -0,0 +1,16 @@
|
||||||
|
#extension GL_ARB_shader_image_load_store: enable
|
||||||
|
|
||||||
|
struct VertToFrag {
|
||||||
|
vec4 mvPos;
|
||||||
|
vec4 mvNorm;
|
||||||
|
vec2 lightmapUv;
|
||||||
|
vec2 diffuseUv;
|
||||||
|
vec2 emissiveUv;
|
||||||
|
vec2 specularUv;
|
||||||
|
vec2 extendedSpecularUv;
|
||||||
|
vec2 reflectionUv;
|
||||||
|
vec2 alphaUv;
|
||||||
|
vec2 extUvs[3];
|
||||||
|
vec2 dynReflectionUvs[2];
|
||||||
|
float dynReflectionAlpha;
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
struct VertToFrag {
|
||||||
|
float4 mvpPos : SV_Position;
|
||||||
|
float4 mvPos : POSITION;
|
||||||
|
float4 mvNorm : NORMAL;
|
||||||
|
float2 lightmapUv : UV0;
|
||||||
|
float2 diffuseUv : UV1;
|
||||||
|
float2 emissiveUv : UV2;
|
||||||
|
float2 specularUv : UV3;
|
||||||
|
float2 extendedSpecularUv : UV4;
|
||||||
|
float2 reflectionUv : UV5;
|
||||||
|
float2 alphaUv : UV6;
|
||||||
|
float2 extUvs[3] : EXTUV;
|
||||||
|
float2 dynReflectionUvs[2] : REFLECTUV;
|
||||||
|
float dynReflectionAlpha : REFLECTALPHA;
|
||||||
|
};
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include <metal_stdlib>
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct VertToFrag {
|
||||||
|
float4 mvpPos [[ position ]];
|
||||||
|
float4 mvPos;
|
||||||
|
float4 mvNorm;
|
||||||
|
float2 lightmapUv;
|
||||||
|
float2 diffuseUv;
|
||||||
|
float2 emissiveUv;
|
||||||
|
float2 specularUv;
|
||||||
|
float2 extendedSpecularUv;
|
||||||
|
float2 reflectionUv;
|
||||||
|
float2 alphaUv;
|
||||||
|
float2 extUvs0;
|
||||||
|
float2 extUvs1;
|
||||||
|
float2 extUvs2;
|
||||||
|
float2 dynReflectionUvs0;
|
||||||
|
float2 dynReflectionUvs1;
|
||||||
|
float dynReflectionAlpha;
|
||||||
|
};
|
|
@ -0,0 +1,348 @@
|
||||||
|
#if !defined(URDE_ALPHA_TEST) && defined(GL_ARB_shader_image_load_store)
|
||||||
|
layout(early_fragment_tests) in;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SBINDING(0) in VertToFrag vtf;
|
||||||
|
TBINDING0 uniform sampler2D lightmap;
|
||||||
|
TBINDING1 uniform sampler2D diffuse;
|
||||||
|
TBINDING2 uniform sampler2D emissive;
|
||||||
|
TBINDING3 uniform sampler2D specular;
|
||||||
|
TBINDING4 uniform sampler2D extendedSpecular;
|
||||||
|
TBINDING5 uniform sampler2D reflection;
|
||||||
|
TBINDING6 uniform sampler2D alpha;
|
||||||
|
TBINDING7 uniform sampler2D reflectionIndTex;
|
||||||
|
TBINDING8 uniform sampler2D extTex0;
|
||||||
|
TBINDING9 uniform sampler2D extTex1;
|
||||||
|
TBINDING10 uniform sampler2D extTex2;
|
||||||
|
TBINDING11 uniform sampler2D reflectionTex;
|
||||||
|
|
||||||
|
const vec3 kRGBToYPrime = vec3(0.257, 0.504, 0.098);
|
||||||
|
|
||||||
|
/*
|
||||||
|
#if defined(ALPHA_%s)
|
||||||
|
vec3 SampleTexture_%s() { return texture(%s, vtf.%sUv).aaa; }
|
||||||
|
float SampleTextureAlpha_%s() { return texture(%s, vtf.%sUv).a; }
|
||||||
|
#else
|
||||||
|
vec3 SampleTexture_%s() { return texture(%s, vtf.%sUv).rgb; }
|
||||||
|
float SampleTextureAlpha_%s() { return dot(texture(%s, vtf.%sUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(ALPHA_lightmap)
|
||||||
|
vec3 SampleTexture_lightmap() { return texture(lightmap, vtf.lightmapUv).aaa; }
|
||||||
|
float SampleTextureAlpha_lightmap() { return texture(lightmap, vtf.lightmapUv).a; }
|
||||||
|
#else
|
||||||
|
vec3 SampleTexture_lightmap() { return texture(lightmap, vtf.lightmapUv).rgb; }
|
||||||
|
float SampleTextureAlpha_lightmap() { return dot(texture(lightmap, vtf.lightmapUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_diffuse)
|
||||||
|
vec3 SampleTexture_diffuse() { return texture(diffuse, vtf.diffuseUv).aaa; }
|
||||||
|
float SampleTextureAlpha_diffuse() { return texture(diffuse, vtf.diffuseUv).a; }
|
||||||
|
#else
|
||||||
|
vec3 SampleTexture_diffuse() { return texture(diffuse, vtf.diffuseUv).rgb; }
|
||||||
|
float SampleTextureAlpha_diffuse() { return dot(texture(diffuse, vtf.diffuseUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_emissive)
|
||||||
|
vec3 SampleTexture_emissive() { return texture(emissive, vtf.emissiveUv).aaa; }
|
||||||
|
float SampleTextureAlpha_emissive() { return texture(emissive, vtf.emissiveUv).a; }
|
||||||
|
#else
|
||||||
|
vec3 SampleTexture_emissive() { return texture(emissive, vtf.emissiveUv).rgb; }
|
||||||
|
float SampleTextureAlpha_emissive() { return dot(texture(emissive, vtf.emissiveUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_specular)
|
||||||
|
vec3 SampleTexture_specular() { return texture(specular, vtf.specularUv).aaa; }
|
||||||
|
float SampleTextureAlpha_specular() { return texture(specular, vtf.specularUv).a; }
|
||||||
|
#else
|
||||||
|
vec3 SampleTexture_specular() { return texture(specular, vtf.specularUv).rgb; }
|
||||||
|
float SampleTextureAlpha_specular() { return dot(texture(specular, vtf.specularUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_extendedSpecular)
|
||||||
|
vec3 SampleTexture_extendedSpecular() { return texture(extendedSpecular, vtf.extendedSpecularUv).aaa; }
|
||||||
|
float SampleTextureAlpha_extendedSpecular() { return texture(extendedSpecular, vtf.extendedSpecularUv).a; }
|
||||||
|
#else
|
||||||
|
vec3 SampleTexture_extendedSpecular() { return texture(extendedSpecular, vtf.extendedSpecularUv).rgb; }
|
||||||
|
float SampleTextureAlpha_extendedSpecular() { return dot(texture(extendedSpecular, vtf.extendedSpecularUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_reflection)
|
||||||
|
vec3 SampleTexture_reflection() { return texture(reflection, vtf.reflectionUv).aaa; }
|
||||||
|
float SampleTextureAlpha_reflection() { return texture(reflection, vtf.reflectionUv).a; }
|
||||||
|
#else
|
||||||
|
vec3 SampleTexture_reflection() { return texture(reflection, vtf.reflectionUv).rgb; }
|
||||||
|
float SampleTextureAlpha_reflection() { return dot(texture(reflection, vtf.reflectionUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_alpha)
|
||||||
|
vec3 SampleTexture_alpha() { return texture(alpha, vtf.alphaUv).aaa; }
|
||||||
|
float SampleTextureAlpha_alpha() { return texture(alpha, vtf.alphaUv).a; }
|
||||||
|
#else
|
||||||
|
vec3 SampleTexture_alpha() { return texture(alpha, vtf.alphaUv).rgb; }
|
||||||
|
float SampleTextureAlpha_alpha() { return dot(texture(alpha, vtf.alphaUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW) || defined(URDE_DISINTEGRATE)
|
||||||
|
struct Fog {
|
||||||
|
vec4 color;
|
||||||
|
float A;
|
||||||
|
float B;
|
||||||
|
float C;
|
||||||
|
int mode;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW)
|
||||||
|
struct Light {
|
||||||
|
vec4 pos;
|
||||||
|
vec4 dir;
|
||||||
|
vec4 color;
|
||||||
|
vec4 linAtt;
|
||||||
|
vec4 angAtt;
|
||||||
|
};
|
||||||
|
|
||||||
|
UBINDING2 uniform LightingUniform {
|
||||||
|
Light lights[URDE_MAX_LIGHTS];
|
||||||
|
vec4 ambient;
|
||||||
|
vec4 colorReg0;
|
||||||
|
vec4 colorReg1;
|
||||||
|
vec4 colorReg2;
|
||||||
|
vec4 mulColor;
|
||||||
|
vec4 addColor;
|
||||||
|
Fog fog;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
const vec4 colorReg0 = vec4(1.0);
|
||||||
|
const vec4 colorReg1 = vec4(1.0);
|
||||||
|
const vec4 colorReg2 = vec4(1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING)
|
||||||
|
vec3 LightingFunc() {
|
||||||
|
vec4 ret = ambient;
|
||||||
|
|
||||||
|
for (int i = 0; i < URDE_MAX_LIGHTS; ++i) {
|
||||||
|
vec3 delta = vtf.mvPos.xyz - lights[i].pos.xyz;
|
||||||
|
float dist = length(delta);
|
||||||
|
vec3 deltaNorm = delta / dist;
|
||||||
|
float angDot = max(dot(deltaNorm, lights[i].dir.xyz), 0.0);
|
||||||
|
float att = 1.0 / (lights[i].linAtt[2] * dist * dist +
|
||||||
|
lights[i].linAtt[1] * dist +
|
||||||
|
lights[i].linAtt[0]);
|
||||||
|
float angAtt = lights[i].angAtt[2] * angDot * angDot +
|
||||||
|
lights[i].angAtt[1] * angDot +
|
||||||
|
lights[i].angAtt[0];
|
||||||
|
ret += lights[i].color * angAtt * att * max(dot(-deltaNorm, vtf.mvNorm.xyz), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return clamp(ret.rgb, vec3(0.0), vec3(1.0));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_THERMAL_HOT)
|
||||||
|
vec3 LightingFunc() {
|
||||||
|
return vec3(1.0);
|
||||||
|
}
|
||||||
|
UBINDING2 uniform ThermalUniform {
|
||||||
|
vec4 tmulColor;
|
||||||
|
vec4 taddColor;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_THERMAL_COLD)
|
||||||
|
vec3 LightingFunc() {
|
||||||
|
return vec3(1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_SOLID)
|
||||||
|
vec3 LightingFunc() {
|
||||||
|
return vec3(1.0);
|
||||||
|
}
|
||||||
|
UBINDING2 uniform SolidUniform {
|
||||||
|
vec4 solidColor;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_MB_SHADOW)
|
||||||
|
vec3 LightingFunc() {
|
||||||
|
return vec3(1.0);
|
||||||
|
}
|
||||||
|
UBINDING2 uniform MBShadowUniform {
|
||||||
|
vec4 shadowUp;
|
||||||
|
float shadowId;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING_SHADOW)
|
||||||
|
vec3 LightingFunc() {
|
||||||
|
vec2 shadowUV = vtf.extUvs[0];
|
||||||
|
shadowUV.y = 1.0 - shadowUV.y;
|
||||||
|
|
||||||
|
vec4 ret = ambient;
|
||||||
|
|
||||||
|
vec3 delta = vtf.mvPos.xyz - lights[0].pos.xyz;
|
||||||
|
float dist = length(delta);
|
||||||
|
vec3 deltaNorm = delta / dist;
|
||||||
|
float angDot = max(dot(deltaNorm, lights[0].dir.xyz), 0.0);
|
||||||
|
float att = 1.0 / (lights[0].linAtt[2] * dist * dist +
|
||||||
|
lights[0].linAtt[1] * dist +
|
||||||
|
lights[0].linAtt[0]);
|
||||||
|
float angAtt = lights[0].angAtt[2] * angDot * angDot +
|
||||||
|
lights[0].angAtt[1] * angDot +
|
||||||
|
lights[0].angAtt[0];
|
||||||
|
ret += lights[0].color * angAtt * att * max(dot(-deltaNorm, vtf.mvNorm.xyz), 0.0) *
|
||||||
|
texture(extTex0, shadowUV).r;
|
||||||
|
|
||||||
|
for (int i = 1; i < URDE_MAX_LIGHTS; ++i) {
|
||||||
|
vec3 delta = vtf.mvPos.xyz - lights[i].pos.xyz;
|
||||||
|
float dist = length(delta);
|
||||||
|
vec3 deltaNorm = delta / dist;
|
||||||
|
float angDot = max(dot(deltaNorm, lights[i].dir.xyz), 0.0);
|
||||||
|
float att = 1.0 / (lights[i].linAtt[2] * dist * dist +
|
||||||
|
lights[i].linAtt[1] * dist +
|
||||||
|
lights[i].linAtt[0]);
|
||||||
|
float angAtt = lights[i].angAtt[2] * angDot * angDot +
|
||||||
|
lights[i].angAtt[1] * angDot +
|
||||||
|
lights[i].angAtt[0];
|
||||||
|
ret += lights[i].color * angAtt * att * max(dot(-deltaNorm, vtf.mvNorm.xyz), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return clamp(ret.rgb, vec3(0.0), vec3(1.0));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_DISINTEGRATE)
|
||||||
|
UBINDING2 uniform DisintegrateUniform {
|
||||||
|
vec4 daddColor;
|
||||||
|
Fog fog;
|
||||||
|
};
|
||||||
|
vec3 LightingFunc() {
|
||||||
|
return vec3(1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW) || defined(URDE_DISINTEGRATE)
|
||||||
|
vec4 FogFunc(vec4 colorIn) {
|
||||||
|
float fogZ;
|
||||||
|
float fogF = clamp((fog.A / (fog.B - gl_FragCoord.z)) - fog.C, 0.0, 1.0);
|
||||||
|
switch (fog.mode) {
|
||||||
|
case 2:
|
||||||
|
fogZ = fogF;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
fogZ = 1.0 - exp2(-8.0 * fogF);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
fogZ = 1.0 - exp2(-8.0 * fogF * fogF);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
fogZ = exp2(-8.0 * (1.0 - fogF));
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
fogF = 1.0 - fogF;
|
||||||
|
fogZ = exp2(-8.0 * fogF * fogF);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fogZ = 0.0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef BLEND_DST_ONE
|
||||||
|
return vec4(mix(colorIn, vec4(0.0), clamp(fogZ, 0.0, 1.0)).rgb, colorIn.a);
|
||||||
|
#else
|
||||||
|
return vec4(mix(colorIn, fog.color, clamp(fogZ, 0.0, 1.0)).rgb, colorIn.a);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW)
|
||||||
|
vec4 PostFunc(vec4 colorIn) {
|
||||||
|
return FogFunc(colorIn) * mulColor + addColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_THERMAL_HOT)
|
||||||
|
vec4 PostFunc(vec4 colorIn) {
|
||||||
|
return texture(extTex0, vtf.extUvs[0]).rrrr * tmulColor + taddColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_THERMAL_COLD)
|
||||||
|
vec4 PostFunc(vec4 colorIn) {
|
||||||
|
return colorIn * vec4(0.75);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_SOLID)
|
||||||
|
vec4 PostFunc(vec4 colorIn) {
|
||||||
|
return solidColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_MB_SHADOW)
|
||||||
|
vec4 PostFunc(vec4 colorIn) {
|
||||||
|
float idTexel = texture(extTex0, vtf.extUvs[0]).a;
|
||||||
|
float sphereTexel = texture(extTex1, vtf.extUvs[1]).a;
|
||||||
|
float fadeTexel = texture(extTex2, vtf.extUvs[2]).a;
|
||||||
|
float val = ((abs(idTexel - shadowId) < 0.001) ?
|
||||||
|
(dot(vtf.mvNorm.xyz, shadowUp.xyz) * shadowUp.w) : 0.0) *
|
||||||
|
sphereTexel * fadeTexel;
|
||||||
|
return vec4(0.0, 0.0, 0.0, val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_DISINTEGRATE)
|
||||||
|
vec4 PostFunc(vec4 colorIn) {
|
||||||
|
vec4 texel0 = texture(extTex0, vtf.extUvs[0]);
|
||||||
|
vec4 texel1 = texture(extTex0, vtf.extUvs[1]);
|
||||||
|
colorIn = mix(vec4(0.0), texel1, texel0);
|
||||||
|
colorIn.rgb += daddColor.rgb;
|
||||||
|
return FogFunc(colorIn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_REFLECTION_SIMPLE)
|
||||||
|
vec3 ReflectionFunc() { return texture(reflectionTex, vtf.dynReflectionUvs[1]).rgb * vtf.dynReflectionAlpha; }
|
||||||
|
#elif defined(URDE_REFLECTION_INDIRECT)
|
||||||
|
vec3 ReflectionFunc() { return texture(reflectionTex, (texture(reflectionIndTex, vtf.dynReflectionUvs[0]).ab -
|
||||||
|
vec2(0.5, 0.5)) * vec2(0.5, 0.5) + vtf.dynReflectionUvs[1]).rgb * vtf.dynReflectionAlpha; }
|
||||||
|
#else
|
||||||
|
vec3 ReflectionFunc() { return vec3(0.0); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
layout(location=0) out vec4 colorOut;
|
||||||
|
void main() {
|
||||||
|
vec3 lighting = LightingFunc();
|
||||||
|
vec4 tmp;
|
||||||
|
#if defined(URDE_DIFFUSE_ONLY)
|
||||||
|
tmp.rgb = SampleTexture_diffuse();
|
||||||
|
tmp.a = SampleTextureAlpha_alpha();
|
||||||
|
#elif defined(RETRO_SHADER)
|
||||||
|
tmp.rgb = (SampleTexture_lightmap() * colorReg1.rgb + lighting) * SampleTexture_diffuse() +
|
||||||
|
SampleTexture_emissive() + (SampleTexture_specular() + SampleTexture_extendedSpecular() * lighting) *
|
||||||
|
SampleTexture_reflection() + ReflectionFunc();
|
||||||
|
tmp.a = SampleTextureAlpha_alpha();
|
||||||
|
#elif defined(RETRO_DYNAMIC_SHADER)
|
||||||
|
tmp.rgb = (SampleTexture_lightmap() * colorReg1.rgb + lighting) * SampleTexture_diffuse() * colorReg1.rgb +
|
||||||
|
SampleTexture_emissive() * colorReg1.rgb + (SampleTexture_specular() + SampleTexture_extendedSpecular() * lighting) *
|
||||||
|
SampleTexture_reflection() + ReflectionFunc();
|
||||||
|
tmp.a = SampleTextureAlpha_alpha();
|
||||||
|
#elif defined(RETRO_DYNAMIC_ALPHA_SHADER)
|
||||||
|
tmp.rgb = (SampleTexture_lightmap() * colorReg1.rgb + lighting) * SampleTexture_diffuse() * colorReg1.rgb +
|
||||||
|
SampleTexture_emissive() * colorReg1.rgb + (SampleTexture_specular() + SampleTexture_extendedSpecular() * lighting) *
|
||||||
|
SampleTexture_reflection() + ReflectionFunc();
|
||||||
|
tmp.a = SampleTextureAlpha_alpha() * colorReg1.a;
|
||||||
|
#elif defined(RETRO_DYNAMIC_CHARACTER_SHADER)
|
||||||
|
tmp.rgb = (SampleTexture_lightmap() + lighting) * SampleTexture_diffuse() +
|
||||||
|
SampleTexture_emissive() * colorReg1.rgb + (SampleTexture_specular() + SampleTexture_extendedSpecular() * lighting) *
|
||||||
|
SampleTexture_reflection() + ReflectionFunc();
|
||||||
|
tmp.a = SampleTextureAlpha_alpha();
|
||||||
|
#endif
|
||||||
|
colorOut = PostFunc(tmp);
|
||||||
|
#if defined(URDE_ALPHA_TEST)
|
||||||
|
if (colorOut.a < 0.25)
|
||||||
|
discard;
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,351 @@
|
||||||
|
SamplerState samp : register(s0);
|
||||||
|
SamplerState clampSamp : register(s1);
|
||||||
|
SamplerState reflectSamp : register(s2);
|
||||||
|
Texture2D lightmap : register(t0);
|
||||||
|
Texture2D diffuse : register(t1);
|
||||||
|
Texture2D emissive : register(t2);
|
||||||
|
Texture2D specular : register(t3);
|
||||||
|
Texture2D extendedSpecular : register(t4);
|
||||||
|
Texture2D reflection : register(t5);
|
||||||
|
Texture2D alpha : register(t6);
|
||||||
|
Texture2D reflectionIndTex : register(t7);
|
||||||
|
Texture2D extTex0 : register(t8);
|
||||||
|
Texture2D extTex1 : register(t9);
|
||||||
|
Texture2D extTex2 : register(t10);
|
||||||
|
Texture2D reflectionTex : register(t11);
|
||||||
|
|
||||||
|
static const float3 kRGBToYPrime = float3(0.257, 0.504, 0.098);
|
||||||
|
|
||||||
|
/*
|
||||||
|
#if defined(ALPHA_%s)
|
||||||
|
float3 SampleTexture_%s(in VertToFrag vtf) { return %s.Sample(samp, vtf.%sUv).aaa; }
|
||||||
|
float SampleTextureAlpha_%s(in VertToFrag vtf) { return %s.Sample(samp, vtf.%sUv).a; }
|
||||||
|
#else
|
||||||
|
float3 SampleTexture_%s(in VertToFrag vtf) { return %s.Sample(samp, vtf.%sUv).rgb; }
|
||||||
|
float SampleTextureAlpha_%s(in VertToFrag vtf) { return dot(%s.Sample(samp, vtf.%sUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(ALPHA_lightmap)
|
||||||
|
float3 SampleTexture_lightmap(in VertToFrag vtf) { return lightmap.Sample(samp, vtf.lightmapUv).aaa; }
|
||||||
|
float SampleTextureAlpha_lightmap(in VertToFrag vtf) { return lightmap.Sample(samp, vtf.lightmapUv).a; }
|
||||||
|
#else
|
||||||
|
float3 SampleTexture_lightmap(in VertToFrag vtf) { return lightmap.Sample(samp, vtf.lightmapUv).rgb; }
|
||||||
|
float SampleTextureAlpha_lightmap(in VertToFrag vtf) { return dot(lightmap.Sample(samp, vtf.lightmapUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_diffuse)
|
||||||
|
float3 SampleTexture_diffuse(in VertToFrag vtf) { return diffuse.Sample(samp, vtf.diffuseUv).aaa; }
|
||||||
|
float SampleTextureAlpha_diffuse(in VertToFrag vtf) { return diffuse.Sample(samp, vtf.diffuseUv).a; }
|
||||||
|
#else
|
||||||
|
float3 SampleTexture_diffuse(in VertToFrag vtf) { return diffuse.Sample(samp, vtf.diffuseUv).rgb; }
|
||||||
|
float SampleTextureAlpha_diffuse(in VertToFrag vtf) { return dot(diffuse.Sample(samp, vtf.diffuseUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_emissive)
|
||||||
|
float3 SampleTexture_emissive(in VertToFrag vtf) { return emissive.Sample(samp, vtf.emissiveUv).aaa; }
|
||||||
|
float SampleTextureAlpha_emissive(in VertToFrag vtf) { return emissive.Sample(samp, vtf.emissiveUv).a; }
|
||||||
|
#else
|
||||||
|
float3 SampleTexture_emissive(in VertToFrag vtf) { return emissive.Sample(samp, vtf.emissiveUv).rgb; }
|
||||||
|
float SampleTextureAlpha_emissive(in VertToFrag vtf) { return dot(emissive.Sample(samp, vtf.emissiveUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_specular)
|
||||||
|
float3 SampleTexture_specular(in VertToFrag vtf) { return specular.Sample(samp, vtf.specularUv).aaa; }
|
||||||
|
float SampleTextureAlpha_specular(in VertToFrag vtf) { return specular.Sample(samp, vtf.specularUv).a; }
|
||||||
|
#else
|
||||||
|
float3 SampleTexture_specular(in VertToFrag vtf) { return specular.Sample(samp, vtf.specularUv).rgb; }
|
||||||
|
float SampleTextureAlpha_specular(in VertToFrag vtf) { return dot(specular.Sample(samp, vtf.specularUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_extendedSpecular)
|
||||||
|
float3 SampleTexture_extendedSpecular(in VertToFrag vtf) { return extendedSpecular.Sample(samp, vtf.extendedSpecularUv).aaa; }
|
||||||
|
float SampleTextureAlpha_extendedSpecular(in VertToFrag vtf) { return extendedSpecular.Sample(samp, vtf.extendedSpecularUv).a; }
|
||||||
|
#else
|
||||||
|
float3 SampleTexture_extendedSpecular(in VertToFrag vtf) { return extendedSpecular.Sample(samp, vtf.extendedSpecularUv).rgb; }
|
||||||
|
float SampleTextureAlpha_extendedSpecular(in VertToFrag vtf) { return dot(extendedSpecular.Sample(samp, vtf.extendedSpecularUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_reflection)
|
||||||
|
float3 SampleTexture_reflection(in VertToFrag vtf) { return reflection.Sample(samp, vtf.reflectionUv).aaa; }
|
||||||
|
float SampleTextureAlpha_reflection(in VertToFrag vtf) { return reflection.Sample(samp, vtf.reflectionUv).a; }
|
||||||
|
#else
|
||||||
|
float3 SampleTexture_reflection(in VertToFrag vtf) { return reflection.Sample(samp, vtf.reflectionUv).rgb; }
|
||||||
|
float SampleTextureAlpha_reflection(in VertToFrag vtf) { return dot(reflection.Sample(samp, vtf.reflectionUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_alpha)
|
||||||
|
float3 SampleTexture_alpha(in VertToFrag vtf) { return alpha.Sample(samp, vtf.alphaUv).aaa; }
|
||||||
|
float SampleTextureAlpha_alpha(in VertToFrag vtf) { return alpha.Sample(samp, vtf.alphaUv).a; }
|
||||||
|
#else
|
||||||
|
float3 SampleTexture_alpha(in VertToFrag vtf) { return alpha.Sample(samp, vtf.alphaUv).rgb; }
|
||||||
|
float SampleTextureAlpha_alpha(in VertToFrag vtf) { return dot(alpha.Sample(samp, vtf.alphaUv).rgb, kRGBToYPrime); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW) || defined(URDE_DISINTEGRATE)
|
||||||
|
struct Fog {
|
||||||
|
float4 color;
|
||||||
|
float A;
|
||||||
|
float B;
|
||||||
|
float C;
|
||||||
|
int mode;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW)
|
||||||
|
struct Light {
|
||||||
|
float4 pos;
|
||||||
|
float4 dir;
|
||||||
|
float4 color;
|
||||||
|
float4 linAtt;
|
||||||
|
float4 angAtt;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer LightingUniform : register(b2) {
|
||||||
|
Light lights[URDE_MAX_LIGHTS];
|
||||||
|
float4 ambient;
|
||||||
|
float4 colorReg0;
|
||||||
|
float4 colorReg1;
|
||||||
|
float4 colorReg2;
|
||||||
|
float4 mulColor;
|
||||||
|
float4 addColor;
|
||||||
|
Fog fog;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
static const float4 colorReg0 = float4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
static const float4 colorReg1 = float4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
static const float4 colorReg2 = float4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING)
|
||||||
|
float3 LightingFunc(in VertToFrag vtf) {
|
||||||
|
float4 ret = ambient;
|
||||||
|
|
||||||
|
for (int i = 0; i < URDE_MAX_LIGHTS; ++i) {
|
||||||
|
float3 delta = vtf.mvPos.xyz - lights[i].pos.xyz;
|
||||||
|
float dist = length(delta);
|
||||||
|
float3 deltaNorm = delta / dist;
|
||||||
|
float angDot = max(dot(deltaNorm, lights[i].dir.xyz), 0.0);
|
||||||
|
float att = 1.0 / (lights[i].linAtt[2] * dist * dist +
|
||||||
|
lights[i].linAtt[1] * dist +
|
||||||
|
lights[i].linAtt[0]);
|
||||||
|
float angAtt = lights[i].angAtt[2] * angDot * angDot +
|
||||||
|
lights[i].angAtt[1] * angDot +
|
||||||
|
lights[i].angAtt[0];
|
||||||
|
ret += lights[i].color * angAtt * att * max(dot(-deltaNorm, vtf.mvNorm.xyz), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return saturate(ret.rgb);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_THERMAL_HOT)
|
||||||
|
float3 LightingFunc(in VertToFrag vtf) {
|
||||||
|
return float3(1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
cbuffer ThermalUniform : register(b2) {
|
||||||
|
float4 tmulColor;
|
||||||
|
float4 taddColor;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_THERMAL_COLD)
|
||||||
|
float3 LightingFunc(in VertToFrag vtf) {
|
||||||
|
return float3(1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_SOLID)
|
||||||
|
float3 LightingFunc(in VertToFrag vtf) {
|
||||||
|
return float3(1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
cbuffer SolidUniform : register(b2) {
|
||||||
|
float4 solidColor;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_MB_SHADOW)
|
||||||
|
float3 LightingFunc(in VertToFrag vtf) {
|
||||||
|
return float3(1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
cbuffer MBShadowUniform : register(b2) {
|
||||||
|
float4 shadowUp;
|
||||||
|
float shadowId;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING_SHADOW)
|
||||||
|
float3 LightingFunc(in VertToFrag vtf) {
|
||||||
|
float2 shadowUV = vtf.extUvs[0];
|
||||||
|
shadowUV.y = 1.0 - shadowUV.y;
|
||||||
|
|
||||||
|
float4 ret = ambient;
|
||||||
|
|
||||||
|
float3 delta = vtf.mvPos.xyz - lights[0].pos.xyz;
|
||||||
|
float dist = length(delta);
|
||||||
|
float3 deltaNorm = delta / dist;
|
||||||
|
float angDot = max(dot(deltaNorm, lights[0].dir.xyz), 0.0);
|
||||||
|
float att = 1.0 / (lights[0].linAtt[2] * dist * dist +
|
||||||
|
lights[0].linAtt[1] * dist +
|
||||||
|
lights[0].linAtt[0]);
|
||||||
|
float angAtt = lights[0].angAtt[2] * angDot * angDot +
|
||||||
|
lights[0].angAtt[1] * angDot +
|
||||||
|
lights[0].angAtt[0];
|
||||||
|
ret += lights[0].color * angAtt * att * max(dot(-deltaNorm, vtf.mvNorm.xyz), 0.0) *
|
||||||
|
extTex0.Sample(clampSamp, shadowUV).r;
|
||||||
|
|
||||||
|
for (int i = 1; i < URDE_MAX_LIGHTS; ++i) {
|
||||||
|
float3 delta = vtf.mvPos.xyz - lights[i].pos.xyz;
|
||||||
|
float dist = length(delta);
|
||||||
|
float3 deltaNorm = delta / dist;
|
||||||
|
float angDot = max(dot(deltaNorm, lights[i].dir.xyz), 0.0);
|
||||||
|
float att = 1.0 / (lights[i].linAtt[2] * dist * dist +
|
||||||
|
lights[i].linAtt[1] * dist +
|
||||||
|
lights[i].linAtt[0]);
|
||||||
|
float angAtt = lights[i].angAtt[2] * angDot * angDot +
|
||||||
|
lights[i].angAtt[1] * angDot +
|
||||||
|
lights[i].angAtt[0];
|
||||||
|
ret += lights[i].color * angAtt * att * max(dot(-deltaNorm, vtf.mvNorm.xyz), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return saturate(ret.rgb);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_DISINTEGRATE)
|
||||||
|
cbuffer DisintegrateUniform : register(b2) {
|
||||||
|
float4 daddColor;
|
||||||
|
Fog fog;
|
||||||
|
};
|
||||||
|
float3 LightingFunc(in VertToFrag vtf) {
|
||||||
|
return float3(1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW) || defined(URDE_DISINTEGRATE)
|
||||||
|
float4 FogFunc(in VertToFrag vtf, float4 colorIn) {
|
||||||
|
float fogZ;
|
||||||
|
float fogF = saturate((fog.A / (fog.B - (1.0 - vtf.mvpPos.z))) - fog.C);
|
||||||
|
switch (fog.mode) {
|
||||||
|
case 2:
|
||||||
|
fogZ = fogF;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
fogZ = 1.0 - exp2(-8.0 * fogF);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
fogZ = 1.0 - exp2(-8.0 * fogF * fogF);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
fogZ = exp2(-8.0 * (1.0 - fogF));
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
fogF = 1.0 - fogF;
|
||||||
|
fogZ = exp2(-8.0 * fogF * fogF);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fogZ = 0.0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef BLEND_DST_ONE
|
||||||
|
return float4(lerp(colorIn, float4(0.0, 0.0, 0.0, 0.0), saturate(fogZ)).rgb, colorIn.a);
|
||||||
|
#else
|
||||||
|
return float4(lerp(colorIn, fog.color, saturate(fogZ)).rgb, colorIn.a);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW)
|
||||||
|
float4 PostFunc(in VertToFrag vtf, float4 colorIn) {
|
||||||
|
return FogFunc(vtf, colorIn) * mulColor + addColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_THERMAL_HOT)
|
||||||
|
float4 PostFunc(in VertToFrag vtf, float4 colorIn) {
|
||||||
|
return extTex0.Sample(samp, vtf.extUvs[0]).rrrr * tmulColor + taddColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_THERMAL_COLD)
|
||||||
|
float4 PostFunc(in VertToFrag vtf, float4 colorIn) {
|
||||||
|
return colorIn * float4(0.75, 0.75, 0.75, 0.75);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_SOLID)
|
||||||
|
float4 PostFunc(in VertToFrag vtf, float4 colorIn) {
|
||||||
|
return solidColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_MB_SHADOW)
|
||||||
|
float4 PostFunc(in VertToFrag vtf, float4 colorIn) {
|
||||||
|
float idTexel = extTex0.Sample(samp, vtf.extUvs[0]).a;
|
||||||
|
float sphereTexel = extTex1.Sample(samp, vtf.extUvs[1]).a;
|
||||||
|
float fadeTexel = extTex2.Sample(samp, vtf.extUvs[2]).a;
|
||||||
|
float val = ((abs(idTexel - shadowId) < 0.001) ?
|
||||||
|
(dot(vtf.mvNorm.xyz, shadowUp.xyz) * shadowUp.w) : 0.0) *
|
||||||
|
sphereTexel * fadeTexel;
|
||||||
|
return float4(0.0, 0.0, 0.0, val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_DISINTEGRATE)
|
||||||
|
float4 PostFunc(in VertToFrag vtf, float4 colorIn) {
|
||||||
|
float4 texel0 = extTex0.Sample(samp, vtf.extUvs[0]);
|
||||||
|
float4 texel1 = extTex0.Sample(samp, vtf.extUvs[1]);
|
||||||
|
colorIn = lerp(float4(0.0, 0.0, 0.0, 0.0), texel1, texel0);
|
||||||
|
colorIn.rgb += daddColor.rgb;
|
||||||
|
return FogFunc(vtf, colorIn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_REFLECTION_SIMPLE)
|
||||||
|
float3 ReflectionFunc(in VertToFrag vtf)
|
||||||
|
{ return reflectionTex.Sample(reflectSamp, vtf.dynReflectionUvs[1]).rgb * vtf.dynReflectionAlpha; }
|
||||||
|
#elif defined(URDE_REFLECTION_INDIRECT)
|
||||||
|
float3 ReflectionFunc(in VertToFrag vtf)
|
||||||
|
{ return reflectionTex.Sample(reflectSamp, (reflectionIndTex.Sample(samp, vtf.dynReflectionUvs[0]).ab -
|
||||||
|
float2(0.5, 0.5)) * float2(0.5, 0.5) + vtf.dynReflectionUvs[1]).rgb * vtf.dynReflectionAlpha; }
|
||||||
|
#else
|
||||||
|
float3 ReflectionFunc(in VertToFrag vtf) { return float3(0.0, 0.0, 0.0); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(URDE_ALPHA_TEST)
|
||||||
|
[earlydepthstencil]
|
||||||
|
#endif
|
||||||
|
float4 main(in VertToFrag vtf) : SV_Target0 {
|
||||||
|
float3 lighting = LightingFunc(vtf);
|
||||||
|
float4 tmp;
|
||||||
|
#if defined(URDE_DIFFUSE_ONLY)
|
||||||
|
tmp.rgb = SampleTexture_diffuse(vtf);
|
||||||
|
tmp.a = SampleTextureAlpha_alpha(vtf);
|
||||||
|
#elif defined(RETRO_SHADER)
|
||||||
|
tmp.rgb = (SampleTexture_lightmap(vtf) * colorReg1.rgb + lighting) * SampleTexture_diffuse(vtf) +
|
||||||
|
SampleTexture_emissive(vtf) + (SampleTexture_specular(vtf) + SampleTexture_extendedSpecular(vtf) * lighting) *
|
||||||
|
SampleTexture_reflection(vtf) + ReflectionFunc(vtf);
|
||||||
|
tmp.a = SampleTextureAlpha_alpha(vtf);
|
||||||
|
#elif defined(RETRO_DYNAMIC_SHADER)
|
||||||
|
tmp.rgb = (SampleTexture_lightmap(vtf) * colorReg1.rgb + lighting) * SampleTexture_diffuse(vtf) * colorReg1.rgb +
|
||||||
|
SampleTexture_emissive(vtf) * colorReg1.rgb + (SampleTexture_specular(vtf) + SampleTexture_extendedSpecular(vtf) * lighting) *
|
||||||
|
SampleTexture_reflection(vtf) + ReflectionFunc(vtf);
|
||||||
|
tmp.a = SampleTextureAlpha_alpha(vtf);
|
||||||
|
#elif defined(RETRO_DYNAMIC_ALPHA_SHADER)
|
||||||
|
tmp.rgb = (SampleTexture_lightmap(vtf) * colorReg1.rgb + lighting) * SampleTexture_diffuse(vtf) * colorReg1.rgb +
|
||||||
|
SampleTexture_emissive(vtf) * colorReg1.rgb + (SampleTexture_specular(vtf) + SampleTexture_extendedSpecular(vtf) * lighting) *
|
||||||
|
SampleTexture_reflection(vtf) + ReflectionFunc(vtf);
|
||||||
|
tmp.a = SampleTextureAlpha_alpha(vtf) * colorReg1.a;
|
||||||
|
#elif defined(RETRO_DYNAMIC_CHARACTER_SHADER)
|
||||||
|
tmp.rgb = (SampleTexture_lightmap(vtf) + lighting) * SampleTexture_diffuse(vtf) +
|
||||||
|
SampleTexture_emissive(vtf) * colorReg1.rgb + (SampleTexture_specular(vtf) + SampleTexture_extendedSpecular(vtf) * lighting) *
|
||||||
|
SampleTexture_reflection(vtf) + ReflectionFunc(vtf);
|
||||||
|
tmp.a = SampleTextureAlpha_alpha(vtf);
|
||||||
|
#endif
|
||||||
|
float4 colorOut = PostFunc(vtf, tmp);
|
||||||
|
#if defined(URDE_ALPHA_TEST)
|
||||||
|
if (colorOut.a < 0.25)
|
||||||
|
discard;
|
||||||
|
#endif
|
||||||
|
return colorOut;
|
||||||
|
}
|
|
@ -0,0 +1,367 @@
|
||||||
|
constant float3 kRGBToYPrime = float3(0.257, 0.504, 0.098);
|
||||||
|
|
||||||
|
/*
|
||||||
|
#if defined(ALPHA_%s)
|
||||||
|
#define SampleTexture_%s() %s.sample(samp, vtf.%sUv).aaa
|
||||||
|
#define SampleTextureAlpha_%s() %s.sample(samp, vtf.%sUv).a
|
||||||
|
#else
|
||||||
|
#define SampleTexture_%s() %s.sample(samp, vtf.%sUv).rgb
|
||||||
|
#define SampleTextureAlpha_%s() dot(%s.sample(samp, vtf.%sUv).rgb, kRGBToYPrime)
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(ALPHA_lightmap)
|
||||||
|
#define SampleTexture_lightmap() lightmap.sample(samp, vtf.lightmapUv).aaa
|
||||||
|
#define SampleTextureAlpha_lightmap() lightmap.sample(samp, vtf.lightmapUv).a
|
||||||
|
#else
|
||||||
|
#define SampleTexture_lightmap() lightmap.sample(samp, vtf.lightmapUv).rgb
|
||||||
|
#define SampleTextureAlpha_lightmap() dot(lightmap.sample(samp, vtf.lightmapUv).rgb, kRGBToYPrime)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_diffuse)
|
||||||
|
#define SampleTexture_diffuse() diffuse.sample(samp, vtf.diffuseUv).aaa
|
||||||
|
#define SampleTextureAlpha_diffuse() diffuse.sample(samp, vtf.diffuseUv).a
|
||||||
|
#else
|
||||||
|
#define SampleTexture_diffuse() diffuse.sample(samp, vtf.diffuseUv).rgb
|
||||||
|
#define SampleTextureAlpha_diffuse() dot(diffuse.sample(samp, vtf.diffuseUv).rgb, kRGBToYPrime)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_emissive)
|
||||||
|
#define SampleTexture_emissive() emissive.sample(samp, vtf.emissiveUv).aaa
|
||||||
|
#define SampleTextureAlpha_emissive() emissive.sample(samp, vtf.emissiveUv).a
|
||||||
|
#else
|
||||||
|
#define SampleTexture_emissive() emissive.sample(samp, vtf.emissiveUv).rgb
|
||||||
|
#define SampleTextureAlpha_emissive() dot(emissive.sample(samp, vtf.emissiveUv).rgb, kRGBToYPrime)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_specular)
|
||||||
|
#define SampleTexture_specular() specular.sample(samp, vtf.specularUv).aaa
|
||||||
|
#define SampleTextureAlpha_specular() specular.sample(samp, vtf.specularUv).a
|
||||||
|
#else
|
||||||
|
#define SampleTexture_specular() specular.sample(samp, vtf.specularUv).rgb
|
||||||
|
#define SampleTextureAlpha_specular() dot(specular.sample(samp, vtf.specularUv).rgb, kRGBToYPrime)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_extendedSpecular)
|
||||||
|
#define SampleTexture_extendedSpecular() extendedSpecular.sample(samp, vtf.extendedSpecularUv).aaa
|
||||||
|
#define SampleTextureAlpha_extendedSpecular() extendedSpecular.sample(samp, vtf.extendedSpecularUv).a
|
||||||
|
#else
|
||||||
|
#define SampleTexture_extendedSpecular() extendedSpecular.sample(samp, vtf.extendedSpecularUv).rgb
|
||||||
|
#define SampleTextureAlpha_extendedSpecular() dot(extendedSpecular.sample(samp, vtf.extendedSpecularUv).rgb, kRGBToYPrime)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_reflection)
|
||||||
|
#define SampleTexture_reflection() reflection.sample(samp, vtf.reflectionUv).aaa
|
||||||
|
#define SampleTextureAlpha_reflection() reflection.sample(samp, vtf.reflectionUv).a
|
||||||
|
#else
|
||||||
|
#define SampleTexture_reflection() reflection.sample(samp, vtf.reflectionUv).rgb
|
||||||
|
#define SampleTextureAlpha_reflection() dot(reflection.sample(samp, vtf.reflectionUv).rgb, kRGBToYPrime)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ALPHA_alpha)
|
||||||
|
#define SampleTexture_alpha() alpha.sample(samp, vtf.alphaUv).aaa
|
||||||
|
#define SampleTextureAlpha_alpha() alpha.sample(samp, vtf.alphaUv).a
|
||||||
|
#else
|
||||||
|
#define SampleTexture_alpha() alpha.sample(samp, vtf.alphaUv).rgb
|
||||||
|
#define SampleTextureAlpha_alpha() dot(alpha.sample(samp, vtf.alphaUv).rgb, kRGBToYPrime)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW) || defined(URDE_DISINTEGRATE)
|
||||||
|
struct Fog {
|
||||||
|
float4 color;
|
||||||
|
float A;
|
||||||
|
float B;
|
||||||
|
float C;
|
||||||
|
int mode;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW)
|
||||||
|
struct Light {
|
||||||
|
float4 pos;
|
||||||
|
float4 dir;
|
||||||
|
float4 color;
|
||||||
|
float4 linAtt;
|
||||||
|
float4 angAtt;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LightingUniform {
|
||||||
|
Light lights[URDE_MAX_LIGHTS];
|
||||||
|
float4 ambient;
|
||||||
|
float4 colorReg0;
|
||||||
|
float4 colorReg1;
|
||||||
|
float4 colorReg2;
|
||||||
|
float4 mulColor;
|
||||||
|
float4 addColor;
|
||||||
|
Fog fog;
|
||||||
|
};
|
||||||
|
#define colorReg0 lu.colorReg0
|
||||||
|
#define colorReg1 lu.colorReg1
|
||||||
|
#define colorReg2 lu.colorReg2
|
||||||
|
#else
|
||||||
|
constant float4 colorReg0 = float4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
constant float4 colorReg1 = float4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
constant float4 colorReg2 = float4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING)
|
||||||
|
float3 LightingFunc(thread VertToFrag& vtf, constant LightingUniform& lu, texture2d<float> extTex0, sampler clampSamp) {
|
||||||
|
float4 ret = lu.ambient;
|
||||||
|
|
||||||
|
for (int i = 0; i < URDE_MAX_LIGHTS; ++i) {
|
||||||
|
float3 delta = vtf.mvPos.xyz - lu.lights[i].pos.xyz;
|
||||||
|
float dist = length(delta);
|
||||||
|
float3 deltaNorm = delta / dist;
|
||||||
|
float angDot = max(dot(deltaNorm, lu.lights[i].dir.xyz), 0.0);
|
||||||
|
float att = 1.0 / (lu.lights[i].linAtt[2] * dist * dist +
|
||||||
|
lu.lights[i].linAtt[1] * dist +
|
||||||
|
lu.lights[i].linAtt[0]);
|
||||||
|
float angAtt = lu.lights[i].angAtt[2] * angDot * angDot +
|
||||||
|
lu.lights[i].angAtt[1] * angDot +
|
||||||
|
lu.lights[i].angAtt[0];
|
||||||
|
ret += lu.lights[i].color * angAtt * att * max(dot(-deltaNorm, vtf.mvNorm.xyz), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return saturate(ret.rgb);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_THERMAL_HOT)
|
||||||
|
struct LightingUniform {
|
||||||
|
float4 tmulColor;
|
||||||
|
float4 taddColor;
|
||||||
|
};
|
||||||
|
float3 LightingFunc(thread VertToFrag& vtf, constant LightingUniform& lu, texture2d<float> extTex0, sampler clampSamp) {
|
||||||
|
return float3(1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_THERMAL_COLD)
|
||||||
|
struct LightingUniform {};
|
||||||
|
float3 LightingFunc(thread VertToFrag& vtf, constant LightingUniform& lu, texture2d<float> extTex0, sampler clampSamp) {
|
||||||
|
return float3(1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_SOLID)
|
||||||
|
struct LightingUniform {
|
||||||
|
float4 solidColor;
|
||||||
|
};
|
||||||
|
float3 LightingFunc(thread VertToFrag& vtf, constant LightingUniform& lu, texture2d<float> extTex0, sampler clampSamp) {
|
||||||
|
return float3(1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_MB_SHADOW)
|
||||||
|
struct LightingUniform {
|
||||||
|
float4 shadowUp;
|
||||||
|
float shadowId;
|
||||||
|
};
|
||||||
|
float3 LightingFunc(thread VertToFrag& vtf, constant LightingUniform& lu, texture2d<float> extTex0, sampler clampSamp) {
|
||||||
|
return float3(1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING_SHADOW)
|
||||||
|
float3 LightingFunc(thread VertToFrag& vtf, constant LightingUniform& lu, texture2d<float> extTex0, sampler clampSamp) {
|
||||||
|
float2 shadowUV = vtf.extUvs0;
|
||||||
|
shadowUV.y = 1.0 - shadowUV.y;
|
||||||
|
|
||||||
|
float4 ret = lu.ambient;
|
||||||
|
|
||||||
|
float3 delta = vtf.mvPos.xyz - lu.lights[0].pos.xyz;
|
||||||
|
float dist = length(delta);
|
||||||
|
float3 deltaNorm = delta / dist;
|
||||||
|
float angDot = max(dot(deltaNorm, lu.lights[0].dir.xyz), 0.0);
|
||||||
|
float att = 1.0 / (lu.lights[0].linAtt[2] * dist * dist +
|
||||||
|
lu.lights[0].linAtt[1] * dist +
|
||||||
|
lu.lights[0].linAtt[0]);
|
||||||
|
float angAtt = lu.lights[0].angAtt[2] * angDot * angDot +
|
||||||
|
lu.lights[0].angAtt[1] * angDot +
|
||||||
|
lu.lights[0].angAtt[0];
|
||||||
|
ret += lu.lights[0].color * angAtt * att * max(dot(-deltaNorm, vtf.mvNorm.xyz), 0.0) *
|
||||||
|
extTex0.sample(clampSamp, shadowUV).r;
|
||||||
|
|
||||||
|
for (int i = 1; i < URDE_MAX_LIGHTS; ++i) {
|
||||||
|
float3 delta = vtf.mvPos.xyz - lu.lights[i].pos.xyz;
|
||||||
|
float dist = length(delta);
|
||||||
|
float3 deltaNorm = delta / dist;
|
||||||
|
float angDot = max(dot(deltaNorm, lu.lights[i].dir.xyz), 0.0);
|
||||||
|
float att = 1.0 / (lu.lights[i].linAtt[2] * dist * dist +
|
||||||
|
lu.lights[i].linAtt[1] * dist +
|
||||||
|
lu.lights[i].linAtt[0]);
|
||||||
|
float angAtt = lu.lights[i].angAtt[2] * angDot * angDot +
|
||||||
|
lu.lights[i].angAtt[1] * angDot +
|
||||||
|
lu.lights[i].angAtt[0];
|
||||||
|
ret += lu.lights[i].color * angAtt * att * max(dot(-deltaNorm, vtf.mvNorm.xyz), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return saturate(ret.rgb);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_DISINTEGRATE)
|
||||||
|
struct LightingUniform {
|
||||||
|
float4 daddColor;
|
||||||
|
Fog fog;
|
||||||
|
};
|
||||||
|
float3 LightingFunc(thread VertToFrag& vtf, constant LightingUniform& lu, texture2d<float> extTex0, sampler clampSamp) {
|
||||||
|
return float3(1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW) || defined(URDE_DISINTEGRATE)
|
||||||
|
float4 FogFunc(thread VertToFrag& vtf, constant LightingUniform& lu, float4 colorIn) {
|
||||||
|
float fogZ;
|
||||||
|
float fogF = saturate((lu.fog.A / (lu.fog.B - (1.0 - vtf.mvpPos.z))) - lu.fog.C);
|
||||||
|
switch (lu.fog.mode) {
|
||||||
|
case 2:
|
||||||
|
fogZ = fogF;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
fogZ = 1.0 - exp2(-8.0 * fogF);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
fogZ = 1.0 - exp2(-8.0 * fogF * fogF);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
fogZ = exp2(-8.0 * (1.0 - fogF));
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
fogF = 1.0 - fogF;
|
||||||
|
fogZ = exp2(-8.0 * fogF * fogF);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fogZ = 0.0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef BLEND_DST_ONE
|
||||||
|
return float4(mix(colorIn, float4(0.0, 0.0, 0.0, 0.0), saturate(fogZ)).rgb, colorIn.a);
|
||||||
|
#else
|
||||||
|
return float4(mix(colorIn, lu.fog.color, saturate(fogZ)).rgb, colorIn.a);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_LIGHTING) || defined(URDE_LIGHTING_SHADOW)
|
||||||
|
float4 PostFunc(thread VertToFrag& vtf, constant LightingUniform& lu,
|
||||||
|
texture2d<float> extTex0, texture2d<float> extTex1, texture2d<float> extTex2,
|
||||||
|
sampler samp, float4 colorIn) {
|
||||||
|
return FogFunc(vtf, lu, colorIn) * lu.mulColor + lu.addColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_THERMAL_HOT)
|
||||||
|
float4 PostFunc(thread VertToFrag& vtf, constant LightingUniform& lu,
|
||||||
|
texture2d<float> extTex0, texture2d<float> extTex1, texture2d<float> extTex2,
|
||||||
|
sampler samp, float4 colorIn) {
|
||||||
|
return extTex0.sample(samp, vtf.extUvs0).rrrr * lu.tmulColor + lu.taddColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_THERMAL_COLD)
|
||||||
|
float4 PostFunc(thread VertToFrag& vtf, constant LightingUniform& lu,
|
||||||
|
texture2d<float> extTex0, texture2d<float> extTex1, texture2d<float> extTex2,
|
||||||
|
sampler samp, float4 colorIn) {
|
||||||
|
return colorIn * float4(0.75, 0.75, 0.75, 0.75);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_SOLID)
|
||||||
|
float4 PostFunc(thread VertToFrag& vtf, constant LightingUniform& lu,
|
||||||
|
texture2d<float> extTex0, texture2d<float> extTex1, texture2d<float> extTex2,
|
||||||
|
sampler samp, float4 colorIn) {
|
||||||
|
return lu.solidColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_MB_SHADOW)
|
||||||
|
float4 PostFunc(thread VertToFrag& vtf, constant LightingUniform& lu,
|
||||||
|
texture2d<float> extTex0, texture2d<float> extTex1, texture2d<float> extTex2,
|
||||||
|
sampler samp, float4 colorIn) {
|
||||||
|
float idTexel = extTex0.sample(samp, vtf.extUvs0).a;
|
||||||
|
float sphereTexel = extTex1.sample(samp, vtf.extUvs1).a;
|
||||||
|
float fadeTexel = extTex2.sample(samp, vtf.extUvs2).a;
|
||||||
|
float val = ((abs(idTexel - lu.shadowId) < 0.001) ?
|
||||||
|
(dot(vtf.mvNorm.xyz, lu.shadowUp.xyz) * lu.shadowUp.w) : 0.0) *
|
||||||
|
sphereTexel * fadeTexel;
|
||||||
|
return float4(0.0, 0.0, 0.0, val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_DISINTEGRATE)
|
||||||
|
float4 PostFunc(thread VertToFrag& vtf, constant LightingUniform& lu,
|
||||||
|
texture2d<float> extTex0, texture2d<float> extTex1, texture2d<float> extTex2,
|
||||||
|
sampler samp, float4 colorIn) {
|
||||||
|
float4 texel0 = extTex0.sample(samp, vtf.extUvs0);
|
||||||
|
float4 texel1 = extTex0.sample(samp, vtf.extUvs1);
|
||||||
|
colorIn = mix(float4(0.0, 0.0, 0.0, 0.0), texel1, texel0);
|
||||||
|
colorIn.rgb += lu.daddColor.rgb;
|
||||||
|
return FogFunc(vtf, lu, colorIn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(URDE_REFLECTION_SIMPLE)
|
||||||
|
#define ReflectionFunc() \
|
||||||
|
(reflectionTex.sample(reflectSamp, vtf.dynReflectionUvs1).rgb * vtf.dynReflectionAlpha)
|
||||||
|
#elif defined(URDE_REFLECTION_INDIRECT)
|
||||||
|
#define ReflectionFunc() \
|
||||||
|
(reflectionTex.sample(reflectSamp, (reflectionIndTex.sample(samp, vtf.dynReflectionUvs0).ab - \
|
||||||
|
float2(0.5, 0.5)) * float2(0.5, 0.5) + vtf.dynReflectionUvs1).rgb * vtf.dynReflectionAlpha)
|
||||||
|
#else
|
||||||
|
#define ReflectionFunc() float3(0.0, 0.0, 0.0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(URDE_ALPHA_TEST)
|
||||||
|
[[ early_fragment_tests ]]
|
||||||
|
#endif
|
||||||
|
fragment float4 fmain(VertToFrag vtf [[ stage_in ]],
|
||||||
|
sampler samp [[ sampler(0) ]],
|
||||||
|
sampler clampSamp [[ sampler(1) ]],
|
||||||
|
sampler reflectSamp [[ sampler(2) ]],
|
||||||
|
texture2d<float> lightmap [[ texture(0) ]],
|
||||||
|
texture2d<float> diffuse [[ texture(1) ]],
|
||||||
|
texture2d<float> emissive [[ texture(2) ]],
|
||||||
|
texture2d<float> specular [[ texture(3) ]],
|
||||||
|
texture2d<float> extendedSpecular [[ texture(4) ]],
|
||||||
|
texture2d<float> reflection [[ texture(5) ]],
|
||||||
|
texture2d<float> alpha [[ texture(6) ]],
|
||||||
|
texture2d<float> reflectionIndTex [[ texture(7) ]],
|
||||||
|
texture2d<float> extTex0 [[ texture(8) ]],
|
||||||
|
texture2d<float> extTex1 [[ texture(9) ]],
|
||||||
|
texture2d<float> extTex2 [[ texture(10) ]],
|
||||||
|
texture2d<float> reflectionTex [[ texture(11) ]],
|
||||||
|
constant LightingUniform& lu [[ buffer(4) ]]) {
|
||||||
|
float3 lighting = LightingFunc(vtf, lu, extTex0, clampSamp);
|
||||||
|
float4 tmp;
|
||||||
|
#if defined(URDE_DIFFUSE_ONLY)
|
||||||
|
tmp.rgb = SampleTexture_diffuse();
|
||||||
|
tmp.a = SampleTextureAlpha_alpha();
|
||||||
|
#elif defined(RETRO_SHADER)
|
||||||
|
tmp.rgb = (SampleTexture_lightmap() * colorReg1.rgb + lighting) * SampleTexture_diffuse() +
|
||||||
|
SampleTexture_emissive() + (SampleTexture_specular() + SampleTexture_extendedSpecular() * lighting) *
|
||||||
|
SampleTexture_reflection() + ReflectionFunc();
|
||||||
|
tmp.a = SampleTextureAlpha_alpha();
|
||||||
|
#elif defined(RETRO_DYNAMIC_SHADER)
|
||||||
|
tmp.rgb = (SampleTexture_lightmap() * colorReg1.rgb + lighting) * SampleTexture_diffuse() * colorReg1.rgb +
|
||||||
|
SampleTexture_emissive() * colorReg1.rgb + (SampleTexture_specular() + SampleTexture_extendedSpecular() * lighting) *
|
||||||
|
SampleTexture_reflection() + ReflectionFunc();
|
||||||
|
tmp.a = SampleTextureAlpha_alpha();
|
||||||
|
#elif defined(RETRO_DYNAMIC_ALPHA_SHADER)
|
||||||
|
tmp.rgb = (SampleTexture_lightmap() * colorReg1.rgb + lighting) * SampleTexture_diffuse() * colorReg1.rgb +
|
||||||
|
SampleTexture_emissive() * colorReg1.rgb + (SampleTexture_specular() + SampleTexture_extendedSpecular() * lighting) *
|
||||||
|
SampleTexture_reflection() + ReflectionFunc();
|
||||||
|
tmp.a = SampleTextureAlpha_alpha() * colorReg1.a;
|
||||||
|
#elif defined(RETRO_DYNAMIC_CHARACTER_SHADER)
|
||||||
|
tmp.rgb = (SampleTexture_lightmap() + lighting) * SampleTexture_diffuse() +
|
||||||
|
SampleTexture_emissive() * colorReg1.rgb + (SampleTexture_specular() + SampleTexture_extendedSpecular() * lighting) *
|
||||||
|
SampleTexture_reflection() + ReflectionFunc();
|
||||||
|
tmp.a = SampleTextureAlpha_alpha();
|
||||||
|
#endif
|
||||||
|
float4 colorOut = PostFunc(vtf, lu, extTex0, extTex1, extTex2, samp, tmp);
|
||||||
|
#if defined(URDE_ALPHA_TEST)
|
||||||
|
if (colorOut.a < 0.25)
|
||||||
|
discard_fragment();
|
||||||
|
#endif
|
||||||
|
return colorOut;
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
UBINDING0 uniform URDEVertUniform {
|
||||||
|
#if URDE_SKIN_SLOTS
|
||||||
|
mat4 objs[URDE_SKIN_SLOTS];
|
||||||
|
mat4 objsInv[URDE_SKIN_SLOTS];
|
||||||
|
#endif
|
||||||
|
mat4 mv;
|
||||||
|
mat4 mvInv;
|
||||||
|
mat4 proj;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct URDETCGMatrix {
|
||||||
|
mat4 mtx;
|
||||||
|
mat4 postMtx;
|
||||||
|
};
|
||||||
|
UBINDING1 uniform URDETexMtxUniform {
|
||||||
|
URDETCGMatrix texMtxs[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
UBINDING3 uniform URDEReflectMtx {
|
||||||
|
mat4 indMtx;
|
||||||
|
mat4 reflectMtx;
|
||||||
|
float reflectAlpha;
|
||||||
|
};
|
||||||
|
|
||||||
|
URDE_VERT_DATA_DECL
|
||||||
|
|
||||||
|
SBINDING(0) out VertToFrag vtf;
|
||||||
|
void main() {
|
||||||
|
#if URDE_SKIN_SLOTS
|
||||||
|
vec4 objPos = vec4(0.0);
|
||||||
|
vec4 objNorm = vec4(0.0);
|
||||||
|
for (int i = 0; i < URDE_SKIN_SLOTS; ++i) {
|
||||||
|
objPos += (objs[i] * vec4(posIn, 1.0)) * weightIn[i / 4][i % 4];
|
||||||
|
objNorm += (objsInv[i] * vec4(normIn, 1.0)) * weightIn[i / 4][i % 4];
|
||||||
|
}
|
||||||
|
objPos[3] = 1.0;
|
||||||
|
objNorm = vec4(normalize(objNorm.xyz), 0.0);
|
||||||
|
vtf.mvPos = mv * objPos;
|
||||||
|
vtf.mvNorm = vec4(normalize((mvInv * objNorm).xyz), 0.0);
|
||||||
|
gl_Position = proj * vtf.mvPos;
|
||||||
|
#else
|
||||||
|
vec4 objPos = vec4(posIn, 1.0);
|
||||||
|
vec4 objNorm = vec4(normIn, 0.0);
|
||||||
|
vtf.mvPos = mv * objPos;
|
||||||
|
vtf.mvNorm = mvInv * objNorm;
|
||||||
|
gl_Position = proj * vtf.mvPos;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec4 tmpProj;
|
||||||
|
vtf.lightmapUv = vec2(0.0);
|
||||||
|
vtf.diffuseUv = vec2(0.0);
|
||||||
|
vtf.emissiveUv = vec2(0.0);
|
||||||
|
vtf.specularUv = vec2(0.0);
|
||||||
|
vtf.extendedSpecularUv = vec2(0.0);
|
||||||
|
vtf.reflectionUv = vec2(0.0);
|
||||||
|
vtf.alphaUv = vec2(0.0);
|
||||||
|
URDE_TCG_EXPR
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
cbuffer URDEVertUniform : register(b0) {
|
||||||
|
#if URDE_SKIN_SLOTS
|
||||||
|
float4x4 objs[URDE_SKIN_SLOTS];
|
||||||
|
float4x4 objsInv[URDE_SKIN_SLOTS];
|
||||||
|
#endif
|
||||||
|
float4x4 mv;
|
||||||
|
float4x4 mvInv;
|
||||||
|
float4x4 proj;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct URDETCGMatrix {
|
||||||
|
float4x4 mtx;
|
||||||
|
float4x4 postMtx;
|
||||||
|
};
|
||||||
|
cbuffer URDETexMtxUniform : register(b1) {
|
||||||
|
URDETCGMatrix texMtxs[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer URDEReflectMtx : register(b3) {
|
||||||
|
float4x4 indMtx;
|
||||||
|
float4x4 reflectMtx;
|
||||||
|
float reflectAlpha;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertData {
|
||||||
|
float3 posIn : POSITION;
|
||||||
|
float3 normIn : NORMAL;
|
||||||
|
#if URDE_COL_SLOTS
|
||||||
|
float4 colIn[URDE_COL_SLOTS] : COLOR;
|
||||||
|
#endif
|
||||||
|
#if URDE_UV_SLOTS
|
||||||
|
float2 uvIn[URDE_UV_SLOTS] : UV;
|
||||||
|
#endif
|
||||||
|
#if URDE_WEIGHT_SLOTS
|
||||||
|
float4 weightIn[URDE_WEIGHT_SLOTS] : WEIGHT;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
VertToFrag main(in VertData v) {
|
||||||
|
VertToFrag vtf;
|
||||||
|
#if URDE_SKIN_SLOTS
|
||||||
|
float4 objPos = float4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
float4 objNorm = float4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
for (int i = 0; i < URDE_SKIN_SLOTS; ++i) {
|
||||||
|
objPos += mul(objs[i], float4(v.posIn, 1.0)) * v.weightIn[i / 4][i % 4];
|
||||||
|
objNorm += mul(objsInv[i], float4(v.normIn, 1.0)) * v.weightIn[i / 4][i % 4];
|
||||||
|
}
|
||||||
|
objPos[3] = 1.0;
|
||||||
|
objNorm = float4(normalize(objNorm.xyz), 0.0);
|
||||||
|
vtf.mvPos = mul(mv, objPos);
|
||||||
|
vtf.mvNorm = float4(normalize(mul(mvInv, objNorm).xyz), 0.0);
|
||||||
|
vtf.mvpPos = mul(proj, vtf.mvPos);
|
||||||
|
#else
|
||||||
|
float4 objPos = float4(v.posIn, 1.0);
|
||||||
|
float4 objNorm = float4(v.normIn, 0.0);
|
||||||
|
vtf.mvPos = mul(mv, objPos);
|
||||||
|
vtf.mvNorm = mul(mvInv, objNorm);
|
||||||
|
vtf.mvpPos = mul(proj, vtf.mvPos);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vtf.lightmapUv = float2(0.0, 0.0);
|
||||||
|
vtf.diffuseUv = float2(0.0, 0.0);
|
||||||
|
vtf.emissiveUv = float2(0.0, 0.0);
|
||||||
|
vtf.specularUv = float2(0.0, 0.0);
|
||||||
|
vtf.extendedSpecularUv = float2(0.0, 0.0);
|
||||||
|
vtf.reflectionUv = float2(0.0, 0.0);
|
||||||
|
vtf.alphaUv = float2(0.0, 0.0);
|
||||||
|
float4 tmpProj;
|
||||||
|
URDE_TCG_EXPR
|
||||||
|
|
||||||
|
return vtf;
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
struct URDEVertUniform {
|
||||||
|
#if URDE_SKIN_SLOTS
|
||||||
|
float4x4 objs[URDE_SKIN_SLOTS];
|
||||||
|
float4x4 objsInv[URDE_SKIN_SLOTS];
|
||||||
|
#endif
|
||||||
|
float4x4 mv;
|
||||||
|
float4x4 mvInv;
|
||||||
|
float4x4 proj;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct URDETCGMatrix {
|
||||||
|
float4x4 mtx;
|
||||||
|
float4x4 postMtx;
|
||||||
|
};
|
||||||
|
struct URDETexMtxUniform {
|
||||||
|
URDETCGMatrix texMtxs[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct URDEReflectMtx {
|
||||||
|
float4x4 indMtx;
|
||||||
|
float4x4 reflectMtx;
|
||||||
|
float reflectAlpha;
|
||||||
|
};
|
||||||
|
|
||||||
|
URDE_VERT_DATA_DECL
|
||||||
|
|
||||||
|
vertex VertToFrag vmain(VertData v [[ stage_in ]],
|
||||||
|
constant URDEVertUniform& vu [[ buffer(2) ]],
|
||||||
|
constant URDETexMtxUniform& tu [[ buffer(3) ]],
|
||||||
|
constant URDEReflectMtx& ru [[ buffer(5) ]]) {
|
||||||
|
VertToFrag vtf;
|
||||||
|
#if URDE_SKIN_SLOTS
|
||||||
|
float4 objPos = float4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
float4 objNorm = float4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
URDE_WEIGHTING_EXPR
|
||||||
|
objPos[3] = 1.0;
|
||||||
|
objNorm = float4(normalize(objNorm.xyz), 0.0);
|
||||||
|
vtf.mvPos = vu.mv * objPos;
|
||||||
|
vtf.mvNorm = float4(normalize((vu.mvInv * objNorm).xyz), 0.0);
|
||||||
|
vtf.mvpPos = vu.proj * vtf.mvPos;
|
||||||
|
#else
|
||||||
|
float4 objPos = float4(v.posIn, 1.0);
|
||||||
|
float4 objNorm = float4(v.normIn, 0.0);
|
||||||
|
vtf.mvPos = vu.mv * objPos;
|
||||||
|
vtf.mvNorm = vu.mvInv * objNorm;
|
||||||
|
vtf.mvpPos = vu.proj * vtf.mvPos;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vtf.lightmapUv = float2(0.0, 0.0);
|
||||||
|
vtf.diffuseUv = float2(0.0, 0.0);
|
||||||
|
vtf.emissiveUv = float2(0.0, 0.0);
|
||||||
|
vtf.specularUv = float2(0.0, 0.0);
|
||||||
|
vtf.extendedSpecularUv = float2(0.0, 0.0);
|
||||||
|
vtf.reflectionUv = float2(0.0, 0.0);
|
||||||
|
vtf.alphaUv = float2(0.0, 0.0);
|
||||||
|
float4 tmpProj;
|
||||||
|
URDE_TCG_EXPR
|
||||||
|
|
||||||
|
return vtf;
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
#pragma once
|
||||||
|
#include "hecl/PipelineBase.hpp"
|
||||||
|
#include "hecl/hecl.hpp"
|
||||||
|
#include "DataSpec/DNAMP1/CMDLMaterials.hpp"
|
||||||
|
|
||||||
|
struct SModelShadersInfo {
|
||||||
|
uint64_t m_hash;
|
||||||
|
using Material = DataSpec::DNAMP1::HMDLMaterialSet::Material;
|
||||||
|
const Material& m_material;
|
||||||
|
const hecl::Backend::ShaderTag& m_tag;
|
||||||
|
const hecl::Backend::ExtensionSlot& m_extension;
|
||||||
|
std::vector<boo::VertexElementDescriptor> m_vtxFmtData;
|
||||||
|
boo::VertexFormatInfo m_vtxFmt;
|
||||||
|
boo::AdditionalPipelineInfo m_additionalInfo;
|
||||||
|
|
||||||
|
explicit SModelShadersInfo(const Material& material,
|
||||||
|
const hecl::Backend::ShaderTag& tag,
|
||||||
|
const hecl::Backend::ExtensionSlot& extension)
|
||||||
|
: m_material(material), m_tag(tag), m_extension(extension) {
|
||||||
|
m_hash = m_tag.val64();
|
||||||
|
hecl::hash_combine_impl<uint64_t>(m_hash, std::hash<uint64_t>()(m_extension.hash()));
|
||||||
|
|
||||||
|
m_vtxFmtData = tag.vertexFormat();
|
||||||
|
m_vtxFmt = boo::VertexFormatInfo(m_vtxFmtData.size(), m_vtxFmtData.data());
|
||||||
|
|
||||||
|
m_additionalInfo = m_tag.additionalInfo(extension, material.blendFactors());
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr bool HasHash = true;
|
||||||
|
uint64_t Hash() const { return m_hash; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Shader_CModelShaders : public hecl::GeneralShader {
|
||||||
|
const SModelShadersInfo& m_info;
|
||||||
|
public:
|
||||||
|
Shader_CModelShaders(const SModelShadersInfo& in)
|
||||||
|
: m_info(in)
|
||||||
|
, VtxFmt(in.m_vtxFmt)
|
||||||
|
, PipelineInfo(in.m_additionalInfo) {}
|
||||||
|
|
||||||
|
const boo::VertexFormatInfo VtxFmt;
|
||||||
|
const boo::AdditionalPipelineInfo PipelineInfo;
|
||||||
|
static constexpr bool HasHash = true;
|
||||||
|
uint64_t Hash() const { return m_info.m_hash; }
|
||||||
|
const SModelShadersInfo& info() const { return m_info; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename P, typename S>
|
||||||
|
class StageObject_CModelShaders : public hecl::StageBinary<P, S> {
|
||||||
|
static std::string BuildShader(const SModelShadersInfo& in);
|
||||||
|
|
||||||
|
public:
|
||||||
|
StageObject_CModelShaders(hecl::StageConverter<P, S>& conv, hecl::FactoryCtx& ctx,
|
||||||
|
const Shader_CModelShaders& in)
|
||||||
|
: hecl::StageBinary<P, S>(conv, ctx, hecl::StageSourceText<P, S>(BuildShader(in.info()))) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define UNIVERSAL_PIPELINES_shader_CModelShaders ::Shader_CModelShaders
|
||||||
|
#define STAGES_shader_CModelShaders(P, S) ::StageObject_CModelShaders<P, S>,
|
|
@ -0,0 +1,229 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <sstream>
|
||||||
|
#include "shader_CModelShaders.hpp"
|
||||||
|
#include "Runtime/Graphics/Shaders/CModelShaders.hpp"
|
||||||
|
|
||||||
|
extern "C" const uint8_t CMODELSHADERS_COMMON_GLSL[];
|
||||||
|
extern "C" size_t CMODELSHADERS_COMMON_GLSL_SZ;
|
||||||
|
static std::string_view CMODELSHADERS_COMMON_GLSL_SV((char*)CMODELSHADERS_COMMON_GLSL, CMODELSHADERS_COMMON_GLSL_SZ);
|
||||||
|
|
||||||
|
extern "C" const uint8_t CMODELSHADERS_VERT_GLSL[];
|
||||||
|
extern "C" size_t CMODELSHADERS_VERT_GLSL_SZ;
|
||||||
|
static std::string_view CMODELSHADERS_VERT_GLSL_SV((char*)CMODELSHADERS_VERT_GLSL, CMODELSHADERS_VERT_GLSL_SZ);
|
||||||
|
|
||||||
|
extern "C" const uint8_t CMODELSHADERS_FRAG_GLSL[];
|
||||||
|
extern "C" size_t CMODELSHADERS_FRAG_GLSL_SZ;
|
||||||
|
static std::string_view CMODELSHADERS_FRAG_GLSL_SV((char*)CMODELSHADERS_FRAG_GLSL, CMODELSHADERS_FRAG_GLSL_SZ);
|
||||||
|
|
||||||
|
using BlendMaterial = SModelShadersInfo::Material::BlendMaterial;
|
||||||
|
using TexCoordSource = BlendMaterial::TexCoordSource;
|
||||||
|
|
||||||
|
static std::string_view EmitTexGenSource2(TexCoordSource src) {
|
||||||
|
switch (src) {
|
||||||
|
case TexCoordSource::Position:
|
||||||
|
return "objPos.xy"sv;
|
||||||
|
case TexCoordSource::Normal:
|
||||||
|
return "objNorm.xy"sv;
|
||||||
|
case TexCoordSource::Tex0:
|
||||||
|
return "uvIn[0]"sv;
|
||||||
|
case TexCoordSource::Tex1:
|
||||||
|
return "uvIn[1]"sv;
|
||||||
|
case TexCoordSource::Tex2:
|
||||||
|
return "uvIn[2]"sv;
|
||||||
|
case TexCoordSource::Tex3:
|
||||||
|
return "uvIn[3]"sv;
|
||||||
|
case TexCoordSource::Tex4:
|
||||||
|
return "uvIn[4]"sv;
|
||||||
|
case TexCoordSource::Tex5:
|
||||||
|
return "uvIn[5]"sv;
|
||||||
|
case TexCoordSource::Tex6:
|
||||||
|
return "uvIn[6]"sv;
|
||||||
|
case TexCoordSource::Tex7:
|
||||||
|
return "uvIn[7]"sv;
|
||||||
|
default:
|
||||||
|
assert(false && "Unknown source type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string_view EmitTexGenSource4(TexCoordSource src) {
|
||||||
|
switch (src) {
|
||||||
|
case TexCoordSource::Position:
|
||||||
|
return "vec4(objPos.xyz, 1.0)"sv;
|
||||||
|
case TexCoordSource::Normal:
|
||||||
|
return "vec4(objNorm.xyz, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex0:
|
||||||
|
return "vec4(uvIn[0], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex1:
|
||||||
|
return "vec4(uvIn[1], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex2:
|
||||||
|
return "vec4(uvIn[2], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex3:
|
||||||
|
return "vec4(uvIn[3], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex4:
|
||||||
|
return "vec4(uvIn[4], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex5:
|
||||||
|
return "vec4(uvIn[5], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex6:
|
||||||
|
return "vec4(uvIn[6], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex7:
|
||||||
|
return "vec4(uvIn[7], 0.0, 1.0)"sv;
|
||||||
|
default:
|
||||||
|
assert(false && "Unknown source type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string _BuildVS(const SModelShadersInfo& info) {
|
||||||
|
std::stringstream vertOut;
|
||||||
|
vertOut << CMODELSHADERS_COMMON_GLSL_SV;
|
||||||
|
vertOut << "#define URDE_COL_SLOTS "sv << unsigned(info.m_tag.getColorCount()) << '\n';
|
||||||
|
vertOut << "#define URDE_UV_SLOTS "sv << unsigned(info.m_tag.getUvCount()) << '\n';
|
||||||
|
vertOut << "#define URDE_SKIN_SLOTS "sv << unsigned(info.m_tag.getSkinSlotCount()) << '\n';
|
||||||
|
vertOut << "#define URDE_WEIGHT_SLOTS "sv << unsigned(info.m_tag.getWeightCount()) << '\n';
|
||||||
|
|
||||||
|
vertOut << "#define URDE_VERT_DATA_DECL "
|
||||||
|
"layout(location=0) in vec3 posIn;"
|
||||||
|
"layout(location=1) in vec3 normIn;"sv;
|
||||||
|
if (info.m_tag.getColorCount())
|
||||||
|
vertOut << "layout(location=2) in vec4 colIn["sv << unsigned(info.m_tag.getColorCount()) << "];"sv;
|
||||||
|
if (info.m_tag.getUvCount())
|
||||||
|
vertOut << "layout(location="sv << 2 + info.m_tag.getColorCount() <<
|
||||||
|
") in vec2 uvIn["sv << unsigned(info.m_tag.getUvCount()) << "];"sv;
|
||||||
|
if (info.m_tag.getWeightCount())
|
||||||
|
vertOut << "layout(location="sv << 2 + info.m_tag.getColorCount() + info.m_tag.getUvCount() <<
|
||||||
|
") in vec4 weightIn["sv << unsigned(info.m_tag.getWeightCount()) << "];"sv;
|
||||||
|
|
||||||
|
vertOut << "#define URDE_TCG_EXPR "sv;
|
||||||
|
using UVAnimType = BlendMaterial::UVAnimType;
|
||||||
|
using PassType = BlendMaterial::PassType;
|
||||||
|
int mtxIdx = 0;
|
||||||
|
for (const auto& chunk : info.m_material.chunks) {
|
||||||
|
if (auto passChunk = chunk.get_if<SModelShadersInfo::Material::PASS>()) {
|
||||||
|
if (passChunk->type != PassType::IndirectTex) {
|
||||||
|
std::string_view tpStr = BlendMaterial::PassTypeToString(passChunk->type);
|
||||||
|
if (passChunk->uvAnimType == UVAnimType::Invalid) {
|
||||||
|
vertOut << "vtf."sv << tpStr << "Uv = "sv << EmitTexGenSource2(passChunk->source) << ";"sv;
|
||||||
|
} else {
|
||||||
|
vertOut << "tmpProj = texMtxs["sv << mtxIdx << "].postMtx * vec4("sv <<
|
||||||
|
(passChunk->shouldNormalizeUv() ? "normalize"sv : ""sv) << "((texMtxs["sv << mtxIdx << "].mtx * "sv <<
|
||||||
|
EmitTexGenSource4(passChunk->source) << ").xyz), 1.0);"sv <<
|
||||||
|
"vtf."sv << tpStr << "Uv = (tmpProj / tmpProj.w).xy;"sv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (auto clrChunk = chunk.get_if<SModelShadersInfo::Material::CLR>()) {
|
||||||
|
std::string_view tpStr = BlendMaterial::PassTypeToString(clrChunk->type);
|
||||||
|
vertOut << "vtf."sv << tpStr << "Uv = vec2(0.0,0.0);"sv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!info.m_extension.noReflection && info.m_tag.getReflectionType() != hecl::Backend::ReflectionType::None)
|
||||||
|
vertOut << "vtf.dynReflectionUvs[0] = normalize((indMtx * vec4(objPos.xyz, 1.0)).xz) * vec2(0.5, 0.5) + vec2(0.5, 0.5);"
|
||||||
|
"vtf.dynReflectionUvs[1] = (reflectMtx * vec4(objPos.xyz, 1.0)).xy;"
|
||||||
|
"vtf.dynReflectionAlpha = reflectAlpha;";
|
||||||
|
|
||||||
|
for (size_t i = 0; i < info.m_extension.texCount; ++i) {
|
||||||
|
const auto& extTex = info.m_extension.texs[i];
|
||||||
|
if (extTex.mtxIdx == 0xff)
|
||||||
|
vertOut << "vtf.extUvs["sv << i << "] = "sv << EmitTexGenSource2(extTex.src) << ";"sv;
|
||||||
|
else
|
||||||
|
vertOut << "tmpProj = texMtxs["sv << unsigned(extTex.mtxIdx) << "].postMtx * vec4("sv <<
|
||||||
|
(extTex.normalize ? "normalize"sv : ""sv) << "((texMtxs["sv << unsigned(extTex.mtxIdx) << "].mtx * "sv <<
|
||||||
|
EmitTexGenSource4(extTex.src) << ").xyz), 1.0);"sv <<
|
||||||
|
"vtf.extUvs["sv << i << "] = (tmpProj / tmpProj.w).xy;"sv;
|
||||||
|
}
|
||||||
|
vertOut << '\n';
|
||||||
|
|
||||||
|
vertOut << CMODELSHADERS_VERT_GLSL_SV;
|
||||||
|
return vertOut.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string _BuildFS(const SModelShadersInfo& info) {
|
||||||
|
std::stringstream fragOut;
|
||||||
|
fragOut << CMODELSHADERS_COMMON_GLSL_SV;
|
||||||
|
fragOut << "#define URDE_MAX_LIGHTS " _XSTR(URDE_MAX_LIGHTS) "\n";
|
||||||
|
fragOut << "#define " << info.m_extension.shaderMacro << "\n";
|
||||||
|
|
||||||
|
using ShaderType = BlendMaterial::ShaderType;
|
||||||
|
switch (info.m_material.shaderType) {
|
||||||
|
case ShaderType::RetroShader:
|
||||||
|
fragOut << "#define RETRO_SHADER\n"; break;
|
||||||
|
case ShaderType::RetroDynamicShader:
|
||||||
|
fragOut << "#define RETRO_DYNAMIC_SHADER\n"; break;
|
||||||
|
case ShaderType::RetroDynamicAlphaShader:
|
||||||
|
fragOut << "#define RETRO_DYNAMIC_ALPHA_SHADER\n"; break;
|
||||||
|
case ShaderType::RetroDynamicCharacterShader:
|
||||||
|
fragOut << "#define RETRO_DYNAMIC_CHARACTER_SHADER\n"; break;
|
||||||
|
default:
|
||||||
|
assert(false && "Unknown shader type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragOut << "#define BLEND_SRC_"sv << hecl::Backend::BlendFactorToDefine(
|
||||||
|
hecl::Backend::BlendFactor(info.m_additionalInfo.srcFac), hecl::Backend::BlendFactor::One) << '\n';
|
||||||
|
fragOut << "#define BLEND_DST_"sv << hecl::Backend::BlendFactorToDefine(
|
||||||
|
hecl::Backend::BlendFactor(info.m_additionalInfo.dstFac), hecl::Backend::BlendFactor::Zero) << '\n';
|
||||||
|
|
||||||
|
using PassType = BlendMaterial::PassType;
|
||||||
|
for (const auto& chunk : info.m_material.chunks) {
|
||||||
|
if (auto passChunk = chunk.get_if<SModelShadersInfo::Material::PASS>()) {
|
||||||
|
if (passChunk->alpha) {
|
||||||
|
std::string_view tpStr = BlendMaterial::PassTypeToString(passChunk->type);
|
||||||
|
fragOut << "#define ALPHA_" << tpStr << '\n';
|
||||||
|
}
|
||||||
|
} else if (auto clrChunk = chunk.get_if<SModelShadersInfo::Material::CLR>()) {
|
||||||
|
if (clrChunk->type == PassType::Alpha)
|
||||||
|
fragOut << "#define ALPHA_alpha\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.m_tag.getAlphaTest() || info.m_extension.forceAlphaTest)
|
||||||
|
fragOut << "#define URDE_ALPHA_TEST\n";
|
||||||
|
|
||||||
|
if (info.m_extension.diffuseOnly)
|
||||||
|
fragOut << "#define URDE_DIFFUSE_ONLY\n";
|
||||||
|
|
||||||
|
if (!info.m_extension.noReflection) {
|
||||||
|
if (info.m_tag.getReflectionType() == hecl::Backend::ReflectionType::Indirect)
|
||||||
|
fragOut << "#define URDE_REFLECTION_INDIRECT\n"sv;
|
||||||
|
else if (info.m_tag.getReflectionType() == hecl::Backend::ReflectionType::Simple)
|
||||||
|
fragOut << "#define URDE_REFLECTION_SIMPLE\n"sv;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragOut << CMODELSHADERS_FRAG_GLSL_SV;
|
||||||
|
return fragOut.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string StageObject_CModelShaders<hecl::PlatformType::OpenGL, hecl::PipelineStage::Vertex>::BuildShader(
|
||||||
|
const SModelShadersInfo& in) {
|
||||||
|
return _BuildVS(in);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
std::string StageObject_CModelShaders<hecl::PlatformType::Vulkan, hecl::PipelineStage::Vertex>::BuildShader(
|
||||||
|
const SModelShadersInfo& in) {
|
||||||
|
return _BuildVS(in);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
std::string StageObject_CModelShaders<hecl::PlatformType::NX, hecl::PipelineStage::Vertex>::BuildShader(
|
||||||
|
const SModelShadersInfo& in) {
|
||||||
|
return _BuildVS(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string StageObject_CModelShaders<hecl::PlatformType::OpenGL, hecl::PipelineStage::Fragment>::BuildShader(
|
||||||
|
const SModelShadersInfo& in) {
|
||||||
|
return _BuildFS(in);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
std::string StageObject_CModelShaders<hecl::PlatformType::Vulkan, hecl::PipelineStage::Fragment>::BuildShader(
|
||||||
|
const SModelShadersInfo& in) {
|
||||||
|
return _BuildFS(in);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
std::string StageObject_CModelShaders<hecl::PlatformType::NX, hecl::PipelineStage::Fragment>::BuildShader(
|
||||||
|
const SModelShadersInfo& in) {
|
||||||
|
return _BuildFS(in);
|
||||||
|
}
|
|
@ -0,0 +1,197 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <sstream>
|
||||||
|
#include "shader_CModelShaders.hpp"
|
||||||
|
#include "Runtime/Graphics/Shaders/CModelShaders.hpp"
|
||||||
|
|
||||||
|
extern "C" const uint8_t CMODELSHADERS_COMMON_HLSL[];
|
||||||
|
extern "C" size_t CMODELSHADERS_COMMON_HLSL_SZ;
|
||||||
|
static std::string_view CMODELSHADERS_COMMON_HLSL_SV((char*)CMODELSHADERS_COMMON_HLSL, CMODELSHADERS_COMMON_HLSL_SZ);
|
||||||
|
|
||||||
|
extern "C" const uint8_t CMODELSHADERS_VERT_HLSL[];
|
||||||
|
extern "C" size_t CMODELSHADERS_VERT_HLSL_SZ;
|
||||||
|
static std::string_view CMODELSHADERS_VERT_HLSL_SV((char*)CMODELSHADERS_VERT_HLSL, CMODELSHADERS_VERT_HLSL_SZ);
|
||||||
|
|
||||||
|
extern "C" const uint8_t CMODELSHADERS_FRAG_HLSL[];
|
||||||
|
extern "C" size_t CMODELSHADERS_FRAG_HLSL_SZ;
|
||||||
|
static std::string_view CMODELSHADERS_FRAG_HLSL_SV((char*)CMODELSHADERS_FRAG_HLSL, CMODELSHADERS_FRAG_HLSL_SZ);
|
||||||
|
|
||||||
|
using BlendMaterial = SModelShadersInfo::Material::BlendMaterial;
|
||||||
|
using TexCoordSource = BlendMaterial::TexCoordSource;
|
||||||
|
|
||||||
|
static std::string_view EmitTexGenSource2(TexCoordSource src) {
|
||||||
|
switch (src) {
|
||||||
|
case TexCoordSource::Position:
|
||||||
|
return "objPos.xy"sv;
|
||||||
|
case TexCoordSource::Normal:
|
||||||
|
return "objNorm.xy"sv;
|
||||||
|
case TexCoordSource::Tex0:
|
||||||
|
return "v.uvIn[0]"sv;
|
||||||
|
case TexCoordSource::Tex1:
|
||||||
|
return "v.uvIn[1]"sv;
|
||||||
|
case TexCoordSource::Tex2:
|
||||||
|
return "v.uvIn[2]"sv;
|
||||||
|
case TexCoordSource::Tex3:
|
||||||
|
return "v.uvIn[3]"sv;
|
||||||
|
case TexCoordSource::Tex4:
|
||||||
|
return "v.uvIn[4]"sv;
|
||||||
|
case TexCoordSource::Tex5:
|
||||||
|
return "v.uvIn[5]"sv;
|
||||||
|
case TexCoordSource::Tex6:
|
||||||
|
return "v.uvIn[6]"sv;
|
||||||
|
case TexCoordSource::Tex7:
|
||||||
|
return "v.uvIn[7]"sv;
|
||||||
|
default:
|
||||||
|
assert(false && "Unknown source type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string_view EmitTexGenSource4(TexCoordSource src) {
|
||||||
|
switch (src) {
|
||||||
|
case TexCoordSource::Position:
|
||||||
|
return "float4(objPos.xyz, 1.0)"sv;
|
||||||
|
case TexCoordSource::Normal:
|
||||||
|
return "float4(objNorm.xyz, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex0:
|
||||||
|
return "float4(v.uvIn[0], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex1:
|
||||||
|
return "float4(v.uvIn[1], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex2:
|
||||||
|
return "float4(v.uvIn[2], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex3:
|
||||||
|
return "float4(v.uvIn[3], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex4:
|
||||||
|
return "float4(v.uvIn[4], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex5:
|
||||||
|
return "float4(v.uvIn[5], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex6:
|
||||||
|
return "float4(v.uvIn[6], 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex7:
|
||||||
|
return "float4(v.uvIn[7], 0.0, 1.0)"sv;
|
||||||
|
default:
|
||||||
|
assert(false && "Unknown source type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string _BuildVS(const SModelShadersInfo& info) {
|
||||||
|
std::stringstream vertOut;
|
||||||
|
vertOut << CMODELSHADERS_COMMON_HLSL_SV;
|
||||||
|
vertOut << "#define URDE_COL_SLOTS "sv << unsigned(info.m_tag.getColorCount()) << '\n';
|
||||||
|
vertOut << "#define URDE_UV_SLOTS "sv << unsigned(info.m_tag.getUvCount()) << '\n';
|
||||||
|
vertOut << "#define URDE_SKIN_SLOTS "sv << unsigned(info.m_tag.getSkinSlotCount()) << '\n';
|
||||||
|
vertOut << "#define URDE_WEIGHT_SLOTS "sv << unsigned(info.m_tag.getWeightCount()) << '\n';
|
||||||
|
|
||||||
|
vertOut << "#define URDE_TCG_EXPR "sv;
|
||||||
|
using UVAnimType = BlendMaterial::UVAnimType;
|
||||||
|
using PassType = BlendMaterial::PassType;
|
||||||
|
int mtxIdx = 0;
|
||||||
|
for (const auto& chunk : info.m_material.chunks) {
|
||||||
|
if (auto passChunk = chunk.get_if<SModelShadersInfo::Material::PASS>()) {
|
||||||
|
if (passChunk->type != PassType::IndirectTex) {
|
||||||
|
std::string_view tpStr = BlendMaterial::PassTypeToString(passChunk->type);
|
||||||
|
if (passChunk->uvAnimType == UVAnimType::Invalid) {
|
||||||
|
vertOut << "vtf."sv << tpStr << "Uv = "sv << EmitTexGenSource2(passChunk->source) << ";"sv;
|
||||||
|
} else {
|
||||||
|
vertOut << "tmpProj = mul(texMtxs["sv << mtxIdx << "].postMtx, float4("sv <<
|
||||||
|
(passChunk->shouldNormalizeUv() ? "normalize"sv : ""sv) << "(mul(texMtxs["sv << mtxIdx << "].mtx, "sv <<
|
||||||
|
EmitTexGenSource4(passChunk->source) << ").xyz), 1.0));"sv <<
|
||||||
|
"vtf."sv << tpStr << "Uv = (tmpProj / tmpProj.w).xy;"sv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (auto clrChunk = chunk.get_if<SModelShadersInfo::Material::CLR>()) {
|
||||||
|
std::string_view tpStr = BlendMaterial::PassTypeToString(clrChunk->type);
|
||||||
|
vertOut << "vtf."sv << tpStr << "Uv = float2(0.0,0.0);"sv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!info.m_extension.noReflection && info.m_tag.getReflectionType() != hecl::Backend::ReflectionType::None)
|
||||||
|
vertOut << "vtf.dynReflectionUvs[0] = normalize(mul(indMtx, float4(objPos.xyz, 1.0)).xz) * float2(0.5, 0.5) + float2(0.5, 0.5);"
|
||||||
|
"vtf.dynReflectionUvs[1] = mul(reflectMtx, float4(objPos.xyz, 1.0)).xy;"
|
||||||
|
"vtf.dynReflectionAlpha = reflectAlpha;";
|
||||||
|
|
||||||
|
for (size_t i = 0; i < info.m_extension.texCount; ++i) {
|
||||||
|
const auto& extTex = info.m_extension.texs[i];
|
||||||
|
if (extTex.mtxIdx == 0xff)
|
||||||
|
vertOut << "vtf.extUvs["sv << i << "] = "sv << EmitTexGenSource2(extTex.src) << ";"sv;
|
||||||
|
else
|
||||||
|
vertOut << "tmpProj = mul(texMtxs["sv << unsigned(extTex.mtxIdx) << "].postMtx, float4("sv <<
|
||||||
|
(extTex.normalize ? "normalize"sv : ""sv) << "(mul(texMtxs["sv << unsigned(extTex.mtxIdx) << "].mtx, "sv <<
|
||||||
|
EmitTexGenSource4(extTex.src) << ").xyz), 1.0));"sv <<
|
||||||
|
"vtf.extUvs["sv << i << "] = (tmpProj / tmpProj.w).xy;"sv;
|
||||||
|
}
|
||||||
|
vertOut << '\n';
|
||||||
|
|
||||||
|
vertOut << CMODELSHADERS_VERT_HLSL_SV;
|
||||||
|
return vertOut.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string _BuildFS(const SModelShadersInfo& info) {
|
||||||
|
std::stringstream fragOut;
|
||||||
|
fragOut << CMODELSHADERS_COMMON_HLSL_SV;
|
||||||
|
fragOut << "#define URDE_MAX_LIGHTS " _XSTR(URDE_MAX_LIGHTS) "\n";
|
||||||
|
fragOut << "#define " << info.m_extension.shaderMacro << "\n";
|
||||||
|
|
||||||
|
using ShaderType = BlendMaterial::ShaderType;
|
||||||
|
switch (info.m_material.shaderType) {
|
||||||
|
case ShaderType::RetroShader:
|
||||||
|
fragOut << "#define RETRO_SHADER\n"; break;
|
||||||
|
case ShaderType::RetroDynamicShader:
|
||||||
|
fragOut << "#define RETRO_DYNAMIC_SHADER\n"; break;
|
||||||
|
case ShaderType::RetroDynamicAlphaShader:
|
||||||
|
fragOut << "#define RETRO_DYNAMIC_ALPHA_SHADER\n"; break;
|
||||||
|
case ShaderType::RetroDynamicCharacterShader:
|
||||||
|
fragOut << "#define RETRO_DYNAMIC_CHARACTER_SHADER\n"; break;
|
||||||
|
default:
|
||||||
|
assert(false && "Unknown shader type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragOut << "#define BLEND_SRC_"sv << hecl::Backend::BlendFactorToDefine(
|
||||||
|
hecl::Backend::BlendFactor(info.m_additionalInfo.srcFac), hecl::Backend::BlendFactor::One) << '\n';
|
||||||
|
fragOut << "#define BLEND_DST_"sv << hecl::Backend::BlendFactorToDefine(
|
||||||
|
hecl::Backend::BlendFactor(info.m_additionalInfo.dstFac), hecl::Backend::BlendFactor::Zero) << '\n';
|
||||||
|
|
||||||
|
using PassType = BlendMaterial::PassType;
|
||||||
|
for (const auto& chunk : info.m_material.chunks) {
|
||||||
|
if (auto passChunk = chunk.get_if<SModelShadersInfo::Material::PASS>()) {
|
||||||
|
if (passChunk->alpha) {
|
||||||
|
std::string_view tpStr = BlendMaterial::PassTypeToString(passChunk->type);
|
||||||
|
fragOut << "#define ALPHA_" << tpStr << '\n';
|
||||||
|
}
|
||||||
|
} else if (auto clrChunk = chunk.get_if<SModelShadersInfo::Material::CLR>()) {
|
||||||
|
if (clrChunk->type == PassType::Alpha)
|
||||||
|
fragOut << "#define ALPHA_alpha\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.m_tag.getAlphaTest() || info.m_extension.forceAlphaTest)
|
||||||
|
fragOut << "#define URDE_ALPHA_TEST\n";
|
||||||
|
|
||||||
|
if (info.m_extension.diffuseOnly)
|
||||||
|
fragOut << "#define URDE_DIFFUSE_ONLY\n";
|
||||||
|
|
||||||
|
if (!info.m_extension.noReflection) {
|
||||||
|
if (info.m_tag.getReflectionType() == hecl::Backend::ReflectionType::Indirect)
|
||||||
|
fragOut << "#define URDE_REFLECTION_INDIRECT\n"sv;
|
||||||
|
else if (info.m_tag.getReflectionType() == hecl::Backend::ReflectionType::Simple)
|
||||||
|
fragOut << "#define URDE_REFLECTION_SIMPLE\n"sv;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragOut << CMODELSHADERS_FRAG_HLSL_SV;
|
||||||
|
return fragOut.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string StageObject_CModelShaders<hecl::PlatformType::D3D11, hecl::PipelineStage::Vertex>::BuildShader(
|
||||||
|
const SModelShadersInfo& in) {
|
||||||
|
return _BuildVS(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string StageObject_CModelShaders<hecl::PlatformType::D3D11, hecl::PipelineStage::Fragment>::BuildShader(
|
||||||
|
const SModelShadersInfo& in) {
|
||||||
|
return _BuildFS(in);
|
||||||
|
}
|
|
@ -0,0 +1,218 @@
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <sstream>
|
||||||
|
#include "shader_CModelShaders.hpp"
|
||||||
|
#include "Runtime/Graphics/Shaders/CModelShaders.hpp"
|
||||||
|
|
||||||
|
extern "C" const uint8_t CMODELSHADERS_COMMON_METAL[];
|
||||||
|
extern "C" size_t CMODELSHADERS_COMMON_METAL_SZ;
|
||||||
|
static std::string_view CMODELSHADERS_COMMON_METAL_SV((char*)CMODELSHADERS_COMMON_METAL, CMODELSHADERS_COMMON_METAL_SZ);
|
||||||
|
|
||||||
|
extern "C" const uint8_t CMODELSHADERS_VERT_METAL[];
|
||||||
|
extern "C" size_t CMODELSHADERS_VERT_METAL_SZ;
|
||||||
|
static std::string_view CMODELSHADERS_VERT_METAL_SV((char*)CMODELSHADERS_VERT_METAL, CMODELSHADERS_VERT_METAL_SZ);
|
||||||
|
|
||||||
|
extern "C" const uint8_t CMODELSHADERS_FRAG_METAL[];
|
||||||
|
extern "C" size_t CMODELSHADERS_FRAG_METAL_SZ;
|
||||||
|
static std::string_view CMODELSHADERS_FRAG_METAL_SV((char*)CMODELSHADERS_FRAG_METAL, CMODELSHADERS_FRAG_METAL_SZ);
|
||||||
|
|
||||||
|
using BlendMaterial = SModelShadersInfo::Material::BlendMaterial;
|
||||||
|
using TexCoordSource = BlendMaterial::TexCoordSource;
|
||||||
|
|
||||||
|
static std::string_view EmitTexGenSource2(TexCoordSource src) {
|
||||||
|
switch (src) {
|
||||||
|
case TexCoordSource::Position:
|
||||||
|
return "objPos.xy"sv;
|
||||||
|
case TexCoordSource::Normal:
|
||||||
|
return "objNorm.xy"sv;
|
||||||
|
case TexCoordSource::Tex0:
|
||||||
|
return "v.uvIn0"sv;
|
||||||
|
case TexCoordSource::Tex1:
|
||||||
|
return "v.uvIn1"sv;
|
||||||
|
case TexCoordSource::Tex2:
|
||||||
|
return "v.uvIn2"sv;
|
||||||
|
case TexCoordSource::Tex3:
|
||||||
|
return "v.uvIn3"sv;
|
||||||
|
case TexCoordSource::Tex4:
|
||||||
|
return "v.uvIn4"sv;
|
||||||
|
case TexCoordSource::Tex5:
|
||||||
|
return "v.uvIn5"sv;
|
||||||
|
case TexCoordSource::Tex6:
|
||||||
|
return "v.uvIn6"sv;
|
||||||
|
case TexCoordSource::Tex7:
|
||||||
|
return "v.uvIn7"sv;
|
||||||
|
default:
|
||||||
|
assert(false && "Unknown source type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string_view EmitTexGenSource4(TexCoordSource src) {
|
||||||
|
switch (src) {
|
||||||
|
case TexCoordSource::Position:
|
||||||
|
return "float4(objPos.xyz, 1.0)"sv;
|
||||||
|
case TexCoordSource::Normal:
|
||||||
|
return "float4(objNorm.xyz, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex0:
|
||||||
|
return "float4(v.uvIn0, 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex1:
|
||||||
|
return "float4(v.uvIn1, 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex2:
|
||||||
|
return "float4(v.uvIn2, 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex3:
|
||||||
|
return "float4(v.uvIn3, 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex4:
|
||||||
|
return "float4(v.uvIn4, 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex5:
|
||||||
|
return "float4(v.uvIn5, 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex6:
|
||||||
|
return "float4(v.uvIn6, 0.0, 1.0)"sv;
|
||||||
|
case TexCoordSource::Tex7:
|
||||||
|
return "float4(v.uvIn7, 0.0, 1.0)"sv;
|
||||||
|
default:
|
||||||
|
assert(false && "Unknown source type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string _BuildVS(const SModelShadersInfo& info) {
|
||||||
|
std::stringstream vertOut;
|
||||||
|
vertOut << CMODELSHADERS_COMMON_METAL_SV;
|
||||||
|
vertOut << "#define URDE_COL_SLOTS "sv << unsigned(info.m_tag.getColorCount()) << '\n';
|
||||||
|
vertOut << "#define URDE_UV_SLOTS "sv << unsigned(info.m_tag.getUvCount()) << '\n';
|
||||||
|
vertOut << "#define URDE_SKIN_SLOTS "sv << unsigned(info.m_tag.getSkinSlotCount()) << '\n';
|
||||||
|
vertOut << "#define URDE_WEIGHT_SLOTS "sv << unsigned(info.m_tag.getWeightCount()) << '\n';
|
||||||
|
|
||||||
|
vertOut << "#define URDE_VERT_DATA_DECL struct VertData {"
|
||||||
|
"float3 posIn [[ attribute(0) ]];"
|
||||||
|
"float3 normIn [[ attribute(1) ]];"sv;
|
||||||
|
for (unsigned i = 0; i < unsigned(info.m_tag.getColorCount()); ++i)
|
||||||
|
vertOut << "float4 colIn"sv << i << " [[ attribute("sv << 2 + i << ") ]];"sv;
|
||||||
|
for (unsigned i = 0; i < unsigned(info.m_tag.getUvCount()); ++i)
|
||||||
|
vertOut << "float2 uvIn"sv << i << " [[ attribute("sv << 2 + info.m_tag.getColorCount() + i << ") ]];"sv;
|
||||||
|
for (unsigned i = 0; i < unsigned(info.m_tag.getWeightCount()); ++i)
|
||||||
|
vertOut << "float4 weightIn"sv << i << " [[ attribute("sv <<
|
||||||
|
2 + info.m_tag.getColorCount() + info.m_tag.getUvCount() + i << ") ]];"sv;
|
||||||
|
vertOut << "};\n"sv;
|
||||||
|
|
||||||
|
if (info.m_tag.getSkinSlotCount()) {
|
||||||
|
vertOut << "#define URDE_WEIGHTING_EXPR "sv;
|
||||||
|
for (unsigned i = 0; i < info.m_tag.getSkinSlotCount(); ++i) {
|
||||||
|
vertOut << "objPos += (vu.objs["sv << i << "] * float4(v.posIn, 1.0)) * v.weightIn"sv << i / 4 << "["sv << i % 4 <<"];"sv;
|
||||||
|
vertOut << "objNorm += (vu.objsInv["sv << i << "] * float4(v.normIn, 1.0)) * v.weightIn"sv << i / 4 << "["sv << i % 4 <<"];"sv;
|
||||||
|
}
|
||||||
|
vertOut << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
vertOut << "#define URDE_TCG_EXPR "sv;
|
||||||
|
using UVAnimType = BlendMaterial::UVAnimType;
|
||||||
|
using PassType = BlendMaterial::PassType;
|
||||||
|
int mtxIdx = 0;
|
||||||
|
for (const auto& chunk : info.m_material.chunks) {
|
||||||
|
if (auto passChunk = chunk.get_if<SModelShadersInfo::Material::PASS>()) {
|
||||||
|
if (passChunk->type != PassType::IndirectTex) {
|
||||||
|
std::string_view tpStr = BlendMaterial::PassTypeToString(passChunk->type);
|
||||||
|
if (passChunk->uvAnimType == UVAnimType::Invalid) {
|
||||||
|
vertOut << "vtf."sv << tpStr << "Uv = "sv << EmitTexGenSource2(passChunk->source) << ";"sv;
|
||||||
|
} else {
|
||||||
|
vertOut << "tmpProj = tu.texMtxs["sv << mtxIdx << "].postMtx * float4("sv <<
|
||||||
|
(passChunk->shouldNormalizeUv() ? "normalize"sv : ""sv) << "((tu.texMtxs["sv << mtxIdx << "].mtx * "sv <<
|
||||||
|
EmitTexGenSource4(passChunk->source) << ").xyz), 1.0);"sv <<
|
||||||
|
"vtf."sv << tpStr << "Uv = (tmpProj / tmpProj.w).xy;"sv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (auto clrChunk = chunk.get_if<SModelShadersInfo::Material::CLR>()) {
|
||||||
|
std::string_view tpStr = BlendMaterial::PassTypeToString(clrChunk->type);
|
||||||
|
vertOut << "vtf."sv << tpStr << "Uv = float2(0.0,0.0);"sv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!info.m_extension.noReflection && info.m_tag.getReflectionType() != hecl::Backend::ReflectionType::None)
|
||||||
|
vertOut << "vtf.dynReflectionUvs0 = normalize((ru.indMtx * float4(objPos.xyz, 1.0)).xz) * float2(0.5, 0.5) + float2(0.5, 0.5);"
|
||||||
|
"vtf.dynReflectionUvs1 = (ru.reflectMtx * float4(objPos.xyz, 1.0)).xy;"
|
||||||
|
"vtf.dynReflectionAlpha = ru.reflectAlpha;";
|
||||||
|
|
||||||
|
for (size_t i = 0; i < info.m_extension.texCount; ++i) {
|
||||||
|
const auto& extTex = info.m_extension.texs[i];
|
||||||
|
if (extTex.mtxIdx == 0xff)
|
||||||
|
vertOut << "vtf.extUvs"sv << i << " = "sv << EmitTexGenSource2(extTex.src) << ";"sv;
|
||||||
|
else
|
||||||
|
vertOut << "tmpProj = tu.texMtxs["sv << unsigned(extTex.mtxIdx) << "].postMtx * float4("sv <<
|
||||||
|
(extTex.normalize ? "normalize"sv : ""sv) << "((tu.texMtxs["sv << unsigned(extTex.mtxIdx) << "].mtx * "sv <<
|
||||||
|
EmitTexGenSource4(extTex.src) << ").xyz), 1.0);"sv <<
|
||||||
|
"vtf.extUvs"sv << i << " = (tmpProj / tmpProj.w).xy;"sv;
|
||||||
|
}
|
||||||
|
vertOut << '\n';
|
||||||
|
|
||||||
|
vertOut << CMODELSHADERS_VERT_METAL_SV;
|
||||||
|
return vertOut.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string _BuildFS(const SModelShadersInfo& info) {
|
||||||
|
std::stringstream fragOut;
|
||||||
|
fragOut << CMODELSHADERS_COMMON_METAL_SV;
|
||||||
|
fragOut << "#define URDE_MAX_LIGHTS " _XSTR(URDE_MAX_LIGHTS) "\n";
|
||||||
|
fragOut << "#define " << info.m_extension.shaderMacro << "\n";
|
||||||
|
|
||||||
|
using ShaderType = BlendMaterial::ShaderType;
|
||||||
|
switch (info.m_material.shaderType) {
|
||||||
|
case ShaderType::RetroShader:
|
||||||
|
fragOut << "#define RETRO_SHADER\n"; break;
|
||||||
|
case ShaderType::RetroDynamicShader:
|
||||||
|
fragOut << "#define RETRO_DYNAMIC_SHADER\n"; break;
|
||||||
|
case ShaderType::RetroDynamicAlphaShader:
|
||||||
|
fragOut << "#define RETRO_DYNAMIC_ALPHA_SHADER\n"; break;
|
||||||
|
case ShaderType::RetroDynamicCharacterShader:
|
||||||
|
fragOut << "#define RETRO_DYNAMIC_CHARACTER_SHADER\n"; break;
|
||||||
|
default:
|
||||||
|
assert(false && "Unknown shader type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragOut << "#define BLEND_SRC_"sv << hecl::Backend::BlendFactorToDefine(
|
||||||
|
hecl::Backend::BlendFactor(info.m_additionalInfo.srcFac), hecl::Backend::BlendFactor::One) << '\n';
|
||||||
|
fragOut << "#define BLEND_DST_"sv << hecl::Backend::BlendFactorToDefine(
|
||||||
|
hecl::Backend::BlendFactor(info.m_additionalInfo.dstFac), hecl::Backend::BlendFactor::Zero) << '\n';
|
||||||
|
|
||||||
|
using PassType = BlendMaterial::PassType;
|
||||||
|
for (const auto& chunk : info.m_material.chunks) {
|
||||||
|
if (auto passChunk = chunk.get_if<SModelShadersInfo::Material::PASS>()) {
|
||||||
|
if (passChunk->alpha) {
|
||||||
|
std::string_view tpStr = BlendMaterial::PassTypeToString(passChunk->type);
|
||||||
|
fragOut << "#define ALPHA_" << tpStr << '\n';
|
||||||
|
}
|
||||||
|
} else if (auto clrChunk = chunk.get_if<SModelShadersInfo::Material::CLR>()) {
|
||||||
|
if (clrChunk->type == PassType::Alpha)
|
||||||
|
fragOut << "#define ALPHA_alpha\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.m_tag.getAlphaTest() || info.m_extension.forceAlphaTest)
|
||||||
|
fragOut << "#define URDE_ALPHA_TEST\n";
|
||||||
|
|
||||||
|
if (info.m_extension.diffuseOnly)
|
||||||
|
fragOut << "#define URDE_DIFFUSE_ONLY\n";
|
||||||
|
|
||||||
|
if (!info.m_extension.noReflection) {
|
||||||
|
if (info.m_tag.getReflectionType() == hecl::Backend::ReflectionType::Indirect)
|
||||||
|
fragOut << "#define URDE_REFLECTION_INDIRECT\n"sv;
|
||||||
|
else if (info.m_tag.getReflectionType() == hecl::Backend::ReflectionType::Simple)
|
||||||
|
fragOut << "#define URDE_REFLECTION_SIMPLE\n"sv;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragOut << CMODELSHADERS_FRAG_METAL_SV;
|
||||||
|
return fragOut.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string StageObject_CModelShaders<hecl::PlatformType::Metal, hecl::PipelineStage::Vertex>::BuildShader(
|
||||||
|
const SModelShadersInfo& in) {
|
||||||
|
return _BuildVS(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string StageObject_CModelShaders<hecl::PlatformType::Metal, hecl::PipelineStage::Fragment>::BuildShader(
|
||||||
|
const SModelShadersInfo& in) {
|
||||||
|
return _BuildFS(in);
|
||||||
|
}
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit a80592249b8a6ace071249824a55a1e979ae3e3d
|
Subproject commit 4c65ccf85be21b9869dcdaea09692ca6677f3204
|
2
nod
2
nod
|
@ -1 +1 @@
|
||||||
Subproject commit 95ed2ae7dc8619054bff5a6d0d63d51f07334943
|
Subproject commit ed28576b99f87551bfd01a00e37b6f8513dd6135
|
2
specter
2
specter
|
@ -1 +1 @@
|
||||||
Subproject commit b32f4975a8f0e5f282339b162069d1fbc15c298d
|
Subproject commit 3d0d62e0324bc881f4ae3058b8ec89c8a2c95a66
|
|
@ -245,7 +245,6 @@ int main(int argc, const char** argv) {
|
||||||
int x11Fd = ConnectionNumber(xDisp);
|
int x11Fd = ConnectionNumber(xDisp);
|
||||||
|
|
||||||
/* Spawn client thread */
|
/* Spawn client thread */
|
||||||
bool clientRunning = true;
|
|
||||||
std::mutex initmt;
|
std::mutex initmt;
|
||||||
std::condition_variable initcv;
|
std::condition_variable initcv;
|
||||||
std::unique_lock<std::mutex> outerLk(initmt);
|
std::unique_lock<std::mutex> outerLk(initmt);
|
||||||
|
@ -260,7 +259,6 @@ int main(int argc, const char** argv) {
|
||||||
XUnlockDisplay(xDisp);
|
XUnlockDisplay(xDisp);
|
||||||
|
|
||||||
renderer.Run(UpdatePercent);
|
renderer.Run(UpdatePercent);
|
||||||
clientRunning = false;
|
|
||||||
|
|
||||||
XLockDisplay(xDisp);
|
XLockDisplay(xDisp);
|
||||||
XClientMessageEvent exitEvent = {};
|
XClientMessageEvent exitEvent = {};
|
||||||
|
@ -270,10 +268,12 @@ int main(int argc, const char** argv) {
|
||||||
XSendEvent(xDisp, windowId, 0, 0, reinterpret_cast<XEvent*>(&exitEvent));
|
XSendEvent(xDisp, windowId, 0, 0, reinterpret_cast<XEvent*>(&exitEvent));
|
||||||
XFlush(xDisp);
|
XFlush(xDisp);
|
||||||
XUnlockDisplay(xDisp);
|
XUnlockDisplay(xDisp);
|
||||||
|
pthread_kill(mainThread, SIGUSR2);
|
||||||
});
|
});
|
||||||
initcv.wait(outerLk);
|
initcv.wait(outerLk);
|
||||||
|
|
||||||
/* Begin application event loop */
|
/* Begin application event loop */
|
||||||
|
bool clientRunning = true;
|
||||||
while (clientRunning) {
|
while (clientRunning) {
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
|
@ -291,6 +291,8 @@ int main(int argc, const char** argv) {
|
||||||
XNextEvent(xDisp, &event);
|
XNextEvent(xDisp, &event);
|
||||||
if (XFilterEvent(&event, None))
|
if (XFilterEvent(&event, None))
|
||||||
continue;
|
continue;
|
||||||
|
if (event.type == ClientMessage)
|
||||||
|
clientRunning = false;
|
||||||
}
|
}
|
||||||
XUnlockDisplay(xDisp);
|
XUnlockDisplay(xDisp);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue