@@ -202,6 +202,17 @@ static void xml_read_camera(XMLReadState &state, xml_node node)
202202
203203 cam->need_update = true ;
204204 cam->update (state.scene );
205+
206+ // dicing camera
207+ Camera *dicing_cam = state.scene ->dicing_camera ;
208+ dicing_cam->width = cam->width ;
209+ dicing_cam->height = cam->height ;
210+ dicing_cam->full_width = cam->full_width ;
211+ dicing_cam->full_height = cam->full_height ;
212+
213+ dicing_cam->matrix = state.tfm ;
214+ dicing_cam->need_update = true ;
215+ dicing_cam->update (state.scene );
205216}
206217
207218/* Shader */
@@ -391,6 +402,122 @@ static Mesh *xml_add_mesh(Scene *scene, const Transform &tfm)
391402 return mesh;
392403}
393404
405+ static void xml_read_mesh_attributes (const XMLReadState &state, Mesh *mesh, xml_node attribute_node)
406+ {
407+ AttributeSet &attributes = mesh->subdivision_type == Mesh::SUBDIVISION_NONE ?
408+ mesh->attributes :
409+ mesh->subd_attributes ;
410+
411+ xml_attribute name_attr = attribute_node.attribute (" name" );
412+ if (!name_attr) {
413+ return ;
414+ }
415+
416+ if (state.scene ->integrator ->motion_blur
417+ && string_iequals (name_attr.value (), " motion_vertex_position" )) {
418+ vector<float3> data;
419+
420+ if (xml_read_float3_array (data, attribute_node, " data" )) {
421+ if (data.size () % mesh->verts .size () != 0 ) {
422+ return ;
423+ }
424+
425+ mesh->motion_steps = 1 + data.size () / mesh->verts .size ();
426+ mesh->use_motion_blur = true ;
427+
428+ Attribute *motion_vertex_position = attributes.add (ATTR_STD_MOTION_VERTEX_POSITION);
429+ float3 *motion = motion_vertex_position->data_float3 ();
430+
431+ for (size_t i = 0 ; i < data.size (); ++i) {
432+ motion[i] = data[i];
433+ }
434+ }
435+ }
436+
437+ xml_attribute data_attr = attribute_node.attribute (" data" );
438+ if (!data_attr) {
439+ return ;
440+ }
441+
442+ // TODO: add support for standard attributes such as P, UV etc
443+
444+ // custom attribute
445+ xml_attribute type_attr = attribute_node.attribute (" type" );
446+ xml_attribute elem_attr = attribute_node.attribute (" element" );
447+ if (!type_attr || !elem_attr) {
448+ return ;
449+ }
450+
451+ // type
452+ TypeDesc type_desc = TypeUnknown;
453+ int type_size = 0 ;
454+ if (string_iequals (type_attr.value (), " float" )) {
455+ type_desc = TypeFloat;
456+ type_size = 1 ;
457+ }
458+ else if (string_iequals (type_attr.value (), " float2" )) {
459+ type_desc = TypeFloat2;
460+ type_size = 2 ;
461+ }
462+ else if (string_iequals (type_attr.value (), " color" )) {
463+ type_desc = TypeColor;
464+ type_size = 3 ;
465+ }
466+
467+ if (type_desc == TypeUnknown) {
468+ fprintf (stderr, " Unknown attribute type \" %s\" .\n " , name_attr.value ());
469+ return ;
470+ }
471+
472+ // element
473+ AttributeElement element = AttributeElement::ATTR_ELEMENT_NONE;
474+ if (string_iequals (elem_attr.value (), " vertex" )) {
475+ element = AttributeElement::ATTR_ELEMENT_VERTEX;
476+ }
477+ if (string_iequals (elem_attr.value (), " face" )) {
478+ element = AttributeElement::ATTR_ELEMENT_FACE;
479+ }
480+ if (string_iequals (elem_attr.value (), " corner" )) {
481+ element = AttributeElement::ATTR_ELEMENT_CORNER;
482+ }
483+
484+ // unknown element
485+ if (element == AttributeElement::ATTR_ELEMENT_NONE) {
486+ fprintf (stderr, " Unknown attribute element \" %s\" .\n " , name_attr.value ());
487+ return ;
488+ }
489+
490+ // create
491+ vector<float > data;
492+ if (xml_read_float_array (data, attribute_node, " data" )) {
493+ auto size = mesh->element_size (element, attributes.prim );
494+ if (data.size () != size * type_size) {
495+ fprintf (stderr, " Invalid attribute size \" %s\" .\n " , name_attr.value ());
496+ return ;
497+ }
498+
499+ Attribute *attrib = attributes.add (ustring{name_attr.value ()}, type_desc, element);
500+ if (type_desc == TypeFloat) {
501+ auto adata = attrib->data_float ();
502+ for (size_t i = 0 ; i < size; ++i) {
503+ adata[i] = data[i];
504+ }
505+ }
506+ else if (type_desc == TypeFloat2) {
507+ auto adata = attrib->data_float2 ();
508+ for (size_t i = 0 , o = 0 ; i < size; ++i, o += type_size) {
509+ adata[i] = make_float2 (data[o], data[o + 1 ]);
510+ }
511+ }
512+ else if (type_desc == TypeColor) {
513+ auto adata = attrib->data_float3 ();
514+ for (size_t i = 0 , o = 0 ; i < size; ++i, o += type_size) {
515+ adata[i] = make_float3 (data[o], data[o + 1 ], data[o + 2 ]);
516+ }
517+ }
518+ }
519+ }
520+
394521static void xml_read_mesh (const XMLReadState &state, xml_node node)
395522{
396523 /* add mesh */
@@ -460,7 +587,6 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
460587
461588 assert (v0 * 2 + 1 < (int )UV.size ());
462589 assert (v1 * 2 + 1 < (int )UV.size ());
463- assert (v2 * 2 + 1 < (int )UV.size ());
464590
465591 fdata[0 ] = make_float2 (UV[v0 * 2 ], UV[v0 * 2 + 1 ]);
466592 fdata[1 ] = make_float2 (UV[v1 * 2 ], UV[v1 * 2 + 1 ]);
@@ -496,7 +622,7 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
496622 if (xml_read_float_array (UV, node, " UV" )) {
497623 ustring name = ustring (" UVMap" );
498624 Attribute *attr = mesh->subd_attributes .add (ATTR_STD_UV, name);
499- float3 *fdata = attr->data_float3 ();
625+ float2 *fdata = attr->data_float2 ();
500626
501627#if 0
502628 if (subdivide_uvs) {
@@ -507,7 +633,9 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
507633 index_offset = 0 ;
508634 for (size_t i = 0 ; i < nverts.size (); i++) {
509635 for (int j = 0 ; j < nverts[i]; j++) {
510- *(fdata++) = make_float3 (UV[index_offset++]);
636+ auto u = UV[index_offset++];
637+ auto v = UV[index_offset++];
638+ *(fdata++) = make_float2 (u, v);
511639 }
512640 }
513641 }
@@ -525,6 +653,13 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
525653 sdparams.objecttoworld = state.tfm ;
526654 }
527655
656+ for (xml_node child_node = node.first_child (); child_node;
657+ child_node = child_node.next_sibling ()) {
658+ if (string_iequals (child_node.name (), " attribute" )) {
659+ xml_read_mesh_attributes (state, mesh, child_node);
660+ }
661+ }
662+
528663 /* we don't yet support arbitrary attributes, for now add vertex
529664 * coordinates as generated coordinates if requested */
530665 if (mesh->need_attribute (state.scene , ATTR_STD_GENERATED)) {
0 commit comments