mirror of https://github.com/AxioDL/metaforce.git
Additional BlenderConnection interfaces
This commit is contained in:
parent
761be432be
commit
51822eec94
|
@ -369,6 +369,30 @@ BlenderConnection::~BlenderConnection()
|
||||||
_closePipe();
|
_closePipe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::streambuf::int_type
|
||||||
|
BlenderConnection::PyOutStream::StreamBuf::overflow(int_type ch)
|
||||||
|
{
|
||||||
|
if (!m_parent.m_parent || !m_parent.m_parent->m_lock)
|
||||||
|
BlenderLog.report(logvisor::Fatal, "lock not held for PyOutStream writing");
|
||||||
|
if (ch != traits_type::eof() && ch != '\n' && ch != '\0')
|
||||||
|
{
|
||||||
|
m_lineBuf += char_type(ch);
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
//printf("FLUSHING %s\n", m_lineBuf.c_str());
|
||||||
|
m_parent.m_parent->_writeLine(m_lineBuf.c_str());
|
||||||
|
char readBuf[16];
|
||||||
|
m_parent.m_parent->_readLine(readBuf, 16);
|
||||||
|
if (strcmp(readBuf, "OK"))
|
||||||
|
{
|
||||||
|
if (m_deleteOnError)
|
||||||
|
m_parent.m_parent->deleteBlend();
|
||||||
|
BlenderLog.report(logvisor::Fatal, "error sending '%s' to blender", m_lineBuf.c_str());
|
||||||
|
}
|
||||||
|
m_lineBuf.clear();
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* BlendTypeStrs[] =
|
static const char* BlendTypeStrs[] =
|
||||||
{
|
{
|
||||||
"NONE",
|
"NONE",
|
||||||
|
@ -956,6 +980,204 @@ BlenderConnection::DataStream::Actor::Action::Channel::Key::Key(BlenderConnectio
|
||||||
scale.read(conn);
|
scale.read(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlenderConnection::DataStream::Mesh
|
||||||
|
BlenderConnection::DataStream::compileMesh(HMDLTopology topology,
|
||||||
|
int skinSlotCount,
|
||||||
|
Mesh::SurfProgFunc surfProg)
|
||||||
|
{
|
||||||
|
if (m_parent->m_loadedType != BlendType::Mesh)
|
||||||
|
BlenderLog.report(logvisor::Fatal, _S("%s is not a MESH blend"),
|
||||||
|
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
||||||
|
|
||||||
|
char req[128];
|
||||||
|
snprintf(req, 128, "MESHCOMPILE %s %d",
|
||||||
|
MeshOutputModeString(topology), skinSlotCount);
|
||||||
|
m_parent->_writeLine(req);
|
||||||
|
|
||||||
|
char readBuf[256];
|
||||||
|
m_parent->_readLine(readBuf, 256);
|
||||||
|
if (strcmp(readBuf, "OK"))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "unable to cook mesh: %s", readBuf);
|
||||||
|
|
||||||
|
return Mesh(*m_parent, topology, skinSlotCount, surfProg);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlenderConnection::DataStream::Mesh
|
||||||
|
BlenderConnection::DataStream::compileMesh(const std::string& name,
|
||||||
|
HMDLTopology topology,
|
||||||
|
int skinSlotCount,
|
||||||
|
Mesh::SurfProgFunc surfProg)
|
||||||
|
{
|
||||||
|
if (m_parent->m_loadedType != BlendType::Area)
|
||||||
|
BlenderLog.report(logvisor::Fatal, _S("%s is not an AREA blend"),
|
||||||
|
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
||||||
|
|
||||||
|
char req[128];
|
||||||
|
snprintf(req, 128, "MESHCOMPILENAME %s %s %d", name.c_str(),
|
||||||
|
MeshOutputModeString(topology), skinSlotCount);
|
||||||
|
m_parent->_writeLine(req);
|
||||||
|
|
||||||
|
char readBuf[256];
|
||||||
|
m_parent->_readLine(readBuf, 256);
|
||||||
|
if (strcmp(readBuf, "OK"))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "unable to cook mesh '%s': %s", name.c_str(), readBuf);
|
||||||
|
|
||||||
|
return Mesh(*m_parent, topology, skinSlotCount, surfProg);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlenderConnection::DataStream::Mesh
|
||||||
|
BlenderConnection::DataStream::compileAllMeshes(HMDLTopology topology,
|
||||||
|
int skinSlotCount,
|
||||||
|
float maxOctantLength,
|
||||||
|
Mesh::SurfProgFunc surfProg)
|
||||||
|
{
|
||||||
|
if (m_parent->m_loadedType != BlendType::Area)
|
||||||
|
BlenderLog.report(logvisor::Fatal, _S("%s is not an AREA blend"),
|
||||||
|
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
||||||
|
|
||||||
|
char req[128];
|
||||||
|
snprintf(req, 128, "MESHCOMPILEALL %s %d %f",
|
||||||
|
MeshOutputModeString(topology),
|
||||||
|
skinSlotCount, maxOctantLength);
|
||||||
|
m_parent->_writeLine(req);
|
||||||
|
|
||||||
|
char readBuf[256];
|
||||||
|
m_parent->_readLine(readBuf, 256);
|
||||||
|
if (strcmp(readBuf, "OK"))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "unable to cook all meshes: %s", readBuf);
|
||||||
|
|
||||||
|
return Mesh(*m_parent, topology, skinSlotCount, surfProg);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlenderConnection::DataStream::Actor BlenderConnection::DataStream::compileActor()
|
||||||
|
{
|
||||||
|
if (m_parent->m_loadedType != BlendType::Actor)
|
||||||
|
BlenderLog.report(logvisor::Fatal, _S("%s is not an ACTOR blend"),
|
||||||
|
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
||||||
|
|
||||||
|
m_parent->_writeLine("ACTORCOMPILE");
|
||||||
|
|
||||||
|
char readBuf[256];
|
||||||
|
m_parent->_readLine(readBuf, 256);
|
||||||
|
if (strcmp(readBuf, "OK"))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "unable to compile actor: %s", readBuf);
|
||||||
|
|
||||||
|
return Actor(*m_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> BlenderConnection::DataStream::getArmatureNames()
|
||||||
|
{
|
||||||
|
if (m_parent->m_loadedType != BlendType::Actor)
|
||||||
|
BlenderLog.report(logvisor::Fatal, _S("%s is not an ACTOR blend"),
|
||||||
|
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
||||||
|
|
||||||
|
m_parent->_writeLine("GETARMATURENAMES");
|
||||||
|
|
||||||
|
char readBuf[256];
|
||||||
|
m_parent->_readLine(readBuf, 256);
|
||||||
|
if (strcmp(readBuf, "OK"))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "unable to get armatures of actor: %s", readBuf);
|
||||||
|
|
||||||
|
std::vector<std::string> ret;
|
||||||
|
|
||||||
|
uint32_t armCount;
|
||||||
|
m_parent->_readBuf(&armCount, 4);
|
||||||
|
ret.reserve(armCount);
|
||||||
|
for (uint32_t i=0 ; i<armCount ; ++i)
|
||||||
|
{
|
||||||
|
ret.emplace_back();
|
||||||
|
std::string& name = ret.back();
|
||||||
|
uint32_t bufSz;
|
||||||
|
m_parent->_readBuf(&bufSz, 4);
|
||||||
|
name.assign(bufSz, ' ');
|
||||||
|
m_parent->_readBuf(&name[0], bufSz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> BlenderConnection::DataStream::getActionNames()
|
||||||
|
{
|
||||||
|
if (m_parent->m_loadedType != BlendType::Actor)
|
||||||
|
BlenderLog.report(logvisor::Fatal, _S("%s is not an ACTOR blend"),
|
||||||
|
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
||||||
|
|
||||||
|
m_parent->_writeLine("GETACTIONNAMES");
|
||||||
|
|
||||||
|
char readBuf[256];
|
||||||
|
m_parent->_readLine(readBuf, 256);
|
||||||
|
if (strcmp(readBuf, "OK"))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "unable to get actions of actor: %s", readBuf);
|
||||||
|
|
||||||
|
std::vector<std::string> ret;
|
||||||
|
|
||||||
|
uint32_t actCount;
|
||||||
|
m_parent->_readBuf(&actCount, 4);
|
||||||
|
ret.reserve(actCount);
|
||||||
|
for (uint32_t i=0 ; i<actCount ; ++i)
|
||||||
|
{
|
||||||
|
ret.emplace_back();
|
||||||
|
std::string& name = ret.back();
|
||||||
|
uint32_t bufSz;
|
||||||
|
m_parent->_readBuf(&bufSz, 4);
|
||||||
|
name.assign(bufSz, ' ');
|
||||||
|
m_parent->_readBuf(&name[0], bufSz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, BlenderConnection::DataStream::Matrix3f>
|
||||||
|
BlenderConnection::DataStream::getBoneMatrices(const std::string& name)
|
||||||
|
{
|
||||||
|
if (name.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (m_parent->m_loadedType != BlendType::Actor)
|
||||||
|
BlenderLog.report(logvisor::Fatal, _S("%s is not an ACTOR blend"),
|
||||||
|
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
||||||
|
|
||||||
|
char req[128];
|
||||||
|
snprintf(req, 128, "GETBONEMATRICES %s", name.c_str());
|
||||||
|
m_parent->_writeLine(req);
|
||||||
|
|
||||||
|
char readBuf[256];
|
||||||
|
m_parent->_readLine(readBuf, 256);
|
||||||
|
if (strcmp(readBuf, "OK"))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "unable to get matrices of armature: %s", readBuf);
|
||||||
|
|
||||||
|
std::unordered_map<std::string, Matrix3f> ret;
|
||||||
|
|
||||||
|
uint32_t boneCount;
|
||||||
|
m_parent->_readBuf(&boneCount, 4);
|
||||||
|
ret.reserve(boneCount);
|
||||||
|
for (uint32_t i=0 ; i<boneCount ; ++i)
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
uint32_t bufSz;
|
||||||
|
m_parent->_readBuf(&bufSz, 4);
|
||||||
|
name.assign(bufSz, ' ');
|
||||||
|
m_parent->_readBuf(&name[0], bufSz);
|
||||||
|
|
||||||
|
Matrix3f matOut;
|
||||||
|
for (int i=0 ; i<3 ; ++i)
|
||||||
|
{
|
||||||
|
for (int j=0 ; j<3 ; ++j)
|
||||||
|
{
|
||||||
|
float val;
|
||||||
|
m_parent->_readBuf(&val, 4);
|
||||||
|
matOut[i].vec[j] = val;
|
||||||
|
}
|
||||||
|
reinterpret_cast<atVec4f&>(matOut[i]).vec[3] = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.emplace(std::make_pair(std::move(name), std::move(matOut)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void BlenderConnection::quitBlender()
|
void BlenderConnection::quitBlender()
|
||||||
{
|
{
|
||||||
_writeLine("QUIT");
|
_writeLine("QUIT");
|
||||||
|
|
|
@ -97,28 +97,7 @@ public:
|
||||||
: m_parent(parent), m_deleteOnError(deleteOnError) {}
|
: m_parent(parent), m_deleteOnError(deleteOnError) {}
|
||||||
StreamBuf(const StreamBuf& other) = delete;
|
StreamBuf(const StreamBuf& other) = delete;
|
||||||
StreamBuf(StreamBuf&& other) = default;
|
StreamBuf(StreamBuf&& other) = default;
|
||||||
int_type overflow(int_type ch)
|
int_type overflow(int_type ch);
|
||||||
{
|
|
||||||
if (!m_parent.m_parent || !m_parent.m_parent->m_lock)
|
|
||||||
BlenderLog.report(logvisor::Fatal, "lock not held for PyOutStream writing");
|
|
||||||
if (ch != traits_type::eof() && ch != '\n' && ch != '\0')
|
|
||||||
{
|
|
||||||
m_lineBuf += char_type(ch);
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
//printf("FLUSHING %s\n", m_lineBuf.c_str());
|
|
||||||
m_parent.m_parent->_writeLine(m_lineBuf.c_str());
|
|
||||||
char readBuf[16];
|
|
||||||
m_parent.m_parent->_readLine(readBuf, 16);
|
|
||||||
if (strcmp(readBuf, "OK"))
|
|
||||||
{
|
|
||||||
if (m_deleteOnError)
|
|
||||||
m_parent.m_parent->deleteBlend();
|
|
||||||
BlenderLog.report(logvisor::Fatal, "error sending '%s' to blender", m_lineBuf.c_str());
|
|
||||||
}
|
|
||||||
m_lineBuf.clear();
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
} m_sbuf;
|
} m_sbuf;
|
||||||
PyOutStream(BlenderConnection* parent, bool deleteOnError)
|
PyOutStream(BlenderConnection* parent, bool deleteOnError)
|
||||||
: std::ostream(&m_sbuf),
|
: std::ostream(&m_sbuf),
|
||||||
|
@ -532,67 +511,15 @@ public:
|
||||||
|
|
||||||
/** Compile mesh by context (MESH blends only) */
|
/** Compile mesh by context (MESH blends only) */
|
||||||
Mesh compileMesh(HMDLTopology topology, int skinSlotCount=10,
|
Mesh compileMesh(HMDLTopology topology, int skinSlotCount=10,
|
||||||
Mesh::SurfProgFunc surfProg=[](int){})
|
Mesh::SurfProgFunc surfProg=[](int){});
|
||||||
{
|
|
||||||
if (m_parent->m_loadedType != BlendType::Mesh)
|
|
||||||
BlenderLog.report(logvisor::Fatal, _S("%s is not a MESH blend"),
|
|
||||||
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
|
||||||
|
|
||||||
char req[128];
|
|
||||||
snprintf(req, 128, "MESHCOMPILE %s %d",
|
|
||||||
MeshOutputModeString(topology), skinSlotCount);
|
|
||||||
m_parent->_writeLine(req);
|
|
||||||
|
|
||||||
char readBuf[256];
|
|
||||||
m_parent->_readLine(readBuf, 256);
|
|
||||||
if (strcmp(readBuf, "OK"))
|
|
||||||
BlenderLog.report(logvisor::Fatal, "unable to cook mesh: %s", readBuf);
|
|
||||||
|
|
||||||
return Mesh(*m_parent, topology, skinSlotCount, surfProg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Compile mesh by name (AREA blends only) */
|
/** Compile mesh by name (AREA blends only) */
|
||||||
Mesh compileMesh(const std::string& name, HMDLTopology topology, int skinSlotCount=10,
|
Mesh compileMesh(const std::string& name, HMDLTopology topology, int skinSlotCount=10,
|
||||||
Mesh::SurfProgFunc surfProg=[](int){})
|
Mesh::SurfProgFunc surfProg=[](int){});
|
||||||
{
|
|
||||||
if (m_parent->m_loadedType != BlendType::Area)
|
|
||||||
BlenderLog.report(logvisor::Fatal, _S("%s is not an AREA blend"),
|
|
||||||
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
|
||||||
|
|
||||||
char req[128];
|
|
||||||
snprintf(req, 128, "MESHCOMPILENAME %s %s %d", name.c_str(),
|
|
||||||
MeshOutputModeString(topology), skinSlotCount);
|
|
||||||
m_parent->_writeLine(req);
|
|
||||||
|
|
||||||
char readBuf[256];
|
|
||||||
m_parent->_readLine(readBuf, 256);
|
|
||||||
if (strcmp(readBuf, "OK"))
|
|
||||||
BlenderLog.report(logvisor::Fatal, "unable to cook mesh '%s': %s", name.c_str(), readBuf);
|
|
||||||
|
|
||||||
return Mesh(*m_parent, topology, skinSlotCount, surfProg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Compile all meshes into one (AREA blends only) */
|
/** Compile all meshes into one (AREA blends only) */
|
||||||
Mesh compileAllMeshes(HMDLTopology topology, int skinSlotCount=10, float maxOctantLength=5.0,
|
Mesh compileAllMeshes(HMDLTopology topology, int skinSlotCount=10, float maxOctantLength=5.0,
|
||||||
Mesh::SurfProgFunc surfProg=[](int){})
|
Mesh::SurfProgFunc surfProg=[](int){});
|
||||||
{
|
|
||||||
if (m_parent->m_loadedType != BlendType::Area)
|
|
||||||
BlenderLog.report(logvisor::Fatal, _S("%s is not an AREA blend"),
|
|
||||||
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
|
||||||
|
|
||||||
char req[128];
|
|
||||||
snprintf(req, 128, "MESHCOMPILEALL %s %d %f",
|
|
||||||
MeshOutputModeString(topology),
|
|
||||||
skinSlotCount, maxOctantLength);
|
|
||||||
m_parent->_writeLine(req);
|
|
||||||
|
|
||||||
char readBuf[256];
|
|
||||||
m_parent->_readLine(readBuf, 256);
|
|
||||||
if (strcmp(readBuf, "OK"))
|
|
||||||
BlenderLog.report(logvisor::Fatal, "unable to cook all meshes: %s", readBuf);
|
|
||||||
|
|
||||||
return Mesh(*m_parent, topology, skinSlotCount, surfProg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Intermediate actor representation prepared by blender from a single HECL actor blend */
|
/** Intermediate actor representation prepared by blender from a single HECL actor blend */
|
||||||
struct Actor
|
struct Actor
|
||||||
|
@ -681,83 +608,17 @@ public:
|
||||||
Actor(BlenderConnection& conn);
|
Actor(BlenderConnection& conn);
|
||||||
};
|
};
|
||||||
|
|
||||||
Actor compileActor()
|
Actor compileActor();
|
||||||
|
std::vector<std::string> getArmatureNames();
|
||||||
|
std::vector<std::string> getActionNames();
|
||||||
|
|
||||||
|
struct Matrix3f
|
||||||
{
|
{
|
||||||
if (m_parent->m_loadedType != BlendType::Actor)
|
atVec3f m[3];
|
||||||
BlenderLog.report(logvisor::Fatal, _S("%s is not an ACTOR blend"),
|
inline atVec3f& operator[](size_t idx) {return m[idx];}
|
||||||
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
inline const atVec3f& operator[](size_t idx) const {return m[idx];}
|
||||||
|
};
|
||||||
m_parent->_writeLine("ACTORCOMPILE");
|
std::unordered_map<std::string, Matrix3f> getBoneMatrices(const std::string& name);
|
||||||
|
|
||||||
char readBuf[256];
|
|
||||||
m_parent->_readLine(readBuf, 256);
|
|
||||||
if (strcmp(readBuf, "OK"))
|
|
||||||
BlenderLog.report(logvisor::Fatal, "unable to compile actor: %s", readBuf);
|
|
||||||
|
|
||||||
return Actor(*m_parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> getArmatureNames()
|
|
||||||
{
|
|
||||||
if (m_parent->m_loadedType != BlendType::Actor)
|
|
||||||
BlenderLog.report(logvisor::Fatal, _S("%s is not an ACTOR blend"),
|
|
||||||
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
|
||||||
|
|
||||||
m_parent->_writeLine("GETARMATURENAMES");
|
|
||||||
|
|
||||||
char readBuf[256];
|
|
||||||
m_parent->_readLine(readBuf, 256);
|
|
||||||
if (strcmp(readBuf, "OK"))
|
|
||||||
BlenderLog.report(logvisor::Fatal, "unable to get armatures of actor: %s", readBuf);
|
|
||||||
|
|
||||||
std::vector<std::string> ret;
|
|
||||||
|
|
||||||
uint32_t armCount;
|
|
||||||
m_parent->_readBuf(&armCount, 4);
|
|
||||||
ret.reserve(armCount);
|
|
||||||
for (uint32_t i=0 ; i<armCount ; ++i)
|
|
||||||
{
|
|
||||||
ret.emplace_back();
|
|
||||||
std::string& name = ret.back();
|
|
||||||
uint32_t bufSz;
|
|
||||||
m_parent->_readBuf(&bufSz, 4);
|
|
||||||
name.assign(bufSz, ' ');
|
|
||||||
m_parent->_readBuf(&name[0], bufSz);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> getActionNames()
|
|
||||||
{
|
|
||||||
if (m_parent->m_loadedType != BlendType::Actor)
|
|
||||||
BlenderLog.report(logvisor::Fatal, _S("%s is not an ACTOR blend"),
|
|
||||||
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
|
||||||
|
|
||||||
m_parent->_writeLine("GETACTIONNAMES");
|
|
||||||
|
|
||||||
char readBuf[256];
|
|
||||||
m_parent->_readLine(readBuf, 256);
|
|
||||||
if (strcmp(readBuf, "OK"))
|
|
||||||
BlenderLog.report(logvisor::Fatal, "unable to get actions of actor: %s", readBuf);
|
|
||||||
|
|
||||||
std::vector<std::string> ret;
|
|
||||||
|
|
||||||
uint32_t actCount;
|
|
||||||
m_parent->_readBuf(&actCount, 4);
|
|
||||||
ret.reserve(actCount);
|
|
||||||
for (uint32_t i=0 ; i<actCount ; ++i)
|
|
||||||
{
|
|
||||||
ret.emplace_back();
|
|
||||||
std::string& name = ret.back();
|
|
||||||
uint32_t bufSz;
|
|
||||||
m_parent->_readBuf(&bufSz, 4);
|
|
||||||
name.assign(bufSz, ' ');
|
|
||||||
m_parent->_readBuf(&name[0], bufSz);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
DataStream beginData()
|
DataStream beginData()
|
||||||
{
|
{
|
||||||
|
|
|
@ -197,6 +197,27 @@ def dataout_loop():
|
||||||
writepipeline(b'OK')
|
writepipeline(b'OK')
|
||||||
hecl.sact.get_action_names(writepipebuf)
|
hecl.sact.get_action_names(writepipebuf)
|
||||||
|
|
||||||
|
elif cmdargs[0] == 'GETBONEMATRICES':
|
||||||
|
armName = cmdargs[1]
|
||||||
|
|
||||||
|
if armName not in bpy.data.objects:
|
||||||
|
writepipeline(('armature %s not found' % armName).encode())
|
||||||
|
continue
|
||||||
|
|
||||||
|
armObj = bpy.data.objects[armName]
|
||||||
|
if armObj.type != 'ARMATURE':
|
||||||
|
writepipeline(('object %s not an ARMATURE' % armName).encode())
|
||||||
|
continue
|
||||||
|
|
||||||
|
writepipeline(b'OK')
|
||||||
|
writepipebuf(struct.pack('I', len(armObj.data.bones)))
|
||||||
|
for bone in armObj.data.bones:
|
||||||
|
writepipebuf(struct.pack('I', len(bone.name)))
|
||||||
|
writepipebuf(bone.name.encode())
|
||||||
|
for r in bone.matrix:
|
||||||
|
for c in r:
|
||||||
|
writepipebuf(struct.pack('f', c))
|
||||||
|
|
||||||
|
|
||||||
# Command loop
|
# Command loop
|
||||||
while True:
|
while True:
|
||||||
|
|
Loading…
Reference in New Issue