From 63e835daaaf2749559fa9d6f2eb333623c505488 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Thu, 11 Aug 2016 09:51:41 -1000 Subject: [PATCH] Add BlenderConnection::compileLights --- hecl/blender/BlenderConnection.cpp | 31 +++++++++++++ hecl/blender/BlenderConnection.hpp | 29 ++++++++++++ hecl/blender/hecl_blendershell.py | 71 ++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+) diff --git a/hecl/blender/BlenderConnection.cpp b/hecl/blender/BlenderConnection.cpp index 11e63354f..65849c175 100644 --- a/hecl/blender/BlenderConnection.cpp +++ b/hecl/blender/BlenderConnection.cpp @@ -919,6 +919,12 @@ BlenderConnection::DataStream::ColMesh::Triangle::Triangle(BlenderConnection& co conn._readBuf(this, 16); } +BlenderConnection::DataStream::Light::Light(BlenderConnection& conn) +: sceneXf(conn), color(conn) +{ + conn._readBuf(&layer, 29); +} + BlenderConnection::DataStream::Actor::Actor(BlenderConnection& conn) { uint32_t armCount; @@ -1175,6 +1181,31 @@ BlenderConnection::DataStream::compileAllMeshes(HMDLTopology topology, return Mesh(*m_parent, topology, skinSlotCount, surfProg); } +std::vector BlenderConnection::DataStream::compileLights() +{ + 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()); + + m_parent->_writeLine("LIGHTCOMPILEALL"); + + char readBuf[256]; + m_parent->_readLine(readBuf, 256); + if (strcmp(readBuf, "OK")) + BlenderLog.report(logvisor::Fatal, "unable to gather all lights: %s", readBuf); + + uint32_t lightCount; + m_parent->_readBuf(&lightCount, 4); + + std::vector ret; + ret.reserve(lightCount); + + for (int i=0 ; im_loadedType != BlendType::Actor) diff --git a/hecl/blender/BlenderConnection.hpp b/hecl/blender/BlenderConnection.hpp index e74d84912..eb7df41b7 100644 --- a/hecl/blender/BlenderConnection.hpp +++ b/hecl/blender/BlenderConnection.hpp @@ -563,6 +563,32 @@ public: ColMesh(BlenderConnection& 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; + + Light(BlenderConnection& conn); + }; static const char* MeshOutputModeString(HMDLTopology topology) { @@ -586,6 +612,9 @@ public: Mesh compileAllMeshes(HMDLTopology topology, int skinSlotCount=10, float maxOctantLength=5.0, Mesh::SurfProgFunc surfProg=[](int){}); + /** Gather all lights in scene (AREA blends only) */ + std::vector compileLights(); + /** Intermediate actor representation prepared by blender from a single HECL actor blend */ struct Actor { diff --git a/hecl/blender/hecl_blendershell.py b/hecl/blender/hecl_blendershell.py index dcdb56d8e..2ec395da0 100644 --- a/hecl/blender/hecl_blendershell.py +++ b/hecl/blender/hecl_blendershell.py @@ -211,6 +211,77 @@ def dataout_loop(): bpy.data.objects.remove(join_obj) bpy.data.meshes.remove(join_mesh) + elif cmdargs[0] == 'LIGHTCOMPILEALL': + writepipeline(b'OK') + lampCount = 0; + for obj in bpy.context.scene: + if obj.type == 'LAMP': + lampCount += 1 + + world = bpy.context.scene.world + ambient_energy = 0.0 + ambient_color = None + if world.use_nodes and 'Background' in world.node_tree.nodes: + bg_node = world.node_tree.nodes['Background'] + ambient_energy = bg_node.inputs[1].default_value + ambient_color = bg_node.inputs[0].default_value + if ambient_energy: + lampCount += 1 + + writepipebuf(struct.pack('I', lampCount)) + + if ambient_energy: + writepipebuf(struct.pack('ffffffffffffffff', + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.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('IIfffffb', 0, 0, ambient_energy, 0.0, 1.0, 0.0, 0.0, False) + + for obj in bpy.context.scene: + if obj.type == 'LAMP': + wmtx = obj.matrix_world + writepipebuf(struct.pack('ffffffffffffffff', + wmtx[0][0], wmtx[0][1], wmtx[0][2], wmtx[0][3], + wmtx[1][0], wmtx[1][1], wmtx[1][2], wmtx[1][3], + wmtx[2][0], wmtx[2][1], wmtx[2][2], wmtx[2][3], + wmtx[3][0], wmtx[3][1], wmtx[3][2], wmtx[3][3])) + writepipebuf(struct.pack('fff', obj.data.color[0], obj.data.color[1], obj.data.color[2])) + + type = 2 + spotCutoff = 0.0 + hasFalloff = False + castShadow = False + if obj.data.type == 'POINT': + type = 2 + hasFalloff = True + castShadow = obj.data.shadow_method != 'NOSHADOW' + elif obj.data.type == 'SPOT': + type = 3 + hasFalloff = True + spotCutoff = obj.data.spot_size + castShadow = obj.data.shadow_method != 'NOSHADOW' + elif obj.data.type == 'SUN': + type = 1 + castShadow = obj.data.shadow_method != 'NOSHADOW' + + constant = 1.0 + linear = 0.0 + quadratic = 0.0 + if hasFalloff: + if obj.data.falloff_type == 'INVERSE_COEFFICIENTS': + constant = obj.data.constant_coefficient + linear = obj.data.linear_coefficient + quadratic = obj.data.quadratic_coefficient + + layer = 0 + if 'retro_layer' in obj.data.keys(): + layer = obj.data['retro_layer'] + + writepipebuf(struct.pack('IIfffffb', layer, type, obj.data.energy, spotCutoff, constant, linear, quadratic, + castShadow) + elif cmdargs[0] == 'ACTORCOMPILE': writepipeline(b'OK') hecl.sact.cook(writepipebuf)