mirror of https://github.com/AxioDL/metaforce.git
Refactor for blender 2.8 and new shader model
This commit is contained in:
parent
1f10769af3
commit
233d13ceb9
|
@ -130,6 +130,13 @@ else()
|
|||
message(STATUS "Building with x87 Vector ISA")
|
||||
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)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
|
||||
-stdlib=libc++ -fsanitize=memory -fsanitize-memory-track-origins -fsanitize-recover=all")
|
||||
|
@ -138,7 +145,7 @@ else()
|
|||
endif()
|
||||
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 \
|
||||
-fno-exceptions -fno-rtti -Werror")
|
||||
-Wno-unused-function -fno-exceptions -fno-rtti -Werror")
|
||||
|
||||
if(APPLE)
|
||||
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(HECL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/hecl/include
|
||||
${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(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::SpecEntMP3PC);
|
||||
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)
|
||||
include(hecl/ApplicationTools.cmake)
|
||||
add_subdirectory(specter/shaders)
|
||||
|
@ -233,6 +245,11 @@ if(NOT TARGET bintoc)
|
|||
find_package(hecl-bintoc REQUIRED)
|
||||
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)
|
||||
add_library(CModelShaders CModelShaders.common.glsl.cpp CModelShaders.vert.glsl.cpp CModelShaders.frag.glsl.cpp)
|
||||
|
||||
if(NOT TARGET atdna)
|
||||
# Import native atdna if cross-compiling
|
||||
find_package(atdna REQUIRED)
|
||||
|
@ -245,13 +262,9 @@ add_definitions(${BOO_SYS_DEFINES})
|
|||
include_directories(${BOO_SYS_INCLUDES})
|
||||
add_subdirectory(amuse)
|
||||
add_subdirectory(specter)
|
||||
set(SPECTER_INCLUDE_DIR specter/include specter/freetype2/include)
|
||||
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}
|
||||
${NOD_INCLUDE_DIR} ${ZEUS_INCLUDE_DIR} ${BOO_INCLUDE_DIR} ${AMUSE_INCLUDE_DIR}
|
||||
${SPECTER_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${BOO_INCLUDE_DIR} ${AMUSE_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/NESEmulator)
|
||||
add_subdirectory(NESEmulator)
|
||||
add_subdirectory(DataSpec)
|
||||
|
|
|
@ -2,6 +2,661 @@
|
|||
|
||||
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:
|
||||
# http://www.metroid2002.com/retromodding/wiki/Materials_(Metroid_Prime)#UV_Animations
|
||||
|
||||
|
@ -18,17 +673,28 @@ def make_uva0():
|
|||
|
||||
# Group outputs
|
||||
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)
|
||||
v_flip = new_grp.nodes.new('ShaderNodeMapping')
|
||||
v_flip.location = (100, 0)
|
||||
v_flip.vector_type = 'TEXTURE'
|
||||
v_flip.scale[1] = -1.0
|
||||
# Vector Transform to bring world space into camera space
|
||||
vec_xf = new_grp.nodes.new('ShaderNodeVectorTransform')
|
||||
vec_xf.location = (100, 0)
|
||||
vec_xf.vector_type = 'NORMAL'
|
||||
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
|
||||
new_grp.links.new(grp_in.outputs[0], v_flip.inputs[0])
|
||||
new_grp.links.new(v_flip.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[0], vec_xf.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
|
||||
def make_uva1():
|
||||
|
@ -45,33 +711,8 @@ def make_uva1():
|
|||
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||
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
|
||||
new_grp.links.new(grp_in.outputs[0], adder.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])
|
||||
new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0])
|
||||
|
||||
# 2 - UV Scroll
|
||||
def make_uva2():
|
||||
|
@ -84,12 +725,19 @@ def make_uva2():
|
|||
|
||||
# Group inputs
|
||||
grp_in = new_grp.nodes.new('NodeGroupInput')
|
||||
grp_in.location = (-100, 0)
|
||||
grp_in.location = (-457, 22)
|
||||
|
||||
# Group outputs
|
||||
grp_out = new_grp.nodes.new('NodeGroupOutput')
|
||||
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 = new_grp.nodes.new('ShaderNodeVectorMath')
|
||||
adder1.operation = 'ADD'
|
||||
|
@ -103,7 +751,8 @@ def make_uva2():
|
|||
# Links
|
||||
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[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(adder2.outputs[0], grp_out.inputs[0])
|
||||
|
||||
|
@ -129,10 +778,18 @@ def make_uva3():
|
|||
add1.operation = 'ADD'
|
||||
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
|
||||
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[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
|
||||
def make_uva4():
|
||||
|
@ -166,7 +823,7 @@ def make_uva4():
|
|||
# Modulo
|
||||
mod1 = new_grp.nodes.new('ShaderNodeMath')
|
||||
mod1.operation = 'MODULO'
|
||||
mod1.inputs[1].default_value = 900.0
|
||||
mod1.inputs[1].default_value = 1.0
|
||||
mod1.location = (-400, 0)
|
||||
|
||||
# Multiply3
|
||||
|
@ -189,17 +846,32 @@ def make_uva4():
|
|||
add1.operation = 'ADD'
|
||||
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
|
||||
new_grp.links.new(grp_in.outputs[0], add1.inputs[1])
|
||||
new_grp.links.new(grp_in.outputs[1], mult1.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], 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(mult2.outputs[0], mod1.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(map1.outputs[0], add1.inputs[0])
|
||||
new_grp.links.new(add1.outputs[0], grp_out.inputs[0])
|
||||
|
@ -236,7 +908,7 @@ def make_uva5():
|
|||
# Modulo
|
||||
mod1 = new_grp.nodes.new('ShaderNodeMath')
|
||||
mod1.operation = 'MODULO'
|
||||
mod1.inputs[1].default_value = 900.0
|
||||
mod1.inputs[1].default_value = 1.0
|
||||
mod1.location = (-400, 0)
|
||||
|
||||
# Multiply3
|
||||
|
@ -259,17 +931,32 @@ def make_uva5():
|
|||
add1.operation = 'ADD'
|
||||
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
|
||||
new_grp.links.new(grp_in.outputs[0], add1.inputs[1])
|
||||
new_grp.links.new(grp_in.outputs[1], mult1.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], 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(mult2.outputs[0], mod1.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(map1.outputs[0], add1.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)
|
||||
|
||||
# Geometry input
|
||||
geom_in = new_grp.nodes.new('ShaderNodeGeometry')
|
||||
geom_in = new_grp.nodes.new('ShaderNodeTexCoord')
|
||||
geom_in.location = (-300, 0)
|
||||
|
||||
# Adder1
|
||||
|
@ -300,7 +987,7 @@ def make_uva6():
|
|||
|
||||
# Links
|
||||
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])
|
||||
|
||||
# 7 - Mode Who Must Not Be Named
|
||||
|
@ -321,7 +1008,7 @@ def make_uva7():
|
|||
grp_out.location = (0, 0)
|
||||
|
||||
# Geometry input
|
||||
geom_in = new_grp.nodes.new('ShaderNodeGeometry')
|
||||
geom_in = new_grp.nodes.new('ShaderNodeTexCoord')
|
||||
geom_in.location = (-1000, 0)
|
||||
|
||||
# View flip
|
||||
|
@ -382,7 +1069,7 @@ def make_uva7():
|
|||
|
||||
# Links
|
||||
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(grp_in.outputs[1], comb2.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], comb2.inputs[1])
|
||||
|
@ -850,6 +1537,8 @@ MP3_PASS_GROUPS = (
|
|||
)
|
||||
|
||||
def make_master_shader_library():
|
||||
for shad in ROOT_SHADER_GROUPS:
|
||||
shad()
|
||||
for uva in UV_ANIMATION_GROUPS:
|
||||
uva()
|
||||
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.hecl_mesh_obj = bpy.context.scene.name\n"
|
||||
"\n"
|
||||
"# Using 'Blender Game'\n"
|
||||
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
|
||||
"\n"
|
||||
"# Clear Scene\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" if ob.type != 'LAMP' and ob.type != 'CAMERA':\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n"
|
||||
"if 'Collection 1' in bpy.data.collections:\n"
|
||||
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||
"\n"
|
||||
"actor_data = bpy.context.scene.hecl_sact_data\n"
|
||||
"arm_obj = None\n",
|
||||
|
@ -143,7 +138,7 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
|
|||
|
||||
/* Attach CMDL to CINF */
|
||||
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_type = 'ARMATURE'\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 */
|
||||
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_type = 'ARMATURE'\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 */
|
||||
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_type = 'ARMATURE'\n"
|
||||
"attachment.linked_mesh = obj.name\n\n";
|
||||
|
|
|
@ -18,42 +18,42 @@ void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLi
|
|||
return;
|
||||
case BabeDeadLight::LightType::Directional:
|
||||
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_obj = bpy.data.objects.new(lamp.name, lamp)\n"
|
||||
"lamp_obj.rotation_mode = 'QUATERNION'\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",
|
||||
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;
|
||||
case BabeDeadLight::LightType::Custom:
|
||||
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_obj = bpy.data.objects.new(lamp.name, lamp)\n"
|
||||
"lamp.shadow_soft_size = 1.0\n"
|
||||
"lamp.shadow_method = '%s'\n"
|
||||
"lamp.use_shadow = %s\n"
|
||||
"\n",
|
||||
s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2],
|
||||
light.castShadows ? "RAY_SHADOW" : "NOSHADOW");
|
||||
light.castShadows ? "True" : "False");
|
||||
break;
|
||||
case BabeDeadLight::LightType::Spot:
|
||||
case BabeDeadLight::LightType::Spot2:
|
||||
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.spot_size = %.6g\n"
|
||||
"lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n"
|
||||
"lamp_obj.rotation_mode = 'QUATERNION'\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_method = '%s'\n"
|
||||
"lamp.use_shadow = %s\n"
|
||||
"\n",
|
||||
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.castShadows ? "RAY_SHADOW" : "NOSHADOW");
|
||||
light.castShadows ? "True" : "False");
|
||||
break;
|
||||
default:
|
||||
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"
|
||||
"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"
|
||||
"bpy.context.scene.objects.link(lamp_obj)\n"
|
||||
"bpy.context.scene.collection.objects.link(lamp_obj)\n"
|
||||
"\n",
|
||||
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]);
|
||||
|
|
|
@ -80,15 +80,12 @@ void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os, const Material
|
|||
hecl::SystemString resPath = pakRouter.getResourceRelativePath(entry, tex);
|
||||
hecl::SystemUTF8Conv resPathView(resPath);
|
||||
os.format(
|
||||
"if '%s' in bpy.data.textures:\n"
|
||||
"if '%s' in bpy.data.images:\n"
|
||||
" image = bpy.data.images['%s']\n"
|
||||
" texture = bpy.data.textures[image.name]\n"
|
||||
"else:\n"
|
||||
" image = bpy.data.images.load('''//%s''')\n"
|
||||
" image.name = '%s'\n"
|
||||
" texture = bpy.data.textures.new(image.name, 'IMAGE')\n"
|
||||
" texture.image = image\n"
|
||||
"texmap_list.append(texture)\n"
|
||||
"texmap_list.append(image)\n"
|
||||
"\n",
|
||||
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,
|
||||
bool solidShading) {
|
||||
void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath) {
|
||||
os << "import math\n"
|
||||
"from mathutils import Vector\n"
|
||||
"\n"
|
||||
"# Using 'Blender Game'\n"
|
||||
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
|
||||
"\n"
|
||||
"# Clear Scene\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" if ob.type != 'LAMP' and ob.type != 'CAMERA':\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n"
|
||||
"if 'Collection 1' in bpy.data.collections:\n"
|
||||
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||
"\n"
|
||||
"def loop_from_facevert(bm, face, vert_idx):\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"
|
||||
" bm_cpy = bm.copy()\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_entry['bm'].verts.ensure_lookup_table()\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"
|
||||
"\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 */
|
||||
os.format(
|
||||
"# 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) {
|
||||
if (meshIdx < 0)
|
||||
os.format(
|
||||
"mesh = bpy.data.meshes.new(bpy.context.scene.name)\n"
|
||||
os << "if 'Render' not in bpy.data.collections:\n"
|
||||
" coll = bpy.data.collections.new('Render')\n"
|
||||
" bpy.context.scene.collection.children.link(coll)\n"
|
||||
"else:\n"
|
||||
" coll = bpy.data.collections['Render']\n";
|
||||
if (meshIdx < 0) {
|
||||
os << "mesh = bpy.data.meshes.new(bpy.context.scene.name)\n"
|
||||
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
|
||||
"obj.show_transparent = True\n"
|
||||
"bpy.context.scene.objects.link(obj)\n"
|
||||
"mesh.hecl_material_count = %u\n",
|
||||
matSetCount);
|
||||
else
|
||||
os.format(
|
||||
"mesh = bpy.data.meshes.new(bpy.context.scene.name + '_%03d')\n"
|
||||
"obj = bpy.data.objects.new(mesh.name, mesh)\n"
|
||||
"coll.objects.link(obj)\n";
|
||||
os.format("mesh.hecl_material_count = %u\n", matSetCount);
|
||||
} else {
|
||||
os.format("mesh = bpy.data.meshes.new(bpy.context.scene.name + '_%03d')\n", meshIdx);
|
||||
os << "obj = bpy.data.objects.new(mesh.name, mesh)\n"
|
||||
"obj.show_transparent = True\n"
|
||||
"bpy.context.scene.objects.link(obj)\n"
|
||||
"mesh.hecl_material_count = %u\n",
|
||||
meshIdx, matSetCount);
|
||||
"coll.objects.link(obj)\n";
|
||||
os.format("mesh.hecl_material_count = %u\n", matSetCount);
|
||||
}
|
||||
|
||||
os << "mesh.use_auto_smooth = True\n"
|
||||
"mesh.auto_smooth_angle = math.pi\n"
|
||||
"mesh.show_edge_sharp = True\n"
|
||||
"\n"
|
||||
"for material in materials:\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"
|
||||
" if len(v.link_faces) == 0:\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"
|
||||
"for edge in bm.edges:\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.hecl_mesh_obj = bpy.context.scene.name\n",
|
||||
pakRouter.getBestEntryName(entry).c_str());
|
||||
InitGeomBlenderContext(os, dataspec.getMasterShaderPath(), false);
|
||||
InitGeomBlenderContext(os, dataspec.getMasterShaderPath());
|
||||
MaterialSet::RegisterMaterialProps(os);
|
||||
|
||||
os << "# Materials\n"
|
||||
|
@ -1142,9 +1127,9 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
|
|||
|
||||
/* Build material sets */
|
||||
std::vector<MaterialSet> matSets;
|
||||
#if 0
|
||||
matSets.reserve(mesh.materialSets.size());
|
||||
{
|
||||
hecl::Frontend::Frontend FE;
|
||||
for (const std::vector<Material>& mset : mesh.materialSets) {
|
||||
matSets.emplace_back();
|
||||
MaterialSet& targetMSet = matSets.back();
|
||||
|
@ -1191,6 +1176,7 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
|
|||
paddingSizes.push_back(secSz32 - secSz);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Vertex Positions */
|
||||
size_t secSz = mesh.pos.size() * 12;
|
||||
|
@ -1435,45 +1421,25 @@ bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& in
|
|||
/* Build material sets */
|
||||
std::vector<MaterialSet> matSets;
|
||||
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 Material& mat : mset) {
|
||||
std::string diagName = hecl::Format("%s:%s", inPath.getLastComponentUTF8().data(), mat.name.c_str());
|
||||
targetMSet.materials.emplace_back(FE, diagName, mat, mat.iprops, texPaths);
|
||||
++targetMSet.materialCount;
|
||||
targetMSet.materials.emplace_back(mat);
|
||||
targetMSet.materials.back().binarySize(endOff);
|
||||
targetMSet.head.addMaterialEndOff(endOff);
|
||||
targetMSet.materialEndOffs.push_back(endOff);
|
||||
}
|
||||
|
||||
for (const hecl::ProjectPath& path : texPaths)
|
||||
targetMSet.head.addTexture(path);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -1614,10 +1580,8 @@ bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::Proje
|
|||
surfCount += mesh.surfaces.size();
|
||||
surfToGlobalMats.reserve(surfCount);
|
||||
|
||||
hecl::Frontend::Frontend FE;
|
||||
size_t endOff = 0;
|
||||
std::vector<hecl::ProjectPath> texPaths;
|
||||
std::vector<hecl::Backend::GX> setBackends;
|
||||
for (const Mesh& mesh : meshes) {
|
||||
if (mesh.materialSets.size()) {
|
||||
std::vector<size_t> meshToGlobalMats;
|
||||
|
@ -1630,28 +1594,24 @@ bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::Proje
|
|||
if (!newMat)
|
||||
continue;
|
||||
|
||||
for (const hecl::ProjectPath& path : mat.texs) {
|
||||
for (const auto& chunk : mat.chunks) {
|
||||
if (auto pass = chunk.get_if<Material::PASS>()) {
|
||||
bool found = false;
|
||||
for (const hecl::ProjectPath& ePath : texPaths) {
|
||||
if (path == ePath) {
|
||||
if (pass->tex == ePath) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
texPaths.push_back(path);
|
||||
texPaths.push_back(pass->tex);
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
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.head.addMaterialEndOff(endOff);
|
||||
|
@ -1917,10 +1877,8 @@ bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::P
|
|||
surfCount += mesh.surfaces.size();
|
||||
surfToGlobalMats.reserve(surfCount);
|
||||
|
||||
MaterialSet matSet;
|
||||
hecl::Frontend::Frontend FE;
|
||||
MaterialSet matSet = {};
|
||||
size_t endOff = 0;
|
||||
std::vector<hecl::ProjectPath> texPaths;
|
||||
for (const Mesh& mesh : meshes) {
|
||||
if (mesh.materialSets.size()) {
|
||||
std::vector<size_t> meshToGlobalMats;
|
||||
|
@ -1933,30 +1891,16 @@ bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::P
|
|||
if (!newMat)
|
||||
continue;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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.materialCount;
|
||||
matSet.materials.emplace_back(mat);
|
||||
matSet.materials.back().binarySize(endOff);
|
||||
matSet.head.addMaterialEndOff(endOff);
|
||||
matSet.materialEndOffs.push_back(endOff);
|
||||
}
|
||||
|
||||
for (const Mesh::Surface& surf : mesh.surfaces)
|
||||
surfToGlobalMats.push_back(meshToGlobalMats[surf.materialIdx]);
|
||||
}
|
||||
}
|
||||
for (const hecl::ProjectPath& path : texPaths)
|
||||
matSet.head.addTexture(path);
|
||||
|
||||
size_t secSz = 0;
|
||||
matSet.binarySize(secSz);
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "athena/FileWriter.hpp"
|
||||
#include "hecl/Frontend.hpp"
|
||||
#include "hecl/Backend/GX.hpp"
|
||||
#include "PAK.hpp"
|
||||
#include "GX.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,
|
||||
const typename PAKRouter::EntryType& entry, unsigned setIdx);
|
||||
|
||||
void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath,
|
||||
bool solidShading);
|
||||
void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath);
|
||||
void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx);
|
||||
|
||||
template <class PAKRouter, class MaterialSet, class RigPair, class SurfaceHeader>
|
||||
|
|
|
@ -13,7 +13,7 @@ make_dnalist(liblist DNACommon
|
|||
set(DNACOMMON_SOURCES
|
||||
DNACommon.hpp DNACommon.cpp
|
||||
PAK.hpp PAK.cpp
|
||||
GX.hpp
|
||||
GX.hpp GX.cpp
|
||||
FSM2.hpp FSM2.cpp
|
||||
MLVL.hpp MLVL.cpp
|
||||
CMDL.cpp
|
||||
|
|
|
@ -75,18 +75,18 @@ void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, b
|
|||
" mat = material_dict[mat_name]\n"
|
||||
" col_mesh.materials.append(mat)\n"
|
||||
"\n"
|
||||
"bpy.context.scene.objects.link(col_mesh_obj)\n"
|
||||
"bpy.context.scene.objects.active = col_mesh_obj\n"
|
||||
"if 'Collision' not in bpy.data.collections:\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.mesh.tris_convert_to_quads()\n"
|
||||
"bpy.ops.object.mode_set(mode='OBJECT')\n"
|
||||
"bpy.context.scene.objects.active = None\n";
|
||||
if (!isDcln)
|
||||
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"
|
||||
"bpy.context.view_layer.objects.active = None\n"
|
||||
"col_mesh_obj.display_type = 'SOLID'\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
|
||||
#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)],"
|
||||
"name='Retro: Map Object Visibility Mode')\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"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" if ob.type != 'CAMERA':\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n"
|
||||
"if 'Collection 1' in bpy.data.collections:\n"
|
||||
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||
"\n"
|
||||
"def add_triangle(bm, 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]);
|
||||
os.format(
|
||||
"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_mapobj_vis_mode = '%s'\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]);
|
||||
os.format(
|
||||
"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_mapobj_vis_mode = '%s'\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"
|
||||
"mesh.show_edge_seams = True\n"
|
||||
"obj = bpy.data.objects.new(mesh.name, 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";
|
||||
|
||||
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"
|
||||
"\n"
|
||||
"# Clear Scene\n"
|
||||
"bpy.context.scene.camera = None\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n"
|
||||
"if 'Collection 1' in bpy.data.collections:\n"
|
||||
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||
"\n"
|
||||
"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"
|
||||
|
@ -53,7 +51,7 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
|
|||
"wldObj.scale = mtxd[2]\n"
|
||||
"wldObj.retro_mapworld_color = (%f, %f, %f, %f)\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],
|
||||
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());
|
||||
|
@ -70,7 +68,7 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
|
|||
"obj.location = mtxd[0]\n"
|
||||
"obj.rotation_quaternion = mtxd[1]\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",
|
||||
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]);
|
||||
|
@ -81,7 +79,6 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
|
|||
" for area in screen.areas:\n"
|
||||
" for space in area.spaces:\n"
|
||||
" if space.type == 'VIEW_3D':\n"
|
||||
" space.viewport_shade = 'SOLID'\n"
|
||||
" space.clip_end = 8000.0\n";
|
||||
|
||||
os.centerView();
|
||||
|
|
|
@ -18,18 +18,15 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const
|
|||
if (!conn.createBlend(blendPath, hecl::blender::BlendType::World))
|
||||
return false;
|
||||
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
|
||||
os.format(
|
||||
"import bpy\n"
|
||||
os << "import bpy\n"
|
||||
"import bmesh\n"
|
||||
"from mathutils import Matrix\n"
|
||||
"\n"
|
||||
"bpy.context.scene.name = 'World'\n"
|
||||
"\n"
|
||||
"# Clear Scene\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" if ob.type != 'CAMERA':\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n");
|
||||
"if 'Collection 1' in bpy.data.collections:\n"
|
||||
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n";
|
||||
|
||||
/* Insert area empties */
|
||||
int areaIdx = 0;
|
||||
|
@ -46,7 +43,7 @@ bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const
|
|||
"bm.to_mesh(box_mesh)\n"
|
||||
"bm.free()\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"
|
||||
"mtxd = mtx.decompose()\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.format("dockMesh = bpy.data.meshes.new('DOCK_%02d_%02d')\n", areaIdx, dockIdx);
|
||||
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.free()\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);
|
||||
if (overrideSearch != m_overrideEntries.end()) {
|
||||
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();
|
||||
|
|
|
@ -34,7 +34,7 @@ void CINF::sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const {
|
|||
for (atUint32 bid : boneIds) {
|
||||
for (const Name& name : names) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -47,8 +47,8 @@ void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& c
|
|||
os.format(
|
||||
"arm = bpy.data.armatures.new('CINF_%08X')\n"
|
||||
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
|
||||
"bpy.context.scene.objects.link(arm_obj)\n"
|
||||
"bpy.context.scene.objects.active = arm_obj\n"
|
||||
"bpy.context.scene.collection.objects.link(arm_obj)\n"
|
||||
"bpy.context.view_layer.objects.active = arm_obj\n"
|
||||
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
||||
"arm_bone_table = {}\n",
|
||||
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";
|
||||
|
||||
const char* rotMode = os.getConnection().hasSLERP() ? "QUATERNION_SLERP" : "QUATERNION";
|
||||
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(),
|
||||
rotMode);
|
||||
os.format("arm_obj.pose.bones['%s'].rotation_mode = 'QUATERNION'\n",
|
||||
getBoneNameFromId(bone.m_origBone.id)->c_str());
|
||||
}
|
||||
|
||||
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.writeUint32Big(skinMesh.skins.size());
|
||||
for (const std::vector<DNACMDL::Mesh::SkinBind> skin : skinMesh.skins) {
|
||||
writer.writeUint32Big(skin.size());
|
||||
for (const DNACMDL::Mesh::SkinBind& bind : skin) {
|
||||
writer.writeUint32Big(bind.boneIdx);
|
||||
writer.writeFloatBig(bind.weight);
|
||||
for (const auto& skin : skinMesh.skins) {
|
||||
size_t numBinds = skinMesh.countSkinBinds(skin);
|
||||
writer.writeUint32Big(numBinds);
|
||||
for (size_t i = 0; i < numBinds; ++i) {
|
||||
writer.writeUint32Big(skin[i].vg_idx);
|
||||
writer.writeFloatBig(skin[i].weight);
|
||||
}
|
||||
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) */
|
||||
writer.writeUint32Big(mesh.skins.size());
|
||||
for (auto& s : mesh.skins) {
|
||||
writer.writeUint32Big(s.size());
|
||||
for (auto& b : s) {
|
||||
writer.writeUint32Big(b.boneIdx);
|
||||
writer.writeFloatBig(b.weight);
|
||||
size_t numBinds = mesh.countSkinBinds(s);
|
||||
writer.writeUint32Big(numBinds);
|
||||
for (size_t i = 0; i < numBinds; ++i) {
|
||||
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/CMDL.hpp"
|
||||
#include "DNAMP1.hpp"
|
||||
#include "hecl/Blender/Connection.hpp"
|
||||
|
||||
namespace DataSpec::DNAMP1 {
|
||||
|
||||
|
@ -60,7 +61,7 @@ struct MaterialSet : BigDNA {
|
|||
flags |= atUint32(enabled) << 4;
|
||||
}
|
||||
bool alphaTest() const { return (flags & 0x20) != 0; }
|
||||
void setPunchthroughAlpha(bool enabled) {
|
||||
void setAlphaTest(bool enabled) {
|
||||
flags &= ~0x20;
|
||||
flags |= atUint32(enabled) << 5;
|
||||
}
|
||||
|
@ -468,8 +469,8 @@ struct MaterialSet : BigDNA {
|
|||
static void AddDynamicAlpha(hecl::blender::PyOutStream& out, unsigned idx);
|
||||
|
||||
Material() = default;
|
||||
Material(const hecl::Backend::GX& gx, const std::unordered_map<std::string, int32_t>& iprops,
|
||||
const std::vector<hecl::ProjectPath>& texPathsIn, std::vector<hecl::ProjectPath>& texPathsOut,
|
||||
Material(const hecl::blender::Material& material,
|
||||
std::vector<hecl::ProjectPath>& texPathsOut,
|
||||
int colorCount, bool lightmapUVs, bool matrixSkinning);
|
||||
};
|
||||
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
|
||||
|
@ -528,29 +529,114 @@ struct HMDLMaterialSet : BigDNA {
|
|||
static constexpr bool OneSection() { return false; }
|
||||
|
||||
AT_DECL_DNA
|
||||
MaterialSet::MaterialSetHead head;
|
||||
Value<atUint32> materialCount = 0;
|
||||
Vector<atUint32, AT_DNA_COUNT(materialCount)> materialEndOffs;
|
||||
|
||||
struct Material : BigDNA {
|
||||
AT_DECL_DNA
|
||||
MaterialSet::Material::Flags flags;
|
||||
|
||||
Value<atUint32> textureCount = 0;
|
||||
Vector<atUint32, AT_DNA_COUNT(textureCount)> textureIdxs;
|
||||
using BlendMaterial = hecl::blender::Material;
|
||||
|
||||
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;
|
||||
Value<atUint32> uvAnimsCount = 0;
|
||||
Vector<MaterialSet::Material::UVAnimation, AT_DNA_COUNT(uvAnimsCount)> uvAnims;
|
||||
static unsigned TexMapIdx(BlendMaterial::PassType type) {
|
||||
switch (type) {
|
||||
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;
|
||||
hecl::Frontend::IR heclIr;
|
||||
Value<atUint64> hash;
|
||||
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(hecl::Frontend::Frontend& FE, const std::string& diagName, const hecl::blender::Material& mat,
|
||||
const std::unordered_map<std::string, int32_t>& iprops, const std::vector<hecl::ProjectPath>& texPaths);
|
||||
Material(const hecl::blender::Material& mat);
|
||||
};
|
||||
Vector<Material, AT_DNA_COUNT(head.materialCount)> materials;
|
||||
Vector<Material, AT_DNA_COUNT(materialCount)> materials;
|
||||
};
|
||||
|
||||
} // 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 {
|
||||
os.format(
|
||||
"obj = bpy.data.objects.new('%s', None)\n"
|
||||
"obj.empty_draw_type = 'CUBE'\n"
|
||||
"bpy.context.scene.objects.link(obj)\n"
|
||||
"obj.empty_display_type = 'CUBE'\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"
|
||||
"mtxd = mtx.decompose()\n"
|
||||
"obj.rotation_mode = 'QUATERNION'\n"
|
||||
|
@ -27,29 +27,6 @@ void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const
|
|||
}
|
||||
#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) {
|
||||
/* Open Py Stream and read sections */
|
||||
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
|
||||
|
@ -60,10 +37,8 @@ void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
|
|||
"\n"
|
||||
"bpy.context.scene.name = '%s'\n"
|
||||
"# Clear Scene\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" if ob.type != 'CAMERA':\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n",
|
||||
"if 'Collection 1' in bpy.data.collections:\n"
|
||||
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n",
|
||||
entryName.data());
|
||||
|
||||
DeafBabe::BlenderInit(os);
|
||||
|
|
|
@ -91,4 +91,27 @@ struct DCLN : BigDNA {
|
|||
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
|
||||
|
|
|
@ -25,12 +25,15 @@ void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) {
|
|||
" 'Organic':(0.19, 0.45, 0.2)}\n"
|
||||
"\n"
|
||||
"# Diffuse Color Maker\n"
|
||||
"from mathutils import Color\n"
|
||||
"def make_color(index, mat_type, name):\n"
|
||||
" new_mat = bpy.data.materials.new(name)\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"
|
||||
" 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"
|
||||
"\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"
|
||||
" else:\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_surface_stone = ((data >> 1) & 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"
|
||||
"from mathutils import Matrix, Quaternion\n"
|
||||
"# Clear Scene\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" if ob.type != 'CAMERA':\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n"
|
||||
"if 'Collection 1' in bpy.data.collections:\n"
|
||||
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||
"\n"
|
||||
"def duplicateObject(copy_obj):\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.location = copy_obj.location\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";
|
||||
|
||||
os.format(
|
||||
"bpy.context.scene.name = '%s'\n"
|
||||
"bpy.context.scene.render.resolution_x = 640\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.render.engine = 'BLENDER_GAME'\n"
|
||||
"bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n"
|
||||
"bg_node.inputs[1].default_value = 0.0\n",
|
||||
pakRouter.getBestEntryName(entry).c_str());
|
||||
|
@ -377,12 +373,11 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
|||
default: {
|
||||
zeus::simd_floats colorF(w.header.color.simd);
|
||||
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.falloff_type = 'INVERSE_COEFFICIENTS'\n"
|
||||
"lamp.constant_coefficient = %f\n"
|
||||
"lamp.linear_coefficient = %f\n"
|
||||
"lamp.quadratic_coefficient = %f\n"
|
||||
"lamp.hecl_falloff_constant = %f\n"
|
||||
"lamp.hecl_falloff_linear = %f\n"
|
||||
"lamp.hecl_falloff_quadratic = %f\n"
|
||||
"lamp.retro_light_angle_constant = %f\n"
|
||||
"lamp.retro_light_angle_linear = %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",
|
||||
info->cutoff);
|
||||
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(
|
||||
"material = bpy.data.materials.new('%s')\n"
|
||||
"material.specular_intensity = 0.0\n"
|
||||
"tex_slot = material.texture_slots.add()\n"
|
||||
"tex_slot.texture = bpy.data.textures.new('%s', 'IMAGE')\n"
|
||||
"tex_slot.texture.image = image\n"
|
||||
"material.active_texture = tex_slot.texture\n"
|
||||
"material.use_nodes = True\n"
|
||||
"new_nodetree = material.node_tree\n"
|
||||
"for n in new_nodetree.nodes:\n"
|
||||
" new_nodetree.nodes.remove(n)\n"
|
||||
"tex_node = new_nodetree.nodes.new('ShaderNodeTexImage')\n"
|
||||
"tex_node.image = image\n"
|
||||
"bm = bmesh.new()\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) {
|
||||
int ti;
|
||||
|
@ -511,12 +507,12 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
|||
os << "print(obj.name)\n"
|
||||
"copy_obj = duplicateObject(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')) {
|
||||
os << "bpy.context.scene.camera = frme_obj\n"
|
||||
"if 'Camera' in bpy.data.objects:\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";
|
||||
} else if (w.type == SBIG('PANE')) {
|
||||
using PANEInfo = Widget::PANEInfo;
|
||||
|
@ -611,9 +607,9 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
|||
"mtxd = mtx.decompose()\n"
|
||||
"frme_obj.rotation_mode = 'QUATERNION'\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"
|
||||
"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[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());
|
||||
for (const std::pair<hecl::ProjectPath, bool>& path : layer) {
|
||||
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 (path.second)
|
||||
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);
|
||||
|
||||
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 (path.second)
|
||||
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"));
|
||||
urde::SObjectTag pathTag = g_curSpec->buildTagFromPath(pathPath, btok);
|
||||
urde::SObjectTag pathTag = g_curSpec->buildTagFromPath(pathPath);
|
||||
if (pathTag.id.IsValid()) {
|
||||
areaOut.deps.emplace_back(pathTag.id.Value(), pathTag.type);
|
||||
areaOut.lazyDeps.emplace_back(0, FOURCC('NONE'));
|
||||
|
@ -369,7 +369,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
|
|||
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;
|
||||
mapaTags.reserve(wld.areas.size());
|
||||
|
||||
|
@ -380,7 +380,7 @@ bool MLVL::CookMAPW(const hecl::ProjectPath& outPath, const World& wld, hecl::bl
|
|||
/* Area map */
|
||||
hecl::ProjectPath mapPath(area.path, _SYS_STR("/!map.blend"));
|
||||
if (mapPath.isFile())
|
||||
mapaTags.push_back(g_curSpec->buildTagFromPath(mapPath, btok));
|
||||
mapaTags.push_back(g_curSpec->buildTagFromPath(mapPath));
|
||||
}
|
||||
|
||||
/* Write out MAPW */
|
||||
|
|
|
@ -136,7 +136,7 @@ struct MLVL : BigDNA {
|
|||
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld,
|
||||
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);
|
||||
};
|
||||
|
|
|
@ -21,9 +21,7 @@ void MREA::ReadBabeDeadToBlender_1_2(hecl::blender::PyOutStream& os, athena::io:
|
|||
atUint32 bdMagic = rs.readUint32Big();
|
||||
if (bdMagic != 0xBABEDEAD)
|
||||
Log.report(logvisor::Fatal, "invalid BABEDEAD magic");
|
||||
os << "bpy.context.scene.render.engine = 'CYCLES'\n"
|
||||
"bpy.context.scene.world.use_nodes = True\n"
|
||||
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
|
||||
os << "bpy.context.scene.world.use_nodes = True\n"
|
||||
"bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n"
|
||||
"bg_node.inputs[1].default_value = 0.0\n";
|
||||
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();
|
||||
os.format(
|
||||
"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.scale = (%f,%f,%f)\n"
|
||||
"obj.empty_draw_type = 'CUBE'\n"
|
||||
"obj.empty_display_type = 'CUBE'\n"
|
||||
"obj.layers[1] = True\n"
|
||||
"obj.layers[0] = False\n",
|
||||
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();
|
||||
os.format(
|
||||
"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.scale = (%f,%f,%f)\n"
|
||||
"obj.empty_draw_type = 'CUBE'\n"
|
||||
"obj.empty_display_type = 'CUBE'\n"
|
||||
"obj.layers[1] = True\n"
|
||||
"obj.layers[0] = False\n",
|
||||
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 */
|
||||
hecl::blender::PyOutStream os = conn.beginPythonOut(true);
|
||||
os.format(
|
||||
"import bpy\n"
|
||||
os << "import bpy\n"
|
||||
"import bmesh\n"
|
||||
"from mathutils import Vector\n"
|
||||
"\n"
|
||||
"bpy.context.scene.name = '%s'\n",
|
||||
"bpy.context.scene.render.fps = 60\n"
|
||||
"\n";
|
||||
os.format("bpy.context.scene.name = '%s'\n",
|
||||
pakRouter.getBestEntryName(entry, false).c_str());
|
||||
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath(), true);
|
||||
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath());
|
||||
MaterialSet::RegisterMaterialProps(os);
|
||||
os << "# Clear Scene\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" if ob.type != 'CAMERA':\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n"
|
||||
"bpy.types.Lamp.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
|
||||
"bpy.types.Lamp.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n"
|
||||
"if 'Collection 1' in bpy.data.collections:\n"
|
||||
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||
"\n"
|
||||
"bpy.types.Light.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.Object.retro_disable_enviro_visor = bpy.props.BoolProperty(name='Retro: Disable in Combat/Scan "
|
||||
"Visor')\n"
|
||||
"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 */
|
||||
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.origin_set(type='ORIGIN_CENTER_OF_MASS')\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 */
|
||||
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)
|
||||
w.writeUint32Big(vert.iPos);
|
||||
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();
|
||||
os.format(
|
||||
"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.scale = (%f,%f,%f)\n"
|
||||
"obj.empty_draw_type = 'CUBE'\n"
|
||||
"obj.empty_display_type = 'CUBE'\n"
|
||||
"obj.layers[1] = True\n"
|
||||
"obj.layers[0] = False\n", idx,
|
||||
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"
|
||||
"def make_ground_material(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"
|
||||
"def make_flyer_material(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"
|
||||
"def make_swimmer_material(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"
|
||||
"def select_material(meshIdxMask, meshTypeMask):\n"
|
||||
" key = (meshIdxMask, meshTypeMask)\n"
|
||||
|
@ -71,10 +71,8 @@ void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
|
|||
"\n"
|
||||
"bpy.context.scene.name = '%s'\n"
|
||||
"# Clear Scene\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" if ob.type != 'CAMERA':\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n"
|
||||
"if 'Collection 1' in bpy.data.collections:\n"
|
||||
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||
"\n"
|
||||
"bm = bmesh.new()\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"
|
||||
"aabb.location = (%f,%f,%f)\n"
|
||||
"aabb.scale = (%f,%f,%f)\n"
|
||||
"aabb.empty_draw_type = 'CUBE'\n"
|
||||
"bpy.context.scene.objects.link(aabb)\n"
|
||||
"aabb.empty_display_type = 'CUBE'\n"
|
||||
"bpy.context.scene.collection.objects.link(aabb)\n"
|
||||
"centr = bpy.data.objects.new('Center', None)\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[1] + (aabb.max[1] - aabb.min[1]) / 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"
|
||||
" path_mesh.materials.append(mat)\n"
|
||||
"\n"
|
||||
"bpy.context.scene.objects.link(path_mesh_obj)\n"
|
||||
"path_mesh_obj.draw_type = 'SOLID'\n"
|
||||
"path_mesh_obj.game.physics_type = 'STATIC'\n"
|
||||
"path_mesh_obj.layers[1] = True\n"
|
||||
"bpy.context.scene.collection.objects.link(path_mesh_obj)\n"
|
||||
"path_mesh_obj.display_type = 'SOLID'\n"
|
||||
"bpy.context.scene.hecl_path_obj = path_mesh_obj.name\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";
|
||||
|
||||
if (xf) {
|
||||
const zeus::CMatrix4f& w = *xf;
|
||||
|
|
|
@ -34,7 +34,7 @@ void CINF::sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const {
|
|||
for (atUint32 bid : boneIds) {
|
||||
for (const Name& name : names) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -47,8 +47,8 @@ void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& c
|
|||
os.format(
|
||||
"arm = bpy.data.armatures.new('CINF_%08X')\n"
|
||||
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
|
||||
"bpy.context.scene.objects.link(arm_obj)\n"
|
||||
"bpy.context.scene.objects.active = arm_obj\n"
|
||||
"bpy.context.scene.collection.objects.link(arm_obj)\n"
|
||||
"bpy.context.view_layer.objects.active = arm_obj\n"
|
||||
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
||||
"arm_bone_table = {}\n",
|
||||
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";
|
||||
|
||||
const char* rotMode = os.getConnection().hasSLERP() ? "QUATERNION_SLERP" : "QUATERNION";
|
||||
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(),
|
||||
rotMode);
|
||||
os.format("arm_obj.pose.bones['%s'].rotation_mode = 'QUATERNION'\n",
|
||||
getBoneNameFromId(bone.m_origBone.id)->c_str());
|
||||
}
|
||||
|
||||
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"
|
||||
" else:\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_surface_stone = ((data >> 1) & 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"
|
||||
"bpy.context.scene.name = '%s'\n",
|
||||
pakRouter.getBestEntryName(entry, false).c_str());
|
||||
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath(), true);
|
||||
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath());
|
||||
MaterialSet::RegisterMaterialProps(os);
|
||||
os << "# Clear Scene\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" if ob.type != 'CAMERA':\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n"
|
||||
"bpy.types.Lamp.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
|
||||
"bpy.types.Lamp.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n"
|
||||
"if 'Collection 1' in bpy.data.collections:\n"
|
||||
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||
"\n"
|
||||
"bpy.types.Light.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.Object.retro_disable_enviro_visor = bpy.props.BoolProperty(name='Retro: Disable in Combat/Scan "
|
||||
"Visor')\n"
|
||||
"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);
|
||||
|
||||
/* 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.origin_set(type='ORIGIN_CENTER_OF_MASS')\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.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
|
||||
"')\n"
|
||||
"arm_obj = bpy.data.objects.new(arm.name, arm)\n"
|
||||
"bpy.context.scene.objects.link(arm_obj)\n"
|
||||
"bpy.context.scene.objects.active = arm_obj\n"
|
||||
"bpy.context.scene.collection.objects.link(arm_obj)\n"
|
||||
"bpy.context.view_layer.objects.active = arm_obj\n"
|
||||
"bpy.ops.object.mode_set(mode='EDIT')\n"
|
||||
"arm_bone_table = {}\n",
|
||||
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";
|
||||
|
||||
const char* rotMode = os.getConnection().hasSLERP() ? "QUATERNION_SLERP" : "QUATERNION";
|
||||
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(),
|
||||
rotMode);
|
||||
os.format("arm_obj.pose.bones['%s'].rotation_mode = 'QUATERNION'\n",
|
||||
getBoneNameFromId(bone.m_origBone.id)->c_str());
|
||||
}
|
||||
|
||||
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_transparent_shadows = True\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_nodetree = new_material.node_tree\n"
|
||||
"material_node = new_nodetree.nodes['Material']\n"
|
||||
|
@ -112,22 +110,16 @@ void MaterialSet::ConstructMaterial(Stream& out, const PAKRouter<PAKBridge>& pak
|
|||
out.format(
|
||||
"new_material.retro_alpha_test = %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.shadowOccluderMesh() ? "True" : "False",
|
||||
material.header.flags.shadowOccluderMesh() ? "True" : "False");
|
||||
material.header.flags.shadowOccluderMesh() ? "0" : "1");
|
||||
|
||||
/* Blend factors */
|
||||
if (material.header.flags.alphaBlending())
|
||||
out << "new_material.game_settings.alpha_blend = 'ALPHA'\n"
|
||||
"new_material.use_transparency = True\n"
|
||||
"new_material.transparency_method = 'RAYTRACE'\n"
|
||||
"new_material.alpha = 1.0\n";
|
||||
out << "new_material.blend_method = 'BLEND'\n";
|
||||
else if (material.header.flags.additiveBlending())
|
||||
out << "new_material.game_settings.alpha_blend = 'ADD'\n"
|
||||
"new_material.use_transparency = True\n"
|
||||
"new_material.transparency_method = 'RAYTRACE'\n"
|
||||
"new_material.alpha = 1.0\n";
|
||||
out << "new_material.blend_method = 'ADD'\n";
|
||||
|
||||
/* Texmap list */
|
||||
out << "tex_maps = []\n"
|
||||
|
|
|
@ -43,9 +43,7 @@ void MREA::ReadBabeDeadToBlender_3(hecl::blender::PyOutStream& os, athena::io::I
|
|||
atUint32 bdMagic = rs.readUint32Big();
|
||||
if (bdMagic != 0xBABEDEAD)
|
||||
Log.report(logvisor::Fatal, "invalid BABEDEAD magic");
|
||||
os << "bpy.context.scene.render.engine = 'CYCLES'\n"
|
||||
"bpy.context.scene.world.use_nodes = True\n"
|
||||
"bpy.context.scene.render.engine = 'BLENDER_GAME'\n"
|
||||
os << "bpy.context.scene.world.use_nodes = True\n"
|
||||
"bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n"
|
||||
"bg_node.inputs[1].default_value = 0.0\n";
|
||||
for (atUint32 s = 0; s < 4; ++s) {
|
||||
|
@ -102,15 +100,14 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
|
|||
"\n"
|
||||
"bpy.context.scene.name = '%s'\n",
|
||||
pakRouter.getBestEntryName(entry, false).c_str());
|
||||
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath(), true);
|
||||
DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath());
|
||||
MaterialSet::RegisterMaterialProps(os);
|
||||
os << "# Clear Scene\n"
|
||||
"for ob in bpy.data.objects:\n"
|
||||
" if ob.type != 'CAMERA':\n"
|
||||
" bpy.context.scene.objects.unlink(ob)\n"
|
||||
" bpy.data.objects.remove(ob)\n"
|
||||
"bpy.types.Lamp.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
|
||||
"bpy.types.Lamp.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n"
|
||||
"if 'Collection 1' in bpy.data.collections:\n"
|
||||
" bpy.data.collections.remove(bpy.data.collections['Collection 1'])\n"
|
||||
"\n"
|
||||
"bpy.types.Light.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n"
|
||||
"bpy.types.Light.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n"
|
||||
"\n";
|
||||
|
||||
/* 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 */
|
||||
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.origin_set(type='ORIGIN_CENTER_OF_MASS')\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.close();
|
||||
|
|
|
@ -193,7 +193,7 @@ static bool IsPathSong(const hecl::ProjectPath& path) {
|
|||
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))
|
||||
return false;
|
||||
|
||||
|
@ -205,16 +205,9 @@ bool SpecBase::canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok
|
|||
|
||||
if (hecl::IsPathBlend(asBlend)) {
|
||||
hecl::blender::BlendType type = hecl::blender::GetBlendType(asBlend.getAbsolutePath());
|
||||
if (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;
|
||||
return type != hecl::blender::BlendType::None;
|
||||
}
|
||||
|
||||
/* Non-CMDLs shall not pass */
|
||||
if (cookPass == 0)
|
||||
return false;
|
||||
|
||||
if (hecl::IsPathPNG(path)) {
|
||||
return true;
|
||||
} 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* oldEntry,
|
||||
hecl::blender::Token& btok) const {
|
||||
const hecl::Database::DataSpecEntry* oldEntry) const {
|
||||
if (!checkPathPrefix(path))
|
||||
return nullptr;
|
||||
|
||||
|
@ -487,7 +479,7 @@ void SpecBase::recursiveBuildResourceList(std::vector<urde::SObjectTag>& listOut
|
|||
if (hecl::ProjectPath(childPath, _SYS_STR("!project.yaml")).isFile() &&
|
||||
hecl::ProjectPath(childPath, _SYS_STR("!pool.yaml")).isFile()) {
|
||||
/* Handle AudioGroup case */
|
||||
if (urde::SObjectTag tag = tagFromPath(childPath, btok)) {
|
||||
if (urde::SObjectTag tag = tagFromPath(childPath)) {
|
||||
if (addedTags.find(tag) != addedTags.end())
|
||||
continue;
|
||||
addedTags.insert(tag);
|
||||
|
@ -501,7 +493,7 @@ void SpecBase::recursiveBuildResourceList(std::vector<urde::SObjectTag>& listOut
|
|||
std::vector<hecl::ProjectPath> subPaths;
|
||||
flattenDependencies(childPath, subPaths, btok);
|
||||
for (const auto& subPath : subPaths) {
|
||||
if (urde::SObjectTag tag = tagFromPath(subPath, btok)) {
|
||||
if (urde::SObjectTag tag = tagFromPath(subPath)) {
|
||||
if (addedTags.find(tag) != addedTags.end())
|
||||
continue;
|
||||
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::vector<std::pair<urde::SObjectTag, std::string>> nameList;
|
||||
for (const auto& subPath : subPaths) {
|
||||
if (urde::SObjectTag tag = tagFromPath(subPath, btok)) {
|
||||
if (urde::SObjectTag tag = tagFromPath(subPath)) {
|
||||
if (addedTags.find(tag) != addedTags.end())
|
||||
continue;
|
||||
addedTags.insert(tag);
|
||||
|
@ -664,20 +656,30 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
|
|||
if (cp) {
|
||||
Log.report(logvisor::Info, _SYS_STR("Validating resources"));
|
||||
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;
|
||||
addedTags.reserve(buildList.size());
|
||||
for (auto& tag : buildList) {
|
||||
if ((i == 0 && tag.type == FOURCC('CMDL')) ||
|
||||
(i == 1 && tag.type != FOURCC('CMDL'))) {
|
||||
if (addedTags.find(tag) != addedTags.end())
|
||||
continue;
|
||||
addedTags.insert(tag);
|
||||
cookTags.push_back(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Cook ordered tags */
|
||||
for (auto& tag : cookTags) {
|
||||
hecl::ProjectPath depPath = pathFromTag(tag);
|
||||
if (!depPath) {
|
||||
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, i);
|
||||
}
|
||||
m_project.cookPath(depPath, progress, false, false, fast, entry, cp);
|
||||
}
|
||||
progress.setMainIndeterminate(false);
|
||||
cp->waitUntilComplete();
|
||||
|
@ -699,7 +701,7 @@ void SpecBase::interruptCook() { cancelBackgroundIndex(); }
|
|||
hecl::ProjectPath SpecBase::getCookedPath(const hecl::ProjectPath& working, bool pcTarget) const {
|
||||
const hecl::Database::DataSpecEntry* spec = &getOriginalSpec();
|
||||
if (pcTarget)
|
||||
spec = overrideDataSpec(working, getDataSpecEntry(), hecl::blender::SharedBlenderToken);
|
||||
spec = overrideDataSpec(working, getDataSpecEntry());
|
||||
if (!spec)
|
||||
return {};
|
||||
return working.getCookedPath(*spec);
|
||||
|
@ -771,11 +773,11 @@ hecl::ProjectPath SpecBase::pathFromTag(const urde::SObjectTag& tag) const {
|
|||
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());
|
||||
if (search != m_pathToTag.cend())
|
||||
return search->second;
|
||||
return buildTagFromPath(path, btok);
|
||||
return buildTagFromPath(path);
|
||||
}
|
||||
|
||||
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())
|
||||
continue;
|
||||
urde::SObjectTag pathTag = tagFromPath(path, m_backgroundBlender);
|
||||
urde::SObjectTag pathTag = tagFromPath(path);
|
||||
if (pathTag) {
|
||||
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
||||
m_catalogNameToTag[pLower] = pathTag;
|
||||
|
@ -981,7 +983,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
|||
return true;
|
||||
|
||||
/* Classify intermediate into tag */
|
||||
urde::SObjectTag pathTag = buildTagFromPath(path, m_backgroundBlender);
|
||||
urde::SObjectTag pathTag = buildTagFromPath(path);
|
||||
if (pathTag) {
|
||||
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
||||
bool useGlob = false;
|
||||
|
@ -1004,7 +1006,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
|||
for (const std::string& arm : armatureNames) {
|
||||
hecl::SystemStringConv sysStr(arm);
|
||||
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_pathToTag[subPath.hash()] = pathTag;
|
||||
WriteTag(cacheWriter, pathTag, subPath);
|
||||
|
@ -1016,7 +1018,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
|||
for (const std::string& sub : subtypeNames) {
|
||||
hecl::SystemStringConv sysStr(sub);
|
||||
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_pathToTag[subPath.hash()] = pathTag;
|
||||
WriteTag(cacheWriter, pathTag, subPath);
|
||||
|
@ -1029,7 +1031,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
|||
hecl::SystemStringConv overlaySys(overlay);
|
||||
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR('.') +
|
||||
overlaySys.c_str() + _SYS_STR(".CSKR"));
|
||||
urde::SObjectTag pathTag = buildTagFromPath(subPath, m_backgroundBlender);
|
||||
urde::SObjectTag pathTag = buildTagFromPath(subPath);
|
||||
m_tagToPath[pathTag] = subPath;
|
||||
m_pathToTag[subPath.hash()] = pathTag;
|
||||
WriteTag(cacheWriter, pathTag, subPath);
|
||||
|
@ -1044,7 +1046,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
|||
hecl::SystemStringConv attachmentSys(attachment);
|
||||
hecl::ProjectPath subPath =
|
||||
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_pathToTag[subPath.hash()] = pathTag;
|
||||
WriteTag(cacheWriter, pathTag, subPath);
|
||||
|
@ -1056,7 +1058,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
|||
for (const std::string& act : actionNames) {
|
||||
hecl::SystemStringConv sysStr(act);
|
||||
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_pathToTag[subPath.hash()] = pathTag;
|
||||
WriteTag(cacheWriter, pathTag, subPath);
|
||||
|
@ -1070,7 +1072,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
|||
useGlob = true;
|
||||
|
||||
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_pathToTag[subPath.hash()] = pathTag;
|
||||
WriteTag(cacheWriter, pathTag, subPath);
|
||||
|
@ -1079,7 +1081,7 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
|
|||
#endif
|
||||
|
||||
subPath = asGlob.ensureAuxInfo(_SYS_STR("SAVW"));
|
||||
pathTag = buildTagFromPath(subPath, m_backgroundBlender);
|
||||
pathTag = buildTagFromPath(subPath);
|
||||
m_tagToPath[pathTag] = subPath;
|
||||
m_pathToTag[subPath.hash()] = pathTag;
|
||||
WriteTag(cacheWriter, pathTag, subPath);
|
||||
|
@ -1216,7 +1218,7 @@ void SpecBase::backgroundIndexProc() {
|
|||
|
||||
/* Add special original IDs resource if exists (not name-cached to disk) */
|
||||
hecl::ProjectPath oidsPath(specRoot, "!original_ids.yaml");
|
||||
urde::SObjectTag oidsTag = buildTagFromPath(oidsPath, m_backgroundBlender);
|
||||
urde::SObjectTag oidsTag = buildTagFromPath(oidsPath);
|
||||
if (oidsTag) {
|
||||
m_catalogNameToTag["mp1originalids"] = oidsTag;
|
||||
m_catalogTagToNames[oidsTag].insert("MP1OriginalIDs");
|
||||
|
|
|
@ -36,10 +36,9 @@ struct SpecBase : hecl::Database::IDataSpec {
|
|||
bool canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps);
|
||||
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* oldEntry,
|
||||
hecl::blender::Token& btok) const;
|
||||
const hecl::Database::DataSpecEntry* oldEntry) const;
|
||||
void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, hecl::blender::Token& btok,
|
||||
FCookProgress progress);
|
||||
|
||||
|
@ -59,7 +58,7 @@ struct SpecBase : hecl::Database::IDataSpec {
|
|||
virtual bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) = 0;
|
||||
|
||||
/* 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 */
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
bool waitForTagReady(const urde::SObjectTag& tag, const hecl::ProjectPath*& pathOut);
|
||||
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")))
|
||||
return {SBIG('CINF'), path.hash().val32()};
|
||||
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,
|
||||
hecl::blender::Token& btok, FCookProgress progress) {
|
||||
Mesh mesh =
|
||||
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()); });
|
||||
Mesh mesh = ds.compileMesh(fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, m_pc ? 16 : -1);
|
||||
|
||||
if (m_pc)
|
||||
DNAMP1::CMDL::HMDLCook(out, in, mesh);
|
||||
|
@ -747,8 +745,7 @@ struct SpecMP1 : SpecBase {
|
|||
continue;
|
||||
}
|
||||
meshCompiles.push_back(ds.compileMesh(
|
||||
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()); }));
|
||||
mesh, fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, -1, !m_pc));
|
||||
}
|
||||
|
||||
if (!colMesh)
|
||||
|
@ -773,7 +770,7 @@ struct SpecMP1 : SpecBase {
|
|||
if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR("MAPW"))) {
|
||||
hecl::blender::World world = ds.compileWorld();
|
||||
ds.close();
|
||||
DNAMP1::MLVL::CookMAPW(out, world, btok);
|
||||
DNAMP1::MLVL::CookMAPW(out, world);
|
||||
} else if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR("SAVW"))) {
|
||||
hecl::blender::World world = ds.compileWorld();
|
||||
ds.close();
|
||||
|
@ -1028,7 +1025,7 @@ struct SpecMP1 : SpecBase {
|
|||
}
|
||||
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(0);
|
||||
|
@ -1131,7 +1128,7 @@ struct SpecMP1 : SpecBase {
|
|||
auto data = btok.getBlenderConnection().beginData();
|
||||
std::vector<hecl::ProjectPath> textures = data.getTextures();
|
||||
for (const auto& tex : textures) {
|
||||
urde::SObjectTag texTag = tagFromPath(tex, btok);
|
||||
urde::SObjectTag texTag = tagFromPath(tex);
|
||||
if (!texTag)
|
||||
Log.report(logvisor::Fatal, _SYS_STR("Unable to resolve %s"), tex.getRelativePath().data());
|
||||
listOut.push_back(texTag);
|
||||
|
@ -1270,14 +1267,13 @@ struct SpecMP1 : SpecBase {
|
|||
};
|
||||
|
||||
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> {
|
||||
return std::make_unique<SpecMP1>(&SpecEntMP1, project, false);
|
||||
}};
|
||||
|
||||
hecl::Database::DataSpecEntry SpecEntMP1PC = {
|
||||
_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::DataSpecTool tool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
||||
if (tool != hecl::Database::DataSpecTool::Extract)
|
||||
|
@ -1286,5 +1282,5 @@ hecl::Database::DataSpecEntry SpecEntMP1PC = {
|
|||
}};
|
||||
|
||||
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
|
||||
|
|
|
@ -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,
|
||||
hecl::blender::Token& btok, FCookProgress progress) {}
|
||||
|
@ -430,14 +430,13 @@ struct SpecMP2 : SpecBase {
|
|||
};
|
||||
|
||||
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> {
|
||||
return std::make_unique<SpecMP2>(&SpecEntMP2, project, false);
|
||||
});
|
||||
|
||||
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),
|
||||
2,
|
||||
[](hecl::Database::Project& project,
|
||||
hecl::Database::DataSpecTool tool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
||||
if (tool != hecl::Database::DataSpecTool::Extract)
|
||||
|
@ -446,6 +445,6 @@ hecl::Database::DataSpecEntry SpecEntMP2PC = {
|
|||
}};
|
||||
|
||||
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
|
||||
|
|
|
@ -517,7 +517,7 @@ struct SpecMP3 : SpecBase {
|
|||
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,
|
||||
hecl::blender::Token& btok, FCookProgress progress) {}
|
||||
|
@ -577,14 +577,13 @@ struct SpecMP3 : SpecBase {
|
|||
};
|
||||
|
||||
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> {
|
||||
return std::make_unique<SpecMP3>(&SpecEntMP3, project, false);
|
||||
});
|
||||
|
||||
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),
|
||||
2,
|
||||
[](hecl::Database::Project& project,
|
||||
hecl::Database::DataSpecTool tool) -> std::unique_ptr<hecl::Database::IDataSpec> {
|
||||
if (tool != hecl::Database::DataSpecTool::Extract)
|
||||
|
@ -593,6 +592,6 @@ hecl::Database::DataSpecEntry SpecEntMP3PC = {
|
|||
}};
|
||||
|
||||
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
|
||||
|
|
|
@ -14,7 +14,7 @@ CToken ProjectResourcePool::GetObj(std::string_view name) {
|
|||
|
||||
hecl::ProjectPath path(*m_parent.project(), name);
|
||||
SObjectTag tag =
|
||||
static_cast<ProjectResourceFactoryBase&>(x18_factory).TagFromPath(path, hecl::blender::SharedBlenderToken);
|
||||
static_cast<ProjectResourceFactoryBase&>(x18_factory).TagFromPath(path);
|
||||
if (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);
|
||||
SObjectTag tag =
|
||||
static_cast<ProjectResourceFactoryBase&>(x18_factory).TagFromPath(path, hecl::blender::SharedBlenderToken);
|
||||
static_cast<ProjectResourceFactoryBase&>(x18_factory).TagFromPath(path);
|
||||
if (tag)
|
||||
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);
|
||||
if (!m_cookedPath.isFile() || m_cookedPath.getModtime() < path.getModtime()) {
|
||||
/* 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) {
|
||||
Log.report(logvisor::Error, _SYS_STR("%s: expected type '%.4s', found '%.4s'"), path.getRelativePath().data(),
|
||||
tag.type.getChars(), verifyTag.type.getChars());
|
||||
|
@ -179,7 +179,7 @@ bool ProjectResourceFactoryBase::PrepForReadSync(const SObjectTag& tag, const he
|
|||
cooked = path.getCookedPath(*m_origSpec);
|
||||
if (!cooked.isFile() || cooked.getModtime() < path.getModtime()) {
|
||||
/* Last chance type validation */
|
||||
urde::SObjectTag verifyTag = TagFromPath(path, hecl::blender::SharedBlenderToken);
|
||||
urde::SObjectTag verifyTag = TagFromPath(path);
|
||||
if (verifyTag.type != tag.type) {
|
||||
Log.report(logvisor::Error, _SYS_STR("%s: expected type '%.4s', found '%.4s'"), path.getRelativePath().data(),
|
||||
tag.type.getChars(), verifyTag.type.getChars());
|
||||
|
|
|
@ -96,11 +96,11 @@ protected:
|
|||
bool WaitForTagReady(const urde::SObjectTag& tag, const hecl::ProjectPath*& pathOut) {
|
||||
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).waitForTagReady(tag, pathOut);
|
||||
}
|
||||
SObjectTag TagFromPath(const hecl::ProjectPath& path, hecl::blender::Token& btok) const {
|
||||
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).tagFromPath(path, btok);
|
||||
SObjectTag TagFromPath(const hecl::ProjectPath& path) const {
|
||||
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).tagFromPath(path);
|
||||
}
|
||||
SObjectTag BuildTagFromPath(const hecl::ProjectPath& path, hecl::blender::Token& btok) const {
|
||||
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).buildTagFromPath(path, btok);
|
||||
SObjectTag BuildTagFromPath(const hecl::ProjectPath& path) const {
|
||||
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).buildTagFromPath(path);
|
||||
}
|
||||
void GetTagListForFile(const char* pakName, std::vector<SObjectTag>& out) const {
|
||||
return static_cast<DataSpec::SpecBase&>(*m_cookSpec).getTagListForFile(pakName, out);
|
||||
|
@ -150,7 +150,7 @@ public:
|
|||
bool IsBusy() const { return m_asyncLoadMap.size() != 0; }
|
||||
|
||||
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(); }
|
||||
|
|
|
@ -5,7 +5,11 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
|
|||
macro(runtime_add_list rel_path a_list)
|
||||
unset(tmp_list)
|
||||
foreach(path IN LISTS ${a_list})
|
||||
if(IS_ABSOLUTE ${path})
|
||||
list(APPEND tmp_list "${path}")
|
||||
else()
|
||||
list(APPEND tmp_list "${rel_path}/${path}")
|
||||
endif()
|
||||
endforeach(path)
|
||||
set(${a_list} "${tmp_list}" PARENT_SCOPE)
|
||||
endmacro(runtime_add_list)
|
||||
|
@ -144,3 +148,5 @@ if(MSVC)
|
|||
else()
|
||||
add_runtime_common_library(RuntimeCommon ${RUNTIME_SOURCES_A} ${RUNTIME_SOURCES_B})
|
||||
endif()
|
||||
|
||||
target_link_libraries(RuntimeCommon CModelShaders)
|
|
@ -339,7 +339,7 @@ float CPlayerState::CalculateHealth() {
|
|||
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)
|
||||
return;
|
||||
|
||||
|
@ -360,7 +360,7 @@ void CPlayerState::InitializePowerUp(CPlayerState::EItemType type, u32 capacity)
|
|||
|
||||
void CPlayerState::ReInitalizePowerUp(CPlayerState::EItemType type, u32 capacity) {
|
||||
x24_powerups[u32(type)].x4_capacity = 0;
|
||||
InitializePowerUp(type, capacity);
|
||||
AddPowerUp(type, capacity);
|
||||
}
|
||||
|
||||
void CPlayerState::InitializeScanTimes() {
|
||||
|
|
|
@ -160,7 +160,7 @@ public:
|
|||
static float GetBaseHealthCapacity() { return 99.f; }
|
||||
float CalculateHealth();
|
||||
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 GetTotalLogScans() const { return x180_scanCompletionRate.second; }
|
||||
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 statePu = x8b8_playerState->GetItemAmount(iType);
|
||||
if (statePu < spawnPu)
|
||||
x8b8_playerState->InitializePowerUp(iType, spawnPu - statePu);
|
||||
x8b8_playerState->AddPowerUp(iType, spawnPu - statePu);
|
||||
|
||||
spawnPu = sp->GetPowerup(iType);
|
||||
statePu = x8b8_playerState->GetItemAmount(iType);
|
||||
|
|
|
@ -168,7 +168,7 @@ void Buckets::Init() {
|
|||
|
||||
CBooRenderer::CAreaListItem::CAreaListItem(const std::vector<CMetroidModelInstance>* geom,
|
||||
const CAreaRenderOctTree* octTree,
|
||||
std::vector<TCachedToken<CTexture>>&& textures,
|
||||
std::unordered_map<CAssetId, TCachedToken<CTexture>>&& textures,
|
||||
std::vector<CBooModel*>&& models, int areaIdx, const SShader* shaderSet)
|
||||
: x0_geometry(geom)
|
||||
, 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());
|
||||
}
|
||||
|
||||
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() {
|
||||
m_thermoPaletteTex = xc_store.GetObj("TXTR_ThermoPalette");
|
||||
CTexture* thermoTexObj = m_thermoPaletteTex.GetObj();
|
||||
|
@ -652,8 +668,7 @@ void CBooRenderer::AddWorldSurfaces(CBooModel& model) {
|
|||
zeus::CAABox aabb = surf->GetBounds();
|
||||
zeus::CVector3f pt = aabb.closestPointAlongVector(xb0_viewPlane.normal());
|
||||
Buckets::Insert(pt, aabb, EDrawableType::WorldSurface, surf, xb0_viewPlane,
|
||||
mat.heclIr.m_blendSrc == boo::BlendFactor::SrcAlpha &&
|
||||
mat.heclIr.m_blendDst == boo::BlendFactor::InvSrcAlpha);
|
||||
mat.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Alpha);
|
||||
surf = surf->m_next;
|
||||
}
|
||||
}
|
||||
|
@ -668,7 +683,7 @@ void CBooRenderer::AddStaticGeometry(const std::vector<CMetroidModelInstance>* g
|
|||
const CAreaRenderOctTree* octTree, int areaIdx, const SShader* shaderSet) {
|
||||
auto search = FindStaticGeometry(geometry);
|
||||
if (search == x1c_areaListItems.end()) {
|
||||
std::vector<TCachedToken<CTexture>> textures;
|
||||
std::unordered_map<CAssetId, TCachedToken<CTexture>> textures;
|
||||
std::vector<CBooModel*> models;
|
||||
if (geometry->size()) {
|
||||
(*geometry)[0].m_instance->MakeTexturesFromMats(textures, xc_store);
|
||||
|
|
|
@ -58,7 +58,7 @@ class CBooRenderer final : public IRenderer {
|
|||
const std::vector<CMetroidModelInstance>* x0_geometry;
|
||||
const CAreaRenderOctTree* x4_octTree;
|
||||
/* originally auto_ptrs of vectors */
|
||||
std::vector<TCachedToken<CTexture>> x8_textures;
|
||||
std::unordered_map<CAssetId, TCachedToken<CTexture>> x8_textures;
|
||||
std::vector<CBooModel*> x10_models;
|
||||
int x18_areaIdx;
|
||||
/* Per-area octree-word major, light bits minor */
|
||||
|
@ -66,8 +66,8 @@ class CBooRenderer final : public IRenderer {
|
|||
const SShader* m_shaderSet;
|
||||
|
||||
CAreaListItem(const std::vector<CMetroidModelInstance>* geom, const CAreaRenderOctTree* octTree,
|
||||
std::vector<TCachedToken<CTexture>>&& textures, std::vector<CBooModel*>&& models, int areaIdx,
|
||||
const SShader* shaderSet);
|
||||
std::unordered_map<CAssetId, TCachedToken<CTexture>>&& textures, std::vector<CBooModel*>&& models,
|
||||
int areaIdx, const SShader* shaderSet);
|
||||
~CAreaListItem();
|
||||
};
|
||||
|
||||
|
@ -109,6 +109,7 @@ class CBooRenderer final : public IRenderer {
|
|||
boo::ObjToken<boo::ITexture> m_clearTexture;
|
||||
boo::ObjToken<boo::ITexture> m_blackTexture;
|
||||
boo::ObjToken<boo::ITexture> m_whiteTexture;
|
||||
std::unordered_map<zeus::CColor, boo::ObjToken<boo::ITexture>> m_colorTextures;
|
||||
|
||||
boo::ObjToken<boo::ITextureR> x14c_reflectionTex;
|
||||
// boo::ITextureS* x150_mirrorRamp = nullptr;
|
||||
|
@ -278,6 +279,8 @@ public:
|
|||
const boo::ObjToken<boo::ITexture>& GetBlackTexture() { return m_blackTexture; }
|
||||
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); }
|
||||
void BindReflectionDrawTarget() { CGraphics::g_BooMainCommandQueue->setRenderTarget(x14c_reflectionTex); }
|
||||
void BindBallShadowIdTarget() {
|
||||
|
|
|
@ -24,7 +24,6 @@ set(GRAPHICS_SOURCES
|
|||
Shaders/CColoredQuadFilter.hpp Shaders/CColoredQuadFilter.cpp
|
||||
Shaders/CColoredStripShader.hpp Shaders/CColoredStripShader.cpp
|
||||
Shaders/CModelShaders.hpp Shaders/CModelShaders.cpp
|
||||
Shaders/CModelShadersGLSL.cpp Shaders/CModelShadersHLSL.cpp Shaders/CModelShadersMetal.cpp
|
||||
Shaders/CThermalColdFilter.hpp Shaders/CThermalColdFilter.cpp
|
||||
Shaders/CThermalHotFilter.hpp Shaders/CThermalHotFilter.cpp
|
||||
Shaders/CSpaceWarpFilter.hpp Shaders/CSpaceWarpFilter.cpp
|
||||
|
|
|
@ -75,7 +75,6 @@ struct CBooSurface {
|
|||
};
|
||||
|
||||
using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet;
|
||||
using UVAnimation = DataSpec::DNAMP1::MaterialSet::Material::UVAnimation;
|
||||
|
||||
struct GeometryUniformLayout {
|
||||
boo::ObjToken<boo::IGraphicsBufferD> m_sharedBuffer[2];
|
||||
|
@ -96,7 +95,7 @@ struct GeometryUniformLayout {
|
|||
};
|
||||
|
||||
struct SShader {
|
||||
std::vector<TCachedToken<CTexture>> x0_textures;
|
||||
std::unordered_map<CAssetId, TCachedToken<CTexture>> x0_textures;
|
||||
std::unordered_map<int, CModelShaders::ShaderPipelines> m_shaders;
|
||||
MaterialSet m_matSet;
|
||||
rstl::optional<GeometryUniformLayout> m_geomLayout;
|
||||
|
@ -134,7 +133,7 @@ private:
|
|||
const GeometryUniformLayout* m_geomLayout;
|
||||
int m_matSetIdx = -1;
|
||||
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;
|
||||
CBooSurface* x38_firstUnsortedSurface = nullptr;
|
||||
CBooSurface* x3c_firstSortedSurface = nullptr;
|
||||
|
@ -144,7 +143,7 @@ private:
|
|||
u32 x44_areaInstanceIdx = -1;
|
||||
|
||||
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 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_staticIbo;
|
||||
|
||||
boo::ObjToken<boo::ITexture> m_txtrOverrides[8];
|
||||
|
||||
boo::ObjToken<boo::ITexture> m_lastDrawnShadowMap;
|
||||
boo::ObjToken<boo::ITexture> m_lastDrawnOneTexture;
|
||||
|
||||
|
@ -192,11 +189,12 @@ public:
|
|||
~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 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);
|
||||
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; }
|
||||
void ActivateLights(const std::vector<CLight>& lights);
|
||||
|
@ -284,9 +282,7 @@ public:
|
|||
const zeus::CAABox& GetAABB() const { return m_aabb; }
|
||||
CBooModel& GetInstance() { return *x28_modelInst; }
|
||||
const CBooModel& GetInstance() const { return *x28_modelInst; }
|
||||
std::unique_ptr<CBooModel> MakeNewInstance(int shaderIdx, int subInsts,
|
||||
const boo::ObjToken<boo::ITexture> txtrOverrides[8] = nullptr,
|
||||
bool lockParent = true);
|
||||
std::unique_ptr<CBooModel> MakeNewInstance(int shaderIdx, int subInsts, bool lockParent = true);
|
||||
void UpdateLastFrame() const { const_cast<CModel&>(*this).x38_lastFrame = CGraphics::GetFrameCounter(); }
|
||||
|
||||
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,
|
||||
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)
|
||||
: m_modelTok(token)
|
||||
, m_model(parent)
|
||||
, x0_surfaces(surfaces)
|
||||
|
@ -157,10 +156,6 @@ CBooModel::CBooModel(TToken<CModel>& token, CModel* parent, std::vector<CBooSurf
|
|||
, x41_mask(renderMask)
|
||||
, m_staticVbo(vbo)
|
||||
, m_staticIbo(ibo) {
|
||||
if (txtrOverrides)
|
||||
for (int i = 0; i < 8; ++i)
|
||||
m_txtrOverrides[i] = txtrOverrides[i];
|
||||
|
||||
if (!g_FirstModel)
|
||||
g_FirstModel = this;
|
||||
else {
|
||||
|
@ -291,10 +286,6 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
|
|||
/* Binding for each surface */
|
||||
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 thisSizes[4];
|
||||
|
||||
|
@ -306,20 +297,23 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
|
|||
for (const CBooSurface& surf : *x0_surfaces) {
|
||||
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(),
|
||||
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->m_clearTexture.get(), g_Renderer->m_clearTexture.get(),
|
||||
g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(),
|
||||
g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(),
|
||||
g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(),
|
||||
g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get()};
|
||||
u32 texCount = 0;
|
||||
for (atUint32 idx : mat.textureIdxs) {
|
||||
if (boo::ObjToken<boo::ITexture> overtex = m_txtrOverrides[texCount]) {
|
||||
texs[texCount++] = overtex;
|
||||
} else if (g_DummyTextures) {
|
||||
texs[texCount++] = g_Renderer->x220_sphereRamp.get();
|
||||
} else {
|
||||
TCachedToken<CTexture>& tex = x1c_textures[idx];
|
||||
if (boo::ObjToken<boo::ITexture> btex = tex.GetObj()->GetBooTexture())
|
||||
texs[texCount++] = btex;
|
||||
if (!g_DummyTextures) {
|
||||
for (const auto& ch : mat.chunks) {
|
||||
if (auto pass = ch.get_if<MaterialSet::Material::PASS>()) {
|
||||
auto search = x1c_textures.find(pass->texId.toUint32());
|
||||
boo::ObjToken<boo::ITexture> btex;
|
||||
if (search != x1c_textures.cend() && (btex = search->second.GetObj()->GetBooTexture()))
|
||||
texs[MaterialSet::Material::TexMapIdx(pass->type)] = 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();
|
||||
if (useReflection) {
|
||||
if (g_Renderer->x14c_reflectionTex)
|
||||
texs[texCount] = g_Renderer->x14c_reflectionTex.get();
|
||||
else
|
||||
texs[texCount] = g_Renderer->x220_sphereRamp.get();
|
||||
texs[11] = g_Renderer->x14c_reflectionTex.get();
|
||||
thisOffs[3] = curReflect;
|
||||
curReflect += 256;
|
||||
} else {
|
||||
|
@ -358,31 +350,25 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
|
|||
|
||||
int idx = 0;
|
||||
for (const auto& pipeline : *pipelines) {
|
||||
boo::ObjToken<boo::ITexture>* ltexs;
|
||||
if (idx == EExtendedShader::Thermal) {
|
||||
texs[7] = g_Renderer->x220_sphereRamp.get();
|
||||
ltexs = texs;
|
||||
texs[8] = g_Renderer->x220_sphereRamp.get();
|
||||
} 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) {
|
||||
if (g_shadowMap)
|
||||
texs[7] = g_shadowMap;
|
||||
texs[8] = g_shadowMap;
|
||||
else
|
||||
texs[7] = g_Renderer->x220_sphereRamp.get();
|
||||
ltexs = texs;
|
||||
texs[8] = g_Renderer->x220_sphereRamp.get();
|
||||
} else if (idx == EExtendedShader::Disintegrate) {
|
||||
if (g_disintegrateTexture)
|
||||
texs[7] = g_disintegrateTexture;
|
||||
texs[8] = g_disintegrateTexture;
|
||||
else
|
||||
texs[7] = g_Renderer->x220_sphereRamp.get();
|
||||
ltexs = texs;
|
||||
} else if (useReflection) {
|
||||
ltexs = texs;
|
||||
} else {
|
||||
ltexs = texs;
|
||||
texs[8] = g_Renderer->x220_sphereRamp.get();
|
||||
}
|
||||
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));
|
||||
++idx;
|
||||
}
|
||||
|
@ -393,14 +379,20 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
|
|||
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) {
|
||||
toksOut.reserve(matSet.head.textureIDs.size());
|
||||
for (const DataSpec::UniqueID32& id : matSet.head.textureIDs)
|
||||
toksOut.emplace_back(store.GetObj({SBIG('TXTR'), id.toUint32()}));
|
||||
for (const auto& mat : matSet.materials) {
|
||||
for (const auto& chunk : mat.chunks) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -445,9 +437,9 @@ void CBooModel::RemapMaterialData(SShader& shader,
|
|||
bool CBooModel::TryLockTextures() const {
|
||||
if (!x40_24_texturesLoaded) {
|
||||
bool allLoad = true;
|
||||
for (TCachedToken<CTexture>& tex : const_cast<std::vector<TCachedToken<CTexture>>&>(x1c_textures)) {
|
||||
tex.Lock();
|
||||
if (!tex.IsLoaded())
|
||||
for (auto& tex : const_cast<std::unordered_map<CAssetId, TCachedToken<CTexture>>&>(x1c_textures)) {
|
||||
tex.second.Lock();
|
||||
if (!tex.second.IsLoaded())
|
||||
allLoad = false;
|
||||
}
|
||||
|
||||
|
@ -459,15 +451,15 @@ bool CBooModel::TryLockTextures() const {
|
|||
|
||||
void CBooModel::UnlockTextures() const {
|
||||
const_cast<CBooModel*>(this)->m_instances.clear();
|
||||
for (TCachedToken<CTexture>& tex : const_cast<std::vector<TCachedToken<CTexture>>&>(x1c_textures))
|
||||
tex.Unlock();
|
||||
for (auto& tex : const_cast<std::unordered_map<CAssetId, TCachedToken<CTexture>>&>(x1c_textures))
|
||||
tex.second.Unlock();
|
||||
const_cast<CBooModel*>(this)->x40_24_texturesLoaded = false;
|
||||
}
|
||||
|
||||
void CBooModel::SyncLoadTextures() const {
|
||||
if (!x40_24_texturesLoaded) {
|
||||
for (TCachedToken<CTexture>& tex : const_cast<std::vector<TCachedToken<CTexture>>&>(x1c_textures))
|
||||
tex.GetObj();
|
||||
for (auto& tex : const_cast<std::unordered_map<CAssetId, TCachedToken<CTexture>>&>(x1c_textures))
|
||||
tex.second.GetObj();
|
||||
const_cast<CBooModel*>(this)->x40_24_texturesLoaded = true;
|
||||
}
|
||||
}
|
||||
|
@ -534,7 +526,7 @@ static EExtendedShader ResolveExtendedShader(const MaterialSet::Material& data,
|
|||
return EExtendedShader::LightingAlphaWrite;
|
||||
else if (g_Renderer->IsThermalVisorActive())
|
||||
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) */
|
||||
if (flags.x0_blendMode > 6) {
|
||||
if (flags.m_depthGreater)
|
||||
|
@ -555,19 +547,19 @@ static EExtendedShader ResolveExtendedShader(const MaterialSet::Material& data,
|
|||
}
|
||||
} else if (flags.m_noCull && noZWrite) {
|
||||
/* 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;
|
||||
else
|
||||
extended = EExtendedShader::ForcedAlphaNoCullNoZWrite;
|
||||
} else if (flags.m_noCull) {
|
||||
/* 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;
|
||||
else
|
||||
extended = EExtendedShader::ForcedAlphaNoCull;
|
||||
} else if (noZWrite) {
|
||||
/* 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;
|
||||
else
|
||||
extended = EExtendedShader::ForcedAlphaNoZWrite;
|
||||
|
@ -619,21 +611,22 @@ void CBooModel::WarmupDrawSurface(const CBooSurface& surf) const {
|
|||
return;
|
||||
const ModelInstance& inst = m_instances[m_uniUpdateCount - 1];
|
||||
|
||||
// Only warmup normal lighting and thermal visor
|
||||
for (int i = 1; i <= 2; ++i) {
|
||||
auto& binding = inst.m_shaderDataBindings[surf.selfIdx][i];
|
||||
for (auto& binding : inst.m_shaderDataBindings[surf.selfIdx]) {
|
||||
CGraphics::SetShaderDataBinding(binding);
|
||||
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& postMtxOut = reinterpret_cast<zeus::CMatrix4f&>(*(bufOut + sizeof(zeus::CMatrix4f)));
|
||||
texMtxOut = zeus::CMatrix4f();
|
||||
postMtxOut = zeus::CMatrix4f();
|
||||
switch (anim.mode) {
|
||||
case UVAnimation::Mode::MvInvNoTranslation: {
|
||||
switch (anim.uvAnimType) {
|
||||
case UVAnimType::MvInvNoTranslation: {
|
||||
texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
|
||||
texMtxOut[3].w() = 1.f;
|
||||
postMtxOut[0].x() = 0.5f;
|
||||
|
@ -642,7 +635,7 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimati
|
|||
postMtxOut[3].y() = 0.5f;
|
||||
break;
|
||||
}
|
||||
case UVAnimation::Mode::MvInv: {
|
||||
case UVAnimType::MvInv: {
|
||||
texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
|
||||
texMtxOut[3] = CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix.origin;
|
||||
texMtxOut[3].w() = 1.f;
|
||||
|
@ -652,13 +645,13 @@ void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const UVAnimati
|
|||
postMtxOut[3].y() = 0.5f;
|
||||
break;
|
||||
}
|
||||
case UVAnimation::Mode::Scroll: {
|
||||
texMtxOut[3].x() = CGraphics::GetSecondsMod900() * anim.vals[2] + anim.vals[0];
|
||||
texMtxOut[3].y() = CGraphics::GetSecondsMod900() * anim.vals[3] + anim.vals[1];
|
||||
case UVAnimType::Scroll: {
|
||||
texMtxOut[3].x() = CGraphics::GetSecondsMod900() * anim.uvAnimParms[2] + anim.uvAnimParms[0];
|
||||
texMtxOut[3].y() = CGraphics::GetSecondsMod900() * anim.uvAnimParms[3] + anim.uvAnimParms[1];
|
||||
break;
|
||||
}
|
||||
case UVAnimation::Mode::Rotation: {
|
||||
float angle = CGraphics::GetSecondsMod900() * anim.vals[1] + anim.vals[0];
|
||||
case UVAnimType::Rotation: {
|
||||
float angle = CGraphics::GetSecondsMod900() * anim.uvAnimParms[1] + anim.uvAnimParms[0];
|
||||
float acos = std::cos(angle);
|
||||
float asin = std::sin(angle);
|
||||
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;
|
||||
break;
|
||||
}
|
||||
case UVAnimation::Mode::HStrip: {
|
||||
float value = anim.vals[0] * anim.vals[2] * (anim.vals[3] + CGraphics::GetSecondsMod900());
|
||||
texMtxOut[3].x() = std::trunc(anim.vals[1] * fmod(value, 1.0f)) * anim.vals[2];
|
||||
case UVAnimType::HStrip: {
|
||||
float value = anim.uvAnimParms[0] * anim.uvAnimParms[2] * (anim.uvAnimParms[3] + CGraphics::GetSecondsMod900());
|
||||
texMtxOut[3].x() = std::trunc(anim.uvAnimParms[1] * fmod(value, 1.0f)) * anim.uvAnimParms[2];
|
||||
break;
|
||||
}
|
||||
case UVAnimation::Mode::VStrip: {
|
||||
float value = anim.vals[0] * anim.vals[2] * (anim.vals[3] + CGraphics::GetSecondsMod900());
|
||||
texMtxOut[3].y() = std::trunc(anim.vals[1] * fmod(value, 1.0f)) * anim.vals[2];
|
||||
case UVAnimType::VStrip: {
|
||||
float value = anim.uvAnimParms[0] * anim.uvAnimParms[2] * (anim.uvAnimParms[3] + CGraphics::GetSecondsMod900());
|
||||
texMtxOut[3].y() = std::trunc(anim.uvAnimParms[1] * fmod(value, 1.0f)) * anim.uvAnimParms[2];
|
||||
break;
|
||||
}
|
||||
case UVAnimation::Mode::Model: {
|
||||
case UVAnimType::Model: {
|
||||
texMtxOut = CGraphics::g_GXModelMatrix.toMatrix4f();
|
||||
texMtxOut[3] = zeus::CVector4f(0.f, 0.f, 0.f, 1.f);
|
||||
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;
|
||||
break;
|
||||
}
|
||||
case UVAnimation::Mode::CylinderEnvironment: {
|
||||
case UVAnimType::CylinderEnvironment: {
|
||||
texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f();
|
||||
|
||||
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));
|
||||
float z = (viewOrigin.z()) * 0.05f * anim.vals[1];
|
||||
float z = (viewOrigin.z()) * 0.05f * anim.uvAnimParms[1];
|
||||
z = (z - std::trunc(z));
|
||||
|
||||
float halfA = anim.vals[0] * 0.5f;
|
||||
float halfA = anim.uvAnimParms[0] * 0.5f;
|
||||
|
||||
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))
|
||||
|
@ -808,8 +801,11 @@ void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet
|
|||
mtxs[7][1] = (*specialMtxOut)[1];
|
||||
}
|
||||
u8* bufOrig = bufOut;
|
||||
for (const UVAnimation& anim : mat.uvAnims)
|
||||
ProcessAnimation(bufOut, anim);
|
||||
for (const auto& chunk : mat.chunks) {
|
||||
if (auto pass = chunk.get_if<MaterialSet::Material::PASS>()) {
|
||||
ProcessAnimation(bufOut, *pass);
|
||||
}
|
||||
}
|
||||
bufOut = bufOrig + sizeof(zeus::CMatrix4f) * 2 * 8;
|
||||
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,
|
||||
const CPoseAsTransforms* pose,
|
||||
int sharedLayoutBuf) const {
|
||||
if (!TryLockTextures())
|
||||
if (!g_DummyTextures && !TryLockTextures())
|
||||
return {};
|
||||
|
||||
/* Invalidate instances if new shadow being drawn */
|
||||
|
@ -1046,13 +1042,11 @@ static const u8* MemoryFromPartData(const u8*& dataCur, const u32*& secSizeCur)
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::unique_ptr<CBooModel> CModel::MakeNewInstance(int shaderIdx, int subInsts,
|
||||
const boo::ObjToken<boo::ITexture> txtrOverrides[8],
|
||||
bool lockParent) {
|
||||
std::unique_ptr<CBooModel> CModel::MakeNewInstance(int shaderIdx, int subInsts, bool lockParent) {
|
||||
if (shaderIdx >= x18_matSets.size())
|
||||
shaderIdx = 0;
|
||||
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)
|
||||
ret->LockParent();
|
||||
return ret;
|
||||
|
@ -1066,9 +1060,9 @@ CModelShaders::ShaderPipelines SShader::BuildShader(const hecl::HMDLMeta& meta,
|
|||
reflectionType = hecl::Backend::ReflectionType::Simple;
|
||||
else
|
||||
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());
|
||||
return CModelShaders::BuildExtendedShader(tag, mat.heclIr);
|
||||
return CModelShaders::BuildExtendedShader(tag, mat);
|
||||
}
|
||||
|
||||
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);
|
||||
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]));
|
||||
x28_modelInst = MakeNewInstance(0, 1, nullptr, false);
|
||||
x28_modelInst = MakeNewInstance(0, 1, false);
|
||||
}
|
||||
|
||||
void SShader::UnlockTextures() {
|
||||
for (TCachedToken<CTexture>& tex : x0_textures)
|
||||
tex.Unlock();
|
||||
for (auto& tex : x0_textures)
|
||||
tex.second.Unlock();
|
||||
}
|
||||
|
||||
void CBooModel::VerifyCurrentShader(int shaderIdx) {
|
||||
|
|
|
@ -54,142 +54,138 @@ 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[] = {
|
||||
{hecl::Backend::TexGenSrc::Position, 0, 0, 0, false}, // ID tex
|
||||
{hecl::Backend::TexGenSrc::Position, 1, 0, 0, false}, // Sphere ramp
|
||||
{hecl::Backend::TexGenSrc::Position, 2, 0, 1, false} // TXTR_BallFade
|
||||
{TexCoordSource::Position, 0, false}, // ID tex
|
||||
{TexCoordSource::Position, 0, false}, // Sphere ramp
|
||||
{TexCoordSource::Position, 1, false} // TXTR_BallFade
|
||||
};
|
||||
|
||||
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[] = {
|
||||
{hecl::Backend::TexGenSrc::Position, 7, 0, 0, false}, // Ashy tex
|
||||
{hecl::Backend::TexGenSrc::Position, 7, 0, 1, false} // Ashy tex
|
||||
{TexCoordSource::Position, 0, 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[] = {
|
||||
/* Default solid 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* MorphBall shadow shading */
|
||||
{1, MBShadowBlockNames, 3, BallFadeTextures, hecl::Backend::BlendFactor::SrcAlpha,
|
||||
{3, BallFadeTextures, hecl::Backend::BlendFactor::SrcAlpha,
|
||||
hecl::Backend::BlendFactor::InvSrcAlpha, hecl::Backend::ZTest::Equal, hecl::Backend::CullMode::Backface, false,
|
||||
false, true, false, true},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* 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},
|
||||
/* Disintegration */
|
||||
{1, DisintegrateBlockNames, 2, DisintegrateTextures, hecl::Backend::BlendFactor::SrcAlpha,
|
||||
{2, DisintegrateTextures, hecl::Backend::BlendFactor::SrcAlpha,
|
||||
hecl::Backend::BlendFactor::InvSrcAlpha, hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Original, false,
|
||||
false, true, false, false, true},
|
||||
/* 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},
|
||||
/* 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,
|
||||
false, false, true, false, false, false, true},
|
||||
/* 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}};
|
||||
|
||||
extern const hecl::Backend::Function ExtensionLightingFuncsGLSL[];
|
||||
extern const hecl::Backend::Function ExtensionPostFuncsGLSL[];
|
||||
extern const hecl::Backend::Function ExtensionLightingFuncsHLSL[];
|
||||
extern const hecl::Backend::Function ExtensionPostFuncsHLSL[];
|
||||
extern const hecl::Backend::Function ExtensionLightingFuncsMetal[];
|
||||
extern const hecl::Backend::Function ExtensionPostFuncsMetal[];
|
||||
const char* ShaderMacros[] = {
|
||||
"URDE_LIGHTING",
|
||||
"URDE_LIGHTING",
|
||||
"URDE_THERMAL_HOT",
|
||||
"URDE_LIGHTING",
|
||||
"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() {
|
||||
const hecl::Backend::Function* lightingFuncs;
|
||||
const hecl::Backend::Function* postFuncs;
|
||||
switch (CGraphics::g_BooPlatform) {
|
||||
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++;
|
||||
}
|
||||
const char** macro = ShaderMacros;
|
||||
for (auto& ext : g_ExtensionSlots)
|
||||
ext.shaderMacro = *macro++;
|
||||
}
|
||||
|
||||
void CModelShaders::Shutdown() { g_ShaderPipelines.clear(); }
|
||||
|
||||
CModelShaders::ShaderPipelines CModelShaders::BuildExtendedShader(const hecl::Backend::ShaderTag& tag,
|
||||
const hecl::Frontend::IR& ir) {
|
||||
const Material& material) {
|
||||
auto search = g_ShaderPipelines.find(tag.val64());
|
||||
if (search != g_ShaderPipelines.cend())
|
||||
return search->second;
|
||||
|
@ -199,9 +195,10 @@ CModelShaders::ShaderPipelines CModelShaders::BuildExtendedShader(const hecl::Ba
|
|||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
size_t idx = 0;
|
||||
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;
|
||||
} BooTrace);
|
||||
return newPipelines;
|
||||
}
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "hecl/Runtime.hpp"
|
||||
#include "hecl/Backend/Backend.hpp"
|
||||
#include "hecl/Backend.hpp"
|
||||
#include "optional.hpp"
|
||||
#include "zeus/CVector3f.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
#include "DataSpec/DNAMP1/CMDLMaterials.hpp"
|
||||
#include <array>
|
||||
|
||||
#define URDE_MAX_LIGHTS 8
|
||||
|
@ -88,7 +89,8 @@ public:
|
|||
using ShaderPipelinesData = std::array<boo::ObjToken<boo::IShaderPipeline>, EExtendedShader::MAX>;
|
||||
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:
|
||||
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
|
|
@ -1081,7 +1081,7 @@ void CGameArea::FillInStaticGeometry(bool textures) {
|
|||
|
||||
TToken<CModel> nullModel;
|
||||
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;
|
||||
|
|
|
@ -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.FreeScriptObject(GetUniqueId());
|
||||
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) {
|
||||
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);
|
||||
|
||||
if (x44_ctrlCmdOpt == EControlCommandOption::Filtered && x40_ctrl == EControl::Filtered) {
|
||||
|
|
|
@ -2,7 +2,7 @@ include_directories(../hecl/include
|
|||
../hecl/extern/boo/include
|
||||
../hecl/extern/boo/logvisor/include
|
||||
../hecl/extern/athena/include
|
||||
../specter/zeus/include
|
||||
../DataSpec
|
||||
../Runtime)
|
||||
add_shader(CAABoxShader)
|
||||
add_shader(CCameraBlurFilter)
|
||||
|
@ -35,3 +35,7 @@ add_special_shader(shader_CFluidPlaneShader
|
|||
shader_CFluidPlaneShaderGLSL.cpp
|
||||
shader_CFluidPlaneShaderHLSL.cpp
|
||||
shader_CFluidPlaneShaderMetal.cpp)
|
||||
add_special_shader(shader_CModelShaders
|
||||
shader_CModelShadersGLSL.cpp
|
||||
shader_CModelShadersHLSL.cpp
|
||||
shader_CModelShadersMetal.cpp)
|
|
@ -0,0 +1,18 @@
|
|||
#extension GL_ARB_enhanced_layouts: enable
|
||||
#extension GL_ARB_shader_image_load_store: enable
|
||||
|
||||
struct VertToFrag {
|
||||
vec4 mvPos;
|
||||
vec4 mvNorm;
|
||||
vec4 color;
|
||||
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,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, 1.0, 1.0, 1.0);
|
||||
const vec4 colorReg1 = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
const vec4 colorReg2 = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
#endif
|
||||
|
||||
#if defined(URDE_LIGHTING)
|
||||
vec3 LightingFunc(vec3 mvPosIn, vec3 mvNormIn) {
|
||||
vec4 ret = ambient;
|
||||
|
||||
for (int i = 0; i < URDE_MAX_LIGHTS; ++i) {
|
||||
vec3 delta = mvPosIn - 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, mvNormIn), 0.0);
|
||||
}
|
||||
|
||||
return clamp(ret.rgb, vec3(0.0), vec3(1.0));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(URDE_THERMAL_HOT)
|
||||
vec3 LightingFunc(vec3 mvPosIn, vec3 mvNormIn) {
|
||||
return vec3(1.0,1.0,1.0);
|
||||
}
|
||||
UBINDING2 uniform ThermalUniform {
|
||||
vec4 tmulColor;
|
||||
vec4 taddColor;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(URDE_THERMAL_COLD)
|
||||
vec3 LightingFunc(vec3 mvPosIn, vec3 mvNormIn) {
|
||||
return vec3(1.0,1.0,1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(URDE_SOLID)
|
||||
vec3 LightingFunc(vec3 mvPosIn, vec3 mvNormIn) {
|
||||
return vec3(1.0,1.0,1.0);
|
||||
}
|
||||
UBINDING2 uniform SolidUniform {
|
||||
vec4 solidColor;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(URDE_MB_SHADOW)
|
||||
vec3 LightingFunc(vec3 mvPosIn, vec3 mvNormIn) {
|
||||
return vec3(1.0,1.0,1.0);
|
||||
}
|
||||
UBINDING2 uniform MBShadowUniform {
|
||||
vec4 shadowUp;
|
||||
float shadowId;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(URDE_LIGHTING_SHADOW)
|
||||
vec3 LightingFunc(vec3 mvPosIn, vec3 mvNormIn) {
|
||||
vec2 shadowUV = vtf.extUvs[0];
|
||||
shadowUV.y = 1.0 - shadowUV.y;
|
||||
|
||||
vec4 ret = ambient;
|
||||
|
||||
vec3 delta = mvPosIn - 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, mvNormIn), 0.0) *
|
||||
texture(extTex0, shadowUV).r;
|
||||
|
||||
for (int i = 1; i < URDE_MAX_LIGHTS; ++i) {
|
||||
vec3 delta = mvPosIn - 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, mvNormIn), 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(vec3 mvPosIn, vec3 mvNormIn) {
|
||||
return vec3(1.0,1.0,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, 0.0, 0.0); }
|
||||
#endif
|
||||
|
||||
layout(location=0) out vec4 colorOut;
|
||||
void main() {
|
||||
vec3 lighting = LightingFunc(vtf.mvPos.xyz, vtf.mvNorm.xyz);
|
||||
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,61 @@
|
|||
UBINDING0 uniform HECLVertUniform {
|
||||
#if URDE_SKIN_SLOTS
|
||||
mat4 objs[URDE_SKIN_SLOTS];
|
||||
mat4 objsInv[URDE_SKIN_SLOTS];
|
||||
#endif
|
||||
mat4 mv;
|
||||
mat4 mvInv;
|
||||
mat4 proj;
|
||||
};
|
||||
|
||||
struct HECLTCGMatrix {
|
||||
mat4 mtx;
|
||||
mat4 postMtx;
|
||||
};
|
||||
UBINDING1 uniform HECLTexMtxUniform {
|
||||
HECLTCGMatrix texMtxs[8];
|
||||
};
|
||||
|
||||
UBINDING3 uniform HECLReflectMtx {
|
||||
mat4 indMtx;
|
||||
mat4 reflectMtx;
|
||||
float reflectAlpha;
|
||||
};
|
||||
|
||||
layout(location=0) in vec3 posIn;
|
||||
layout(location=1) in vec3 normIn;
|
||||
#if URDE_COL_SLOTS
|
||||
layout(location=2) in vec4 colIn[URDE_COL_SLOTS];
|
||||
#endif
|
||||
#if URDE_UV_SLOTS
|
||||
layout(location=2 + URDE_COL_SLOTS) in vec2 uvIn[URDE_UV_SLOTS];
|
||||
#endif
|
||||
#if URDE_WEIGHT_SLOTS
|
||||
layout(location=2 + URDE_COL_SLOTS + URDE_UV_SLOTS) in vec4 weightIn[URDE_WEIGHT_SLOTS];
|
||||
#endif
|
||||
|
||||
SBINDING(0) out VertToFrag vtf;
|
||||
void main() {
|
||||
#if URDE_SKIN_SLOTS
|
||||
vec4 objPos = vec4(0.0,0.0,0.0,0.0);
|
||||
vec4 objNorm = vec4(0.0,0.0,0.0,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;
|
||||
URDE_TCG_EXPR
|
||||
}
|
|
@ -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(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,217 @@
|
|||
#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_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 (int i = 0; i < info.m_extension.texCount; ++i) {
|
||||
const auto& extTex = info.m_extension.texs[i];
|
||||
if (extTex.mtxIdx < 0)
|
||||
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);
|
||||
}
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit a80592249b8a6ace071249824a55a1e979ae3e3d
|
||||
Subproject commit 43536e34f1d820c7b88c71f77c3ccd7b3d7bc35c
|
2
specter
2
specter
|
@ -1 +1 @@
|
|||
Subproject commit b32f4975a8f0e5f282339b162069d1fbc15c298d
|
||||
Subproject commit 3d0d62e0324bc881f4ae3058b8ec89c8a2c95a66
|
Loading…
Reference in New Issue