CCL_NAMESPACE_BEGIN Camera::Camera() { shuttertime = 1.0f; aperturesize = 0.0f; focaldistance = 10.0f; blades = 0; bladesrotation = 0.0f; matrix = transform_identity(); motion.pre = transform_identity(); motion.post = transform_identity(); use_motion = false; use_perspective_motion = false; aperture_ratio = 1.0f; type = CAMERA_PERSPECTIVE; panorama_type = PANORAMA_EQUIRECTANGULAR; fisheye_fov = M_PI_F; fisheye_lens = 10.5f; latitude_min = -M_PI_2_F; latitude_max = M_PI_2_F; longitude_min = -M_PI_F; longitude_max = M_PI_F; fov = M_PI_4_F; sensorwidth = 0.036f; sensorheight = 0.024f; nearclip = 1e-5f; farclip = 1e5f; width = 1024; height = 512; resolution = 1; viewplane.left = -((float)width/(float)height); viewplane.right = (float)width/(float)height; viewplane.bottom = -1.0f; viewplane.top = 1.0f; screentoworld = transform_identity(); rastertoworld = transform_identity(); ndctoworld = transform_identity(); rastertocamera = transform_identity(); cameratoworld = transform_identity(); worldtoraster = transform_identity(); dx = make_float3(0.0f, 0.0f, 0.0f); dy = make_float3(0.0f, 0.0f, 0.0f); need_update = true; need_device_update = true; need_flags_update = true; previous_need_motion = -1; }
Transform transform_inverse(const Transform& tfm) { union { Transform T; float M[4][4]; } R, M; R.T = transform_identity(); M.T = tfm; if(!transform_matrix4_gj_inverse(R.M, M.M)) return transform_identity(); return R.T; }
static int bb_render_glyph(void *backend_data, drawctx_t *context, source_t *source, sysarg_t ox, sysarg_t oy, glyph_id_t glyph_id) { bitmap_backend_data_t *data = (bitmap_backend_data_t *) backend_data; glyph_metrics_t glyph_metrics; int rc = bb_get_glyph_metrics(backend_data, glyph_id, &glyph_metrics); if (rc != EOK) return rc; surface_t *glyph_surface; rc = get_glyph_surface(data, glyph_id, &glyph_surface); if (rc != EOK) return rc; native_t x = ox + glyph_metrics.left_side_bearing; native_t y = oy - glyph_metrics.ascender; transform_t transform; transform_identity(&transform); transform_translate(&transform, x, y); source_set_transform(source, transform); source_set_mask(source, glyph_surface, false); drawctx_transfer(context, x, y, glyph_metrics.width, glyph_metrics.height); return EOK; }
static int get_glyph_surface(bitmap_backend_data_t *data, glyph_id_t glyph_id, surface_t **result) { if (glyph_id >= data->glyph_count) return ENOENT; if (data->glyph_cache[glyph_id].surface != NULL) { *result = data->glyph_cache[glyph_id].surface; return EOK; } surface_t *raw_surface; int rc = data->decoder->load_glyph_surface(data->decoder_data, glyph_id, &raw_surface); if (rc != EOK) return rc; sysarg_t w; sysarg_t h; surface_get_resolution(raw_surface, &w, &h); if (!data->scale) { *result = raw_surface; return EOK; } source_t source; source_init(&source); source_set_texture(&source, raw_surface, PIXELMAP_EXTEND_TRANSPARENT_BLACK); transform_t transform; transform_identity(&transform); transform_translate(&transform, 0.5, 0.5); transform_scale(&transform, data->scale_ratio, data->scale_ratio); source_set_transform(&source, transform); surface_coord_t scaled_width = (data->scale_ratio * ((double) w) + 0.5); surface_coord_t scaled_height = (data->scale_ratio * ((double) h) + 0.5); surface_t *scaled_surface = surface_create(scaled_width, scaled_height, NULL, 0); if (!scaled_surface) { surface_destroy(raw_surface); return ENOMEM; } drawctx_t context; drawctx_init(&context, scaled_surface); drawctx_set_source(&context, &source); drawctx_transfer(&context, 0, 0, scaled_width, scaled_height); surface_destroy(raw_surface); data->glyph_cache[glyph_id].surface = scaled_surface; *result = scaled_surface; return EOK; }
XMLReadState() : scene(NULL), smooth(false), shader(0), dicing_rate(0.0f), displacement_method(Mesh::DISPLACE_BUMP) { tfm = transform_identity(); }
void source_init(source_t *source) { transform_identity(&source->transform); source->filter = filter_nearest; source->color = PIXEL(0, 0, 0, 0); source->texture = NULL; source->texture_tile = false; source->alpha = PIXEL(255, 0, 0, 0); source->mask = NULL; source->mask_tile = false; }
OCT_NAMESPACE_BEGIN ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CONSTRUCTOR ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Object::Object(Scene* scene_) { scene = scene_; name = ""; mesh = 0; light = 0; tfm = transform_identity(); visibility = true; random_id = 0; pass_id = 0; particle_id = 0; use_holdout = false; need_update = true; } //Object()
Camera::Camera() : Node(node_type) { shutter_table_offset = TABLE_OFFSET_INVALID; width = 1024; height = 512; resolution = 1; motion.pre = transform_identity(); motion.post = transform_identity(); use_motion = false; use_perspective_motion = false; shutter_curve.resize(RAMP_TABLE_SIZE); for(int i = 0; i < shutter_curve.size(); ++i) { shutter_curve[i] = 1.0f; } compute_auto_viewplane(); screentoworld = transform_identity(); rastertoworld = transform_identity(); ndctoworld = transform_identity(); rastertocamera = transform_identity(); cameratoworld = transform_identity(); worldtoraster = transform_identity(); dx = make_float3(0.0f, 0.0f, 0.0f); dy = make_float3(0.0f, 0.0f, 0.0f); need_update = true; need_device_update = true; need_flags_update = true; previous_need_motion = -1; }
void Camera::update() { if(!need_update) return; /* Full viewport to camera border in the viewport. */ Transform fulltoborder = transform_from_viewplane(viewport_camera_border); Transform bordertofull = transform_inverse(fulltoborder); /* ndc to raster */ Transform screentocamera; Transform ndctoraster = transform_scale(width, height, 1.0f) * bordertofull; /* raster to screen */ Transform screentondc = fulltoborder * transform_from_viewplane(viewplane); Transform screentoraster = ndctoraster * screentondc; Transform rastertoscreen = transform_inverse(screentoraster); /* screen to camera */ if(type == CAMERA_PERSPECTIVE) screentocamera = transform_inverse(transform_perspective(fov, nearclip, farclip)); else if(type == CAMERA_ORTHOGRAPHIC) screentocamera = transform_inverse(transform_orthographic(nearclip, farclip)); else screentocamera = transform_identity(); Transform cameratoscreen = transform_inverse(screentocamera); rastertocamera = screentocamera * rastertoscreen; cameratoraster = screentoraster * cameratoscreen; cameratoworld = matrix; screentoworld = cameratoworld * screentocamera; rastertoworld = cameratoworld * rastertocamera; ndctoworld = rastertoworld * ndctoraster; /* note we recompose matrices instead of taking inverses of the above, this * is needed to avoid inverting near degenerate matrices that happen due to * precision issues with large scenes */ worldtocamera = transform_inverse(matrix); worldtoscreen = cameratoscreen * worldtocamera; worldtondc = screentondc * worldtoscreen; worldtoraster = ndctoraster * worldtondc; /* differentials */ if(type == CAMERA_ORTHOGRAPHIC) { dx = transform_direction(&rastertocamera, make_float3(1, 0, 0)); dy = transform_direction(&rastertocamera, make_float3(0, 1, 0)); } else if(type == CAMERA_PERSPECTIVE) { dx = transform_perspective(&rastertocamera, make_float3(1, 0, 0)) - transform_perspective(&rastertocamera, make_float3(0, 0, 0)); dy = transform_perspective(&rastertocamera, make_float3(0, 1, 0)) - transform_perspective(&rastertocamera, make_float3(0, 0, 0)); } else { dx = make_float3(0.0f, 0.0f, 0.0f); dy = make_float3(0.0f, 0.0f, 0.0f); } dx = transform_direction(&cameratoworld, dx); dy = transform_direction(&cameratoworld, dy); need_update = false; need_device_update = true; need_flags_update = true; }
void BVH4::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility) { if(leaf) { int4 *data = &pack.leaf_nodes[idx]; int4 c = data[0]; /* Refit leaf node. */ for(int prim = c.x; prim < c.y; prim++) { int pidx = pack.prim_index[prim]; int tob = pack.prim_object[prim]; Object *ob = objects[tob]; if(pidx == -1) { /* Object instance. */ bbox.grow(ob->bounds); } else { /* Primitives. */ const Mesh *mesh = ob->mesh; if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) { /* Curves. */ int str_offset = (params.top_level)? mesh->curve_offset: 0; Mesh::Curve curve = mesh->get_curve(pidx - str_offset); int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]); curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox); visibility |= PATH_RAY_CURVE; /* Motion curves. */ if(mesh->use_motion_blur) { Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if(attr) { size_t mesh_size = mesh->curve_keys.size(); size_t steps = mesh->motion_steps - 1; float3 *key_steps = attr->data_float3(); for(size_t i = 0; i < steps; i++) curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bbox); } } } else { /* Triangles. */ int tri_offset = (params.top_level)? mesh->tri_offset: 0; Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset); const float3 *vpos = &mesh->verts[0]; triangle.bounds_grow(vpos, bbox); /* Motion triangles. */ if(mesh->use_motion_blur) { Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if(attr) { size_t mesh_size = mesh->verts.size(); size_t steps = mesh->motion_steps - 1; float3 *vert_steps = attr->data_float3(); for(size_t i = 0; i < steps; i++) triangle.bounds_grow(vert_steps + i*mesh_size, bbox); } } } } visibility |= ob->visibility_for_tracing(); } /* TODO(sergey): This is actually a copy of pack_leaf(), * but this chunk of code only knows actual data and has * no idea about BVHNode. * * Would be nice to de-duplicate code, but trying to make * making code more general ends up in much nastier code * in my opinion so far. * * Same applies to the inner nodes case below. */ float4 leaf_data[BVH_QNODE_LEAF_SIZE]; leaf_data[0].x = __int_as_float(c.x); leaf_data[0].y = __int_as_float(c.y); leaf_data[0].z = __uint_as_float(visibility); leaf_data[0].w = __uint_as_float(c.w); memcpy(&pack.leaf_nodes[idx], leaf_data, sizeof(float4)*BVH_QNODE_LEAF_SIZE); } else { int4 *data = &pack.nodes[idx]; bool is_unaligned = (data[0].x & PATH_RAY_NODE_UNALIGNED) != 0; int4 c; if(is_unaligned) { c = data[13]; } else { c = data[7]; } /* Refit inner node, set bbox from children. */ BoundBox child_bbox[4] = {BoundBox::empty, BoundBox::empty, BoundBox::empty, BoundBox::empty}; uint child_visibility[4] = {0}; int num_nodes = 0; for(int i = 0; i < 4; ++i) { if(c[i] != 0) { refit_node((c[i] < 0)? -c[i]-1: c[i], (c[i] < 0), child_bbox[i], child_visibility[i]); ++num_nodes; bbox.grow(child_bbox[i]); visibility |= child_visibility[i]; } } if(is_unaligned) { Transform aligned_space[4] = {transform_identity(), transform_identity(), transform_identity(), transform_identity()}; pack_unaligned_node(idx, aligned_space, child_bbox, &c[0], visibility, 0.0f, 1.0f, 4); } else { pack_aligned_node(idx, child_bbox, &c[0], visibility, 0.0f, 1.0f, 4); } } }
void BVH8::refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility) { if (leaf) { int4 *data = &pack.leaf_nodes[idx]; int4 c = data[0]; /* Refit leaf node. */ for (int prim = c.x; prim < c.y; prim++) { int pidx = pack.prim_index[prim]; int tob = pack.prim_object[prim]; Object *ob = objects[tob]; if (pidx == -1) { /* Object instance. */ bbox.grow(ob->bounds); } else { /* Primitives. */ const Mesh *mesh = ob->mesh; if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) { /* Curves. */ int str_offset = (params.top_level) ? mesh->curve_offset : 0; Mesh::Curve curve = mesh->get_curve(pidx - str_offset); int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]); curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox); visibility |= PATH_RAY_CURVE; /* Motion curves. */ if (mesh->use_motion_blur) { Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr) { size_t mesh_size = mesh->curve_keys.size(); size_t steps = mesh->motion_steps - 1; float3 *key_steps = attr->data_float3(); for (size_t i = 0; i < steps; i++) { curve.bounds_grow(k, key_steps + i * mesh_size, &mesh->curve_radius[0], bbox); } } } } else { /* Triangles. */ int tri_offset = (params.top_level) ? mesh->tri_offset : 0; Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset); const float3 *vpos = &mesh->verts[0]; triangle.bounds_grow(vpos, bbox); /* Motion triangles. */ if (mesh->use_motion_blur) { Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr) { size_t mesh_size = mesh->verts.size(); size_t steps = mesh->motion_steps - 1; float3 *vert_steps = attr->data_float3(); for (size_t i = 0; i < steps; i++) { triangle.bounds_grow(vert_steps + i * mesh_size, bbox); } } } } } visibility |= ob->visibility; } float4 leaf_data[BVH_ONODE_LEAF_SIZE]; leaf_data[0].x = __int_as_float(c.x); leaf_data[0].y = __int_as_float(c.y); leaf_data[0].z = __uint_as_float(visibility); leaf_data[0].w = __uint_as_float(c.w); memcpy(&pack.leaf_nodes[idx], leaf_data, sizeof(float4) * BVH_ONODE_LEAF_SIZE); } else { float8 *data = (float8 *)&pack.nodes[idx]; bool is_unaligned = (__float_as_uint(data[0].a) & PATH_RAY_NODE_UNALIGNED) != 0; /* Refit inner node, set bbox from children. */ BoundBox child_bbox[8] = {BoundBox::empty, BoundBox::empty, BoundBox::empty, BoundBox::empty, BoundBox::empty, BoundBox::empty, BoundBox::empty, BoundBox::empty}; int child[8]; uint child_visibility[8] = {0}; int num_nodes = 0; for (int i = 0; i < 8; ++i) { child[i] = __float_as_int(data[(is_unaligned) ? 13 : 7][i]); if (child[i] != 0) { refit_node((child[i] < 0) ? -child[i] - 1 : child[i], (child[i] < 0), child_bbox[i], child_visibility[i]); ++num_nodes; bbox.grow(child_bbox[i]); visibility |= child_visibility[i]; } } if (is_unaligned) { Transform aligned_space[8] = {transform_identity(), transform_identity(), transform_identity(), transform_identity(), transform_identity(), transform_identity(), transform_identity(), transform_identity()}; pack_unaligned_node( idx, aligned_space, child_bbox, child, visibility, 0.0f, 1.0f, num_nodes); } else { pack_aligned_node(idx, child_bbox, child, visibility, 0.0f, 1.0f, num_nodes); } } }
void read(istream& stream) { read(stream, transform_identity()); }
void source_reset_transform(source_t *source) { transform_identity(&source->transform); }
Camera::Camera() { shuttertime = 1.0f; motion_position = MOTION_POSITION_CENTER; shutter_table_offset = TABLE_OFFSET_INVALID; aperturesize = 0.0f; focaldistance = 10.0f; blades = 0; bladesrotation = 0.0f; matrix = transform_identity(); motion.pre = transform_identity(); motion.post = transform_identity(); use_motion = false; use_perspective_motion = false; aperture_ratio = 1.0f; type = CAMERA_PERSPECTIVE; panorama_type = PANORAMA_EQUIRECTANGULAR; fisheye_fov = M_PI_F; fisheye_lens = 10.5f; latitude_min = -M_PI_2_F; latitude_max = M_PI_2_F; longitude_min = -M_PI_F; longitude_max = M_PI_F; fov = M_PI_4_F; fov_pre = fov_post = fov; sensorwidth = 0.036f; sensorheight = 0.024f; nearclip = 1e-5f; farclip = 1e5f; width = 1024; height = 512; resolution = 1; viewplane.left = -((float)width/(float)height); viewplane.right = (float)width/(float)height; viewplane.bottom = -1.0f; viewplane.top = 1.0f; screentoworld = transform_identity(); rastertoworld = transform_identity(); ndctoworld = transform_identity(); rastertocamera = transform_identity(); cameratoworld = transform_identity(); worldtoraster = transform_identity(); dx = make_float3(0.0f, 0.0f, 0.0f); dy = make_float3(0.0f, 0.0f, 0.0f); need_update = true; need_device_update = true; need_flags_update = true; previous_need_motion = -1; /* Initialize shutter curve. */ const int num_shutter_points = sizeof(shutter_curve) / sizeof(*shutter_curve); for(int i = 0; i < num_shutter_points; ++i) { shutter_curve[i] = 1.0f; } /* Initialize rolling shutter effect. */ rolling_shutter_type = ROLLING_SHUTTER_NONE; rolling_shutter_duration = 0.1f; }