BabeDead update for Blender 2.77 light falloff

This commit is contained in:
Jack Andersen 2016-03-27 10:43:04 -10:00
parent ee9562d7df
commit 182f519158
13 changed files with 126 additions and 39 deletions

View File

@ -49,6 +49,7 @@ void ReadBabeDeadLightToBlender(hecl::BlenderConnection::PyOutStream& os,
os.format("lamp.retro_layer = %u\n"
"lamp.retro_origtype = %u\n"
"lamp.falloff_type = 'INVERSE_COEFFICIENTS'\n"
"lamp.use_nodes = True\n"
"falloff_node = lamp.node_tree.nodes.new('ShaderNodeLightFalloff')\n"
"lamp.energy = 0.0\n"
@ -68,12 +69,15 @@ void ReadBabeDeadLightToBlender(hecl::BlenderConnection::PyOutStream& os,
case BabeDeadLight::Falloff::Constant:
os << "falloff_node.inputs[0].default_value *= 75.0\n"
"lamp.node_tree.links.new(falloff_node.outputs[2], lamp.node_tree.nodes['Emission'].inputs[1])\n";
os.format("lamp.constant_coefficient = 2.0 / %f\n", light.q);
break;
case BabeDeadLight::Falloff::Linear:
os << "lamp.node_tree.links.new(falloff_node.outputs[1], lamp.node_tree.nodes['Emission'].inputs[1])\n";
os.format("lamp.linear_coefficient = 250 / %f\n", light.q);
break;
case BabeDeadLight::Falloff::Quadratic:
os << "lamp.node_tree.links.new(falloff_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[1])\n";
os.format("lamp.quadratic_coefficient = 25000 / %f\n", light.q);
break;
default: break;
}

View File

@ -32,19 +32,20 @@ static void BoxFilter(const uint8_t* input, unsigned chanCount,
int y,x,c;
for (y=0 ; y<mipHeight ; ++y)
{
unsigned mip_line_base = mipWidth * y;
unsigned in1_line_base = inWidth * (y*2);
unsigned in2_line_base = inWidth * (y*2+1);
unsigned miplineBase = mipWidth * y;
unsigned in1LineBase = inWidth * (y*2);
unsigned in2LineBase = inWidth * (y*2+1);
for (x=0 ; x<mipWidth ; ++x)
{
uint8_t* out = &output[(mip_line_base+x)*chanCount];
uint8_t* out = &output[(miplineBase+x)*chanCount];
for (c=0 ; c<chanCount ; ++c)
{
out[c] = 0;
out[c] += input[(in1_line_base+(x*2))*chanCount+c] / 4;
out[c] += input[(in1_line_base+(x*2+1))*chanCount+c] / 4;
out[c] += input[(in2_line_base+(x*2))*chanCount+c] / 4;
out[c] += input[(in2_line_base+(x*2+1))*chanCount+c] / 4;
uint32_t tmp = 0;
tmp += input[(in1LineBase+(x*2))*chanCount+c];
tmp += input[(in1LineBase+(x*2+1))*chanCount+c];
tmp += input[(in2LineBase+(x*2))*chanCount+c];
tmp += input[(in2LineBase+(x*2+1))*chanCount+c];
out[c] = tmp / 4;
}
}
}

View File

@ -7,6 +7,7 @@
#include "Blender/BlenderSupport.hpp"
#include "BlenderConnection.hpp"
#include "DNACommon/DNACommon.hpp"
#include "DNACommon/TXTR.hpp"
#include <time.h>
@ -32,8 +33,8 @@ static const hecl::SystemChar* MomErr[] =
};
constexpr uint32_t MomErrCount = std::extent<decltype(MomErr)>::value;
SpecBase::SpecBase(hecl::Database::Project& project)
: m_project(project),
SpecBase::SpecBase(hecl::Database::Project& project, bool pc)
: m_project(project), m_pc(pc),
m_masterShader(project.getProjectWorkingPath(), ".hecl/RetroMasterShader.blend") {}
bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps)
@ -139,6 +140,32 @@ bool SpecBase::canCook(const hecl::ProjectPath& path)
return false;
}
const hecl::Database::DataSpecEntry* SpecBase::overrideDataSpec(const hecl::ProjectPath& path,
const hecl::Database::DataSpecEntry* oldEntry)
{
if (!checkPathPrefix(path))
return nullptr;
if (hecl::IsPathBlend(path))
{
hecl::BlenderConnection& conn = hecl::BlenderConnection::SharedConnection();
if (!conn.openBlend(path))
{
Log.report(logvisor::Error, _S("unable to cook '%s'"),
path.getAbsolutePath().c_str());
return nullptr;
}
hecl::BlenderConnection::BlendType type = conn.getBlendType();
if (type == hecl::BlenderConnection::BlendType::Mesh ||
type == hecl::BlenderConnection::BlendType::Area)
return oldEntry;
}
else if (hecl::IsPathPNG(path))
{
return oldEntry;
}
return getOriginalSpec();
}
void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath,
bool fast, FCookProgress progress)
{
@ -171,6 +198,13 @@ void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& co
default: break;
}
}
else if (hecl::IsPathPNG(path))
{
if (m_pc)
TXTR::CookPC(path, cookedPath);
else
TXTR::Cook(path, cookedPath);
}
else if (hecl::IsPathYAML(path))
{
FILE* fp = hecl::Fopen(path.getAbsolutePath().c_str(), _S("r"));

View File

@ -17,7 +17,10 @@ struct SpecBase : hecl::Database::IDataSpec
void doExtract(const ExtractPassInfo& info, FProgress progress);
bool canCook(const hecl::ProjectPath& path);
void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, FCookProgress progress);
const hecl::Database::DataSpecEntry* overrideDataSpec(const hecl::ProjectPath& path,
const hecl::Database::DataSpecEntry* oldEntry);
void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath,
bool fast, FCookProgress progress);
bool canPackage(const PackagePassInfo& info);
void gatherDependencies(const PackagePassInfo& info,
@ -37,6 +40,9 @@ struct SpecBase : hecl::Database::IDataSpec
virtual bool extractFromDisc(nod::DiscBase& disc, bool force,
FProgress progress)=0;
/* Even if PC spec is being cooked, this will return the vanilla GCN spec */
virtual const hecl::Database::DataSpecEntry* getOriginalSpec() const=0;
/* Basic path check (game directory matching) */
virtual bool checkPathPrefix(const hecl::ProjectPath& path)=0;
@ -48,10 +54,14 @@ struct SpecBase : hecl::Database::IDataSpec
using Mesh = BlendStream::Mesh;
using Actor = BlendStream::Actor;
virtual void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, FCookProgress progress) const=0;
virtual void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, FCookProgress progress) const=0;
virtual void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, FCookProgress progress) const=0;
virtual void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FILE* fin, FCookProgress progress) const=0;
virtual void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const=0;
virtual void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const=0;
virtual void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const=0;
virtual void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
FILE* fin, FCookProgress progress) const=0;
const hecl::ProjectPath& getMasterShaderPath() const {return m_masterShader;}
@ -62,9 +72,10 @@ struct SpecBase : hecl::Database::IDataSpec
/* Project accessor */
hecl::Database::Project& getProject() const {return m_project;}
SpecBase(hecl::Database::Project& project);
SpecBase(hecl::Database::Project& project, bool pc);
protected:
hecl::Database::Project& m_project;
bool m_pc;
hecl::ProjectPath m_masterShader;
private:
std::unique_ptr<nod::DiscBase> m_disc;

View File

@ -33,8 +33,8 @@ struct SpecMP1 : SpecBase
hecl::ProjectPath m_cookPath;
PAKRouter<DNAMP1::PAKBridge> m_pakRouter;
SpecMP1(hecl::Database::Project& project)
: SpecBase(project),
SpecMP1(hecl::Database::Project& project, bool pc)
: SpecBase(project, pc),
m_workPath(project.getProjectWorkingPath(), _S("MP1")),
m_cookPath(project.getProjectCookedPath(SpecEntMP1), _S("MP1")),
m_pakRouter(*this, m_workPath, m_cookPath) {}
@ -213,6 +213,8 @@ struct SpecMP1 : SpecBase
bool extractFromDisc(nod::DiscBase&, bool force, FProgress progress)
{
m_project.enableDataSpecs({"MP1-PC"});
nod::ExtractionContext ctx = {true, force, nullptr};
m_workPath.makeDir();
@ -267,7 +269,12 @@ struct SpecMP1 : SpecBase
return true;
}
virtual hecl::ProjectPath getWorking(class UniqueID32& id)
const hecl::Database::DataSpecEntry* getOriginalSpec() const
{
return &SpecEntMP1;
}
hecl::ProjectPath getWorking(class UniqueID32& id)
{
return m_pakRouter.getWorking(id);
}
@ -320,15 +327,20 @@ hecl::Database::DataSpecEntry SpecEntMP1 =
_S("MP1"),
_S("Data specification for original Metroid Prime engine"),
[](hecl::Database::Project& project, hecl::Database::DataSpecTool)
-> hecl::Database::IDataSpec* {return new struct SpecMP1(project);}
-> hecl::Database::IDataSpec* {return new struct SpecMP1(project, false);}
};
hecl::Database::DataSpecEntry SpecEntMP1PC =
{
_S("MP1-PC"),
_S("Data specification for PC-optimized Metroid Prime engine"),
[](hecl::Database::Project& project, hecl::Database::DataSpecTool)
-> hecl::Database::IDataSpec* {return nullptr;}
[](hecl::Database::Project& project, hecl::Database::DataSpecTool tool)
-> hecl::Database::IDataSpec*
{
if (tool != hecl::Database::DataSpecTool::Extract)
return new struct SpecMP1(project, true);
return nullptr;
}
};
}

