mirror of https://github.com/AxioDL/metaforce.git
Updates to support VISI generation
This commit is contained in:
parent
9cf2aec5c1
commit
8c3a7da616
|
@ -11,8 +11,9 @@ bl_info = {
|
||||||
# Package import
|
# Package import
|
||||||
from . import hmdl, sact, srea, swld, mapa, mapu, frme, Nodegrid, Patching
|
from . import hmdl, sact, srea, swld, mapa, mapu, frme, Nodegrid, Patching
|
||||||
Nodegrid = Nodegrid.Nodegrid
|
Nodegrid = Nodegrid.Nodegrid
|
||||||
import bpy, os, sys
|
import bpy, os, sys, struct
|
||||||
from bpy.app.handlers import persistent
|
from bpy.app.handlers import persistent
|
||||||
|
from mathutils import Vector
|
||||||
|
|
||||||
|
|
||||||
# Appendable list allowing external addons to register additional resource types
|
# Appendable list allowing external addons to register additional resource types
|
||||||
|
@ -69,6 +70,41 @@ def add_export_type(type_tuple):
|
||||||
def command(cmdline, writepipeline, writepipebuf):
|
def command(cmdline, writepipeline, writepipebuf):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def mesh_aabb(writepipebuf):
|
||||||
|
scene = bpy.context.scene
|
||||||
|
total_min = Vector((99999.0, 99999.0, 99999.0))
|
||||||
|
total_max = Vector((-99999.0, -99999.0, -99999.0))
|
||||||
|
|
||||||
|
if bpy.context.scene.hecl_type == 'ACTOR':
|
||||||
|
sact_data = bpy.context.scene.hecl_sact_data
|
||||||
|
for subtype in sact_data.subtypes:
|
||||||
|
if subtype.linked_mesh in bpy.data.objects:
|
||||||
|
mesh = bpy.data.objects[subtype.linked_mesh]
|
||||||
|
minPt = mesh.bound_box[0]
|
||||||
|
maxPt = mesh.bound_box[6]
|
||||||
|
for comp in range(3):
|
||||||
|
if minPt[comp] < total_min[comp]:
|
||||||
|
total_min[comp] = minPt[comp]
|
||||||
|
for comp in range(3):
|
||||||
|
if maxPt[comp] > total_max[comp]:
|
||||||
|
total_max[comp] = maxPt[comp]
|
||||||
|
|
||||||
|
elif bpy.context.scene.hecl_type == 'MESH':
|
||||||
|
meshName = bpy.context.scene.hecl_mesh_obj
|
||||||
|
if meshName in bpy.data.objects:
|
||||||
|
mesh = bpy.data.objects[meshName]
|
||||||
|
minPt = mesh.bound_box[0]
|
||||||
|
maxPt = mesh.bound_box[6]
|
||||||
|
for comp in range(3):
|
||||||
|
if minPt[comp] < total_min[comp]:
|
||||||
|
total_min[comp] = minPt[comp]
|
||||||
|
for comp in range(3):
|
||||||
|
if maxPt[comp] > total_max[comp]:
|
||||||
|
total_max[comp] = maxPt[comp]
|
||||||
|
|
||||||
|
writepipebuf(struct.pack('fff', total_min[0], total_min[1], total_min[2]))
|
||||||
|
writepipebuf(struct.pack('fff', total_max[0], total_max[1], total_max[2]))
|
||||||
|
|
||||||
# Load scene callback
|
# Load scene callback
|
||||||
from bpy.app.handlers import persistent
|
from bpy.app.handlers import persistent
|
||||||
@persistent
|
@persistent
|
||||||
|
|
|
@ -25,6 +25,13 @@ def write_out_material(writebuf, mat, mesh_obj):
|
||||||
writebuf(prop[0].encode())
|
writebuf(prop[0].encode())
|
||||||
writebuf(struct.pack('i', prop[1]))
|
writebuf(struct.pack('i', prop[1]))
|
||||||
|
|
||||||
|
transparent = False
|
||||||
|
if mat.game_settings.alpha_blend == 'ALPHA' or mat.game_settings.alpha_blend == 'ALPHA_SORT':
|
||||||
|
transparent = True
|
||||||
|
elif mat.game_settings.alpha_blend == 'ADD':
|
||||||
|
transparent = True
|
||||||
|
writebuf(struct.pack('b', int(transparent)))
|
||||||
|
|
||||||
# Takes a Blender 'Mesh' object (not the datablock)
|
# Takes a Blender 'Mesh' object (not the datablock)
|
||||||
# and performs a one-shot conversion process to HMDL
|
# and performs a one-shot conversion process to HMDL
|
||||||
def cook(writebuf, mesh_obj, output_mode, max_skin_banks, max_octant_length=None):
|
def cook(writebuf, mesh_obj, output_mode, max_skin_banks, max_octant_length=None):
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import bpy
|
import bpy
|
||||||
from bpy.app.handlers import persistent
|
from bpy.app.handlers import persistent
|
||||||
|
from mathutils import Quaternion, Color
|
||||||
|
import math
|
||||||
from .. import Nodegrid
|
from .. import Nodegrid
|
||||||
|
|
||||||
# Preview update func (for lighting preview)
|
# Preview update func (for lighting preview)
|
||||||
|
@ -404,6 +406,79 @@ class SREARenderLightmaps(bpy.types.Operator):
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def shadeless_material(idx):
|
||||||
|
name = 'SHADELESS_MAT_%d' % idx
|
||||||
|
if name in bpy.data.materials:
|
||||||
|
return bpy.data.materials[name]
|
||||||
|
mat = bpy.data.materials.new(name)
|
||||||
|
mat.use_shadeless = True
|
||||||
|
r = idx % 256
|
||||||
|
g = (idx % 65536) // 256
|
||||||
|
b = idx // 65536
|
||||||
|
mat.diffuse_color = Color((r / 255.0, g / 255.0, b / 255.0))
|
||||||
|
return mat
|
||||||
|
|
||||||
|
look_forward = Quaternion((1.0, 0.0, 0.0), math.radians(90.0))
|
||||||
|
look_backward = Quaternion((0.0, 0.0, 1.0), math.radians(180.0)) * Quaternion((1.0, 0.0, 0.0), math.radians(90.0))
|
||||||
|
look_up = Quaternion((1.0, 0.0, 0.0), math.radians(180.0))
|
||||||
|
look_down = Quaternion((1.0, 0.0, 0.0), math.radians(0.0))
|
||||||
|
look_left = Quaternion((0.0, 0.0, 1.0), math.radians(90.0)) * Quaternion((1.0, 0.0, 0.0), math.radians(90.0))
|
||||||
|
look_right = Quaternion((0.0, 0.0, 1.0), math.radians(-90.0)) * Quaternion((1.0, 0.0, 0.0), math.radians(90.0))
|
||||||
|
look_list = (look_forward, look_backward, look_up, look_down, look_left, look_right)
|
||||||
|
|
||||||
|
# Render PVS for location
|
||||||
|
def render_pvs(pathOut, location):
|
||||||
|
bpy.context.scene.render.resolution_x = 256
|
||||||
|
bpy.context.scene.render.resolution_y = 256
|
||||||
|
bpy.context.scene.render.resolution_percentage = 100
|
||||||
|
bpy.context.scene.render.use_antialiasing = False
|
||||||
|
bpy.context.scene.render.use_textures = False
|
||||||
|
bpy.context.scene.render.use_shadows = False
|
||||||
|
bpy.context.scene.render.use_sss = False
|
||||||
|
bpy.context.scene.render.use_envmaps = False
|
||||||
|
bpy.context.scene.render.use_raytrace = False
|
||||||
|
bpy.context.scene.render.engine = 'BLENDER_RENDER'
|
||||||
|
bpy.context.scene.display_settings.display_device = 'None'
|
||||||
|
bpy.context.scene.render.image_settings.file_format = 'PNG'
|
||||||
|
bpy.context.scene.world.horizon_color = Color((1.0, 1.0, 1.0))
|
||||||
|
bpy.context.scene.world.zenith_color = Color((1.0, 1.0, 1.0))
|
||||||
|
|
||||||
|
cam = bpy.data.cameras.new('CUBIC_CAM')
|
||||||
|
cam_obj = bpy.data.objects.new('CUBIC_CAM', cam)
|
||||||
|
bpy.context.scene.objects.link(cam_obj)
|
||||||
|
bpy.context.scene.camera = cam_obj
|
||||||
|
cam.lens_unit = 'FOV'
|
||||||
|
cam.angle = math.radians(90.0)
|
||||||
|
|
||||||
|
mat_idx = 0
|
||||||
|
for obj in bpy.data.objects:
|
||||||
|
if obj.type == 'MESH':
|
||||||
|
if obj.name == 'CMESH':
|
||||||
|
continue
|
||||||
|
mat = shadeless_material(mat_idx)
|
||||||
|
for slot in obj.material_slots:
|
||||||
|
slot.material = mat
|
||||||
|
mat_idx += 1
|
||||||
|
|
||||||
|
cam_obj.location = location
|
||||||
|
cam_obj.rotation_mode = 'QUATERNION'
|
||||||
|
|
||||||
|
for i in range(6):
|
||||||
|
cam_obj.rotation_quaternion = look_list[i]
|
||||||
|
bpy.context.scene.render.filepath = '%s%d' % (pathOut, i)
|
||||||
|
bpy.ops.render.render(write_still=True)
|
||||||
|
|
||||||
|
bpy.context.scene.camera = None
|
||||||
|
bpy.context.scene.objects.unlink(cam_obj)
|
||||||
|
bpy.data.objects.remove(cam_obj)
|
||||||
|
bpy.data.cameras.remove(cam)
|
||||||
|
|
||||||
|
# Render PVS for light
|
||||||
|
def render_pvs_light(pathOut, lightName):
|
||||||
|
if lightName not in bpy.data.objects:
|
||||||
|
raise RuntimeError('Unable to find light %s' % lightName)
|
||||||
|
render_pvs(pathOut, bpy.data.objects[lightName].location)
|
||||||
|
|
||||||
# Cook
|
# Cook
|
||||||
def cook(writebuffunc, platform, endianchar):
|
def cook(writebuffunc, platform, endianchar):
|
||||||
print('COOKING SREA')
|
print('COOKING SREA')
|
||||||
|
|
|
@ -188,6 +188,20 @@ def dataout_loop():
|
||||||
if meshobj.type == 'MESH' and not meshobj.library:
|
if meshobj.type == 'MESH' and not meshobj.library:
|
||||||
writepipestr(meshobj.name.encode())
|
writepipestr(meshobj.name.encode())
|
||||||
|
|
||||||
|
elif cmdargs[0] == 'LIGHTLIST':
|
||||||
|
lightCount = 0
|
||||||
|
for obj in bpy.context.scene.objects:
|
||||||
|
if obj.type == 'LAMP' and not obj.library:
|
||||||
|
lightCount += 1
|
||||||
|
writepipebuf(struct.pack('I', lightCount))
|
||||||
|
for obj in bpy.context.scene.objects:
|
||||||
|
if obj.type == 'LAMP' and not obj.library:
|
||||||
|
writepipestr(obj.name.encode())
|
||||||
|
|
||||||
|
elif cmdargs[0] == 'MESHAABB':
|
||||||
|
writepipestr(b'OK')
|
||||||
|
hecl.mesh_aabb(writepipebuf)
|
||||||
|
|
||||||
elif cmdargs[0] == 'MESHCOMPILE':
|
elif cmdargs[0] == 'MESHCOMPILE':
|
||||||
maxSkinBanks = int(cmdargs[2])
|
maxSkinBanks = int(cmdargs[2])
|
||||||
|
|
||||||
|
@ -281,6 +295,7 @@ def dataout_loop():
|
||||||
0.0, 0.0, 0.0, 1.0))
|
0.0, 0.0, 0.0, 1.0))
|
||||||
writepipebuf(struct.pack('fff', ambient_color[0], ambient_color[1], ambient_color[2]))
|
writepipebuf(struct.pack('fff', ambient_color[0], ambient_color[1], ambient_color[2]))
|
||||||
writepipebuf(struct.pack('IIfffffb', 0, 0, ambient_energy, 0.0, 1.0, 0.0, 0.0, False))
|
writepipebuf(struct.pack('IIfffffb', 0, 0, ambient_energy, 0.0, 1.0, 0.0, 0.0, False))
|
||||||
|
writepipestr(b'AMBIENT')
|
||||||
|
|
||||||
for obj in bpy.context.scene.objects:
|
for obj in bpy.context.scene.objects:
|
||||||
if obj.type == 'LAMP':
|
if obj.type == 'LAMP':
|
||||||
|
@ -325,6 +340,8 @@ def dataout_loop():
|
||||||
writepipebuf(struct.pack('IIfffffb', layer, type, obj.data.energy, spotCutoff, constant, linear, quadratic,
|
writepipebuf(struct.pack('IIfffffb', layer, type, obj.data.energy, spotCutoff, constant, linear, quadratic,
|
||||||
castShadow))
|
castShadow))
|
||||||
|
|
||||||
|
writepipestr(obj.name.encode())
|
||||||
|
|
||||||
elif cmdargs[0] == 'GETTEXTURES':
|
elif cmdargs[0] == 'GETTEXTURES':
|
||||||
writepipestr(b'OK')
|
writepipestr(b'OK')
|
||||||
|
|
||||||
|
@ -386,6 +403,20 @@ def dataout_loop():
|
||||||
for c in r:
|
for c in r:
|
||||||
writepipebuf(struct.pack('f', c))
|
writepipebuf(struct.pack('f', c))
|
||||||
|
|
||||||
|
elif cmdargs[0] == 'RENDERPVS':
|
||||||
|
pathOut = cmdargs[1]
|
||||||
|
locX = float(cmdargs[2])
|
||||||
|
locY = float(cmdargs[3])
|
||||||
|
locZ = float(cmdargs[4])
|
||||||
|
hecl.srea.render_pvs(pathOut, (locX, locY, locZ))
|
||||||
|
writepipestr(b'OK')
|
||||||
|
|
||||||
|
elif cmdargs[0] == 'RENDERPVSLIGHT':
|
||||||
|
pathOut = cmdargs[1]
|
||||||
|
lightName = cmdargs[2]
|
||||||
|
hecl.srea.render_pvs_light(pathOut, lightName)
|
||||||
|
writepipestr(b'OK')
|
||||||
|
|
||||||
loaded_blend = None
|
loaded_blend = None
|
||||||
|
|
||||||
# Main exception handling
|
# Main exception handling
|
||||||
|
|
|
@ -85,6 +85,9 @@ static void AthenaExc(athena::error::Level level, const char* file,
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static hecl::SystemChar cwdbuf[1024];
|
||||||
|
hecl::SystemString ExeDir;
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
int wmain(int argc, const wchar_t** argv)
|
int wmain(int argc, const wchar_t** argv)
|
||||||
#else
|
#else
|
||||||
|
@ -138,7 +141,6 @@ int main(int argc, const char** argv)
|
||||||
/* Assemble common tool pass info */
|
/* Assemble common tool pass info */
|
||||||
ToolPassInfo info;
|
ToolPassInfo info;
|
||||||
info.pname = argv[0];
|
info.pname = argv[0];
|
||||||
hecl::SystemChar cwdbuf[1024];
|
|
||||||
if (hecl::Getcwd(cwdbuf, 1024))
|
if (hecl::Getcwd(cwdbuf, 1024))
|
||||||
{
|
{
|
||||||
info.cwd = cwdbuf;
|
info.cwd = cwdbuf;
|
||||||
|
@ -148,6 +150,13 @@ int main(int argc, const char** argv)
|
||||||
#else
|
#else
|
||||||
info.cwd += _S('/');
|
info.cwd += _S('/');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (argv[0][0] != _S('/') && argv[0][0] != _S('\\'))
|
||||||
|
ExeDir = hecl::SystemString(cwdbuf) + _S('/');
|
||||||
|
hecl::SystemString Argv0(argv[0]);
|
||||||
|
hecl::SystemString::size_type lastIdx = Argv0.find_last_of(_S("/\\"));
|
||||||
|
if (lastIdx != hecl::SystemString::npos)
|
||||||
|
ExeDir.insert(ExeDir.end(), Argv0.begin(), Argv0.begin() + lastIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Concatenate args */
|
/* Concatenate args */
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 245a39fd92da80af40dcaf5e7567ff0b4cbf9a9a
|
Subproject commit 0cc794f49d8884c30ba43b195aecdfed14062a53
|
|
@ -354,6 +354,40 @@ public:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> getLightList()
|
||||||
|
{
|
||||||
|
m_parent->_writeStr("LIGHTLIST");
|
||||||
|
uint32_t count;
|
||||||
|
m_parent->_readBuf(&count, 4);
|
||||||
|
std::vector<std::string> retval;
|
||||||
|
retval.reserve(count);
|
||||||
|
for (uint32_t i=0 ; i<count ; ++i)
|
||||||
|
{
|
||||||
|
char name[128];
|
||||||
|
m_parent->_readStr(name, 128);
|
||||||
|
retval.push_back(name);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<atVec3f, atVec3f> getMeshAABB()
|
||||||
|
{
|
||||||
|
if (m_parent->m_loadedType != BlendType::Mesh &&
|
||||||
|
m_parent->m_loadedType != BlendType::Actor)
|
||||||
|
BlenderLog.report(logvisor::Fatal, _S("%s is not a MESH or ACTOR blend"),
|
||||||
|
m_parent->m_loadedBlend.getAbsolutePath().c_str());
|
||||||
|
|
||||||
|
m_parent->_writeStr("MESHAABB");
|
||||||
|
char readBuf[256];
|
||||||
|
m_parent->_readStr(readBuf, 256);
|
||||||
|
if (strcmp(readBuf, "OK"))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "unable get AABB: %s", readBuf);
|
||||||
|
|
||||||
|
Vector3f min(*m_parent);
|
||||||
|
Vector3f max(*m_parent);
|
||||||
|
return std::make_pair(min.val, max.val);
|
||||||
|
}
|
||||||
|
|
||||||
/* Vector types with integrated stream reading constructor */
|
/* Vector types with integrated stream reading constructor */
|
||||||
struct Vector2f
|
struct Vector2f
|
||||||
{
|
{
|
||||||
|
@ -418,6 +452,7 @@ public:
|
||||||
std::string source;
|
std::string source;
|
||||||
std::vector<ProjectPath> texs;
|
std::vector<ProjectPath> texs;
|
||||||
std::unordered_map<std::string, int32_t> iprops;
|
std::unordered_map<std::string, int32_t> iprops;
|
||||||
|
bool transparent;
|
||||||
|
|
||||||
Material(BlenderConnection& conn);
|
Material(BlenderConnection& conn);
|
||||||
bool operator==(const Material& other) const
|
bool operator==(const Material& other) const
|
||||||
|
@ -653,7 +688,7 @@ public:
|
||||||
|
|
||||||
/** Intermediate lamp representation */
|
/** Intermediate lamp representation */
|
||||||
struct Light
|
struct Light
|
||||||
{
|
{
|
||||||
/* Object transform in scene */
|
/* Object transform in scene */
|
||||||
Matrix4f sceneXf;
|
Matrix4f sceneXf;
|
||||||
Vector3f color;
|
Vector3f color;
|
||||||
|
@ -675,6 +710,8 @@ public:
|
||||||
float quadratic;
|
float quadratic;
|
||||||
bool shadow;
|
bool shadow;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
|
||||||
Light(BlenderConnection& conn);
|
Light(BlenderConnection& conn);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -814,6 +851,9 @@ public:
|
||||||
inline const atVec3f& operator[](size_t idx) const {return m[idx];}
|
inline const atVec3f& operator[](size_t idx) const {return m[idx];}
|
||||||
};
|
};
|
||||||
std::unordered_map<std::string, Matrix3f> getBoneMatrices(const std::string& name);
|
std::unordered_map<std::string, Matrix3f> getBoneMatrices(const std::string& name);
|
||||||
|
|
||||||
|
bool renderPvs(const std::string& path, const atVec3f& location);
|
||||||
|
bool renderPvsLight(const std::string& path, const std::string& lightName);
|
||||||
};
|
};
|
||||||
DataStream beginData()
|
DataStream beginData()
|
||||||
{
|
{
|
||||||
|
|
|
@ -264,6 +264,10 @@ static inline bool IsAbsolute(const SystemString& path)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SystemChar* GetTmpDir();
|
||||||
|
|
||||||
|
int RunProcess(const SystemChar* path, const SystemChar* const args[]);
|
||||||
|
|
||||||
enum class FileLockType
|
enum class FileLockType
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
|
@ -237,16 +237,11 @@ BlenderConnection::BlenderConnection(int verbosityLevel)
|
||||||
BlenderLog.report(logvisor::Info, "Establishing BlenderConnection...");
|
BlenderLog.report(logvisor::Info, "Establishing BlenderConnection...");
|
||||||
|
|
||||||
/* Put hecl_blendershell.py in temp dir */
|
/* Put hecl_blendershell.py in temp dir */
|
||||||
|
const SystemChar* TMPDIR = GetTmpDir();
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
wchar_t* TMPDIR = _wgetenv(L"TEMP");
|
|
||||||
if (!TMPDIR)
|
|
||||||
TMPDIR = (wchar_t*)L"\\Temp";
|
|
||||||
m_startupBlend = hecl::WideToUTF8(TMPDIR);
|
m_startupBlend = hecl::WideToUTF8(TMPDIR);
|
||||||
#else
|
#else
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
char* TMPDIR = getenv("TMPDIR");
|
|
||||||
if (!TMPDIR)
|
|
||||||
TMPDIR = (char*)"/tmp";
|
|
||||||
m_startupBlend = TMPDIR;
|
m_startupBlend = TMPDIR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -905,6 +900,8 @@ BlenderConnection::DataStream::Mesh::Material::Material
|
||||||
conn._readBuf(&val, 4);
|
conn._readBuf(&val, 4);
|
||||||
iprops[readStr] = val;
|
iprops[readStr] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conn._readBuf(&transparent, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlenderConnection::DataStream::Mesh::Surface::Surface
|
BlenderConnection::DataStream::Mesh::Surface::Surface
|
||||||
|
@ -1088,6 +1085,14 @@ BlenderConnection::DataStream::Light::Light(BlenderConnection& conn)
|
||||||
: sceneXf(conn), color(conn)
|
: sceneXf(conn), color(conn)
|
||||||
{
|
{
|
||||||
conn._readBuf(&layer, 29);
|
conn._readBuf(&layer, 29);
|
||||||
|
|
||||||
|
uint32_t nameLen;
|
||||||
|
conn._readBuf(&nameLen, 4);
|
||||||
|
if (nameLen)
|
||||||
|
{
|
||||||
|
name.assign(nameLen, '\0');
|
||||||
|
conn._readBuf(&name[0], nameLen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BlenderConnection::DataStream::Actor::Actor(BlenderConnection& conn)
|
BlenderConnection::DataStream::Actor::Actor(BlenderConnection& conn)
|
||||||
|
@ -1662,6 +1667,51 @@ BlenderConnection::DataStream::getBoneMatrices(const std::string& name)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BlenderConnection::DataStream::renderPvs(const std::string& path, const atVec3f& location)
|
||||||
|
{
|
||||||
|
if (path.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
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[256];
|
||||||
|
snprintf(req, 256, "RENDERPVS %s %f %f %f", path.c_str(),
|
||||||
|
location.vec[0], location.vec[1], location.vec[2]);
|
||||||
|
m_parent->_writeStr(req);
|
||||||
|
|
||||||
|
char readBuf[256];
|
||||||
|
m_parent->_readStr(readBuf, 256);
|
||||||
|
if (strcmp(readBuf, "OK"))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "unable to render PVS for: %s; %s",
|
||||||
|
m_parent->m_loadedBlend.getAbsolutePath().c_str(), readBuf);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BlenderConnection::DataStream::renderPvsLight(const std::string& path, const std::string& lightName)
|
||||||
|
{
|
||||||
|
if (path.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
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[256];
|
||||||
|
snprintf(req, 256, "RENDERPVSLIGHT %s %s", path.c_str(), lightName.c_str());
|
||||||
|
m_parent->_writeStr(req);
|
||||||
|
|
||||||
|
char readBuf[256];
|
||||||
|
m_parent->_readStr(readBuf, 256);
|
||||||
|
if (strcmp(readBuf, "OK"))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "unable to render PVS light %s for: %s; %s", lightName.c_str(),
|
||||||
|
m_parent->m_loadedBlend.getAbsolutePath().c_str(), readBuf);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void BlenderConnection::quitBlender()
|
void BlenderConnection::quitBlender()
|
||||||
{
|
{
|
||||||
char lineBuf[256];
|
char lineBuf[256];
|
||||||
|
|
|
@ -744,4 +744,37 @@ int RecursiveMakeDir(const SystemChar* dir) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const SystemChar* GetTmpDir()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
wchar_t* TMPDIR = _wgetenv(L"TEMP");
|
||||||
|
if (!TMPDIR)
|
||||||
|
TMPDIR = (wchar_t*)L"\\Temp";
|
||||||
|
#else
|
||||||
|
char* TMPDIR = getenv("TMPDIR");
|
||||||
|
if (!TMPDIR)
|
||||||
|
TMPDIR = (char*)"/tmp";
|
||||||
|
#endif
|
||||||
|
return TMPDIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RunProcess(const SystemChar* path, const SystemChar* const args[])
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
#else
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (!pid)
|
||||||
|
{
|
||||||
|
execvp(path, (char * const *)args);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
int ret;
|
||||||
|
if (waitpid(pid, &ret, 0) < 0)
|
||||||
|
return -1;
|
||||||
|
if (WIFEXITED(ret))
|
||||||
|
return WEXITSTATUS(ret);
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue