mirror of https://github.com/AxioDL/metaforce.git
Add emissive cycles shaders
This commit is contained in:
parent
2c5a662fec
commit
aa84d7c725
|
@ -191,6 +191,10 @@ class VertPool:
|
||||||
sp = struct.pack('I', self.get_skin_idx(loop.vert))
|
sp = struct.pack('I', self.get_skin_idx(loop.vert))
|
||||||
writebuf(sp)
|
writebuf(sp)
|
||||||
|
|
||||||
|
def null_loop_out(self, writebuf):
|
||||||
|
writebuf(struct.pack('B', 1))
|
||||||
|
writebuf(struct.pack('I', 0xffffffff))
|
||||||
|
|
||||||
def loop_out_map(self, writebuf, loop):
|
def loop_out_map(self, writebuf, loop):
|
||||||
writebuf(struct.pack('B', 1))
|
writebuf(struct.pack('B', 1))
|
||||||
writebuf(struct.pack('I', self.get_pos_idx(loop.vert)))
|
writebuf(struct.pack('I', self.get_pos_idx(loop.vert)))
|
||||||
|
@ -346,8 +350,7 @@ def write_out_surface(writebuf, output_mode, vert_pool, island_faces, mat_idx):
|
||||||
out_count = sl[2]
|
out_count = sl[2]
|
||||||
island_faces = max_island_faces
|
island_faces = max_island_faces
|
||||||
if prev_loop_emit:
|
if prev_loop_emit:
|
||||||
vert_pool.loop_out(writebuf, prev_loop_emit)
|
vert_pool.null_loop_out(writebuf)
|
||||||
vert_pool.loop_out(writebuf, max_sl[0])
|
|
||||||
for loop in max_sl:
|
for loop in max_sl:
|
||||||
vert_pool.loop_out(writebuf, loop)
|
vert_pool.loop_out(writebuf, loop)
|
||||||
prev_loop_emit = loop
|
prev_loop_emit = loop
|
||||||
|
|
|
@ -301,14 +301,10 @@ def tex_node_from_node(node):
|
||||||
if node.type == 'TEXTURE':
|
if node.type == 'TEXTURE':
|
||||||
return node
|
return node
|
||||||
elif node.type == 'MIX_RGB':
|
elif node.type == 'MIX_RGB':
|
||||||
if node.inputs[1].is_linked:
|
if node.inputs[1].is_linked and node.inputs[1].links[0].from_node.type == 'TEXTURE':
|
||||||
ret = image_from_node(node.inputs[1].links[0].from_node)
|
return node.inputs[1].links[0].from_node
|
||||||
if ret:
|
if node.inputs[2].is_linked and node.inputs[2].links[0].from_node.type == 'TEXTURE':
|
||||||
return ret
|
return node.inputs[2].links[0].from_node
|
||||||
if node.inputs[2].is_linked:
|
|
||||||
ret = image_from_node(node.inputs[2].links[0].from_node)
|
|
||||||
if ret:
|
|
||||||
return ret
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Delete existing cycles nodes and convert from GLSL nodes
|
# Delete existing cycles nodes and convert from GLSL nodes
|
||||||
|
@ -379,20 +375,28 @@ def initialize_nodetree_cycles(mat, area_data):
|
||||||
mapping = nt.nodes.new('ShaderNodeUVMap')
|
mapping = nt.nodes.new('ShaderNodeUVMap')
|
||||||
gridder.place_node(mapping, 1)
|
gridder.place_node(mapping, 1)
|
||||||
mapping.uv_map = tex_node.inputs[0].links[0].from_node.uv_layer
|
mapping.uv_map = tex_node.inputs[0].links[0].from_node.uv_layer
|
||||||
nt.links.new(diffuse_image_node.outputs[0], diffuse.inputs[0])
|
nt.links.new(mapping.outputs[0], diffuse_image_node.inputs[0])
|
||||||
nt.links.new(diffuse_image_node.outputs[0], mixrgb_node.inputs[2])
|
light_path = nt.nodes.new('ShaderNodeLightPath')
|
||||||
|
gridder.place_node(light_path, 2)
|
||||||
|
mixrgb_reflect = nt.nodes.new('ShaderNodeMixRGB')
|
||||||
|
gridder.place_node(mixrgb_reflect, 2)
|
||||||
|
nt.links.new(light_path.outputs['Is Reflection Ray'], mixrgb_reflect.inputs[0])
|
||||||
|
mixrgb_reflect.inputs[1].default_value = (1.0,1.0,1.0,1.0)
|
||||||
|
nt.links.new(diffuse_image_node.outputs[0], mixrgb_reflect.inputs[2])
|
||||||
|
nt.links.new(mixrgb_reflect.outputs[0], diffuse.inputs[0])
|
||||||
|
nt.links.new(mixrgb_reflect.outputs[0], mixrgb_node.inputs[2])
|
||||||
if nt.nodes['Output'].inputs[1].is_linked:
|
if nt.nodes['Output'].inputs[1].is_linked:
|
||||||
nt.links.new(nt.nodes['Output'].inputs[1].links[0].from_socket, mix_shader.inputs[0])
|
nt.links.new(nt.nodes['Output'].inputs[1].links[0].from_socket, mix_shader.inputs[0])
|
||||||
nt.links.new(nt.nodes['Output'].inputs[1].links[0].from_socket, mixrgb_node.inputs[0])
|
nt.links.new(nt.nodes['Output'].inputs[1].links[0].from_socket, mixrgb_node.inputs[0])
|
||||||
nt.links.new(mixrgb_node.outputs[0], transp.inputs[0])
|
nt.links.new(mixrgb_node.outputs[0], transp.inputs[0])
|
||||||
nt.links.new(mapping.outputs[0], diffuse_image_node.inputs[0])
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Classify connected opaque textures
|
# Classify connected opaque textures
|
||||||
chain = recursive_build_material_chain(nt.nodes['Output'])
|
chain = recursive_build_material_chain(nt.nodes['Output'])
|
||||||
if chain:
|
if chain:
|
||||||
|
diffuse = None
|
||||||
|
emissive = None
|
||||||
diffuse_soc, emissive_soc = get_de_sockets(chain)
|
diffuse_soc, emissive_soc = get_de_sockets(chain)
|
||||||
emissive_soc = None
|
|
||||||
if diffuse_soc:
|
if diffuse_soc:
|
||||||
tex_node = tex_node_from_node(diffuse_soc.node)
|
tex_node = tex_node_from_node(diffuse_soc.node)
|
||||||
if tex_node and tex_node.inputs[0].links[0].from_socket.name == 'UV':
|
if tex_node and tex_node.inputs[0].links[0].from_socket.name == 'UV':
|
||||||
|
@ -402,21 +406,37 @@ def initialize_nodetree_cycles(mat, area_data):
|
||||||
mapping = nt.nodes.new('ShaderNodeUVMap')
|
mapping = nt.nodes.new('ShaderNodeUVMap')
|
||||||
gridder.place_node(mapping, 1)
|
gridder.place_node(mapping, 1)
|
||||||
mapping.uv_map = tex_node.inputs[0].links[0].from_node.uv_layer
|
mapping.uv_map = tex_node.inputs[0].links[0].from_node.uv_layer
|
||||||
|
nt.links.new(mapping.outputs[0], diffuse_image_node.inputs[0])
|
||||||
|
light_path = nt.nodes.new('ShaderNodeLightPath')
|
||||||
|
gridder.place_node(light_path, 2)
|
||||||
|
mixrgb_reflect = nt.nodes.new('ShaderNodeMixRGB')
|
||||||
|
gridder.place_node(mixrgb_reflect, 2)
|
||||||
|
nt.links.new(light_path.outputs['Is Reflection Ray'], mixrgb_reflect.inputs[0])
|
||||||
|
mixrgb_reflect.inputs[1].default_value = (1.0,1.0,1.0,1.0)
|
||||||
|
nt.links.new(diffuse_image_node.outputs[0], mixrgb_reflect.inputs[2])
|
||||||
diffuse = nt.nodes.new('ShaderNodeBsdfDiffuse')
|
diffuse = nt.nodes.new('ShaderNodeBsdfDiffuse')
|
||||||
gridder.place_node(diffuse, 2)
|
gridder.place_node(diffuse, 2)
|
||||||
nt.links.new(diffuse_image_node.outputs[0], diffuse.inputs[0])
|
nt.links.new(mixrgb_reflect.outputs[0], diffuse.inputs[0])
|
||||||
nt.links.new(mapping.outputs[0], diffuse_image_node.inputs[0])
|
|
||||||
else:
|
else:
|
||||||
diffuse = nt.nodes.new('ShaderNodeBsdfDiffuse')
|
diffuse = nt.nodes.new('ShaderNodeBsdfDiffuse')
|
||||||
gridder.place_node(diffuse, 2)
|
gridder.place_node(diffuse, 2)
|
||||||
if emissive_soc:
|
if emissive_soc:
|
||||||
emissive = nt.nodes.new('ShaderNodeEmission')
|
tex_node = tex_node_from_node(emissive_soc.node)
|
||||||
gridder.place_node(emissive, 2)
|
if tex_node and tex_node.inputs[0].links[0].from_socket.name == 'UV':
|
||||||
nt.links.new(emissive_soc, emissive.inputs[0])
|
emissive_image_node = nt.nodes.new('ShaderNodeTexImage')
|
||||||
|
gridder.place_node(emissive_image_node, 1)
|
||||||
|
emissive_image_node.image = tex_node.texture.image
|
||||||
|
mapping = nt.nodes.new('ShaderNodeUVMap')
|
||||||
|
gridder.place_node(mapping, 1)
|
||||||
|
mapping.uv_map = tex_node.inputs[0].links[0].from_node.uv_layer
|
||||||
|
nt.links.new(mapping.outputs[0], emissive_image_node.inputs[0])
|
||||||
|
emissive = nt.nodes.new('ShaderNodeEmission')
|
||||||
|
gridder.place_node(emissive, 2)
|
||||||
|
nt.links.new(emissive_image_node.outputs[0], emissive.inputs[0])
|
||||||
|
|
||||||
material_output = nt.nodes.new('ShaderNodeOutputMaterial')
|
material_output = nt.nodes.new('ShaderNodeOutputMaterial')
|
||||||
gridder.place_node(material_output, 3)
|
gridder.place_node(material_output, 3)
|
||||||
if diffuse_soc and emissive_soc:
|
if diffuse and emissive:
|
||||||
shader_add = nt.nodes.new('ShaderNodeAddShader')
|
shader_add = nt.nodes.new('ShaderNodeAddShader')
|
||||||
gridder.place_node(shader_add, 2)
|
gridder.place_node(shader_add, 2)
|
||||||
nt.links.new(diffuse.outputs[0], shader_add.inputs[0])
|
nt.links.new(diffuse.outputs[0], shader_add.inputs[0])
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
if(NOT WINDOWS_STORE)
|
if(NOT WINDOWS_STORE)
|
||||||
|
if(TARGET nod)
|
||||||
|
include_directories(${NOD_INCLUDE_DIR})
|
||||||
|
add_definitions(-DHECL_HAS_NOD=1)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_executable(hecl main.cpp
|
add_executable(hecl main.cpp
|
||||||
ToolBase.hpp
|
ToolBase.hpp
|
||||||
ToolPackage.hpp
|
ToolPackage.hpp
|
||||||
|
@ -6,6 +11,7 @@ add_executable(hecl main.cpp
|
||||||
ToolInit.hpp
|
ToolInit.hpp
|
||||||
ToolHelp.hpp
|
ToolHelp.hpp
|
||||||
ToolCook.hpp
|
ToolCook.hpp
|
||||||
|
ToolImage.hpp
|
||||||
ToolSpec.hpp
|
ToolSpec.hpp
|
||||||
../DataSpecRegistry.hpp)
|
../DataSpecRegistry.hpp)
|
||||||
if(COMMAND add_sanitizers)
|
if(COMMAND add_sanitizers)
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
#ifndef CTOOL_IMAGE
|
||||||
|
#define CTOOL_IMAGE
|
||||||
|
|
||||||
|
#if HECL_HAS_NOD
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "ToolBase.hpp"
|
||||||
|
#include <cstdio>
|
||||||
|
#include "nod/DiscGCN.hpp"
|
||||||
|
#include "nod/DiscWii.hpp"
|
||||||
|
#include "athena/FileReader.hpp"
|
||||||
|
|
||||||
|
class ToolImage final : public ToolBase
|
||||||
|
{
|
||||||
|
std::unique_ptr<hecl::Database::Project> m_fallbackProj;
|
||||||
|
hecl::Database::Project* m_useProj;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ToolImage(const ToolPassInfo& info)
|
||||||
|
: ToolBase(info), m_useProj(info.project)
|
||||||
|
{
|
||||||
|
if (!info.project)
|
||||||
|
LogModule.report(logvisor::Fatal, "hecl image must be ran within a project directory");
|
||||||
|
|
||||||
|
/* Scan args */
|
||||||
|
if (info.args.size())
|
||||||
|
{
|
||||||
|
/* See if project path is supplied via args and use that over the getcwd one */
|
||||||
|
for (const hecl::SystemString& arg : info.args)
|
||||||
|
{
|
||||||
|
if (arg.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
hecl::SystemString subPath;
|
||||||
|
hecl::ProjectRootPath root = hecl::SearchForProject(MakePathArgAbsolute(arg, info.cwd), subPath);
|
||||||
|
|
||||||
|
if (root)
|
||||||
|
{
|
||||||
|
if (!m_fallbackProj)
|
||||||
|
{
|
||||||
|
m_fallbackProj.reset(new hecl::Database::Project(root));
|
||||||
|
m_useProj = m_fallbackProj.get();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!m_useProj)
|
||||||
|
LogModule.report(logvisor::Fatal,
|
||||||
|
"hecl image must be ran within a project directory or "
|
||||||
|
"provided a path within a project");
|
||||||
|
}
|
||||||
|
|
||||||
|
~ToolImage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Help(HelpOutput& help)
|
||||||
|
{
|
||||||
|
help.secHead(_S("NAME"));
|
||||||
|
help.beginWrap();
|
||||||
|
help.wrap(_S("hecl-image - Generate GameCube/Wii disc image from packaged files\n"));
|
||||||
|
help.endWrap();
|
||||||
|
|
||||||
|
help.secHead(_S("SYNOPSIS"));
|
||||||
|
help.beginWrap();
|
||||||
|
help.wrap(_S("hecl image [<input-dir>]\n"));
|
||||||
|
help.endWrap();
|
||||||
|
|
||||||
|
help.secHead(_S("DESCRIPTION"));
|
||||||
|
help.beginWrap();
|
||||||
|
help.wrap(_S("This command uses the current contents of `out` to generate a GameCube or ")
|
||||||
|
_S("Wii disc image. `hecl package` must have been run previously to be effective.\n"));
|
||||||
|
help.endWrap();
|
||||||
|
|
||||||
|
help.secHead(_S("OPTIONS"));
|
||||||
|
help.optionHead(_S("<input-dir>"), _S("input directory"));
|
||||||
|
help.beginWrap();
|
||||||
|
help.wrap(_S("Specifies a project subdirectory to root the resulting image from. ")
|
||||||
|
_S("Project must contain an out/sys and out/files directory to succeed.\n"));
|
||||||
|
help.endWrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
hecl::SystemString toolName() const {return _S("image");}
|
||||||
|
|
||||||
|
int run()
|
||||||
|
{
|
||||||
|
if (XTERM_COLOR)
|
||||||
|
hecl::Printf(_S("" GREEN BOLD "ABOUT TO IMAGE:" NORMAL "\n"));
|
||||||
|
else
|
||||||
|
hecl::Printf(_S("ABOUT TO IMAGE:\n"));
|
||||||
|
|
||||||
|
hecl::Printf(_S(" %s\n"), m_useProj->getProjectRootPath().getAbsolutePath().data());
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
if (continuePrompt())
|
||||||
|
{
|
||||||
|
hecl::ProjectPath outPath(m_useProj->getProjectWorkingPath(), _S("out"));
|
||||||
|
if (!outPath.isDirectory())
|
||||||
|
{
|
||||||
|
LogModule.report(logvisor::Error, _S("%s is not a directory"), outPath.getAbsolutePath().data());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hecl::ProjectPath bootBinPath(outPath, _S("sys/boot.bin"));
|
||||||
|
if (!bootBinPath.isFile())
|
||||||
|
{
|
||||||
|
LogModule.report(logvisor::Error, _S("%s is not a file"), bootBinPath.getAbsolutePath().data());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
athena::io::FileReader r(bootBinPath.getAbsolutePath());
|
||||||
|
if (r.hasError())
|
||||||
|
{
|
||||||
|
LogModule.report(logvisor::Error, _S("unable to open %s"), bootBinPath.getAbsolutePath().data());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::string id = r.readString(6);
|
||||||
|
r.close();
|
||||||
|
|
||||||
|
hecl::SystemStringConv idView(id);
|
||||||
|
hecl::SystemString fileOut = hecl::SystemString(outPath.getAbsolutePath()) + _S('/') + idView.c_str();
|
||||||
|
hecl::MultiProgressPrinter printer(true);
|
||||||
|
auto progFunc = [&printer](float totalProg, nod::SystemStringView fileName, size_t fileBytesXfered)
|
||||||
|
{
|
||||||
|
printer.print(fileName.data(), nullptr, totalProg);
|
||||||
|
};
|
||||||
|
if (id[0] == 'G')
|
||||||
|
{
|
||||||
|
fileOut += _S(".gcm");
|
||||||
|
if (nod::DiscBuilderGCN::CalculateTotalSizeRequired(outPath.getAbsolutePath()) == -1)
|
||||||
|
return 1;
|
||||||
|
LogModule.report(logvisor::Info, _S("Generating %s as GameCube image"), fileOut.c_str());
|
||||||
|
nod::DiscBuilderGCN db(fileOut, progFunc);
|
||||||
|
if (db.buildFromDirectory(outPath.getAbsolutePath()) != nod::EBuildResult::Success)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileOut += _S(".iso");
|
||||||
|
bool dualLayer;
|
||||||
|
if (nod::DiscBuilderWii::CalculateTotalSizeRequired(outPath.getAbsolutePath(), dualLayer) == -1)
|
||||||
|
return 1;
|
||||||
|
LogModule.report(logvisor::Info, _S("Generating %s as %s-layer Wii image"), fileOut.c_str(),
|
||||||
|
dualLayer ? _S("dual") : _S("single"));
|
||||||
|
nod::DiscBuilderWii db(fileOut, dualLayer, progFunc);
|
||||||
|
if (db.buildFromDirectory(outPath.getAbsolutePath()) != nod::EBuildResult::Success)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // CTOOL_IMAGE
|
|
@ -26,6 +26,7 @@ logvisor::Module LogModule("hecl::Driver");
|
||||||
#include "ToolExtract.hpp"
|
#include "ToolExtract.hpp"
|
||||||
#include "ToolCook.hpp"
|
#include "ToolCook.hpp"
|
||||||
#include "ToolPackage.hpp"
|
#include "ToolPackage.hpp"
|
||||||
|
#include "ToolImage.hpp"
|
||||||
#include "ToolHelp.hpp"
|
#include "ToolHelp.hpp"
|
||||||
|
|
||||||
/* Static reference to dataspec additions
|
/* Static reference to dataspec additions
|
||||||
|
@ -49,12 +50,17 @@ static void printHelp(const hecl::SystemChar* pname)
|
||||||
hecl::Printf(_S("" BOLD "HECL" NORMAL ""));
|
hecl::Printf(_S("" BOLD "HECL" NORMAL ""));
|
||||||
else
|
else
|
||||||
hecl::Printf(_S("HECL"));
|
hecl::Printf(_S("HECL"));
|
||||||
#if HECL_GIT
|
#if HECL_HAS_NOD
|
||||||
hecl::Printf(_S(" Commit " HECL_GIT_S " " HECL_BRANCH_S "\nUsage: %s extract|init|add|remove|group|cook|clean|package|help\n"), pname);
|
# define TOOL_LIST "extract|init|cook|package|image|help"
|
||||||
#elif HECL_VER
|
|
||||||
hecl::Printf(_S(" Version " HECL_VER_S "\nUsage: %s extract|init|add|remove|group|cook|clean|package|help\n"), pname);
|
|
||||||
#else
|
#else
|
||||||
hecl::Printf(_S("\nUsage: %s extract|init|cook|package|help\n"), pname);
|
# define TOOL_LIST "extract|init|cook|package|help"
|
||||||
|
#endif
|
||||||
|
#if HECL_GIT
|
||||||
|
hecl::Printf(_S(" Commit " HECL_GIT_S " " HECL_BRANCH_S "\nUsage: %s " TOOL_LIST "\n"), pname);
|
||||||
|
#elif HECL_VER
|
||||||
|
hecl::Printf(_S(" Version " HECL_VER_S "\nUsage: %s " TOOL_LIST "\n"), pname);
|
||||||
|
#else
|
||||||
|
hecl::Printf(_S("\nUsage: %s " TOOL_LIST "\n"), pname);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,6 +272,10 @@ int main(int argc, const char** argv)
|
||||||
tool.reset(new ToolCook(info));
|
tool.reset(new ToolCook(info));
|
||||||
else if (toolName == _S("package") || toolName == _S("pack"))
|
else if (toolName == _S("package") || toolName == _S("pack"))
|
||||||
tool.reset(new ToolPackage(info));
|
tool.reset(new ToolPackage(info));
|
||||||
|
#if HECL_HAS_NOD
|
||||||
|
else if (toolName == _S("image"))
|
||||||
|
tool.reset(new ToolImage(info));
|
||||||
|
#endif
|
||||||
else if (toolName == _S("help"))
|
else if (toolName == _S("help"))
|
||||||
tool.reset(new ToolHelp(info));
|
tool.reset(new ToolHelp(info));
|
||||||
else
|
else
|
||||||
|
|
|
@ -227,12 +227,12 @@ struct Mesh
|
||||||
/** Vertex indexing data (all primitives joined as degenerate tri-strip) */
|
/** Vertex indexing data (all primitives joined as degenerate tri-strip) */
|
||||||
struct Vert
|
struct Vert
|
||||||
{
|
{
|
||||||
uint32_t iPos;
|
uint32_t iPos = 0xffffffff;
|
||||||
uint32_t iNorm;
|
uint32_t iNorm = 0xffffffff;
|
||||||
uint32_t iColor[4] = {uint32_t(-1)};
|
uint32_t iColor[4] = {0xffffffff};
|
||||||
uint32_t iUv[8] = {uint32_t(-1)};
|
uint32_t iUv[8] = {0xffffffff};
|
||||||
uint32_t iSkin;
|
uint32_t iSkin = 0xffffffff;
|
||||||
uint32_t iBankSkin = -1;
|
uint32_t iBankSkin = 0xffffffff;
|
||||||
|
|
||||||
Vert(Connection& conn, const Mesh& parent);
|
Vert(Connection& conn, const Mesh& parent);
|
||||||
bool operator==(const Vert& other) const;
|
bool operator==(const Vert& other) const;
|
||||||
|
|
|
@ -1073,6 +1073,8 @@ Mesh::Mesh(Connection& conn, HMDLTopology topologyIn, int skinSlotCount, SurfPro
|
||||||
SkinBanks::Bank& bank = skinBanks.banks[surf.skinBankIdx];
|
SkinBanks::Bank& bank = skinBanks.banks[surf.skinBankIdx];
|
||||||
for (Surface::Vert& vert : surf.verts)
|
for (Surface::Vert& vert : surf.verts)
|
||||||
{
|
{
|
||||||
|
if (vert.iPos == 0xffffffff)
|
||||||
|
continue;
|
||||||
for (uint32_t i=0 ; i<bank.m_skinIdxs.size() ; ++i)
|
for (uint32_t i=0 ; i<bank.m_skinIdxs.size() ; ++i)
|
||||||
{
|
{
|
||||||
if (bank.m_skinIdxs[i] == vert.iSkin)
|
if (bank.m_skinIdxs[i] == vert.iSkin)
|
||||||
|
@ -1101,6 +1103,8 @@ Mesh Mesh::getContiguousSkinningVersion() const
|
||||||
{
|
{
|
||||||
for (Surface::Vert& vert : surf.verts)
|
for (Surface::Vert& vert : surf.verts)
|
||||||
{
|
{
|
||||||
|
if (vert.iPos == 0xffffffff)
|
||||||
|
continue;
|
||||||
if (vert.iSkin == i)
|
if (vert.iSkin == i)
|
||||||
{
|
{
|
||||||
auto key = std::make_pair(vert.iPos, vert.iNorm);
|
auto key = std::make_pair(vert.iPos, vert.iNorm);
|
||||||
|
@ -1194,6 +1198,8 @@ Mesh::Surface::Surface(Connection& conn, Mesh& parent, int skinSlotCount)
|
||||||
Mesh::Surface::Vert::Vert(Connection& conn, const Mesh& parent)
|
Mesh::Surface::Vert::Vert(Connection& conn, const Mesh& parent)
|
||||||
{
|
{
|
||||||
conn._readBuf(&iPos, 4);
|
conn._readBuf(&iPos, 4);
|
||||||
|
if (iPos == 0xffffffff)
|
||||||
|
return;
|
||||||
conn._readBuf(&iNorm, 4);
|
conn._readBuf(&iNorm, 4);
|
||||||
for (uint32_t i=0 ; i<parent.colorLayerCount ; ++i)
|
for (uint32_t i=0 ; i<parent.colorLayerCount ; ++i)
|
||||||
conn._readBuf(&iColor[i], 4);
|
conn._readBuf(&iColor[i], 4);
|
||||||
|
@ -1282,6 +1288,8 @@ uint32_t Mesh::SkinBanks::addSurface(const Mesh& mesh, const Surface& surf, int
|
||||||
done = true;
|
done = true;
|
||||||
for (const Surface::Vert& v : surf.verts)
|
for (const Surface::Vert& v : surf.verts)
|
||||||
{
|
{
|
||||||
|
if (v.iPos == 0xffffffff)
|
||||||
|
continue;
|
||||||
if (!VertInBank(bank.m_skinIdxs, v.iSkin) && !VertInBank(toAdd, v.iSkin))
|
if (!VertInBank(bank.m_skinIdxs, v.iSkin) && !VertInBank(toAdd, v.iSkin))
|
||||||
{
|
{
|
||||||
toAdd.push_back(v.iSkin);
|
toAdd.push_back(v.iSkin);
|
||||||
|
|
|
@ -67,6 +67,12 @@ HMDLBuffers Mesh::getHMDLBuffers(bool absoluteCoords, PoolSkinIndex& poolSkinInd
|
||||||
size_t iboStart = iboData.size();
|
size_t iboStart = iboData.size();
|
||||||
for (const Surface::Vert& v : surf.verts)
|
for (const Surface::Vert& v : surf.verts)
|
||||||
{
|
{
|
||||||
|
if (v.iPos == 0xffffffff)
|
||||||
|
{
|
||||||
|
iboData.push_back(0xffffffff);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
size_t ti = 0;
|
size_t ti = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (const std::pair<const Surface*, const Surface::Vert*>& tv : vertPool)
|
for (const std::pair<const Surface*, const Surface::Vert*>& tv : vertPool)
|
||||||
|
|
Loading…
Reference in New Issue