View File

@ -29,8 +29,8 @@ struct SpecMP2 : SpecBase
hecl::ProjectPath m_cookPath;
PAKRouter<DNAMP2::PAKBridge> m_pakRouter;
SpecMP2(hecl::Database::Project& project)
: SpecBase(project),
SpecMP2(hecl::Database::Project& project, bool pc)
: SpecBase(project, pc),
m_workPath(project.getProjectWorkingPath(), _S("MP2")),
m_cookPath(project.getProjectCookedPath(SpecEntMP2), _S("MP2")),
m_pakRouter(*this, m_workPath, m_cookPath) {}
@ -257,7 +257,12 @@ struct SpecMP2 : SpecBase
return true;
}
virtual hecl::ProjectPath getWorking(class UniqueID32& id)
const hecl::Database::DataSpecEntry* getOriginalSpec() const
{
return &SpecEntMP2;
}
hecl::ProjectPath getWorking(class UniqueID32& id)
{
return m_pakRouter.getWorking(id);
}
@ -302,15 +307,20 @@ hecl::Database::DataSpecEntry SpecEntMP2
_S("MP2"),
_S("Data specification for original Metroid Prime 2 engine"),
[](hecl::Database::Project& project, hecl::Database::DataSpecTool)
-> hecl::Database::IDataSpec* {return new struct SpecMP2(project);}
-> hecl::Database::IDataSpec* {return new struct SpecMP2(project, false);}
);
hecl::Database::DataSpecEntry SpecEntMP2PC =
{
_S("MP2-PC"),
_S("Data specification for PC-optimized Metroid Prime 2 engine"),
[](hecl::Database::Project& project, hecl::Database::DataSpecTool)
-> hecl::Database::IDataSpec* {return nullptr;}
[](hecl::Database::Project& project, hecl::Database::DataSpecTool tool)
-> hecl::Database::IDataSpec*
{
if (tool != hecl::Database::DataSpecTool::Extract)
return new struct SpecMP2(project, true);
return nullptr;
}
};
}

View File

