mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-06-10 00:33:27 +00:00
Huge compile performance refactor
This commit is contained in:
parent
bc055b9126
commit
aae0dc56b7
@ -8,14 +8,11 @@
|
|||||||
|
|
||||||
#include "hecl/Database.hpp"
|
#include "hecl/Database.hpp"
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Database
|
||||||
{
|
|
||||||
namespace Database
|
|
||||||
{
|
{
|
||||||
/* Centralized registry for DataSpec lookup */
|
/* Centralized registry for DataSpec lookup */
|
||||||
std::vector<const struct DataSpecEntry*> DATA_SPEC_REGISTRY;
|
std::vector<const struct DataSpecEntry*> DATA_SPEC_REGISTRY;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@HECL_DATASPEC_DECLS@
|
@HECL_DATASPEC_DECLS@
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ macro(bintoc out in sym)
|
|||||||
endif()
|
endif()
|
||||||
add_custom_command(OUTPUT ${theOut}
|
add_custom_command(OUTPUT ${theOut}
|
||||||
COMMAND $<TARGET_FILE:bintoc> ARGS ${theIn} ${theOut} ${sym}
|
COMMAND $<TARGET_FILE:bintoc> ARGS ${theIn} ${theOut} ${sym}
|
||||||
DEPENDS ${theIn})
|
DEPENDS ${theIn} bintoc)
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
##################
|
##################
|
||||||
|
@ -20,7 +20,8 @@ int main(int argc, char** argv)
|
|||||||
fprintf(stderr, "Unable to open %s for writing\n", argv[2]);
|
fprintf(stderr, "Unable to open %s for writing\n", argv[2]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
fprintf(fout, "#include <stdint.h>\n#include <stdlib.h>\nconst uint8_t %s[] =\n{\n", argv[3]);
|
fprintf(fout, "#include <cstdint>\n#include <cstddef>\n");
|
||||||
|
fprintf(fout, "extern \"C\" const uint8_t %s[] =\n{\n", argv[3]);
|
||||||
size_t totalSz = 0;
|
size_t totalSz = 0;
|
||||||
size_t readSz;
|
size_t readSz;
|
||||||
uint8_t buf[32];
|
uint8_t buf[32];
|
||||||
@ -32,7 +33,7 @@ int main(int argc, char** argv)
|
|||||||
fprintf(fout, "0x%02X, ", buf[b]);
|
fprintf(fout, "0x%02X, ", buf[b]);
|
||||||
fprintf(fout, "\n");
|
fprintf(fout, "\n");
|
||||||
}
|
}
|
||||||
fprintf(fout, "0x0};\nconst size_t %s_SZ = %zu;\n", argv[3], totalSz);
|
fprintf(fout, "0x0};\nextern \"C\" const size_t %s_SZ = %zu;\n", argv[3], totalSz);
|
||||||
fclose(fin);
|
fclose(fin);
|
||||||
fclose(fout);
|
fclose(fout);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -14,20 +14,20 @@ list(APPEND PY_SOURCES
|
|||||||
hecl/mapu.py
|
hecl/mapu.py
|
||||||
hecl/frme.py)
|
hecl/frme.py)
|
||||||
|
|
||||||
bintoc(hecl_blendershell.c hecl_blendershell.py HECL_BLENDERSHELL)
|
bintoc(hecl_blendershell.cpp hecl_blendershell.py HECL_BLENDERSHELL)
|
||||||
|
|
||||||
add_custom_command(OUTPUT hecl.zip DEPENDS ${PY_SOURCES}
|
add_custom_command(OUTPUT hecl.zip DEPENDS ${PY_SOURCES}
|
||||||
COMMAND python ARGS zip_package.py ${CMAKE_CURRENT_BINARY_DIR}/hecl.zip
|
COMMAND python ARGS zip_package.py ${CMAKE_CURRENT_BINARY_DIR}/hecl.zip
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
COMMENT "Generating addon package")
|
COMMENT "Generating addon package")
|
||||||
bintoc(hecl_addon.c "${CMAKE_CURRENT_BINARY_DIR}/hecl.zip" HECL_ADDON)
|
bintoc(hecl_addon.cpp "${CMAKE_CURRENT_BINARY_DIR}/hecl.zip" HECL_ADDON)
|
||||||
bintoc(hecl_startup.c hecl_startup.blend HECL_STARTUP)
|
bintoc(hecl_startup.cpp hecl_startup.blend HECL_STARTUP)
|
||||||
|
|
||||||
add_library(hecl-blender-addon
|
add_library(hecl-blender-addon
|
||||||
hecl_blendershell.py
|
hecl_blendershell.py
|
||||||
hecl_blendershell.c
|
hecl_blendershell.cpp
|
||||||
zip_package.py
|
zip_package.py
|
||||||
hecl.zip
|
hecl.zip
|
||||||
hecl_addon.c
|
hecl_addon.cpp
|
||||||
hecl_startup.c
|
hecl_startup.cpp
|
||||||
${PY_SOURCES})
|
${PY_SOURCES})
|
||||||
|
@ -5,11 +5,7 @@ add_executable(hecl main.cpp
|
|||||||
ToolExtract.hpp
|
ToolExtract.hpp
|
||||||
ToolInit.hpp
|
ToolInit.hpp
|
||||||
ToolHelp.hpp
|
ToolHelp.hpp
|
||||||
ToolGroup.hpp
|
|
||||||
ToolCook.hpp
|
ToolCook.hpp
|
||||||
ToolClean.hpp
|
|
||||||
ToolAdd.hpp
|
|
||||||
ToolRemove.hpp
|
|
||||||
ToolSpec.hpp
|
ToolSpec.hpp
|
||||||
../DataSpecRegistry.hpp)
|
../DataSpecRegistry.hpp)
|
||||||
if(COMMAND add_sanitizers)
|
if(COMMAND add_sanitizers)
|
||||||
@ -30,4 +26,8 @@ target_link_libraries(hecl
|
|||||||
hecl-common hecl-blender-addon athena-core nod
|
hecl-common hecl-blender-addon athena-core nod
|
||||||
logvisor athena-libyaml ${PNG_LIB} squish xxhash zeus boo
|
logvisor athena-libyaml ${PNG_LIB} squish xxhash zeus boo
|
||||||
${ZLIB_LIBRARIES} ${LZO_LIB} ${PLAT_LIBS} ${BOO_SYS_LIBS})
|
${ZLIB_LIBRARIES} ${LZO_LIB} ${PLAT_LIBS} ${BOO_SYS_LIBS})
|
||||||
|
|
||||||
|
if(COMMAND cotire)
|
||||||
|
cotire(hecl)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
#ifndef CTOOL_ADD
|
|
||||||
#define CTOOL_ADD
|
|
||||||
|
|
||||||
#include "ToolBase.hpp"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
class ToolAdd final : public ToolBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ToolAdd(const ToolPassInfo& info)
|
|
||||||
: ToolBase(info)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Help(HelpOutput& help)
|
|
||||||
{
|
|
||||||
help.secHead(_S("NAME"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("hecl-add - Add working files to the HECL index\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.secHead(_S("SYNOPSIS"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("hecl add [<pathspec>...]\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.secHead(_S("DESCRIPTION"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("This command stages a file or glob-pattern of files within the project database ")
|
|
||||||
_S("for inclusion in the "));
|
|
||||||
help.wrapBold(_S("hecl cook"));
|
|
||||||
help.wrap(_S(" process.\n\n")
|
|
||||||
_S("Files added in this manner automatically become 'explicit' database ")
|
|
||||||
_S("objects. 'Explicit objects' will not be removed in housekeeping tasks automatically ")
|
|
||||||
_S("performed by HECL's library functions, unless the user (re)moves the file ")
|
|
||||||
_S("using the filesystem.\n\n")
|
|
||||||
_S("For details on explicit vs. implicit objects, view the "));
|
|
||||||
help.wrapBold(_S("hecl cook"));
|
|
||||||
help.wrap(_S(" documentation.\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.secHead(_S("OPTIONS"));
|
|
||||||
help.optionHead(_S("<pathspec>..."), _S("input file(s)"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("Working file(s) containing production data to be cooked by HECL. ")
|
|
||||||
_S("Glob-strings may be specified (e.g. "));
|
|
||||||
help.wrapBold(_S("*.blend"));
|
|
||||||
help.wrap(_S(") to automatically add all matching files to the database.\n"));
|
|
||||||
help.endWrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
hecl::SystemString toolName() const {return _S("add");}
|
|
||||||
|
|
||||||
int run()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CTOOL_ADD
|
|
@ -4,8 +4,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
#ifndef CTOOL_CLEAN
|
|
||||||
#define CTOOL_CLEAN
|
|
||||||
|
|
||||||
#include "ToolBase.hpp"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
class ToolClean final : public ToolBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ToolClean(const ToolPassInfo& info)
|
|
||||||
: ToolBase(info)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~ToolClean()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Help(HelpOutput& help)
|
|
||||||
{
|
|
||||||
help.secHead(_S("NAME"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("hecl-clean - Delete cached cooked objects referenced via working files\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.secHead(_S("SYNOPSIS"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("hecl clean [-ri] [<pathspec>...]\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.secHead(_S("DESCRIPTION"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("This command performs an immediate deletion of cooked objects cached ")
|
|
||||||
_S("within the project database. It may operate on a subset of objects or the ")
|
|
||||||
_S("entire project.\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.secHead(_S("OPTIONS"));
|
|
||||||
help.optionHead(_S("<pathspec>..."), _S("clean path(s)"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("When one or more paths are specified in the command, the clean process will ")
|
|
||||||
_S("restrict object deletion to only the working file(s) specified. If "));
|
|
||||||
help.wrapBold(_S("-r"));
|
|
||||||
help.wrap(_S(" is also specifed, directories may be provided as well. If no path(s) specified, ")
|
|
||||||
_S("the entire project is cleaned.\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.optionHead(_S("-r"), _S("recursion"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("Enables recursive file-matching for cleaning entire directories of working files.\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.optionHead(_S("-i"), _S("follow implicit links"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("Enables implicit object traversal and cleaning. This is only useful if one or more paths ")
|
|
||||||
_S("are specified. For objects supporting implicit-gathering, this will query those ")
|
|
||||||
_S("objects for their current implicit links and ensure the linked-objects are cleaned ")
|
|
||||||
_S("as well.\n"));
|
|
||||||
help.endWrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
hecl::SystemString toolName() const {return _S("clean");}
|
|
||||||
|
|
||||||
int run()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CTOOL_CLEAN
|
|
@ -2,7 +2,7 @@
|
|||||||
#define CTOOL_COOK
|
#define CTOOL_COOK
|
||||||
|
|
||||||
#include "ToolBase.hpp"
|
#include "ToolBase.hpp"
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include "hecl/ClientProcess.hpp"
|
#include "hecl/ClientProcess.hpp"
|
||||||
|
|
||||||
class ToolCook final : public ToolBase
|
class ToolCook final : public ToolBase
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define CTOOL_EXTRACT
|
#define CTOOL_EXTRACT
|
||||||
|
|
||||||
#include "ToolBase.hpp"
|
#include "ToolBase.hpp"
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
#ifndef CTOOL_GROUP
|
|
||||||
#define CTOOL_GROUP
|
|
||||||
|
|
||||||
#include "ToolBase.hpp"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
class ToolGroup final : public ToolBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ToolGroup(const ToolPassInfo& info)
|
|
||||||
: ToolBase(info)
|
|
||||||
{
|
|
||||||
if (!info.project)
|
|
||||||
LogModule.report(logvisor::Fatal, "hecl group must be ran within a project directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
~ToolGroup()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Help(HelpOutput& help)
|
|
||||||
{
|
|
||||||
help.secHead(_S("NAME"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("hecl-group - Fork a project directory as an explicit group\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.secHead(_S("SYNOPSIS"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("hecl group [-D] <dir>\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.secHead(_S("DESCRIPTION"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("This command turns a nested subdirectory of the project into a HECL group. ")
|
|
||||||
_S("Groups play an important role in the resulting structure of the packaged ")
|
|
||||||
_S("database. All objects in HECL belong to a group of some sort since the runtime ")
|
|
||||||
_S("only provides loading functions for groups. Ungrouped ")
|
|
||||||
_S("objects in the project root are individually added to 'loose groups'.\n\n With "));
|
|
||||||
help.wrapBold(_S("hecl group"));
|
|
||||||
help.wrap(_S(", explicit groups may be defined (e.g. a stage, level, area, loadable segment). "));
|
|
||||||
help.wrap(_S("Groups are defined by filesystem directories relative to the project root ")
|
|
||||||
_S("and may be loaded within the runtime using the relative path as a lookup-string. ")
|
|
||||||
_S("Sub-directories that aren't explicitly made into a group inherit the group-status ")
|
|
||||||
_S("of the parent directory.\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.secHead(_S("OPTIONS"));
|
|
||||||
help.optionHead(_S("<dir>"), _S("group directory path"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("Directory to fork as an explicit group\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.optionHead(_S("-D"), _S("delete group"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("Remove's directory's status as an explicit group; restoring its inheritance ")
|
|
||||||
_S("from the parent directory.\n"));
|
|
||||||
help.endWrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
hecl::SystemString toolName() const {return _S("group");}
|
|
||||||
|
|
||||||
int run()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CTOOL_GROUP
|
|
@ -2,7 +2,7 @@
|
|||||||
#define CTOOL_HELP
|
#define CTOOL_HELP
|
||||||
|
|
||||||
#include "ToolBase.hpp"
|
#include "ToolBase.hpp"
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
class ToolHelp final : public ToolBase
|
class ToolHelp final : public ToolBase
|
||||||
@ -66,16 +66,8 @@ public:
|
|||||||
helpFunc = ToolSpec::Help;
|
helpFunc = ToolSpec::Help;
|
||||||
else if (toolName == _S("extract"))
|
else if (toolName == _S("extract"))
|
||||||
helpFunc = ToolExtract::Help;
|
helpFunc = ToolExtract::Help;
|
||||||
else if (toolName == _S("add"))
|
|
||||||
helpFunc = ToolAdd::Help;
|
|
||||||
else if (toolName == _S("remove") || toolName == _S("rm"))
|
|
||||||
helpFunc = ToolRemove::Help;
|
|
||||||
else if (toolName == _S("group"))
|
|
||||||
helpFunc = ToolGroup::Help;
|
|
||||||
else if (toolName == _S("cook"))
|
else if (toolName == _S("cook"))
|
||||||
helpFunc = ToolCook::Help;
|
helpFunc = ToolCook::Help;
|
||||||
else if (toolName == _S("clean"))
|
|
||||||
helpFunc = ToolClean::Help;
|
|
||||||
else if (toolName == _S("package") || toolName == _S("pack"))
|
else if (toolName == _S("package") || toolName == _S("pack"))
|
||||||
helpFunc = ToolPackage::Help;
|
helpFunc = ToolPackage::Help;
|
||||||
else if (toolName == _S("help"))
|
else if (toolName == _S("help"))
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define CTOOL_INIT
|
#define CTOOL_INIT
|
||||||
|
|
||||||
#include "ToolBase.hpp"
|
#include "ToolBase.hpp"
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
|
|
||||||
class ToolInit final : public ToolBase
|
class ToolInit final : public ToolBase
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "ToolBase.hpp"
|
#include "ToolBase.hpp"
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
|
|
||||||
class ToolPackage final : public ToolBase
|
class ToolPackage final : public ToolBase
|
||||||
{
|
{
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
#ifndef CTOOL_REMOVE
|
|
||||||
#define CTOOL_REMOVE
|
|
||||||
|
|
||||||
#include "ToolBase.hpp"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
class ToolRemove final : public ToolBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ToolRemove(const ToolPassInfo& info)
|
|
||||||
: ToolBase(info)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~ToolRemove()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Help(HelpOutput& help)
|
|
||||||
{
|
|
||||||
help.secHead(_S("NAME"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("hecl-rm\n"));
|
|
||||||
help.wrap(_S("hecl-remove - Remove working files from the HECL index\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.secHead(_S("SYNOPSIS"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("hecl remove [-r] [<pathspec>...]\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.secHead(_S("DESCRIPTION"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("This command removes a file, directory, or glob-pattern of files from the project database. ")
|
|
||||||
_S("Once a file is removed, any cooked cache objects are deleted automatically. "));
|
|
||||||
help.wrapBold(_S("The working file itself is not deleted from the filesystem.\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.secHead(_S("OPTIONS"));
|
|
||||||
help.optionHead(_S("<pathspec>..."), _S("input file(s)"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("Working file(s) to be removed from the project database. ")
|
|
||||||
_S("Glob-strings may be specified (e.g. "));
|
|
||||||
help.wrapBold(_S("*.blend"));
|
|
||||||
help.wrap(_S(") to automatically remove all matching files from the database.\n"));
|
|
||||||
help.endWrap();
|
|
||||||
|
|
||||||
help.optionHead(_S("-r"), _S("recursion"));
|
|
||||||
help.beginWrap();
|
|
||||||
help.wrap(_S("Enables recursive file-matching for removing entire directories of working files.\n"));
|
|
||||||
help.endWrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
hecl::SystemString toolName() const {return _S("remove");}
|
|
||||||
|
|
||||||
int run()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CTOOL_REMOVE
|
|
@ -2,7 +2,7 @@
|
|||||||
#define CTOOL_SPEC
|
#define CTOOL_SPEC
|
||||||
|
|
||||||
#include "ToolBase.hpp"
|
#include "ToolBase.hpp"
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class ToolSpec final : public ToolBase
|
class ToolSpec final : public ToolBase
|
||||||
|
@ -7,15 +7,15 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <stdarg.h>
|
#include <cstdarg>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include "hecl/Database.hpp"
|
#include "hecl/Database.hpp"
|
||||||
#include "hecl/Blender/BlenderConnection.hpp"
|
#include "hecl/Blender/Connection.hpp"
|
||||||
#include "logvisor/logvisor.hpp"
|
#include "logvisor/logvisor.hpp"
|
||||||
|
|
||||||
logvisor::Module LogModule("hecl::Driver");
|
logvisor::Module LogModule("hecl::Driver");
|
||||||
@ -24,11 +24,7 @@ logvisor::Module LogModule("hecl::Driver");
|
|||||||
#include "ToolInit.hpp"
|
#include "ToolInit.hpp"
|
||||||
#include "ToolSpec.hpp"
|
#include "ToolSpec.hpp"
|
||||||
#include "ToolExtract.hpp"
|
#include "ToolExtract.hpp"
|
||||||
#include "ToolAdd.hpp"
|
|
||||||
#include "ToolRemove.hpp"
|
|
||||||
#include "ToolGroup.hpp"
|
|
||||||
#include "ToolCook.hpp"
|
#include "ToolCook.hpp"
|
||||||
#include "ToolClean.hpp"
|
|
||||||
#include "ToolPackage.hpp"
|
#include "ToolPackage.hpp"
|
||||||
#include "ToolHelp.hpp"
|
#include "ToolHelp.hpp"
|
||||||
|
|
||||||
@ -58,7 +54,7 @@ static void printHelp(const hecl::SystemChar* pname)
|
|||||||
#elif HECL_VER
|
#elif HECL_VER
|
||||||
hecl::Printf(_S(" Version " HECL_VER_S "\nUsage: %s extract|init|add|remove|group|cook|clean|package|help\n"), pname);
|
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|add|remove|group|cook|clean|package|help\n"), pname);
|
hecl::Printf(_S("\nUsage: %s extract|init|cook|package|help\n"), pname);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +64,7 @@ static const hecl::SystemRegex regOPEN(_S("-o([^\"]*|\\S*)"), std::regex::ECMASc
|
|||||||
/* SIGINT will gracefully close blender connections and delete blends in progress */
|
/* SIGINT will gracefully close blender connections and delete blends in progress */
|
||||||
static void SIGINTHandler(int sig)
|
static void SIGINTHandler(int sig)
|
||||||
{
|
{
|
||||||
hecl::BlenderConnection::Shutdown();
|
hecl::blender::Connection::Shutdown();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,16 +255,8 @@ int main(int argc, const char** argv)
|
|||||||
tool.reset(new ToolSpec(info));
|
tool.reset(new ToolSpec(info));
|
||||||
else if (toolName == _S("extract"))
|
else if (toolName == _S("extract"))
|
||||||
tool.reset(new ToolExtract(info));
|
tool.reset(new ToolExtract(info));
|
||||||
else if (toolName == _S("add"))
|
|
||||||
tool.reset(new ToolAdd(info));
|
|
||||||
else if (toolName == _S("remove") || toolName == _S("rm"))
|
|
||||||
tool.reset(new ToolRemove(info));
|
|
||||||
else if (toolName == _S("group"))
|
|
||||||
tool.reset(new ToolGroup(info));
|
|
||||||
else if (toolName == _S("cook"))
|
else if (toolName == _S("cook"))
|
||||||
tool.reset(new ToolCook(info));
|
tool.reset(new ToolCook(info));
|
||||||
else if (toolName == _S("clean"))
|
|
||||||
tool.reset(new ToolClean(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));
|
||||||
else if (toolName == _S("help"))
|
else if (toolName == _S("help"))
|
||||||
@ -304,14 +292,14 @@ int main(int argc, const char** argv)
|
|||||||
int retval = tool->run();
|
int retval = tool->run();
|
||||||
if (logvisor::ErrorCount > ErrorRef)
|
if (logvisor::ErrorCount > ErrorRef)
|
||||||
{
|
{
|
||||||
hecl::BlenderConnection::Shutdown();
|
hecl::blender::Connection::Shutdown();
|
||||||
#if WIN_PAUSE
|
#if WIN_PAUSE
|
||||||
system("PAUSE");
|
system("PAUSE");
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hecl::BlenderConnection::Shutdown();
|
hecl::blender::Connection::Shutdown();
|
||||||
#if WIN_PAUSE
|
#if WIN_PAUSE
|
||||||
system("PAUSE");
|
system("PAUSE");
|
||||||
#endif
|
#endif
|
||||||
|
2
hecl/extern/athena
vendored
2
hecl/extern/athena
vendored
@ -1 +1 @@
|
|||||||
Subproject commit cee9478773927a99ce40e625b9cc20bfdea32597
|
Subproject commit 017a921fdc0207590df519093fc06362ab04d457
|
2
hecl/extern/boo
vendored
2
hecl/extern/boo
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 867665cc782cf2f5a9ade477904c95692f4b1ae1
|
Subproject commit fa8989bed30bd5022c4951ae46adc4de50a261f1
|
4
hecl/extern/libpng/pngconf.h
vendored
4
hecl/extern/libpng/pngconf.h
vendored
@ -47,8 +47,12 @@
|
|||||||
|
|
||||||
#ifdef PNG_SETJMP_SUPPORTED
|
#ifdef PNG_SETJMP_SUPPORTED
|
||||||
/* Required for the definition of jmp_buf and the declaration of longjmp: */
|
/* Required for the definition of jmp_buf and the declaration of longjmp: */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
# include <csetjmp>
|
||||||
|
#else
|
||||||
# include <setjmp.h>
|
# include <setjmp.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PNG_CONVERT_tIME_SUPPORTED
|
#ifdef PNG_CONVERT_tIME_SUPPORTED
|
||||||
/* Required for struct tm: */
|
/* Required for struct tm: */
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
#include "hecl/Frontend.hpp"
|
#include "hecl/Frontend.hpp"
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Backend
|
||||||
{
|
|
||||||
namespace Backend
|
|
||||||
{
|
{
|
||||||
|
|
||||||
using IR = Frontend::IR;
|
using IR = Frontend::IR;
|
||||||
@ -76,7 +74,6 @@ public:
|
|||||||
virtual void reset(const IR& ir, Diagnostics& diag)=0;
|
virtual void reset(const IR& ir, Diagnostics& diag)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HECLBACKEND_HPP
|
#endif // HECLBACKEND_HPP
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
#include "ProgrammableCommon.hpp"
|
#include "ProgrammableCommon.hpp"
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Backend
|
||||||
{
|
|
||||||
namespace Backend
|
|
||||||
{
|
{
|
||||||
|
|
||||||
#define HECL_GLSL_VERT_UNIFORM_BLOCK_NAME "HECLVertUniform"
|
#define HECL_GLSL_VERT_UNIFORM_BLOCK_NAME "HECLVertUniform"
|
||||||
@ -46,7 +44,6 @@ private:
|
|||||||
std::string EmitTexGenSource4(TexGenSrc src, int uvIdx) const;
|
std::string EmitTexGenSource4(TexGenSrc src, int uvIdx) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HECLBACKEND_GLSL_HPP
|
#endif // HECLBACKEND_GLSL_HPP
|
||||||
|
@ -3,16 +3,14 @@
|
|||||||
|
|
||||||
#include "Backend.hpp"
|
#include "Backend.hpp"
|
||||||
#include <athena/DNA.hpp>
|
#include <athena/DNA.hpp>
|
||||||
#include <stdint.h>
|
#include <cstdint>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Backend
|
||||||
{
|
|
||||||
namespace Backend
|
|
||||||
{
|
{
|
||||||
|
|
||||||
struct GX : IBackend
|
struct GX : IBackend
|
||||||
@ -573,7 +571,6 @@ private:
|
|||||||
TexMtx mtx, bool normalize, PTTexMtx pmtx);
|
TexMtx mtx, bool normalize, PTTexMtx pmtx);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HECLBACKEND_GX_HPP
|
#endif // HECLBACKEND_GX_HPP
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
#include "ProgrammableCommon.hpp"
|
#include "ProgrammableCommon.hpp"
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Backend
|
||||||
{
|
|
||||||
namespace Backend
|
|
||||||
{
|
{
|
||||||
|
|
||||||
struct HLSL : ProgrammableCommon
|
struct HLSL : ProgrammableCommon
|
||||||
@ -42,7 +40,6 @@ private:
|
|||||||
std::string EmitTexGenSource4(TexGenSrc src, int uvIdx) const;
|
std::string EmitTexGenSource4(TexGenSrc src, int uvIdx) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HECLBACKEND_HLSL_HPP
|
#endif // HECLBACKEND_HLSL_HPP
|
||||||
|
@ -5,9 +5,7 @@
|
|||||||
|
|
||||||
#include "ProgrammableCommon.hpp"
|
#include "ProgrammableCommon.hpp"
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Backend
|
||||||
{
|
|
||||||
namespace Backend
|
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Metal : ProgrammableCommon
|
struct Metal : ProgrammableCommon
|
||||||
@ -46,7 +44,6 @@ private:
|
|||||||
std::string EmitTexGenSource4(TexGenSrc src, int uvIdx) const;
|
std::string EmitTexGenSource4(TexGenSrc src, int uvIdx) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BOO_HAS_METAL
|
#endif // BOO_HAS_METAL
|
||||||
|
@ -4,13 +4,11 @@
|
|||||||
#include "Backend.hpp"
|
#include "Backend.hpp"
|
||||||
#include "hecl/Runtime.hpp"
|
#include "hecl/Runtime.hpp"
|
||||||
#include <athena/DNA.hpp>
|
#include <athena/DNA.hpp>
|
||||||
#include <stdint.h>
|
#include <cstdint>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Backend
|
||||||
{
|
|
||||||
namespace Backend
|
|
||||||
{
|
{
|
||||||
|
|
||||||
struct ProgrammableCommon : IBackend
|
struct ProgrammableCommon : IBackend
|
||||||
@ -137,7 +135,6 @@ private:
|
|||||||
const std::string& a, const atInt8 swiz[4]) const;
|
const std::string& a, const atInt8 swiz[4]) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HECLBACKEND_PROGCOMMON_HPP
|
#endif // HECLBACKEND_PROGCOMMON_HPP
|
||||||
|
File diff suppressed because it is too large
Load Diff
706
hecl/include/hecl/Blender/Connection.hpp
Normal file
706
hecl/include/hecl/Blender/Connection.hpp
Normal file
@ -0,0 +1,706 @@
|
|||||||
|
#ifndef BLENDERCONNECTION_HPP
|
||||||
|
#define BLENDERCONNECTION_HPP
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN 1
|
||||||
|
#endif
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cfloat>
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
#include "hecl/hecl.hpp"
|
||||||
|
#include "hecl/HMDLMeta.hpp"
|
||||||
|
#include "athena/Types.hpp"
|
||||||
|
#include "athena/MemoryWriter.hpp"
|
||||||
|
#include "optional.hpp"
|
||||||
|
#include "Token.hpp"
|
||||||
|
|
||||||
|
namespace hecl::blender
|
||||||
|
{
|
||||||
|
|
||||||
|
extern logvisor::Module BlenderLog;
|
||||||
|
class HMDLBuffers;
|
||||||
|
class Connection;
|
||||||
|
|
||||||
|
struct PoolSkinIndex
|
||||||
|
{
|
||||||
|
size_t m_poolSz = 0;
|
||||||
|
std::unique_ptr<uint32_t[]> m_poolToSkinIndex;
|
||||||
|
|
||||||
|
void allocate(size_t poolSz)
|
||||||
|
{
|
||||||
|
m_poolSz = poolSz;
|
||||||
|
if (poolSz)
|
||||||
|
m_poolToSkinIndex.reset(new uint32_t[poolSz]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ANIMCurveType
|
||||||
|
{
|
||||||
|
Rotate,
|
||||||
|
Translate,
|
||||||
|
Scale
|
||||||
|
};
|
||||||
|
|
||||||
|
class ANIMOutStream
|
||||||
|
{
|
||||||
|
Connection* m_parent;
|
||||||
|
unsigned m_curCount = 0;
|
||||||
|
unsigned m_totalCount = 0;
|
||||||
|
bool m_inCurve = false;
|
||||||
|
public:
|
||||||
|
using CurveType = ANIMCurveType;
|
||||||
|
ANIMOutStream(Connection* parent);
|
||||||
|
~ANIMOutStream();
|
||||||
|
void changeCurve(CurveType type, unsigned crvIdx, unsigned keyCount);
|
||||||
|
void write(unsigned frame, float val);
|
||||||
|
};
|
||||||
|
|
||||||
|
class PyOutStream : public std::ostream
|
||||||
|
{
|
||||||
|
friend class Connection;
|
||||||
|
Connection* m_parent;
|
||||||
|
bool m_deleteOnError;
|
||||||
|
struct StreamBuf : std::streambuf
|
||||||
|
{
|
||||||
|
PyOutStream& m_parent;
|
||||||
|
std::string m_lineBuf;
|
||||||
|
bool m_deleteOnError;
|
||||||
|
StreamBuf(PyOutStream& parent, bool deleteOnError)
|
||||||
|
: m_parent(parent), m_deleteOnError(deleteOnError) {}
|
||||||
|
StreamBuf(const StreamBuf& other) = delete;
|
||||||
|
StreamBuf(StreamBuf&& other) = default;
|
||||||
|
int_type overflow(int_type ch);
|
||||||
|
} m_sbuf;
|
||||||
|
PyOutStream(Connection* parent, bool deleteOnError);
|
||||||
|
public:
|
||||||
|
PyOutStream(const PyOutStream& other) = delete;
|
||||||
|
PyOutStream(PyOutStream&& other)
|
||||||
|
: std::ostream(&m_sbuf), m_parent(other.m_parent), m_sbuf(std::move(other.m_sbuf))
|
||||||
|
{other.m_parent = nullptr;}
|
||||||
|
~PyOutStream() {close();}
|
||||||
|
void close();
|
||||||
|
#if __GNUC__
|
||||||
|
__attribute__((__format__ (__printf__, 2, 3)))
|
||||||
|
#endif
|
||||||
|
void format(const char* fmt, ...);
|
||||||
|
void linkBlend(const char* target, const char* objName, bool link=true);
|
||||||
|
void linkBackground(const char* target, const char* sceneName);
|
||||||
|
void AABBToBMesh(const atVec3f& min, const atVec3f& max);
|
||||||
|
void centerView();
|
||||||
|
|
||||||
|
ANIMOutStream beginANIMCurve()
|
||||||
|
{
|
||||||
|
return ANIMOutStream(m_parent);
|
||||||
|
}
|
||||||
|
Connection& getConnection() {return *m_parent;}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Vector types with integrated stream reading constructor */
|
||||||
|
struct Vector2f
|
||||||
|
{
|
||||||
|
atVec2f val;
|
||||||
|
Vector2f() = default;
|
||||||
|
void read(Connection& conn);
|
||||||
|
Vector2f(Connection& conn) {read(conn);}
|
||||||
|
operator const atVec2f&() const {return val;}
|
||||||
|
};
|
||||||
|
struct Vector3f
|
||||||
|
{
|
||||||
|
atVec3f val;
|
||||||
|
Vector3f() = default;
|
||||||
|
void read(Connection& conn);
|
||||||
|
Vector3f(Connection& conn) {read(conn);}
|
||||||
|
operator const atVec3f&() const {return val;}
|
||||||
|
};
|
||||||
|
struct Vector4f
|
||||||
|
{
|
||||||
|
atVec4f val;
|
||||||
|
Vector4f() = default;
|
||||||
|
void read(Connection& conn);
|
||||||
|
Vector4f(Connection& conn) {read(conn);}
|
||||||
|
operator const atVec4f&() const {return val;}
|
||||||
|
};
|
||||||
|
struct Matrix3f
|
||||||
|
{
|
||||||
|
atVec3f m[3];
|
||||||
|
inline atVec3f& operator[](size_t idx) {return m[idx];}
|
||||||
|
inline const atVec3f& operator[](size_t idx) const {return m[idx];}
|
||||||
|
};
|
||||||
|
struct Matrix4f
|
||||||
|
{
|
||||||
|
atVec4f val[4];
|
||||||
|
Matrix4f() = default;
|
||||||
|
void read(Connection& conn);
|
||||||
|
Matrix4f(Connection& conn) {read(conn);}
|
||||||
|
const atVec4f& operator[] (size_t idx) const {return val[idx];}
|
||||||
|
};
|
||||||
|
struct Index
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
Index() = default;
|
||||||
|
void read(Connection& conn);
|
||||||
|
Index(Connection& conn) {read(conn);}
|
||||||
|
operator const uint32_t&() const {return val;}
|
||||||
|
};
|
||||||
|
|
||||||
|
atVec3f MtxVecMul4RM(const Matrix4f& mtx, const Vector3f& vec);
|
||||||
|
atVec3f MtxVecMul3RM(const Matrix4f& mtx, const Vector3f& vec);
|
||||||
|
|
||||||
|
/** HECL source and metadata of each material */
|
||||||
|
struct Material
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::string source;
|
||||||
|
std::vector<ProjectPath> texs;
|
||||||
|
std::unordered_map<std::string, int32_t> iprops;
|
||||||
|
bool transparent;
|
||||||
|
|
||||||
|
Material(Connection& conn);
|
||||||
|
bool operator==(const Material& other) const
|
||||||
|
{
|
||||||
|
return source == other.source && texs == other.texs && iprops == other.iprops;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Intermediate mesh representation prepared by blender from a single mesh object */
|
||||||
|
struct Mesh
|
||||||
|
{
|
||||||
|
HMDLTopology topology;
|
||||||
|
|
||||||
|
/* Object transform in scene */
|
||||||
|
Matrix4f sceneXf;
|
||||||
|
|
||||||
|
/* Cumulative AABB */
|
||||||
|
Vector3f aabbMin;
|
||||||
|
Vector3f aabbMax;
|
||||||
|
|
||||||
|
std::vector<std::vector<Material>> materialSets;
|
||||||
|
|
||||||
|
/* Vertex buffer data */
|
||||||
|
std::vector<Vector3f> pos;
|
||||||
|
std::vector<Vector3f> norm;
|
||||||
|
uint32_t colorLayerCount = 0;
|
||||||
|
std::vector<Vector3f> color;
|
||||||
|
uint32_t uvLayerCount = 0;
|
||||||
|
std::vector<Vector2f> uv;
|
||||||
|
|
||||||
|
/* Skinning data */
|
||||||
|
std::vector<std::string> boneNames;
|
||||||
|
struct SkinBind
|
||||||
|
{
|
||||||
|
uint32_t boneIdx;
|
||||||
|
float weight;
|
||||||
|
SkinBind(Connection& conn);
|
||||||
|
};
|
||||||
|
std::vector<std::vector<SkinBind>> skins;
|
||||||
|
std::vector<size_t> contiguousSkinVertCounts;
|
||||||
|
|
||||||
|
void normalizeSkinBinds();
|
||||||
|
|
||||||
|
/** Islands of the same material/skinBank are represented here */
|
||||||
|
struct Surface
|
||||||
|
{
|
||||||
|
Vector3f centroid;
|
||||||
|
Index materialIdx;
|
||||||
|
Vector3f aabbMin;
|
||||||
|
Vector3f aabbMax;
|
||||||
|
Vector3f reflectionNormal;
|
||||||
|
uint32_t skinBankIdx;
|
||||||
|
|
||||||
|
/** Vertex indexing data (all primitives joined as degenerate tri-strip) */
|
||||||
|
struct Vert
|
||||||
|
{
|
||||||
|
uint32_t iPos;
|
||||||
|
uint32_t iNorm;
|
||||||
|
uint32_t iColor[4] = {uint32_t(-1)};
|
||||||
|
uint32_t iUv[8] = {uint32_t(-1)};
|
||||||
|
uint32_t iSkin;
|
||||||
|
uint32_t iBankSkin = -1;
|
||||||
|
|
||||||
|
Vert(Connection& conn, const Mesh& parent);
|
||||||
|
bool operator==(const Vert& other) const;
|
||||||
|
};
|
||||||
|
std::vector<Vert> verts;
|
||||||
|
|
||||||
|
Surface(Connection& conn, Mesh& parent, int skinSlotCount);
|
||||||
|
};
|
||||||
|
std::vector<Surface> surfaces;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::string> customProps;
|
||||||
|
|
||||||
|
struct SkinBanks
|
||||||
|
{
|
||||||
|
struct Bank
|
||||||
|
{
|
||||||
|
std::vector<uint32_t> m_skinIdxs;
|
||||||
|
std::vector<uint32_t> m_boneIdxs;
|
||||||
|
|
||||||
|
void addSkins(const Mesh& parent, const std::vector<uint32_t>& skinIdxs);
|
||||||
|
size_t lookupLocalBoneIdx(uint32_t boneIdx) const;
|
||||||
|
};
|
||||||
|
std::vector<Bank> banks;
|
||||||
|
std::vector<Bank>::iterator addSkinBank(int skinSlotCount);
|
||||||
|
uint32_t addSurface(const Mesh& mesh, const Surface& surf, int skinSlotCount);
|
||||||
|
} skinBanks;
|
||||||
|
|
||||||
|
using SurfProgFunc = std::function<void(int)>;
|
||||||
|
Mesh(Connection& conn, HMDLTopology topology, int skinSlotCount, SurfProgFunc& surfProg);
|
||||||
|
|
||||||
|
Mesh getContiguousSkinningVersion() const;
|
||||||
|
|
||||||
|
/** Prepares mesh representation for indexed access on modern APIs.
|
||||||
|
* Mesh must remain resident for accessing reference members
|
||||||
|
*/
|
||||||
|
HMDLBuffers getHMDLBuffers(bool absoluteCoords, PoolSkinIndex& poolSkinIndex) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Intermediate collision mesh representation prepared by blender from a single mesh object */
|
||||||
|
struct ColMesh
|
||||||
|
{
|
||||||
|
/** HECL source and metadata of each material */
|
||||||
|
struct Material
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
bool unknown;
|
||||||
|
bool surfaceStone;
|
||||||
|
bool surfaceMetal;
|
||||||
|
bool surfaceGrass;
|
||||||
|
bool surfaceIce;
|
||||||
|
bool pillar;
|
||||||
|
bool surfaceMetalGrating;
|
||||||
|
bool surfacePhazon;
|
||||||
|
bool surfaceDirt;
|
||||||
|
bool surfaceLava;
|
||||||
|
bool surfaceSPMetal;
|
||||||
|
bool surfaceStoneRock;
|
||||||
|
bool surfaceSnow;
|
||||||
|
bool surfaceMudSlow;
|
||||||
|
bool surfaceFabric;
|
||||||
|
bool halfPipe;
|
||||||
|
bool surfaceMud;
|
||||||
|
bool surfaceGlass;
|
||||||
|
bool unused3;
|
||||||
|
bool unused4;
|
||||||
|
bool surfaceShield;
|
||||||
|
bool surfaceSand;
|
||||||
|
bool surfaceMothOrSeedOrganics;
|
||||||
|
bool surfaceWeb;
|
||||||
|
bool projPassthrough;
|
||||||
|
bool solid;
|
||||||
|
bool u20;
|
||||||
|
bool camPassthrough;
|
||||||
|
bool surfaceWood;
|
||||||
|
bool surfaceOrganic;
|
||||||
|
bool u24;
|
||||||
|
bool surfaceRubber;
|
||||||
|
bool seeThrough;
|
||||||
|
bool scanPassthrough;
|
||||||
|
bool aiPassthrough;
|
||||||
|
bool ceiling;
|
||||||
|
bool wall;
|
||||||
|
bool floor;
|
||||||
|
bool aiBlock;
|
||||||
|
bool jumpNotAllowed;
|
||||||
|
bool spiderBall;
|
||||||
|
bool screwAttackWallJump;
|
||||||
|
|
||||||
|
Material(Connection& conn);
|
||||||
|
};
|
||||||
|
std::vector<Material> materials;
|
||||||
|
|
||||||
|
std::vector<Vector3f> verts;
|
||||||
|
|
||||||
|
struct Edge
|
||||||
|
{
|
||||||
|
uint32_t verts[2];
|
||||||
|
bool seam;
|
||||||
|
Edge(Connection& conn);
|
||||||
|
};
|
||||||
|
std::vector<Edge> edges;
|
||||||
|
|
||||||
|
struct Triangle
|
||||||
|
{
|
||||||
|
uint32_t edges[3];
|
||||||
|
uint32_t matIdx;
|
||||||
|
bool flip;
|
||||||
|
Triangle(Connection& conn);
|
||||||
|
};
|
||||||
|
std::vector<Triangle> trianges;
|
||||||
|
|
||||||
|
ColMesh(Connection& conn);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Intermediate world representation */
|
||||||
|
struct World
|
||||||
|
{
|
||||||
|
struct Area
|
||||||
|
{
|
||||||
|
ProjectPath path;
|
||||||
|
Vector3f aabb[2];
|
||||||
|
Matrix4f transform;
|
||||||
|
struct Dock
|
||||||
|
{
|
||||||
|
Vector3f verts[4];
|
||||||
|
Index targetArea;
|
||||||
|
Index targetDock;
|
||||||
|
Dock(Connection& conn);
|
||||||
|
};
|
||||||
|
std::vector<Dock> docks;
|
||||||
|
Area(Connection& conn);
|
||||||
|
};
|
||||||
|
std::vector<Area> areas;
|
||||||
|
World(Connection& conn);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Intermediate lamp representation */
|
||||||
|
struct Light
|
||||||
|
{
|
||||||
|
/* Object transform in scene */
|
||||||
|
Matrix4f sceneXf;
|
||||||
|
Vector3f color;
|
||||||
|
|
||||||
|
uint32_t layer;
|
||||||
|
|
||||||
|
enum class Type : uint32_t
|
||||||
|
{
|
||||||
|
Ambient,
|
||||||
|
Directional,
|
||||||
|
Custom,
|
||||||
|
Spot
|
||||||
|
} type;
|
||||||
|
|
||||||
|
float energy;
|
||||||
|
float spotCutoff;
|
||||||
|
float constant;
|
||||||
|
float linear;
|
||||||
|
float quadratic;
|
||||||
|
bool shadow;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
Light(Connection& conn);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Intermediate MapArea representation */
|
||||||
|
struct MapArea
|
||||||
|
{
|
||||||
|
Index visType;
|
||||||
|
std::vector<Vector3f> verts;
|
||||||
|
std::vector<Index> indices;
|
||||||
|
struct Surface
|
||||||
|
{
|
||||||
|
Vector3f normal;
|
||||||
|
Vector3f centerOfMass;
|
||||||
|
Index start;
|
||||||
|
Index count;
|
||||||
|
std::vector<std::pair<Index, Index>> borders;
|
||||||
|
Surface(Connection& conn);
|
||||||
|
};
|
||||||
|
std::vector<Surface> surfaces;
|
||||||
|
struct POI
|
||||||
|
{
|
||||||
|
uint32_t type;
|
||||||
|
uint32_t visMode;
|
||||||
|
uint32_t objid;
|
||||||
|
Matrix4f xf;
|
||||||
|
POI(Connection& conn);
|
||||||
|
};
|
||||||
|
std::vector<POI> pois;
|
||||||
|
MapArea(Connection& conn);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Intermediate MapUniverse representation */
|
||||||
|
struct MapUniverse
|
||||||
|
{
|
||||||
|
hecl::ProjectPath hexagonPath;
|
||||||
|
struct World
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
Matrix4f xf;
|
||||||
|
std::vector<Matrix4f> hexagons;
|
||||||
|
Vector4f color;
|
||||||
|
hecl::ProjectPath worldPath;
|
||||||
|
World(Connection& conn);
|
||||||
|
};
|
||||||
|
std::vector<World> worlds;
|
||||||
|
MapUniverse(Connection& conn);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Intermediate bone representation used in Armature */
|
||||||
|
struct Bone
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
Vector3f origin;
|
||||||
|
int32_t parent = -1;
|
||||||
|
std::vector<int32_t> children;
|
||||||
|
Bone(Connection& conn);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Intermediate armature representation used in Actor */
|
||||||
|
struct Armature
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::vector<Bone> bones;
|
||||||
|
const Bone* lookupBone(const char* name) const;
|
||||||
|
const Bone* getParent(const Bone* bone) const;
|
||||||
|
const Bone* getChild(const Bone* bone, size_t child) const;
|
||||||
|
const Bone* getRoot() const;
|
||||||
|
Armature(Connection& conn);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Intermediate action representation used in Actor */
|
||||||
|
struct Action
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
float interval;
|
||||||
|
bool additive;
|
||||||
|
bool looping;
|
||||||
|
std::vector<int32_t> frames;
|
||||||
|
struct Channel
|
||||||
|
{
|
||||||
|
std::string boneName;
|
||||||
|
uint32_t attrMask;
|
||||||
|
struct Key
|
||||||
|
{
|
||||||
|
Vector4f rotation;
|
||||||
|
Vector3f position;
|
||||||
|
Vector3f scale;
|
||||||
|
Key(Connection& conn, uint32_t attrMask);
|
||||||
|
};
|
||||||
|
std::vector<Key> keys;
|
||||||
|
Channel(Connection& conn);
|
||||||
|
};
|
||||||
|
std::vector<Channel> channels;
|
||||||
|
std::vector<std::pair<Vector3f, Vector3f>> subtypeAABBs;
|
||||||
|
Action(Connection& conn);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Intermediate actor representation prepared by blender from a single HECL actor blend */
|
||||||
|
struct Actor
|
||||||
|
{
|
||||||
|
std::vector<Armature> armatures;
|
||||||
|
|
||||||
|
struct Subtype
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
ProjectPath mesh;
|
||||||
|
int32_t armature = -1;
|
||||||
|
std::vector<std::pair<std::string, ProjectPath>> overlayMeshes;
|
||||||
|
Subtype(Connection& conn);
|
||||||
|
};
|
||||||
|
std::vector<Subtype> subtypes;
|
||||||
|
std::vector<Action> actions;
|
||||||
|
|
||||||
|
Actor(Connection& conn);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DataStream
|
||||||
|
{
|
||||||
|
friend class Connection;
|
||||||
|
Connection* m_parent;
|
||||||
|
DataStream(Connection* parent);
|
||||||
|
public:
|
||||||
|
DataStream(const DataStream& other) = delete;
|
||||||
|
DataStream(DataStream&& other)
|
||||||
|
: m_parent(other.m_parent) {other.m_parent = nullptr;}
|
||||||
|
~DataStream() {close();}
|
||||||
|
void close();
|
||||||
|
std::vector<std::string> getMeshList();
|
||||||
|
std::vector<std::string> getLightList();
|
||||||
|
std::pair<atVec3f, atVec3f> getMeshAABB();
|
||||||
|
static const char* MeshOutputModeString(HMDLTopology topology);
|
||||||
|
|
||||||
|
/** Compile mesh by context (MESH blends only) */
|
||||||
|
Mesh compileMesh(HMDLTopology topology, int skinSlotCount=10,
|
||||||
|
Mesh::SurfProgFunc surfProg=[](int){});
|
||||||
|
|
||||||
|
/** Compile mesh by name (AREA blends only) */
|
||||||
|
Mesh compileMesh(std::string_view name, HMDLTopology topology, int skinSlotCount=10,
|
||||||
|
Mesh::SurfProgFunc surfProg=[](int){});
|
||||||
|
|
||||||
|
/** Compile collision mesh by name (AREA blends only) */
|
||||||
|
ColMesh compileColMesh(std::string_view name);
|
||||||
|
|
||||||
|
/** Compile all meshes as collision meshes (CMESH blends only) */
|
||||||
|
std::vector<ColMesh> compileColMeshes();
|
||||||
|
|
||||||
|
/** Compile all meshes into one (AREA blends only) */
|
||||||
|
Mesh compileAllMeshes(HMDLTopology topology, int skinSlotCount=10, float maxOctantLength=5.0,
|
||||||
|
Mesh::SurfProgFunc surfProg=[](int){});
|
||||||
|
|
||||||
|
/** Compile world intermediate (WORLD blends only) */
|
||||||
|
World compileWorld();
|
||||||
|
|
||||||
|
/** Gather all lights in scene (AREA blends only) */
|
||||||
|
std::vector<Light> compileLights();
|
||||||
|
|
||||||
|
/** Compile GUI into FRME data (FRAME blends only) */
|
||||||
|
void compileGuiFrame(std::string_view pathOut, int version);
|
||||||
|
|
||||||
|
/** Gather all texture paths in scene */
|
||||||
|
std::vector<ProjectPath> getTextures();
|
||||||
|
|
||||||
|
Actor compileActor();
|
||||||
|
Actor compileActorCharacterOnly();
|
||||||
|
Action compileActionChannelsOnly(std::string_view name);
|
||||||
|
std::vector<std::string> getArmatureNames();
|
||||||
|
std::vector<std::string> getSubtypeNames();
|
||||||
|
std::vector<std::string> getActionNames();
|
||||||
|
std::vector<std::string> getSubtypeOverlayNames(std::string_view name);
|
||||||
|
|
||||||
|
std::unordered_map<std::string, Matrix3f> getBoneMatrices(std::string_view name);
|
||||||
|
|
||||||
|
bool renderPvs(std::string_view path, const atVec3f& location);
|
||||||
|
bool renderPvsLight(std::string_view path, std::string_view lightName);
|
||||||
|
|
||||||
|
MapArea compileMapArea();
|
||||||
|
MapUniverse compileMapUniverse();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Connection
|
||||||
|
{
|
||||||
|
friend class DataStream;
|
||||||
|
friend class PyOutStream;
|
||||||
|
friend class ANIMOutStream;
|
||||||
|
friend struct PyOutStream::StreamBuf;
|
||||||
|
friend struct Mesh;
|
||||||
|
friend struct Material;
|
||||||
|
friend struct ColMesh;
|
||||||
|
friend struct World;
|
||||||
|
friend struct Light;
|
||||||
|
friend struct MapArea;
|
||||||
|
friend struct MapUniverse;
|
||||||
|
friend struct Actor;
|
||||||
|
friend struct Armature;
|
||||||
|
friend struct Action;
|
||||||
|
friend struct Bone;
|
||||||
|
friend struct Vector2f;
|
||||||
|
friend struct Vector3f;
|
||||||
|
friend struct Vector4f;
|
||||||
|
friend struct Matrix3f;
|
||||||
|
friend struct Matrix4f;
|
||||||
|
friend struct Index;
|
||||||
|
|
||||||
|
std::atomic_bool m_lock = {false};
|
||||||
|
bool m_pyStreamActive = false;
|
||||||
|
bool m_dataStreamActive = false;
|
||||||
|
#if _WIN32
|
||||||
|
PROCESS_INFORMATION m_pinfo = {};
|
||||||
|
std::thread m_consoleThread;
|
||||||
|
bool m_consoleThreadRunning = true;
|
||||||
|
#else
|
||||||
|
pid_t m_blenderProc = 0;
|
||||||
|
#endif
|
||||||
|
int m_readpipe[2];
|
||||||
|
int m_writepipe[2];
|
||||||
|
bool m_hasSlerp;
|
||||||
|
BlendType m_loadedType = BlendType::None;
|
||||||
|
bool m_loadedRigged = false;
|
||||||
|
ProjectPath m_loadedBlend;
|
||||||
|
std::string m_startupBlend;
|
||||||
|
hecl::SystemString m_errPath;
|
||||||
|
uint32_t _readStr(char* buf, uint32_t bufSz);
|
||||||
|
uint32_t _writeStr(const char* str, uint32_t len, int wpipe);
|
||||||
|
uint32_t _writeStr(const char* str, uint32_t len) { return _writeStr(str, len, m_writepipe[1]); }
|
||||||
|
uint32_t _writeStr(const char* str) { return _writeStr(str, strlen(str)); }
|
||||||
|
size_t _readBuf(void* buf, size_t len);
|
||||||
|
size_t _writeBuf(const void* buf, size_t len);
|
||||||
|
void _closePipe();
|
||||||
|
void _blenderDied();
|
||||||
|
|
||||||
|
public:
|
||||||
|
Connection(int verbosityLevel=1);
|
||||||
|
~Connection();
|
||||||
|
|
||||||
|
Connection(const Connection&)=delete;
|
||||||
|
Connection& operator=(const Connection&)=delete;
|
||||||
|
Connection(Connection&&)=delete;
|
||||||
|
Connection& operator=(Connection&&)=delete;
|
||||||
|
|
||||||
|
bool hasSLERP() const {return m_hasSlerp;}
|
||||||
|
|
||||||
|
bool createBlend(const ProjectPath& path, BlendType type);
|
||||||
|
BlendType getBlendType() const {return m_loadedType;}
|
||||||
|
const ProjectPath& getBlendPath() const {return m_loadedBlend;}
|
||||||
|
bool getRigged() const {return m_loadedRigged;}
|
||||||
|
bool openBlend(const ProjectPath& path, bool force=false);
|
||||||
|
bool saveBlend();
|
||||||
|
void deleteBlend();
|
||||||
|
|
||||||
|
PyOutStream beginPythonOut(bool deleteOnError=false)
|
||||||
|
{
|
||||||
|
bool expect = false;
|
||||||
|
if (!m_lock.compare_exchange_strong(expect, true))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "lock already held for blender::Connection::beginPythonOut()");
|
||||||
|
return PyOutStream(this, deleteOnError);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataStream beginData()
|
||||||
|
{
|
||||||
|
bool expect = false;
|
||||||
|
if (!m_lock.compare_exchange_strong(expect, true))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "lock already held for blender::Connection::beginDataIn()");
|
||||||
|
return DataStream(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void quitBlender();
|
||||||
|
|
||||||
|
void closeStream()
|
||||||
|
{
|
||||||
|
if (m_lock)
|
||||||
|
deleteBlend();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Connection& SharedConnection();
|
||||||
|
static void Shutdown();
|
||||||
|
};
|
||||||
|
|
||||||
|
class HMDLBuffers
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Surface;
|
||||||
|
private:
|
||||||
|
friend struct Mesh;
|
||||||
|
HMDLBuffers(HMDLMeta&& meta,
|
||||||
|
size_t vboSz, const std::vector<atUint32>& iboData,
|
||||||
|
std::vector<Surface>&& surfaces,
|
||||||
|
const Mesh::SkinBanks& skinBanks);
|
||||||
|
public:
|
||||||
|
HMDLMeta m_meta;
|
||||||
|
size_t m_vboSz;
|
||||||
|
std::unique_ptr<uint8_t[]> m_vboData;
|
||||||
|
size_t m_iboSz;
|
||||||
|
std::unique_ptr<uint8_t[]> m_iboData;
|
||||||
|
|
||||||
|
struct Surface
|
||||||
|
{
|
||||||
|
Surface(const Mesh::Surface& origSurf,
|
||||||
|
atUint32 start, atUint32 count)
|
||||||
|
: m_origSurf(origSurf), m_start(start), m_count(count) {}
|
||||||
|
const Mesh::Surface& m_origSurf;
|
||||||
|
atUint32 m_start;
|
||||||
|
atUint32 m_count;
|
||||||
|
};
|
||||||
|
std::vector<Surface> m_surfaces;
|
||||||
|
|
||||||
|
const Mesh::SkinBanks& m_skinBanks;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BLENDERCONNECTION_HPP
|
27
hecl/include/hecl/Blender/Token.hpp
Normal file
27
hecl/include/hecl/Blender/Token.hpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef HECL_BLENDERTOKEN_HPP
|
||||||
|
#define HECL_BLENDERTOKEN_HPP
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace hecl::blender
|
||||||
|
{
|
||||||
|
class Connection;
|
||||||
|
|
||||||
|
class Token
|
||||||
|
{
|
||||||
|
std::unique_ptr<Connection> m_conn;
|
||||||
|
public:
|
||||||
|
Connection& getBlenderConnection();
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
Token() = default;
|
||||||
|
~Token();
|
||||||
|
Token(const Token&)=delete;
|
||||||
|
Token& operator=(const Token&)=delete;
|
||||||
|
Token(Token&&)=default;
|
||||||
|
Token& operator=(Token&&)=default;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HECL_BLENDERTOKEN_HPP
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include "hecl.hpp"
|
#include "hecl.hpp"
|
||||||
#include "Database.hpp"
|
#include "Database.hpp"
|
||||||
#include "hecl/Blender/BlenderConnection.hpp"
|
|
||||||
#include "boo/ThreadLocalPtr.hpp"
|
#include "boo/ThreadLocalPtr.hpp"
|
||||||
|
#include "hecl/Blender/Token.hpp"
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
@ -34,7 +34,7 @@ public:
|
|||||||
Lambda
|
Lambda
|
||||||
} m_type;
|
} m_type;
|
||||||
bool m_complete = false;
|
bool m_complete = false;
|
||||||
virtual void run(BlenderToken& btok)=0;
|
virtual void run(blender::Token& btok)=0;
|
||||||
Transaction(ClientProcess& parent, Type tp) : m_parent(parent), m_type(tp) {}
|
Transaction(ClientProcess& parent, Type tp) : m_parent(parent), m_type(tp) {}
|
||||||
};
|
};
|
||||||
struct BufferTransaction : Transaction
|
struct BufferTransaction : Transaction
|
||||||
@ -43,7 +43,7 @@ public:
|
|||||||
void* m_targetBuf;
|
void* m_targetBuf;
|
||||||
size_t m_maxLen;
|
size_t m_maxLen;
|
||||||
size_t m_offset;
|
size_t m_offset;
|
||||||
void run(BlenderToken& btok);
|
void run(blender::Token& btok);
|
||||||
BufferTransaction(ClientProcess& parent, const ProjectPath& path,
|
BufferTransaction(ClientProcess& parent, const ProjectPath& path,
|
||||||
void* target, size_t maxLen, size_t offset)
|
void* target, size_t maxLen, size_t offset)
|
||||||
: Transaction(parent, Type::Buffer),
|
: Transaction(parent, Type::Buffer),
|
||||||
@ -55,15 +55,15 @@ public:
|
|||||||
ProjectPath m_path;
|
ProjectPath m_path;
|
||||||
Database::IDataSpec* m_dataSpec;
|
Database::IDataSpec* m_dataSpec;
|
||||||
bool m_returnResult = false;
|
bool m_returnResult = false;
|
||||||
void run(BlenderToken& btok);
|
void run(blender::Token& btok);
|
||||||
CookTransaction(ClientProcess& parent, const ProjectPath& path, Database::IDataSpec* spec)
|
CookTransaction(ClientProcess& parent, const ProjectPath& path, Database::IDataSpec* spec)
|
||||||
: Transaction(parent, Type::Cook), m_path(path), m_dataSpec(spec) {}
|
: Transaction(parent, Type::Cook), m_path(path), m_dataSpec(spec) {}
|
||||||
};
|
};
|
||||||
struct LambdaTransaction : Transaction
|
struct LambdaTransaction : Transaction
|
||||||
{
|
{
|
||||||
std::function<void(BlenderToken&)> m_func;
|
std::function<void(blender::Token&)> m_func;
|
||||||
void run(BlenderToken& btok);
|
void run(blender::Token& btok);
|
||||||
LambdaTransaction(ClientProcess& parent, std::function<void(BlenderToken&)>&& func)
|
LambdaTransaction(ClientProcess& parent, std::function<void(blender::Token&)>&& func)
|
||||||
: Transaction(parent, Type::Lambda), m_func(std::move(func)) {}
|
: Transaction(parent, Type::Lambda), m_func(std::move(func)) {}
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
@ -77,7 +77,7 @@ private:
|
|||||||
ClientProcess& m_proc;
|
ClientProcess& m_proc;
|
||||||
int m_idx;
|
int m_idx;
|
||||||
std::thread m_thr;
|
std::thread m_thr;
|
||||||
BlenderToken m_blendTok;
|
blender::Token m_blendTok;
|
||||||
bool m_didInit = false;
|
bool m_didInit = false;
|
||||||
Worker(ClientProcess& proc, int idx);
|
Worker(ClientProcess& proc, int idx);
|
||||||
void proc();
|
void proc();
|
||||||
@ -94,8 +94,8 @@ public:
|
|||||||
std::shared_ptr<const CookTransaction>
|
std::shared_ptr<const CookTransaction>
|
||||||
addCookTransaction(const hecl::ProjectPath& path, Database::IDataSpec* spec);
|
addCookTransaction(const hecl::ProjectPath& path, Database::IDataSpec* spec);
|
||||||
std::shared_ptr<const LambdaTransaction>
|
std::shared_ptr<const LambdaTransaction>
|
||||||
addLambdaTransaction(std::function<void(BlenderToken&)>&& func);
|
addLambdaTransaction(std::function<void(blender::Token&)>&& func);
|
||||||
bool syncCook(const hecl::ProjectPath& path, Database::IDataSpec* spec, BlenderToken& btok);
|
bool syncCook(const hecl::ProjectPath& path, Database::IDataSpec* spec, blender::Token& btok);
|
||||||
void swapCompletedQueue(std::list<std::shared_ptr<Transaction>>& queue);
|
void swapCompletedQueue(std::list<std::shared_ptr<Transaction>>& queue);
|
||||||
void waitUntilComplete();
|
void waitUntilComplete();
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
@ -13,16 +13,15 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
|
|
||||||
#include <athena/IStreamReader.hpp>
|
#include "athena/IStreamReader.hpp"
|
||||||
#include "logvisor/logvisor.hpp"
|
#include "logvisor/logvisor.hpp"
|
||||||
|
|
||||||
#include "hecl.hpp"
|
#include "hecl.hpp"
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl
|
||||||
{
|
{
|
||||||
class BlenderToken;
|
|
||||||
class ClientProcess;
|
class ClientProcess;
|
||||||
|
|
||||||
namespace Database
|
namespace Database
|
||||||
@ -71,7 +70,7 @@ class IDataSpec
|
|||||||
public:
|
public:
|
||||||
IDataSpec(const DataSpecEntry* specEntry) : m_specEntry(specEntry) {}
|
IDataSpec(const DataSpecEntry* specEntry) : m_specEntry(specEntry) {}
|
||||||
virtual ~IDataSpec() {}
|
virtual ~IDataSpec() {}
|
||||||
using FProgress = hecl::Database::FProgress;
|
using FProgress = Database::FProgress;
|
||||||
using FCookProgress = std::function<void(const SystemChar*)>;
|
using FCookProgress = std::function<void(const SystemChar*)>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,20 +106,20 @@ public:
|
|||||||
virtual void doExtract(const ExtractPassInfo& info, FProgress progress)
|
virtual void doExtract(const ExtractPassInfo& info, FProgress progress)
|
||||||
{(void)info;(void)progress;}
|
{(void)info;(void)progress;}
|
||||||
|
|
||||||
virtual bool canCook(const ProjectPath& path, BlenderToken& btok)
|
virtual bool canCook(const ProjectPath& path, blender::Token& btok)
|
||||||
{(void)path;LogModule.report(logvisor::Error, "not implemented");return false;}
|
{(void)path;LogModule.report(logvisor::Error, "not implemented");return false;}
|
||||||
virtual const DataSpecEntry* overrideDataSpec(const ProjectPath& path,
|
virtual const DataSpecEntry* overrideDataSpec(const ProjectPath& path,
|
||||||
const Database::DataSpecEntry* oldEntry,
|
const Database::DataSpecEntry* oldEntry,
|
||||||
BlenderToken& btok) const
|
blender::Token& btok) const
|
||||||
{(void)path;return oldEntry;}
|
{(void)path;return oldEntry;}
|
||||||
virtual void doCook(const ProjectPath& path, const ProjectPath& cookedPath,
|
virtual void doCook(const ProjectPath& path, const ProjectPath& cookedPath,
|
||||||
bool fast, BlenderToken& btok, FCookProgress progress)
|
bool fast, blender::Token& btok, FCookProgress progress)
|
||||||
{(void)path;(void)cookedPath;(void)fast;(void)progress;}
|
{(void)path;(void)cookedPath;(void)fast;(void)progress;}
|
||||||
|
|
||||||
virtual bool canPackage(const hecl::ProjectPath& path)
|
virtual bool canPackage(const ProjectPath& path)
|
||||||
{(void)path;return false;}
|
{(void)path;return false;}
|
||||||
virtual void doPackage(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* entry,
|
virtual void doPackage(const ProjectPath& path, const Database::DataSpecEntry* entry,
|
||||||
bool fast, hecl::BlenderToken& btok, FProgress progress, ClientProcess* cp=nullptr)
|
bool fast, blender::Token& btok, FProgress progress, ClientProcess* cp=nullptr)
|
||||||
{(void)path;}
|
{(void)path;}
|
||||||
|
|
||||||
const DataSpecEntry* getDataSpecEntry() const {return m_specEntry;}
|
const DataSpecEntry* getDataSpecEntry() const {return m_specEntry;}
|
||||||
@ -263,7 +262,7 @@ private:
|
|||||||
std::unique_ptr<IDataSpec> m_lastPackageSpec;
|
std::unique_ptr<IDataSpec> m_lastPackageSpec;
|
||||||
bool m_valid = false;
|
bool m_valid = false;
|
||||||
public:
|
public:
|
||||||
Project(const hecl::ProjectRootPath& rootPath);
|
Project(const ProjectRootPath& rootPath);
|
||||||
operator bool() const {return m_valid;}
|
operator bool() const {return m_valid;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
62
hecl/include/hecl/FourCC.hpp
Normal file
62
hecl/include/hecl/FourCC.hpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#ifndef HECL_FOURCC_HPP
|
||||||
|
#define HECL_FOURCC_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace hecl
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FourCC representation used within HECL's database
|
||||||
|
*
|
||||||
|
* FourCCs are efficient, mnemonic four-char-sequences used to represent types
|
||||||
|
* while fitting comfortably in a 32-bit word. HECL uses a four-char array
|
||||||
|
* to remain endian-independent.
|
||||||
|
*/
|
||||||
|
class FourCC
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
union
|
||||||
|
{
|
||||||
|
char fcc[4];
|
||||||
|
uint32_t num;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
FourCC() /* Sentinel FourCC */
|
||||||
|
: num(0) {}
|
||||||
|
FourCC(const FourCC& other)
|
||||||
|
{num = other.num;}
|
||||||
|
FourCC(const char* name)
|
||||||
|
: num(*(uint32_t*)name) {}
|
||||||
|
FourCC(uint32_t n)
|
||||||
|
: num(n) {}
|
||||||
|
bool operator==(const FourCC& other) const {return num == other.num;}
|
||||||
|
bool operator!=(const FourCC& other) const {return num != other.num;}
|
||||||
|
bool operator==(const char* other) const {return num == *(uint32_t*)other;}
|
||||||
|
bool operator!=(const char* other) const {return num != *(uint32_t*)other;}
|
||||||
|
bool operator==(int32_t other) const { return num == other;}
|
||||||
|
bool operator!=(int32_t other) const { return num != other;}
|
||||||
|
bool operator==(uint32_t other) const {return num == other;}
|
||||||
|
bool operator!=(uint32_t other) const {return num != other;}
|
||||||
|
std::string toString() const {return std::string(fcc, 4);}
|
||||||
|
uint32_t toUint32() const {return num;}
|
||||||
|
operator uint32_t() const {return num;}
|
||||||
|
const char* getChars() const {return fcc;}
|
||||||
|
char* getChars() {return fcc;}
|
||||||
|
};
|
||||||
|
#define FOURCC(chars) FourCC(SBIG(chars))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template <> struct hash<hecl::FourCC>
|
||||||
|
{
|
||||||
|
size_t operator()(const hecl::FourCC& val) const noexcept
|
||||||
|
{return val.toUint32();}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HECL_FOURCC_HPP
|
@ -1,8 +1,8 @@
|
|||||||
#ifndef HMDLMETA_HPP
|
#ifndef HMDLMETA_HPP
|
||||||
#define HMDLMETA_HPP
|
#define HMDLMETA_HPP
|
||||||
|
|
||||||
#include <hecl/hecl.hpp>
|
#include "hecl/hecl.hpp"
|
||||||
#include <athena/DNA.hpp>
|
#include "athena/DNA.hpp"
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl
|
||||||
{
|
{
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
#include "hecl.hpp"
|
#include "hecl.hpp"
|
||||||
#include "Frontend.hpp"
|
#include "Frontend.hpp"
|
||||||
#include "Backend/Backend.hpp"
|
#include "Backend/Backend.hpp"
|
||||||
#include <boo/graphicsdev/IGraphicsDataFactory.hpp>
|
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||||
#include <athena/DNA.hpp>
|
#include "athena/DNA.hpp"
|
||||||
#include <athena/FileReader.hpp>
|
#include "athena/FileReader.hpp"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl
|
||||||
@ -323,7 +323,7 @@ namespace std
|
|||||||
{
|
{
|
||||||
template <> struct hash<hecl::Runtime::ShaderTag>
|
template <> struct hash<hecl::Runtime::ShaderTag>
|
||||||
{
|
{
|
||||||
size_t operator()(const hecl::Runtime::ShaderTag& val) const NOEXCEPT
|
size_t operator()(const hecl::Runtime::ShaderTag& val) const noexcept
|
||||||
{return val.valSizeT();}
|
{return val.valSizeT();}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define SYSTEMCHAR_HPP
|
#define SYSTEMCHAR_HPP
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#else
|
#else
|
||||||
@ -12,7 +12,7 @@
|
|||||||
#ifndef NOMINMAX
|
#ifndef NOMINMAX
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#endif
|
#endif
|
||||||
#include <wchar.h>
|
#include <cwchar>
|
||||||
#endif
|
#endif
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define HECL_HPP
|
#define HECL_HPP
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
@ -18,15 +18,15 @@
|
|||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#endif
|
#endif
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <wchar.h>
|
#include <cwchar>
|
||||||
#include <Shlwapi.h>
|
#include <Shlwapi.h>
|
||||||
#include "winsupport.hpp"
|
#include "winsupport.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <cinttypes>
|
||||||
#include <time.h>
|
#include <ctime>
|
||||||
#include <stdarg.h>
|
#include <cstdarg>
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -34,9 +34,10 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "logvisor/logvisor.hpp"
|
#include "logvisor/logvisor.hpp"
|
||||||
#include <athena/Global.hpp>
|
#include "athena/Global.hpp"
|
||||||
#include "../extern/boo/xxhash/xxhash.h"
|
#include "../extern/boo/xxhash/xxhash.h"
|
||||||
#include "SystemChar.hpp"
|
#include "SystemChar.hpp"
|
||||||
|
#include "FourCC.hpp"
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl
|
||||||
{
|
{
|
||||||
@ -46,6 +47,43 @@ class Project;
|
|||||||
struct DataSpecEntry;
|
struct DataSpecEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace blender
|
||||||
|
{
|
||||||
|
enum class BlendType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Mesh,
|
||||||
|
ColMesh,
|
||||||
|
Actor,
|
||||||
|
Area,
|
||||||
|
World,
|
||||||
|
MapArea,
|
||||||
|
MapUniverse,
|
||||||
|
Frame
|
||||||
|
};
|
||||||
|
|
||||||
|
class Connection;
|
||||||
|
class Token;
|
||||||
|
class DataStream;
|
||||||
|
class PyOutStream;
|
||||||
|
class ANIMOutStream;
|
||||||
|
struct Mesh;
|
||||||
|
struct Material;
|
||||||
|
struct ColMesh;
|
||||||
|
struct World;
|
||||||
|
struct Light;
|
||||||
|
struct MapArea;
|
||||||
|
struct MapUniverse;
|
||||||
|
struct Actor;
|
||||||
|
struct Armature;
|
||||||
|
struct Action;
|
||||||
|
struct Bone;
|
||||||
|
struct Matrix3f;
|
||||||
|
struct PoolSkinIndex;
|
||||||
|
|
||||||
|
extern class Token SharedBlenderToken;
|
||||||
|
}
|
||||||
|
|
||||||
extern unsigned VerbosityLevel;
|
extern unsigned VerbosityLevel;
|
||||||
extern bool GuiMode;
|
extern bool GuiMode;
|
||||||
extern logvisor::Module LogModule;
|
extern logvisor::Module LogModule;
|
||||||
@ -480,46 +518,6 @@ typedef std::match_results<SystemString::const_iterator> SystemRegexMatch;
|
|||||||
|
|
||||||
class ProjectRootPath;
|
class ProjectRootPath;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief FourCC representation used within HECL's database
|
|
||||||
*
|
|
||||||
* FourCCs are efficient, mnemonic four-char-sequences used to represent types
|
|
||||||
* while fitting comfortably in a 32-bit word. HECL uses a four-char array
|
|
||||||
* to remain endian-independent.
|
|
||||||
*/
|
|
||||||
class FourCC
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
union
|
|
||||||
{
|
|
||||||
char fcc[4];
|
|
||||||
uint32_t num;
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
FourCC() /* Sentinel FourCC */
|
|
||||||
: num(0) {}
|
|
||||||
FourCC(const FourCC& other)
|
|
||||||
{num = other.num;}
|
|
||||||
FourCC(const char* name)
|
|
||||||
: num(*(uint32_t*)name) {}
|
|
||||||
FourCC(uint32_t n)
|
|
||||||
: num(n) {}
|
|
||||||
bool operator==(const FourCC& other) const {return num == other.num;}
|
|
||||||
bool operator!=(const FourCC& other) const {return num != other.num;}
|
|
||||||
bool operator==(const char* other) const {return num == *(uint32_t*)other;}
|
|
||||||
bool operator!=(const char* other) const {return num != *(uint32_t*)other;}
|
|
||||||
bool operator==(int32_t other) const { return num == other;}
|
|
||||||
bool operator!=(int32_t other) const { return num != other;}
|
|
||||||
bool operator==(uint32_t other) const {return num == other;}
|
|
||||||
bool operator!=(uint32_t other) const {return num != other;}
|
|
||||||
std::string toString() const {return std::string(fcc, 4);}
|
|
||||||
uint32_t toUint32() const {return num;}
|
|
||||||
operator uint32_t() const {return num;}
|
|
||||||
const char* getChars() const {return fcc;}
|
|
||||||
char* getChars() {return fcc;}
|
|
||||||
};
|
|
||||||
#define FOURCC(chars) FourCC(SBIG(chars))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Hash representation used for all storable and comparable objects
|
* @brief Hash representation used for all storable and comparable objects
|
||||||
*
|
*
|
||||||
@ -1465,27 +1463,16 @@ static inline double SBig(double val) {return val;}
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _MSC_VER
|
|
||||||
#define NOEXCEPT
|
|
||||||
#else
|
|
||||||
#define NOEXCEPT noexcept
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
template <> struct hash<hecl::FourCC>
|
|
||||||
{
|
|
||||||
size_t operator()(const hecl::FourCC& val) const NOEXCEPT
|
|
||||||
{return val.toUint32();}
|
|
||||||
};
|
|
||||||
template <> struct hash<hecl::ProjectPath>
|
template <> struct hash<hecl::ProjectPath>
|
||||||
{
|
{
|
||||||
size_t operator()(const hecl::ProjectPath& val) const NOEXCEPT
|
size_t operator()(const hecl::ProjectPath& val) const noexcept
|
||||||
{return val.hash().valSizeT();}
|
{return val.hash().valSizeT();}
|
||||||
};
|
};
|
||||||
template <> struct hash<hecl::Hash>
|
template <> struct hash<hecl::Hash>
|
||||||
{
|
{
|
||||||
size_t operator()(const hecl::Hash& val) const NOEXCEPT
|
size_t operator()(const hecl::Hash& val) const noexcept
|
||||||
{return val.valSizeT();}
|
{return val.valSizeT();}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,9 @@
|
|||||||
#include <boo/graphicsdev/GL.hpp>
|
#include <boo/graphicsdev/GL.hpp>
|
||||||
#include <boo/graphicsdev/Vulkan.hpp>
|
#include <boo/graphicsdev/Vulkan.hpp>
|
||||||
|
|
||||||
static logvisor::Module Log("hecl::Backend::GLSL");
|
static logvisor::Module GLSL_Log("hecl::Backend::GLSL");
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Backend
|
||||||
{
|
|
||||||
namespace Backend
|
|
||||||
{
|
{
|
||||||
|
|
||||||
std::string GLSL::EmitTexGenSource2(TexGenSrc src, int uvIdx) const
|
std::string GLSL::EmitTexGenSource2(TexGenSrc src, int uvIdx) const
|
||||||
@ -364,7 +362,8 @@ std::string GLSL::makeFrag(const char* glslVer, bool alphaTest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
namespace Runtime
|
|
||||||
|
namespace hecl::Runtime
|
||||||
{
|
{
|
||||||
|
|
||||||
static const char* STD_BLOCKNAMES[] = {HECL_GLSL_VERT_UNIFORM_BLOCK_NAME,
|
static const char* STD_BLOCKNAMES[] = {HECL_GLSL_VERT_UNIFORM_BLOCK_NAME,
|
||||||
@ -407,7 +406,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
|
|||||||
cachedSz += fragSource.size() + 1;
|
cachedSz += fragSource.size() + 1;
|
||||||
|
|
||||||
if (m_backend.m_texMapEnd > 8)
|
if (m_backend.m_texMapEnd > 8)
|
||||||
Log.report(logvisor::Fatal, "maximum of 8 texture maps supported");
|
GLSL_Log.report(logvisor::Fatal, "maximum of 8 texture maps supported");
|
||||||
|
|
||||||
objOut =
|
objOut =
|
||||||
static_cast<boo::GLDataFactory::Context&>(ctx).
|
static_cast<boo::GLDataFactory::Context&>(ctx).
|
||||||
@ -420,7 +419,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
|
|||||||
tag.getDepthWrite(), true, false,
|
tag.getDepthWrite(), true, false,
|
||||||
tag.getBackfaceCulling() ? boo::CullMode::Backface : boo::CullMode::None);
|
tag.getBackfaceCulling() ? boo::CullMode::Backface : boo::CullMode::None);
|
||||||
if (!objOut)
|
if (!objOut)
|
||||||
Log.report(logvisor::Fatal, "unable to build shader");
|
GLSL_Log.report(logvisor::Fatal, "unable to build shader");
|
||||||
|
|
||||||
ShaderCachedData dataOut(tag, cachedSz);
|
ShaderCachedData dataOut(tag, cachedSz);
|
||||||
athena::io::MemoryWriter w(dataOut.m_data.get(), dataOut.m_sz);
|
athena::io::MemoryWriter w(dataOut.m_data.get(), dataOut.m_sz);
|
||||||
@ -448,7 +447,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (texMapEnd > 8)
|
if (texMapEnd > 8)
|
||||||
Log.report(logvisor::Fatal, "maximum of 8 texture maps supported");
|
GLSL_Log.report(logvisor::Fatal, "maximum of 8 texture maps supported");
|
||||||
|
|
||||||
auto ret =
|
auto ret =
|
||||||
static_cast<boo::GLDataFactory::Context&>(ctx).
|
static_cast<boo::GLDataFactory::Context&>(ctx).
|
||||||
@ -460,7 +459,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
|
|||||||
tag.getDepthWrite(), true, false,
|
tag.getDepthWrite(), true, false,
|
||||||
tag.getBackfaceCulling() ? boo::CullMode::Backface : boo::CullMode::None);
|
tag.getBackfaceCulling() ? boo::CullMode::Backface : boo::CullMode::None);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
Log.report(logvisor::Fatal, "unable to build shader");
|
GLSL_Log.report(logvisor::Fatal, "unable to build shader");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,7 +474,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
|
|||||||
size_t cachedSz = 3;
|
size_t cachedSz = 3;
|
||||||
|
|
||||||
if (m_backend.m_texMapEnd > 8)
|
if (m_backend.m_texMapEnd > 8)
|
||||||
Log.report(logvisor::Fatal, "maximum of 8 texture maps supported");
|
GLSL_Log.report(logvisor::Fatal, "maximum of 8 texture maps supported");
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> sources;
|
std::vector<std::pair<std::string, std::string>> sources;
|
||||||
sources.reserve(extensionSlots.size());
|
sources.reserve(extensionSlots.size());
|
||||||
@ -531,7 +530,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
|
|||||||
(tag.getBackfaceCulling() ? boo::CullMode::Backface : boo::CullMode::None) :
|
(tag.getBackfaceCulling() ? boo::CullMode::Backface : boo::CullMode::None) :
|
||||||
boo::CullMode(slot.cullMode));
|
boo::CullMode(slot.cullMode));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
Log.report(logvisor::Fatal, "unable to build shader");
|
GLSL_Log.report(logvisor::Fatal, "unable to build shader");
|
||||||
returnFunc(ret);
|
returnFunc(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,7 +563,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (texMapEnd > 8)
|
if (texMapEnd > 8)
|
||||||
Log.report(logvisor::Fatal, "maximum of 8 texture maps supported");
|
GLSL_Log.report(logvisor::Fatal, "maximum of 8 texture maps supported");
|
||||||
|
|
||||||
for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots)
|
for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots)
|
||||||
{
|
{
|
||||||
@ -614,7 +613,7 @@ struct GLSLBackendFactory : IShaderBackendFactory
|
|||||||
(tag.getBackfaceCulling() ? boo::CullMode::Backface : boo::CullMode::None) :
|
(tag.getBackfaceCulling() ? boo::CullMode::Backface : boo::CullMode::None) :
|
||||||
boo::CullMode(slot.cullMode));
|
boo::CullMode(slot.cullMode));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
Log.report(logvisor::Fatal, "unable to build shader");
|
GLSL_Log.report(logvisor::Fatal, "unable to build shader");
|
||||||
returnFunc(ret);
|
returnFunc(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -927,4 +926,3 @@ IShaderBackendFactory* _NewSPIRVBackendFactory()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
#include "hecl/Backend/GX.hpp"
|
#include "hecl/Backend/GX.hpp"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Backend
|
||||||
{
|
|
||||||
namespace Backend
|
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned GX::addKColor(Diagnostics& diag, const SourceLocation& loc, const Color& color)
|
unsigned GX::addKColor(Diagnostics& diag, const SourceLocation& loc, const Color& color)
|
||||||
@ -773,4 +771,3 @@ void GX::reset(const IR& ir, Diagnostics& diag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -6,9 +6,7 @@
|
|||||||
|
|
||||||
static logvisor::Module Log("hecl::Backend::HLSL");
|
static logvisor::Module Log("hecl::Backend::HLSL");
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Backend
|
||||||
{
|
|
||||||
namespace Backend
|
|
||||||
{
|
{
|
||||||
|
|
||||||
std::string HLSL::EmitTexGenSource2(TexGenSrc src, int uvIdx) const
|
std::string HLSL::EmitTexGenSource2(TexGenSrc src, int uvIdx) const
|
||||||
@ -683,4 +681,3 @@ IShaderBackendFactory* _NewHLSLBackendFactory()
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -6,9 +6,7 @@
|
|||||||
|
|
||||||
static logvisor::Module Log("hecl::Backend::Metal");
|
static logvisor::Module Log("hecl::Backend::Metal");
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Backend
|
||||||
{
|
|
||||||
namespace Backend
|
|
||||||
{
|
{
|
||||||
|
|
||||||
std::string Metal::EmitTexGenSource2(TexGenSrc src, int uvIdx) const
|
std::string Metal::EmitTexGenSource2(TexGenSrc src, int uvIdx) const
|
||||||
@ -432,7 +430,8 @@ std::string Metal::makeFrag(size_t blockCount, const char** blockNames, bool alp
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
namespace Runtime
|
|
||||||
|
namespace hecl::Runtime
|
||||||
{
|
{
|
||||||
|
|
||||||
struct MetalBackendFactory : IShaderBackendFactory
|
struct MetalBackendFactory : IShaderBackendFactory
|
||||||
@ -701,7 +700,6 @@ IShaderBackendFactory* _NewMetalBackendFactory()
|
|||||||
return new struct MetalBackendFactory();
|
return new struct MetalBackendFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
#include "hecl/Backend/ProgrammableCommon.hpp"
|
#include "hecl/Backend/ProgrammableCommon.hpp"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Backend
|
||||||
{
|
|
||||||
namespace Backend
|
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned ProgrammableCommon::addTexCoordGen(TexGenSrc src, int uvIdx, int mtx, bool normalize)
|
unsigned ProgrammableCommon::addTexCoordGen(TexGenSrc src, int uvIdx, int mtx, bool normalize)
|
||||||
@ -337,4 +335,3 @@ std::string ProgrammableCommon::EmitSwizzle1(Diagnostics& diag, const SourceLoca
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
set(BLENDER_SOURCES
|
set(BLENDER_SOURCES
|
||||||
BlenderConnection.cpp
|
Connection.cpp
|
||||||
HMDL.cpp)
|
HMDL.cpp)
|
||||||
|
|
||||||
hecl_add_list(Blender BLENDER_SOURCES)
|
hecl_add_list(Blender BLENDER_SOURCES)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,11 @@
|
|||||||
#include "hecl/Blender/BlenderConnection.hpp"
|
#include "hecl/Blender/Connection.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <float.h>
|
#include <cfloat>
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::blender
|
||||||
{
|
{
|
||||||
|
|
||||||
atVec3f BlenderConnection::DataStream::MtxVecMul4RM(const Matrix4f& mtx, const Vector3f& vec)
|
atVec3f MtxVecMul4RM(const Matrix4f& mtx, const Vector3f& vec)
|
||||||
{
|
{
|
||||||
atVec3f res;
|
atVec3f res;
|
||||||
res.vec[0] = mtx[0].vec[0] * vec.val.vec[0] + mtx[0].vec[1] * vec.val.vec[1] + mtx[0].vec[2] * vec.val.vec[2] + mtx[0].vec[3];
|
res.vec[0] = mtx[0].vec[0] * vec.val.vec[0] + mtx[0].vec[1] * vec.val.vec[1] + mtx[0].vec[2] * vec.val.vec[2] + mtx[0].vec[3];
|
||||||
@ -14,7 +14,7 @@ atVec3f BlenderConnection::DataStream::MtxVecMul4RM(const Matrix4f& mtx, const V
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
atVec3f BlenderConnection::DataStream::MtxVecMul3RM(const Matrix4f& mtx, const Vector3f& vec)
|
atVec3f MtxVecMul3RM(const Matrix4f& mtx, const Vector3f& vec)
|
||||||
{
|
{
|
||||||
atVec3f res;
|
atVec3f res;
|
||||||
res.vec[0] = mtx[0].vec[0] * vec.val.vec[0] + mtx[0].vec[1] * vec.val.vec[1] + mtx[0].vec[2] * vec.val.vec[2];
|
res.vec[0] = mtx[0].vec[0] * vec.val.vec[0] + mtx[0].vec[1] * vec.val.vec[1] + mtx[0].vec[2] * vec.val.vec[2];
|
||||||
@ -23,8 +23,7 @@ atVec3f BlenderConnection::DataStream::MtxVecMul3RM(const Matrix4f& mtx, const V
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
HMDLBuffers BlenderConnection::DataStream::Mesh::getHMDLBuffers(bool absoluteCoords,
|
HMDLBuffers Mesh::getHMDLBuffers(bool absoluteCoords, PoolSkinIndex& poolSkinIndex) const
|
||||||
PoolSkinIndex& poolSkinIndex) const
|
|
||||||
{
|
{
|
||||||
/* If skinned, compute max weight vec count */
|
/* If skinned, compute max weight vec count */
|
||||||
size_t weightCount = 0;
|
size_t weightCount = 0;
|
||||||
|
@ -39,6 +39,7 @@ add_library(hecl-common
|
|||||||
../include/hecl/CVar.hpp
|
../include/hecl/CVar.hpp
|
||||||
../include/hecl/CVarManager.hpp
|
../include/hecl/CVarManager.hpp
|
||||||
../include/hecl/hecl.hpp
|
../include/hecl/hecl.hpp
|
||||||
|
../include/hecl/FourCC.hpp
|
||||||
../include/hecl/HMDLMeta.hpp
|
../include/hecl/HMDLMeta.hpp
|
||||||
../include/hecl/Backend/Backend.hpp
|
../include/hecl/Backend/Backend.hpp
|
||||||
../include/hecl/Backend/GX.hpp
|
../include/hecl/Backend/GX.hpp
|
||||||
@ -46,7 +47,8 @@ add_library(hecl-common
|
|||||||
../include/hecl/Backend/GLSL.hpp
|
../include/hecl/Backend/GLSL.hpp
|
||||||
../include/hecl/Backend/HLSL.hpp
|
../include/hecl/Backend/HLSL.hpp
|
||||||
../include/hecl/Backend/Metal.hpp
|
../include/hecl/Backend/Metal.hpp
|
||||||
../include/hecl/Blender/BlenderConnection.hpp
|
../include/hecl/Blender/Connection.hpp
|
||||||
|
../include/hecl/Blender/Token.hpp
|
||||||
../include/hecl/SteamFinder.hpp
|
../include/hecl/SteamFinder.hpp
|
||||||
../include/hecl/Frontend.hpp
|
../include/hecl/Frontend.hpp
|
||||||
../include/hecl/Database.hpp
|
../include/hecl/Database.hpp
|
||||||
@ -67,6 +69,9 @@ add_library(hecl-common
|
|||||||
if(COMMAND add_sanitizers)
|
if(COMMAND add_sanitizers)
|
||||||
add_sanitizers(hecl-common)
|
add_sanitizers(hecl-common)
|
||||||
endif()
|
endif()
|
||||||
|
if(COMMAND cotire)
|
||||||
|
cotire(hecl-common)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WINDOWS_STORE)
|
if(WINDOWS_STORE)
|
||||||
set_property(TARGET hecl-common PROPERTY VS_WINRT_COMPONENT TRUE)
|
set_property(TARGET hecl-common PROPERTY VS_WINRT_COMPONENT TRUE)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "hecl/ClientProcess.hpp"
|
#include "hecl/ClientProcess.hpp"
|
||||||
#include "hecl/Database.hpp"
|
#include "hecl/Database.hpp"
|
||||||
#include "athena/FileReader.hpp"
|
#include "athena/FileReader.hpp"
|
||||||
#include "hecl/Blender/BlenderConnection.hpp"
|
#include "hecl/Blender/Connection.hpp"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
namespace hecl
|
namespace hecl
|
||||||
{
|
{
|
||||||
static logvisor::Module Log("hecl::ClientProcess");
|
static logvisor::Module CP_Log("hecl::ClientProcess");
|
||||||
|
|
||||||
ThreadLocalPtr<ClientProcess::Worker> ClientProcess::ThreadWorker;
|
ThreadLocalPtr<ClientProcess::Worker> ClientProcess::ThreadWorker;
|
||||||
|
|
||||||
@ -29,12 +29,12 @@ static int GetCPUCount()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientProcess::BufferTransaction::run(BlenderToken& btok)
|
void ClientProcess::BufferTransaction::run(blender::Token& btok)
|
||||||
{
|
{
|
||||||
athena::io::FileReader r(m_path.getAbsolutePath(), 32 * 1024, false);
|
athena::io::FileReader r(m_path.getAbsolutePath(), 32 * 1024, false);
|
||||||
if (r.hasError())
|
if (r.hasError())
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Fatal, _S("unable to background-buffer '%s'"),
|
CP_Log.report(logvisor::Fatal, _S("unable to background-buffer '%s'"),
|
||||||
m_path.getAbsolutePath().data());
|
m_path.getAbsolutePath().data());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -44,14 +44,14 @@ void ClientProcess::BufferTransaction::run(BlenderToken& btok)
|
|||||||
m_complete = true;
|
m_complete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientProcess::CookTransaction::run(BlenderToken& btok)
|
void ClientProcess::CookTransaction::run(blender::Token& btok)
|
||||||
{
|
{
|
||||||
m_dataSpec->setThreadProject();
|
m_dataSpec->setThreadProject();
|
||||||
m_returnResult = m_parent.syncCook(m_path, m_dataSpec, btok);
|
m_returnResult = m_parent.syncCook(m_path, m_dataSpec, btok);
|
||||||
m_complete = true;
|
m_complete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientProcess::LambdaTransaction::run(BlenderToken& btok)
|
void ClientProcess::LambdaTransaction::run(blender::Token& btok)
|
||||||
{
|
{
|
||||||
m_func(btok);
|
m_func(btok);
|
||||||
m_complete = true;
|
m_complete = true;
|
||||||
@ -137,7 +137,7 @@ ClientProcess::addCookTransaction(const hecl::ProjectPath& path, Database::IData
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const ClientProcess::LambdaTransaction>
|
std::shared_ptr<const ClientProcess::LambdaTransaction>
|
||||||
ClientProcess::addLambdaTransaction(std::function<void(BlenderToken&)>&& func)
|
ClientProcess::addLambdaTransaction(std::function<void(blender::Token&)>&& func)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lk(m_mutex);
|
std::unique_lock<std::mutex> lk(m_mutex);
|
||||||
auto ret = std::make_shared<LambdaTransaction>(*this, std::move(func));
|
auto ret = std::make_shared<LambdaTransaction>(*this, std::move(func));
|
||||||
@ -146,7 +146,7 @@ ClientProcess::addLambdaTransaction(std::function<void(BlenderToken&)>&& func)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClientProcess::syncCook(const hecl::ProjectPath& path, Database::IDataSpec* spec, BlenderToken& btok)
|
bool ClientProcess::syncCook(const hecl::ProjectPath& path, Database::IDataSpec* spec, blender::Token& btok)
|
||||||
{
|
{
|
||||||
if (spec->canCook(path, btok))
|
if (spec->canCook(path, btok))
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "hecl/hecl.hpp"
|
#include "hecl/hecl.hpp"
|
||||||
#include "hecl/Frontend.hpp"
|
#include "hecl/Frontend.hpp"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <cstdarg>
|
||||||
|
|
||||||
/* ANSI sequences */
|
/* ANSI sequences */
|
||||||
#define RED "\x1b[1;31m"
|
#define RED "\x1b[1;31m"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <cerrno>
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
@ -10,12 +10,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "hecl/Database.hpp"
|
#include "hecl/Database.hpp"
|
||||||
#include "hecl/Blender/BlenderConnection.hpp"
|
#include "hecl/Blender/Connection.hpp"
|
||||||
#include "hecl/ClientProcess.hpp"
|
#include "hecl/ClientProcess.hpp"
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Database
|
||||||
{
|
|
||||||
namespace Database
|
|
||||||
{
|
{
|
||||||
|
|
||||||
logvisor::Module LogModule("hecl::Database");
|
logvisor::Module LogModule("hecl::Database");
|
||||||
@ -397,7 +395,7 @@ static void VisitFile(const ProjectPath& path, bool force, bool fast,
|
|||||||
{
|
{
|
||||||
for (auto& spec : specInsts)
|
for (auto& spec : specInsts)
|
||||||
{
|
{
|
||||||
if (spec->canCook(path, hecl::SharedBlenderToken))
|
if (spec->canCook(path, hecl::blender::SharedBlenderToken))
|
||||||
{
|
{
|
||||||
if (cp)
|
if (cp)
|
||||||
{
|
{
|
||||||
@ -406,7 +404,7 @@ static void VisitFile(const ProjectPath& path, bool force, bool fast,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
const DataSpecEntry* override = spec->overrideDataSpec(path, spec->getDataSpecEntry(),
|
const DataSpecEntry* override = spec->overrideDataSpec(path, spec->getDataSpecEntry(),
|
||||||
hecl::SharedBlenderToken);
|
hecl::blender::SharedBlenderToken);
|
||||||
if (!override)
|
if (!override)
|
||||||
continue;
|
continue;
|
||||||
ProjectPath cooked = path.getCookedPath(*override);
|
ProjectPath cooked = path.getCookedPath(*override);
|
||||||
@ -416,7 +414,7 @@ static void VisitFile(const ProjectPath& path, bool force, bool fast,
|
|||||||
path.getModtime() > cooked.getModtime())
|
path.getModtime() > cooked.getModtime())
|
||||||
{
|
{
|
||||||
progress.reportFile(override);
|
progress.reportFile(override);
|
||||||
spec->doCook(path, cooked, fast, hecl::SharedBlenderToken,
|
spec->doCook(path, cooked, fast, hecl::blender::SharedBlenderToken,
|
||||||
[&](const SystemChar* extra)
|
[&](const SystemChar* extra)
|
||||||
{
|
{
|
||||||
progress.reportFile(override, extra);
|
progress.reportFile(override, extra);
|
||||||
@ -539,7 +537,7 @@ bool Project::packagePath(const ProjectPath& path, FProgress progress, bool fast
|
|||||||
|
|
||||||
if (m_lastPackageSpec->canPackage(path))
|
if (m_lastPackageSpec->canPackage(path))
|
||||||
{
|
{
|
||||||
m_lastPackageSpec->doPackage(path, specEntry, fast, hecl::SharedBlenderToken, progress, cp);
|
m_lastPackageSpec->doPackage(path, specEntry, fast, hecl::blender::SharedBlenderToken, progress, cp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,4 +577,3 @@ const ProjectPath* Project::lookupBridgePath(uint64_t id) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -8,9 +8,7 @@
|
|||||||
using namespace Windows::Storage;
|
using namespace Windows::Storage;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Runtime
|
||||||
{
|
|
||||||
namespace Runtime
|
|
||||||
{
|
{
|
||||||
static logvisor::Module Log("FileStoreManager");
|
static logvisor::Module Log("FileStoreManager");
|
||||||
|
|
||||||
@ -53,4 +51,3 @@ FileStoreManager::FileStoreManager(SystemStringView domain)
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -2,11 +2,9 @@
|
|||||||
#include "hecl/Runtime.hpp"
|
#include "hecl/Runtime.hpp"
|
||||||
#include <athena/MemoryReader.hpp>
|
#include <athena/MemoryReader.hpp>
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Runtime
|
||||||
{
|
{
|
||||||
namespace Runtime
|
static logvisor::Module HMDL_Log("HMDL");
|
||||||
{
|
|
||||||
static logvisor::Module Log("HMDL");
|
|
||||||
|
|
||||||
HMDLData::HMDLData(boo::IGraphicsDataFactory::Context& ctx,
|
HMDLData::HMDLData(boo::IGraphicsDataFactory::Context& ctx,
|
||||||
const void* metaData, const void* vbo, const void* ibo)
|
const void* metaData, const void* vbo, const void* ibo)
|
||||||
@ -17,7 +15,7 @@ HMDLData::HMDLData(boo::IGraphicsDataFactory::Context& ctx,
|
|||||||
meta.read(r);
|
meta.read(r);
|
||||||
}
|
}
|
||||||
if (meta.magic != 'TACO')
|
if (meta.magic != 'TACO')
|
||||||
Log.report(logvisor::Fatal, "invalid HMDL magic");
|
HMDL_Log.report(logvisor::Fatal, "invalid HMDL magic");
|
||||||
|
|
||||||
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, vbo, meta.vertStride, meta.vertCount);
|
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, vbo, meta.vertStride, meta.vertCount);
|
||||||
m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, ibo, 4, meta.indexCount);
|
m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, ibo, 4, meta.indexCount);
|
||||||
@ -102,4 +100,3 @@ boo::ObjToken<boo::IVertexFormat> ShaderTag::newVertexFormat(boo::IGraphicsDataF
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -8,9 +8,7 @@
|
|||||||
#include "hecl/Backend/GLSL.hpp"
|
#include "hecl/Backend/GLSL.hpp"
|
||||||
#include "hecl/Backend/Metal.hpp"
|
#include "hecl/Backend/Metal.hpp"
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Runtime
|
||||||
{
|
|
||||||
namespace Runtime
|
|
||||||
{
|
{
|
||||||
#if BOO_HAS_GL
|
#if BOO_HAS_GL
|
||||||
IShaderBackendFactory* _NewGLSLBackendFactory();
|
IShaderBackendFactory* _NewGLSLBackendFactory();
|
||||||
@ -25,7 +23,7 @@ IShaderBackendFactory* _NewMetalBackendFactory();
|
|||||||
IShaderBackendFactory* _NewSPIRVBackendFactory();
|
IShaderBackendFactory* _NewSPIRVBackendFactory();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static logvisor::Module Log("ShaderCacheManager");
|
static logvisor::Module SCM_Log("ShaderCacheManager");
|
||||||
static uint64_t IDX_MAGIC = SBig(uint64_t(0xDEADFEEDC001D00D));
|
static uint64_t IDX_MAGIC = SBig(uint64_t(0xDEADFEEDC001D00D));
|
||||||
static uint64_t DAT_MAGIC = SBig(uint64_t(0xC001D00DDEADBABE));
|
static uint64_t DAT_MAGIC = SBig(uint64_t(0xC001D00DDEADBABE));
|
||||||
static uint64_t ZERO64 = 0;
|
static uint64_t ZERO64 = 0;
|
||||||
@ -88,7 +86,7 @@ void ShaderCacheManager::bootstrapIndex()
|
|||||||
|
|
||||||
FILE* idxFp = hecl::Fopen(idxFilename.c_str(), _S("wb"));
|
FILE* idxFp = hecl::Fopen(idxFilename.c_str(), _S("wb"));
|
||||||
if (!idxFp)
|
if (!idxFp)
|
||||||
Log.report(logvisor::Fatal, _S("unable to write shader cache index at %s"),
|
SCM_Log.report(logvisor::Fatal, _S("unable to write shader cache index at %s"),
|
||||||
idxFilename.c_str());
|
idxFilename.c_str());
|
||||||
fwrite(&IDX_MAGIC, 1, 8, idxFp);
|
fwrite(&IDX_MAGIC, 1, 8, idxFp);
|
||||||
fwrite(&m_timeHash, 1, 8, idxFp);
|
fwrite(&m_timeHash, 1, 8, idxFp);
|
||||||
@ -103,7 +101,7 @@ void ShaderCacheManager::bootstrapIndex()
|
|||||||
|
|
||||||
FILE* datFp = hecl::Fopen(datFilename.c_str(), _S("wb"));
|
FILE* datFp = hecl::Fopen(datFilename.c_str(), _S("wb"));
|
||||||
if (!datFp)
|
if (!datFp)
|
||||||
Log.report(logvisor::Fatal, _S("unable to write shader cache data at %s"),
|
SCM_Log.report(logvisor::Fatal, _S("unable to write shader cache data at %s"),
|
||||||
datFilename.c_str());
|
datFilename.c_str());
|
||||||
fwrite(&DAT_MAGIC, 1, 8, datFp);
|
fwrite(&DAT_MAGIC, 1, 8, datFp);
|
||||||
fwrite(&m_timeHash, 1, 8, datFp);
|
fwrite(&m_timeHash, 1, 8, datFp);
|
||||||
@ -125,7 +123,7 @@ ShaderCacheManager::ShaderCacheManager(const FileStoreManager& storeMgr,
|
|||||||
{
|
{
|
||||||
boo::IGraphicsDataFactory::Platform plat = gfxFactory->platform();
|
boo::IGraphicsDataFactory::Platform plat = gfxFactory->platform();
|
||||||
if (m_extensions && m_extensions.m_plat != plat)
|
if (m_extensions && m_extensions.m_plat != plat)
|
||||||
Log.report(logvisor::Fatal, "ShaderCacheExtension backend mismatch (should be %s)",
|
SCM_Log.report(logvisor::Fatal, "ShaderCacheExtension backend mismatch (should be %s)",
|
||||||
gfxFactory->platformName());
|
gfxFactory->platformName());
|
||||||
m_extensionsHash = m_extensions.hashExtensions();
|
m_extensionsHash = m_extensions.hashExtensions();
|
||||||
|
|
||||||
@ -153,7 +151,7 @@ ShaderCacheManager::ShaderCacheManager(const FileStoreManager& storeMgr,
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
Log.report(logvisor::Fatal, _S("unsupported backend %s"), gfxFactory->platformName());
|
SCM_Log.report(logvisor::Fatal, _S("unsupported backend %s"), gfxFactory->platformName());
|
||||||
}
|
}
|
||||||
|
|
||||||
reload();
|
reload();
|
||||||
@ -241,7 +239,7 @@ ShaderCachedData ShaderCacheManager::lookupData(const Hash& hash)
|
|||||||
const IndexEntry& ent = m_entries[search->second];
|
const IndexEntry& ent = m_entries[search->second];
|
||||||
if (ent.m_compOffset + ent.m_compSize > m_datFr.length())
|
if (ent.m_compOffset + ent.m_compSize > m_datFr.length())
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Warning, "shader cache not long enough to read entry, might be corrupt");
|
SCM_Log.report(logvisor::Warning, "shader cache not long enough to read entry, might be corrupt");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,18 +278,18 @@ bool ShaderCacheManager::addData(const ShaderCachedData& data)
|
|||||||
uLong cBound = compressBound(data.m_sz);
|
uLong cBound = compressBound(data.m_sz);
|
||||||
void* compBuf = malloc(cBound);
|
void* compBuf = malloc(cBound);
|
||||||
if (compress((Bytef*)compBuf, &cBound, (Bytef*)data.m_data.get(), data.m_sz) != Z_OK)
|
if (compress((Bytef*)compBuf, &cBound, (Bytef*)data.m_data.get(), data.m_sz) != Z_OK)
|
||||||
Log.report(logvisor::Fatal, "unable to deflate data");
|
SCM_Log.report(logvisor::Fatal, "unable to deflate data");
|
||||||
|
|
||||||
/* Open index for writing (non overwriting) */
|
/* Open index for writing (non overwriting) */
|
||||||
athena::io::FileWriter idxFw(m_idxFr.filename(), false);
|
athena::io::FileWriter idxFw(m_idxFr.filename(), false);
|
||||||
if (idxFw.hasError())
|
if (idxFw.hasError())
|
||||||
Log.report(logvisor::Fatal, _S("unable to append shader cache index at %s"),
|
SCM_Log.report(logvisor::Fatal, _S("unable to append shader cache index at %s"),
|
||||||
m_idxFr.filename().c_str());
|
m_idxFr.filename().c_str());
|
||||||
|
|
||||||
/* Open data for writing (non overwriting) */
|
/* Open data for writing (non overwriting) */
|
||||||
athena::io::FileWriter datFw(m_datFr.filename(), false);
|
athena::io::FileWriter datFw(m_datFr.filename(), false);
|
||||||
if (datFw.hasError())
|
if (datFw.hasError())
|
||||||
Log.report(logvisor::Fatal, _S("unable to append shader cache data at %s"),
|
SCM_Log.report(logvisor::Fatal, _S("unable to append shader cache data at %s"),
|
||||||
m_datFr.filename().c_str());
|
m_datFr.filename().c_str());
|
||||||
|
|
||||||
size_t targetOffset = 0;
|
size_t targetOffset = 0;
|
||||||
@ -398,7 +396,7 @@ ShaderCacheManager::buildShader(const ShaderTag& tag, std::string_view source,
|
|||||||
{
|
{
|
||||||
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.data(), tag.val64());
|
SCM_Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.data(), tag.val64());
|
||||||
boo::ObjToken<boo::IShaderPipeline> build = buildFromCache(foundData, ctx);
|
boo::ObjToken<boo::IShaderPipeline> build = buildFromCache(foundData, ctx);
|
||||||
if (build)
|
if (build)
|
||||||
{
|
{
|
||||||
@ -413,13 +411,13 @@ ShaderCacheManager::buildShader(const ShaderTag& tag, std::string_view source,
|
|||||||
m_pipelineLookup[tag] = ret;
|
m_pipelineLookup[tag] = ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.data());
|
SCM_Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
{
|
{
|
||||||
hecl::Frontend::IR ir = FE.compileSource(source, diagName);
|
hecl::Frontend::IR ir = FE.compileSource(source, diagName);
|
||||||
Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.data(), tag.val64());
|
SCM_Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.data(), tag.val64());
|
||||||
FE.getDiagnostics().reset(diagName);
|
FE.getDiagnostics().reset(diagName);
|
||||||
boo::ObjToken<boo::IShaderPipeline> build;
|
boo::ObjToken<boo::IShaderPipeline> build;
|
||||||
addData(m_factory->buildShaderFromIR(tag, ir, FE.getDiagnostics(), ctx, build));
|
addData(m_factory->buildShaderFromIR(tag, ir, FE.getDiagnostics(), ctx, build));
|
||||||
@ -445,7 +443,7 @@ ShaderCacheManager::buildShader(const ShaderTag& tag, const hecl::Frontend::IR&
|
|||||||
{
|
{
|
||||||
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.data(), tag.val64());
|
SCM_Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.data(), tag.val64());
|
||||||
boo::ObjToken<boo::IShaderPipeline> build = buildFromCache(foundData, ctx);
|
boo::ObjToken<boo::IShaderPipeline> build = buildFromCache(foundData, ctx);
|
||||||
if (build)
|
if (build)
|
||||||
{
|
{
|
||||||
@ -460,12 +458,12 @@ ShaderCacheManager::buildShader(const ShaderTag& tag, const hecl::Frontend::IR&
|
|||||||
m_pipelineLookup[tag] = ret;
|
m_pipelineLookup[tag] = ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.data());
|
SCM_Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.data(), tag.val64());
|
SCM_Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.data(), tag.val64());
|
||||||
FE.getDiagnostics().reset(diagName);
|
FE.getDiagnostics().reset(diagName);
|
||||||
boo::ObjToken<boo::IShaderPipeline> build;
|
boo::ObjToken<boo::IShaderPipeline> build;
|
||||||
addData(m_factory->buildShaderFromIR(tag, ir, FE.getDiagnostics(), ctx, build));
|
addData(m_factory->buildShaderFromIR(tag, ir, FE.getDiagnostics(), ctx, build));
|
||||||
@ -486,7 +484,7 @@ ShaderCacheManager::buildExtendedFromCache(const ShaderCachedData& foundData,
|
|||||||
[&](const boo::ObjToken<boo::IShaderPipeline>& shader){shaders.push_back(shader);}))
|
[&](const boo::ObjToken<boo::IShaderPipeline>& shader){shaders.push_back(shader);}))
|
||||||
return {};
|
return {};
|
||||||
if (shaders.size() != m_extensions.m_extensionSlots.size())
|
if (shaders.size() != m_extensions.m_extensionSlots.size())
|
||||||
Log.report(logvisor::Fatal, "buildShaderFromCache returned %" PRISize " times, expected %" PRISize,
|
SCM_Log.report(logvisor::Fatal, "buildShaderFromCache returned %" PRISize " times, expected %" PRISize,
|
||||||
shaders.size(), m_extensions.m_extensionSlots.size());
|
shaders.size(), m_extensions.m_extensionSlots.size());
|
||||||
return shaders;
|
return shaders;
|
||||||
}
|
}
|
||||||
@ -506,7 +504,7 @@ ShaderCacheManager::buildExtendedShader(const ShaderTag& tag, std::string_view s
|
|||||||
{
|
{
|
||||||
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.data(), tag.val64());
|
SCM_Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.data(), tag.val64());
|
||||||
ret->m_pipelines = buildExtendedFromCache(foundData, ctx);
|
ret->m_pipelines = buildExtendedFromCache(foundData, ctx);
|
||||||
return ret->m_pipelines.size() != 0;
|
return ret->m_pipelines.size() != 0;
|
||||||
});
|
});
|
||||||
@ -516,7 +514,7 @@ ShaderCacheManager::buildExtendedShader(const ShaderTag& tag, std::string_view s
|
|||||||
m_pipelineLookup[tag] = ret;
|
m_pipelineLookup[tag] = ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.data());
|
SCM_Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
hecl::Frontend::IR ir = FE.compileSource(source, diagName);
|
hecl::Frontend::IR ir = FE.compileSource(source, diagName);
|
||||||
@ -525,12 +523,12 @@ ShaderCacheManager::buildExtendedShader(const ShaderTag& tag, std::string_view s
|
|||||||
{
|
{
|
||||||
ret->m_pipelines.reserve(m_extensions.m_extensionSlots.size());
|
ret->m_pipelines.reserve(m_extensions.m_extensionSlots.size());
|
||||||
FE.getDiagnostics().reset(diagName);
|
FE.getDiagnostics().reset(diagName);
|
||||||
Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.data(), tag.val64());
|
SCM_Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.data(), tag.val64());
|
||||||
ShaderCachedData data =
|
ShaderCachedData data =
|
||||||
m_factory->buildExtendedShaderFromIR(tag, ir, FE.getDiagnostics(), m_extensions.m_extensionSlots, ctx,
|
m_factory->buildExtendedShaderFromIR(tag, ir, FE.getDiagnostics(), m_extensions.m_extensionSlots, ctx,
|
||||||
[&](const boo::ObjToken<boo::IShaderPipeline>& shader){ret->m_pipelines.push_back(shader);});
|
[&](const boo::ObjToken<boo::IShaderPipeline>& shader){ret->m_pipelines.push_back(shader);});
|
||||||
if (ret->m_pipelines.size() != m_extensions.m_extensionSlots.size())
|
if (ret->m_pipelines.size() != m_extensions.m_extensionSlots.size())
|
||||||
Log.report(logvisor::Fatal, "buildShaderFromIR returned %" PRISize " times, expected %" PRISize,
|
SCM_Log.report(logvisor::Fatal, "buildShaderFromIR returned %" PRISize " times, expected %" PRISize,
|
||||||
ret->m_pipelines.size(), m_extensions.m_extensionSlots.size());
|
ret->m_pipelines.size(), m_extensions.m_extensionSlots.size());
|
||||||
addData(data);
|
addData(data);
|
||||||
return true;
|
return true;
|
||||||
@ -554,7 +552,7 @@ ShaderCacheManager::buildExtendedShader(const ShaderTag& tag, const hecl::Fronte
|
|||||||
{
|
{
|
||||||
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.data(), tag.val64());
|
SCM_Log.report(logvisor::Info, "building cached shader '%s' %016llX", diagName.data(), tag.val64());
|
||||||
ret->m_pipelines = buildExtendedFromCache(foundData, ctx);
|
ret->m_pipelines = buildExtendedFromCache(foundData, ctx);
|
||||||
return ret->m_pipelines.size() != 0;
|
return ret->m_pipelines.size() != 0;
|
||||||
});
|
});
|
||||||
@ -564,19 +562,19 @@ ShaderCacheManager::buildExtendedShader(const ShaderTag& tag, const hecl::Fronte
|
|||||||
m_pipelineLookup[tag] = ret;
|
m_pipelineLookup[tag] = ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.data());
|
SCM_Log.report(logvisor::Warning, "invalid cache read, rebuilding shader '%s'", diagName.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
factory.commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
{
|
{
|
||||||
ret->m_pipelines.reserve(m_extensions.m_extensionSlots.size());
|
ret->m_pipelines.reserve(m_extensions.m_extensionSlots.size());
|
||||||
FE.getDiagnostics().reset(diagName);
|
FE.getDiagnostics().reset(diagName);
|
||||||
Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.data(), tag.val64());
|
SCM_Log.report(logvisor::Info, "building shader '%s' %016llX", diagName.data(), tag.val64());
|
||||||
ShaderCachedData data =
|
ShaderCachedData data =
|
||||||
m_factory->buildExtendedShaderFromIR(tag, ir, FE.getDiagnostics(), m_extensions.m_extensionSlots, ctx,
|
m_factory->buildExtendedShaderFromIR(tag, ir, FE.getDiagnostics(), m_extensions.m_extensionSlots, ctx,
|
||||||
[&](const boo::ObjToken<boo::IShaderPipeline>& shader){ret->m_pipelines.push_back(shader);});
|
[&](const boo::ObjToken<boo::IShaderPipeline>& shader){ret->m_pipelines.push_back(shader);});
|
||||||
if (ret->m_pipelines.size() != m_extensions.m_extensionSlots.size())
|
if (ret->m_pipelines.size() != m_extensions.m_extensionSlots.size())
|
||||||
Log.report(logvisor::Fatal, "buildShaderFromIR returned %" PRISize " times, expected %" PRISize,
|
SCM_Log.report(logvisor::Fatal, "buildShaderFromIR returned %" PRISize " times, expected %" PRISize,
|
||||||
ret->m_pipelines.size(), m_extensions.m_extensionSlots.size());
|
ret->m_pipelines.size(), m_extensions.m_extensionSlots.size());
|
||||||
addData(data);
|
addData(data);
|
||||||
return true;
|
return true;
|
||||||
@ -586,4 +584,3 @@ ShaderCacheManager::buildExtendedShader(const ShaderTag& tag, const hecl::Fronte
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <stdint.h>
|
#include <cstdint>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "hecl/winsupport.hpp"
|
#include "hecl/winsupport.hpp"
|
||||||
|
|
||||||
|
@ -4,18 +4,15 @@
|
|||||||
#include "hecl/Runtime.hpp"
|
#include "hecl/Runtime.hpp"
|
||||||
#include "hecl/HMDLMeta.hpp"
|
#include "hecl/HMDLMeta.hpp"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl::Database
|
||||||
{
|
|
||||||
namespace Database
|
|
||||||
{
|
{
|
||||||
std::vector<const struct DataSpecEntry*> DATA_SPEC_REGISTRY;
|
std::vector<const struct DataSpecEntry*> DATA_SPEC_REGISTRY;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
struct HECLWindowCallback : boo::IWindowCallback
|
struct HECLWindowCallback : boo::IWindowCallback
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user