diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2011-09-02 20:15:18 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2011-09-02 20:15:18 +0400 |
commit | 67030aaf84229b4d0dc52fbe07e91c2c9d320b0d (patch) | |
tree | 9b8d2402b3dd92134d78d1661d678effd8a70ecd /intern/cycles/render/object.cpp | |
parent | 1135875ab1501ff38184b91dc541aa8a2fe89c92 (diff) |
Cycles: optimizations for instances in scene updates before render starts,
should load a non-trivial mesh instanced many times quite a bit faster now.
Diffstat (limited to 'intern/cycles/render/object.cpp')
-rw-r--r-- | intern/cycles/render/object.cpp | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 4ba2de6e61b..fab051bde72 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -22,6 +22,7 @@ #include "scene.h" #include "util_foreach.h" +#include "util_map.h" #include "util_progress.h" CCL_NAMESPACE_BEGIN @@ -103,6 +104,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene { float4 *objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size()); int i = 0; + map<Mesh*, float> surface_area_map; foreach(Object *ob, scene->objects) { Mesh *mesh = ob->mesh; @@ -112,16 +114,39 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene Transform itfm = transform_inverse(tfm); Transform ntfm = transform_transpose(itfm); - /* compute surface area */ + /* compute surface area. for uniform scale we can do avoid the many + transform calls and share computation for instances */ /* todo: correct for displacement, and move to a better place */ - float surfacearea = 0.0f; - - foreach(Mesh::Triangle& t, mesh->triangles) { - float3 p1 = transform(&tfm, mesh->verts[t.v[0]]); - float3 p2 = transform(&tfm, mesh->verts[t.v[1]]); - float3 p3 = transform(&tfm, mesh->verts[t.v[2]]); - - surfacearea += triangle_area(p1, p2, p3); + float uniform_scale; + float surface_area = 0.0f; + + if(transform_uniform_scale(tfm, uniform_scale)) { + map<Mesh*, float>::iterator it = surface_area_map.find(mesh); + + if(it == surface_area_map.end()) { + foreach(Mesh::Triangle& t, mesh->triangles) { + float3 p1 = mesh->verts[t.v[0]]; + float3 p2 = mesh->verts[t.v[1]]; + float3 p3 = mesh->verts[t.v[2]]; + + surface_area += triangle_area(p1, p2, p3); + } + + surface_area_map[mesh] = surface_area; + } + else + surface_area = it->second; + + surface_area *= uniform_scale; + } + else { + foreach(Mesh::Triangle& t, mesh->triangles) { + float3 p1 = transform(&tfm, mesh->verts[t.v[0]]); + float3 p2 = transform(&tfm, mesh->verts[t.v[1]]); + float3 p3 = transform(&tfm, mesh->verts[t.v[2]]); + + surface_area += triangle_area(p1, p2, p3); + } } /* pack in texture */ @@ -130,7 +155,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene memcpy(&objects[offset], &tfm, sizeof(float4)*4); memcpy(&objects[offset+4], &itfm, sizeof(float4)*4); memcpy(&objects[offset+8], &ntfm, sizeof(float4)*4); - objects[offset+12] = make_float4(surfacearea, 0.0f, 0.0f, 0.0f); + objects[offset+12] = make_float4(surface_area, 0.0f, 0.0f, 0.0f); i++; |