@ -42,8 +42,8 @@ struct SpecMP3 : SpecBase
hecl::ProjectPath m_feCookPath;
PAKRouter<DNAMP3::PAKBridge> m_fePakRouter;
SpecMP3(hecl::Database::Project& project)
: SpecBase(project),
SpecMP3(hecl::Database::Project& project, bool pc)
: SpecBase(project, pc),
m_workPath(project.getProjectWorkingPath(), _S("MP3")),
m_cookPath(project.getProjectCookedPath(SpecEntMP3), _S("MP3")),
m_pakRouter(*this, m_workPath, m_cookPath),
@ -439,7 +439,12 @@ struct SpecMP3 : SpecBase
return true;
}
virtual hecl::ProjectPath getWorking(class UniqueID64& id)
const hecl::Database::DataSpecEntry* getOriginalSpec() const
{
return &SpecEntMP3;
}
hecl::ProjectPath getWorking(class UniqueID64& id)
{
return m_pakRouter.getWorking(id);
}
@ -486,15 +491,20 @@ hecl::Database::DataSpecEntry SpecEntMP3
_S("MP3"),
_S("Data specification for original Metroid Prime 3 engine"),
[](hecl::Database::Project& project, hecl::Database::DataSpecTool)
-> hecl::Database::IDataSpec* {return new struct SpecMP3(project);}
-> hecl::Database::IDataSpec* {return new struct SpecMP3(project, false);}
);
hecl::Database::DataSpecEntry SpecEntMP3PC =
{
_S("MP3-PC"),
_S("Data specification for PC-optimized Metroid Prime 3 engine"),
[](hecl::Database::Project& project, hecl::Database::DataSpecTool)
-> hecl::Database::IDataSpec* {return nullptr;}
[](hecl::Database::Project& project, hecl::Database::DataSpecTool tool)
-> hecl::Database::IDataSpec*
{
if (tool != hecl::Database::DataSpecTool::Extract)
return new struct SpecMP3(project, true);
return nullptr;
}
};
}

View File

@ -8,7 +8,7 @@ static logvisor::Module Log("URDE::ProjectManager");
bool ProjectManager::m_registeredSpecs = false;
ProjectManager::ProjectManager(ViewManager &vm)
: m_vm(vm), m_objStore(m_factoryMP1)
: m_vm(vm), m_clientProc(1), m_factoryMP1(m_clientProc), m_objStore(m_factoryMP1)
{
if (!m_registeredSpecs)
{

View File

@ -18,6 +18,7 @@ class ProjectManager
ViewManager& m_vm;
std::unique_ptr<hecl::Database::Project> m_proj;
static bool m_registeredSpecs;
hecl::ClientProcess m_clientProc;
ProjectResourceFactoryMP1 m_factoryMP1;
urde::CSimplePool m_objStore;

View File

@ -1,6 +1,7 @@
#ifndef URDE_PROJECT_RESOURCE_FACTORY_BASE_HPP
#define URDE_PROJECT_RESOURCE_FACTORY_BASE_HPP
#include "hecl/ClientProcess.hpp"
#include "Runtime/IFactory.hpp"
#include "Runtime/CFactoryMgr.hpp"
#include "Runtime/CResFactory.hpp"
@ -14,6 +15,7 @@ namespace urde
class ProjectResourceFactoryBase : public urde::IFactory
{
hecl::ClientProcess& m_clientProc;
protected:
std::unordered_map<urde::SObjectTag, hecl::ProjectPath> m_tagToPath;
std::unordered_map<std::string, urde::SObjectTag> m_catalogNameToTag;
@ -52,6 +54,7 @@ protected:
const CVParamTransfer& paramXfer);
public:
ProjectResourceFactoryBase(hecl::ClientProcess& clientProc) : m_clientProc(clientProc) {}
std::unique_ptr<urde::IObj> Build(const urde::SObjectTag&, const urde::CVParamTransfer&);
void BuildAsync(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**);
void CancelBuild(const urde::SObjectTag&);

View File

@ -21,7 +21,8 @@ extern hecl::Database::DataSpecEntry SpecEntMP1PC;
namespace urde
{
ProjectResourceFactoryMP1::ProjectResourceFactoryMP1()
ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc)
: ProjectResourceFactoryBase(clientProc)
{
m_factoryMgr.AddFactory(FOURCC('TXTR'), urde::FTextureFactory);
m_factoryMgr.AddFactory(FOURCC('PART'), urde::FParticleFactory);

View File

@ -9,7 +9,7 @@ namespace urde
class ProjectResourceFactoryMP1 : public ProjectResourceFactoryBase
{
public:
ProjectResourceFactoryMP1();
ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc);
void IndexMP1Resources(const hecl::Database::Project& proj);
SObjectTag TagFromPath(const hecl::ProjectPath& path) const;
hecl::ProjectPath GetCookedPath(const SObjectTag& tag,

2
hecl

@ -1 +1 @@
Subproject commit b6be61576548e44bc5a06e58813965ddd5c5ca94
Subproject commit 50b614abd46fc59f2cd2ca0b32261263baffd2f2