Implement world cooker

This commit is contained in:
Jack Andersen 2016-10-01 13:18:52 -10:00
parent b3b0b7cd46
commit 4f53d886ce
6 changed files with 158 additions and 2 deletions

View File

@ -1,7 +1,74 @@
import bpy
from mathutils import Vector
def build_dock_connections():
areas = []
docks = []
for obj in bpy.context.scene.objects:
if obj.type == 'MESH' and obj.parent is None:
dock_list = []
for ch in obj.children:
if ch.type == 'MESH':
docks.append((len(areas), len(dock_list), ch))
dock_list.append(ch)
areas.append((obj, dock_list))
dock_dict = dict()
for dockA in docks:
mtxA = dockA[2].matrix_world
locA = Vector((mtxA[0][3], mtxA[1][3], mtxA[2][3]))
match = False
for dockB in docks:
if dockA == dockB:
continue
mtxB = dockB[2].matrix_world
locB = Vector((mtxB[0][3], mtxB[1][3], mtxB[2][3]))
if (locA - locB).magnitude < 0.1:
dock_dict[dockA[2].name] = dockB
match = True
break
if not match:
raise RuntimeError('No dock match for %s' % dockA[2].name)
return (areas, dock_dict)
# Cook
def cook(writebuf):
pass
areas, dock_conns = build_dock_connections()
writebuf(struct.pack('I', len(areas)))
for area in areas:
obj = area[0]
dock_list = area[1]
writebuf(struct.pack('I', len(obj.name)))
writebuf(obj.name.encode())
pt = Vector(copy_obj.bound_box[0])
writebuf(struct.pack('fff', pt[0], pt[1], pt[2]))
pt = Vector(copy_obj.bound_box[6])
writebuf(struct.pack('fff', pt[0], pt[1], pt[2]))
wmtx = obj.matrix_world
writebuf(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]))
wmtx_inv = wmtx.inverted()
writebuf(struct.pack('I', len(dock_list)))
for ch in dock_list:
if len(ch.data.vertices) < 4:
raise RuntimeError('Not enough vertices in dock %s' % ch.name)
wmtx = wmtx_inv * ch.matrix_world
for vi in range(4):
v = wmtx * ch.data.vertices[vi].co
writebuf(struct.pack('fff', v[0], v[1], v[2]))
conn_dock = dock_conns[ch.name]
writebuf(struct.pack('II', conn_dock[0], conn_dock[1]))
# Panel draw
def draw(layout, context):

View File

@ -216,6 +216,10 @@ def dataout_loop():
bpy.data.objects.remove(join_obj)
bpy.data.meshes.remove(join_mesh)
elif cmdargs[0] == 'WORLDCOMPILE':
writepipeline(b'OK')
hecl.swld.cook(writepipebuf)
elif cmdargs[0] == 'LIGHTCOMPILEALL':
writepipeline(b'OK')
lampCount = 0;

2
hecl/extern/athena vendored

@ -1 +1 @@
Subproject commit 779e741a916e7e5a550efc8153abac56d1f43b07
Subproject commit d3d63082d0087e2f85ee3bd43d27f077f40f6ebf

View File

@ -584,6 +584,22 @@ public:
/** Intermediate world representation */
struct World
{
struct Area
{
ProjectPath path;
Vector3f aabb[2];
Matrix4f transform;
struct Dock
{
Vector3f verts[4];
Index targetArea;
Index targetDock;
Dock(BlenderConnection& conn);
};
std::vector<Dock> docks;
Area(BlenderConnection& conn);
};
std::vector<Area> areas;
World(BlenderConnection& conn);
};

View File

@ -401,6 +401,15 @@ static inline int StrCaseCmp(const SystemChar* str1, const SystemChar* str2)
#endif
}
static inline unsigned long StrToUl(const SystemChar* str, SystemChar** endPtr, int base)
{
#if HECL_UCS2
return wcstoul(str, endPtr, base);
#else
return strtoul(str, endPtr, base);
#endif
}
#define FORMAT_BUF_SZ 1024
#if __GNUC__
@ -1270,6 +1279,17 @@ public:
return !StrCmp(&*(str.end() - len), test);
}
static std::string TrimWhitespace(const std::string& str)
{
auto bit = str.begin();
while (bit != str.cend() && isspace(*bit))
++bit;
auto eit = str.end();
while (eit != str.cbegin() && isspace(*(eit-1)))
--eit;
return {bit, eit};
}
#if HECL_UCS2
static bool BeginsWith(const std::string& str, const char* test)
{
@ -1286,6 +1306,17 @@ public:
return false;
return !strcmp(&*(str.end() - len), test);
}
static SystemString TrimWhitespace(const SystemString& str)
{
auto bit = str.begin();
while (bit != str.cend() && iswspace(*bit))
++bit;
auto eit = str.end();
while (eit != str.cbegin() && iswspace(*(eit-1)))
--eit;
return {bit, eit};
}
#endif
};

View File

@ -1001,8 +1001,46 @@ BlenderConnection::DataStream::ColMesh::Triangle::Triangle(BlenderConnection& co
conn._readBuf(this, 16);
}
BlenderConnection::DataStream::World::Area::Dock::Dock(BlenderConnection& conn)
{
verts[0].read(conn);
verts[1].read(conn);
verts[2].read(conn);
verts[3].read(conn);
targetArea.read(conn);
targetDock.read(conn);
}
BlenderConnection::DataStream::World::Area::Area(BlenderConnection& conn)
{
std::string name;
uint32_t nameLen;
conn._readBuf(&nameLen, 4);
if (nameLen)
{
name.assign(nameLen, '\0');
conn._readBuf(&name[0], nameLen);
}
path.assign(conn.m_loadedBlend.getParentPath(), name);
aabb[0].read(conn);
aabb[1].read(conn);
transform.read(conn);
uint32_t dockCount;
conn._readBuf(&dockCount, 4);
docks.reserve(dockCount);
for (uint32_t i=0 ; i<dockCount ; ++i)
docks.emplace_back(conn);
}
BlenderConnection::DataStream::World::World(BlenderConnection& conn)
{
uint32_t areaCount;
conn._readBuf(&areaCount, 4);
areas.reserve(areaCount);
for (uint32_t i=0 ; i<areaCount ; ++i)
areas.emplace_back(conn);
}
BlenderConnection::DataStream::Light::Light(BlenderConnection& conn)