Cycles: optimization of panoramic camera in volume
[blender-staging.git] / intern / cycles / render / mesh.cpp
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16
17 #include "bvh.h"
18 #include "bvh_build.h"
19
20 #include "camera.h"
21 #include "curves.h"
22 #include "device.h"
23 #include "shader.h"
24 #include "light.h"
25 #include "mesh.h"
26 #include "object.h"
27 #include "scene.h"
28
29 #include "osl_globals.h"
30
31 #include "util_cache.h"
32 #include "util_foreach.h"
33 #include "util_progress.h"
34 #include "util_set.h"
35
36 CCL_NAMESPACE_BEGIN
37
38 /* Triangle */
39
40 void Mesh::Triangle::bounds_grow(const float3 *verts, BoundBox& bounds) const
41 {
42         bounds.grow(verts[v[0]]);
43         bounds.grow(verts[v[1]]);
44         bounds.grow(verts[v[2]]);
45 }
46
47 /* Curve */
48
49 void Mesh::Curve::bounds_grow(const int k, const float4 *curve_keys, BoundBox& bounds) const
50 {
51         float3 P[4];
52
53         P[0] = float4_to_float3(curve_keys[max(first_key + k - 1,first_key)]);
54         P[1] = float4_to_float3(curve_keys[first_key + k]);
55         P[2] = float4_to_float3(curve_keys[first_key + k + 1]);
56         P[3] = float4_to_float3(curve_keys[min(first_key + k + 2, first_key + num_keys - 1)]);
57
58         float3 lower;
59         float3 upper;
60
61         curvebounds(&lower.x, &upper.x, P, 0);
62         curvebounds(&lower.y, &upper.y, P, 1);
63         curvebounds(&lower.z, &upper.z, P, 2);
64
65         float mr = max(curve_keys[first_key + k].w, curve_keys[first_key + k + 1].w);
66
67         bounds.grow(lower, mr);
68         bounds.grow(upper, mr);
69 }
70
71 /* Mesh */
72
73 Mesh::Mesh()
74 {
75         need_update = true;
76         need_update_rebuild = false;
77         transform_applied = false;
78         transform_negative_scaled = false;
79         transform_normal = transform_identity();
80         displacement_method = DISPLACE_BUMP;
81         bounds = BoundBox::empty;
82
83         motion_steps = 3;
84         use_motion_blur = false;
85
86         bvh = NULL;
87
88         tri_offset = 0;
89         vert_offset = 0;
90
91         curve_offset = 0;
92         curvekey_offset = 0;
93
94         attributes.triangle_mesh = this;
95         curve_attributes.curve_mesh = this;
96 }
97
98 Mesh::~Mesh()
99 {
100         delete bvh;
101 }
102
103 void Mesh::reserve(int numverts, int numtris, int numcurves, int numcurvekeys)
104 {
105         /* reserve space to add verts and triangles later */
106         verts.resize(numverts);
107         triangles.resize(numtris);
108         shader.resize(numtris);
109         smooth.resize(numtris);
110         curve_keys.resize(numcurvekeys);
111         curves.resize(numcurves);
112
113         attributes.reserve();
114         curve_attributes.reserve();
115 }
116
117 void Mesh::clear()
118 {
119         /* clear all verts and triangles */
120         verts.clear();
121         triangles.clear();
122         shader.clear();
123         smooth.clear();
124
125         curve_keys.clear();
126         curves.clear();
127
128         attributes.clear();
129         curve_attributes.clear();
130         used_shaders.clear();
131
132         transform_applied = false;
133         transform_negative_scaled = false;
134         transform_normal = transform_identity();
135         geometry_synced = false;
136 }
137
138 int Mesh::split_vertex(int vertex)
139 {
140         /* copy vertex location and vertex attributes */
141         verts.push_back(verts[vertex]);
142
143         foreach(Attribute& attr, attributes.attributes) {
144                 if(attr.element == ATTR_ELEMENT_VERTEX) {
145                         vector<char> tmp(attr.data_sizeof());
146                         memcpy(&tmp[0], attr.data() + tmp.size()*vertex, tmp.size());
147                         attr.add(&tmp[0]);
148                 }
149         }
150
151         return verts.size() - 1;
152 }
153
154 void Mesh::set_triangle(int i, int v0, int v1, int v2, int shader_, bool smooth_)
155 {
156         Triangle tri;
157         tri.v[0] = v0;
158         tri.v[1] = v1;
159         tri.v[2] = v2;
160
161         triangles[i] = tri;
162         shader[i] = shader_;
163         smooth[i] = smooth_;
164 }
165
166 void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
167 {
168         Triangle tri;
169         tri.v[0] = v0;
170         tri.v[1] = v1;
171         tri.v[2] = v2;
172
173         triangles.push_back(tri);
174         shader.push_back(shader_);
175         smooth.push_back(smooth_);
176 }
177
178 void Mesh::add_curve_key(float3 co, float radius)
179 {
180         float4 key = float3_to_float4(co);
181         key.w = radius;
182
183         curve_keys.push_back(key);
184 }
185
186 void Mesh::add_curve(int first_key, int num_keys, int shader)
187 {
188         Curve curve;
189         curve.first_key = first_key;
190         curve.num_keys = num_keys;
191         curve.shader = shader;
192
193         curves.push_back(curve);
194 }
195
196 void Mesh::compute_bounds()
197 {
198         BoundBox bnds = BoundBox::empty;
199         size_t verts_size = verts.size();
200         size_t curve_keys_size = curve_keys.size();
201
202         if(verts_size + curve_keys_size > 0) {
203                 for(size_t i = 0; i < verts_size; i++)
204                         bnds.grow(verts[i]);
205
206                 for(size_t i = 0; i < curve_keys_size; i++)
207                         bnds.grow(float4_to_float3(curve_keys[i]), curve_keys[i].w);
208
209                 Attribute *attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
210                 if (use_motion_blur && attr) {
211                         size_t steps_size = verts.size() * (motion_steps - 1);
212                         float3 *vert_steps = attr->data_float3();
213         
214                         for (size_t i = 0; i < steps_size; i++)
215                                 bnds.grow(vert_steps[i]);
216                 }
217
218                 Attribute *curve_attr = curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
219                 if(use_motion_blur && curve_attr) {
220                         size_t steps_size = curve_keys.size() * (motion_steps - 1);
221                         float3 *key_steps = curve_attr->data_float3();
222         
223                         for (size_t i = 0; i < steps_size; i++)
224                                 bnds.grow(key_steps[i]);
225                 }
226
227                 if(!bnds.valid()) {
228                         bnds = BoundBox::empty;
229
230                         /* skip nan or inf coordinates */
231                         for(size_t i = 0; i < verts_size; i++)
232                                 bnds.grow_safe(verts[i]);
233
234                         for(size_t i = 0; i < curve_keys_size; i++)
235                                 bnds.grow_safe(float4_to_float3(curve_keys[i]), curve_keys[i].w);
236                         
237                         if (use_motion_blur && attr) {
238                                 size_t steps_size = verts.size() * (motion_steps - 1);
239                                 float3 *vert_steps = attr->data_float3();
240                 
241                                 for (size_t i = 0; i < steps_size; i++)
242                                         bnds.grow_safe(vert_steps[i]);
243                         }
244
245                         if (use_motion_blur && curve_attr) {
246                                 size_t steps_size = curve_keys.size() * (motion_steps - 1);
247                                 float3 *key_steps = curve_attr->data_float3();
248                 
249                                 for (size_t i = 0; i < steps_size; i++)
250                                         bnds.grow_safe(key_steps[i]);
251                         }
252                 }
253         }
254
255         if(!bnds.valid()) {
256                 /* empty mesh */
257                 bnds.grow(make_float3(0.0f, 0.0f, 0.0f));
258         }
259
260         bounds = bnds;
261 }
262
263 static float3 compute_face_normal(const Mesh::Triangle& t, float3 *verts)
264 {
265         float3 v0 = verts[t.v[0]];
266         float3 v1 = verts[t.v[1]];
267         float3 v2 = verts[t.v[2]];
268
269         float3 norm = cross(v1 - v0, v2 - v0);
270         float normlen = len(norm);
271
272         if(normlen == 0.0f)
273                 return make_float3(0.0f, 0.0f, 0.0f);
274
275         return norm / normlen;
276 }
277
278 void Mesh::add_face_normals()
279 {
280         /* don't compute if already there */
281         if(attributes.find(ATTR_STD_FACE_NORMAL))
282                 return;
283         
284         /* get attributes */
285         Attribute *attr_fN = attributes.add(ATTR_STD_FACE_NORMAL);
286         float3 *fN = attr_fN->data_float3();
287
288         /* compute face normals */
289         size_t triangles_size = triangles.size();
290         bool flip = transform_negative_scaled;
291
292         if(triangles_size) {
293                 float3 *verts_ptr = &verts[0];
294                 Triangle *triangles_ptr = &triangles[0];
295
296                 for(size_t i = 0; i < triangles_size; i++) {
297                         fN[i] = compute_face_normal(triangles_ptr[i], verts_ptr);
298
299                         if(flip)
300                                 fN[i] = -fN[i];
301                 }
302         }
303
304         /* expected to be in local space */
305         if(transform_applied) {
306                 Transform ntfm = transform_inverse(transform_normal);
307
308                 for(size_t i = 0; i < triangles_size; i++)
309                         fN[i] = normalize(transform_direction(&ntfm, fN[i]));
310         }
311 }
312
313 void Mesh::add_vertex_normals()
314 {
315         bool flip = transform_negative_scaled;
316         size_t verts_size = verts.size();
317         size_t triangles_size = triangles.size();
318
319         /* static vertex normals */
320         if(!attributes.find(ATTR_STD_VERTEX_NORMAL)) {
321                 /* get attributes */
322                 Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
323                 Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
324
325                 float3 *fN = attr_fN->data_float3();
326                 float3 *vN = attr_vN->data_float3();
327
328                 /* compute vertex normals */
329                 memset(vN, 0, verts.size()*sizeof(float3));
330
331                 if(triangles_size) {
332                         Triangle *triangles_ptr = &triangles[0];
333
334                         for(size_t i = 0; i < triangles_size; i++)
335                                 for(size_t j = 0; j < 3; j++)
336                                         vN[triangles_ptr[i].v[j]] += fN[i];
337                 }
338
339                 for(size_t i = 0; i < verts_size; i++) {
340                         vN[i] = normalize(vN[i]);
341                         if(flip)
342                                 vN[i] = -vN[i];
343                 }
344         }
345
346         /* motion vertex normals */
347         Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
348         Attribute *attr_mN = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
349
350         if(has_motion_blur() && attr_mP && !attr_mN) {
351                 /* create attribute */
352                 attr_mN = attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
353
354                 for(int step = 0; step < motion_steps - 1; step++) {
355                         float3 *mP = attr_mP->data_float3() + step*verts.size();
356                         float3 *mN = attr_mN->data_float3() + step*verts.size();
357
358                         /* compute */
359                         memset(mN, 0, verts.size()*sizeof(float3));
360
361                         if(triangles_size) {
362                                 Triangle *triangles_ptr = &triangles[0];
363
364                                 for(size_t i = 0; i < triangles_size; i++) {
365                                         for(size_t j = 0; j < 3; j++) {
366                                                 float3 fN = compute_face_normal(triangles_ptr[i], mP);
367                                                 mN[triangles_ptr[i].v[j]] += fN;
368                                         }
369                                 }
370                         }
371
372                         for(size_t i = 0; i < verts_size; i++) {
373                                 mN[i] = normalize(mN[i]);
374                                 if(flip)
375                                         mN[i] = -mN[i];
376                         }
377                 }
378         }
379 }
380
381 void Mesh::pack_normals(Scene *scene, uint *tri_shader, float4 *vnormal)
382 {
383         Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
384
385         float3 *vN = attr_vN->data_float3();
386         uint shader_id = 0;
387         uint last_shader = -1;
388         bool last_smooth = false;
389
390         size_t triangles_size = triangles.size();
391         uint *shader_ptr = (shader.size())? &shader[0]: NULL;
392
393         bool do_transform = transform_applied;
394         Transform ntfm = transform_normal;
395
396         /* save shader */
397         for(size_t i = 0; i < triangles_size; i++) {
398                 if(shader_ptr[i] != last_shader || last_smooth != smooth[i]) {
399                         last_shader = shader_ptr[i];
400                         last_smooth = smooth[i];
401                         shader_id = scene->shader_manager->get_shader_id(last_shader, this, last_smooth);
402                 }
403
404                 tri_shader[i] = shader_id;
405         }
406
407         size_t verts_size = verts.size();
408
409         for(size_t i = 0; i < verts_size; i++) {
410                 float3 vNi = vN[i];
411
412                 if(do_transform)
413                         vNi = normalize(transform_direction(&ntfm, vNi));
414
415                 vnormal[i] = make_float4(vNi.x, vNi.y, vNi.z, 0.0f);
416         }
417 }
418
419 void Mesh::pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset)
420 {
421         size_t verts_size = verts.size();
422
423         if(verts_size) {
424                 float3 *verts_ptr = &verts[0];
425
426                 for(size_t i = 0; i < verts_size; i++) {
427                         float3 p = verts_ptr[i];
428                         tri_verts[i] = make_float4(p.x, p.y, p.z, 0.0f);
429                 }
430         }
431
432         size_t triangles_size = triangles.size();
433
434         if(triangles_size) {
435                 Triangle *triangles_ptr = &triangles[0];
436
437                 for(size_t i = 0; i < triangles_size; i++) {
438                         Triangle t = triangles_ptr[i];
439
440                         tri_vindex[i] = make_float4(
441                                 __int_as_float(t.v[0] + vert_offset),
442                                 __int_as_float(t.v[1] + vert_offset),
443                                 __int_as_float(t.v[2] + vert_offset),
444                                 0);
445                 }
446         }
447 }
448
449 void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset)
450 {
451         size_t curve_keys_size = curve_keys.size();
452         float4 *keys_ptr = NULL;
453
454         /* pack curve keys */
455         if(curve_keys_size) {
456                 keys_ptr = &curve_keys[0];
457
458                 for(size_t i = 0; i < curve_keys_size; i++)
459                         curve_key_co[i] = keys_ptr[i];
460         }
461
462         /* pack curve segments */
463         size_t curve_num = curves.size();
464
465         if(curve_num) {
466                 Curve *curve_ptr = &curves[0];
467                 int shader_id = 0;
468                 
469                 for(size_t i = 0; i < curve_num; i++) {
470                         Curve curve = curve_ptr[i];
471                         shader_id = scene->shader_manager->get_shader_id(curve.shader, this, false);
472
473                         curve_data[i] = make_float4(
474                                 __int_as_float(curve.first_key + curvekey_offset),
475                                 __int_as_float(curve.num_keys),
476                                 __int_as_float(shader_id),
477                                 0.0f);
478                 }
479         }
480 }
481
482 void Mesh::compute_bvh(SceneParams *params, Progress *progress, int n, int total)
483 {
484         if(progress->get_cancel())
485                 return;
486
487         compute_bounds();
488
489         if(!transform_applied) {
490                 string msg = "Updating Mesh BVH ";
491                 if(name == "")
492                         msg += string_printf("%u/%u", (uint)(n+1), (uint)total);
493                 else
494                         msg += string_printf("%s %u/%u", name.c_str(), (uint)(n+1), (uint)total);
495
496                 Object object;
497                 object.mesh = this;
498
499                 vector<Object*> objects;
500                 objects.push_back(&object);
501
502                 if(bvh && !need_update_rebuild) {
503                         progress->set_status(msg, "Refitting BVH");
504                         bvh->objects = objects;
505                         bvh->refit(*progress);
506                 }
507                 else {
508                         progress->set_status(msg, "Building BVH");
509
510                         BVHParams bparams;
511                         bparams.use_cache = params->use_bvh_cache;
512                         bparams.use_spatial_split = params->use_bvh_spatial_split;
513                         bparams.use_qbvh = params->use_qbvh;
514
515                         delete bvh;
516                         bvh = BVH::create(bparams, objects);
517                         bvh->build(*progress);
518                 }
519         }
520
521         need_update = false;
522         need_update_rebuild = false;
523 }
524
525 void Mesh::tag_update(Scene *scene, bool rebuild)
526 {
527         need_update = true;
528
529         if(rebuild) {
530                 need_update_rebuild = true;
531                 scene->light_manager->need_update = true;
532         }
533         else {
534                 foreach(uint sindex, used_shaders)
535                         if(scene->shaders[sindex]->has_surface_emission)
536                                 scene->light_manager->need_update = true;
537         }
538
539         scene->mesh_manager->need_update = true;
540         scene->object_manager->need_update = true;
541 }
542
543 bool Mesh::has_motion_blur() const
544 {
545         return (use_motion_blur &&
546                 (attributes.find(ATTR_STD_MOTION_VERTEX_POSITION) ||
547                  curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)));
548 }
549
550 /* Mesh Manager */
551
552 MeshManager::MeshManager()
553 {
554         bvh = NULL;
555         need_update = true;
556 }
557
558 MeshManager::~MeshManager()
559 {
560         delete bvh;
561 }
562
563 void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<AttributeRequestSet>& mesh_attributes)
564 {
565 #ifdef WITH_OSL
566         /* for OSL, a hash map is used to lookup the attribute by name. */
567         OSLGlobals *og = (OSLGlobals*)device->osl_memory();
568
569         og->object_name_map.clear();
570         og->attribute_map.clear();
571         og->object_names.clear();
572
573         og->attribute_map.resize(scene->objects.size()*ATTR_PRIM_TYPES);
574
575         for(size_t i = 0; i < scene->objects.size(); i++) {
576                 /* set object name to object index map */
577                 Object *object = scene->objects[i];
578                 og->object_name_map[object->name] = i;
579                 og->object_names.push_back(object->name);
580
581                 /* set object attributes */
582                 foreach(ParamValue& attr, object->attributes) {
583                         OSLGlobals::Attribute osl_attr;
584
585                         osl_attr.type = attr.type();
586                         osl_attr.elem = ATTR_ELEMENT_OBJECT;
587                         osl_attr.value = attr;
588                         osl_attr.offset = 0;
589
590                         og->attribute_map[i*ATTR_PRIM_TYPES][attr.name()] = osl_attr;
591                         og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][attr.name()] = osl_attr;
592                 }
593
594                 /* find mesh attributes */
595                 size_t j;
596
597                 for(j = 0; j < scene->meshes.size(); j++)
598                         if(scene->meshes[j] == object->mesh)
599                                 break;
600
601                 AttributeRequestSet& attributes = mesh_attributes[j];
602
603                 /* set object attributes */
604                 foreach(AttributeRequest& req, attributes.requests) {
605                         OSLGlobals::Attribute osl_attr;
606
607                         if(req.triangle_element != ATTR_ELEMENT_NONE) {
608                                 osl_attr.elem = req.triangle_element;
609                                 osl_attr.offset = req.triangle_offset;
610
611                                 if(req.triangle_type == TypeDesc::TypeFloat)
612                                         osl_attr.type = TypeDesc::TypeFloat;
613                                 else if(req.triangle_type == TypeDesc::TypeMatrix)
614                                         osl_attr.type = TypeDesc::TypeMatrix;
615                                 else
616                                         osl_attr.type = TypeDesc::TypeColor;
617
618                                 if(req.std != ATTR_STD_NONE) {
619                                         /* if standard attribute, add lookup by geom: name convention */
620                                         ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
621                                         og->attribute_map[i*ATTR_PRIM_TYPES][stdname] = osl_attr;
622                                 }
623                                 else if(req.name != ustring()) {
624                                         /* add lookup by mesh attribute name */
625                                         og->attribute_map[i*ATTR_PRIM_TYPES][req.name] = osl_attr;
626                                 }
627                         }
628
629                         if(req.curve_element != ATTR_ELEMENT_NONE) {
630                                 osl_attr.elem = req.curve_element;
631                                 osl_attr.offset = req.curve_offset;
632
633                                 if(req.curve_type == TypeDesc::TypeFloat)
634                                         osl_attr.type = TypeDesc::TypeFloat;
635                                 else if(req.curve_type == TypeDesc::TypeMatrix)
636                                         osl_attr.type = TypeDesc::TypeMatrix;
637                                 else
638                                         osl_attr.type = TypeDesc::TypeColor;
639
640                                 if(req.std != ATTR_STD_NONE) {
641                                         /* if standard attribute, add lookup by geom: name convention */
642                                         ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
643                                         og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][stdname] = osl_attr;
644                                 }
645                                 else if(req.name != ustring()) {
646                                         /* add lookup by mesh attribute name */
647                                         og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][req.name] = osl_attr;
648                                 }
649                         }
650                 }
651         }
652 #endif
653 }
654
655 void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Scene *scene, vector<AttributeRequestSet>& mesh_attributes)
656 {
657         /* for SVM, the attributes_map table is used to lookup the offset of an
658          * attribute, based on a unique shader attribute id. */
659
660         /* compute array stride */
661         int attr_map_stride = 0;
662
663         for(size_t i = 0; i < scene->meshes.size(); i++)
664                 attr_map_stride = max(attr_map_stride, (mesh_attributes[i].size() + 1)*ATTR_PRIM_TYPES);
665
666         if(attr_map_stride == 0)
667                 return;
668         
669         /* create attribute map */
670         uint4 *attr_map = dscene->attributes_map.resize(attr_map_stride*scene->objects.size());
671         memset(attr_map, 0, dscene->attributes_map.size()*sizeof(uint));
672
673         for(size_t i = 0; i < scene->objects.size(); i++) {
674                 Object *object = scene->objects[i];
675                 Mesh *mesh = object->mesh;
676
677                 /* find mesh attributes */
678                 size_t j;
679
680                 for(j = 0; j < scene->meshes.size(); j++)
681                         if(scene->meshes[j] == mesh)
682                                 break;
683
684                 AttributeRequestSet& attributes = mesh_attributes[j];
685
686                 /* set object attributes */
687                 int index = i*attr_map_stride;
688
689                 foreach(AttributeRequest& req, attributes.requests) {
690                         uint id;
691
692                         if(req.std == ATTR_STD_NONE)
693                                 id = scene->shader_manager->get_attribute_id(req.name);
694                         else
695                                 id = scene->shader_manager->get_attribute_id(req.std);
696
697                         if(mesh->triangles.size()) {
698                                 attr_map[index].x = id;
699                                 attr_map[index].y = req.triangle_element;
700                                 attr_map[index].z = as_uint(req.triangle_offset);
701
702                                 if(req.triangle_type == TypeDesc::TypeFloat)
703                                         attr_map[index].w = NODE_ATTR_FLOAT;
704                                 else if(req.triangle_type == TypeDesc::TypeMatrix)
705                                         attr_map[index].w = NODE_ATTR_MATRIX;
706                                 else
707                                         attr_map[index].w = NODE_ATTR_FLOAT3;
708                         }
709
710                         index++;
711
712                         if(mesh->curves.size()) {
713                                 attr_map[index].x = id;
714                                 attr_map[index].y = req.curve_element;
715                                 attr_map[index].z = as_uint(req.curve_offset);
716
717                                 if(req.curve_type == TypeDesc::TypeFloat)
718                                         attr_map[index].w = NODE_ATTR_FLOAT;
719                                 else if(req.curve_type == TypeDesc::TypeMatrix)
720                                         attr_map[index].w = NODE_ATTR_MATRIX;
721                                 else
722                                         attr_map[index].w = NODE_ATTR_FLOAT3;
723                         }
724
725                         index++;
726                 }
727
728                 /* terminator */
729                 attr_map[index].x = ATTR_STD_NONE;
730                 attr_map[index].y = 0;
731                 attr_map[index].z = 0;
732                 attr_map[index].w = 0;
733
734                 index++;
735
736                 attr_map[index].x = ATTR_STD_NONE;
737                 attr_map[index].y = 0;
738                 attr_map[index].z = 0;
739                 attr_map[index].w = 0;
740
741                 index++;
742         }
743
744         /* copy to device */
745         dscene->data.bvh.attributes_map_stride = attr_map_stride;
746         device->tex_alloc("__attributes_map", dscene->attributes_map);
747 }
748
749 static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_float, vector<float4>& attr_float3, vector<uchar4>& attr_uchar4,
750         Attribute *mattr, TypeDesc& type, int& offset, AttributeElement& element)
751 {
752         if(mattr) {
753                 /* store element and type */
754                 element = mattr->element;
755                 type = mattr->type;
756
757                 /* store attribute data in arrays */
758                 size_t size = mattr->element_size(
759                         mesh->verts.size(),
760                         mesh->triangles.size(),
761                         mesh->motion_steps,
762                         mesh->curves.size(),
763                         mesh->curve_keys.size());
764
765                 if(mattr->element == ATTR_ELEMENT_VOXEL) {
766                         /* store slot in offset value */
767                         VoxelAttribute *voxel_data = mattr->data_voxel();
768                         offset = voxel_data->slot;
769                 }
770                 else if(mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
771                         uchar4 *data = mattr->data_uchar4();
772                         offset = attr_uchar4.size();
773
774                         attr_uchar4.resize(attr_uchar4.size() + size);
775
776                         for(size_t k = 0; k < size; k++)
777                                 attr_uchar4[offset+k] = data[k];
778                 }
779                 else if(mattr->type == TypeDesc::TypeFloat) {
780                         float *data = mattr->data_float();
781                         offset = attr_float.size();
782
783                         attr_float.resize(attr_float.size() + size);
784
785                         for(size_t k = 0; k < size; k++)
786                                 attr_float[offset+k] = data[k];
787                 }
788                 else if(mattr->type == TypeDesc::TypeMatrix) {
789                         Transform *tfm = mattr->data_transform();
790                         offset = attr_float3.size();
791
792                         attr_float3.resize(attr_float3.size() + size*4);
793
794                         for(size_t k = 0; k < size*4; k++)
795                                 attr_float3[offset+k] = (&tfm->x)[k];
796                 }
797                 else {
798                         float4 *data = mattr->data_float4();
799                         offset = attr_float3.size();
800
801                         attr_float3.resize(attr_float3.size() + size);
802
803                         for(size_t k = 0; k < size; k++)
804                                 attr_float3[offset+k] = data[k];
805                 }
806
807                 /* mesh vertex/curve index is global, not per object, so we sneak
808                  * a correction for that in here */
809                 if(element == ATTR_ELEMENT_VERTEX)
810                         offset -= mesh->vert_offset;
811                 else if(element == ATTR_ELEMENT_VERTEX_MOTION)
812                         offset -= mesh->vert_offset;
813                 else if(element == ATTR_ELEMENT_FACE)
814                         offset -= mesh->tri_offset;
815                 else if(element == ATTR_ELEMENT_CORNER || element == ATTR_ELEMENT_CORNER_BYTE)
816                         offset -= 3*mesh->tri_offset;
817                 else if(element == ATTR_ELEMENT_CURVE)
818                         offset -= mesh->curve_offset;
819                 else if(element == ATTR_ELEMENT_CURVE_KEY)
820                         offset -= mesh->curvekey_offset;
821                 else if(element == ATTR_ELEMENT_CURVE_KEY_MOTION)
822                         offset -= mesh->curvekey_offset;
823         }
824         else {
825                 /* attribute not found */
826                 element = ATTR_ELEMENT_NONE;
827                 offset = 0;
828         }
829 }
830
831 void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
832 {
833         progress.set_status("Updating Mesh", "Computing attributes");
834
835         /* gather per mesh requested attributes. as meshes may have multiple
836          * shaders assigned, this merges the requested attributes that have
837          * been set per shader by the shader manager */
838         vector<AttributeRequestSet> mesh_attributes(scene->meshes.size());
839
840         for(size_t i = 0; i < scene->meshes.size(); i++) {
841                 Mesh *mesh = scene->meshes[i];
842
843                 scene->need_global_attributes(mesh_attributes[i]);
844
845                 foreach(uint sindex, mesh->used_shaders) {
846                         Shader *shader = scene->shaders[sindex];
847                         mesh_attributes[i].add(shader->attributes);
848                 }
849         }
850
851         /* mesh attribute are stored in a single array per data type. here we fill
852          * those arrays, and set the offset and element type to create attribute
853          * maps next */
854         vector<float> attr_float;
855         vector<float4> attr_float3;
856         vector<uchar4> attr_uchar4;
857
858         for(size_t i = 0; i < scene->meshes.size(); i++) {
859                 Mesh *mesh = scene->meshes[i];
860                 AttributeRequestSet& attributes = mesh_attributes[i];
861
862                 /* todo: we now store std and name attributes from requests even if
863                  * they actually refer to the same mesh attributes, optimize */
864                 foreach(AttributeRequest& req, attributes.requests) {
865                         Attribute *triangle_mattr = mesh->attributes.find(req);
866                         Attribute *curve_mattr = mesh->curve_attributes.find(req);
867
868                         /* todo: get rid of this exception, it's only here for giving some
869                          * working texture coordinate for subdivision as we can't preserve
870                          * any attributes yet */
871                         if(!triangle_mattr && req.std == ATTR_STD_GENERATED) {
872                                 triangle_mattr = mesh->attributes.add(ATTR_STD_GENERATED);
873                                 if(mesh->verts.size())
874                                         memcpy(triangle_mattr->data_float3(), &mesh->verts[0], sizeof(float3)*mesh->verts.size());
875                         }
876
877                         update_attribute_element_offset(mesh, attr_float, attr_float3, attr_uchar4, triangle_mattr,
878                                 req.triangle_type, req.triangle_offset, req.triangle_element);
879
880                         update_attribute_element_offset(mesh, attr_float, attr_float3, attr_uchar4, curve_mattr,
881                                 req.curve_type, req.curve_offset, req.curve_element);
882         
883                         if(progress.get_cancel()) return;
884                 }
885         }
886
887         /* create attribute lookup maps */
888         if(scene->shader_manager->use_osl())
889                 update_osl_attributes(device, scene, mesh_attributes);
890
891         update_svm_attributes(device, dscene, scene, mesh_attributes);
892
893         if(progress.get_cancel()) return;
894
895         /* copy to device */
896         progress.set_status("Updating Mesh", "Copying Attributes to device");
897
898         if(attr_float.size()) {
899                 dscene->attributes_float.copy(&attr_float[0], attr_float.size());
900                 device->tex_alloc("__attributes_float", dscene->attributes_float);
901         }
902         if(attr_float3.size()) {
903                 dscene->attributes_float3.copy(&attr_float3[0], attr_float3.size());
904                 device->tex_alloc("__attributes_float3", dscene->attributes_float3);
905         }
906         if(attr_uchar4.size()) {
907                 dscene->attributes_uchar4.copy(&attr_uchar4[0], attr_uchar4.size());
908                 device->tex_alloc("__attributes_uchar4", dscene->attributes_uchar4);
909         }
910 }
911
912 void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
913 {
914         /* count and update offsets */
915         size_t vert_size = 0;
916         size_t tri_size = 0;
917
918         size_t curve_key_size = 0;
919         size_t curve_size = 0;
920
921         foreach(Mesh *mesh, scene->meshes) {
922                 mesh->vert_offset = vert_size;
923                 mesh->tri_offset = tri_size;
924
925                 mesh->curvekey_offset = curve_key_size;
926                 mesh->curve_offset = curve_size;
927
928                 vert_size += mesh->verts.size();
929                 tri_size += mesh->triangles.size();
930
931                 curve_key_size += mesh->curve_keys.size();
932                 curve_size += mesh->curves.size();
933         }
934
935         if(tri_size != 0) {
936                 /* normals */
937                 progress.set_status("Updating Mesh", "Computing normals");
938
939                 uint *tri_shader = dscene->tri_shader.resize(tri_size);
940                 float4 *vnormal = dscene->tri_vnormal.resize(vert_size);
941                 float4 *tri_verts = dscene->tri_verts.resize(vert_size);
942                 float4 *tri_vindex = dscene->tri_vindex.resize(tri_size);
943
944                 foreach(Mesh *mesh, scene->meshes) {
945                         mesh->pack_normals(scene, &tri_shader[mesh->tri_offset], &vnormal[mesh->vert_offset]);
946                         mesh->pack_verts(&tri_verts[mesh->vert_offset], &tri_vindex[mesh->tri_offset], mesh->vert_offset);
947
948                         if(progress.get_cancel()) return;
949                 }
950
951                 /* vertex coordinates */
952                 progress.set_status("Updating Mesh", "Copying Mesh to device");
953
954                 device->tex_alloc("__tri_shader", dscene->tri_shader);
955                 device->tex_alloc("__tri_vnormal", dscene->tri_vnormal);
956                 device->tex_alloc("__tri_verts", dscene->tri_verts);
957                 device->tex_alloc("__tri_vindex", dscene->tri_vindex);
958         }
959
960         if(curve_size != 0) {
961                 progress.set_status("Updating Mesh", "Copying Strands to device");
962
963                 float4 *curve_keys = dscene->curve_keys.resize(curve_key_size);
964                 float4 *curves = dscene->curves.resize(curve_size);
965
966                 foreach(Mesh *mesh, scene->meshes) {
967                         mesh->pack_curves(scene, &curve_keys[mesh->curvekey_offset], &curves[mesh->curve_offset], mesh->curvekey_offset);
968                         if(progress.get_cancel()) return;
969                 }
970
971                 device->tex_alloc("__curve_keys", dscene->curve_keys);
972                 device->tex_alloc("__curves", dscene->curves);
973         }
974 }
975
976 void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
977 {
978         /* bvh build */
979         progress.set_status("Updating Scene BVH", "Building");
980
981         BVHParams bparams;
982         bparams.top_level = true;
983         bparams.use_qbvh = scene->params.use_qbvh;
984         bparams.use_spatial_split = scene->params.use_bvh_spatial_split;
985         bparams.use_cache = scene->params.use_bvh_cache;
986
987         delete bvh;
988         bvh = BVH::create(bparams, scene->objects);
989         bvh->build(progress);
990
991         if(progress.get_cancel()) return;
992
993         /* copy to device */
994         progress.set_status("Updating Scene BVH", "Copying BVH to device");
995
996         PackedBVH& pack = bvh->pack;
997
998         if(pack.nodes.size()) {
999                 dscene->bvh_nodes.reference((float4*)&pack.nodes[0], pack.nodes.size());
1000                 device->tex_alloc("__bvh_nodes", dscene->bvh_nodes);
1001         }
1002         if(pack.object_node.size()) {
1003                 dscene->object_node.reference((uint*)&pack.object_node[0], pack.object_node.size());
1004                 device->tex_alloc("__object_node", dscene->object_node);
1005         }
1006         if(pack.tri_woop.size()) {
1007                 dscene->tri_woop.reference(&pack.tri_woop[0], pack.tri_woop.size());
1008                 device->tex_alloc("__tri_woop", dscene->tri_woop);
1009         }
1010         if(pack.prim_type.size()) {
1011                 dscene->prim_type.reference((uint*)&pack.prim_type[0], pack.prim_type.size());
1012                 device->tex_alloc("__prim_type", dscene->prim_type);
1013         }
1014         if(pack.prim_visibility.size()) {
1015                 dscene->prim_visibility.reference((uint*)&pack.prim_visibility[0], pack.prim_visibility.size());
1016                 device->tex_alloc("__prim_visibility", dscene->prim_visibility);
1017         }
1018         if(pack.prim_index.size()) {
1019                 dscene->prim_index.reference((uint*)&pack.prim_index[0], pack.prim_index.size());
1020                 device->tex_alloc("__prim_index", dscene->prim_index);
1021         }
1022         if(pack.prim_object.size()) {
1023                 dscene->prim_object.reference((uint*)&pack.prim_object[0], pack.prim_object.size());
1024                 device->tex_alloc("__prim_object", dscene->prim_object);
1025         }
1026
1027         dscene->data.bvh.root = pack.root_index;
1028 }
1029
1030 void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
1031 {
1032         if(!need_update)
1033                 return;
1034
1035         /* update normals */
1036         foreach(Mesh *mesh, scene->meshes) {
1037                 mesh->has_volume = false;
1038                 foreach(uint shader, mesh->used_shaders) {
1039                         if(scene->shaders[shader]->need_update_attributes)
1040                                 mesh->need_update = true;
1041                         if(scene->shaders[shader]->has_volume) {
1042                                 mesh->has_volume = true;
1043                         }
1044                 }
1045
1046                 if(mesh->need_update) {
1047                         mesh->add_face_normals();
1048                         mesh->add_vertex_normals();
1049
1050                         if(progress.get_cancel()) return;
1051                 }
1052         }
1053
1054         /* device update */
1055         device_free(device, dscene);
1056
1057         device_update_mesh(device, dscene, scene, progress);
1058         if(progress.get_cancel()) return;
1059
1060         device_update_attributes(device, dscene, scene, progress);
1061         if(progress.get_cancel()) return;
1062
1063         /* update displacement */
1064         bool displacement_done = false;
1065
1066         foreach(Mesh *mesh, scene->meshes)
1067                 if(mesh->need_update && displace(device, dscene, scene, mesh, progress))
1068                         displacement_done = true;
1069
1070         /* todo: properly handle cancel halfway displacement */
1071         if(progress.get_cancel()) return;
1072
1073         /* device re-update after displacement */
1074         if(displacement_done) {
1075                 device_free(device, dscene);
1076
1077                 device_update_mesh(device, dscene, scene, progress);
1078                 if(progress.get_cancel()) return;
1079
1080                 device_update_attributes(device, dscene, scene, progress);
1081                 if(progress.get_cancel()) return;
1082         }
1083
1084         /* update bvh */
1085         size_t i = 0, num_bvh = 0;
1086
1087         foreach(Mesh *mesh, scene->meshes)
1088                 if(mesh->need_update && !mesh->transform_applied)
1089                         num_bvh++;
1090
1091         TaskPool pool;
1092
1093         foreach(Mesh *mesh, scene->meshes) {
1094                 if(mesh->need_update) {
1095                         pool.push(function_bind(&Mesh::compute_bvh, mesh, &scene->params, &progress, i, num_bvh));
1096                         i++;
1097                 }
1098         }
1099
1100         pool.wait_work();
1101         
1102         foreach(Shader *shader, scene->shaders)
1103                 shader->need_update_attributes = false;
1104
1105 #ifdef __OBJECT_MOTION__
1106         Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
1107         bool motion_blur = need_motion == Scene::MOTION_BLUR;
1108 #else
1109         bool motion_blur = false;
1110 #endif
1111
1112         foreach(Object *object, scene->objects)
1113                 object->compute_bounds(motion_blur);
1114
1115         if(progress.get_cancel()) return;
1116
1117         device_update_bvh(device, dscene, scene, progress);
1118
1119         need_update = false;
1120 }
1121
1122 void MeshManager::device_free(Device *device, DeviceScene *dscene)
1123 {
1124         device->tex_free(dscene->bvh_nodes);
1125         device->tex_free(dscene->object_node);
1126         device->tex_free(dscene->tri_woop);
1127         device->tex_free(dscene->prim_type);
1128         device->tex_free(dscene->prim_visibility);
1129         device->tex_free(dscene->prim_index);
1130         device->tex_free(dscene->prim_object);
1131         device->tex_free(dscene->tri_shader);
1132         device->tex_free(dscene->tri_vnormal);
1133         device->tex_free(dscene->tri_vindex);
1134         device->tex_free(dscene->tri_verts);
1135         device->tex_free(dscene->curves);
1136         device->tex_free(dscene->curve_keys);
1137         device->tex_free(dscene->attributes_map);
1138         device->tex_free(dscene->attributes_float);
1139         device->tex_free(dscene->attributes_float3);
1140         device->tex_free(dscene->attributes_uchar4);
1141
1142         dscene->bvh_nodes.clear();
1143         dscene->object_node.clear();
1144         dscene->tri_woop.clear();
1145         dscene->prim_type.clear();
1146         dscene->prim_visibility.clear();
1147         dscene->prim_index.clear();
1148         dscene->prim_object.clear();
1149         dscene->tri_shader.clear();
1150         dscene->tri_vnormal.clear();
1151         dscene->tri_vindex.clear();
1152         dscene->tri_verts.clear();
1153         dscene->curves.clear();
1154         dscene->curve_keys.clear();
1155         dscene->attributes_map.clear();
1156         dscene->attributes_float.clear();
1157         dscene->attributes_float3.clear();
1158         dscene->attributes_uchar4.clear();
1159
1160 #ifdef WITH_OSL
1161         OSLGlobals *og = (OSLGlobals*)device->osl_memory();
1162
1163         if(og) {
1164                 og->object_name_map.clear();
1165                 og->attribute_map.clear();
1166                 og->object_names.clear();
1167         }
1168 #endif
1169 }
1170
1171 void MeshManager::tag_update(Scene *scene)
1172 {
1173         need_update = true;
1174         scene->object_manager->need_update = true;
1175 }
1176
1177 bool Mesh::need_attribute(Scene *scene, AttributeStandard std)
1178 {
1179         if(std == ATTR_STD_NONE)
1180                 return false;
1181         
1182         if(scene->need_global_attribute(std))
1183                 return true;
1184
1185         foreach(uint shader, used_shaders)
1186                 if(scene->shaders[shader]->attributes.find(std))
1187                         return true;
1188         
1189         return false;
1190 }
1191
1192 bool Mesh::need_attribute(Scene *scene, ustring name)
1193 {
1194         if(name == ustring())
1195                 return false;
1196
1197         foreach(uint shader, used_shaders)
1198                 if(scene->shaders[shader]->attributes.find(name))
1199                         return true;
1200         
1201         return false;
1202 }
1203
1204 CCL_NAMESPACE_END
1205