Cleanup: use braces for sources in intern/
Omitted intern/itasc as some of these sources are from KDL: https://www.orocos.org/kdl.html
This commit is contained in:
parent
e3444fd314
commit
5b9740c913
@ -22,15 +22,17 @@ void AUD_destroySet(void *set)
|
|||||||
|
|
||||||
char AUD_removeSet(void *set, void *entry)
|
char AUD_removeSet(void *set, void *entry)
|
||||||
{
|
{
|
||||||
if (set)
|
if (set) {
|
||||||
return reinterpret_cast<std::set<void *> *>(set)->erase(entry);
|
return reinterpret_cast<std::set<void *> *>(set)->erase(entry);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AUD_addSet(void *set, void *entry)
|
void AUD_addSet(void *set, void *entry)
|
||||||
{
|
{
|
||||||
if (entry)
|
if (entry) {
|
||||||
reinterpret_cast<std::set<void *> *>(set)->insert(entry);
|
reinterpret_cast<std::set<void *> *>(set)->insert(entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *AUD_getSet(void *set)
|
void *AUD_getSet(void *set)
|
||||||
|
@ -61,8 +61,9 @@ static void session_print(const string &str)
|
|||||||
int len = str.size();
|
int len = str.size();
|
||||||
maxlen = max(len, maxlen);
|
maxlen = max(len, maxlen);
|
||||||
|
|
||||||
for (int i = len; i < maxlen; i++)
|
for (int i = len; i < maxlen; i++) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
/* flush because we don't write an end of line */
|
/* flush because we don't write an end of line */
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@ -76,8 +77,9 @@ static void session_print_status()
|
|||||||
double progress = options.session->progress.get_progress();
|
double progress = options.session->progress.get_progress();
|
||||||
options.session->progress.get_status(status, substatus);
|
options.session->progress.get_status(status, substatus);
|
||||||
|
|
||||||
if (substatus != "")
|
if (substatus != "") {
|
||||||
status += ": " + substatus;
|
status += ": " + substatus;
|
||||||
|
}
|
||||||
|
|
||||||
/* print status */
|
/* print status */
|
||||||
status = string_printf("Progress %05.2f %s", (double)progress * 100, status.c_str());
|
status = string_printf("Progress %05.2f %s", (double)progress * 100, status.c_str());
|
||||||
@ -141,8 +143,9 @@ static void session_init()
|
|||||||
options.output_filepath, options.output_pass, session_print));
|
options.output_filepath, options.output_pass, session_print));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.session_params.background && !options.quiet)
|
if (options.session_params.background && !options.quiet) {
|
||||||
options.session->progress.set_update_callback(function_bind(&session_print_status));
|
options.session->progress.set_update_callback(function_bind(&session_print_status));
|
||||||
|
}
|
||||||
#ifdef WITH_CYCLES_STANDALONE_GUI
|
#ifdef WITH_CYCLES_STANDALONE_GUI
|
||||||
else
|
else
|
||||||
options.session->progress.set_update_callback(function_bind(&window_redraw));
|
options.session->progress.set_update_callback(function_bind(&window_redraw));
|
||||||
@ -347,8 +350,9 @@ static void keyboard(unsigned char key)
|
|||||||
|
|
||||||
static int files_parse(int argc, const char *argv[])
|
static int files_parse(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
if (argc > 0)
|
if (argc > 0) {
|
||||||
options.filepath = argv[0];
|
options.filepath = argv[0];
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -371,8 +375,9 @@ static void options_parse(int argc, const char **argv)
|
|||||||
/* List devices for which support is compiled in. */
|
/* List devices for which support is compiled in. */
|
||||||
vector<DeviceType> types = Device::available_types();
|
vector<DeviceType> types = Device::available_types();
|
||||||
foreach (DeviceType type, types) {
|
foreach (DeviceType type, types) {
|
||||||
if (device_names != "")
|
if (device_names != "") {
|
||||||
device_names += ", ";
|
device_names += ", ";
|
||||||
|
}
|
||||||
|
|
||||||
device_names += Device::string_from_type(type);
|
device_names += Device::string_from_type(type);
|
||||||
}
|
}
|
||||||
@ -478,10 +483,12 @@ static void options_parse(int argc, const char **argv)
|
|||||||
|
|
||||||
options.session_params.use_profiling = profile;
|
options.session_params.use_profiling = profile;
|
||||||
|
|
||||||
if (ssname == "osl")
|
if (ssname == "osl") {
|
||||||
options.scene_params.shadingsystem = SHADINGSYSTEM_OSL;
|
options.scene_params.shadingsystem = SHADINGSYSTEM_OSL;
|
||||||
else if (ssname == "svm")
|
}
|
||||||
|
else if (ssname == "svm") {
|
||||||
options.scene_params.shadingsystem = SHADINGSYSTEM_SVM;
|
options.scene_params.shadingsystem = SHADINGSYSTEM_SVM;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef WITH_CYCLES_STANDALONE_GUI
|
#ifndef WITH_CYCLES_STANDALONE_GUI
|
||||||
options.session_params.background = true;
|
options.session_params.background = true;
|
||||||
|
@ -130,8 +130,9 @@ static bool xml_read_float3_array(vector<float3> &value, xml_node node, const ch
|
|||||||
vector<float> array;
|
vector<float> array;
|
||||||
|
|
||||||
if (xml_read_float_array(array, node, name)) {
|
if (xml_read_float_array(array, node, name)) {
|
||||||
for (size_t i = 0; i < array.size(); i += 3)
|
for (size_t i = 0; i < array.size(); i += 3) {
|
||||||
value.push_back(make_float3(array[i + 0], array[i + 1], array[i + 2]));
|
value.push_back(make_float3(array[i + 0], array[i + 1], array[i + 2]));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -167,8 +168,9 @@ static bool xml_equal_string(xml_node node, const char *name, const char *value)
|
|||||||
{
|
{
|
||||||
xml_attribute attr = node.attribute(name);
|
xml_attribute attr = node.attribute(name);
|
||||||
|
|
||||||
if (attr)
|
if (attr) {
|
||||||
return string_iequals(attr.value(), value);
|
return string_iequals(attr.value(), value);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -255,40 +257,48 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node
|
|||||||
ShaderNode *fromnode = (ShaderNode *)graph_reader.node_map[from_node_name];
|
ShaderNode *fromnode = (ShaderNode *)graph_reader.node_map[from_node_name];
|
||||||
|
|
||||||
foreach (ShaderOutput *out, fromnode->outputs)
|
foreach (ShaderOutput *out, fromnode->outputs)
|
||||||
if (string_iequals(out->socket_type.name.string(), from_socket_name.string()))
|
if (string_iequals(out->socket_type.name.string(), from_socket_name.string())) {
|
||||||
output = out;
|
output = out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!output)
|
if (!output) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Unknown output socket name \"%s\" on \"%s\".\n",
|
"Unknown output socket name \"%s\" on \"%s\".\n",
|
||||||
from_node_name.c_str(),
|
from_node_name.c_str(),
|
||||||
from_socket_name.c_str());
|
from_socket_name.c_str());
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
fprintf(stderr, "Unknown shader node name \"%s\".\n", from_node_name.c_str());
|
fprintf(stderr, "Unknown shader node name \"%s\".\n", from_node_name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
if (graph_reader.node_map.find(to_node_name) != graph_reader.node_map.end()) {
|
if (graph_reader.node_map.find(to_node_name) != graph_reader.node_map.end()) {
|
||||||
ShaderNode *tonode = (ShaderNode *)graph_reader.node_map[to_node_name];
|
ShaderNode *tonode = (ShaderNode *)graph_reader.node_map[to_node_name];
|
||||||
|
|
||||||
foreach (ShaderInput *in, tonode->inputs)
|
foreach (ShaderInput *in, tonode->inputs)
|
||||||
if (string_iequals(in->socket_type.name.string(), to_socket_name.string()))
|
if (string_iequals(in->socket_type.name.string(), to_socket_name.string())) {
|
||||||
input = in;
|
input = in;
|
||||||
|
}
|
||||||
|
|
||||||
if (!input)
|
if (!input) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Unknown input socket name \"%s\" on \"%s\".\n",
|
"Unknown input socket name \"%s\" on \"%s\".\n",
|
||||||
to_socket_name.c_str(),
|
to_socket_name.c_str(),
|
||||||
to_node_name.c_str());
|
to_node_name.c_str());
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
fprintf(stderr, "Unknown shader node name \"%s\".\n", to_node_name.c_str());
|
fprintf(stderr, "Unknown shader node name \"%s\".\n", to_node_name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
/* connect */
|
/* connect */
|
||||||
if (output && input)
|
if (output && input) {
|
||||||
graph->connect(output, input);
|
graph->connect(output, input);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
fprintf(stderr, "Invalid from or to value for connect node.\n");
|
fprintf(stderr, "Invalid from or to value for connect node.\n");
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -328,8 +338,9 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* exception for name collision */
|
/* exception for name collision */
|
||||||
if (node_name == "background")
|
if (node_name == "background") {
|
||||||
node_name = "background_shader";
|
node_name = "background_shader";
|
||||||
|
}
|
||||||
|
|
||||||
const NodeType *node_type = NodeType::find(node_name);
|
const NodeType *node_type = NodeType::find(node_name);
|
||||||
|
|
||||||
@ -446,8 +457,9 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
|
|||||||
mesh->set_verts(P_array);
|
mesh->set_verts(P_array);
|
||||||
|
|
||||||
size_t num_triangles = 0;
|
size_t num_triangles = 0;
|
||||||
for (size_t i = 0; i < nverts.size(); i++)
|
for (size_t i = 0; i < nverts.size(); i++) {
|
||||||
num_triangles += nverts[i] - 2;
|
num_triangles += nverts[i] - 2;
|
||||||
|
}
|
||||||
mesh->reserve_mesh(mesh->get_verts().size(), num_triangles);
|
mesh->reserve_mesh(mesh->get_verts().size(), num_triangles);
|
||||||
|
|
||||||
/* create triangles */
|
/* create triangles */
|
||||||
@ -615,17 +627,20 @@ static void xml_read_state(XMLReadState &state, xml_node node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (!found) {
|
||||||
fprintf(stderr, "Unknown shader \"%s\".\n", shadername.c_str());
|
fprintf(stderr, "Unknown shader \"%s\".\n", shadername.c_str());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xml_read_float(&state.dicing_rate, node, "dicing_rate");
|
xml_read_float(&state.dicing_rate, node, "dicing_rate");
|
||||||
|
|
||||||
/* read smooth/flat */
|
/* read smooth/flat */
|
||||||
if (xml_equal_string(node, "interpolation", "smooth"))
|
if (xml_equal_string(node, "interpolation", "smooth")) {
|
||||||
state.smooth = true;
|
state.smooth = true;
|
||||||
else if (xml_equal_string(node, "interpolation", "flat"))
|
}
|
||||||
|
else if (xml_equal_string(node, "interpolation", "flat")) {
|
||||||
state.smooth = false;
|
state.smooth = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scene */
|
/* Scene */
|
||||||
@ -671,17 +686,19 @@ static void xml_read_scene(XMLReadState &state, xml_node scene_node)
|
|||||||
else if (string_iequals(node.name(), "include")) {
|
else if (string_iequals(node.name(), "include")) {
|
||||||
string src;
|
string src;
|
||||||
|
|
||||||
if (xml_read_string(&src, node, "src"))
|
if (xml_read_string(&src, node, "src")) {
|
||||||
xml_read_include(state, src);
|
xml_read_include(state, src);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#ifdef WITH_ALEMBIC
|
#ifdef WITH_ALEMBIC
|
||||||
else if (string_iequals(node.name(), "alembic")) {
|
else if (string_iequals(node.name(), "alembic")) {
|
||||||
xml_read_alembic(state, node);
|
xml_read_alembic(state, node);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else {
|
||||||
fprintf(stderr, "Unknown node \"%s\".\n", node.name());
|
fprintf(stderr, "Unknown node \"%s\".\n", node.name());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Include */
|
/* Include */
|
||||||
|
@ -174,8 +174,9 @@ static void window_display()
|
|||||||
|
|
||||||
glRasterPos3f(0, 0, 0);
|
glRasterPos3f(0, 0, 0);
|
||||||
|
|
||||||
if (V.display)
|
if (V.display) {
|
||||||
V.display();
|
V.display();
|
||||||
|
}
|
||||||
|
|
||||||
SDL_GL_SwapWindow(V.window);
|
SDL_GL_SwapWindow(V.window);
|
||||||
window_opengl_context_disable();
|
window_opengl_context_disable();
|
||||||
@ -195,12 +196,14 @@ static void window_reshape(int width, int height)
|
|||||||
|
|
||||||
static bool window_keyboard(unsigned char key)
|
static bool window_keyboard(unsigned char key)
|
||||||
{
|
{
|
||||||
if (V.keyboard)
|
if (V.keyboard) {
|
||||||
V.keyboard(key);
|
V.keyboard(key);
|
||||||
|
}
|
||||||
|
|
||||||
if (key == 'q') {
|
if (key == 'q') {
|
||||||
if (V.exitf)
|
if (V.exitf) {
|
||||||
V.exitf();
|
V.exitf();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,8 +240,9 @@ static void window_motion(int x, int y)
|
|||||||
const int distX = x - V.mouseX;
|
const int distX = x - V.mouseX;
|
||||||
const int distY = y - V.mouseY;
|
const int distY = y - V.mouseY;
|
||||||
|
|
||||||
if (V.motion)
|
if (V.motion) {
|
||||||
V.motion(distX, distY, but);
|
V.motion(distX, distY, but);
|
||||||
|
}
|
||||||
|
|
||||||
V.mouseX = x;
|
V.mouseX = x;
|
||||||
V.mouseY = y;
|
V.mouseY = y;
|
||||||
|
@ -142,8 +142,9 @@ static float blender_camera_focal_distance(BL::RenderEngine &b_engine,
|
|||||||
{
|
{
|
||||||
BL::Object b_dof_object = b_camera.dof().focus_object();
|
BL::Object b_dof_object = b_camera.dof().focus_object();
|
||||||
|
|
||||||
if (!b_dof_object)
|
if (!b_dof_object) {
|
||||||
return b_camera.dof().focus_distance();
|
return b_camera.dof().focus_distance();
|
||||||
|
}
|
||||||
|
|
||||||
Transform dofmat = get_transform(b_dof_object.matrix_world());
|
Transform dofmat = get_transform(b_dof_object.matrix_world());
|
||||||
|
|
||||||
@ -202,10 +203,12 @@ static void blender_camera_from_object(BlenderCamera *bcam,
|
|||||||
bcam->type = CAMERA_ORTHOGRAPHIC;
|
bcam->type = CAMERA_ORTHOGRAPHIC;
|
||||||
break;
|
break;
|
||||||
case BL::Camera::type_PANO:
|
case BL::Camera::type_PANO:
|
||||||
if (!skip_panorama)
|
if (!skip_panorama) {
|
||||||
bcam->type = CAMERA_PANORAMA;
|
bcam->type = CAMERA_PANORAMA;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
bcam->type = CAMERA_PERSPECTIVE;
|
bcam->type = CAMERA_PERSPECTIVE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case BL::Camera::type_PERSP:
|
case BL::Camera::type_PERSP:
|
||||||
default:
|
default:
|
||||||
@ -252,10 +255,12 @@ static void blender_camera_from_object(BlenderCamera *bcam,
|
|||||||
float fstop = b_camera.dof().aperture_fstop();
|
float fstop = b_camera.dof().aperture_fstop();
|
||||||
fstop = max(fstop, 1e-5f);
|
fstop = max(fstop, 1e-5f);
|
||||||
|
|
||||||
if (bcam->type == CAMERA_ORTHOGRAPHIC)
|
if (bcam->type == CAMERA_ORTHOGRAPHIC) {
|
||||||
bcam->aperturesize = 1.0f / (2.0f * fstop);
|
bcam->aperturesize = 1.0f / (2.0f * fstop);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
bcam->aperturesize = (bcam->lens * 1e-3f) / (2.0f * fstop);
|
bcam->aperturesize = (bcam->lens * 1e-3f) / (2.0f * fstop);
|
||||||
|
}
|
||||||
|
|
||||||
bcam->apertureblades = b_camera.dof().aperture_blades();
|
bcam->apertureblades = b_camera.dof().aperture_blades();
|
||||||
bcam->aperturerotation = b_camera.dof().aperture_rotation();
|
bcam->aperturerotation = b_camera.dof().aperture_rotation();
|
||||||
@ -277,13 +282,16 @@ static void blender_camera_from_object(BlenderCamera *bcam,
|
|||||||
bcam->sensor_width = b_camera.sensor_width();
|
bcam->sensor_width = b_camera.sensor_width();
|
||||||
bcam->sensor_height = b_camera.sensor_height();
|
bcam->sensor_height = b_camera.sensor_height();
|
||||||
|
|
||||||
if (b_camera.sensor_fit() == BL::Camera::sensor_fit_AUTO)
|
if (b_camera.sensor_fit() == BL::Camera::sensor_fit_AUTO) {
|
||||||
bcam->sensor_fit = BlenderCamera::AUTO;
|
bcam->sensor_fit = BlenderCamera::AUTO;
|
||||||
else if (b_camera.sensor_fit() == BL::Camera::sensor_fit_HORIZONTAL)
|
}
|
||||||
|
else if (b_camera.sensor_fit() == BL::Camera::sensor_fit_HORIZONTAL) {
|
||||||
bcam->sensor_fit = BlenderCamera::HORIZONTAL;
|
bcam->sensor_fit = BlenderCamera::HORIZONTAL;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
bcam->sensor_fit = BlenderCamera::VERTICAL;
|
bcam->sensor_fit = BlenderCamera::VERTICAL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (b_ob_data.is_a(&RNA_Light)) {
|
else if (b_ob_data.is_a(&RNA_Light)) {
|
||||||
/* Can also look through spot light. */
|
/* Can also look through spot light. */
|
||||||
BL::SpotLight b_light(b_ob_data);
|
BL::SpotLight b_light(b_ob_data);
|
||||||
@ -509,13 +517,16 @@ static void blender_camera_sync(Camera *cam,
|
|||||||
cam->set_use_spherical_stereo(bcam->use_spherical_stereo);
|
cam->set_use_spherical_stereo(bcam->use_spherical_stereo);
|
||||||
|
|
||||||
if (cam->get_use_spherical_stereo()) {
|
if (cam->get_use_spherical_stereo()) {
|
||||||
if (strcmp(viewname, "left") == 0)
|
if (strcmp(viewname, "left") == 0) {
|
||||||
cam->set_stereo_eye(Camera::STEREO_LEFT);
|
cam->set_stereo_eye(Camera::STEREO_LEFT);
|
||||||
else if (strcmp(viewname, "right") == 0)
|
}
|
||||||
|
else if (strcmp(viewname, "right") == 0) {
|
||||||
cam->set_stereo_eye(Camera::STEREO_RIGHT);
|
cam->set_stereo_eye(Camera::STEREO_RIGHT);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
cam->set_stereo_eye(Camera::STEREO_NONE);
|
cam->set_stereo_eye(Camera::STEREO_NONE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cam->set_use_pole_merge(bcam->use_pole_merge);
|
cam->set_use_pole_merge(bcam->use_pole_merge);
|
||||||
cam->set_pole_merge_angle_from(bcam->pole_merge_angle_from);
|
cam->set_pole_merge_angle_from(bcam->pole_merge_angle_from);
|
||||||
@ -604,8 +615,9 @@ void BlenderSync::sync_camera(BL::RenderSettings &b_render,
|
|||||||
/* camera object */
|
/* camera object */
|
||||||
BL::Object b_ob = b_scene.camera();
|
BL::Object b_ob = b_scene.camera();
|
||||||
|
|
||||||
if (b_override)
|
if (b_override) {
|
||||||
b_ob = b_override;
|
b_ob = b_override;
|
||||||
|
}
|
||||||
|
|
||||||
if (b_ob) {
|
if (b_ob) {
|
||||||
BL::Array<float, 16> b_ob_matrix;
|
BL::Array<float, 16> b_ob_matrix;
|
||||||
@ -641,8 +653,9 @@ void BlenderSync::sync_camera(BL::RenderSettings &b_render,
|
|||||||
void BlenderSync::sync_camera_motion(
|
void BlenderSync::sync_camera_motion(
|
||||||
BL::RenderSettings &b_render, BL::Object &b_ob, int width, int height, float motion_time)
|
BL::RenderSettings &b_render, BL::Object &b_ob, int width, int height, float motion_time)
|
||||||
{
|
{
|
||||||
if (!b_ob)
|
if (!b_ob) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Camera *cam = scene->camera;
|
Camera *cam = scene->camera;
|
||||||
BL::Array<float, 16> b_ob_matrix;
|
BL::Array<float, 16> b_ob_matrix;
|
||||||
@ -771,10 +784,12 @@ static void blender_camera_from_view(BlenderCamera *bcam,
|
|||||||
bcam->nearclip = -bcam->farclip;
|
bcam->nearclip = -bcam->farclip;
|
||||||
|
|
||||||
float sensor_size;
|
float sensor_size;
|
||||||
if (bcam->sensor_fit == BlenderCamera::VERTICAL)
|
if (bcam->sensor_fit == BlenderCamera::VERTICAL) {
|
||||||
sensor_size = bcam->sensor_height;
|
sensor_size = bcam->sensor_height;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
sensor_size = bcam->sensor_width;
|
sensor_size = bcam->sensor_width;
|
||||||
|
}
|
||||||
|
|
||||||
bcam->type = CAMERA_ORTHOGRAPHIC;
|
bcam->type = CAMERA_ORTHOGRAPHIC;
|
||||||
bcam->ortho_scale = b_rv3d.view_distance() * sensor_size / b_v3d.lens();
|
bcam->ortho_scale = b_rv3d.view_distance() * sensor_size / b_v3d.lens();
|
||||||
@ -890,8 +905,9 @@ static void blender_camera_border(BlenderCamera *bcam,
|
|||||||
|
|
||||||
BL::Object b_ob = (b_v3d.use_local_camera()) ? b_v3d.camera() : b_scene.camera();
|
BL::Object b_ob = (b_v3d.use_local_camera()) ? b_v3d.camera() : b_scene.camera();
|
||||||
|
|
||||||
if (!b_ob)
|
if (!b_ob) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine camera border inside the viewport. */
|
/* Determine camera border inside the viewport. */
|
||||||
BoundBox2D full_border;
|
BoundBox2D full_border;
|
||||||
@ -970,11 +986,13 @@ BufferParams BlenderSync::get_buffer_params(
|
|||||||
params.full_width = width;
|
params.full_width = width;
|
||||||
params.full_height = height;
|
params.full_height = height;
|
||||||
|
|
||||||
if (b_v3d && b_rv3d && b_rv3d.view_perspective() != BL::RegionView3D::view_perspective_CAMERA)
|
if (b_v3d && b_rv3d && b_rv3d.view_perspective() != BL::RegionView3D::view_perspective_CAMERA) {
|
||||||
use_border = b_v3d.use_render_border();
|
use_border = b_v3d.use_render_border();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
/* the camera can always have a passepartout */
|
/* the camera can always have a passepartout */
|
||||||
use_border = true;
|
use_border = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (use_border) {
|
if (use_border) {
|
||||||
/* border render */
|
/* border render */
|
||||||
|
@ -33,11 +33,13 @@ static float shaperadius(float shape, float root, float tip, float time)
|
|||||||
float radius = 1.0f - time;
|
float radius = 1.0f - time;
|
||||||
|
|
||||||
if (shape != 0.0f) {
|
if (shape != 0.0f) {
|
||||||
if (shape < 0.0f)
|
if (shape < 0.0f) {
|
||||||
radius = powf(radius, 1.0f + shape);
|
radius = powf(radius, 1.0f + shape);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
radius = powf(radius, 1.0f / (1.0f - shape));
|
radius = powf(radius, 1.0f / (1.0f - shape));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return (radius * (root - tip)) + tip;
|
return (radius * (root - tip)) + tip;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,8 +51,9 @@ static bool ObtainCacheParticleData(
|
|||||||
int curvenum = 0;
|
int curvenum = 0;
|
||||||
int keyno = 0;
|
int keyno = 0;
|
||||||
|
|
||||||
if (!(hair && b_mesh && b_ob && CData))
|
if (!(hair && b_mesh && b_ob && CData)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Transform tfm = get_transform(b_ob->matrix_world());
|
Transform tfm = get_transform(b_ob->matrix_world());
|
||||||
Transform itfm = transform_inverse(tfm);
|
Transform itfm = transform_inverse(tfm);
|
||||||
@ -147,8 +150,9 @@ static bool ObtainCacheParticleUV(Hair *hair,
|
|||||||
bool background,
|
bool background,
|
||||||
int uv_num)
|
int uv_num)
|
||||||
{
|
{
|
||||||
if (!(hair && b_mesh && b_ob && CData))
|
if (!(hair && b_mesh && b_ob && CData)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CData->curve_uv.clear();
|
CData->curve_uv.clear();
|
||||||
|
|
||||||
@ -211,8 +215,9 @@ static bool ObtainCacheParticleVcol(Hair *hair,
|
|||||||
bool background,
|
bool background,
|
||||||
int vcol_num)
|
int vcol_num)
|
||||||
{
|
{
|
||||||
if (!(hair && b_mesh && b_ob && CData))
|
if (!(hair && b_mesh && b_ob && CData)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CData->curve_vcol.clear();
|
CData->curve_vcol.clear();
|
||||||
|
|
||||||
@ -273,22 +278,27 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
|
|||||||
int num_keys = 0;
|
int num_keys = 0;
|
||||||
int num_curves = 0;
|
int num_curves = 0;
|
||||||
|
|
||||||
if (hair->num_curves())
|
if (hair->num_curves()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Attribute *attr_normal = NULL;
|
Attribute *attr_normal = NULL;
|
||||||
Attribute *attr_intercept = NULL;
|
Attribute *attr_intercept = NULL;
|
||||||
Attribute *attr_length = NULL;
|
Attribute *attr_length = NULL;
|
||||||
Attribute *attr_random = NULL;
|
Attribute *attr_random = NULL;
|
||||||
|
|
||||||
if (hair->need_attribute(scene, ATTR_STD_VERTEX_NORMAL))
|
if (hair->need_attribute(scene, ATTR_STD_VERTEX_NORMAL)) {
|
||||||
attr_normal = hair->attributes.add(ATTR_STD_VERTEX_NORMAL);
|
attr_normal = hair->attributes.add(ATTR_STD_VERTEX_NORMAL);
|
||||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
|
}
|
||||||
|
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
|
||||||
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
|
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
|
||||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH))
|
}
|
||||||
|
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH)) {
|
||||||
attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH);
|
attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH);
|
||||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM))
|
}
|
||||||
|
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) {
|
||||||
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
|
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
|
||||||
|
}
|
||||||
|
|
||||||
/* compute and reserve size of arrays */
|
/* compute and reserve size of arrays */
|
||||||
for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
|
for (int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
|
||||||
@ -330,8 +340,9 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
|
|||||||
radius = 0.0f;
|
radius = 0.0f;
|
||||||
}
|
}
|
||||||
hair->add_curve_key(ickey_loc, radius);
|
hair->add_curve_key(ickey_loc, radius);
|
||||||
if (attr_intercept)
|
if (attr_intercept) {
|
||||||
attr_intercept->add(time);
|
attr_intercept->add(time);
|
||||||
|
}
|
||||||
|
|
||||||
if (attr_normal) {
|
if (attr_normal) {
|
||||||
/* NOTE: the geometry normals are not computed for legacy particle hairs. This hair
|
/* NOTE: the geometry normals are not computed for legacy particle hairs. This hair
|
||||||
@ -374,7 +385,9 @@ static float4 CurveSegmentMotionCV(ParticleCurveData *CData, int sys, int curve,
|
|||||||
|
|
||||||
if (CData->psys_closetip[sys] &&
|
if (CData->psys_closetip[sys] &&
|
||||||
(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
|
(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1))
|
||||||
|
{
|
||||||
radius = 0.0f;
|
radius = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
/* curve motion keys store both position and radius in float4 */
|
/* curve motion keys store both position and radius in float4 */
|
||||||
float4 mP = float3_to_float4(ickey_loc);
|
float4 mP = float3_to_float4(ickey_loc);
|
||||||
@ -476,10 +489,11 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int
|
|||||||
* space, so we use an epsilon to detect actual changes */
|
* space, so we use an epsilon to detect actual changes */
|
||||||
float4 curve_key = float3_to_float4(hair->get_curve_keys()[i]);
|
float4 curve_key = float3_to_float4(hair->get_curve_keys()[i]);
|
||||||
curve_key.w = hair->get_curve_radius()[i];
|
curve_key.w = hair->get_curve_radius()[i];
|
||||||
if (len_squared(mP[i] - curve_key) > 1e-5f * 1e-5f)
|
if (len_squared(mP[i] - curve_key) > 1e-5f * 1e-5f) {
|
||||||
have_motion = true;
|
have_motion = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,10 +564,12 @@ void BlenderSync::sync_particle_hair(
|
|||||||
ObtainCacheParticleData(hair, &b_mesh, &b_ob, &CData, !preview);
|
ObtainCacheParticleData(hair, &b_mesh, &b_ob, &CData, !preview);
|
||||||
|
|
||||||
/* add hair geometry */
|
/* add hair geometry */
|
||||||
if (motion)
|
if (motion) {
|
||||||
ExportCurveSegmentsMotion(hair, &CData, motion_step);
|
ExportCurveSegmentsMotion(hair, &CData, motion_step);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
ExportCurveSegments(scene, hair, &CData);
|
ExportCurveSegments(scene, hair, &CData);
|
||||||
|
}
|
||||||
|
|
||||||
/* generated coordinates from first key. we should ideally get this from
|
/* generated coordinates from first key. we should ideally get this from
|
||||||
* blender to handle deforming objects */
|
* blender to handle deforming objects */
|
||||||
@ -578,8 +594,9 @@ void BlenderSync::sync_particle_hair(
|
|||||||
int vcol_num = 0;
|
int vcol_num = 0;
|
||||||
|
|
||||||
for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) {
|
for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) {
|
||||||
if (!hair->need_attribute(scene, ustring(l->name().c_str())))
|
if (!hair->need_attribute(scene, ustring(l->name().c_str()))) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ObtainCacheParticleVcol(hair, &b_mesh, &b_ob, &CData, !preview, vcol_num);
|
ObtainCacheParticleVcol(hair, &b_mesh, &b_ob, &CData, !preview, vcol_num);
|
||||||
|
|
||||||
@ -615,10 +632,12 @@ void BlenderSync::sync_particle_hair(
|
|||||||
|
|
||||||
ObtainCacheParticleUV(hair, &b_mesh, &b_ob, &CData, !preview, uv_num);
|
ObtainCacheParticleUV(hair, &b_mesh, &b_ob, &CData, !preview, uv_num);
|
||||||
|
|
||||||
if (active_render)
|
if (active_render) {
|
||||||
attr_uv = hair->attributes.add(std, name);
|
attr_uv = hair->attributes.add(std, name);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
attr_uv = hair->attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
|
attr_uv = hair->attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
|
||||||
|
}
|
||||||
|
|
||||||
float2 *uv = attr_uv->data_float2();
|
float2 *uv = attr_uv->data_float2();
|
||||||
|
|
||||||
|
@ -25,10 +25,12 @@ int blender_device_threads(BL::Scene &b_scene)
|
|||||||
{
|
{
|
||||||
BL::RenderSettings b_r = b_scene.render();
|
BL::RenderSettings b_r = b_scene.render();
|
||||||
|
|
||||||
if (b_r.threads_mode() == BL::RenderSettings::threads_mode_FIXED)
|
if (b_r.threads_mode() == BL::RenderSettings::threads_mode_FIXED) {
|
||||||
return b_r.threads();
|
return b_r.threads();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void static adjust_device_info_from_preferences(DeviceInfo &info, PointerRNA cpreferences)
|
void static adjust_device_info_from_preferences(DeviceInfo &info, PointerRNA cpreferences)
|
||||||
|
@ -56,11 +56,13 @@ array<Node *> BlenderSync::find_used_shaders(BL::Object &b_ob)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (used_shaders.size() == 0) {
|
if (used_shaders.size() == 0) {
|
||||||
if (material_override)
|
if (material_override) {
|
||||||
find_shader(material_override, used_shaders, default_shader);
|
find_shader(material_override, used_shaders, default_shader);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
used_shaders.push_back_slow(default_shader);
|
used_shaders.push_back_slow(default_shader);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return used_shaders;
|
return used_shaders;
|
||||||
}
|
}
|
||||||
@ -149,8 +151,9 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
|
|||||||
geom->set_used_shaders(used_shaders);
|
geom->set_used_shaders(used_shaders);
|
||||||
|
|
||||||
auto sync_func = [=]() mutable {
|
auto sync_func = [=]() mutable {
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_sync_status("Synchronizing object", b_ob_info.real_object.name());
|
progress.set_sync_status("Synchronizing object", b_ob_info.real_object.name());
|
||||||
|
|
||||||
@ -203,8 +206,9 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
|
|||||||
|
|
||||||
/* Ensure we only motion sync geometry that also had geometry synced, to avoid
|
/* Ensure we only motion sync geometry that also had geometry synced, to avoid
|
||||||
* unnecessary work and to ensure that its attributes were clear. */
|
* unnecessary work and to ensure that its attributes were clear. */
|
||||||
if (geometry_synced.find(geom) == geometry_synced.end())
|
if (geometry_synced.find(geom) == geometry_synced.end()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find time matching motion step required by geometry. */
|
/* Find time matching motion step required by geometry. */
|
||||||
int motion_step = geom->motion_step(motion_time);
|
int motion_step = geom->motion_step(motion_time);
|
||||||
@ -213,8 +217,9 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto sync_func = [=]() mutable {
|
auto sync_func = [=]() mutable {
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (b_ob_info.object_data.is_a(&RNA_Curves) || use_particle_hair) {
|
if (b_ob_info.object_data.is_a(&RNA_Curves) || use_particle_hair) {
|
||||||
Hair *hair = static_cast<Hair *>(geom);
|
Hair *hair = static_cast<Hair *>(geom);
|
||||||
|
@ -33,8 +33,9 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
|||||||
if (!light_map.add_or_update(&light, b_ob_info.real_object, b_parent, key) && !tfm_updated) {
|
if (!light_map.add_or_update(&light, b_ob_info.real_object, b_parent, key) && !tfm_updated) {
|
||||||
Shader *shader;
|
Shader *shader;
|
||||||
if (!shader_map.add_or_update(&shader, b_light)) {
|
if (!shader_map.add_or_update(&shader, b_light)) {
|
||||||
if (light->get_is_portal())
|
if (light->get_is_portal()) {
|
||||||
*use_portal = true;
|
*use_portal = true;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,13 +127,16 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
|||||||
light->set_random_id(hash_uint2(hash_string(b_ob_info.real_object.name().c_str()), 0));
|
light->set_random_id(hash_uint2(hash_string(b_ob_info.real_object.name().c_str()), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (light->get_light_type() == LIGHT_AREA)
|
if (light->get_light_type() == LIGHT_AREA) {
|
||||||
light->set_is_portal(get_boolean(clight, "is_portal"));
|
light->set_is_portal(get_boolean(clight, "is_portal"));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
light->set_is_portal(false);
|
light->set_is_portal(false);
|
||||||
|
}
|
||||||
|
|
||||||
if (light->get_is_portal())
|
if (light->get_is_portal()) {
|
||||||
*use_portal = true;
|
*use_portal = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* visibility */
|
/* visibility */
|
||||||
uint visibility = object_ray_visibility(b_ob_info.real_object);
|
uint visibility = object_ray_visibility(b_ob_info.real_object);
|
||||||
|
@ -648,10 +648,12 @@ static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
|
|||||||
|
|
||||||
/* UV map */
|
/* UV map */
|
||||||
if (need_uv || need_tangent) {
|
if (need_uv || need_tangent) {
|
||||||
if (active_render)
|
if (active_render) {
|
||||||
uv_attr = mesh->subd_attributes.add(uv_std, uv_name);
|
uv_attr = mesh->subd_attributes.add(uv_std, uv_name);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
uv_attr = mesh->subd_attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
|
uv_attr = mesh->subd_attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
|
||||||
|
}
|
||||||
|
|
||||||
if (subdivide_uvs) {
|
if (subdivide_uvs) {
|
||||||
uv_attr->flags |= ATTR_SUBDIVIDED;
|
uv_attr->flags |= ATTR_SUBDIVIDED;
|
||||||
@ -1344,7 +1346,7 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, M
|
|||||||
0.0f;
|
0.0f;
|
||||||
|
|
||||||
/* Sync mesh itself. */
|
/* Sync mesh itself. */
|
||||||
if (new_mesh.get_subdivision_type() != Mesh::SUBDIVISION_NONE)
|
if (new_mesh.get_subdivision_type() != Mesh::SUBDIVISION_NONE) {
|
||||||
create_subd_mesh(scene,
|
create_subd_mesh(scene,
|
||||||
&new_mesh,
|
&new_mesh,
|
||||||
b_ob_info,
|
b_ob_info,
|
||||||
@ -1354,7 +1356,8 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, M
|
|||||||
motion_scale,
|
motion_scale,
|
||||||
dicing_rate,
|
dicing_rate,
|
||||||
max_subdivisions);
|
max_subdivisions);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
create_mesh(scene,
|
create_mesh(scene,
|
||||||
&new_mesh,
|
&new_mesh,
|
||||||
b_mesh,
|
b_mesh,
|
||||||
@ -1362,6 +1365,7 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, M
|
|||||||
need_motion,
|
need_motion,
|
||||||
motion_scale,
|
motion_scale,
|
||||||
false);
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
free_object_to_mesh(b_data, b_ob_info, b_mesh);
|
free_object_to_mesh(b_data, b_ob_info, b_mesh);
|
||||||
}
|
}
|
||||||
@ -1434,8 +1438,9 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
|
|||||||
/* Add new attributes if they don't exist already. */
|
/* Add new attributes if they don't exist already. */
|
||||||
if (!attr_mP) {
|
if (!attr_mP) {
|
||||||
attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
|
attr_mP = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||||
if (attr_N)
|
if (attr_N) {
|
||||||
attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
|
attr_mN = mesh->attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
new_attribute = true;
|
new_attribute = true;
|
||||||
}
|
}
|
||||||
@ -1471,9 +1476,10 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
|
|||||||
VLOG_DEBUG << "No actual deformation motion for object " << ob_name;
|
VLOG_DEBUG << "No actual deformation motion for object " << ob_name;
|
||||||
}
|
}
|
||||||
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
|
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||||
if (attr_mN)
|
if (attr_mN) {
|
||||||
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
|
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (motion_step > 0) {
|
else if (motion_step > 0) {
|
||||||
VLOG_DEBUG << "Filling deformation motion for object " << ob_name;
|
VLOG_DEBUG << "Filling deformation motion for object " << ob_name;
|
||||||
/* motion, fill up previous steps that we might have skipped because
|
/* motion, fill up previous steps that we might have skipped because
|
||||||
@ -1482,11 +1488,12 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
|
|||||||
float3 *N = (attr_N) ? attr_N->data_float3() : NULL;
|
float3 *N = (attr_N) ? attr_N->data_float3() : NULL;
|
||||||
for (int step = 0; step < motion_step; step++) {
|
for (int step = 0; step < motion_step; step++) {
|
||||||
memcpy(attr_mP->data_float3() + step * numverts, P, sizeof(float3) * numverts);
|
memcpy(attr_mP->data_float3() + step * numverts, P, sizeof(float3) * numverts);
|
||||||
if (attr_mN)
|
if (attr_mN) {
|
||||||
memcpy(attr_mN->data_float3() + step * numverts, N, sizeof(float3) * numverts);
|
memcpy(attr_mN->data_float3() + step * numverts, N, sizeof(float3) * numverts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (b_verts_num != numverts) {
|
if (b_verts_num != numverts) {
|
||||||
VLOG_WARNING << "Topology differs, discarding motion blur for object " << ob_name
|
VLOG_WARNING << "Topology differs, discarding motion blur for object " << ob_name
|
||||||
|
@ -260,10 +260,11 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* mesh deformation */
|
/* mesh deformation */
|
||||||
if (object->get_geometry())
|
if (object->get_geometry()) {
|
||||||
sync_geometry_motion(
|
sync_geometry_motion(
|
||||||
b_depsgraph, b_ob_info, object, motion_time, use_particle_hair, object_geom_task_pool);
|
b_depsgraph, b_ob_info, object, motion_time, use_particle_hair, object_geom_task_pool);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
@ -669,13 +670,15 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
|
|||||||
int height,
|
int height,
|
||||||
void **python_thread_state)
|
void **python_thread_state)
|
||||||
{
|
{
|
||||||
if (scene->need_motion() == Scene::MOTION_NONE)
|
if (scene->need_motion() == Scene::MOTION_NONE) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* get camera object here to deal with camera switch */
|
/* get camera object here to deal with camera switch */
|
||||||
BL::Object b_cam = b_scene.camera();
|
BL::Object b_cam = b_scene.camera();
|
||||||
if (b_override)
|
if (b_override) {
|
||||||
b_cam = b_override;
|
b_cam = b_override;
|
||||||
|
}
|
||||||
|
|
||||||
int frame_center = b_scene.frame_current();
|
int frame_center = b_scene.frame_current();
|
||||||
float subframe_center = b_scene.frame_subframe();
|
float subframe_center = b_scene.frame_subframe();
|
||||||
|
@ -21,20 +21,23 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
|
|||||||
{
|
{
|
||||||
/* Test if this dupli was generated from a particle system. */
|
/* Test if this dupli was generated from a particle system. */
|
||||||
BL::ParticleSystem b_psys = b_instance.particle_system();
|
BL::ParticleSystem b_psys = b_instance.particle_system();
|
||||||
if (!b_psys)
|
if (!b_psys) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
object->set_hide_on_missing_motion(true);
|
object->set_hide_on_missing_motion(true);
|
||||||
|
|
||||||
/* test if we need particle data */
|
/* test if we need particle data */
|
||||||
if (!object->get_geometry()->need_attribute(scene, ATTR_STD_PARTICLE))
|
if (!object->get_geometry()->need_attribute(scene, ATTR_STD_PARTICLE)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* don't handle child particles yet */
|
/* don't handle child particles yet */
|
||||||
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_instance.persistent_id();
|
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_instance.persistent_id();
|
||||||
|
|
||||||
if (persistent_id[0] >= b_psys.particles.length())
|
if (persistent_id[0] >= b_psys.particles.length()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* find particle system */
|
/* find particle system */
|
||||||
ParticleSystemKey key(b_ob, persistent_id);
|
ParticleSystemKey key(b_ob, persistent_id);
|
||||||
@ -46,7 +49,9 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
|
|||||||
/* no update needed? */
|
/* no update needed? */
|
||||||
if (!need_update && !object->get_geometry()->is_modified() &&
|
if (!need_update && !object->get_geometry()->is_modified() &&
|
||||||
!scene->object_manager->need_update())
|
!scene->object_manager->need_update())
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* first time used in this sync loop? clear and tag update */
|
/* first time used in this sync loop? clear and tag update */
|
||||||
if (first_use) {
|
if (first_use) {
|
||||||
@ -72,8 +77,9 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
|
|||||||
object->set_particle_system(psys);
|
object->set_particle_system(psys);
|
||||||
object->set_particle_index(psys->particles.size() - 1);
|
object->set_particle_index(psys->particles.size() - 1);
|
||||||
|
|
||||||
if (object->particle_index_is_modified())
|
if (object->particle_index_is_modified()) {
|
||||||
scene->object_manager->tag_update(scene, ObjectManager::PARTICLE_MODIFIED);
|
scene->object_manager->tag_update(scene, ObjectManager::PARTICLE_MODIFIED);
|
||||||
|
}
|
||||||
|
|
||||||
/* return that this object has particle data */
|
/* return that this object has particle data */
|
||||||
return true;
|
return true;
|
||||||
|
@ -44,8 +44,9 @@ bool debug_flags_set = false;
|
|||||||
|
|
||||||
void *pylong_as_voidptr_typesafe(PyObject *object)
|
void *pylong_as_voidptr_typesafe(PyObject *object)
|
||||||
{
|
{
|
||||||
if (object == Py_None)
|
if (object == Py_None) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
return PyLong_AsVoidPtr(object);
|
return PyLong_AsVoidPtr(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,8 +225,9 @@ static PyObject *render_func(PyObject * /*self*/, PyObject *args)
|
|||||||
{
|
{
|
||||||
PyObject *pysession, *pydepsgraph;
|
PyObject *pysession, *pydepsgraph;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph))
|
if (!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
|
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
|
||||||
|
|
||||||
@ -300,7 +302,9 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
|
|||||||
&pass_filter,
|
&pass_filter,
|
||||||
&width,
|
&width,
|
||||||
&height))
|
&height))
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
|
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
|
||||||
|
|
||||||
@ -324,8 +328,9 @@ static PyObject *view_draw_func(PyObject * /*self*/, PyObject *args)
|
|||||||
{
|
{
|
||||||
PyObject *pysession, *pygraph, *pyv3d, *pyrv3d;
|
PyObject *pysession, *pygraph, *pyv3d, *pyrv3d;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "OOOO", &pysession, &pygraph, &pyv3d, &pyrv3d))
|
if (!PyArg_ParseTuple(args, "OOOO", &pysession, &pygraph, &pyv3d, &pyrv3d)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
|
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
|
||||||
|
|
||||||
@ -344,8 +349,9 @@ static PyObject *reset_func(PyObject * /*self*/, PyObject *args)
|
|||||||
{
|
{
|
||||||
PyObject *pysession, *pydata, *pydepsgraph;
|
PyObject *pysession, *pydata, *pydepsgraph;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "OOO", &pysession, &pydata, &pydepsgraph))
|
if (!PyArg_ParseTuple(args, "OOO", &pysession, &pydata, &pydepsgraph)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
|
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
|
||||||
|
|
||||||
@ -369,8 +375,9 @@ static PyObject *sync_func(PyObject * /*self*/, PyObject *args)
|
|||||||
{
|
{
|
||||||
PyObject *pysession, *pydepsgraph;
|
PyObject *pysession, *pydepsgraph;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph))
|
if (!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
|
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
|
||||||
|
|
||||||
|
@ -446,9 +446,10 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
|
|||||||
printf("Render statistics:\n%s\n", stats.full_report().c_str());
|
printf("Render statistics:\n%s\n", stats.full_report().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->progress.get_cancel())
|
if (session->progress.get_cancel()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* add metadata */
|
/* add metadata */
|
||||||
stamp_view_layer_metadata(scene, b_rlay_name);
|
stamp_view_layer_metadata(scene, b_rlay_name);
|
||||||
@ -741,8 +742,9 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
|
|||||||
void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
|
void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
|
||||||
{
|
{
|
||||||
/* only used for viewport render */
|
/* only used for viewport render */
|
||||||
if (!b_v3d)
|
if (!b_v3d) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* on session/scene parameter changes, we recreate session entirely */
|
/* on session/scene parameter changes, we recreate session entirely */
|
||||||
const SessionParams session_params = BlenderSync::get_session_params(
|
const SessionParams session_params = BlenderSync::get_session_params(
|
||||||
@ -786,10 +788,12 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
|
|||||||
sync->sync_data(
|
sync->sync_data(
|
||||||
b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
|
b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
|
||||||
|
|
||||||
if (b_rv3d)
|
if (b_rv3d) {
|
||||||
sync->sync_view(b_v3d, b_rv3d, width, height);
|
sync->sync_view(b_v3d, b_rv3d, width, height);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
sync->sync_camera(b_render, b_camera_override, width, height, "");
|
sync->sync_camera(b_render, b_camera_override, width, height, "");
|
||||||
|
}
|
||||||
|
|
||||||
/* get buffer parameters */
|
/* get buffer parameters */
|
||||||
const BufferParams buffer_params = BlenderSync::get_buffer_params(
|
const BufferParams buffer_params = BlenderSync::get_buffer_params(
|
||||||
@ -891,8 +895,9 @@ void BlenderSession::view_draw(int w, int h)
|
|||||||
|
|
||||||
sync->sync_view(b_v3d, b_rv3d, width, height);
|
sync->sync_view(b_v3d, b_rv3d, width, height);
|
||||||
|
|
||||||
if (scene->camera->is_modified())
|
if (scene->camera->is_modified()) {
|
||||||
reset = true;
|
reset = true;
|
||||||
|
}
|
||||||
|
|
||||||
session->scene->mutex.unlock();
|
session->scene->mutex.unlock();
|
||||||
}
|
}
|
||||||
@ -960,13 +965,16 @@ void BlenderSession::update_status_progress()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (background) {
|
if (background) {
|
||||||
if (scene)
|
if (scene) {
|
||||||
scene_status += " | " + scene->name;
|
scene_status += " | " + scene->name;
|
||||||
if (b_rlay_name != "")
|
}
|
||||||
|
if (b_rlay_name != "") {
|
||||||
scene_status += ", " + b_rlay_name;
|
scene_status += ", " + b_rlay_name;
|
||||||
|
}
|
||||||
|
|
||||||
if (b_rview_name != "")
|
if (b_rview_name != "") {
|
||||||
scene_status += ", " + b_rview_name;
|
scene_status += ", " + b_rview_name;
|
||||||
|
}
|
||||||
|
|
||||||
if (remaining_time > 0) {
|
if (remaining_time > 0) {
|
||||||
timestatus += "Remaining:" + time_human_readable_from_seconds(remaining_time) + " | ";
|
timestatus += "Remaining:" + time_human_readable_from_seconds(remaining_time) + " | ";
|
||||||
@ -974,11 +982,13 @@ void BlenderSession::update_status_progress()
|
|||||||
|
|
||||||
timestatus += string_printf("Mem:%.2fM, Peak:%.2fM", (double)mem_used, (double)mem_peak);
|
timestatus += string_printf("Mem:%.2fM, Peak:%.2fM", (double)mem_used, (double)mem_peak);
|
||||||
|
|
||||||
if (status.size() > 0)
|
if (status.size() > 0) {
|
||||||
status = " | " + status;
|
status = " | " + status;
|
||||||
if (substatus.size() > 0)
|
}
|
||||||
|
if (substatus.size() > 0) {
|
||||||
status += " | " + substatus;
|
status += " | " + substatus;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double current_time = time_dt();
|
double current_time = time_dt();
|
||||||
/* When rendering in a window, redraw the status at least once per second to keep the elapsed
|
/* When rendering in a window, redraw the status at least once per second to keep the elapsed
|
||||||
@ -1046,9 +1056,11 @@ void BlenderSession::tag_redraw()
|
|||||||
void BlenderSession::test_cancel()
|
void BlenderSession::test_cancel()
|
||||||
{
|
{
|
||||||
/* test if we need to cancel rendering */
|
/* test if we need to cancel rendering */
|
||||||
if (background)
|
if (background) {
|
||||||
if (b_engine.test_break())
|
if (b_engine.test_break()) {
|
||||||
session->progress.set_cancel("Cancelled");
|
session->progress.set_cancel("Cancelled");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlenderSession::free_blender_memory_if_possible()
|
void BlenderSession::free_blender_memory_if_possible()
|
||||||
|
@ -254,8 +254,9 @@ static void set_default_value(ShaderInput *input,
|
|||||||
|
|
||||||
static void get_tex_mapping(TextureNode *mapping, BL::TexMapping &b_mapping)
|
static void get_tex_mapping(TextureNode *mapping, BL::TexMapping &b_mapping)
|
||||||
{
|
{
|
||||||
if (!b_mapping)
|
if (!b_mapping) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mapping->set_tex_mapping_translation(get_float3(b_mapping.translation()));
|
mapping->set_tex_mapping_translation(get_float3(b_mapping.translation()));
|
||||||
mapping->set_tex_mapping_rotation(get_float3(b_mapping.rotation()));
|
mapping->set_tex_mapping_rotation(get_float3(b_mapping.rotation()));
|
||||||
@ -1084,8 +1085,9 @@ static ShaderNode *add_node(Scene *scene,
|
|||||||
|
|
||||||
static bool node_use_modified_socket_name(ShaderNode *node)
|
static bool node_use_modified_socket_name(ShaderNode *node)
|
||||||
{
|
{
|
||||||
if (node->special_type == SHADER_SPECIAL_TYPE_OSL)
|
if (node->special_type == SHADER_SPECIAL_TYPE_OSL) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -793,15 +793,19 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene,
|
|||||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||||
const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
|
const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
|
||||||
|
|
||||||
if (shadingsystem == 0)
|
if (shadingsystem == 0) {
|
||||||
params.shadingsystem = SHADINGSYSTEM_SVM;
|
params.shadingsystem = SHADINGSYSTEM_SVM;
|
||||||
else if (shadingsystem == 1)
|
}
|
||||||
|
else if (shadingsystem == 1) {
|
||||||
params.shadingsystem = SHADINGSYSTEM_OSL;
|
params.shadingsystem = SHADINGSYSTEM_OSL;
|
||||||
|
}
|
||||||
|
|
||||||
if (background || (use_developer_ui && get_enum(cscene, "debug_bvh_type")))
|
if (background || (use_developer_ui && get_enum(cscene, "debug_bvh_type"))) {
|
||||||
params.bvh_type = BVH_TYPE_STATIC;
|
params.bvh_type = BVH_TYPE_STATIC;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
params.bvh_type = BVH_TYPE_DYNAMIC;
|
params.bvh_type = BVH_TYPE_DYNAMIC;
|
||||||
|
}
|
||||||
|
|
||||||
params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
|
params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
|
||||||
params.use_bvh_compact_structure = RNA_boolean_get(&cscene, "debug_use_compact_bvh");
|
params.use_bvh_compact_structure = RNA_boolean_get(&cscene, "debug_use_compact_bvh");
|
||||||
@ -903,10 +907,12 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
|
|||||||
/* shading system - scene level needs full refresh */
|
/* shading system - scene level needs full refresh */
|
||||||
const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
|
const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
|
||||||
|
|
||||||
if (shadingsystem == 0)
|
if (shadingsystem == 0) {
|
||||||
params.shadingsystem = SHADINGSYSTEM_SVM;
|
params.shadingsystem = SHADINGSYSTEM_SVM;
|
||||||
else if (shadingsystem == 1)
|
}
|
||||||
|
else if (shadingsystem == 1) {
|
||||||
params.shadingsystem = SHADINGSYSTEM_OSL;
|
params.shadingsystem = SHADINGSYSTEM_OSL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Time limit. */
|
/* Time limit. */
|
||||||
if (background) {
|
if (background) {
|
||||||
|
@ -12,12 +12,15 @@ namespace {
|
|||||||
|
|
||||||
void density_texture_space_invert(float3 &loc, float3 &size)
|
void density_texture_space_invert(float3 &loc, float3 &size)
|
||||||
{
|
{
|
||||||
if (size.x != 0.0f)
|
if (size.x != 0.0f) {
|
||||||
size.x = 0.5f / size.x;
|
size.x = 0.5f / size.x;
|
||||||
if (size.y != 0.0f)
|
}
|
||||||
|
if (size.y != 0.0f) {
|
||||||
size.y = 0.5f / size.y;
|
size.y = 0.5f / size.y;
|
||||||
if (size.z != 0.0f)
|
}
|
||||||
|
if (size.z != 0.0f) {
|
||||||
size.z = 0.5f / size.z;
|
size.z = 0.5f / size.z;
|
||||||
|
}
|
||||||
|
|
||||||
loc = loc * size - make_float3(0.5f, 0.5f, 0.5f);
|
loc = loc * size - make_float3(0.5f, 0.5f, 0.5f);
|
||||||
}
|
}
|
||||||
|
@ -41,12 +41,15 @@ __forceinline int get_best_dimension(const float4 &bestSAH)
|
|||||||
|
|
||||||
float minSAH = min(bestSAH.x, min(bestSAH.y, bestSAH.z));
|
float minSAH = min(bestSAH.x, min(bestSAH.y, bestSAH.z));
|
||||||
|
|
||||||
if (bestSAH.x == minSAH)
|
if (bestSAH.x == minSAH) {
|
||||||
return 0;
|
return 0;
|
||||||
else if (bestSAH.y == minSAH)
|
}
|
||||||
|
else if (bestSAH.y == minSAH) {
|
||||||
return 1;
|
return 1;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return 2;
|
return 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BVH Object Binning */
|
/* BVH Object Binning */
|
||||||
|
@ -383,8 +383,9 @@ static size_t count_curve_segments(Hair *hair)
|
|||||||
{
|
{
|
||||||
size_t num = 0, num_curves = hair->num_curves();
|
size_t num = 0, num_curves = hair->num_curves();
|
||||||
|
|
||||||
for (size_t i = 0; i < num_curves; i++)
|
for (size_t i = 0; i < num_curves; i++) {
|
||||||
num += hair->get_curve(i).num_keys - 1;
|
num += hair->get_curve(i).num_keys - 1;
|
||||||
|
}
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
@ -441,23 +442,28 @@ void BVHBuild::add_references(BVHRange &root)
|
|||||||
++i;
|
++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!ob->get_geometry()->is_instanced())
|
if (!ob->get_geometry()->is_instanced()) {
|
||||||
add_reference_geometry(bounds, center, ob->get_geometry(), i);
|
add_reference_geometry(bounds, center, ob->get_geometry(), i);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
add_reference_object(bounds, center, ob, i);
|
add_reference_object(bounds, center, ob, i);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
add_reference_geometry(bounds, center, ob->get_geometry(), i);
|
add_reference_geometry(bounds, center, ob->get_geometry(), i);
|
||||||
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* happens mostly on empty meshes */
|
/* happens mostly on empty meshes */
|
||||||
if (!bounds.valid())
|
if (!bounds.valid()) {
|
||||||
bounds.grow(zero_float3());
|
bounds.grow(zero_float3());
|
||||||
|
}
|
||||||
|
|
||||||
root = BVHRange(bounds, center, 0, references.size());
|
root = BVHRange(bounds, center, 0, references.size());
|
||||||
}
|
}
|
||||||
@ -471,8 +477,9 @@ BVHNode *BVHBuild::run()
|
|||||||
/* add references */
|
/* add references */
|
||||||
add_references(root);
|
add_references(root);
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* init spatial splits */
|
/* init spatial splits */
|
||||||
if (params.top_level) {
|
if (params.top_level) {
|
||||||
@ -566,8 +573,9 @@ BVHNode *BVHBuild::run()
|
|||||||
|
|
||||||
void BVHBuild::progress_update()
|
void BVHBuild::progress_update()
|
||||||
{
|
{
|
||||||
if (time_dt() - progress_start_time < 0.25)
|
if (time_dt() - progress_start_time < 0.25) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
double progress_start = (double)progress_count / (double)progress_total;
|
double progress_start = (double)progress_count / (double)progress_total;
|
||||||
double duplicates = (double)(progress_total - progress_original_total) / (double)progress_total;
|
double duplicates = (double)(progress_total - progress_original_total) / (double)progress_total;
|
||||||
@ -584,8 +592,9 @@ void BVHBuild::thread_build_node(InnerNode *inner,
|
|||||||
const BVHObjectBinning &range,
|
const BVHObjectBinning &range,
|
||||||
int level)
|
int level)
|
||||||
{
|
{
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* build nodes */
|
/* build nodes */
|
||||||
BVHNode *node = build_node(range, level);
|
BVHNode *node = build_node(range, level);
|
||||||
@ -631,8 +640,9 @@ bool BVHBuild::range_within_max_leaf_size(const BVHRange &range,
|
|||||||
size_t max_leaf_size = max(max(params.max_triangle_leaf_size, params.max_curve_leaf_size),
|
size_t max_leaf_size = max(max(params.max_triangle_leaf_size, params.max_curve_leaf_size),
|
||||||
params.max_point_leaf_size);
|
params.max_point_leaf_size);
|
||||||
|
|
||||||
if (size > max_leaf_size)
|
if (size > max_leaf_size) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
size_t num_triangles = 0;
|
size_t num_triangles = 0;
|
||||||
size_t num_motion_triangles = 0;
|
size_t num_motion_triangles = 0;
|
||||||
@ -1174,22 +1184,26 @@ void BVHBuild::rotate(BVHNode *node, int max_depth, int iterations)
|
|||||||
{
|
{
|
||||||
/* In tested scenes, this resulted in slightly slower ray-tracing, so disabled
|
/* In tested scenes, this resulted in slightly slower ray-tracing, so disabled
|
||||||
* it for now. could be implementation bug, or depend on the scene. */
|
* it for now. could be implementation bug, or depend on the scene. */
|
||||||
if (node)
|
if (node) {
|
||||||
for (int i = 0; i < iterations; i++)
|
for (int i = 0; i < iterations; i++) {
|
||||||
rotate(node, max_depth);
|
rotate(node, max_depth);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BVHBuild::rotate(BVHNode *node, int max_depth)
|
void BVHBuild::rotate(BVHNode *node, int max_depth)
|
||||||
{
|
{
|
||||||
/* nothing to rotate if we reached a leaf node. */
|
/* nothing to rotate if we reached a leaf node. */
|
||||||
if (node->is_leaf() || max_depth < 0)
|
if (node->is_leaf() || max_depth < 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
InnerNode *parent = (InnerNode *)node;
|
InnerNode *parent = (InnerNode *)node;
|
||||||
|
|
||||||
/* rotate all children first */
|
/* rotate all children first */
|
||||||
for (size_t c = 0; c < 2; c++)
|
for (size_t c = 0; c < 2; c++) {
|
||||||
rotate(parent->children[c], max_depth - 1);
|
rotate(parent->children[c], max_depth - 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* compute current area of all children */
|
/* compute current area of all children */
|
||||||
BoundBox bounds0 = parent->children[0]->bounds;
|
BoundBox bounds0 = parent->children[0]->bounds;
|
||||||
@ -1206,8 +1220,9 @@ void BVHBuild::rotate(BVHNode *node, int max_depth)
|
|||||||
|
|
||||||
for (size_t c = 0; c < 2; c++) {
|
for (size_t c = 0; c < 2; c++) {
|
||||||
/* ignore leaf nodes as we cannot descent into */
|
/* ignore leaf nodes as we cannot descent into */
|
||||||
if (parent->children[c]->is_leaf())
|
if (parent->children[c]->is_leaf()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
InnerNode *child = (InnerNode *)parent->children[c];
|
InnerNode *child = (InnerNode *)parent->children[c];
|
||||||
BoundBox &other = (c == 0) ? bounds1 : bounds0;
|
BoundBox &other = (c == 0) ? bounds1 : bounds0;
|
||||||
@ -1236,8 +1251,9 @@ void BVHBuild::rotate(BVHNode *node, int max_depth)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* if we did not find a swap that improves the SAH then do nothing */
|
/* if we did not find a swap that improves the SAH then do nothing */
|
||||||
if (best_cost >= 0)
|
if (best_cost >= 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
assert(best_child == 0 || best_child == 1);
|
assert(best_child == 0 || best_child == 1);
|
||||||
assert(best_target != -1);
|
assert(best_target != -1);
|
||||||
|
@ -92,8 +92,9 @@ void BVH2::refit(Progress &progress)
|
|||||||
progress.set_substatus("Packing BVH primitives");
|
progress.set_substatus("Packing BVH primitives");
|
||||||
pack_primitives();
|
pack_primitives();
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_substatus("Refitting BVH nodes");
|
progress.set_substatus("Refitting BVH nodes");
|
||||||
refit_nodes();
|
refit_nodes();
|
||||||
@ -393,11 +394,12 @@ void BVH2::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility
|
|||||||
size_t steps = hair->get_motion_steps() - 1;
|
size_t steps = hair->get_motion_steps() - 1;
|
||||||
float3 *key_steps = attr->data_float3();
|
float3 *key_steps = attr->data_float3();
|
||||||
|
|
||||||
for (size_t i = 0; i < steps; i++)
|
for (size_t i = 0; i < steps; i++) {
|
||||||
curve.bounds_grow(k, key_steps + i * hair_size, &hair->get_curve_radius()[0], bbox);
|
curve.bounds_grow(k, key_steps + i * hair_size, &hair->get_curve_radius()[0], bbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (pack.prim_type[prim] & PRIMITIVE_POINT) {
|
else if (pack.prim_type[prim] & PRIMITIVE_POINT) {
|
||||||
/* Points. */
|
/* Points. */
|
||||||
const PointCloud *pointcloud = static_cast<const PointCloud *>(ob->get_geometry());
|
const PointCloud *pointcloud = static_cast<const PointCloud *>(ob->get_geometry());
|
||||||
@ -417,11 +419,12 @@ void BVH2::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility
|
|||||||
size_t steps = pointcloud->get_motion_steps() - 1;
|
size_t steps = pointcloud->get_motion_steps() - 1;
|
||||||
float3 *point_steps = attr->data_float3();
|
float3 *point_steps = attr->data_float3();
|
||||||
|
|
||||||
for (size_t i = 0; i < steps; i++)
|
for (size_t i = 0; i < steps; i++) {
|
||||||
point.bounds_grow(point_steps + i * pointcloud_size, radius, bbox);
|
point.bounds_grow(point_steps + i * pointcloud_size, radius, bbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
/* Triangles. */
|
/* Triangles. */
|
||||||
const Mesh *mesh = static_cast<const Mesh *>(ob->get_geometry());
|
const Mesh *mesh = static_cast<const Mesh *>(ob->get_geometry());
|
||||||
@ -440,12 +443,13 @@ void BVH2::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility
|
|||||||
size_t steps = mesh->motion_steps - 1;
|
size_t steps = mesh->motion_steps - 1;
|
||||||
float3 *vert_steps = attr->data_float3();
|
float3 *vert_steps = attr->data_float3();
|
||||||
|
|
||||||
for (size_t i = 0; i < steps; i++)
|
for (size_t i = 0; i < steps; i++) {
|
||||||
triangle.bounds_grow(vert_steps + i * mesh_size, bbox);
|
triangle.bounds_grow(vert_steps + i * mesh_size, bbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
visibility |= ob->visibility_for_tracing();
|
visibility |= ob->visibility_for_tracing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -563,10 +567,12 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
|||||||
int geom_prim_offset = geom->prim_offset;
|
int geom_prim_offset = geom->prim_offset;
|
||||||
|
|
||||||
/* fill in node indexes for instances */
|
/* fill in node indexes for instances */
|
||||||
if (bvh->pack.root_index == -1)
|
if (bvh->pack.root_index == -1) {
|
||||||
pack.object_node[object_offset++] = -noffset_leaf - 1;
|
pack.object_node[object_offset++] = -noffset_leaf - 1;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
pack.object_node[object_offset++] = noffset;
|
pack.object_node[object_offset++] = noffset;
|
||||||
|
}
|
||||||
|
|
||||||
geometry_map[geom] = pack.object_node[object_offset - 1];
|
geometry_map[geom] = pack.object_node[object_offset - 1];
|
||||||
|
|
||||||
|
@ -85,18 +85,22 @@ int BVHNode::getSubtreeSize(BVH_STAT stat) const
|
|||||||
assert(0); /* unknown mode */
|
assert(0); /* unknown mode */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_leaf())
|
if (!is_leaf()) {
|
||||||
for (int i = 0; i < num_children(); i++)
|
for (int i = 0; i < num_children(); i++) {
|
||||||
cnt += get_child(i)->getSubtreeSize(stat);
|
cnt += get_child(i)->getSubtreeSize(stat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BVHNode::deleteSubtree()
|
void BVHNode::deleteSubtree()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < num_children(); i++)
|
for (int i = 0; i < num_children(); i++) {
|
||||||
if (get_child(i))
|
if (get_child(i)) {
|
||||||
get_child(i)->deleteSubtree();
|
get_child(i)->deleteSubtree();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
@ -192,21 +196,25 @@ void BVHNode::dump_graph(const char *filename)
|
|||||||
|
|
||||||
void InnerNode::print(int depth) const
|
void InnerNode::print(int depth) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < depth; i++)
|
for (int i = 0; i < depth; i++) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
printf("inner node %p\n", (void *)this);
|
printf("inner node %p\n", (void *)this);
|
||||||
|
|
||||||
if (children[0])
|
if (children[0]) {
|
||||||
children[0]->print(depth + 1);
|
children[0]->print(depth + 1);
|
||||||
if (children[1])
|
}
|
||||||
|
if (children[1]) {
|
||||||
children[1]->print(depth + 1);
|
children[1]->print(depth + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeafNode::print(int depth) const
|
void LeafNode::print(int depth) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < depth; i++)
|
for (int i = 0; i < depth; i++) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
printf("leaf node %d to %d\n", lo, hi);
|
printf("leaf node %d to %d\n", lo, hi);
|
||||||
}
|
}
|
||||||
|
@ -46,22 +46,30 @@ struct BVHReferenceCompare {
|
|||||||
float ca = ra_bounds.min[dim] + ra_bounds.max[dim];
|
float ca = ra_bounds.min[dim] + ra_bounds.max[dim];
|
||||||
float cb = rb_bounds.min[dim] + rb_bounds.max[dim];
|
float cb = rb_bounds.min[dim] + rb_bounds.max[dim];
|
||||||
|
|
||||||
if (ca < cb)
|
if (ca < cb) {
|
||||||
return -1;
|
return -1;
|
||||||
else if (ca > cb)
|
}
|
||||||
|
else if (ca > cb) {
|
||||||
return 1;
|
return 1;
|
||||||
else if (ra.prim_object() < rb.prim_object())
|
}
|
||||||
|
else if (ra.prim_object() < rb.prim_object()) {
|
||||||
return -1;
|
return -1;
|
||||||
else if (ra.prim_object() > rb.prim_object())
|
}
|
||||||
|
else if (ra.prim_object() > rb.prim_object()) {
|
||||||
return 1;
|
return 1;
|
||||||
else if (ra.prim_index() < rb.prim_index())
|
}
|
||||||
|
else if (ra.prim_index() < rb.prim_index()) {
|
||||||
return -1;
|
return -1;
|
||||||
else if (ra.prim_index() > rb.prim_index())
|
}
|
||||||
|
else if (ra.prim_index() > rb.prim_index()) {
|
||||||
return 1;
|
return 1;
|
||||||
else if (ra.prim_type() < rb.prim_type())
|
}
|
||||||
|
else if (ra.prim_type() < rb.prim_type()) {
|
||||||
return -1;
|
return -1;
|
||||||
else if (ra.prim_type() > rb.prim_type())
|
}
|
||||||
|
else if (ra.prim_type() > rb.prim_type()) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -355,11 +355,13 @@ void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh,
|
|||||||
float v1p = v1[dim];
|
float v1p = v1[dim];
|
||||||
|
|
||||||
/* insert vertex to the boxes it belongs to. */
|
/* insert vertex to the boxes it belongs to. */
|
||||||
if (v0p <= pos)
|
if (v0p <= pos) {
|
||||||
left_bounds.grow(v0);
|
left_bounds.grow(v0);
|
||||||
|
}
|
||||||
|
|
||||||
if (v0p >= pos)
|
if (v0p >= pos) {
|
||||||
right_bounds.grow(v0);
|
right_bounds.grow(v0);
|
||||||
|
}
|
||||||
|
|
||||||
/* edge intersects the plane => insert intersection to both boxes. */
|
/* edge intersects the plane => insert intersection to both boxes. */
|
||||||
if ((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
|
if ((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
|
||||||
@ -397,17 +399,21 @@ void BVHSpatialSplit::split_curve_primitive(const Hair *hair,
|
|||||||
float v1p = v1[dim];
|
float v1p = v1[dim];
|
||||||
|
|
||||||
/* insert vertex to the boxes it belongs to. */
|
/* insert vertex to the boxes it belongs to. */
|
||||||
if (v0p <= pos)
|
if (v0p <= pos) {
|
||||||
left_bounds.grow(v0);
|
left_bounds.grow(v0);
|
||||||
|
}
|
||||||
|
|
||||||
if (v0p >= pos)
|
if (v0p >= pos) {
|
||||||
right_bounds.grow(v0);
|
right_bounds.grow(v0);
|
||||||
|
}
|
||||||
|
|
||||||
if (v1p <= pos)
|
if (v1p <= pos) {
|
||||||
left_bounds.grow(v1);
|
left_bounds.grow(v1);
|
||||||
|
}
|
||||||
|
|
||||||
if (v1p >= pos)
|
if (v1p >= pos) {
|
||||||
right_bounds.grow(v1);
|
right_bounds.grow(v1);
|
||||||
|
}
|
||||||
|
|
||||||
/* edge intersects the plane => insert intersection to both boxes. */
|
/* edge intersects the plane => insert intersection to both boxes. */
|
||||||
if ((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
|
if ((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
|
||||||
|
@ -48,8 +48,9 @@ string device_cpu_capabilities()
|
|||||||
capabilities += system_cpu_support_sse2() ? "SSE2 " : "";
|
capabilities += system_cpu_support_sse2() ? "SSE2 " : "";
|
||||||
capabilities += system_cpu_support_sse41() ? "SSE41 " : "";
|
capabilities += system_cpu_support_sse41() ? "SSE41 " : "";
|
||||||
capabilities += system_cpu_support_avx2() ? "AVX2" : "";
|
capabilities += system_cpu_support_avx2() ? "AVX2" : "";
|
||||||
if (capabilities[capabilities.size() - 1] == ' ')
|
if (capabilities[capabilities.size() - 1] == ' ') {
|
||||||
capabilities.resize(capabilities.size() - 1);
|
capabilities.resize(capabilities.size() - 1);
|
||||||
|
}
|
||||||
return capabilities;
|
return capabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,9 @@ bool device_cuda_init()
|
|||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
static bool result = false;
|
static bool result = false;
|
||||||
|
|
||||||
if (initialized)
|
if (initialized) {
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
int cuew_result = cuewInit(CUEW_INIT_CUDA);
|
int cuew_result = cuewInit(CUEW_INIT_CUDA);
|
||||||
@ -99,8 +100,9 @@ void device_cuda_info(vector<DeviceInfo> &devices)
|
|||||||
#ifdef WITH_CUDA
|
#ifdef WITH_CUDA
|
||||||
CUresult result = device_cuda_safe_init();
|
CUresult result = device_cuda_safe_init();
|
||||||
if (result != CUDA_SUCCESS) {
|
if (result != CUDA_SUCCESS) {
|
||||||
if (result != CUDA_ERROR_NO_DEVICE)
|
if (result != CUDA_ERROR_NO_DEVICE) {
|
||||||
fprintf(stderr, "CUDA cuInit: %s\n", cuewErrorString(result));
|
fprintf(stderr, "CUDA cuInit: %s\n", cuewErrorString(result));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,8 +190,9 @@ void device_cuda_info(vector<DeviceInfo> &devices)
|
|||||||
VLOG_INFO << "Added device \"" << name << "\" with id \"" << info.id << "\".";
|
VLOG_INFO << "Added device \"" << name << "\" with id \"" << info.id << "\".";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!display_devices.empty())
|
if (!display_devices.empty()) {
|
||||||
devices.insert(devices.end(), display_devices.begin(), display_devices.end());
|
devices.insert(devices.end(), display_devices.begin(), display_devices.end());
|
||||||
|
}
|
||||||
#else /* WITH_CUDA */
|
#else /* WITH_CUDA */
|
||||||
(void)devices;
|
(void)devices;
|
||||||
#endif /* WITH_CUDA */
|
#endif /* WITH_CUDA */
|
||||||
|
@ -408,19 +408,22 @@ bool CUDADevice::load_kernels(const uint kernel_features)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if cuda init succeeded */
|
/* check if cuda init succeeded */
|
||||||
if (cuContext == 0)
|
if (cuContext == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* check if GPU is supported */
|
/* check if GPU is supported */
|
||||||
if (!support_device(kernel_features))
|
if (!support_device(kernel_features)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* get kernel */
|
/* get kernel */
|
||||||
const char *kernel_name = "kernel";
|
const char *kernel_name = "kernel";
|
||||||
string cflags = compile_kernel_get_common_cflags(kernel_features);
|
string cflags = compile_kernel_get_common_cflags(kernel_features);
|
||||||
string cubin = compile_kernel(cflags, kernel_name);
|
string cubin = compile_kernel(cflags, kernel_name);
|
||||||
if (cubin.empty())
|
if (cubin.empty()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* open module */
|
/* open module */
|
||||||
CUDAContextScope scope(this);
|
CUDAContextScope scope(this);
|
||||||
@ -428,14 +431,17 @@ bool CUDADevice::load_kernels(const uint kernel_features)
|
|||||||
string cubin_data;
|
string cubin_data;
|
||||||
CUresult result;
|
CUresult result;
|
||||||
|
|
||||||
if (path_read_text(cubin, cubin_data))
|
if (path_read_text(cubin, cubin_data)) {
|
||||||
result = cuModuleLoadData(&cuModule, cubin_data.c_str());
|
result = cuModuleLoadData(&cuModule, cubin_data.c_str());
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
result = CUDA_ERROR_FILE_NOT_FOUND;
|
result = CUDA_ERROR_FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
if (result != CUDA_SUCCESS)
|
if (result != CUDA_SUCCESS) {
|
||||||
set_error(string_printf(
|
set_error(string_printf(
|
||||||
"Failed to load CUDA kernel from '%s' (%s)", cubin.c_str(), cuewErrorString(result)));
|
"Failed to load CUDA kernel from '%s' (%s)", cubin.c_str(), cuewErrorString(result)));
|
||||||
|
}
|
||||||
|
|
||||||
if (result == CUDA_SUCCESS) {
|
if (result == CUDA_SUCCESS) {
|
||||||
kernels.load(this);
|
kernels.load(this);
|
||||||
|
@ -79,8 +79,9 @@ Device *Device::create(const DeviceInfo &info, Stats &stats, Profiler &profiler)
|
|||||||
break;
|
break;
|
||||||
#ifdef WITH_CUDA
|
#ifdef WITH_CUDA
|
||||||
case DEVICE_CUDA:
|
case DEVICE_CUDA:
|
||||||
if (device_cuda_init())
|
if (device_cuda_init()) {
|
||||||
device = device_cuda_create(info, stats, profiler);
|
device = device_cuda_create(info, stats, profiler);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_OPTIX
|
#ifdef WITH_OPTIX
|
||||||
@ -123,44 +124,60 @@ Device *Device::create(const DeviceInfo &info, Stats &stats, Profiler &profiler)
|
|||||||
|
|
||||||
DeviceType Device::type_from_string(const char *name)
|
DeviceType Device::type_from_string(const char *name)
|
||||||
{
|
{
|
||||||
if (strcmp(name, "CPU") == 0)
|
if (strcmp(name, "CPU") == 0) {
|
||||||
return DEVICE_CPU;
|
return DEVICE_CPU;
|
||||||
else if (strcmp(name, "CUDA") == 0)
|
}
|
||||||
|
else if (strcmp(name, "CUDA") == 0) {
|
||||||
return DEVICE_CUDA;
|
return DEVICE_CUDA;
|
||||||
else if (strcmp(name, "OPTIX") == 0)
|
}
|
||||||
|
else if (strcmp(name, "OPTIX") == 0) {
|
||||||
return DEVICE_OPTIX;
|
return DEVICE_OPTIX;
|
||||||
else if (strcmp(name, "MULTI") == 0)
|
}
|
||||||
|
else if (strcmp(name, "MULTI") == 0) {
|
||||||
return DEVICE_MULTI;
|
return DEVICE_MULTI;
|
||||||
else if (strcmp(name, "HIP") == 0)
|
}
|
||||||
|
else if (strcmp(name, "HIP") == 0) {
|
||||||
return DEVICE_HIP;
|
return DEVICE_HIP;
|
||||||
else if (strcmp(name, "METAL") == 0)
|
}
|
||||||
|
else if (strcmp(name, "METAL") == 0) {
|
||||||
return DEVICE_METAL;
|
return DEVICE_METAL;
|
||||||
else if (strcmp(name, "ONEAPI") == 0)
|
}
|
||||||
|
else if (strcmp(name, "ONEAPI") == 0) {
|
||||||
return DEVICE_ONEAPI;
|
return DEVICE_ONEAPI;
|
||||||
else if (strcmp(name, "HIPRT") == 0)
|
}
|
||||||
|
else if (strcmp(name, "HIPRT") == 0) {
|
||||||
return DEVICE_HIPRT;
|
return DEVICE_HIPRT;
|
||||||
|
}
|
||||||
|
|
||||||
return DEVICE_NONE;
|
return DEVICE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Device::string_from_type(DeviceType type)
|
string Device::string_from_type(DeviceType type)
|
||||||
{
|
{
|
||||||
if (type == DEVICE_CPU)
|
if (type == DEVICE_CPU) {
|
||||||
return "CPU";
|
return "CPU";
|
||||||
else if (type == DEVICE_CUDA)
|
}
|
||||||
|
else if (type == DEVICE_CUDA) {
|
||||||
return "CUDA";
|
return "CUDA";
|
||||||
else if (type == DEVICE_OPTIX)
|
}
|
||||||
|
else if (type == DEVICE_OPTIX) {
|
||||||
return "OPTIX";
|
return "OPTIX";
|
||||||
else if (type == DEVICE_MULTI)
|
}
|
||||||
|
else if (type == DEVICE_MULTI) {
|
||||||
return "MULTI";
|
return "MULTI";
|
||||||
else if (type == DEVICE_HIP)
|
}
|
||||||
|
else if (type == DEVICE_HIP) {
|
||||||
return "HIP";
|
return "HIP";
|
||||||
else if (type == DEVICE_METAL)
|
}
|
||||||
|
else if (type == DEVICE_METAL) {
|
||||||
return "METAL";
|
return "METAL";
|
||||||
else if (type == DEVICE_ONEAPI)
|
}
|
||||||
|
else if (type == DEVICE_ONEAPI) {
|
||||||
return "ONEAPI";
|
return "ONEAPI";
|
||||||
else if (type == DEVICE_HIPRT)
|
}
|
||||||
|
else if (type == DEVICE_HIPRT) {
|
||||||
return "HIPRT";
|
return "HIPRT";
|
||||||
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -153,8 +153,9 @@ class MultiDevice : public Device {
|
|||||||
bool load_kernels(const uint kernel_features) override
|
bool load_kernels(const uint kernel_features) override
|
||||||
{
|
{
|
||||||
foreach (SubDevice &sub, devices)
|
foreach (SubDevice &sub, devices)
|
||||||
if (!sub.device->load_kernels(kernel_features))
|
if (!sub.device->load_kernels(kernel_features)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -162,8 +163,9 @@ class MultiDevice : public Device {
|
|||||||
bool load_osl_kernels() override
|
bool load_osl_kernels() override
|
||||||
{
|
{
|
||||||
foreach (SubDevice &sub, devices)
|
foreach (SubDevice &sub, devices)
|
||||||
if (!sub.device->load_osl_kernels())
|
if (!sub.device->load_osl_kernels()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -204,26 +206,34 @@ class MultiDevice : public Device {
|
|||||||
|
|
||||||
if (!bvh_multi->sub_bvhs[i]) {
|
if (!bvh_multi->sub_bvhs[i]) {
|
||||||
BVHParams params = bvh->params;
|
BVHParams params = bvh->params;
|
||||||
if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_OPTIX)
|
if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_OPTIX) {
|
||||||
params.bvh_layout = BVH_LAYOUT_OPTIX;
|
params.bvh_layout = BVH_LAYOUT_OPTIX;
|
||||||
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_METAL)
|
}
|
||||||
|
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_METAL) {
|
||||||
params.bvh_layout = BVH_LAYOUT_METAL;
|
params.bvh_layout = BVH_LAYOUT_METAL;
|
||||||
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_HIPRT)
|
}
|
||||||
|
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_HIPRT) {
|
||||||
params.bvh_layout = BVH_LAYOUT_HIPRT;
|
params.bvh_layout = BVH_LAYOUT_HIPRT;
|
||||||
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_EMBREEGPU)
|
}
|
||||||
|
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_EMBREEGPU) {
|
||||||
params.bvh_layout = BVH_LAYOUT_EMBREEGPU;
|
params.bvh_layout = BVH_LAYOUT_EMBREEGPU;
|
||||||
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE)
|
}
|
||||||
|
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE) {
|
||||||
params.bvh_layout = sub.device->info.type == DEVICE_OPTIX ? BVH_LAYOUT_OPTIX :
|
params.bvh_layout = sub.device->info.type == DEVICE_OPTIX ? BVH_LAYOUT_OPTIX :
|
||||||
BVH_LAYOUT_EMBREE;
|
BVH_LAYOUT_EMBREE;
|
||||||
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_METAL_EMBREE)
|
}
|
||||||
|
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_METAL_EMBREE) {
|
||||||
params.bvh_layout = sub.device->info.type == DEVICE_METAL ? BVH_LAYOUT_METAL :
|
params.bvh_layout = sub.device->info.type == DEVICE_METAL ? BVH_LAYOUT_METAL :
|
||||||
BVH_LAYOUT_EMBREE;
|
BVH_LAYOUT_EMBREE;
|
||||||
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_HIPRT_EMBREE)
|
}
|
||||||
|
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_HIPRT_EMBREE) {
|
||||||
params.bvh_layout = sub.device->info.type == DEVICE_HIP ? BVH_LAYOUT_HIPRT :
|
params.bvh_layout = sub.device->info.type == DEVICE_HIP ? BVH_LAYOUT_HIPRT :
|
||||||
BVH_LAYOUT_EMBREE;
|
BVH_LAYOUT_EMBREE;
|
||||||
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE)
|
}
|
||||||
|
else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE) {
|
||||||
params.bvh_layout = sub.device->info.type == DEVICE_ONEAPI ? BVH_LAYOUT_EMBREEGPU :
|
params.bvh_layout = sub.device->info.type == DEVICE_ONEAPI ? BVH_LAYOUT_EMBREEGPU :
|
||||||
BVH_LAYOUT_EMBREE;
|
BVH_LAYOUT_EMBREE;
|
||||||
|
}
|
||||||
/* Skip building a bottom level acceleration structure for non-instanced geometry on Embree
|
/* Skip building a bottom level acceleration structure for non-instanced geometry on Embree
|
||||||
* (since they are put into the top level directly, see bvh_embree.cpp) */
|
* (since they are put into the top level directly, see bvh_embree.cpp) */
|
||||||
if (!params.top_level && params.bvh_layout == BVH_LAYOUT_EMBREE &&
|
if (!params.top_level && params.bvh_layout == BVH_LAYOUT_EMBREE &&
|
||||||
@ -440,8 +450,9 @@ class MultiDevice : public Device {
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
foreach (SubDevice &sub, devices) {
|
foreach (SubDevice &sub, devices) {
|
||||||
if (sub.device == sub_device)
|
if (sub.device == sub_device) {
|
||||||
return i;
|
return i;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,10 +46,11 @@ DeviceQueue::~DeviceQueue()
|
|||||||
<< "s: " << device_kernel_mask_as_string(mask);
|
<< "s: " << device_kernel_mask_as_string(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_per_kernel_performance_)
|
if (is_per_kernel_performance_) {
|
||||||
VLOG_DEVICE_STATS << "GPU queue total time: " << std::fixed << std::setprecision(5)
|
VLOG_DEVICE_STATS << "GPU queue total time: " << std::fixed << std::setprecision(5)
|
||||||
<< total_time;
|
<< total_time;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceQueue::debug_init_execution()
|
void DeviceQueue::debug_init_execution()
|
||||||
|
@ -566,9 +566,10 @@ bool Node::equals(const Node &other) const
|
|||||||
assert(type == other.type);
|
assert(type == other.type);
|
||||||
|
|
||||||
foreach (const SocketType &socket, type->inputs) {
|
foreach (const SocketType &socket, type->inputs) {
|
||||||
if (!equals_value(other, socket))
|
if (!equals_value(other, socket)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,10 @@ static void xml_read_float_array(T &value, xml_attribute attr)
|
|||||||
for (size_t i = 0; i < value.size(); i++) {
|
for (size_t i = 0; i < value.size(); i++) {
|
||||||
float *value_float = (float *)&value[i];
|
float *value_float = (float *)&value[i];
|
||||||
|
|
||||||
for (size_t j = 0; j < VECTOR_SIZE; j++)
|
for (size_t j = 0; j < VECTOR_SIZE; j++) {
|
||||||
value_float[j] = (float)atof(tokens[i * VECTOR_SIZE + j].c_str());
|
value_float[j] = (float)atof(tokens[i * VECTOR_SIZE + j].c_str());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node)
|
void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node)
|
||||||
@ -71,8 +72,9 @@ void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node)
|
|||||||
|
|
||||||
array<bool> value;
|
array<bool> value;
|
||||||
value.resize(tokens.size());
|
value.resize(tokens.size());
|
||||||
for (size_t i = 0; i < value.size(); i++)
|
for (size_t i = 0; i < value.size(); i++) {
|
||||||
value[i] = xml_read_boolean(tokens[i].c_str());
|
value[i] = xml_read_boolean(tokens[i].c_str());
|
||||||
|
}
|
||||||
node->set(socket, value);
|
node->set(socket, value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -192,9 +194,10 @@ void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node)
|
|||||||
map<ustring, Node *>::iterator it = reader.node_map.find(value);
|
map<ustring, Node *>::iterator it = reader.node_map.find(value);
|
||||||
if (it != reader.node_map.end()) {
|
if (it != reader.node_map.end()) {
|
||||||
Node *value_node = it->second;
|
Node *value_node = it->second;
|
||||||
if (value_node->is_a(socket.node_type))
|
if (value_node->is_a(socket.node_type)) {
|
||||||
node->set(socket, it->second);
|
node->set(socket, it->second);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SocketType::NODE_ARRAY: {
|
case SocketType::NODE_ARRAY: {
|
||||||
@ -223,8 +226,9 @@ void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node->name.empty())
|
if (!node->name.empty()) {
|
||||||
reader.node_map[node->name] = node;
|
reader.node_map[node->name] = node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xml_node xml_write_node(Node *node, xml_node xml_root)
|
xml_node xml_write_node(Node *node, xml_node xml_root)
|
||||||
@ -256,9 +260,10 @@ xml_node xml_write_node(Node *node, xml_node xml_root)
|
|||||||
const array<bool> &value = node->get_bool_array(socket);
|
const array<bool> &value = node->get_bool_array(socket);
|
||||||
for (size_t i = 0; i < value.size(); i++) {
|
for (size_t i = 0; i < value.size(); i++) {
|
||||||
ss << xml_write_boolean(value[i]);
|
ss << xml_write_boolean(value[i]);
|
||||||
if (i != value.size() - 1)
|
if (i != value.size() - 1) {
|
||||||
ss << " ";
|
ss << " ";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
attr = ss.str().c_str();
|
attr = ss.str().c_str();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -162,10 +162,12 @@ bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
|
|||||||
#ifdef __OBJECT_MOTION__
|
#ifdef __OBJECT_MOTION__
|
||||||
Transform tfm;
|
Transform tfm;
|
||||||
|
|
||||||
if (time == sd->time)
|
if (time == sd->time) {
|
||||||
tfm = object_get_transform(kg, sd);
|
tfm = object_get_transform(kg, sd);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
tfm = object_fetch_transform_motion_test(kg, object, time, NULL);
|
tfm = object_fetch_transform_motion_test(kg, object, time, NULL);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
const Transform tfm = object_get_transform(kg, sd);
|
const Transform tfm = object_get_transform(kg, sd);
|
||||||
#endif
|
#endif
|
||||||
@ -200,10 +202,12 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
|
|||||||
#ifdef __OBJECT_MOTION__
|
#ifdef __OBJECT_MOTION__
|
||||||
Transform itfm;
|
Transform itfm;
|
||||||
|
|
||||||
if (time == sd->time)
|
if (time == sd->time) {
|
||||||
itfm = object_get_inverse_transform(kg, sd);
|
itfm = object_get_inverse_transform(kg, sd);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
object_fetch_transform_motion_test(kg, object, time, &itfm);
|
object_fetch_transform_motion_test(kg, object, time, &itfm);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
const Transform itfm = object_get_inverse_transform(kg, sd);
|
const Transform itfm = object_get_inverse_transform(kg, sd);
|
||||||
#endif
|
#endif
|
||||||
@ -740,10 +744,12 @@ static bool set_attribute_float3_3(float3 P[3], TypeDesc type, bool derivatives,
|
|||||||
fval[7] = P[2].y;
|
fval[7] = P[2].y;
|
||||||
fval[8] = P[2].z;
|
fval[8] = P[2].z;
|
||||||
|
|
||||||
if (type.arraylen > 3)
|
if (type.arraylen > 3) {
|
||||||
memset(fval + 3 * 3, 0, sizeof(float) * 3 * (type.arraylen - 3));
|
memset(fval + 3 * 3, 0, sizeof(float) * 3 * (type.arraylen - 3));
|
||||||
if (derivatives)
|
}
|
||||||
|
if (derivatives) {
|
||||||
memset(fval + type.arraylen * 3, 0, sizeof(float) * 2 * 3 * type.arraylen);
|
memset(fval + type.arraylen * 3, 0, sizeof(float) * 2 * 3 * type.arraylen);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1097,8 +1103,9 @@ bool OSLRenderServices::get_background_attribute(const KernelGlobalsCPU *kg,
|
|||||||
|
|
||||||
return set_attribute_float3(ndc, type, derivatives, val);
|
return set_attribute_float3(ndc, type, derivatives, val);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSLRenderServices::get_attribute(OSL::ShaderGlobals *sg,
|
bool OSLRenderServices::get_attribute(OSL::ShaderGlobals *sg,
|
||||||
@ -1108,8 +1115,9 @@ bool OSLRenderServices::get_attribute(OSL::ShaderGlobals *sg,
|
|||||||
OSLUStringHash name,
|
OSLUStringHash name,
|
||||||
void *val)
|
void *val)
|
||||||
{
|
{
|
||||||
if (sg == NULL || sg->renderstate == NULL)
|
if (sg == NULL || sg->renderstate == NULL) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ShaderData *sd = (ShaderData *)(sg->renderstate);
|
ShaderData *sd = (ShaderData *)(sg->renderstate);
|
||||||
return get_attribute(sd, derivatives, object_name, type, name, val);
|
return get_attribute(sd, derivatives, object_name, type, name, val);
|
||||||
@ -1129,8 +1137,9 @@ bool OSLRenderServices::get_attribute(ShaderData *sd,
|
|||||||
if (object_name != u_empty) {
|
if (object_name != u_empty) {
|
||||||
OSLGlobals::ObjectNameMap::iterator it = kg->osl->object_name_map.find(object_name);
|
OSLGlobals::ObjectNameMap::iterator it = kg->osl->object_name_map.find(object_name);
|
||||||
|
|
||||||
if (it == kg->osl->object_name_map.end())
|
if (it == kg->osl->object_name_map.end()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
object = it->second;
|
object = it->second;
|
||||||
}
|
}
|
||||||
@ -1349,12 +1358,15 @@ bool OSLRenderServices::texture(OSLUStringHash filename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
result[0] = rgba[0];
|
result[0] = rgba[0];
|
||||||
if (nchannels > 1)
|
if (nchannels > 1) {
|
||||||
result[1] = rgba[1];
|
result[1] = rgba[1];
|
||||||
if (nchannels > 2)
|
}
|
||||||
|
if (nchannels > 2) {
|
||||||
result[2] = rgba[2];
|
result[2] = rgba[2];
|
||||||
if (nchannels > 3)
|
}
|
||||||
|
if (nchannels > 3) {
|
||||||
result[3] = rgba[3];
|
result[3] = rgba[3];
|
||||||
|
}
|
||||||
status = true;
|
status = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1421,10 +1433,11 @@ bool OSLRenderServices::texture(OSLUStringHash filename,
|
|||||||
result[1] = 0.0f;
|
result[1] = 0.0f;
|
||||||
result[2] = 1.0f;
|
result[2] = 1.0f;
|
||||||
|
|
||||||
if (nchannels == 4)
|
if (nchannels == 4) {
|
||||||
result[3] = 1.0f;
|
result[3] = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -1459,12 +1472,15 @@ bool OSLRenderServices::texture3d(OSLUStringHash filename,
|
|||||||
float4 rgba = kernel_tex_image_interp_3d(kernel_globals, slot, P_float3, INTERPOLATION_NONE);
|
float4 rgba = kernel_tex_image_interp_3d(kernel_globals, slot, P_float3, INTERPOLATION_NONE);
|
||||||
|
|
||||||
result[0] = rgba[0];
|
result[0] = rgba[0];
|
||||||
if (nchannels > 1)
|
if (nchannels > 1) {
|
||||||
result[1] = rgba[1];
|
result[1] = rgba[1];
|
||||||
if (nchannels > 2)
|
}
|
||||||
|
if (nchannels > 2) {
|
||||||
result[2] = rgba[2];
|
result[2] = rgba[2];
|
||||||
if (nchannels > 3)
|
}
|
||||||
|
if (nchannels > 3) {
|
||||||
result[3] = rgba[3];
|
result[3] = rgba[3];
|
||||||
|
}
|
||||||
status = true;
|
status = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1531,10 +1547,11 @@ bool OSLRenderServices::texture3d(OSLUStringHash filename,
|
|||||||
result[1] = 0.0f;
|
result[1] = 0.0f;
|
||||||
result[2] = 1.0f;
|
result[2] = 1.0f;
|
||||||
|
|
||||||
if (nchannels == 4)
|
if (nchannels == 4) {
|
||||||
result[3] = 1.0f;
|
result[3] = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -1587,10 +1604,11 @@ bool OSLRenderServices::environment(OSLUStringHash filename,
|
|||||||
result[1] = 0.0f;
|
result[1] = 0.0f;
|
||||||
result[2] = 1.0f;
|
result[2] = 1.0f;
|
||||||
|
|
||||||
if (nchannels == 4)
|
if (nchannels == 4) {
|
||||||
result[3] = 1.0f;
|
result[3] = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (handle && handle->processor) {
|
else if (handle && handle->processor) {
|
||||||
ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels);
|
ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels);
|
||||||
}
|
}
|
||||||
|
@ -70,8 +70,9 @@ void Attribute::add(const float &f)
|
|||||||
char *data = (char *)&f;
|
char *data = (char *)&f;
|
||||||
size_t size = sizeof(f);
|
size_t size = sizeof(f);
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++) {
|
||||||
buffer.push_back(data[i]);
|
buffer.push_back(data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
@ -83,8 +84,9 @@ void Attribute::add(const uchar4 &f)
|
|||||||
char *data = (char *)&f;
|
char *data = (char *)&f;
|
||||||
size_t size = sizeof(f);
|
size_t size = sizeof(f);
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++) {
|
||||||
buffer.push_back(data[i]);
|
buffer.push_back(data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
@ -96,8 +98,9 @@ void Attribute::add(const float2 &f)
|
|||||||
char *data = (char *)&f;
|
char *data = (char *)&f;
|
||||||
size_t size = sizeof(f);
|
size_t size = sizeof(f);
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++) {
|
||||||
buffer.push_back(data[i]);
|
buffer.push_back(data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
@ -109,8 +112,9 @@ void Attribute::add(const float3 &f)
|
|||||||
char *data = (char *)&f;
|
char *data = (char *)&f;
|
||||||
size_t size = sizeof(f);
|
size_t size = sizeof(f);
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++) {
|
||||||
buffer.push_back(data[i]);
|
buffer.push_back(data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
@ -122,8 +126,9 @@ void Attribute::add(const Transform &f)
|
|||||||
char *data = (char *)&f;
|
char *data = (char *)&f;
|
||||||
size_t size = sizeof(f);
|
size_t size = sizeof(f);
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++) {
|
||||||
buffer.push_back(data[i]);
|
buffer.push_back(data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
@ -132,8 +137,9 @@ void Attribute::add(const char *data)
|
|||||||
{
|
{
|
||||||
size_t size = data_sizeof();
|
size_t size = data_sizeof();
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++) {
|
||||||
buffer.push_back(data[i]);
|
buffer.push_back(data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
@ -158,24 +164,32 @@ void Attribute::set_data_from(Attribute &&other)
|
|||||||
|
|
||||||
size_t Attribute::data_sizeof() const
|
size_t Attribute::data_sizeof() const
|
||||||
{
|
{
|
||||||
if (element == ATTR_ELEMENT_VOXEL)
|
if (element == ATTR_ELEMENT_VOXEL) {
|
||||||
return sizeof(ImageHandle);
|
return sizeof(ImageHandle);
|
||||||
else if (element == ATTR_ELEMENT_CORNER_BYTE)
|
}
|
||||||
|
else if (element == ATTR_ELEMENT_CORNER_BYTE) {
|
||||||
return sizeof(uchar4);
|
return sizeof(uchar4);
|
||||||
else if (type == TypeDesc::TypeFloat)
|
}
|
||||||
|
else if (type == TypeDesc::TypeFloat) {
|
||||||
return sizeof(float);
|
return sizeof(float);
|
||||||
else if (type == TypeFloat2)
|
}
|
||||||
|
else if (type == TypeFloat2) {
|
||||||
return sizeof(float2);
|
return sizeof(float2);
|
||||||
else if (type == TypeDesc::TypeMatrix)
|
}
|
||||||
|
else if (type == TypeDesc::TypeMatrix) {
|
||||||
return sizeof(Transform);
|
return sizeof(Transform);
|
||||||
// The float3 type is not interchangeable with float4
|
// The float3 type is not interchangeable with float4
|
||||||
// as it is now a packed type.
|
// as it is now a packed type.
|
||||||
else if (type == TypeDesc::TypeFloat4)
|
}
|
||||||
|
else if (type == TypeDesc::TypeFloat4) {
|
||||||
return sizeof(float4);
|
return sizeof(float4);
|
||||||
else if (type == TypeRGBA)
|
}
|
||||||
|
else if (type == TypeRGBA) {
|
||||||
return sizeof(float4);
|
return sizeof(float4);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return sizeof(float3);
|
return sizeof(float3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Attribute::element_size(Geometry *geom, AttributePrimitive prim) const
|
size_t Attribute::element_size(Geometry *geom, AttributePrimitive prim) const
|
||||||
@ -275,8 +289,9 @@ size_t Attribute::buffer_size(Geometry *geom, AttributePrimitive prim) const
|
|||||||
|
|
||||||
bool Attribute::same_storage(TypeDesc a, TypeDesc b)
|
bool Attribute::same_storage(TypeDesc a, TypeDesc b)
|
||||||
{
|
{
|
||||||
if (a == b)
|
if (a == b) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (a == TypeDesc::TypeColor || a == TypeDesc::TypePoint || a == TypeDesc::TypeVector ||
|
if (a == TypeDesc::TypeColor || a == TypeDesc::TypePoint || a == TypeDesc::TypeVector ||
|
||||||
a == TypeDesc::TypeNormal)
|
a == TypeDesc::TypeNormal)
|
||||||
@ -471,8 +486,9 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement eleme
|
|||||||
|
|
||||||
if (attr) {
|
if (attr) {
|
||||||
/* return if same already exists */
|
/* return if same already exists */
|
||||||
if (attr->type == type && attr->element == element)
|
if (attr->type == type && attr->element == element) {
|
||||||
return attr;
|
return attr;
|
||||||
|
}
|
||||||
|
|
||||||
/* overwrite attribute with same name but different type/element */
|
/* overwrite attribute with same name but different type/element */
|
||||||
remove(name);
|
remove(name);
|
||||||
@ -487,8 +503,9 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement eleme
|
|||||||
Attribute *AttributeSet::find(ustring name) const
|
Attribute *AttributeSet::find(ustring name) const
|
||||||
{
|
{
|
||||||
foreach (const Attribute &attr, attributes)
|
foreach (const Attribute &attr, attributes)
|
||||||
if (attr.name == name)
|
if (attr.name == name) {
|
||||||
return (Attribute *)&attr;
|
return (Attribute *)&attr;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -513,8 +530,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
|
|||||||
{
|
{
|
||||||
Attribute *attr = NULL;
|
Attribute *attr = NULL;
|
||||||
|
|
||||||
if (name == ustring())
|
if (name == ustring()) {
|
||||||
name = Attribute::standard_name(std);
|
name = Attribute::standard_name(std);
|
||||||
|
}
|
||||||
|
|
||||||
if (geometry->geometry_type == Geometry::MESH) {
|
if (geometry->geometry_type == Geometry::MESH) {
|
||||||
switch (std) {
|
switch (std) {
|
||||||
@ -666,8 +684,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
|
|||||||
Attribute *AttributeSet::find(AttributeStandard std) const
|
Attribute *AttributeSet::find(AttributeStandard std) const
|
||||||
{
|
{
|
||||||
foreach (const Attribute &attr, attributes)
|
foreach (const Attribute &attr, attributes)
|
||||||
if (attr.std == std)
|
if (attr.std == std) {
|
||||||
return (Attribute *)&attr;
|
return (Attribute *)&attr;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -710,10 +729,12 @@ void AttributeSet::remove(AttributeStandard std)
|
|||||||
|
|
||||||
Attribute *AttributeSet::find(AttributeRequest &req)
|
Attribute *AttributeSet::find(AttributeRequest &req)
|
||||||
{
|
{
|
||||||
if (req.std == ATTR_STD_NONE)
|
if (req.std == ATTR_STD_NONE) {
|
||||||
return find(req.name);
|
return find(req.name);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return find(req.std);
|
return find(req.std);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttributeSet::remove(Attribute *attribute)
|
void AttributeSet::remove(Attribute *attribute)
|
||||||
@ -852,16 +873,18 @@ AttributeRequestSet::~AttributeRequestSet() {}
|
|||||||
|
|
||||||
bool AttributeRequestSet::modified(const AttributeRequestSet &other)
|
bool AttributeRequestSet::modified(const AttributeRequestSet &other)
|
||||||
{
|
{
|
||||||
if (requests.size() != other.requests.size())
|
if (requests.size() != other.requests.size()) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < requests.size(); i++) {
|
for (size_t i = 0; i < requests.size(); i++) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for (size_t j = 0; j < requests.size() && !found; j++)
|
for (size_t j = 0; j < requests.size() && !found; j++) {
|
||||||
if (requests[i].name == other.requests[j].name && requests[i].std == other.requests[j].std) {
|
if (requests[i].name == other.requests[j].name && requests[i].std == other.requests[j].std) {
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
return true;
|
return true;
|
||||||
@ -885,8 +908,9 @@ void AttributeRequestSet::add(ustring name)
|
|||||||
void AttributeRequestSet::add(AttributeStandard std)
|
void AttributeRequestSet::add(AttributeStandard std)
|
||||||
{
|
{
|
||||||
foreach (AttributeRequest &req, requests)
|
foreach (AttributeRequest &req, requests)
|
||||||
if (req.std == std)
|
if (req.std == std) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
requests.push_back(AttributeRequest(std));
|
requests.push_back(AttributeRequest(std));
|
||||||
}
|
}
|
||||||
@ -894,11 +918,13 @@ void AttributeRequestSet::add(AttributeStandard std)
|
|||||||
void AttributeRequestSet::add(AttributeRequestSet &reqs)
|
void AttributeRequestSet::add(AttributeRequestSet &reqs)
|
||||||
{
|
{
|
||||||
foreach (AttributeRequest &req, reqs.requests) {
|
foreach (AttributeRequest &req, reqs.requests) {
|
||||||
if (req.std == ATTR_STD_NONE)
|
if (req.std == ATTR_STD_NONE) {
|
||||||
add(req.name);
|
add(req.name);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
add(req.std);
|
add(req.std);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttributeRequestSet::add_standard(ustring name)
|
void AttributeRequestSet::add_standard(ustring name)
|
||||||
@ -920,8 +946,9 @@ void AttributeRequestSet::add_standard(ustring name)
|
|||||||
bool AttributeRequestSet::find(ustring name)
|
bool AttributeRequestSet::find(ustring name)
|
||||||
{
|
{
|
||||||
foreach (AttributeRequest &req, requests)
|
foreach (AttributeRequest &req, requests)
|
||||||
if (req.name == name)
|
if (req.name == name) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -929,8 +956,9 @@ bool AttributeRequestSet::find(ustring name)
|
|||||||
bool AttributeRequestSet::find(AttributeStandard std)
|
bool AttributeRequestSet::find(AttributeStandard std)
|
||||||
{
|
{
|
||||||
foreach (AttributeRequest &req, requests)
|
foreach (AttributeRequest &req, requests)
|
||||||
if (req.std == std)
|
if (req.std == std) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,9 @@ Background::~Background()
|
|||||||
|
|
||||||
void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene)
|
void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene)
|
||||||
{
|
{
|
||||||
if (!is_modified())
|
if (!is_modified()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
@ -80,10 +81,12 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
|||||||
kbackground->transparent_roughness_squared_threshold = -1.0f;
|
kbackground->transparent_roughness_squared_threshold = -1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bg_shader->has_volume)
|
if (bg_shader->has_volume) {
|
||||||
kbackground->volume_shader = kbackground->surface_shader;
|
kbackground->volume_shader = kbackground->surface_shader;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
kbackground->volume_shader = SHADER_NONE;
|
kbackground->volume_shader = SHADER_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
kbackground->volume_step_size = volume_step_size * scene->integrator->get_volume_step_rate();
|
kbackground->volume_step_size = volume_step_size * scene->integrator->get_volume_step_rate();
|
||||||
|
|
||||||
@ -93,17 +96,22 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
|||||||
}
|
}
|
||||||
/* Background present, check visibilities */
|
/* Background present, check visibilities */
|
||||||
else {
|
else {
|
||||||
if (!(visibility & PATH_RAY_DIFFUSE))
|
if (!(visibility & PATH_RAY_DIFFUSE)) {
|
||||||
kbackground->surface_shader |= SHADER_EXCLUDE_DIFFUSE;
|
kbackground->surface_shader |= SHADER_EXCLUDE_DIFFUSE;
|
||||||
if (!(visibility & PATH_RAY_GLOSSY))
|
}
|
||||||
|
if (!(visibility & PATH_RAY_GLOSSY)) {
|
||||||
kbackground->surface_shader |= SHADER_EXCLUDE_GLOSSY;
|
kbackground->surface_shader |= SHADER_EXCLUDE_GLOSSY;
|
||||||
if (!(visibility & PATH_RAY_TRANSMIT))
|
}
|
||||||
|
if (!(visibility & PATH_RAY_TRANSMIT)) {
|
||||||
kbackground->surface_shader |= SHADER_EXCLUDE_TRANSMIT;
|
kbackground->surface_shader |= SHADER_EXCLUDE_TRANSMIT;
|
||||||
if (!(visibility & PATH_RAY_VOLUME_SCATTER))
|
}
|
||||||
|
if (!(visibility & PATH_RAY_VOLUME_SCATTER)) {
|
||||||
kbackground->surface_shader |= SHADER_EXCLUDE_SCATTER;
|
kbackground->surface_shader |= SHADER_EXCLUDE_SCATTER;
|
||||||
if (!(visibility & PATH_RAY_CAMERA))
|
}
|
||||||
|
if (!(visibility & PATH_RAY_CAMERA)) {
|
||||||
kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
|
kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Light group. */
|
/* Light group. */
|
||||||
auto it = scene->lightgroups.find(lightgroup);
|
auto it = scene->lightgroups.find(lightgroup);
|
||||||
|
@ -51,8 +51,9 @@ void BakeManager::device_update(Device * /*device*/,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Progress & /* progress */)
|
Progress & /* progress */)
|
||||||
{
|
{
|
||||||
if (!need_update())
|
if (!need_update()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
KernelBake *kbake = &dscene->data.bake;
|
KernelBake *kbake = &dscene->data.bake;
|
||||||
memset(kbake, 0, sizeof(*kbake));
|
memset(kbake, 0, sizeof(*kbake));
|
||||||
|
@ -227,8 +227,9 @@ void Camera::update(Scene *scene)
|
|||||||
need_device_update = true;
|
need_device_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_modified())
|
if (!is_modified()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
@ -254,12 +255,15 @@ void Camera::update(Scene *scene)
|
|||||||
|
|
||||||
/* Screen to camera. */
|
/* Screen to camera. */
|
||||||
ProjectionTransform cameratoscreen;
|
ProjectionTransform cameratoscreen;
|
||||||
if (camera_type == CAMERA_PERSPECTIVE)
|
if (camera_type == CAMERA_PERSPECTIVE) {
|
||||||
cameratoscreen = projection_perspective(fov, nearclip, farclip);
|
cameratoscreen = projection_perspective(fov, nearclip, farclip);
|
||||||
else if (camera_type == CAMERA_ORTHOGRAPHIC)
|
}
|
||||||
|
else if (camera_type == CAMERA_ORTHOGRAPHIC) {
|
||||||
cameratoscreen = projection_orthographic(nearclip, farclip);
|
cameratoscreen = projection_orthographic(nearclip, farclip);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
cameratoscreen = projection_identity();
|
cameratoscreen = projection_identity();
|
||||||
|
}
|
||||||
|
|
||||||
ProjectionTransform screentocamera = projection_inverse(cameratoscreen);
|
ProjectionTransform screentocamera = projection_inverse(cameratoscreen);
|
||||||
|
|
||||||
@ -474,8 +478,9 @@ void Camera::device_update(Device * /* device */, DeviceScene *dscene, Scene *sc
|
|||||||
{
|
{
|
||||||
update(scene);
|
update(scene);
|
||||||
|
|
||||||
if (!need_device_update)
|
if (!need_device_update) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
|
@ -136,8 +136,9 @@ void Film::add_default(Scene *scene)
|
|||||||
|
|
||||||
void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
|
void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
|
||||||
{
|
{
|
||||||
if (!is_modified())
|
if (!is_modified()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
|
@ -76,8 +76,9 @@ Geometry::~Geometry()
|
|||||||
|
|
||||||
void Geometry::clear(bool preserve_shaders)
|
void Geometry::clear(bool preserve_shaders)
|
||||||
{
|
{
|
||||||
if (!preserve_shaders)
|
if (!preserve_shaders) {
|
||||||
used_shaders.clear();
|
used_shaders.clear();
|
||||||
|
}
|
||||||
|
|
||||||
transform_applied = false;
|
transform_applied = false;
|
||||||
transform_negative_scaled = false;
|
transform_negative_scaled = false;
|
||||||
@ -707,8 +708,9 @@ void GeometryManager::device_update(Device *device,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Progress &progress)
|
Progress &progress)
|
||||||
{
|
{
|
||||||
if (!need_update())
|
if (!need_update()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
VLOG_INFO << "Total " << scene->geometry.size() << " meshes.";
|
VLOG_INFO << "Total " << scene->geometry.size() << " meshes.";
|
||||||
|
|
||||||
@ -787,11 +789,13 @@ void GeometryManager::device_update(Device *device,
|
|||||||
Mesh *mesh = static_cast<Mesh *>(geom);
|
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||||
if (mesh->need_tesselation()) {
|
if (mesh->need_tesselation()) {
|
||||||
string msg = "Tessellating ";
|
string msg = "Tessellating ";
|
||||||
if (mesh->name == "")
|
if (mesh->name == "") {
|
||||||
msg += string_printf("%u/%u", (uint)(i + 1), (uint)total_tess_needed);
|
msg += string_printf("%u/%u", (uint)(i + 1), (uint)total_tess_needed);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
msg += string_printf(
|
msg += string_printf(
|
||||||
"%s %u/%u", mesh->name.c_str(), (uint)(i + 1), (uint)total_tess_needed);
|
"%s %u/%u", mesh->name.c_str(), (uint)(i + 1), (uint)total_tess_needed);
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Mesh", msg);
|
progress.set_status("Updating Mesh", msg);
|
||||||
|
|
||||||
|
@ -35,31 +35,36 @@ CCL_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
bool Geometry::need_attribute(Scene *scene, AttributeStandard std)
|
bool Geometry::need_attribute(Scene *scene, AttributeStandard std)
|
||||||
{
|
{
|
||||||
if (std == ATTR_STD_NONE)
|
if (std == ATTR_STD_NONE) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (scene->need_global_attribute(std))
|
if (scene->need_global_attribute(std)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (Node *node, used_shaders) {
|
foreach (Node *node, used_shaders) {
|
||||||
Shader *shader = static_cast<Shader *>(node);
|
Shader *shader = static_cast<Shader *>(node);
|
||||||
if (shader->attributes.find(std))
|
if (shader->attributes.find(std)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Geometry::need_attribute(Scene * /*scene*/, ustring name)
|
bool Geometry::need_attribute(Scene * /*scene*/, ustring name)
|
||||||
{
|
{
|
||||||
if (name == ustring())
|
if (name == ustring()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (Node *node, used_shaders) {
|
foreach (Node *node, used_shaders) {
|
||||||
Shader *shader = static_cast<Shader *>(node);
|
Shader *shader = static_cast<Shader *>(node);
|
||||||
if (shader->attributes.find(name))
|
if (shader->attributes.find(name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -98,18 +103,24 @@ static void emit_attribute_map_entry(AttributeMap *attr_map,
|
|||||||
attr_map[index].element = desc.element;
|
attr_map[index].element = desc.element;
|
||||||
attr_map[index].offset = as_uint(desc.offset);
|
attr_map[index].offset = as_uint(desc.offset);
|
||||||
|
|
||||||
if (type == TypeDesc::TypeFloat)
|
if (type == TypeDesc::TypeFloat) {
|
||||||
attr_map[index].type = NODE_ATTR_FLOAT;
|
attr_map[index].type = NODE_ATTR_FLOAT;
|
||||||
else if (type == TypeDesc::TypeMatrix)
|
}
|
||||||
|
else if (type == TypeDesc::TypeMatrix) {
|
||||||
attr_map[index].type = NODE_ATTR_MATRIX;
|
attr_map[index].type = NODE_ATTR_MATRIX;
|
||||||
else if (type == TypeFloat2)
|
}
|
||||||
|
else if (type == TypeFloat2) {
|
||||||
attr_map[index].type = NODE_ATTR_FLOAT2;
|
attr_map[index].type = NODE_ATTR_FLOAT2;
|
||||||
else if (type == TypeFloat4)
|
}
|
||||||
|
else if (type == TypeFloat4) {
|
||||||
attr_map[index].type = NODE_ATTR_FLOAT4;
|
attr_map[index].type = NODE_ATTR_FLOAT4;
|
||||||
else if (type == TypeRGBA)
|
}
|
||||||
|
else if (type == TypeRGBA) {
|
||||||
attr_map[index].type = NODE_ATTR_RGBA;
|
attr_map[index].type = NODE_ATTR_RGBA;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
attr_map[index].type = NODE_ATTR_FLOAT3;
|
attr_map[index].type = NODE_ATTR_FLOAT3;
|
||||||
|
}
|
||||||
|
|
||||||
attr_map[index].flags = desc.flags;
|
attr_map[index].flags = desc.flags;
|
||||||
}
|
}
|
||||||
@ -189,8 +200,9 @@ void GeometryManager::update_svm_attributes(Device *,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr_map_size == 0)
|
if (attr_map_size == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dscene->attributes_map.need_realloc()) {
|
if (!dscene->attributes_map.need_realloc()) {
|
||||||
return;
|
return;
|
||||||
@ -209,10 +221,12 @@ void GeometryManager::update_svm_attributes(Device *,
|
|||||||
|
|
||||||
foreach (AttributeRequest &req, attributes.requests) {
|
foreach (AttributeRequest &req, attributes.requests) {
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
if (req.std == ATTR_STD_NONE)
|
if (req.std == ATTR_STD_NONE) {
|
||||||
id = scene->shader_manager->get_attribute_id(req.name);
|
id = scene->shader_manager->get_attribute_id(req.name);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
id = scene->shader_manager->get_attribute_id(req.std);
|
id = scene->shader_manager->get_attribute_id(req.std);
|
||||||
|
}
|
||||||
|
|
||||||
emit_attribute_mapping(attr_map, index, id, req, geom);
|
emit_attribute_mapping(attr_map, index, id, req, geom);
|
||||||
index += ATTR_PRIM_TYPES;
|
index += ATTR_PRIM_TYPES;
|
||||||
@ -240,10 +254,12 @@ void GeometryManager::update_svm_attributes(Device *,
|
|||||||
|
|
||||||
foreach (AttributeRequest &req, attributes.requests) {
|
foreach (AttributeRequest &req, attributes.requests) {
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
if (req.std == ATTR_STD_NONE)
|
if (req.std == ATTR_STD_NONE) {
|
||||||
id = scene->shader_manager->get_attribute_id(req.name);
|
id = scene->shader_manager->get_attribute_id(req.name);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
id = scene->shader_manager->get_attribute_id(req.std);
|
id = scene->shader_manager->get_attribute_id(req.std);
|
||||||
|
}
|
||||||
|
|
||||||
emit_attribute_mapping(attr_map, index, id, req, object->geometry);
|
emit_attribute_mapping(attr_map, index, id, req, object->geometry);
|
||||||
index += ATTR_PRIM_TYPES;
|
index += ATTR_PRIM_TYPES;
|
||||||
@ -378,39 +394,50 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
|
|||||||
/* Indices for subdivided attributes are retrieved
|
/* Indices for subdivided attributes are retrieved
|
||||||
* from patch table so no need for correction here. */
|
* from patch table so no need for correction here. */
|
||||||
}
|
}
|
||||||
else if (element == ATTR_ELEMENT_VERTEX)
|
else if (element == ATTR_ELEMENT_VERTEX) {
|
||||||
offset -= mesh->vert_offset;
|
offset -= mesh->vert_offset;
|
||||||
else if (element == ATTR_ELEMENT_VERTEX_MOTION)
|
}
|
||||||
|
else if (element == ATTR_ELEMENT_VERTEX_MOTION) {
|
||||||
offset -= mesh->vert_offset;
|
offset -= mesh->vert_offset;
|
||||||
|
}
|
||||||
else if (element == ATTR_ELEMENT_FACE) {
|
else if (element == ATTR_ELEMENT_FACE) {
|
||||||
if (prim == ATTR_PRIM_GEOMETRY)
|
if (prim == ATTR_PRIM_GEOMETRY) {
|
||||||
offset -= mesh->prim_offset;
|
offset -= mesh->prim_offset;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
offset -= mesh->face_offset;
|
offset -= mesh->face_offset;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (element == ATTR_ELEMENT_CORNER || element == ATTR_ELEMENT_CORNER_BYTE) {
|
else if (element == ATTR_ELEMENT_CORNER || element == ATTR_ELEMENT_CORNER_BYTE) {
|
||||||
if (prim == ATTR_PRIM_GEOMETRY)
|
if (prim == ATTR_PRIM_GEOMETRY) {
|
||||||
offset -= 3 * mesh->prim_offset;
|
offset -= 3 * mesh->prim_offset;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
offset -= mesh->corner_offset;
|
offset -= mesh->corner_offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (geom->is_hair()) {
|
else if (geom->is_hair()) {
|
||||||
Hair *hair = static_cast<Hair *>(geom);
|
Hair *hair = static_cast<Hair *>(geom);
|
||||||
if (element == ATTR_ELEMENT_CURVE)
|
if (element == ATTR_ELEMENT_CURVE) {
|
||||||
offset -= hair->prim_offset;
|
offset -= hair->prim_offset;
|
||||||
else if (element == ATTR_ELEMENT_CURVE_KEY)
|
}
|
||||||
offset -= hair->curve_key_offset;
|
else if (element == ATTR_ELEMENT_CURVE_KEY) {
|
||||||
else if (element == ATTR_ELEMENT_CURVE_KEY_MOTION)
|
|
||||||
offset -= hair->curve_key_offset;
|
offset -= hair->curve_key_offset;
|
||||||
}
|
}
|
||||||
|
else if (element == ATTR_ELEMENT_CURVE_KEY_MOTION) {
|
||||||
|
offset -= hair->curve_key_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (geom->is_pointcloud()) {
|
else if (geom->is_pointcloud()) {
|
||||||
if (element == ATTR_ELEMENT_VERTEX)
|
if (element == ATTR_ELEMENT_VERTEX) {
|
||||||
offset -= geom->prim_offset;
|
offset -= geom->prim_offset;
|
||||||
else if (element == ATTR_ELEMENT_VERTEX_MOTION)
|
}
|
||||||
|
else if (element == ATTR_ELEMENT_VERTEX_MOTION) {
|
||||||
offset -= geom->prim_offset;
|
offset -= geom->prim_offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
/* attribute not found */
|
/* attribute not found */
|
||||||
desc.element = ATTR_ELEMENT_NONE;
|
desc.element = ATTR_ELEMENT_NONE;
|
||||||
@ -652,10 +679,11 @@ void GeometryManager::device_update_attributes(Device *device,
|
|||||||
req.subd_desc);
|
req.subd_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < scene->objects.size(); i++) {
|
for (size_t i = 0; i < scene->objects.size(); i++) {
|
||||||
Object *object = scene->objects[i];
|
Object *object = scene->objects[i];
|
||||||
@ -689,19 +717,22 @@ void GeometryManager::device_update_attributes(Device *device,
|
|||||||
req.subd_type = req.type;
|
req.subd_type = req.type;
|
||||||
req.subd_desc = req.desc;
|
req.subd_desc = req.desc;
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* create attribute lookup maps */
|
/* create attribute lookup maps */
|
||||||
if (scene->shader_manager->use_osl())
|
if (scene->shader_manager->use_osl()) {
|
||||||
update_osl_globals(device, scene);
|
update_osl_globals(device, scene);
|
||||||
|
}
|
||||||
|
|
||||||
update_svm_attributes(device, dscene, scene, geom_attributes, object_attributes);
|
update_svm_attributes(device, dscene, scene, geom_attributes, object_attributes);
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* copy to device */
|
/* copy to device */
|
||||||
progress.set_status("Updating Mesh", "Copying Attributes to device");
|
progress.set_status("Updating Mesh", "Copying Attributes to device");
|
||||||
@ -712,8 +743,9 @@ void GeometryManager::device_update_attributes(Device *device,
|
|||||||
dscene->attributes_float4.copy_to_device_if_modified();
|
dscene->attributes_float4.copy_to_device_if_modified();
|
||||||
dscene->attributes_uchar4.copy_to_device_if_modified();
|
dscene->attributes_uchar4.copy_to_device_if_modified();
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* After mesh attributes and patch tables have been copied to device memory,
|
/* After mesh attributes and patch tables have been copied to device memory,
|
||||||
* we need to update offsets in the objects. */
|
* we need to update offsets in the objects. */
|
||||||
|
@ -40,8 +40,9 @@ void Geometry::compute_bvh(Device *device,
|
|||||||
size_t n,
|
size_t n,
|
||||||
size_t total)
|
size_t total)
|
||||||
{
|
{
|
||||||
if (progress->get_cancel())
|
if (progress->get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
compute_bounds();
|
compute_bounds();
|
||||||
|
|
||||||
@ -49,10 +50,12 @@ void Geometry::compute_bvh(Device *device,
|
|||||||
params->bvh_layout, device->get_bvh_layout_mask(dscene->data.kernel_features));
|
params->bvh_layout, device->get_bvh_layout_mask(dscene->data.kernel_features));
|
||||||
if (need_build_bvh(bvh_layout)) {
|
if (need_build_bvh(bvh_layout)) {
|
||||||
string msg = "Updating Geometry BVH ";
|
string msg = "Updating Geometry BVH ";
|
||||||
if (name.empty())
|
if (name.empty()) {
|
||||||
msg += string_printf("%u/%u", (uint)(n + 1), (uint)total);
|
msg += string_printf("%u/%u", (uint)(n + 1), (uint)total);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
msg += string_printf("%s %u/%u", name.c_str(), (uint)(n + 1), (uint)total);
|
msg += string_printf("%s %u/%u", name.c_str(), (uint)(n + 1), (uint)total);
|
||||||
|
}
|
||||||
|
|
||||||
Object object;
|
Object object;
|
||||||
|
|
||||||
|
@ -125,10 +125,11 @@ void GeometryManager::device_update_mesh(Device *,
|
|||||||
&tri_patch_uv[mesh->vert_offset]);
|
&tri_patch_uv[mesh->vert_offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* vertex coordinates */
|
/* vertex coordinates */
|
||||||
progress.set_status("Updating Mesh", "Copying Mesh to device");
|
progress.set_status("Updating Mesh", "Copying Mesh to device");
|
||||||
@ -169,10 +170,11 @@ void GeometryManager::device_update_mesh(Device *,
|
|||||||
&curve_keys[hair->curve_key_offset],
|
&curve_keys[hair->curve_key_offset],
|
||||||
&curves[hair->prim_offset],
|
&curves[hair->prim_offset],
|
||||||
&curve_segments[hair->curve_segment_offset]);
|
&curve_segments[hair->curve_segment_offset]);
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dscene->curve_keys.copy_to_device_if_modified();
|
dscene->curve_keys.copy_to_device_if_modified();
|
||||||
dscene->curves.copy_to_device_if_modified();
|
dscene->curves.copy_to_device_if_modified();
|
||||||
@ -190,10 +192,11 @@ void GeometryManager::device_update_mesh(Device *,
|
|||||||
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
|
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
|
||||||
pointcloud->pack(
|
pointcloud->pack(
|
||||||
scene, &points[pointcloud->prim_offset], &points_shader[pointcloud->prim_offset]);
|
scene, &points[pointcloud->prim_offset], &points_shader[pointcloud->prim_offset]);
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dscene->points.copy_to_device();
|
dscene->points.copy_to_device();
|
||||||
dscene->points_shader.copy_to_device();
|
dscene->points_shader.copy_to_device();
|
||||||
@ -214,10 +217,11 @@ void GeometryManager::device_update_mesh(Device *,
|
|||||||
mesh->patch_table_offset);
|
mesh->patch_table_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dscene->patches.copy_to_device();
|
dscene->patches.copy_to_device();
|
||||||
}
|
}
|
||||||
|
@ -398,8 +398,9 @@ void Hair::compute_bounds()
|
|||||||
size_t curve_keys_size = curve_keys.size();
|
size_t curve_keys_size = curve_keys.size();
|
||||||
|
|
||||||
if (curve_keys_size > 0) {
|
if (curve_keys_size > 0) {
|
||||||
for (size_t i = 0; i < curve_keys_size; i++)
|
for (size_t i = 0; i < curve_keys_size; i++) {
|
||||||
bnds.grow(curve_keys[i], curve_radius[i]);
|
bnds.grow(curve_keys[i], curve_radius[i]);
|
||||||
|
}
|
||||||
|
|
||||||
Attribute *curve_attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
Attribute *curve_attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||||
if (use_motion_blur && curve_attr) {
|
if (use_motion_blur && curve_attr) {
|
||||||
@ -408,16 +409,18 @@ void Hair::compute_bounds()
|
|||||||
// interchangeable with float3
|
// interchangeable with float3
|
||||||
float4 *key_steps = curve_attr->data_float4();
|
float4 *key_steps = curve_attr->data_float4();
|
||||||
|
|
||||||
for (size_t i = 0; i < steps_size; i++)
|
for (size_t i = 0; i < steps_size; i++) {
|
||||||
bnds.grow(float4_to_float3(key_steps[i]));
|
bnds.grow(float4_to_float3(key_steps[i]));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!bnds.valid()) {
|
if (!bnds.valid()) {
|
||||||
bnds = BoundBox::empty;
|
bnds = BoundBox::empty;
|
||||||
|
|
||||||
/* skip nan or inf coordinates */
|
/* skip nan or inf coordinates */
|
||||||
for (size_t i = 0; i < curve_keys_size; i++)
|
for (size_t i = 0; i < curve_keys_size; i++) {
|
||||||
bnds.grow_safe(curve_keys[i], curve_radius[i]);
|
bnds.grow_safe(curve_keys[i], curve_radius[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (use_motion_blur && curve_attr) {
|
if (use_motion_blur && curve_attr) {
|
||||||
size_t steps_size = curve_keys.size() * (motion_steps - 1);
|
size_t steps_size = curve_keys.size() * (motion_steps - 1);
|
||||||
@ -425,11 +428,12 @@ void Hair::compute_bounds()
|
|||||||
// interchangeable with float4
|
// interchangeable with float4
|
||||||
float4 *key_steps = curve_attr->data_float4();
|
float4 *key_steps = curve_attr->data_float4();
|
||||||
|
|
||||||
for (size_t i = 0; i < steps_size; i++)
|
for (size_t i = 0; i < steps_size; i++) {
|
||||||
bnds.grow_safe(float4_to_float3(key_steps[i]));
|
bnds.grow_safe(float4_to_float3(key_steps[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!bnds.valid()) {
|
if (!bnds.valid()) {
|
||||||
/* empty mesh */
|
/* empty mesh */
|
||||||
@ -492,9 +496,10 @@ void Hair::pack_curves(Scene *scene,
|
|||||||
float3 *keys_ptr = curve_keys.data();
|
float3 *keys_ptr = curve_keys.data();
|
||||||
float *radius_ptr = curve_radius.data();
|
float *radius_ptr = curve_radius.data();
|
||||||
|
|
||||||
for (size_t i = 0; i < curve_keys_size; i++)
|
for (size_t i = 0; i < curve_keys_size; i++) {
|
||||||
curve_key_co[i] = make_float4(keys_ptr[i].x, keys_ptr[i].y, keys_ptr[i].z, radius_ptr[i]);
|
curve_key_co[i] = make_float4(keys_ptr[i].x, keys_ptr[i].y, keys_ptr[i].z, radius_ptr[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* pack curve segments */
|
/* pack curve segments */
|
||||||
const PrimitiveType type = primitive_type();
|
const PrimitiveType type = primitive_type();
|
||||||
|
@ -330,8 +330,9 @@ ImageManager::ImageManager(const DeviceInfo &info)
|
|||||||
|
|
||||||
ImageManager::~ImageManager()
|
ImageManager::~ImageManager()
|
||||||
{
|
{
|
||||||
for (size_t slot = 0; slot < images.size(); slot++)
|
for (size_t slot = 0; slot < images.size(); slot++) {
|
||||||
assert(!images[slot]);
|
assert(!images[slot]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageManager::set_osl_texture_system(void *texture_system)
|
void ImageManager::set_osl_texture_system(void *texture_system)
|
||||||
@ -346,10 +347,11 @@ bool ImageManager::set_animation_frame_update(int frame)
|
|||||||
animation_frame = frame;
|
animation_frame = frame;
|
||||||
|
|
||||||
for (size_t slot = 0; slot < images.size(); slot++) {
|
for (size_t slot = 0; slot < images.size(); slot++) {
|
||||||
if (images[slot] && images[slot]->params.animated)
|
if (images[slot] && images[slot]->params.animated) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -468,9 +470,10 @@ size_t ImageManager::add_image_slot(ImageLoader *loader,
|
|||||||
|
|
||||||
/* Find free slot. */
|
/* Find free slot. */
|
||||||
for (slot = 0; slot < images.size(); slot++) {
|
for (slot = 0; slot < images.size(); slot++) {
|
||||||
if (!images[slot])
|
if (!images[slot]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (slot == images.size()) {
|
if (slot == images.size()) {
|
||||||
images.resize(images.size() + 1);
|
images.resize(images.size() + 1);
|
||||||
@ -514,8 +517,9 @@ void ImageManager::remove_image_user(size_t slot)
|
|||||||
/* don't remove immediately, rather do it all together later on. one of
|
/* don't remove immediately, rather do it all together later on. one of
|
||||||
* the reasons for this is that on shader changes we add and remove nodes
|
* the reasons for this is that on shader changes we add and remove nodes
|
||||||
* that use them, but we do not want to reload the image all the time. */
|
* that use them, but we do not want to reload the image all the time. */
|
||||||
if (image->users == 0)
|
if (image->users == 0) {
|
||||||
need_update_ = true;
|
need_update_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool image_associate_alpha(ImageManager::Image *img)
|
static bool image_associate_alpha(ImageManager::Image *img)
|
||||||
|
@ -158,8 +158,9 @@ Integrator::~Integrator() {}
|
|||||||
|
|
||||||
void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene)
|
void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene)
|
||||||
{
|
{
|
||||||
if (!is_modified())
|
if (!is_modified()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
|
@ -293,8 +293,9 @@ void LightManager::device_update_distribution(Device *,
|
|||||||
size_t num_triangles = 0;
|
size_t num_triangles = 0;
|
||||||
|
|
||||||
foreach (Object *object, scene->objects) {
|
foreach (Object *object, scene->objects) {
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!object->usable_as_light()) {
|
if (!object->usable_as_light()) {
|
||||||
continue;
|
continue;
|
||||||
@ -338,8 +339,9 @@ void LightManager::device_update_distribution(Device *,
|
|||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
foreach (Object *object, scene->objects) {
|
foreach (Object *object, scene->objects) {
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!object->usable_as_light()) {
|
if (!object->usable_as_light()) {
|
||||||
j++;
|
j++;
|
||||||
@ -414,8 +416,9 @@ void LightManager::device_update_distribution(Device *,
|
|||||||
if (num_lights > 0) {
|
if (num_lights > 0) {
|
||||||
float lightarea = (totarea > 0.0f) ? totarea / num_lights : 1.0f;
|
float lightarea = (totarea > 0.0f) ? totarea / num_lights : 1.0f;
|
||||||
foreach (Light *light, scene->lights) {
|
foreach (Light *light, scene->lights) {
|
||||||
if (!light->is_enabled)
|
if (!light->is_enabled) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
distribution[offset].totarea = totarea;
|
distribution[offset].totarea = totarea;
|
||||||
distribution[offset].prim = ~light_index;
|
distribution[offset].prim = ~light_index;
|
||||||
@ -435,13 +438,15 @@ void LightManager::device_update_distribution(Device *,
|
|||||||
distribution[num_distribution].mesh_light.shader_flag = 0;
|
distribution[num_distribution].mesh_light.shader_flag = 0;
|
||||||
|
|
||||||
if (totarea > 0.0f) {
|
if (totarea > 0.0f) {
|
||||||
for (size_t i = 0; i < num_distribution; i++)
|
for (size_t i = 0; i < num_distribution; i++) {
|
||||||
distribution[i].totarea /= totarea;
|
distribution[i].totarea /= totarea;
|
||||||
|
}
|
||||||
distribution[num_distribution].totarea = 1.0f;
|
distribution[num_distribution].totarea = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Update integrator state. */
|
/* Update integrator state. */
|
||||||
kintegrator->use_direct_light = (totarea > 0.0f);
|
kintegrator->use_direct_light = (totarea > 0.0f);
|
||||||
@ -1048,8 +1053,9 @@ void LightManager::device_update_background(Device *device,
|
|||||||
vector<float3> pixels;
|
vector<float3> pixels;
|
||||||
shade_background_pixels(device, dscene, res.x, res.y, pixels, progress);
|
shade_background_pixels(device, dscene, res.x, res.y, pixels, progress);
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* build row distributions and column distribution for the infinite area environment light */
|
/* build row distributions and column distribution for the infinite area environment light */
|
||||||
int cdf_width = res.x + 1;
|
int cdf_width = res.x + 1;
|
||||||
@ -1090,9 +1096,11 @@ void LightManager::device_update_background(Device *device,
|
|||||||
background_light->set_average_radiance(map_average_radiance);
|
background_light->set_average_radiance(map_average_radiance);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cdf_total > 0.0f)
|
if (cdf_total > 0.0f) {
|
||||||
for (int i = 1; i < res.y; i++)
|
for (int i = 1; i < res.y; i++) {
|
||||||
marg_cdf[i].y /= cdf_total;
|
marg_cdf[i].y /= cdf_total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
marg_cdf[res.y].y = 1.0f;
|
marg_cdf[res.y].y = 1.0f;
|
||||||
|
|
||||||
@ -1199,8 +1207,9 @@ void LightManager::device_update_lights(Device *device, DeviceScene *dscene, Sce
|
|||||||
int shader_id = scene->shader_manager->get_shader_id(shader);
|
int shader_id = scene->shader_manager->get_shader_id(shader);
|
||||||
float random = (float)light->random_id * (1.0f / (float)0xFFFFFFFF);
|
float random = (float)light->random_id * (1.0f / (float)0xFFFFFFFF);
|
||||||
|
|
||||||
if (!light->cast_shadow)
|
if (!light->cast_shadow) {
|
||||||
shader_id &= ~SHADER_CAST_SHADOW;
|
shader_id &= ~SHADER_CAST_SHADOW;
|
||||||
|
}
|
||||||
|
|
||||||
if (!light->use_camera) {
|
if (!light->use_camera) {
|
||||||
shader_id |= SHADER_EXCLUDE_CAMERA;
|
shader_id |= SHADER_EXCLUDE_CAMERA;
|
||||||
@ -1237,8 +1246,9 @@ void LightManager::device_update_lights(Device *device, DeviceScene *dscene, Sce
|
|||||||
/* Convert radiant flux to radiance or radiant intensity. */
|
/* Convert radiant flux to radiance or radiant intensity. */
|
||||||
float eval_fac = invarea * M_1_PI_F;
|
float eval_fac = invarea * M_1_PI_F;
|
||||||
|
|
||||||
if (light->use_mis && radius > 0.0f)
|
if (light->use_mis && radius > 0.0f) {
|
||||||
shader_id |= SHADER_USE_MIS;
|
shader_id |= SHADER_USE_MIS;
|
||||||
|
}
|
||||||
|
|
||||||
klights[light_index].co = light->get_co();
|
klights[light_index].co = light->get_co();
|
||||||
klights[light_index].spot.radius = radius;
|
klights[light_index].spot.radius = radius;
|
||||||
@ -1318,8 +1328,9 @@ void LightManager::device_update_lights(Device *device, DeviceScene *dscene, Sce
|
|||||||
|
|
||||||
float3 dir = safe_normalize(light->get_dir());
|
float3 dir = safe_normalize(light->get_dir());
|
||||||
|
|
||||||
if (light->use_mis && area != 0.0f)
|
if (light->use_mis && area != 0.0f) {
|
||||||
shader_id |= SHADER_USE_MIS;
|
shader_id |= SHADER_USE_MIS;
|
||||||
|
}
|
||||||
|
|
||||||
klights[light_index].co = light->get_co();
|
klights[light_index].co = light->get_co();
|
||||||
klights[light_index].area.axis_u = axis_u;
|
klights[light_index].area.axis_u = axis_u;
|
||||||
@ -1384,8 +1395,9 @@ void LightManager::device_update(Device *device,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Progress &progress)
|
Progress &progress)
|
||||||
{
|
{
|
||||||
if (!need_update())
|
if (!need_update()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
@ -1401,26 +1413,31 @@ void LightManager::device_update(Device *device,
|
|||||||
device_free(device, dscene, need_update_background);
|
device_free(device, dscene, need_update_background);
|
||||||
|
|
||||||
device_update_lights(device, dscene, scene);
|
device_update_lights(device, dscene, scene);
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
|
||||||
|
|
||||||
if (need_update_background) {
|
|
||||||
device_update_background(device, dscene, scene, progress);
|
|
||||||
if (progress.get_cancel())
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_update_distribution(device, dscene, scene, progress);
|
if (need_update_background) {
|
||||||
if (progress.get_cancel())
|
device_update_background(device, dscene, scene, progress);
|
||||||
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
device_update_distribution(device, dscene, scene, progress);
|
||||||
|
if (progress.get_cancel()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
device_update_tree(device, dscene, scene, progress);
|
device_update_tree(device, dscene, scene, progress);
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
device_update_ies(dscene);
|
device_update_ies(dscene);
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
update_flags = UPDATE_NONE;
|
update_flags = UPDATE_NONE;
|
||||||
need_update_background = false;
|
need_update_background = false;
|
||||||
|
@ -429,9 +429,10 @@ void Mesh::copy_center_to_motion_step(const int motion_step)
|
|||||||
size_t numverts = verts.size();
|
size_t numverts = verts.size();
|
||||||
|
|
||||||
memcpy(attr_mP->data_float3() + motion_step * numverts, P, sizeof(float3) * numverts);
|
memcpy(attr_mP->data_float3() + motion_step * numverts, P, sizeof(float3) * numverts);
|
||||||
if (attr_mN)
|
if (attr_mN) {
|
||||||
memcpy(attr_mN->data_float3() + motion_step * numverts, N, sizeof(float3) * numverts);
|
memcpy(attr_mN->data_float3() + motion_step * numverts, N, sizeof(float3) * numverts);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::get_uv_tiles(ustring map, unordered_set<int> &tiles)
|
void Mesh::get_uv_tiles(ustring map, unordered_set<int> &tiles)
|
||||||
@ -461,34 +462,38 @@ void Mesh::compute_bounds()
|
|||||||
size_t verts_size = verts.size();
|
size_t verts_size = verts.size();
|
||||||
|
|
||||||
if (verts_size > 0) {
|
if (verts_size > 0) {
|
||||||
for (size_t i = 0; i < verts_size; i++)
|
for (size_t i = 0; i < verts_size; i++) {
|
||||||
bnds.grow(verts[i]);
|
bnds.grow(verts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
Attribute *attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
Attribute *attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||||
if (use_motion_blur && attr) {
|
if (use_motion_blur && attr) {
|
||||||
size_t steps_size = verts.size() * (motion_steps - 1);
|
size_t steps_size = verts.size() * (motion_steps - 1);
|
||||||
float3 *vert_steps = attr->data_float3();
|
float3 *vert_steps = attr->data_float3();
|
||||||
|
|
||||||
for (size_t i = 0; i < steps_size; i++)
|
for (size_t i = 0; i < steps_size; i++) {
|
||||||
bnds.grow(vert_steps[i]);
|
bnds.grow(vert_steps[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!bnds.valid()) {
|
if (!bnds.valid()) {
|
||||||
bnds = BoundBox::empty;
|
bnds = BoundBox::empty;
|
||||||
|
|
||||||
/* skip nan or inf coordinates */
|
/* skip nan or inf coordinates */
|
||||||
for (size_t i = 0; i < verts_size; i++)
|
for (size_t i = 0; i < verts_size; i++) {
|
||||||
bnds.grow_safe(verts[i]);
|
bnds.grow_safe(verts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (use_motion_blur && attr) {
|
if (use_motion_blur && attr) {
|
||||||
size_t steps_size = verts.size() * (motion_steps - 1);
|
size_t steps_size = verts.size() * (motion_steps - 1);
|
||||||
float3 *vert_steps = attr->data_float3();
|
float3 *vert_steps = attr->data_float3();
|
||||||
|
|
||||||
for (size_t i = 0; i < steps_size; i++)
|
for (size_t i = 0; i < steps_size; i++) {
|
||||||
bnds.grow_safe(vert_steps[i]);
|
bnds.grow_safe(vert_steps[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!bnds.valid()) {
|
if (!bnds.valid()) {
|
||||||
/* empty mesh */
|
/* empty mesh */
|
||||||
@ -503,8 +508,9 @@ void Mesh::apply_transform(const Transform &tfm, const bool apply_to_motion)
|
|||||||
transform_normal = transform_transposed_inverse(tfm);
|
transform_normal = transform_transposed_inverse(tfm);
|
||||||
|
|
||||||
/* apply to mesh vertices */
|
/* apply to mesh vertices */
|
||||||
for (size_t i = 0; i < verts.size(); i++)
|
for (size_t i = 0; i < verts.size(); i++) {
|
||||||
verts[i] = transform_point(&tfm, verts[i]);
|
verts[i] = transform_point(&tfm, verts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
tag_verts_modified();
|
tag_verts_modified();
|
||||||
|
|
||||||
@ -515,9 +521,10 @@ void Mesh::apply_transform(const Transform &tfm, const bool apply_to_motion)
|
|||||||
size_t steps_size = verts.size() * (motion_steps - 1);
|
size_t steps_size = verts.size() * (motion_steps - 1);
|
||||||
float3 *vert_steps = attr->data_float3();
|
float3 *vert_steps = attr->data_float3();
|
||||||
|
|
||||||
for (size_t i = 0; i < steps_size; i++)
|
for (size_t i = 0; i < steps_size; i++) {
|
||||||
vert_steps[i] = transform_point(&tfm, vert_steps[i]);
|
vert_steps[i] = transform_point(&tfm, vert_steps[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Attribute *attr_N = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
|
Attribute *attr_N = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
|
||||||
|
|
||||||
@ -526,17 +533,19 @@ void Mesh::apply_transform(const Transform &tfm, const bool apply_to_motion)
|
|||||||
size_t steps_size = verts.size() * (motion_steps - 1);
|
size_t steps_size = verts.size() * (motion_steps - 1);
|
||||||
float3 *normal_steps = attr_N->data_float3();
|
float3 *normal_steps = attr_N->data_float3();
|
||||||
|
|
||||||
for (size_t i = 0; i < steps_size; i++)
|
for (size_t i = 0; i < steps_size; i++) {
|
||||||
normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i]));
|
normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::add_face_normals()
|
void Mesh::add_face_normals()
|
||||||
{
|
{
|
||||||
/* don't compute if already there */
|
/* don't compute if already there */
|
||||||
if (attributes.find(ATTR_STD_FACE_NORMAL))
|
if (attributes.find(ATTR_STD_FACE_NORMAL)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* get attributes */
|
/* get attributes */
|
||||||
Attribute *attr_fN = attributes.add(ATTR_STD_FACE_NORMAL);
|
Attribute *attr_fN = attributes.add(ATTR_STD_FACE_NORMAL);
|
||||||
@ -557,9 +566,10 @@ void Mesh::add_face_normals()
|
|||||||
if (transform_applied) {
|
if (transform_applied) {
|
||||||
Transform ntfm = transform_inverse(transform_normal);
|
Transform ntfm = transform_inverse(transform_normal);
|
||||||
|
|
||||||
for (size_t i = 0; i < triangles_size; i++)
|
for (size_t i = 0; i < triangles_size; i++) {
|
||||||
fN[i] = normalize(transform_direction(&ntfm, fN[i]));
|
fN[i] = normalize(transform_direction(&ntfm, fN[i]));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::add_vertex_normals()
|
void Mesh::add_vertex_normals()
|
||||||
|
@ -27,8 +27,9 @@ static float3 compute_face_normal(const Mesh::Triangle &t, float3 *verts)
|
|||||||
float3 norm = cross(v1 - v0, v2 - v0);
|
float3 norm = cross(v1 - v0, v2 - v0);
|
||||||
float normlen = len(norm);
|
float normlen = len(norm);
|
||||||
|
|
||||||
if (normlen == 0.0f)
|
if (normlen == 0.0f) {
|
||||||
return make_float3(1.0f, 0.0f, 0.0f);
|
return make_float3(1.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
return norm / normlen;
|
return norm / normlen;
|
||||||
}
|
}
|
||||||
@ -62,8 +63,9 @@ static int fill_shader_input(const Scene *scene,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; j++) {
|
||||||
if (done[t.v[j]])
|
if (done[t.v[j]]) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
done[t.v[j]] = true;
|
done[t.v[j]] = true;
|
||||||
|
|
||||||
@ -312,8 +314,9 @@ bool GeometryManager::displace(Device *device, Scene *scene, Mesh *mesh, Progres
|
|||||||
}
|
}
|
||||||
|
|
||||||
vN[vert] = normalize(vN[vert]);
|
vN[vert] = normalize(vN[vert]);
|
||||||
if (flip)
|
if (flip) {
|
||||||
vN[vert] = -vN[vert];
|
vN[vert] = -vN[vert];
|
||||||
|
}
|
||||||
|
|
||||||
done[vert] = true;
|
done[vert] = true;
|
||||||
}
|
}
|
||||||
@ -382,8 +385,9 @@ bool GeometryManager::displace(Device *device, Scene *scene, Mesh *mesh, Progres
|
|||||||
}
|
}
|
||||||
|
|
||||||
mN[vert] = normalize(mN[vert]);
|
mN[vert] = normalize(mN[vert]);
|
||||||
if (flip)
|
if (flip) {
|
||||||
mN[vert] = -mN[vert];
|
mN[vert] = -mN[vert];
|
||||||
|
}
|
||||||
|
|
||||||
done[vert] = true;
|
done[vert] = true;
|
||||||
}
|
}
|
||||||
|
@ -188,15 +188,17 @@ void Object::compute_bounds(bool motion_blur)
|
|||||||
|
|
||||||
void Object::apply_transform(bool apply_to_motion)
|
void Object::apply_transform(bool apply_to_motion)
|
||||||
{
|
{
|
||||||
if (!geometry || tfm == transform_identity())
|
if (!geometry || tfm == transform_identity()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
geometry->apply_transform(tfm, apply_to_motion);
|
geometry->apply_transform(tfm, apply_to_motion);
|
||||||
|
|
||||||
/* we keep normals pointing in same direction on negative scale, notify
|
/* we keep normals pointing in same direction on negative scale, notify
|
||||||
* geometry about this in it (re)calculates normals */
|
* geometry about this in it (re)calculates normals */
|
||||||
if (transform_negative_scale(tfm))
|
if (transform_negative_scale(tfm)) {
|
||||||
geometry->transform_negative_scaled = true;
|
geometry->transform_negative_scaled = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (bounds.valid()) {
|
if (bounds.valid()) {
|
||||||
geometry->compute_bounds();
|
geometry->compute_bounds();
|
||||||
@ -235,10 +237,11 @@ void Object::tag_update(Scene *scene)
|
|||||||
|
|
||||||
foreach (Node *node, geometry->get_used_shaders()) {
|
foreach (Node *node, geometry->get_used_shaders()) {
|
||||||
Shader *shader = static_cast<Shader *>(node);
|
Shader *shader = static_cast<Shader *>(node);
|
||||||
if (shader->emission_sampling != EMISSION_SAMPLING_NONE)
|
if (shader->emission_sampling != EMISSION_SAMPLING_NONE) {
|
||||||
scene->light_manager->tag_update(scene, LightManager::EMISSIVE_MESH_MODIFIED);
|
scene->light_manager->tag_update(scene, LightManager::EMISSIVE_MESH_MODIFIED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scene->camera->need_flags_update = true;
|
scene->camera->need_flags_update = true;
|
||||||
scene->object_manager->tag_update(scene, flag);
|
scene->object_manager->tag_update(scene, flag);
|
||||||
@ -753,8 +756,9 @@ void ObjectManager::device_update(Device *device,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Progress &progress)
|
Progress &progress)
|
||||||
{
|
{
|
||||||
if (!need_update())
|
if (!need_update()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (update_flags & (OBJECT_ADDED | OBJECT_REMOVED)) {
|
if (update_flags & (OBJECT_ADDED | OBJECT_REMOVED)) {
|
||||||
dscene->objects.tag_realloc();
|
dscene->objects.tag_realloc();
|
||||||
@ -776,8 +780,9 @@ void ObjectManager::device_update(Device *device,
|
|||||||
|
|
||||||
device_free(device, dscene, false);
|
device_free(device, dscene, false);
|
||||||
|
|
||||||
if (scene->objects.size() == 0)
|
if (scene->objects.size() == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Assign object IDs. */
|
/* Assign object IDs. */
|
||||||
@ -816,8 +821,9 @@ void ObjectManager::device_update(Device *device,
|
|||||||
device_update_transforms(dscene, scene, progress);
|
device_update_transforms(dscene, scene, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* prepare for static BVH building */
|
/* prepare for static BVH building */
|
||||||
/* todo: do before to support getting object level coords? */
|
/* todo: do before to support getting object level coords? */
|
||||||
@ -841,8 +847,9 @@ void ObjectManager::device_update(Device *device,
|
|||||||
void ObjectManager::device_update_flags(
|
void ObjectManager::device_update_flags(
|
||||||
Device *, DeviceScene *dscene, Scene *scene, Progress & /*progress*/, bool bounds_valid)
|
Device *, DeviceScene *dscene, Scene *scene, Progress & /*progress*/, bool bounds_valid)
|
||||||
{
|
{
|
||||||
if (!need_update() && !need_flags_update)
|
if (!need_update() && !need_flags_update) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
@ -853,8 +860,9 @@ void ObjectManager::device_update_flags(
|
|||||||
update_flags = UPDATE_NONE;
|
update_flags = UPDATE_NONE;
|
||||||
need_flags_update = false;
|
need_flags_update = false;
|
||||||
|
|
||||||
if (scene->objects.size() == 0)
|
if (scene->objects.size() == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Object info flag. */
|
/* Object info flag. */
|
||||||
uint *object_flag = dscene->object_flag.data();
|
uint *object_flag = dscene->object_flag.data();
|
||||||
@ -997,14 +1005,17 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
|
|||||||
foreach (Object *object, scene->objects) {
|
foreach (Object *object, scene->objects) {
|
||||||
map<Geometry *, int>::iterator it = geometry_users.find(object->geometry);
|
map<Geometry *, int>::iterator it = geometry_users.find(object->geometry);
|
||||||
|
|
||||||
if (it == geometry_users.end())
|
if (it == geometry_users.end()) {
|
||||||
geometry_users[object->geometry] = 1;
|
geometry_users[object->geometry] = 1;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
it->second++;
|
it->second++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint *object_flag = dscene->object_flag.data();
|
uint *object_flag = dscene->object_flag.data();
|
||||||
|
|
||||||
@ -1036,9 +1047,10 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
|
|||||||
object->apply_transform(apply_to_motion);
|
object->apply_transform(apply_to_motion);
|
||||||
geom->transform_applied = true;
|
geom->transform_applied = true;
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object_flag[i] |= SD_OBJECT_TRANSFORM_APPLIED;
|
object_flag[i] |= SD_OBJECT_TRANSFORM_APPLIED;
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,9 @@ void ParticleSystemManager::device_update_particles(Device *,
|
|||||||
* adds one dummy particle at the beginning to avoid invalid lookups,
|
* adds one dummy particle at the beginning to avoid invalid lookups,
|
||||||
* in case a shader uses particle info without actual particle data. */
|
* in case a shader uses particle info without actual particle data. */
|
||||||
int num_particles = 1;
|
int num_particles = 1;
|
||||||
for (size_t j = 0; j < scene->particle_systems.size(); j++)
|
for (size_t j = 0; j < scene->particle_systems.size(); j++) {
|
||||||
num_particles += scene->particle_systems[j]->particles.size();
|
num_particles += scene->particle_systems[j]->particles.size();
|
||||||
|
}
|
||||||
|
|
||||||
KernelParticle *kparticles = dscene->particles.alloc(num_particles);
|
KernelParticle *kparticles = dscene->particles.alloc(num_particles);
|
||||||
|
|
||||||
@ -78,10 +79,11 @@ void ParticleSystemManager::device_update_particles(Device *,
|
|||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dscene->particles.copy_to_device();
|
dscene->particles.copy_to_device();
|
||||||
}
|
}
|
||||||
@ -91,8 +93,9 @@ void ParticleSystemManager::device_update(Device *device,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Progress &progress)
|
Progress &progress)
|
||||||
{
|
{
|
||||||
if (!need_update())
|
if (!need_update()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
@ -107,8 +110,9 @@ void ParticleSystemManager::device_update(Device *device,
|
|||||||
progress.set_status("Updating Particle Systems", "Copying Particles to device");
|
progress.set_status("Updating Particle Systems", "Copying Particles to device");
|
||||||
device_update_particles(device, dscene, scene, progress);
|
device_update_particles(device, dscene, scene, progress);
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
need_update_ = false;
|
need_update_ = false;
|
||||||
}
|
}
|
||||||
|
@ -188,26 +188,29 @@ void PointCloud::compute_bounds()
|
|||||||
size_t steps_size = points.size() * (motion_steps - 1);
|
size_t steps_size = points.size() * (motion_steps - 1);
|
||||||
float4 *point_steps = attr->data_float4();
|
float4 *point_steps = attr->data_float4();
|
||||||
|
|
||||||
for (size_t i = 0; i < steps_size; i++)
|
for (size_t i = 0; i < steps_size; i++) {
|
||||||
bnds.grow(float4_to_float3(point_steps[i]), point_steps[i].w);
|
bnds.grow(float4_to_float3(point_steps[i]), point_steps[i].w);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!bnds.valid()) {
|
if (!bnds.valid()) {
|
||||||
bnds = BoundBox::empty;
|
bnds = BoundBox::empty;
|
||||||
|
|
||||||
/* skip nan or inf coordinates */
|
/* skip nan or inf coordinates */
|
||||||
for (size_t i = 0; i < numpoints; i++)
|
for (size_t i = 0; i < numpoints; i++) {
|
||||||
bnds.grow_safe(points[i], radius[i]);
|
bnds.grow_safe(points[i], radius[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (use_motion_blur && attr) {
|
if (use_motion_blur && attr) {
|
||||||
size_t steps_size = points.size() * (motion_steps - 1);
|
size_t steps_size = points.size() * (motion_steps - 1);
|
||||||
float4 *point_steps = attr->data_float4();
|
float4 *point_steps = attr->data_float4();
|
||||||
|
|
||||||
for (size_t i = 0; i < steps_size; i++)
|
for (size_t i = 0; i < steps_size; i++) {
|
||||||
bnds.grow_safe(float4_to_float3(point_steps[i]), point_steps[i].w);
|
bnds.grow_safe(float4_to_float3(point_steps[i]), point_steps[i].w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!bnds.valid()) {
|
if (!bnds.valid()) {
|
||||||
/* empty mesh */
|
/* empty mesh */
|
||||||
|
@ -149,10 +149,12 @@ void Scene::free_memory(bool final)
|
|||||||
|
|
||||||
bake_manager->device_free(device, &dscene);
|
bake_manager->device_free(device, &dscene);
|
||||||
|
|
||||||
if (final)
|
if (final) {
|
||||||
image_manager->device_free(device);
|
image_manager->device_free(device);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
image_manager->device_free_builtin(device);
|
image_manager->device_free_builtin(device);
|
||||||
|
}
|
||||||
|
|
||||||
lookup_tables->device_free(device, &dscene);
|
lookup_tables->device_free(device, &dscene);
|
||||||
}
|
}
|
||||||
@ -173,8 +175,9 @@ void Scene::free_memory(bool final)
|
|||||||
|
|
||||||
void Scene::device_update(Device *device_, Progress &progress)
|
void Scene::device_update(Device *device_, Progress &progress)
|
||||||
{
|
{
|
||||||
if (!device)
|
if (!device) {
|
||||||
device = device_;
|
device = device_;
|
||||||
|
}
|
||||||
|
|
||||||
bool print_stats = need_data_update();
|
bool print_stats = need_data_update();
|
||||||
|
|
||||||
@ -213,108 +216,126 @@ void Scene::device_update(Device *device_, Progress &progress)
|
|||||||
progress.set_status("Updating Shaders");
|
progress.set_status("Updating Shaders");
|
||||||
shader_manager->device_update(device, &dscene, this, progress);
|
shader_manager->device_update(device, &dscene, this, progress);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
procedural_manager->update(this, progress);
|
procedural_manager->update(this, progress);
|
||||||
|
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Background");
|
progress.set_status("Updating Background");
|
||||||
background->device_update(device, &dscene, this);
|
background->device_update(device, &dscene, this);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Camera");
|
progress.set_status("Updating Camera");
|
||||||
camera->device_update(device, &dscene, this);
|
camera->device_update(device, &dscene, this);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
geometry_manager->device_update_preprocess(device, this, progress);
|
geometry_manager->device_update_preprocess(device, this, progress);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Objects");
|
progress.set_status("Updating Objects");
|
||||||
object_manager->device_update(device, &dscene, this, progress);
|
object_manager->device_update(device, &dscene, this, progress);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Particle Systems");
|
progress.set_status("Updating Particle Systems");
|
||||||
particle_system_manager->device_update(device, &dscene, this, progress);
|
particle_system_manager->device_update(device, &dscene, this, progress);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Meshes");
|
progress.set_status("Updating Meshes");
|
||||||
geometry_manager->device_update(device, &dscene, this, progress);
|
geometry_manager->device_update(device, &dscene, this, progress);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Objects Flags");
|
progress.set_status("Updating Objects Flags");
|
||||||
object_manager->device_update_flags(device, &dscene, this, progress);
|
object_manager->device_update_flags(device, &dscene, this, progress);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Primitive Offsets");
|
progress.set_status("Updating Primitive Offsets");
|
||||||
object_manager->device_update_prim_offsets(device, &dscene, this);
|
object_manager->device_update_prim_offsets(device, &dscene, this);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Images");
|
progress.set_status("Updating Images");
|
||||||
image_manager->device_update(device, this, progress);
|
image_manager->device_update(device, this, progress);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Camera Volume");
|
progress.set_status("Updating Camera Volume");
|
||||||
camera->device_update_volume(device, &dscene, this);
|
camera->device_update_volume(device, &dscene, this);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Lookup Tables");
|
progress.set_status("Updating Lookup Tables");
|
||||||
lookup_tables->device_update(device, &dscene, this);
|
lookup_tables->device_update(device, &dscene, this);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Lights");
|
progress.set_status("Updating Lights");
|
||||||
light_manager->device_update(device, &dscene, this, progress);
|
light_manager->device_update(device, &dscene, this, progress);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Integrator");
|
progress.set_status("Updating Integrator");
|
||||||
integrator->device_update(device, &dscene, this);
|
integrator->device_update(device, &dscene, this);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Film");
|
progress.set_status("Updating Film");
|
||||||
film->device_update(device, &dscene, this);
|
film->device_update(device, &dscene, this);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Lookup Tables");
|
progress.set_status("Updating Lookup Tables");
|
||||||
lookup_tables->device_update(device, &dscene, this);
|
lookup_tables->device_update(device, &dscene, this);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_status("Updating Baking");
|
progress.set_status("Updating Baking");
|
||||||
bake_manager->device_update(device, &dscene, this, progress);
|
bake_manager->device_update(device, &dscene, this, progress);
|
||||||
|
|
||||||
if (progress.get_cancel() || device->have_error())
|
if (progress.get_cancel() || device->have_error()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (device->have_error() == false) {
|
if (device->have_error() == false) {
|
||||||
dscene.data.volume_stack_size = get_volume_stack_size();
|
dscene.data.volume_stack_size = get_volume_stack_size();
|
||||||
@ -339,30 +360,38 @@ void Scene::device_update(Device *device_, Progress &progress)
|
|||||||
|
|
||||||
Scene::MotionType Scene::need_motion() const
|
Scene::MotionType Scene::need_motion() const
|
||||||
{
|
{
|
||||||
if (integrator->get_motion_blur())
|
if (integrator->get_motion_blur()) {
|
||||||
return MOTION_BLUR;
|
return MOTION_BLUR;
|
||||||
else if (Pass::contains(passes, PASS_MOTION))
|
}
|
||||||
|
else if (Pass::contains(passes, PASS_MOTION)) {
|
||||||
return MOTION_PASS;
|
return MOTION_PASS;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return MOTION_NONE;
|
return MOTION_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float Scene::motion_shutter_time()
|
float Scene::motion_shutter_time()
|
||||||
{
|
{
|
||||||
if (need_motion() == Scene::MOTION_PASS)
|
if (need_motion() == Scene::MOTION_PASS) {
|
||||||
return 2.0f;
|
return 2.0f;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return camera->get_shuttertime();
|
return camera->get_shuttertime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Scene::need_global_attribute(AttributeStandard std)
|
bool Scene::need_global_attribute(AttributeStandard std)
|
||||||
{
|
{
|
||||||
if (std == ATTR_STD_UV)
|
if (std == ATTR_STD_UV) {
|
||||||
return Pass::contains(passes, PASS_UV);
|
return Pass::contains(passes, PASS_UV);
|
||||||
else if (std == ATTR_STD_MOTION_VERTEX_POSITION)
|
}
|
||||||
|
else if (std == ATTR_STD_MOTION_VERTEX_POSITION) {
|
||||||
return need_motion() != MOTION_NONE;
|
return need_motion() != MOTION_NONE;
|
||||||
else if (std == ATTR_STD_MOTION_VERTEX_NORMAL)
|
}
|
||||||
|
else if (std == ATTR_STD_MOTION_VERTEX_NORMAL) {
|
||||||
return need_motion() == MOTION_BLUR;
|
return need_motion() == MOTION_BLUR;
|
||||||
|
}
|
||||||
else if (std == ATTR_STD_VOLUME_VELOCITY || std == ATTR_STD_VOLUME_VELOCITY_X ||
|
else if (std == ATTR_STD_VOLUME_VELOCITY || std == ATTR_STD_VOLUME_VELOCITY_X ||
|
||||||
std == ATTR_STD_VOLUME_VELOCITY_Y || std == ATTR_STD_VOLUME_VELOCITY_Z)
|
std == ATTR_STD_VOLUME_VELOCITY_Y || std == ATTR_STD_VOLUME_VELOCITY_Z)
|
||||||
{
|
{
|
||||||
@ -374,9 +403,11 @@ bool Scene::need_global_attribute(AttributeStandard std)
|
|||||||
|
|
||||||
void Scene::need_global_attributes(AttributeRequestSet &attributes)
|
void Scene::need_global_attributes(AttributeRequestSet &attributes)
|
||||||
{
|
{
|
||||||
for (int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
|
for (int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++) {
|
||||||
if (need_global_attribute((AttributeStandard)std))
|
if (need_global_attribute((AttributeStandard)std)) {
|
||||||
attributes.add((AttributeStandard)std);
|
attributes.add((AttributeStandard)std);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Scene::need_update()
|
bool Scene::need_update()
|
||||||
@ -597,8 +628,9 @@ bool Scene::load_kernels(Progress &progress)
|
|||||||
log_kernel_features(kernel_features);
|
log_kernel_features(kernel_features);
|
||||||
if (!device->load_kernels(kernel_features)) {
|
if (!device->load_kernels(kernel_features)) {
|
||||||
string message = device->error_message();
|
string message = device->error_message();
|
||||||
if (message.empty())
|
if (message.empty()) {
|
||||||
message = "Failed loading render kernel, see console for errors";
|
message = "Failed loading render kernel, see console for errors";
|
||||||
|
}
|
||||||
|
|
||||||
progress.set_error(message);
|
progress.set_error(message);
|
||||||
progress.set_status(message);
|
progress.set_status(message);
|
||||||
|
@ -323,8 +323,9 @@ void Shader::tag_update(Scene *scene)
|
|||||||
/* if the shader previously was emissive, update light distribution,
|
/* if the shader previously was emissive, update light distribution,
|
||||||
* if the new shader is emissive, a light manager update tag will be
|
* if the new shader is emissive, a light manager update tag will be
|
||||||
* done in the shader manager device update. */
|
* done in the shader manager device update. */
|
||||||
if (emission_sampling != EMISSION_SAMPLING_NONE)
|
if (emission_sampling != EMISSION_SAMPLING_NONE) {
|
||||||
scene->light_manager->tag_update(scene, LightManager::SHADER_MODIFIED);
|
scene->light_manager->tag_update(scene, LightManager::SHADER_MODIFIED);
|
||||||
|
}
|
||||||
|
|
||||||
/* Special handle of background MIS light for now: for some reason it
|
/* Special handle of background MIS light for now: for some reason it
|
||||||
* has use_mis set to false. We are quite close to release now, so
|
* has use_mis set to false. We are quite close to release now, so
|
||||||
@ -450,8 +451,9 @@ uint64_t ShaderManager::get_attribute_id(ustring name)
|
|||||||
/* get a unique id for each name, for SVM attribute lookup */
|
/* get a unique id for each name, for SVM attribute lookup */
|
||||||
AttributeIDMap::iterator it = unique_attribute_id.find(name);
|
AttributeIDMap::iterator it = unique_attribute_id.find(name);
|
||||||
|
|
||||||
if (it != unique_attribute_id.end())
|
if (it != unique_attribute_id.end()) {
|
||||||
return it->second;
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t id = ATTR_STD_NUM + unique_attribute_id.size();
|
uint64_t id = ATTR_STD_NUM + unique_attribute_id.size();
|
||||||
unique_attribute_id[name] = id;
|
unique_attribute_id[name] = id;
|
||||||
@ -469,8 +471,9 @@ int ShaderManager::get_shader_id(Shader *shader, bool smooth)
|
|||||||
int id = shader->id;
|
int id = shader->id;
|
||||||
|
|
||||||
/* smooth flag */
|
/* smooth flag */
|
||||||
if (smooth)
|
if (smooth) {
|
||||||
id |= SHADER_SMOOTH_NORMAL;
|
id |= SHADER_SMOOTH_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
/* default flags */
|
/* default flags */
|
||||||
id |= SHADER_CAST_SHADOW | SHADER_AREA_LIGHT;
|
id |= SHADER_CAST_SHADOW | SHADER_AREA_LIGHT;
|
||||||
@ -509,8 +512,9 @@ void ShaderManager::device_update_common(Device * /*device*/,
|
|||||||
{
|
{
|
||||||
dscene->shaders.free();
|
dscene->shaders.free();
|
||||||
|
|
||||||
if (scene->shaders.size() == 0)
|
if (scene->shaders.size() == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
KernelShader *kshader = dscene->shaders.alloc(scene->shaders.size());
|
KernelShader *kshader = dscene->shaders.alloc(scene->shaders.size());
|
||||||
bool has_volumes = false;
|
bool has_volumes = false;
|
||||||
@ -529,12 +533,15 @@ void ShaderManager::device_update_common(Device * /*device*/,
|
|||||||
flag |= SD_MIS_FRONT | SD_MIS_BACK;
|
flag |= SD_MIS_FRONT | SD_MIS_BACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_zero(shader->emission_estimate))
|
if (!is_zero(shader->emission_estimate)) {
|
||||||
flag |= SD_HAS_EMISSION;
|
flag |= SD_HAS_EMISSION;
|
||||||
if (shader->has_surface_transparent && shader->get_use_transparent_shadow())
|
}
|
||||||
|
if (shader->has_surface_transparent && shader->get_use_transparent_shadow()) {
|
||||||
flag |= SD_HAS_TRANSPARENT_SHADOW;
|
flag |= SD_HAS_TRANSPARENT_SHADOW;
|
||||||
if (shader->has_surface_raytrace)
|
}
|
||||||
|
if (shader->has_surface_raytrace) {
|
||||||
flag |= SD_HAS_RAYTRACE;
|
flag |= SD_HAS_RAYTRACE;
|
||||||
|
}
|
||||||
if (shader->has_volume) {
|
if (shader->has_volume) {
|
||||||
flag |= SD_HAS_VOLUME;
|
flag |= SD_HAS_VOLUME;
|
||||||
has_volumes = true;
|
has_volumes = true;
|
||||||
@ -545,30 +552,40 @@ void ShaderManager::device_update_common(Device * /*device*/,
|
|||||||
flag |= SD_HAS_TRANSPARENT_SHADOW;
|
flag |= SD_HAS_TRANSPARENT_SHADOW;
|
||||||
}
|
}
|
||||||
/* in this case we can assume transparent surface */
|
/* in this case we can assume transparent surface */
|
||||||
if (shader->has_volume_connected && !shader->has_surface)
|
if (shader->has_volume_connected && !shader->has_surface) {
|
||||||
flag |= SD_HAS_ONLY_VOLUME;
|
flag |= SD_HAS_ONLY_VOLUME;
|
||||||
|
}
|
||||||
if (shader->has_volume) {
|
if (shader->has_volume) {
|
||||||
if (shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying)
|
if (shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying) {
|
||||||
flag |= SD_HETEROGENEOUS_VOLUME;
|
flag |= SD_HETEROGENEOUS_VOLUME;
|
||||||
}
|
}
|
||||||
if (shader->has_volume_attribute_dependency)
|
}
|
||||||
|
if (shader->has_volume_attribute_dependency) {
|
||||||
flag |= SD_NEED_VOLUME_ATTRIBUTES;
|
flag |= SD_NEED_VOLUME_ATTRIBUTES;
|
||||||
if (shader->has_bssrdf_bump)
|
}
|
||||||
|
if (shader->has_bssrdf_bump) {
|
||||||
flag |= SD_HAS_BSSRDF_BUMP;
|
flag |= SD_HAS_BSSRDF_BUMP;
|
||||||
if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_EQUIANGULAR)
|
}
|
||||||
|
if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_EQUIANGULAR) {
|
||||||
flag |= SD_VOLUME_EQUIANGULAR;
|
flag |= SD_VOLUME_EQUIANGULAR;
|
||||||
if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE)
|
}
|
||||||
|
if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE) {
|
||||||
flag |= SD_VOLUME_MIS;
|
flag |= SD_VOLUME_MIS;
|
||||||
if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC)
|
}
|
||||||
|
if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC) {
|
||||||
flag |= SD_VOLUME_CUBIC;
|
flag |= SD_VOLUME_CUBIC;
|
||||||
if (shader->has_bump)
|
}
|
||||||
|
if (shader->has_bump) {
|
||||||
flag |= SD_HAS_BUMP;
|
flag |= SD_HAS_BUMP;
|
||||||
if (shader->get_displacement_method() != DISPLACE_BUMP)
|
}
|
||||||
|
if (shader->get_displacement_method() != DISPLACE_BUMP) {
|
||||||
flag |= SD_HAS_DISPLACEMENT;
|
flag |= SD_HAS_DISPLACEMENT;
|
||||||
|
}
|
||||||
|
|
||||||
/* constant emission check */
|
/* constant emission check */
|
||||||
if (shader->emission_is_constant)
|
if (shader->emission_is_constant) {
|
||||||
flag |= SD_HAS_CONSTANT_EMISSION;
|
flag |= SD_HAS_CONSTANT_EMISSION;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
|
uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
|
||||||
|
|
||||||
|
@ -99,9 +99,10 @@ void ShaderNode::create_inputs_outputs(const NodeType *type)
|
|||||||
ShaderInput *ShaderNode::input(const char *name)
|
ShaderInput *ShaderNode::input(const char *name)
|
||||||
{
|
{
|
||||||
foreach (ShaderInput *socket, inputs) {
|
foreach (ShaderInput *socket, inputs) {
|
||||||
if (socket->name() == name)
|
if (socket->name() == name) {
|
||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -109,8 +110,9 @@ ShaderInput *ShaderNode::input(const char *name)
|
|||||||
ShaderOutput *ShaderNode::output(const char *name)
|
ShaderOutput *ShaderNode::output(const char *name)
|
||||||
{
|
{
|
||||||
foreach (ShaderOutput *socket, outputs)
|
foreach (ShaderOutput *socket, outputs)
|
||||||
if (socket->name() == name)
|
if (socket->name() == name) {
|
||||||
return socket;
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -118,9 +120,10 @@ ShaderOutput *ShaderNode::output(const char *name)
|
|||||||
ShaderInput *ShaderNode::input(ustring name)
|
ShaderInput *ShaderNode::input(ustring name)
|
||||||
{
|
{
|
||||||
foreach (ShaderInput *socket, inputs) {
|
foreach (ShaderInput *socket, inputs) {
|
||||||
if (socket->name() == name)
|
if (socket->name() == name) {
|
||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -128,8 +131,9 @@ ShaderInput *ShaderNode::input(ustring name)
|
|||||||
ShaderOutput *ShaderNode::output(ustring name)
|
ShaderOutput *ShaderNode::output(ustring name)
|
||||||
{
|
{
|
||||||
foreach (ShaderOutput *socket, outputs)
|
foreach (ShaderOutput *socket, outputs)
|
||||||
if (socket->name() == name)
|
if (socket->name() == name) {
|
||||||
return socket;
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -146,17 +150,20 @@ void ShaderNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
|||||||
foreach (ShaderInput *input, inputs) {
|
foreach (ShaderInput *input, inputs) {
|
||||||
if (!input->link) {
|
if (!input->link) {
|
||||||
if (input->flags() & SocketType::LINK_TEXTURE_GENERATED) {
|
if (input->flags() & SocketType::LINK_TEXTURE_GENERATED) {
|
||||||
if (shader->has_surface_link())
|
if (shader->has_surface_link()) {
|
||||||
attributes->add(ATTR_STD_GENERATED);
|
attributes->add(ATTR_STD_GENERATED);
|
||||||
if (shader->has_volume)
|
}
|
||||||
|
if (shader->has_volume) {
|
||||||
attributes->add(ATTR_STD_GENERATED_TRANSFORM);
|
attributes->add(ATTR_STD_GENERATED_TRANSFORM);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (input->flags() & SocketType::LINK_TEXTURE_UV) {
|
else if (input->flags() & SocketType::LINK_TEXTURE_UV) {
|
||||||
if (shader->has_surface_link())
|
if (shader->has_surface_link()) {
|
||||||
attributes->add(ATTR_STD_UV);
|
attributes->add(ATTR_STD_UV);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShaderNode::equals(const ShaderNode &other)
|
bool ShaderNode::equals(const ShaderNode &other)
|
||||||
@ -322,9 +329,10 @@ void ShaderGraph::relink(ShaderOutput *from, ShaderOutput *to)
|
|||||||
|
|
||||||
foreach (ShaderInput *sock, outputs) {
|
foreach (ShaderInput *sock, outputs) {
|
||||||
disconnect(sock);
|
disconnect(sock);
|
||||||
if (to)
|
if (to) {
|
||||||
connect(to, sock);
|
connect(to, sock);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderGraph::relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to)
|
void ShaderGraph::relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to)
|
||||||
@ -336,15 +344,17 @@ void ShaderGraph::relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to)
|
|||||||
|
|
||||||
/* Bypass node by moving all links from "from" to "to" */
|
/* Bypass node by moving all links from "from" to "to" */
|
||||||
foreach (ShaderInput *sock, node->inputs) {
|
foreach (ShaderInput *sock, node->inputs) {
|
||||||
if (sock->link)
|
if (sock->link) {
|
||||||
disconnect(sock);
|
disconnect(sock);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (ShaderInput *sock, outputs) {
|
foreach (ShaderInput *sock, outputs) {
|
||||||
disconnect(sock);
|
disconnect(sock);
|
||||||
if (to)
|
if (to) {
|
||||||
connect(to, sock);
|
connect(to, sock);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderGraph::simplify(Scene *scene)
|
void ShaderGraph::simplify(Scene *scene)
|
||||||
@ -369,18 +379,21 @@ void ShaderGraph::finalize(Scene *scene, bool do_bump, bool bump_in_object_space
|
|||||||
if (!finalized) {
|
if (!finalized) {
|
||||||
simplify(scene);
|
simplify(scene);
|
||||||
|
|
||||||
if (do_bump)
|
if (do_bump) {
|
||||||
bump_from_displacement(bump_in_object_space);
|
bump_from_displacement(bump_in_object_space);
|
||||||
|
}
|
||||||
|
|
||||||
ShaderInput *surface_in = output()->input("Surface");
|
ShaderInput *surface_in = output()->input("Surface");
|
||||||
ShaderInput *volume_in = output()->input("Volume");
|
ShaderInput *volume_in = output()->input("Volume");
|
||||||
|
|
||||||
/* todo: make this work when surface and volume closures are tangled up */
|
/* todo: make this work when surface and volume closures are tangled up */
|
||||||
|
|
||||||
if (surface_in->link)
|
if (surface_in->link) {
|
||||||
transform_multi_closure(surface_in->link->parent, NULL, false);
|
transform_multi_closure(surface_in->link->parent, NULL, false);
|
||||||
if (volume_in->link)
|
}
|
||||||
|
if (volume_in->link) {
|
||||||
transform_multi_closure(volume_in->link->parent, NULL, true);
|
transform_multi_closure(volume_in->link->parent, NULL, true);
|
||||||
|
}
|
||||||
|
|
||||||
finalized = true;
|
finalized = true;
|
||||||
}
|
}
|
||||||
@ -479,15 +492,18 @@ void ShaderGraph::remove_proxy_nodes()
|
|||||||
vector<ShaderInput *> links = tonode->outputs[0]->links;
|
vector<ShaderInput *> links = tonode->outputs[0]->links;
|
||||||
|
|
||||||
foreach (ShaderInput *autoin, links) {
|
foreach (ShaderInput *autoin, links) {
|
||||||
if (autoin->flags() & SocketType::DEFAULT_LINK_MASK)
|
if (autoin->flags() & SocketType::DEFAULT_LINK_MASK) {
|
||||||
disconnect(autoin);
|
disconnect(autoin);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
all_links_removed = false;
|
all_links_removed = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (all_links_removed)
|
if (all_links_removed) {
|
||||||
removed[tonode->id] = true;
|
removed[tonode->id] = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
disconnect(to);
|
disconnect(to);
|
||||||
|
|
||||||
@ -506,11 +522,13 @@ void ShaderGraph::remove_proxy_nodes()
|
|||||||
list<ShaderNode *> newnodes;
|
list<ShaderNode *> newnodes;
|
||||||
|
|
||||||
foreach (ShaderNode *node, nodes) {
|
foreach (ShaderNode *node, nodes) {
|
||||||
if (!removed[node->id])
|
if (!removed[node->id]) {
|
||||||
newnodes.push_back(node);
|
newnodes.push_back(node);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
delete_node(node);
|
delete_node(node);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nodes = newnodes;
|
nodes = newnodes;
|
||||||
}
|
}
|
||||||
@ -805,11 +823,13 @@ void ShaderGraph::clean(Scene *scene)
|
|||||||
list<ShaderNode *> newnodes;
|
list<ShaderNode *> newnodes;
|
||||||
|
|
||||||
foreach (ShaderNode *node, nodes) {
|
foreach (ShaderNode *node, nodes) {
|
||||||
if (visited[node->id])
|
if (visited[node->id]) {
|
||||||
newnodes.push_back(node);
|
newnodes.push_back(node);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
delete_node(node);
|
delete_node(node);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nodes = newnodes;
|
nodes = newnodes;
|
||||||
}
|
}
|
||||||
@ -834,44 +854,51 @@ void ShaderGraph::default_inputs(bool do_osl)
|
|||||||
foreach (ShaderInput *input, node->inputs) {
|
foreach (ShaderInput *input, node->inputs) {
|
||||||
if (!input->link && (!(input->flags() & SocketType::OSL_INTERNAL) || do_osl)) {
|
if (!input->link && (!(input->flags() & SocketType::OSL_INTERNAL) || do_osl)) {
|
||||||
if (input->flags() & SocketType::LINK_TEXTURE_GENERATED) {
|
if (input->flags() & SocketType::LINK_TEXTURE_GENERATED) {
|
||||||
if (!texco)
|
if (!texco) {
|
||||||
texco = create_node<TextureCoordinateNode>();
|
texco = create_node<TextureCoordinateNode>();
|
||||||
|
}
|
||||||
|
|
||||||
connect(texco->output("Generated"), input);
|
connect(texco->output("Generated"), input);
|
||||||
}
|
}
|
||||||
if (input->flags() & SocketType::LINK_TEXTURE_NORMAL) {
|
if (input->flags() & SocketType::LINK_TEXTURE_NORMAL) {
|
||||||
if (!texco)
|
if (!texco) {
|
||||||
texco = create_node<TextureCoordinateNode>();
|
texco = create_node<TextureCoordinateNode>();
|
||||||
|
}
|
||||||
|
|
||||||
connect(texco->output("Normal"), input);
|
connect(texco->output("Normal"), input);
|
||||||
}
|
}
|
||||||
else if (input->flags() & SocketType::LINK_TEXTURE_UV) {
|
else if (input->flags() & SocketType::LINK_TEXTURE_UV) {
|
||||||
if (!texco)
|
if (!texco) {
|
||||||
texco = create_node<TextureCoordinateNode>();
|
texco = create_node<TextureCoordinateNode>();
|
||||||
|
}
|
||||||
|
|
||||||
connect(texco->output("UV"), input);
|
connect(texco->output("UV"), input);
|
||||||
}
|
}
|
||||||
else if (input->flags() & SocketType::LINK_INCOMING) {
|
else if (input->flags() & SocketType::LINK_INCOMING) {
|
||||||
if (!geom)
|
if (!geom) {
|
||||||
geom = create_node<GeometryNode>();
|
geom = create_node<GeometryNode>();
|
||||||
|
}
|
||||||
|
|
||||||
connect(geom->output("Incoming"), input);
|
connect(geom->output("Incoming"), input);
|
||||||
}
|
}
|
||||||
else if (input->flags() & SocketType::LINK_NORMAL) {
|
else if (input->flags() & SocketType::LINK_NORMAL) {
|
||||||
if (!geom)
|
if (!geom) {
|
||||||
geom = create_node<GeometryNode>();
|
geom = create_node<GeometryNode>();
|
||||||
|
}
|
||||||
|
|
||||||
connect(geom->output("Normal"), input);
|
connect(geom->output("Normal"), input);
|
||||||
}
|
}
|
||||||
else if (input->flags() & SocketType::LINK_POSITION) {
|
else if (input->flags() & SocketType::LINK_POSITION) {
|
||||||
if (!geom)
|
if (!geom) {
|
||||||
geom = create_node<GeometryNode>();
|
geom = create_node<GeometryNode>();
|
||||||
|
}
|
||||||
|
|
||||||
connect(geom->output("Position"), input);
|
connect(geom->output("Position"), input);
|
||||||
}
|
}
|
||||||
else if (input->flags() & SocketType::LINK_TANGENT) {
|
else if (input->flags() & SocketType::LINK_TANGENT) {
|
||||||
if (!geom)
|
if (!geom) {
|
||||||
geom = create_node<GeometryNode>();
|
geom = create_node<GeometryNode>();
|
||||||
|
}
|
||||||
|
|
||||||
connect(geom->output("Tangent"), input);
|
connect(geom->output("Tangent"), input);
|
||||||
}
|
}
|
||||||
@ -879,10 +906,12 @@ void ShaderGraph::default_inputs(bool do_osl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geom)
|
if (geom) {
|
||||||
add(geom);
|
add(geom);
|
||||||
if (texco)
|
}
|
||||||
|
if (texco) {
|
||||||
add(texco);
|
add(texco);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderGraph::refine_bump_nodes()
|
void ShaderGraph::refine_bump_nodes()
|
||||||
@ -957,8 +986,9 @@ void ShaderGraph::bump_from_displacement(bool use_object_space)
|
|||||||
|
|
||||||
ShaderInput *displacement_in = output()->input("Displacement");
|
ShaderInput *displacement_in = output()->input("Displacement");
|
||||||
|
|
||||||
if (!displacement_in->link)
|
if (!displacement_in->link) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* find dependencies for the given input */
|
/* find dependencies for the given input */
|
||||||
ShaderNodeSet nodes_displace;
|
ShaderNodeSet nodes_displace;
|
||||||
@ -1056,13 +1086,16 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight
|
|||||||
ShaderInput *fac_in = mix_node->input("Fac");
|
ShaderInput *fac_in = mix_node->input("Fac");
|
||||||
ShaderInput *weight_in = mix_node->input("Weight");
|
ShaderInput *weight_in = mix_node->input("Weight");
|
||||||
|
|
||||||
if (fin->link)
|
if (fin->link) {
|
||||||
connect(fin->link, fac_in);
|
connect(fin->link, fac_in);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
mix_node->set_fac(node->get_float(fin->socket_type));
|
mix_node->set_fac(node->get_float(fin->socket_type));
|
||||||
|
}
|
||||||
|
|
||||||
if (weight_out)
|
if (weight_out) {
|
||||||
connect(weight_out, weight_in);
|
connect(weight_out, weight_in);
|
||||||
|
}
|
||||||
|
|
||||||
weight1_out = mix_node->output("Weight1");
|
weight1_out = mix_node->output("Weight1");
|
||||||
weight2_out = mix_node->output("Weight2");
|
weight2_out = mix_node->output("Weight2");
|
||||||
@ -1073,17 +1106,20 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight
|
|||||||
weight2_out = weight_out;
|
weight2_out = weight_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cl1in->link)
|
if (cl1in->link) {
|
||||||
transform_multi_closure(cl1in->link->parent, weight1_out, volume);
|
transform_multi_closure(cl1in->link->parent, weight1_out, volume);
|
||||||
if (cl2in->link)
|
}
|
||||||
|
if (cl2in->link) {
|
||||||
transform_multi_closure(cl2in->link->parent, weight2_out, volume);
|
transform_multi_closure(cl2in->link->parent, weight2_out, volume);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
ShaderInput *weight_in = node->input((volume) ? "VolumeMixWeight" : "SurfaceMixWeight");
|
ShaderInput *weight_in = node->input((volume) ? "VolumeMixWeight" : "SurfaceMixWeight");
|
||||||
|
|
||||||
/* not a closure node? */
|
/* not a closure node? */
|
||||||
if (!weight_in)
|
if (!weight_in) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* already has a weight connected to it? add weights */
|
/* already has a weight connected to it? add weights */
|
||||||
float weight_value = node->get_float(weight_in->socket_type);
|
float weight_value = node->get_float(weight_in->socket_type);
|
||||||
@ -1091,27 +1127,34 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight
|
|||||||
MathNode *math_node = create_node<MathNode>();
|
MathNode *math_node = create_node<MathNode>();
|
||||||
add(math_node);
|
add(math_node);
|
||||||
|
|
||||||
if (weight_in->link)
|
if (weight_in->link) {
|
||||||
connect(weight_in->link, math_node->input("Value1"));
|
connect(weight_in->link, math_node->input("Value1"));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
math_node->set_value1(weight_value);
|
math_node->set_value1(weight_value);
|
||||||
|
}
|
||||||
|
|
||||||
if (weight_out)
|
if (weight_out) {
|
||||||
connect(weight_out, math_node->input("Value2"));
|
connect(weight_out, math_node->input("Value2"));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
math_node->set_value2(1.0f);
|
math_node->set_value2(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
weight_out = math_node->output("Value");
|
weight_out = math_node->output("Value");
|
||||||
if (weight_in->link)
|
if (weight_in->link) {
|
||||||
disconnect(weight_in);
|
disconnect(weight_in);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* connected to closure mix weight */
|
/* connected to closure mix weight */
|
||||||
if (weight_out)
|
if (weight_out) {
|
||||||
connect(weight_out, weight_in);
|
connect(weight_out, weight_in);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
node->set(weight_in->socket_type, weight_value + 1.0f);
|
node->set(weight_in->socket_type, weight_value + 1.0f);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ShaderGraph::get_num_closures()
|
int ShaderGraph::get_num_closures()
|
||||||
|
@ -71,24 +71,30 @@ Transform TextureMapping::compute_transform()
|
|||||||
{
|
{
|
||||||
Transform mmat = transform_scale(zero_float3());
|
Transform mmat = transform_scale(zero_float3());
|
||||||
|
|
||||||
if (x_mapping != NONE)
|
if (x_mapping != NONE) {
|
||||||
mmat[0][x_mapping - 1] = 1.0f;
|
mmat[0][x_mapping - 1] = 1.0f;
|
||||||
if (y_mapping != NONE)
|
}
|
||||||
|
if (y_mapping != NONE) {
|
||||||
mmat[1][y_mapping - 1] = 1.0f;
|
mmat[1][y_mapping - 1] = 1.0f;
|
||||||
if (z_mapping != NONE)
|
}
|
||||||
|
if (z_mapping != NONE) {
|
||||||
mmat[2][z_mapping - 1] = 1.0f;
|
mmat[2][z_mapping - 1] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
float3 scale_clamped = scale;
|
float3 scale_clamped = scale;
|
||||||
|
|
||||||
if (type == TEXTURE || type == NORMAL) {
|
if (type == TEXTURE || type == NORMAL) {
|
||||||
/* keep matrix invertible */
|
/* keep matrix invertible */
|
||||||
if (fabsf(scale.x) < 1e-5f)
|
if (fabsf(scale.x) < 1e-5f) {
|
||||||
scale_clamped.x = signf(scale.x) * 1e-5f;
|
scale_clamped.x = signf(scale.x) * 1e-5f;
|
||||||
if (fabsf(scale.y) < 1e-5f)
|
}
|
||||||
|
if (fabsf(scale.y) < 1e-5f) {
|
||||||
scale_clamped.y = signf(scale.y) * 1e-5f;
|
scale_clamped.y = signf(scale.y) * 1e-5f;
|
||||||
if (fabsf(scale.z) < 1e-5f)
|
}
|
||||||
|
if (fabsf(scale.z) < 1e-5f) {
|
||||||
scale_clamped.z = signf(scale.z) * 1e-5f;
|
scale_clamped.z = signf(scale.z) * 1e-5f;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Transform smat = transform_scale(scale_clamped);
|
Transform smat = transform_scale(scale_clamped);
|
||||||
Transform rmat = transform_euler(rotation);
|
Transform rmat = transform_euler(rotation);
|
||||||
@ -126,17 +132,22 @@ Transform TextureMapping::compute_transform()
|
|||||||
|
|
||||||
bool TextureMapping::skip()
|
bool TextureMapping::skip()
|
||||||
{
|
{
|
||||||
if (translation != zero_float3())
|
if (translation != zero_float3()) {
|
||||||
return false;
|
return false;
|
||||||
if (rotation != zero_float3())
|
}
|
||||||
|
if (rotation != zero_float3()) {
|
||||||
return false;
|
return false;
|
||||||
if (scale != one_float3())
|
}
|
||||||
|
if (scale != one_float3()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (x_mapping != X || y_mapping != Y || z_mapping != Z)
|
if (x_mapping != X || y_mapping != Y || z_mapping != Z) {
|
||||||
return false;
|
return false;
|
||||||
if (use_minmax)
|
}
|
||||||
|
if (use_minmax) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -906,10 +917,12 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
|
|||||||
ShaderOutput *color_out = output("Color");
|
ShaderOutput *color_out = output("Color");
|
||||||
|
|
||||||
SunSky sunsky;
|
SunSky sunsky;
|
||||||
if (sky_type == NODE_SKY_PREETHAM)
|
if (sky_type == NODE_SKY_PREETHAM) {
|
||||||
sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity);
|
sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity);
|
||||||
else if (sky_type == NODE_SKY_HOSEK)
|
}
|
||||||
|
else if (sky_type == NODE_SKY_HOSEK) {
|
||||||
sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
|
sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
|
||||||
|
}
|
||||||
else if (sky_type == NODE_SKY_NISHITA) {
|
else if (sky_type == NODE_SKY_NISHITA) {
|
||||||
/* Clamp altitude to reasonable values.
|
/* Clamp altitude to reasonable values.
|
||||||
* Below 1m causes numerical issues and above 60km is space. */
|
* Below 1m causes numerical issues and above 60km is space. */
|
||||||
@ -937,8 +950,9 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
|
|||||||
handle = image_manager->add_image(loader, impar);
|
handle = image_manager->add_image(loader, impar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
assert(false);
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
|
int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
|
||||||
|
|
||||||
@ -1002,10 +1016,12 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
|
|||||||
tex_mapping.compile(compiler);
|
tex_mapping.compile(compiler);
|
||||||
|
|
||||||
SunSky sunsky;
|
SunSky sunsky;
|
||||||
if (sky_type == NODE_SKY_PREETHAM)
|
if (sky_type == NODE_SKY_PREETHAM) {
|
||||||
sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity);
|
sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity);
|
||||||
else if (sky_type == NODE_SKY_HOSEK)
|
}
|
||||||
|
else if (sky_type == NODE_SKY_HOSEK) {
|
||||||
sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
|
sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
|
||||||
|
}
|
||||||
else if (sky_type == NODE_SKY_NISHITA) {
|
else if (sky_type == NODE_SKY_NISHITA) {
|
||||||
/* Clamp altitude to reasonable values.
|
/* Clamp altitude to reasonable values.
|
||||||
* Below 1m causes numerical issues and above 60km is space. */
|
* Below 1m causes numerical issues and above 60km is space. */
|
||||||
@ -1033,8 +1049,9 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
|
|||||||
handle = image_manager->add_image(loader, impar);
|
handle = image_manager->add_image(loader, impar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
assert(false);
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
compiler.parameter(this, "sky_type");
|
compiler.parameter(this, "sky_type");
|
||||||
compiler.parameter("theta", sunsky.theta);
|
compiler.parameter("theta", sunsky.theta);
|
||||||
@ -1874,8 +1891,9 @@ ShaderNode *PointDensityTextureNode::clone(ShaderGraph *graph) const
|
|||||||
|
|
||||||
void PointDensityTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
void PointDensityTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||||
{
|
{
|
||||||
if (shader->has_volume)
|
if (shader->has_volume) {
|
||||||
attributes->add(ATTR_STD_GENERATED_TRANSFORM);
|
attributes->add(ATTR_STD_GENERATED_TRANSFORM);
|
||||||
|
}
|
||||||
|
|
||||||
ShaderNode::attributes(shader, attributes);
|
ShaderNode::attributes(shader, attributes);
|
||||||
}
|
}
|
||||||
@ -2153,10 +2171,12 @@ ConvertNode::ConvertNode(SocketType::Type from_, SocketType::Type to_, bool auto
|
|||||||
from = from_;
|
from = from_;
|
||||||
to = to_;
|
to = to_;
|
||||||
|
|
||||||
if (from == to)
|
if (from == to) {
|
||||||
special_type = SHADER_SPECIAL_TYPE_PROXY;
|
special_type = SHADER_SPECIAL_TYPE_PROXY;
|
||||||
else if (autoconvert)
|
}
|
||||||
|
else if (autoconvert) {
|
||||||
special_type = SHADER_SPECIAL_TYPE_AUTOCONVERT;
|
special_type = SHADER_SPECIAL_TYPE_AUTOCONVERT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Union usage requires a manual copy constructor. */
|
/* Union usage requires a manual copy constructor. */
|
||||||
@ -2225,45 +2245,53 @@ void ConvertNode::compile(SVMCompiler &compiler)
|
|||||||
ShaderOutput *out = outputs[0];
|
ShaderOutput *out = outputs[0];
|
||||||
|
|
||||||
if (from == SocketType::FLOAT) {
|
if (from == SocketType::FLOAT) {
|
||||||
if (to == SocketType::INT)
|
if (to == SocketType::INT) {
|
||||||
/* float to int */
|
/* float to int */
|
||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_CONVERT, NODE_CONVERT_FI, compiler.stack_assign(in), compiler.stack_assign(out));
|
NODE_CONVERT, NODE_CONVERT_FI, compiler.stack_assign(in), compiler.stack_assign(out));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
/* float to float3 */
|
/* float to float3 */
|
||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_CONVERT, NODE_CONVERT_FV, compiler.stack_assign(in), compiler.stack_assign(out));
|
NODE_CONVERT, NODE_CONVERT_FV, compiler.stack_assign(in), compiler.stack_assign(out));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (from == SocketType::INT) {
|
else if (from == SocketType::INT) {
|
||||||
if (to == SocketType::FLOAT)
|
if (to == SocketType::FLOAT) {
|
||||||
/* int to float */
|
/* int to float */
|
||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_CONVERT, NODE_CONVERT_IF, compiler.stack_assign(in), compiler.stack_assign(out));
|
NODE_CONVERT, NODE_CONVERT_IF, compiler.stack_assign(in), compiler.stack_assign(out));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
/* int to vector/point/normal */
|
/* int to vector/point/normal */
|
||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_CONVERT, NODE_CONVERT_IV, compiler.stack_assign(in), compiler.stack_assign(out));
|
NODE_CONVERT, NODE_CONVERT_IV, compiler.stack_assign(in), compiler.stack_assign(out));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (to == SocketType::FLOAT) {
|
else if (to == SocketType::FLOAT) {
|
||||||
if (from == SocketType::COLOR)
|
if (from == SocketType::COLOR) {
|
||||||
/* color to float */
|
/* color to float */
|
||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_CONVERT, NODE_CONVERT_CF, compiler.stack_assign(in), compiler.stack_assign(out));
|
NODE_CONVERT, NODE_CONVERT_CF, compiler.stack_assign(in), compiler.stack_assign(out));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
/* vector/point/normal to float */
|
/* vector/point/normal to float */
|
||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_CONVERT, NODE_CONVERT_VF, compiler.stack_assign(in), compiler.stack_assign(out));
|
NODE_CONVERT, NODE_CONVERT_VF, compiler.stack_assign(in), compiler.stack_assign(out));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (to == SocketType::INT) {
|
else if (to == SocketType::INT) {
|
||||||
if (from == SocketType::COLOR)
|
if (from == SocketType::COLOR) {
|
||||||
/* color to int */
|
/* color to int */
|
||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_CONVERT, NODE_CONVERT_CI, compiler.stack_assign(in), compiler.stack_assign(out));
|
NODE_CONVERT, NODE_CONVERT_CI, compiler.stack_assign(in), compiler.stack_assign(out));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
/* vector/point/normal to int */
|
/* vector/point/normal to int */
|
||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_CONVERT, NODE_CONVERT_VI, compiler.stack_assign(in), compiler.stack_assign(out));
|
NODE_CONVERT, NODE_CONVERT_VI, compiler.stack_assign(in), compiler.stack_assign(out));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
/* float3 to float3 */
|
/* float3 to float3 */
|
||||||
if (in->link) {
|
if (in->link) {
|
||||||
@ -2283,20 +2311,27 @@ void ConvertNode::compile(OSLCompiler &compiler)
|
|||||||
/* proxy nodes should have been removed at this point */
|
/* proxy nodes should have been removed at this point */
|
||||||
assert(special_type != SHADER_SPECIAL_TYPE_PROXY);
|
assert(special_type != SHADER_SPECIAL_TYPE_PROXY);
|
||||||
|
|
||||||
if (from == SocketType::FLOAT)
|
if (from == SocketType::FLOAT) {
|
||||||
compiler.add(this, "node_convert_from_float");
|
compiler.add(this, "node_convert_from_float");
|
||||||
else if (from == SocketType::INT)
|
}
|
||||||
|
else if (from == SocketType::INT) {
|
||||||
compiler.add(this, "node_convert_from_int");
|
compiler.add(this, "node_convert_from_int");
|
||||||
else if (from == SocketType::COLOR)
|
}
|
||||||
|
else if (from == SocketType::COLOR) {
|
||||||
compiler.add(this, "node_convert_from_color");
|
compiler.add(this, "node_convert_from_color");
|
||||||
else if (from == SocketType::VECTOR)
|
}
|
||||||
|
else if (from == SocketType::VECTOR) {
|
||||||
compiler.add(this, "node_convert_from_vector");
|
compiler.add(this, "node_convert_from_vector");
|
||||||
else if (from == SocketType::POINT)
|
}
|
||||||
|
else if (from == SocketType::POINT) {
|
||||||
compiler.add(this, "node_convert_from_point");
|
compiler.add(this, "node_convert_from_point");
|
||||||
else if (from == SocketType::NORMAL)
|
}
|
||||||
|
else if (from == SocketType::NORMAL) {
|
||||||
compiler.add(this, "node_convert_from_normal");
|
compiler.add(this, "node_convert_from_normal");
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
assert(0);
|
assert(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Base type for all closure-type nodes */
|
/* Base type for all closure-type nodes */
|
||||||
@ -2328,10 +2363,12 @@ void BsdfNode::compile(SVMCompiler &compiler,
|
|||||||
ShaderInput *normal_in = input("Normal");
|
ShaderInput *normal_in = input("Normal");
|
||||||
ShaderInput *tangent_in = input("Tangent");
|
ShaderInput *tangent_in = input("Tangent");
|
||||||
|
|
||||||
if (color_in->link)
|
if (color_in->link) {
|
||||||
compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
|
compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
|
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
|
||||||
|
}
|
||||||
|
|
||||||
int normal_offset = (normal_in) ? compiler.stack_assign_if_linked(normal_in) : SVM_STACK_INVALID;
|
int normal_offset = (normal_in) ? compiler.stack_assign_if_linked(normal_in) : SVM_STACK_INVALID;
|
||||||
int tangent_offset = (tangent_in) ? compiler.stack_assign_if_linked(tangent_in) :
|
int tangent_offset = (tangent_in) ? compiler.stack_assign_if_linked(tangent_in) :
|
||||||
@ -2405,9 +2442,10 @@ void GlossyBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
|||||||
{
|
{
|
||||||
if (shader->has_surface_link()) {
|
if (shader->has_surface_link()) {
|
||||||
ShaderInput *tangent_in = input("Tangent");
|
ShaderInput *tangent_in = input("Tangent");
|
||||||
if (!tangent_in->link && !is_isotropic())
|
if (!tangent_in->link && !is_isotropic()) {
|
||||||
attributes->add(ATTR_STD_GENERATED);
|
attributes->add(ATTR_STD_GENERATED);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ShaderNode::attributes(shader, attributes);
|
ShaderNode::attributes(shader, attributes);
|
||||||
}
|
}
|
||||||
@ -2740,9 +2778,10 @@ void PrincipledBsdfNode::attributes(Shader *shader, AttributeRequestSet *attribu
|
|||||||
if (shader->has_surface_link()) {
|
if (shader->has_surface_link()) {
|
||||||
ShaderInput *tangent_in = input("Tangent");
|
ShaderInput *tangent_in = input("Tangent");
|
||||||
|
|
||||||
if (!tangent_in->link)
|
if (!tangent_in->link) {
|
||||||
attributes->add(ATTR_STD_GENERATED);
|
attributes->add(ATTR_STD_GENERATED);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ShaderNode::attributes(shader, attributes);
|
ShaderNode::attributes(shader, attributes);
|
||||||
}
|
}
|
||||||
@ -2981,8 +3020,9 @@ void EmissionNode::compile(SVMCompiler &compiler)
|
|||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in));
|
NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
|
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
|
||||||
|
}
|
||||||
|
|
||||||
compiler.add_node(NODE_CLOSURE_EMISSION, compiler.closure_mix_weight_offset());
|
compiler.add_node(NODE_CLOSURE_EMISSION, compiler.closure_mix_weight_offset());
|
||||||
}
|
}
|
||||||
@ -3028,8 +3068,9 @@ void BackgroundNode::compile(SVMCompiler &compiler)
|
|||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in));
|
NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
|
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
|
||||||
|
}
|
||||||
|
|
||||||
compiler.add_node(NODE_CLOSURE_BACKGROUND, compiler.closure_mix_weight_offset());
|
compiler.add_node(NODE_CLOSURE_BACKGROUND, compiler.closure_mix_weight_offset());
|
||||||
}
|
}
|
||||||
@ -3145,10 +3186,12 @@ void VolumeNode::compile(SVMCompiler &compiler, ShaderInput *param1, ShaderInput
|
|||||||
{
|
{
|
||||||
ShaderInput *color_in = input("Color");
|
ShaderInput *color_in = input("Color");
|
||||||
|
|
||||||
if (color_in->link)
|
if (color_in->link) {
|
||||||
compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
|
compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
|
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
|
||||||
|
}
|
||||||
|
|
||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_CLOSURE_VOLUME,
|
NODE_CLOSURE_VOLUME,
|
||||||
@ -3297,10 +3340,12 @@ void PrincipledVolumeNode::compile(SVMCompiler &compiler)
|
|||||||
ShaderInput *blackbody_tint_in = input("Blackbody Tint");
|
ShaderInput *blackbody_tint_in = input("Blackbody Tint");
|
||||||
ShaderInput *temperature_in = input("Temperature");
|
ShaderInput *temperature_in = input("Temperature");
|
||||||
|
|
||||||
if (color_in->link)
|
if (color_in->link) {
|
||||||
compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
|
compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
|
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
|
||||||
|
}
|
||||||
|
|
||||||
compiler.add_node(NODE_PRINCIPLED_VOLUME,
|
compiler.add_node(NODE_PRINCIPLED_VOLUME,
|
||||||
compiler.encode_uchar4(compiler.stack_assign_if_linked(density_in),
|
compiler.encode_uchar4(compiler.stack_assign_if_linked(density_in),
|
||||||
@ -3677,12 +3722,15 @@ void GeometryNode::compile(SVMCompiler &compiler)
|
|||||||
|
|
||||||
void GeometryNode::compile(OSLCompiler &compiler)
|
void GeometryNode::compile(OSLCompiler &compiler)
|
||||||
{
|
{
|
||||||
if (bump == SHADER_BUMP_DX)
|
if (bump == SHADER_BUMP_DX) {
|
||||||
compiler.parameter("bump_offset", "dx");
|
compiler.parameter("bump_offset", "dx");
|
||||||
else if (bump == SHADER_BUMP_DY)
|
}
|
||||||
|
else if (bump == SHADER_BUMP_DY) {
|
||||||
compiler.parameter("bump_offset", "dy");
|
compiler.parameter("bump_offset", "dy");
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
compiler.parameter("bump_offset", "center");
|
compiler.parameter("bump_offset", "center");
|
||||||
|
}
|
||||||
|
|
||||||
compiler.add(this, "node_geometry");
|
compiler.add(this, "node_geometry");
|
||||||
}
|
}
|
||||||
@ -3714,12 +3762,14 @@ void TextureCoordinateNode::attributes(Shader *shader, AttributeRequestSet *attr
|
|||||||
{
|
{
|
||||||
if (shader->has_surface_link()) {
|
if (shader->has_surface_link()) {
|
||||||
if (!from_dupli) {
|
if (!from_dupli) {
|
||||||
if (!output("Generated")->links.empty())
|
if (!output("Generated")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_GENERATED);
|
attributes->add(ATTR_STD_GENERATED);
|
||||||
if (!output("UV")->links.empty())
|
}
|
||||||
|
if (!output("UV")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_UV);
|
attributes->add(ATTR_STD_UV);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (shader->has_volume) {
|
if (shader->has_volume) {
|
||||||
if (!from_dupli) {
|
if (!from_dupli) {
|
||||||
@ -3819,17 +3869,22 @@ void TextureCoordinateNode::compile(SVMCompiler &compiler)
|
|||||||
|
|
||||||
void TextureCoordinateNode::compile(OSLCompiler &compiler)
|
void TextureCoordinateNode::compile(OSLCompiler &compiler)
|
||||||
{
|
{
|
||||||
if (bump == SHADER_BUMP_DX)
|
if (bump == SHADER_BUMP_DX) {
|
||||||
compiler.parameter("bump_offset", "dx");
|
compiler.parameter("bump_offset", "dx");
|
||||||
else if (bump == SHADER_BUMP_DY)
|
}
|
||||||
|
else if (bump == SHADER_BUMP_DY) {
|
||||||
compiler.parameter("bump_offset", "dy");
|
compiler.parameter("bump_offset", "dy");
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
compiler.parameter("bump_offset", "center");
|
compiler.parameter("bump_offset", "center");
|
||||||
|
}
|
||||||
|
|
||||||
if (compiler.background)
|
if (compiler.background) {
|
||||||
compiler.parameter("is_background", true);
|
compiler.parameter("is_background", true);
|
||||||
if (compiler.output_type() == SHADER_TYPE_VOLUME)
|
}
|
||||||
|
if (compiler.output_type() == SHADER_TYPE_VOLUME) {
|
||||||
compiler.parameter("is_volume", true);
|
compiler.parameter("is_volume", true);
|
||||||
|
}
|
||||||
compiler.parameter(this, "use_transform");
|
compiler.parameter(this, "use_transform");
|
||||||
Transform ob_itfm = transform_inverse(ob_tfm);
|
Transform ob_itfm = transform_inverse(ob_tfm);
|
||||||
compiler.parameter("object_itfm", ob_itfm);
|
compiler.parameter("object_itfm", ob_itfm);
|
||||||
@ -3860,13 +3915,15 @@ void UVMapNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
|||||||
if (shader->has_surface) {
|
if (shader->has_surface) {
|
||||||
if (!from_dupli) {
|
if (!from_dupli) {
|
||||||
if (!output("UV")->links.empty()) {
|
if (!output("UV")->links.empty()) {
|
||||||
if (attribute != "")
|
if (attribute != "") {
|
||||||
attributes->add(attribute);
|
attributes->add(attribute);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
attributes->add(ATTR_STD_UV);
|
attributes->add(ATTR_STD_UV);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ShaderNode::attributes(shader, attributes);
|
ShaderNode::attributes(shader, attributes);
|
||||||
}
|
}
|
||||||
@ -3892,10 +3949,12 @@ void UVMapNode::compile(SVMCompiler &compiler)
|
|||||||
compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out));
|
compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (attribute != "")
|
if (attribute != "") {
|
||||||
attr = compiler.attribute(attribute);
|
attr = compiler.attribute(attribute);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
attr = compiler.attribute(ATTR_STD_UV);
|
attr = compiler.attribute(ATTR_STD_UV);
|
||||||
|
}
|
||||||
|
|
||||||
compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3);
|
compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3);
|
||||||
}
|
}
|
||||||
@ -3904,12 +3963,15 @@ void UVMapNode::compile(SVMCompiler &compiler)
|
|||||||
|
|
||||||
void UVMapNode::compile(OSLCompiler &compiler)
|
void UVMapNode::compile(OSLCompiler &compiler)
|
||||||
{
|
{
|
||||||
if (bump == SHADER_BUMP_DX)
|
if (bump == SHADER_BUMP_DX) {
|
||||||
compiler.parameter("bump_offset", "dx");
|
compiler.parameter("bump_offset", "dx");
|
||||||
else if (bump == SHADER_BUMP_DY)
|
}
|
||||||
|
else if (bump == SHADER_BUMP_DY) {
|
||||||
compiler.parameter("bump_offset", "dy");
|
compiler.parameter("bump_offset", "dy");
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
compiler.parameter("bump_offset", "center");
|
compiler.parameter("bump_offset", "center");
|
||||||
|
}
|
||||||
|
|
||||||
compiler.parameter(this, "from_dupli");
|
compiler.parameter(this, "from_dupli");
|
||||||
compiler.parameter(this, "attribute");
|
compiler.parameter(this, "attribute");
|
||||||
@ -4159,26 +4221,34 @@ ParticleInfoNode::ParticleInfoNode() : ShaderNode(get_node_type()) {}
|
|||||||
|
|
||||||
void ParticleInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
void ParticleInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||||
{
|
{
|
||||||
if (!output("Index")->links.empty())
|
if (!output("Index")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_PARTICLE);
|
attributes->add(ATTR_STD_PARTICLE);
|
||||||
if (!output("Random")->links.empty())
|
}
|
||||||
|
if (!output("Random")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_PARTICLE);
|
attributes->add(ATTR_STD_PARTICLE);
|
||||||
if (!output("Age")->links.empty())
|
}
|
||||||
|
if (!output("Age")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_PARTICLE);
|
attributes->add(ATTR_STD_PARTICLE);
|
||||||
if (!output("Lifetime")->links.empty())
|
}
|
||||||
|
if (!output("Lifetime")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_PARTICLE);
|
attributes->add(ATTR_STD_PARTICLE);
|
||||||
if (!output("Location")->links.empty())
|
}
|
||||||
|
if (!output("Location")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_PARTICLE);
|
attributes->add(ATTR_STD_PARTICLE);
|
||||||
|
}
|
||||||
#if 0 /* not yet supported */
|
#if 0 /* not yet supported */
|
||||||
if (!output("Rotation")->links.empty())
|
if (!output("Rotation")->links.empty())
|
||||||
attributes->add(ATTR_STD_PARTICLE);
|
attributes->add(ATTR_STD_PARTICLE);
|
||||||
#endif
|
#endif
|
||||||
if (!output("Size")->links.empty())
|
if (!output("Size")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_PARTICLE);
|
attributes->add(ATTR_STD_PARTICLE);
|
||||||
if (!output("Velocity")->links.empty())
|
}
|
||||||
|
if (!output("Velocity")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_PARTICLE);
|
attributes->add(ATTR_STD_PARTICLE);
|
||||||
if (!output("Angular Velocity")->links.empty())
|
}
|
||||||
|
if (!output("Angular Velocity")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_PARTICLE);
|
attributes->add(ATTR_STD_PARTICLE);
|
||||||
|
}
|
||||||
|
|
||||||
ShaderNode::attributes(shader, attributes);
|
ShaderNode::attributes(shader, attributes);
|
||||||
}
|
}
|
||||||
@ -4265,15 +4335,18 @@ void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
|||||||
if (shader->has_surface_link()) {
|
if (shader->has_surface_link()) {
|
||||||
ShaderOutput *intercept_out = output("Intercept");
|
ShaderOutput *intercept_out = output("Intercept");
|
||||||
|
|
||||||
if (!intercept_out->links.empty())
|
if (!intercept_out->links.empty()) {
|
||||||
attributes->add(ATTR_STD_CURVE_INTERCEPT);
|
attributes->add(ATTR_STD_CURVE_INTERCEPT);
|
||||||
|
}
|
||||||
|
|
||||||
if (!output("Length")->links.empty())
|
if (!output("Length")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_CURVE_LENGTH);
|
attributes->add(ATTR_STD_CURVE_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
if (!output("Random")->links.empty())
|
if (!output("Random")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_CURVE_RANDOM);
|
attributes->add(ATTR_STD_CURVE_RANDOM);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ShaderNode::attributes(shader, attributes);
|
ShaderNode::attributes(shader, attributes);
|
||||||
}
|
}
|
||||||
@ -4339,9 +4412,10 @@ PointInfoNode::PointInfoNode() : ShaderNode(get_node_type()) {}
|
|||||||
void PointInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
void PointInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||||
{
|
{
|
||||||
if (shader->has_surface_link()) {
|
if (shader->has_surface_link()) {
|
||||||
if (!output("Random")->links.empty())
|
if (!output("Random")->links.empty()) {
|
||||||
attributes->add(ATTR_STD_POINT_RANDOM);
|
attributes->add(ATTR_STD_POINT_RANDOM);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ShaderNode::attributes(shader, attributes);
|
ShaderNode::attributes(shader, attributes);
|
||||||
}
|
}
|
||||||
@ -4466,11 +4540,13 @@ VertexColorNode::VertexColorNode() : ShaderNode(get_node_type()) {}
|
|||||||
void VertexColorNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
void VertexColorNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||||
{
|
{
|
||||||
if (!(output("Color")->links.empty() && output("Alpha")->links.empty())) {
|
if (!(output("Color")->links.empty() && output("Alpha")->links.empty())) {
|
||||||
if (layer_name != "")
|
if (layer_name != "") {
|
||||||
attributes->add_standard(layer_name);
|
attributes->add_standard(layer_name);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
attributes->add(ATTR_STD_VERTEX_COLOR);
|
attributes->add(ATTR_STD_VERTEX_COLOR);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ShaderNode::attributes(shader, attributes);
|
ShaderNode::attributes(shader, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4489,10 +4565,12 @@ void VertexColorNode::compile(SVMCompiler &compiler)
|
|||||||
|
|
||||||
ShaderNodeType node;
|
ShaderNodeType node;
|
||||||
|
|
||||||
if (bump == SHADER_BUMP_DX)
|
if (bump == SHADER_BUMP_DX) {
|
||||||
node = NODE_VERTEX_COLOR_BUMP_DX;
|
node = NODE_VERTEX_COLOR_BUMP_DX;
|
||||||
else if (bump == SHADER_BUMP_DY)
|
}
|
||||||
|
else if (bump == SHADER_BUMP_DY) {
|
||||||
node = NODE_VERTEX_COLOR_BUMP_DY;
|
node = NODE_VERTEX_COLOR_BUMP_DY;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
node = NODE_VERTEX_COLOR;
|
node = NODE_VERTEX_COLOR;
|
||||||
}
|
}
|
||||||
@ -5682,10 +5760,12 @@ void AttributeNode::compile(SVMCompiler &compiler)
|
|||||||
ShaderNodeType attr_node = NODE_ATTR;
|
ShaderNodeType attr_node = NODE_ATTR;
|
||||||
int attr = compiler.attribute_standard(attribute);
|
int attr = compiler.attribute_standard(attribute);
|
||||||
|
|
||||||
if (bump == SHADER_BUMP_DX)
|
if (bump == SHADER_BUMP_DX) {
|
||||||
attr_node = NODE_ATTR_BUMP_DX;
|
attr_node = NODE_ATTR_BUMP_DX;
|
||||||
else if (bump == SHADER_BUMP_DY)
|
}
|
||||||
|
else if (bump == SHADER_BUMP_DY) {
|
||||||
attr_node = NODE_ATTR_BUMP_DY;
|
attr_node = NODE_ATTR_BUMP_DY;
|
||||||
|
}
|
||||||
|
|
||||||
if (!color_out->links.empty() || !vector_out->links.empty()) {
|
if (!color_out->links.empty() || !vector_out->links.empty()) {
|
||||||
if (!color_out->links.empty()) {
|
if (!color_out->links.empty()) {
|
||||||
@ -5710,17 +5790,22 @@ void AttributeNode::compile(SVMCompiler &compiler)
|
|||||||
|
|
||||||
void AttributeNode::compile(OSLCompiler &compiler)
|
void AttributeNode::compile(OSLCompiler &compiler)
|
||||||
{
|
{
|
||||||
if (bump == SHADER_BUMP_DX)
|
if (bump == SHADER_BUMP_DX) {
|
||||||
compiler.parameter("bump_offset", "dx");
|
compiler.parameter("bump_offset", "dx");
|
||||||
else if (bump == SHADER_BUMP_DY)
|
}
|
||||||
|
else if (bump == SHADER_BUMP_DY) {
|
||||||
compiler.parameter("bump_offset", "dy");
|
compiler.parameter("bump_offset", "dy");
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
compiler.parameter("bump_offset", "center");
|
compiler.parameter("bump_offset", "center");
|
||||||
|
}
|
||||||
|
|
||||||
if (Attribute::name_standard(attribute.c_str()) != ATTR_STD_NONE)
|
if (Attribute::name_standard(attribute.c_str()) != ATTR_STD_NONE) {
|
||||||
compiler.parameter("name", (string("geom:") + attribute.c_str()).c_str());
|
compiler.parameter("name", (string("geom:") + attribute.c_str()).c_str());
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
compiler.parameter("name", attribute.c_str());
|
compiler.parameter("name", attribute.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
compiler.add(this, "node_attribute");
|
compiler.add(this, "node_attribute");
|
||||||
}
|
}
|
||||||
@ -5985,12 +6070,15 @@ void OutputNode::compile(SVMCompiler &compiler)
|
|||||||
|
|
||||||
void OutputNode::compile(OSLCompiler &compiler)
|
void OutputNode::compile(OSLCompiler &compiler)
|
||||||
{
|
{
|
||||||
if (compiler.output_type() == SHADER_TYPE_SURFACE)
|
if (compiler.output_type() == SHADER_TYPE_SURFACE) {
|
||||||
compiler.add(this, "node_output_surface");
|
compiler.add(this, "node_output_surface");
|
||||||
else if (compiler.output_type() == SHADER_TYPE_VOLUME)
|
}
|
||||||
|
else if (compiler.output_type() == SHADER_TYPE_VOLUME) {
|
||||||
compiler.add(this, "node_output_volume");
|
compiler.add(this, "node_output_volume");
|
||||||
else if (compiler.output_type() == SHADER_TYPE_DISPLACEMENT)
|
}
|
||||||
|
else if (compiler.output_type() == SHADER_TYPE_DISPLACEMENT) {
|
||||||
compiler.add(this, "node_output_displacement");
|
compiler.add(this, "node_output_displacement");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map Range Node */
|
/* Map Range Node */
|
||||||
@ -6703,8 +6791,9 @@ void CurvesNode::compile(SVMCompiler &compiler,
|
|||||||
ShaderInput *value_in,
|
ShaderInput *value_in,
|
||||||
ShaderOutput *value_out)
|
ShaderOutput *value_out)
|
||||||
{
|
{
|
||||||
if (curves.size() == 0)
|
if (curves.size() == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ShaderInput *fac_in = input("Fac");
|
ShaderInput *fac_in = input("Fac");
|
||||||
|
|
||||||
@ -6717,14 +6806,16 @@ void CurvesNode::compile(SVMCompiler &compiler,
|
|||||||
__float_as_int(max_x));
|
__float_as_int(max_x));
|
||||||
|
|
||||||
compiler.add_node(curves.size());
|
compiler.add_node(curves.size());
|
||||||
for (int i = 0; i < curves.size(); i++)
|
for (int i = 0; i < curves.size(); i++) {
|
||||||
compiler.add_node(float3_to_float4(curves[i]));
|
compiler.add_node(float3_to_float4(curves[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CurvesNode::compile(OSLCompiler &compiler, const char *name)
|
void CurvesNode::compile(OSLCompiler &compiler, const char *name)
|
||||||
{
|
{
|
||||||
if (curves.size() == 0)
|
if (curves.size() == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
compiler.parameter_color_array("ramp", curves);
|
compiler.parameter_color_array("ramp", curves);
|
||||||
compiler.parameter(this, "min_x");
|
compiler.parameter(this, "min_x");
|
||||||
@ -6861,8 +6952,9 @@ void FloatCurveNode::constant_fold(const ConstantFolder &folder)
|
|||||||
|
|
||||||
void FloatCurveNode::compile(SVMCompiler &compiler)
|
void FloatCurveNode::compile(SVMCompiler &compiler)
|
||||||
{
|
{
|
||||||
if (curve.size() == 0)
|
if (curve.size() == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ShaderInput *value_in = input("Value");
|
ShaderInput *value_in = input("Value");
|
||||||
ShaderInput *fac_in = input("Factor");
|
ShaderInput *fac_in = input("Factor");
|
||||||
@ -6877,14 +6969,16 @@ void FloatCurveNode::compile(SVMCompiler &compiler)
|
|||||||
__float_as_int(max_x));
|
__float_as_int(max_x));
|
||||||
|
|
||||||
compiler.add_node(curve.size());
|
compiler.add_node(curve.size());
|
||||||
for (int i = 0; i < curve.size(); i++)
|
for (int i = 0; i < curve.size(); i++) {
|
||||||
compiler.add_node(make_float4(curve[i]));
|
compiler.add_node(make_float4(curve[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloatCurveNode::compile(OSLCompiler &compiler)
|
void FloatCurveNode::compile(OSLCompiler &compiler)
|
||||||
{
|
{
|
||||||
if (curve.size() == 0)
|
if (curve.size() == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
compiler.parameter_array("ramp", curve.data(), curve.size());
|
compiler.parameter_array("ramp", curve.data(), curve.size());
|
||||||
compiler.parameter(this, "min_x");
|
compiler.parameter(this, "min_x");
|
||||||
@ -6915,8 +7009,9 @@ RGBRampNode::RGBRampNode() : ShaderNode(get_node_type()) {}
|
|||||||
|
|
||||||
void RGBRampNode::constant_fold(const ConstantFolder &folder)
|
void RGBRampNode::constant_fold(const ConstantFolder &folder)
|
||||||
{
|
{
|
||||||
if (ramp.size() == 0 || ramp.size() != ramp_alpha.size())
|
if (ramp.size() == 0 || ramp.size() != ramp_alpha.size()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (folder.all_inputs_constant()) {
|
if (folder.all_inputs_constant()) {
|
||||||
float f = clamp(fac, 0.0f, 1.0f) * (ramp.size() - 1);
|
float f = clamp(fac, 0.0f, 1.0f) * (ramp.size() - 1);
|
||||||
@ -6940,8 +7035,9 @@ void RGBRampNode::constant_fold(const ConstantFolder &folder)
|
|||||||
|
|
||||||
void RGBRampNode::compile(SVMCompiler &compiler)
|
void RGBRampNode::compile(SVMCompiler &compiler)
|
||||||
{
|
{
|
||||||
if (ramp.size() == 0 || ramp.size() != ramp_alpha.size())
|
if (ramp.size() == 0 || ramp.size() != ramp_alpha.size()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ShaderInput *fac_in = input("Fac");
|
ShaderInput *fac_in = input("Fac");
|
||||||
ShaderOutput *color_out = output("Color");
|
ShaderOutput *color_out = output("Color");
|
||||||
@ -6954,14 +7050,16 @@ void RGBRampNode::compile(SVMCompiler &compiler)
|
|||||||
interpolate);
|
interpolate);
|
||||||
|
|
||||||
compiler.add_node(ramp.size());
|
compiler.add_node(ramp.size());
|
||||||
for (int i = 0; i < ramp.size(); i++)
|
for (int i = 0; i < ramp.size(); i++) {
|
||||||
compiler.add_node(make_float4(ramp[i].x, ramp[i].y, ramp[i].z, ramp_alpha[i]));
|
compiler.add_node(make_float4(ramp[i].x, ramp[i].y, ramp[i].z, ramp_alpha[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RGBRampNode::compile(OSLCompiler &compiler)
|
void RGBRampNode::compile(OSLCompiler &compiler)
|
||||||
{
|
{
|
||||||
if (ramp.size() == 0 || ramp.size() != ramp_alpha.size())
|
if (ramp.size() == 0 || ramp.size() != ramp_alpha.size()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
compiler.parameter_color_array("ramp_color", ramp);
|
compiler.parameter_color_array("ramp_color", ramp);
|
||||||
compiler.parameter_array("ramp_alpha", ramp_alpha.data(), ramp_alpha.size());
|
compiler.parameter_array("ramp_alpha", ramp_alpha.data(), ramp_alpha.size());
|
||||||
@ -7071,10 +7169,12 @@ void OSLNode::compile(SVMCompiler &)
|
|||||||
|
|
||||||
void OSLNode::compile(OSLCompiler &compiler)
|
void OSLNode::compile(OSLCompiler &compiler)
|
||||||
{
|
{
|
||||||
if (!filepath.empty())
|
if (!filepath.empty()) {
|
||||||
compiler.add(this, filepath.c_str(), true);
|
compiler.add(this, filepath.c_str(), true);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
compiler.add(this, bytecode_hash.c_str(), false);
|
compiler.add(this, bytecode_hash.c_str(), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Normal Map */
|
/* Normal Map */
|
||||||
@ -7195,14 +7295,17 @@ void TangentNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
|||||||
{
|
{
|
||||||
if (shader->has_surface_link()) {
|
if (shader->has_surface_link()) {
|
||||||
if (direction_type == NODE_TANGENT_UVMAP) {
|
if (direction_type == NODE_TANGENT_UVMAP) {
|
||||||
if (attribute.empty())
|
if (attribute.empty()) {
|
||||||
attributes->add(ATTR_STD_UV_TANGENT);
|
attributes->add(ATTR_STD_UV_TANGENT);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
|
attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
attributes->add(ATTR_STD_GENERATED);
|
attributes->add(ATTR_STD_GENERATED);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ShaderNode::attributes(shader, attributes);
|
ShaderNode::attributes(shader, attributes);
|
||||||
}
|
}
|
||||||
@ -7213,13 +7316,16 @@ void TangentNode::compile(SVMCompiler &compiler)
|
|||||||
int attr;
|
int attr;
|
||||||
|
|
||||||
if (direction_type == NODE_TANGENT_UVMAP) {
|
if (direction_type == NODE_TANGENT_UVMAP) {
|
||||||
if (attribute.empty())
|
if (attribute.empty()) {
|
||||||
attr = compiler.attribute(ATTR_STD_UV_TANGENT);
|
attr = compiler.attribute(ATTR_STD_UV_TANGENT);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
|
attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
attr = compiler.attribute(ATTR_STD_GENERATED);
|
attr = compiler.attribute(ATTR_STD_GENERATED);
|
||||||
|
}
|
||||||
|
|
||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_TANGENT,
|
NODE_TANGENT,
|
||||||
@ -7230,11 +7336,13 @@ void TangentNode::compile(SVMCompiler &compiler)
|
|||||||
void TangentNode::compile(OSLCompiler &compiler)
|
void TangentNode::compile(OSLCompiler &compiler)
|
||||||
{
|
{
|
||||||
if (direction_type == NODE_TANGENT_UVMAP) {
|
if (direction_type == NODE_TANGENT_UVMAP) {
|
||||||
if (attribute.empty())
|
if (attribute.empty()) {
|
||||||
compiler.parameter("attr_name", ustring("geom:tangent"));
|
compiler.parameter("attr_name", ustring("geom:tangent"));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
|
compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
compiler.parameter(this, "direction_type");
|
compiler.parameter(this, "direction_type");
|
||||||
compiler.parameter(this, "axis");
|
compiler.parameter(this, "axis");
|
||||||
|
@ -54,8 +54,9 @@ void SVMShaderManager::device_update_specific(Device *device,
|
|||||||
Scene *scene,
|
Scene *scene,
|
||||||
Progress &progress)
|
Progress &progress)
|
||||||
{
|
{
|
||||||
if (!need_update())
|
if (!need_update()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
@ -200,17 +201,20 @@ int SVMCompiler::stack_find_offset(int size)
|
|||||||
|
|
||||||
/* find free space in stack & mark as used */
|
/* find free space in stack & mark as used */
|
||||||
for (int i = 0, num_unused = 0; i < SVM_STACK_SIZE; i++) {
|
for (int i = 0, num_unused = 0; i < SVM_STACK_SIZE; i++) {
|
||||||
if (active_stack.users[i])
|
if (active_stack.users[i]) {
|
||||||
num_unused = 0;
|
num_unused = 0;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
num_unused++;
|
num_unused++;
|
||||||
|
}
|
||||||
|
|
||||||
if (num_unused == size) {
|
if (num_unused == size) {
|
||||||
offset = i + 1 - size;
|
offset = i + 1 - size;
|
||||||
max_stack_use = max(i + 1, max_stack_use);
|
max_stack_use = max(i + 1, max_stack_use);
|
||||||
|
|
||||||
while (i >= offset)
|
while (i >= offset) {
|
||||||
active_stack.users[i--] = 1;
|
active_stack.users[i--] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
@ -235,8 +239,9 @@ void SVMCompiler::stack_clear_offset(SocketType::Type type, int offset)
|
|||||||
{
|
{
|
||||||
int size = stack_size(type);
|
int size = stack_size(type);
|
||||||
|
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++) {
|
||||||
active_stack.users[offset + i]--;
|
active_stack.users[offset + i]--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int SVMCompiler::stack_assign(ShaderInput *input)
|
int SVMCompiler::stack_assign(ShaderInput *input)
|
||||||
@ -269,10 +274,11 @@ int SVMCompiler::stack_assign(ShaderInput *input)
|
|||||||
add_node(NODE_VALUE_V, input->stack_offset);
|
add_node(NODE_VALUE_V, input->stack_offset);
|
||||||
add_node(NODE_VALUE_V, node->get_float3(input->socket_type));
|
add_node(NODE_VALUE_V, node->get_float3(input->socket_type));
|
||||||
}
|
}
|
||||||
else /* should not get called for closure */
|
else { /* should not get called for closure */
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return input->stack_offset;
|
return input->stack_offset;
|
||||||
}
|
}
|
||||||
@ -280,24 +286,27 @@ int SVMCompiler::stack_assign(ShaderInput *input)
|
|||||||
int SVMCompiler::stack_assign(ShaderOutput *output)
|
int SVMCompiler::stack_assign(ShaderOutput *output)
|
||||||
{
|
{
|
||||||
/* if no stack offset assigned yet, find one */
|
/* if no stack offset assigned yet, find one */
|
||||||
if (output->stack_offset == SVM_STACK_INVALID)
|
if (output->stack_offset == SVM_STACK_INVALID) {
|
||||||
output->stack_offset = stack_find_offset(output->type());
|
output->stack_offset = stack_find_offset(output->type());
|
||||||
|
}
|
||||||
|
|
||||||
return output->stack_offset;
|
return output->stack_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SVMCompiler::stack_assign_if_linked(ShaderInput *input)
|
int SVMCompiler::stack_assign_if_linked(ShaderInput *input)
|
||||||
{
|
{
|
||||||
if (input->link || input->constant_folded_in)
|
if (input->link || input->constant_folded_in) {
|
||||||
return stack_assign(input);
|
return stack_assign(input);
|
||||||
|
}
|
||||||
|
|
||||||
return SVM_STACK_INVALID;
|
return SVM_STACK_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SVMCompiler::stack_assign_if_linked(ShaderOutput *output)
|
int SVMCompiler::stack_assign_if_linked(ShaderOutput *output)
|
||||||
{
|
{
|
||||||
if (!output->links.empty())
|
if (!output->links.empty()) {
|
||||||
return stack_assign(output);
|
return stack_assign(output);
|
||||||
|
}
|
||||||
|
|
||||||
return SVM_STACK_INVALID;
|
return SVM_STACK_INVALID;
|
||||||
}
|
}
|
||||||
@ -312,9 +321,10 @@ void SVMCompiler::stack_link(ShaderInput *input, ShaderOutput *output)
|
|||||||
|
|
||||||
int size = stack_size(output->type());
|
int size = stack_size(output->type());
|
||||||
|
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++) {
|
||||||
active_stack.users[output->stack_offset + i]++;
|
active_stack.users[output->stack_offset + i]++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVMCompiler::stack_clear_users(ShaderNode *node, ShaderNodeSet &done)
|
void SVMCompiler::stack_clear_users(ShaderNode *node, ShaderNodeSet &done)
|
||||||
@ -334,8 +344,9 @@ void SVMCompiler::stack_clear_users(ShaderNode *node, ShaderNodeSet &done)
|
|||||||
|
|
||||||
/* optimization we should add: verify if in->parent is actually used */
|
/* optimization we should add: verify if in->parent is actually used */
|
||||||
foreach (ShaderInput *in, output->links)
|
foreach (ShaderInput *in, output->links)
|
||||||
if (in->parent != node && done.find(in->parent) == done.end())
|
if (in->parent != node && done.find(in->parent) == done.end()) {
|
||||||
all_done = false;
|
all_done = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (all_done) {
|
if (all_done) {
|
||||||
stack_clear_offset(output->type(), output->stack_offset);
|
stack_clear_offset(output->type(), output->stack_offset);
|
||||||
@ -431,17 +442,21 @@ void SVMCompiler::generate_node(ShaderNode *node, ShaderNodeSet &done)
|
|||||||
stack_clear_temporary(node);
|
stack_clear_temporary(node);
|
||||||
|
|
||||||
if (current_type == SHADER_TYPE_SURFACE) {
|
if (current_type == SHADER_TYPE_SURFACE) {
|
||||||
if (node->has_spatial_varying())
|
if (node->has_spatial_varying()) {
|
||||||
current_shader->has_surface_spatial_varying = true;
|
current_shader->has_surface_spatial_varying = true;
|
||||||
if (node->get_feature() & KERNEL_FEATURE_NODE_RAYTRACE)
|
}
|
||||||
|
if (node->get_feature() & KERNEL_FEATURE_NODE_RAYTRACE) {
|
||||||
current_shader->has_surface_raytrace = true;
|
current_shader->has_surface_raytrace = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (current_type == SHADER_TYPE_VOLUME) {
|
else if (current_type == SHADER_TYPE_VOLUME) {
|
||||||
if (node->has_spatial_varying())
|
if (node->has_spatial_varying()) {
|
||||||
current_shader->has_volume_spatial_varying = true;
|
current_shader->has_volume_spatial_varying = true;
|
||||||
if (node->has_attribute_dependency())
|
}
|
||||||
|
if (node->has_attribute_dependency()) {
|
||||||
current_shader->has_volume_attribute_dependency = true;
|
current_shader->has_volume_attribute_dependency = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVMCompiler::generate_svm_nodes(const ShaderNodeSet &nodes, CompilerState *state)
|
void SVMCompiler::generate_svm_nodes(const ShaderNodeSet &nodes, CompilerState *state)
|
||||||
@ -498,10 +513,12 @@ void SVMCompiler::generate_closure_node(ShaderNode *node, CompilerState *state)
|
|||||||
"SurfaceMixWeight";
|
"SurfaceMixWeight";
|
||||||
ShaderInput *weight_in = node->input(weight_name);
|
ShaderInput *weight_in = node->input(weight_name);
|
||||||
|
|
||||||
if (weight_in && (weight_in->link || node->get_float(weight_in->socket_type) != 1.0f))
|
if (weight_in && (weight_in->link || node->get_float(weight_in->socket_type) != 1.0f)) {
|
||||||
mix_weight_offset = stack_assign(weight_in);
|
mix_weight_offset = stack_assign(weight_in);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
mix_weight_offset = SVM_STACK_INVALID;
|
mix_weight_offset = SVM_STACK_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
/* compile closure itself */
|
/* compile closure itself */
|
||||||
generate_node(node, state->nodes_done);
|
generate_node(node, state->nodes_done);
|
||||||
@ -509,13 +526,15 @@ void SVMCompiler::generate_closure_node(ShaderNode *node, CompilerState *state)
|
|||||||
mix_weight_offset = SVM_STACK_INVALID;
|
mix_weight_offset = SVM_STACK_INVALID;
|
||||||
|
|
||||||
if (current_type == SHADER_TYPE_SURFACE) {
|
if (current_type == SHADER_TYPE_SURFACE) {
|
||||||
if (node->has_surface_transparent())
|
if (node->has_surface_transparent()) {
|
||||||
current_shader->has_surface_transparent = true;
|
current_shader->has_surface_transparent = true;
|
||||||
|
}
|
||||||
if (node->has_surface_bssrdf()) {
|
if (node->has_surface_bssrdf()) {
|
||||||
current_shader->has_surface_bssrdf = true;
|
current_shader->has_surface_bssrdf = true;
|
||||||
if (node->has_bssrdf_bump())
|
if (node->has_bssrdf_bump()) {
|
||||||
current_shader->has_bssrdf_bump = true;
|
current_shader->has_bssrdf_bump = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (node->has_bump()) {
|
if (node->has_bump()) {
|
||||||
current_shader->has_bump = true;
|
current_shader->has_bump = true;
|
||||||
}
|
}
|
||||||
@ -532,10 +551,11 @@ void SVMCompiler::generated_shared_closure_nodes(ShaderNode *root_node,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
foreach (ShaderInput *in, node->inputs) {
|
foreach (ShaderInput *in, node->inputs) {
|
||||||
if (in->type() == SocketType::CLOSURE && in->link)
|
if (in->type() == SocketType::CLOSURE && in->link) {
|
||||||
generated_shared_closure_nodes(root_node, in->link->parent, state, shared);
|
generated_shared_closure_nodes(root_node, in->link->parent, state, shared);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVMCompiler::find_aov_nodes_and_dependencies(ShaderNodeSet &aov_nodes,
|
void SVMCompiler::find_aov_nodes_and_dependencies(ShaderNodeSet &aov_nodes,
|
||||||
@ -562,8 +582,9 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
|||||||
CompilerState *state)
|
CompilerState *state)
|
||||||
{
|
{
|
||||||
/* only generate once */
|
/* only generate once */
|
||||||
if (state->closure_done.find(node) != state->closure_done.end())
|
if (state->closure_done.find(node) != state->closure_done.end()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
state->closure_done.insert(node);
|
state->closure_done.insert(node);
|
||||||
|
|
||||||
@ -574,8 +595,9 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
|||||||
ShaderInput *facin = node->input("Fac");
|
ShaderInput *facin = node->input("Fac");
|
||||||
|
|
||||||
/* skip empty mix/add closure nodes */
|
/* skip empty mix/add closure nodes */
|
||||||
if (!cl1in->link && !cl2in->link)
|
if (!cl1in->link && !cl2in->link) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (facin && facin->link) {
|
if (facin && facin->link) {
|
||||||
/* mix closure: generate instructions to compute mix weight */
|
/* mix closure: generate instructions to compute mix weight */
|
||||||
@ -691,12 +713,14 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
|||||||
/* execute closures and their dependencies, no runtime checks
|
/* execute closures and their dependencies, no runtime checks
|
||||||
* to skip closures here because was already optimized due to
|
* to skip closures here because was already optimized due to
|
||||||
* fixed weight or add closure that always needs both */
|
* fixed weight or add closure that always needs both */
|
||||||
if (cl1in->link)
|
if (cl1in->link) {
|
||||||
generate_multi_closure(root_node, cl1in->link->parent, state);
|
generate_multi_closure(root_node, cl1in->link->parent, state);
|
||||||
if (cl2in->link)
|
}
|
||||||
|
if (cl2in->link) {
|
||||||
generate_multi_closure(root_node, cl2in->link->parent, state);
|
generate_multi_closure(root_node, cl2in->link->parent, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
generate_closure_node(node, state);
|
generate_closure_node(node, state);
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,9 @@ LookupTables::~LookupTables()
|
|||||||
|
|
||||||
void LookupTables::device_update(Device *, DeviceScene *dscene, Scene *scene)
|
void LookupTables::device_update(Device *, DeviceScene *dscene, Scene *scene)
|
||||||
{
|
{
|
||||||
if (!need_update())
|
if (!need_update()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
@ -37,8 +38,9 @@ void LookupTables::device_update(Device *, DeviceScene *dscene, Scene *scene)
|
|||||||
|
|
||||||
VLOG_INFO << "Total " << lookup_tables.size() << " lookup tables.";
|
VLOG_INFO << "Total " << lookup_tables.size() << " lookup tables.";
|
||||||
|
|
||||||
if (lookup_tables.size() > 0)
|
if (lookup_tables.size() > 0) {
|
||||||
dscene->lookup_table.copy_to_device();
|
dscene->lookup_table.copy_to_device();
|
||||||
|
}
|
||||||
|
|
||||||
need_update_ = false;
|
need_update_ = false;
|
||||||
}
|
}
|
||||||
@ -76,9 +78,10 @@ size_t LookupTables::add_table(DeviceScene *dscene, vector<float> &data)
|
|||||||
lookup_tables.insert(table, new_table);
|
lookup_tables.insert(table, new_table);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
new_table.offset = table->offset + table->size;
|
new_table.offset = table->offset + table->size;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (table == lookup_tables.end()) {
|
if (table == lookup_tables.end()) {
|
||||||
/* add at the end */
|
/* add at the end */
|
||||||
|
@ -290,8 +290,9 @@ bool RenderBuffers::copy_from_device()
|
|||||||
{
|
{
|
||||||
DCHECK(params.pass_stride != -1);
|
DCHECK(params.pass_stride != -1);
|
||||||
|
|
||||||
if (!buffer.device_pointer)
|
if (!buffer.device_pointer) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
buffer.copy_from_device(0, params.width * params.pass_stride, params.height);
|
buffer.copy_from_device(0, params.width * params.pass_stride, params.height);
|
||||||
|
|
||||||
|
@ -273,10 +273,12 @@ void Session::thread_render()
|
|||||||
profiler.stop();
|
profiler.stop();
|
||||||
|
|
||||||
/* progress update */
|
/* progress update */
|
||||||
if (progress.get_cancel())
|
if (progress.get_cancel()) {
|
||||||
progress.set_status(progress.get_cancel_message());
|
progress.set_status(progress.get_cancel_message());
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
progress.set_update();
|
progress.set_update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Session::is_session_thread_rendering()
|
bool Session::is_session_thread_rendering()
|
||||||
|
@ -77,8 +77,9 @@ void EdgeDice::stitch_triangles(Subpatch &sub, int edge)
|
|||||||
int outer_T = sub.edges[edge].T;
|
int outer_T = sub.edges[edge].T;
|
||||||
int inner_T = ((edge % 2) == 0) ? Mv - 2 : Mu - 2;
|
int inner_T = ((edge % 2) == 0) ? Mv - 2 : Mu - 2;
|
||||||
|
|
||||||
if (inner_T < 0 || outer_T < 0)
|
if (inner_T < 0 || outer_T < 0) {
|
||||||
return; // XXX avoid crashes for Mu or Mv == 1, missing polygons
|
return; // XXX avoid crashes for Mu or Mv == 1, missing polygons
|
||||||
|
}
|
||||||
|
|
||||||
/* stitch together two arrays of verts with triangles. at each step,
|
/* stitch together two arrays of verts with triangles. at each step,
|
||||||
* we compare using the next verts on both sides, to find the split
|
* we compare using the next verts on both sides, to find the split
|
||||||
@ -104,11 +105,13 @@ void EdgeDice::stitch_triangles(Subpatch &sub, int edge)
|
|||||||
mesh_P[sub.get_vert_along_grid_edge(edge, i + 1)]);
|
mesh_P[sub.get_vert_along_grid_edge(edge, i + 1)]);
|
||||||
|
|
||||||
/* use smallest diagonal */
|
/* use smallest diagonal */
|
||||||
if (len1 < len2)
|
if (len1 < len2) {
|
||||||
v2 = sub.get_vert_along_edge(edge, ++j);
|
v2 = sub.get_vert_along_edge(edge, ++j);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
v2 = sub.get_vert_along_grid_edge(edge, ++i);
|
v2 = sub.get_vert_along_grid_edge(edge, ++i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
add_triangle(sub.patch, v1, v0, v2);
|
add_triangle(sub.patch, v1, v0, v2);
|
||||||
}
|
}
|
||||||
@ -132,8 +135,9 @@ float3 QuadDice::eval_projected(Subpatch &sub, float u, float v)
|
|||||||
float3 P;
|
float3 P;
|
||||||
|
|
||||||
sub.patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
|
sub.patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
|
||||||
if (params.camera)
|
if (params.camera) {
|
||||||
P = transform_perspective(¶ms.camera->worldtoraster, P);
|
P = transform_perspective(¶ms.camera->worldtoraster, P);
|
||||||
|
}
|
||||||
|
|
||||||
return P;
|
return P;
|
||||||
}
|
}
|
||||||
@ -186,9 +190,11 @@ float QuadDice::scale_factor(Subpatch &sub, int Mu, int Mv)
|
|||||||
/* estimate area as 4x largest of 4 quads */
|
/* estimate area as 4x largest of 4 quads */
|
||||||
float3 P[3][3];
|
float3 P[3][3];
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++) {
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++) {
|
||||||
P[i][j] = eval_projected(sub, i * 0.5f, j * 0.5f);
|
P[i][j] = eval_projected(sub, i * 0.5f, j * 0.5f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float A1 = quad_area(P[0][0], P[1][0], P[0][1], P[1][1]);
|
float A1 = quad_area(P[0][0], P[1][0], P[0][1], P[1][1]);
|
||||||
float A2 = quad_area(P[1][0], P[2][0], P[1][1], P[2][1]);
|
float A2 = quad_area(P[1][0], P[2][0], P[1][1], P[2][1]);
|
||||||
|
@ -25,8 +25,9 @@ static void decasteljau_cubic(float3 *P, float3 *dt, float t, const float3 cp[4]
|
|||||||
d1 += t * (d2 - d1);
|
d1 += t * (d2 - d1);
|
||||||
|
|
||||||
*P = d0 + t * (d1 - d0);
|
*P = d0 + t * (d1 - d0);
|
||||||
if (dt)
|
if (dt) {
|
||||||
*dt = d1 - d0;
|
*dt = d1 - d0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decasteljau_bicubic(
|
static void decasteljau_bicubic(
|
||||||
@ -42,8 +43,9 @@ static void decasteljau_bicubic(
|
|||||||
|
|
||||||
/* interpolate over v */
|
/* interpolate over v */
|
||||||
decasteljau_cubic(P, dv, v, ucp);
|
decasteljau_cubic(P, dv, v, ucp);
|
||||||
if (du)
|
if (du) {
|
||||||
decasteljau_cubic(du, NULL, v, utn);
|
decasteljau_cubic(du, NULL, v, utn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Linear Quad Patch */
|
/* Linear Quad Patch */
|
||||||
@ -70,8 +72,9 @@ BoundBox LinearQuadPatch::bound()
|
|||||||
{
|
{
|
||||||
BoundBox bbox = BoundBox::empty;
|
BoundBox bbox = BoundBox::empty;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++) {
|
||||||
bbox.grow(hull[i]);
|
bbox.grow(hull[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return bbox;
|
return bbox;
|
||||||
}
|
}
|
||||||
@ -100,8 +103,9 @@ BoundBox BicubicPatch::bound()
|
|||||||
{
|
{
|
||||||
BoundBox bbox = BoundBox::empty;
|
BoundBox bbox = BoundBox::empty;
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++) {
|
||||||
bbox.grow(hull[i]);
|
bbox.grow(hull[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return bbox;
|
return bbox;
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,9 @@ float3 DiagSplit::to_world(Patch *patch, float2 uv)
|
|||||||
float3 P;
|
float3 P;
|
||||||
|
|
||||||
patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
|
patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
|
||||||
if (params.camera)
|
if (params.camera) {
|
||||||
P = transform_point(¶ms.objecttoworld, P);
|
P = transform_point(¶ms.objecttoworld, P);
|
||||||
|
}
|
||||||
|
|
||||||
return P;
|
return P;
|
||||||
}
|
}
|
||||||
|
@ -56,29 +56,35 @@ DebugFlags::Metal::Metal()
|
|||||||
|
|
||||||
void DebugFlags::CUDA::reset()
|
void DebugFlags::CUDA::reset()
|
||||||
{
|
{
|
||||||
if (getenv("CYCLES_CUDA_ADAPTIVE_COMPILE") != NULL)
|
if (getenv("CYCLES_CUDA_ADAPTIVE_COMPILE") != NULL) {
|
||||||
adaptive_compile = true;
|
adaptive_compile = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugFlags::HIP::reset()
|
void DebugFlags::HIP::reset()
|
||||||
{
|
{
|
||||||
if (getenv("CYCLES_HIP_ADAPTIVE_COMPILE") != NULL)
|
if (getenv("CYCLES_HIP_ADAPTIVE_COMPILE") != NULL) {
|
||||||
adaptive_compile = true;
|
adaptive_compile = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugFlags::Metal::reset()
|
void DebugFlags::Metal::reset()
|
||||||
{
|
{
|
||||||
if (getenv("CYCLES_METAL_ADAPTIVE_COMPILE") != NULL)
|
if (getenv("CYCLES_METAL_ADAPTIVE_COMPILE") != NULL) {
|
||||||
adaptive_compile = true;
|
adaptive_compile = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto str = getenv("CYCLES_METAL_LOCAL_ATOMIC_SORT"))
|
if (auto str = getenv("CYCLES_METAL_LOCAL_ATOMIC_SORT")) {
|
||||||
use_local_atomic_sort = (atoi(str) != 0);
|
use_local_atomic_sort = (atoi(str) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (auto str = getenv("CYCLES_METAL_NANOVDB"))
|
if (auto str = getenv("CYCLES_METAL_NANOVDB")) {
|
||||||
use_nanovdb = (atoi(str) != 0);
|
use_nanovdb = (atoi(str) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (auto str = getenv("CYCLES_METAL_ASYNC_PSO_CREATION"))
|
if (auto str = getenv("CYCLES_METAL_ASYNC_PSO_CREATION")) {
|
||||||
use_async_pso_creation = (atoi(str) != 0);
|
use_async_pso_creation = (atoi(str) != 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugFlags::OptiX::OptiX()
|
DebugFlags::OptiX::OptiX()
|
||||||
|
@ -120,10 +120,11 @@ void MD5Hash::process(const uint8_t *data /*[64]*/)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
X = xbuf; /* (dynamic only) */
|
X = xbuf; /* (dynamic only) */
|
||||||
for (i = 0; i < 16; ++i, xp += 4)
|
for (i = 0; i < 16; ++i, xp += 4) {
|
||||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||||
|
|
||||||
@ -258,34 +259,39 @@ void MD5Hash::append(const uint8_t *data, int nbytes)
|
|||||||
int offset = (count[0] >> 3) & 63;
|
int offset = (count[0] >> 3) & 63;
|
||||||
uint32_t nbits = (uint32_t)(nbytes << 3);
|
uint32_t nbits = (uint32_t)(nbytes << 3);
|
||||||
|
|
||||||
if (nbytes <= 0)
|
if (nbytes <= 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Update the message length. */
|
/* Update the message length. */
|
||||||
count[1] += nbytes >> 29;
|
count[1] += nbytes >> 29;
|
||||||
count[0] += nbits;
|
count[0] += nbits;
|
||||||
if (count[0] < nbits)
|
if (count[0] < nbits) {
|
||||||
count[1]++;
|
count[1]++;
|
||||||
|
}
|
||||||
|
|
||||||
/* Process an initial partial block. */
|
/* Process an initial partial block. */
|
||||||
if (offset) {
|
if (offset) {
|
||||||
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
|
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
|
||||||
|
|
||||||
memcpy(buf + offset, p, copy);
|
memcpy(buf + offset, p, copy);
|
||||||
if (offset + copy < 64)
|
if (offset + copy < 64) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
p += copy;
|
p += copy;
|
||||||
left -= copy;
|
left -= copy;
|
||||||
process(buf);
|
process(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process full blocks. */
|
/* Process full blocks. */
|
||||||
for (; left >= 64; p += 64, left -= 64)
|
for (; left >= 64; p += 64, left -= 64) {
|
||||||
process(p);
|
process(p);
|
||||||
|
}
|
||||||
|
|
||||||
/* Process a final partial block. */
|
/* Process a final partial block. */
|
||||||
if (left)
|
if (left) {
|
||||||
memcpy(buf, p, left);
|
memcpy(buf, p, left);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MD5Hash::append(const string &str)
|
void MD5Hash::append(const string &str)
|
||||||
@ -331,16 +337,18 @@ void MD5Hash::finish(uint8_t digest[16])
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Save the length before padding. */
|
/* Save the length before padding. */
|
||||||
for (i = 0; i < 8; ++i)
|
for (i = 0; i < 8; ++i) {
|
||||||
data[i] = (uint8_t)(count[i >> 2] >> ((i & 3) << 3));
|
data[i] = (uint8_t)(count[i >> 2] >> ((i & 3) << 3));
|
||||||
|
}
|
||||||
|
|
||||||
/* Pad to 56 bytes mod 64. */
|
/* Pad to 56 bytes mod 64. */
|
||||||
append(pad, ((55 - (count[0] >> 3)) & 63) + 1);
|
append(pad, ((55 - (count[0] >> 3)) & 63) + 1);
|
||||||
/* Append the length. */
|
/* Append the length. */
|
||||||
append(data, 8);
|
append(data, 8);
|
||||||
|
|
||||||
for (i = 0; i < 16; ++i)
|
for (i = 0; i < 16; ++i) {
|
||||||
digest[i] = (uint8_t)(abcd[i >> 2] >> ((i & 3) << 3));
|
digest[i] = (uint8_t)(abcd[i >> 2] >> ((i & 3) << 3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string MD5Hash::get_hex()
|
string MD5Hash::get_hex()
|
||||||
|
@ -337,19 +337,22 @@ void path_init(const string &path, const string &user_path)
|
|||||||
string path_get(const string &sub)
|
string path_get(const string &sub)
|
||||||
{
|
{
|
||||||
char *special = path_specials(sub);
|
char *special = path_specials(sub);
|
||||||
if (special != NULL)
|
if (special != NULL) {
|
||||||
return special;
|
return special;
|
||||||
|
}
|
||||||
|
|
||||||
if (cached_path == "")
|
if (cached_path == "") {
|
||||||
cached_path = path_dirname(Sysutil::this_program_path());
|
cached_path = path_dirname(Sysutil::this_program_path());
|
||||||
|
}
|
||||||
|
|
||||||
return path_join(cached_path, sub);
|
return path_join(cached_path, sub);
|
||||||
}
|
}
|
||||||
|
|
||||||
string path_user_get(const string &sub)
|
string path_user_get(const string &sub)
|
||||||
{
|
{
|
||||||
if (cached_user_path == "")
|
if (cached_user_path == "") {
|
||||||
cached_user_path = path_dirname(Sysutil::this_program_path());
|
cached_user_path = path_dirname(Sysutil::this_program_path());
|
||||||
|
}
|
||||||
|
|
||||||
return path_join(cached_user_path, sub);
|
return path_join(cached_user_path, sub);
|
||||||
}
|
}
|
||||||
@ -653,11 +656,13 @@ bool path_write_binary(const string &path, const vector<uint8_t> &binary)
|
|||||||
/* write binary file from memory */
|
/* write binary file from memory */
|
||||||
FILE *f = path_fopen(path, "wb");
|
FILE *f = path_fopen(path, "wb");
|
||||||
|
|
||||||
if (!f)
|
if (!f) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (binary.size() > 0)
|
if (binary.size() > 0) {
|
||||||
fwrite(&binary[0], sizeof(uint8_t), binary.size(), f);
|
fwrite(&binary[0], sizeof(uint8_t), binary.size(), f);
|
||||||
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
@ -703,8 +708,9 @@ bool path_read_text(const string &path, string &text)
|
|||||||
{
|
{
|
||||||
vector<uint8_t> binary;
|
vector<uint8_t> binary;
|
||||||
|
|
||||||
if (!path_exists(path) || !path_read_binary(path, binary))
|
if (!path_exists(path) || !path_read_binary(path, binary)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const char *str = (const char *)&binary[0];
|
const char *str = (const char *)&binary[0];
|
||||||
size_t size = binary.size();
|
size_t size = binary.size();
|
||||||
|
@ -55,9 +55,11 @@ string string_printf(const char *format, ...)
|
|||||||
bool string_iequals(const string &a, const string &b)
|
bool string_iequals(const string &a, const string &b)
|
||||||
{
|
{
|
||||||
if (a.size() == b.size()) {
|
if (a.size() == b.size()) {
|
||||||
for (size_t i = 0; i < a.size(); i++)
|
for (size_t i = 0; i < a.size(); i++) {
|
||||||
if (toupper(a[i]) != toupper(b[i]))
|
if (toupper(a[i]) != toupper(b[i])) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -167,10 +169,12 @@ string string_remove_trademark(const string &s)
|
|||||||
|
|
||||||
string string_from_bool(bool var)
|
string string_from_bool(bool var)
|
||||||
{
|
{
|
||||||
if (var)
|
if (var) {
|
||||||
return "True";
|
return "True";
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return "False";
|
return "False";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string to_string(const char *str)
|
string to_string(const char *str)
|
||||||
@ -240,10 +244,12 @@ string string_human_readable_size(size_t size)
|
|||||||
suffix++;
|
suffix++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*suffix != 'B')
|
if (*suffix != 'B') {
|
||||||
return string_printf("%.2f%c", double(size * 1024 + r) / 1024.0, *suffix);
|
return string_printf("%.2f%c", double(size * 1024 + r) / 1024.0, *suffix);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return string_printf("%zu", size);
|
return string_printf("%zu", size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string string_human_readable_number(size_t num)
|
string string_human_readable_number(size_t num)
|
||||||
@ -260,8 +266,9 @@ string string_human_readable_number(size_t num)
|
|||||||
|
|
||||||
int i = -1;
|
int i = -1;
|
||||||
while (num) {
|
while (num) {
|
||||||
if (++i && i % 3 == 0)
|
if (++i && i % 3 == 0) {
|
||||||
*(--p) = ',';
|
*(--p) = ',';
|
||||||
|
}
|
||||||
|
|
||||||
*(--p) = '0' + (num % 10);
|
*(--p) = '0' + (num % 10);
|
||||||
|
|
||||||
|
@ -129,10 +129,12 @@ void DedicatedTaskPool::push(TaskRunFunction &&task, bool front)
|
|||||||
|
|
||||||
/* add task to queue */
|
/* add task to queue */
|
||||||
queue_mutex.lock();
|
queue_mutex.lock();
|
||||||
if (front)
|
if (front) {
|
||||||
queue.emplace_front(std::move(task));
|
queue.emplace_front(std::move(task));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
queue.emplace_back(std::move(task));
|
queue.emplace_back(std::move(task));
|
||||||
|
}
|
||||||
|
|
||||||
queue_cond.notify_one();
|
queue_cond.notify_one();
|
||||||
queue_mutex.unlock();
|
queue_mutex.unlock();
|
||||||
@ -142,8 +144,9 @@ void DedicatedTaskPool::wait()
|
|||||||
{
|
{
|
||||||
thread_scoped_lock num_lock(num_mutex);
|
thread_scoped_lock num_lock(num_mutex);
|
||||||
|
|
||||||
while (num)
|
while (num) {
|
||||||
num_cond.wait(num_lock);
|
num_cond.wait(num_lock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DedicatedTaskPool::cancel()
|
void DedicatedTaskPool::cancel()
|
||||||
@ -167,8 +170,9 @@ void DedicatedTaskPool::num_decrease(int done)
|
|||||||
num -= done;
|
num -= done;
|
||||||
|
|
||||||
assert(num >= 0);
|
assert(num >= 0);
|
||||||
if (num == 0)
|
if (num == 0) {
|
||||||
num_cond.notify_all();
|
num_cond.notify_all();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DedicatedTaskPool::num_increase()
|
void DedicatedTaskPool::num_increase()
|
||||||
@ -182,8 +186,9 @@ bool DedicatedTaskPool::thread_wait_pop(TaskRunFunction &task)
|
|||||||
{
|
{
|
||||||
thread_scoped_lock queue_lock(queue_mutex);
|
thread_scoped_lock queue_lock(queue_mutex);
|
||||||
|
|
||||||
while (queue.empty() && !do_exit)
|
while (queue.empty() && !do_exit) {
|
||||||
queue_cond.wait(queue_lock);
|
queue_cond.wait(queue_lock);
|
||||||
|
}
|
||||||
|
|
||||||
if (queue.empty()) {
|
if (queue.empty()) {
|
||||||
assert(do_exit);
|
assert(do_exit);
|
||||||
|
@ -56,8 +56,9 @@ void time_sleep(double t)
|
|||||||
|
|
||||||
/* get microseconds */
|
/* get microseconds */
|
||||||
int us = (int)(t * 1e6);
|
int us = (int)(t * 1e6);
|
||||||
if (us > 0)
|
if (us > 0) {
|
||||||
usleep(us);
|
usleep(us);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -24,14 +24,16 @@ static bool projection_matrix4_inverse(float R[][4], float M[][4])
|
|||||||
int pivot = i;
|
int pivot = i;
|
||||||
float pivotsize = M[i][i];
|
float pivotsize = M[i][i];
|
||||||
|
|
||||||
if (pivotsize < 0)
|
if (pivotsize < 0) {
|
||||||
pivotsize = -pivotsize;
|
pivotsize = -pivotsize;
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = i + 1; j < 4; j++) {
|
for (int j = i + 1; j < 4; j++) {
|
||||||
float tmp = M[j][i];
|
float tmp = M[j][i];
|
||||||
|
|
||||||
if (tmp < 0)
|
if (tmp < 0) {
|
||||||
tmp = -tmp;
|
tmp = -tmp;
|
||||||
|
}
|
||||||
|
|
||||||
if (tmp > pivotsize) {
|
if (tmp > pivotsize) {
|
||||||
pivot = j;
|
pivot = j;
|
||||||
@ -39,8 +41,9 @@ static bool projection_matrix4_inverse(float R[][4], float M[][4])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNLIKELY(pivotsize == 0.0f))
|
if (UNLIKELY(pivotsize == 0.0f)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (pivot != i) {
|
if (pivot != i) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
@ -70,8 +73,9 @@ static bool projection_matrix4_inverse(float R[][4], float M[][4])
|
|||||||
for (int i = 3; i >= 0; --i) {
|
for (int i = 3; i >= 0; --i) {
|
||||||
float f;
|
float f;
|
||||||
|
|
||||||
if (UNLIKELY((f = M[i][i]) == 0.0f))
|
if (UNLIKELY((f = M[i][i]) == 0.0f)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
M[i][j] /= f;
|
M[i][j] /= f;
|
||||||
@ -134,10 +138,12 @@ float4 transform_to_quat(const Transform &tfm)
|
|||||||
else {
|
else {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (tfm[1][1] > tfm[i][i])
|
if (tfm[1][1] > tfm[i][i]) {
|
||||||
i = 1;
|
i = 1;
|
||||||
if (tfm[2][2] > tfm[i][i])
|
}
|
||||||
|
if (tfm[2][2] > tfm[i][i]) {
|
||||||
i = 2;
|
i = 2;
|
||||||
|
}
|
||||||
|
|
||||||
int j = (i + 1) % 3;
|
int j = (i + 1) % 3;
|
||||||
int k = (j + 1) % 3;
|
int k = (j + 1) % 3;
|
||||||
@ -146,8 +152,9 @@ float4 transform_to_quat(const Transform &tfm)
|
|||||||
|
|
||||||
double q[3];
|
double q[3];
|
||||||
q[i] = s * 0.5;
|
q[i] = s * 0.5;
|
||||||
if (s != 0.0)
|
if (s != 0.0) {
|
||||||
s = 0.5 / s;
|
s = 0.5 / s;
|
||||||
|
}
|
||||||
|
|
||||||
double w = (double)(tfm[k][j] - tfm[j][k]) * s;
|
double w = (double)(tfm[k][j] - tfm[j][k]) * s;
|
||||||
q[j] = (double)(tfm[j][i] + tfm[i][j]) * s;
|
q[j] = (double)(tfm[j][i] + tfm[i][j]) * s;
|
||||||
@ -253,10 +260,11 @@ void transform_motion_decompose(DecomposedTransform *decomp, const Transform *mo
|
|||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
/* Ensure rotation around shortest angle, negated quaternions are the same
|
/* Ensure rotation around shortest angle, negated quaternions are the same
|
||||||
* but this means we don't have to do the check in quat_interpolate */
|
* but this means we don't have to do the check in quat_interpolate */
|
||||||
if (dot(decomp[i - 1].x, decomp[i].x) < 0.0f)
|
if (dot(decomp[i - 1].x, decomp[i].x) < 0.0f) {
|
||||||
decomp[i].x = -decomp[i].x;
|
decomp[i].x = -decomp[i].x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy rotation to decomposed transform where scale is degenerate. This avoids weird object
|
/* Copy rotation to decomposed transform where scale is degenerate. This avoids weird object
|
||||||
* rotation interpolation when the scale goes to 0 for a time step.
|
* rotation interpolation when the scale goes to 0 for a time step.
|
||||||
|
@ -113,9 +113,10 @@ static void create_projection_axes(int64_t axes[NUM_AXES][3], const int64_t tri[
|
|||||||
/* Get triangle edge vectors */
|
/* Get triangle edge vectors */
|
||||||
int64_t tri_edges[3][3];
|
int64_t tri_edges[3][3];
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++) {
|
||||||
tri_edges[i][j] = tri[(i + 1) % 3][j] - tri[i][j];
|
tri_edges[i][j] = tri[(i + 1) % 3][j] - tri[i][j];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Triangle normal */
|
/* Triangle normal */
|
||||||
crossProduct(axes[3], tri_edges[0], tri_edges[1]);
|
crossProduct(axes[3], tri_edges[0], tri_edges[1]);
|
||||||
@ -171,8 +172,9 @@ CubeTriangleIsect::CubeTriangleIsect(int64_t cube[2][3],
|
|||||||
cube_proj.origin = dotProduct(axes[axis], cube[0]);
|
cube_proj.origin = dotProduct(axes[axis], cube[0]);
|
||||||
|
|
||||||
/* 3 direction vectors */
|
/* 3 direction vectors */
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
cube_proj.edges[i] = dotProduct(axes[axis], cubeedge[i]);
|
cube_proj.edges[i] = dotProduct(axes[axis], cubeedge[i]);
|
||||||
|
}
|
||||||
|
|
||||||
/* Offsets of 2 ends of cube projection */
|
/* Offsets of 2 ends of cube projection */
|
||||||
int64_t max = 0;
|
int64_t max = 0;
|
||||||
@ -201,13 +203,15 @@ CubeTriangleIsect::CubeTriangleIsect(int64_t cube[2][3],
|
|||||||
inherit->tri_proj[axis][0] = vts[0];
|
inherit->tri_proj[axis][0] = vts[0];
|
||||||
inherit->tri_proj[axis][1] = vts[0];
|
inherit->tri_proj[axis][1] = vts[0];
|
||||||
for (i = 1; i < 3; i++) {
|
for (i = 1; i < 3; i++) {
|
||||||
if (vts[i] < inherit->tri_proj[axis][0])
|
if (vts[i] < inherit->tri_proj[axis][0]) {
|
||||||
inherit->tri_proj[axis][0] = vts[i];
|
inherit->tri_proj[axis][0] = vts[i];
|
||||||
|
}
|
||||||
|
|
||||||
if (vts[i] > inherit->tri_proj[axis][1])
|
if (vts[i] > inherit->tri_proj[axis][1]) {
|
||||||
inherit->tri_proj[axis][1] = vts[i];
|
inherit->tri_proj[axis][1] = vts[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,8 +227,9 @@ CubeTriangleIsect::CubeTriangleIsect(CubeTriangleIsect *parent)
|
|||||||
for (int i = 0; i < NUM_AXES; i++) {
|
for (int i = 0; i < NUM_AXES; i++) {
|
||||||
cubeProj[i].origin = parent->cubeProj[i].origin;
|
cubeProj[i].origin = parent->cubeProj[i].origin;
|
||||||
|
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++) {
|
||||||
cubeProj[i].edges[j] = parent->cubeProj[i].edges[j] >> 1;
|
cubeProj[i].edges[j] = parent->cubeProj[i].edges[j] >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
cubeProj[i].min = parent->cubeProj[i].min >> 1;
|
cubeProj[i].min = parent->cubeProj[i].min >> 1;
|
||||||
cubeProj[i].max = parent->cubeProj[i].max >> 1;
|
cubeProj[i].max = parent->cubeProj[i].max >> 1;
|
||||||
@ -337,14 +342,16 @@ float CubeTriangleIsect::getIntersectionPrimary(int edgeInd) const
|
|||||||
int64_t d = proj1 - proj0;
|
int64_t d = proj1 - proj0;
|
||||||
double alpha;
|
double alpha;
|
||||||
|
|
||||||
if (d == 0)
|
if (d == 0) {
|
||||||
alpha = 0.5;
|
alpha = 0.5;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
alpha = (double)((proj2 - proj0)) / (double)d;
|
alpha = (double)((proj2 - proj0)) / (double)d;
|
||||||
|
|
||||||
if (alpha < 0 || alpha > 1)
|
if (alpha < 0 || alpha > 1) {
|
||||||
alpha = 0.5;
|
alpha = 0.5;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (float)alpha;
|
return (float)alpha;
|
||||||
}
|
}
|
||||||
|
@ -54,9 +54,10 @@ class DualConInputReader : public ModelReader {
|
|||||||
/* initialize maxsize */
|
/* initialize maxsize */
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
float d = max[i] - min[i];
|
float d = max[i] - min[i];
|
||||||
if (d > maxsize)
|
if (d > maxsize) {
|
||||||
maxsize = d;
|
maxsize = d;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* redo the bounds */
|
/* redo the bounds */
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
@ -64,15 +65,17 @@ class DualConInputReader : public ModelReader {
|
|||||||
max[i] = (max[i] + min[i]) / 2 + maxsize / 2;
|
max[i] = (max[i] + min[i]) / 2 + maxsize / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++) {
|
||||||
min[i] -= maxsize * (1 / scale - 1) / 2;
|
min[i] -= maxsize * (1 / scale - 1) / 2;
|
||||||
|
}
|
||||||
maxsize *= 1 / scale;
|
maxsize *= 1 / scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
Triangle *getNextTriangle()
|
Triangle *getNextTriangle()
|
||||||
{
|
{
|
||||||
if (curtri == input_mesh->tottri)
|
if (curtri == input_mesh->tottri) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Triangle *t = new Triangle();
|
Triangle *t = new Triangle();
|
||||||
|
|
||||||
@ -97,8 +100,9 @@ class DualConInputReader : public ModelReader {
|
|||||||
|
|
||||||
int getNextTriangle(int t[3])
|
int getNextTriangle(int t[3])
|
||||||
{
|
{
|
||||||
if (curtri == input_mesh->tottri)
|
if (curtri == input_mesh->tottri) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int *tr = GET_TRI(input_mesh, curtri);
|
unsigned int *tr = GET_TRI(input_mesh, curtri);
|
||||||
t[0] = tr[0];
|
t[0] = tr[0];
|
||||||
|
@ -325,17 +325,19 @@ void Octree::addTriangle(Triangle *trian, int triind)
|
|||||||
|
|
||||||
/* Project the triangle's coordinates into the grid */
|
/* Project the triangle's coordinates into the grid */
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
for (j = 0; j < 3; j++)
|
for (j = 0; j < 3; j++) {
|
||||||
trian->vt[i][j] = dimen * (trian->vt[i][j] - origin[j]) / range;
|
trian->vt[i][j] = dimen * (trian->vt[i][j] - origin[j]) / range;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Generate projections */
|
/* Generate projections */
|
||||||
int64_t cube[2][3] = {{0, 0, 0}, {dimen, dimen, dimen}};
|
int64_t cube[2][3] = {{0, 0, 0}, {dimen, dimen, dimen}};
|
||||||
int64_t trig[3][3];
|
int64_t trig[3][3];
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
for (j = 0; j < 3; j++)
|
for (j = 0; j < 3; j++) {
|
||||||
trig[i][j] = (int64_t)(trian->vt[i][j]);
|
trig[i][j] = (int64_t)(trian->vt[i][j]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Add triangle to the octree */
|
/* Add triangle to the octree */
|
||||||
int64_t errorvec = (int64_t)(0);
|
int64_t errorvec = (int64_t)(0);
|
||||||
@ -379,23 +381,28 @@ InternalNode *Octree::addTriangle(InternalNode *node, CubeTriangleIsect *p, int
|
|||||||
/* Pruning using intersection test */
|
/* Pruning using intersection test */
|
||||||
if (subp->isIntersecting()) {
|
if (subp->isIntersecting()) {
|
||||||
if (!node->has_child(i)) {
|
if (!node->has_child(i)) {
|
||||||
if (height == 1)
|
if (height == 1) {
|
||||||
node = addLeafChild(node, i, count, createLeaf(0));
|
node = addLeafChild(node, i, count, createLeaf(0));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
node = addInternalChild(node, i, count, createInternal(0));
|
node = addInternalChild(node, i, count, createInternal(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Node *chd = node->get_child(count);
|
Node *chd = node->get_child(count);
|
||||||
|
|
||||||
if (node->is_child_leaf(i))
|
if (node->is_child_leaf(i)) {
|
||||||
node->set_child(count, (Node *)updateCell(&chd->leaf, subp));
|
node->set_child(count, (Node *)updateCell(&chd->leaf, subp));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
node->set_child(count, (Node *)addTriangle(&chd->internal, subp, height - 1));
|
node->set_child(count, (Node *)addTriangle(&chd->internal, subp, height - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (node->has_child(i))
|
if (node->has_child(i)) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete subp;
|
delete subp;
|
||||||
|
|
||||||
@ -445,10 +452,12 @@ void Octree::preparePrimalEdgesMask(InternalNode *node)
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
if (node->has_child(i)) {
|
if (node->has_child(i)) {
|
||||||
if (node->is_child_leaf(i))
|
if (node->is_child_leaf(i)) {
|
||||||
createPrimalEdgesMask(&node->get_child(count)->leaf);
|
createPrimalEdgesMask(&node->get_child(count)->leaf);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
preparePrimalEdgesMask(&node->get_child(count)->internal);
|
preparePrimalEdgesMask(&node->get_child(count)->internal);
|
||||||
|
}
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@ -2016,8 +2025,9 @@ int Octree::floodFill(LeafNode *leaf, int st[3], int len, int /*height*/, int th
|
|||||||
|
|
||||||
// cells
|
// cells
|
||||||
LeafNode *cs[2];
|
LeafNode *cs[2];
|
||||||
for (j = 0; j < 2; j++)
|
for (j = 0; j < 2; j++) {
|
||||||
cs[j] = locateLeaf(cst[j]);
|
cs[j] = locateLeaf(cst[j]);
|
||||||
|
}
|
||||||
|
|
||||||
// Middle sign
|
// Middle sign
|
||||||
int s = getSign(cs[0], 0);
|
int s = getSign(cs[0], 0);
|
||||||
@ -2195,8 +2205,9 @@ static void solve_least_squares(const float halfA[],
|
|||||||
b2 = b2 + A * -mp;
|
b2 = b2 + A * -mp;
|
||||||
result = pinv * b2 + mp;
|
result = pinv * b2 + mp;
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++) {
|
||||||
rvalue[i] = result(i);
|
rvalue[i] = result(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mass_point(float mp[3], const float pts[12][3], const int parity[12])
|
static void mass_point(float mp[3], const float pts[12][3], const int parity[12])
|
||||||
|
@ -149,10 +149,11 @@ static void linear_solver_variables_to_vector(LinearSolver *solver)
|
|||||||
for (int i = 0; i < solver->num_variables; i++) {
|
for (int i = 0; i < solver->num_variables; i++) {
|
||||||
LinearSolver::Variable *v = &solver->variable[i];
|
LinearSolver::Variable *v = &solver->variable[i];
|
||||||
if (!v->locked) {
|
if (!v->locked) {
|
||||||
for (int j = 0; j < num_rhs; j++)
|
for (int j = 0; j < num_rhs; j++) {
|
||||||
solver->x[j][v->index] = v->value[j];
|
solver->x[j][v->index] = v->value[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void linear_solver_vector_to_variables(LinearSolver *solver)
|
static void linear_solver_vector_to_variables(LinearSolver *solver)
|
||||||
@ -162,10 +163,11 @@ static void linear_solver_vector_to_variables(LinearSolver *solver)
|
|||||||
for (int i = 0; i < solver->num_variables; i++) {
|
for (int i = 0; i < solver->num_variables; i++) {
|
||||||
LinearSolver::Variable *v = &solver->variable[i];
|
LinearSolver::Variable *v = &solver->variable[i];
|
||||||
if (!v->locked) {
|
if (!v->locked) {
|
||||||
for (int j = 0; j < num_rhs; j++)
|
for (int j = 0; j < num_rhs; j++) {
|
||||||
v->value[j] = solver->x[j][v->index];
|
v->value[j] = solver->x[j][v->index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Matrix */
|
/* Matrix */
|
||||||
@ -177,11 +179,13 @@ static void linear_solver_ensure_matrix_construct(LinearSolver *solver)
|
|||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
for (int i = 0; i < solver->num_variables; i++) {
|
for (int i = 0; i < solver->num_variables; i++) {
|
||||||
if (solver->variable[i].locked)
|
if (solver->variable[i].locked) {
|
||||||
solver->variable[i].index = ~0;
|
solver->variable[i].index = ~0;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
solver->variable[i].index = n++;
|
solver->variable[i].index = n++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int m = (solver->num_rows == 0) ? n : solver->num_rows;
|
int m = (solver->num_rows == 0) ? n : solver->num_rows;
|
||||||
|
|
||||||
@ -210,16 +214,19 @@ static void linear_solver_ensure_matrix_construct(LinearSolver *solver)
|
|||||||
|
|
||||||
void EIG_linear_solver_matrix_add(LinearSolver *solver, int row, int col, double value)
|
void EIG_linear_solver_matrix_add(LinearSolver *solver, int row, int col, double value)
|
||||||
{
|
{
|
||||||
if (solver->state == LinearSolver::STATE_MATRIX_SOLVED)
|
if (solver->state == LinearSolver::STATE_MATRIX_SOLVED) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
linear_solver_ensure_matrix_construct(solver);
|
linear_solver_ensure_matrix_construct(solver);
|
||||||
|
|
||||||
if (!solver->least_squares && solver->variable[row].locked)
|
if (!solver->least_squares && solver->variable[row].locked) {
|
||||||
;
|
;
|
||||||
|
}
|
||||||
else if (solver->variable[col].locked) {
|
else if (solver->variable[col].locked) {
|
||||||
if (!solver->least_squares)
|
if (!solver->least_squares) {
|
||||||
row = solver->variable[row].index;
|
row = solver->variable[row].index;
|
||||||
|
}
|
||||||
|
|
||||||
LinearSolver::Coeff coeff;
|
LinearSolver::Coeff coeff;
|
||||||
coeff.index = row;
|
coeff.index = row;
|
||||||
@ -227,8 +234,9 @@ void EIG_linear_solver_matrix_add(LinearSolver *solver, int row, int col, double
|
|||||||
solver->variable[col].a.push_back(coeff);
|
solver->variable[col].a.push_back(coeff);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!solver->least_squares)
|
if (!solver->least_squares) {
|
||||||
row = solver->variable[row].index;
|
row = solver->variable[row].index;
|
||||||
|
}
|
||||||
col = solver->variable[col].index;
|
col = solver->variable[col].index;
|
||||||
|
|
||||||
/* direct insert into matrix is too slow, so use triplets */
|
/* direct insert into matrix is too slow, so use triplets */
|
||||||
@ -257,8 +265,9 @@ void EIG_linear_solver_right_hand_side_add(LinearSolver *solver, int rhs, int in
|
|||||||
bool EIG_linear_solver_solve(LinearSolver *solver)
|
bool EIG_linear_solver_solve(LinearSolver *solver)
|
||||||
{
|
{
|
||||||
/* nothing to solve, perhaps all variables were locked */
|
/* nothing to solve, perhaps all variables were locked */
|
||||||
if (solver->m == 0 || solver->n == 0)
|
if (solver->m == 0 || solver->n == 0) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
|
||||||
@ -271,8 +280,9 @@ bool EIG_linear_solver_solve(LinearSolver *solver)
|
|||||||
solver->Mtriplets.clear();
|
solver->Mtriplets.clear();
|
||||||
|
|
||||||
/* create least squares matrix */
|
/* create least squares matrix */
|
||||||
if (solver->least_squares)
|
if (solver->least_squares) {
|
||||||
solver->MtM = solver->M.transpose() * solver->M;
|
solver->MtM = solver->M.transpose() * solver->M;
|
||||||
|
}
|
||||||
|
|
||||||
/* convert M to compressed column format */
|
/* convert M to compressed column format */
|
||||||
EigenSparseMatrix &M = (solver->least_squares) ? solver->MtM : solver->M;
|
EigenSparseMatrix &M = (solver->least_squares) ? solver->MtM : solver->M;
|
||||||
@ -300,10 +310,11 @@ bool EIG_linear_solver_solve(LinearSolver *solver)
|
|||||||
if (variable->locked) {
|
if (variable->locked) {
|
||||||
std::vector<LinearSolver::Coeff> &a = variable->a;
|
std::vector<LinearSolver::Coeff> &a = variable->a;
|
||||||
|
|
||||||
for (int j = 0; j < a.size(); j++)
|
for (int j = 0; j < a.size(); j++) {
|
||||||
b[a[j].index] -= a[j].value * variable->value[rhs];
|
b[a[j].index] -= a[j].value * variable->value[rhs];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* solve */
|
/* solve */
|
||||||
if (solver->least_squares) {
|
if (solver->least_squares) {
|
||||||
@ -315,17 +326,20 @@ bool EIG_linear_solver_solve(LinearSolver *solver)
|
|||||||
solver->x[rhs] = solver->sparseLU->solve(b);
|
solver->x[rhs] = solver->sparseLU->solve(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (solver->sparseLU->info() != Eigen::Success)
|
if (solver->sparseLU->info() != Eigen::Success) {
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (result)
|
if (result) {
|
||||||
linear_solver_vector_to_variables(solver);
|
linear_solver_vector_to_variables(solver);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* clear for next solve */
|
/* clear for next solve */
|
||||||
for (int rhs = 0; rhs < solver->num_rhs; rhs++)
|
for (int rhs = 0; rhs < solver->num_rhs; rhs++) {
|
||||||
solver->b[rhs].setZero(solver->m);
|
solver->b[rhs].setZero(solver->m);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -336,9 +350,11 @@ void EIG_linear_solver_print_matrix(LinearSolver *solver)
|
|||||||
{
|
{
|
||||||
std::cout << "A:" << solver->M << std::endl;
|
std::cout << "A:" << solver->M << std::endl;
|
||||||
|
|
||||||
for (int rhs = 0; rhs < solver->num_rhs; rhs++)
|
for (int rhs = 0; rhs < solver->num_rhs; rhs++) {
|
||||||
std::cout << "b " << rhs << ":" << solver->b[rhs] << std::endl;
|
std::cout << "b " << rhs << ":" << solver->b[rhs] << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
if (solver->MtM.rows() && solver->MtM.cols())
|
if (solver->MtM.rows() && solver->MtM.cols()) {
|
||||||
std::cout << "AtA:" << solver->MtM << std::endl;
|
std::cout << "AtA:" << solver->MtM << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,8 +64,9 @@ bool test_codec_video_by_codecid(AVCodecID codec_id, AVPixelFormat pixelformat)
|
|||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
const AVCodec *codec = avcodec_find_encoder(codec_id);
|
const AVCodec *codec = avcodec_find_encoder(codec_id);
|
||||||
if (codec)
|
if (codec) {
|
||||||
result = test_vcodec(codec, pixelformat);
|
result = test_vcodec(codec, pixelformat);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,8 +74,9 @@ bool test_codec_video_by_name(const char *codecname, AVPixelFormat pixelformat)
|
|||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
const AVCodec *codec = avcodec_find_encoder_by_name(codecname);
|
const AVCodec *codec = avcodec_find_encoder_by_name(codecname);
|
||||||
if (codec)
|
if (codec) {
|
||||||
result = test_vcodec(codec, pixelformat);
|
result = test_vcodec(codec, pixelformat);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,8 +84,9 @@ bool test_codec_audio_by_codecid(AVCodecID codec_id, AVSampleFormat fmt)
|
|||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
const AVCodec *codec = avcodec_find_encoder(codec_id);
|
const AVCodec *codec = avcodec_find_encoder(codec_id);
|
||||||
if (codec)
|
if (codec) {
|
||||||
result = test_acodec(codec, fmt);
|
result = test_acodec(codec, fmt);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,8 +94,9 @@ bool test_codec_audio_by_name(const char *codecname, AVSampleFormat fmt)
|
|||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
const AVCodec *codec = avcodec_find_encoder_by_name(codecname);
|
const AVCodec *codec = avcodec_find_encoder_by_name(codecname);
|
||||||
if (codec)
|
if (codec) {
|
||||||
result = test_acodec(codec, fmt);
|
result = test_acodec(codec, fmt);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,10 +101,12 @@ void IK_QJacobian::Invert()
|
|||||||
m_svd_v = svd.matrixV();
|
m_svd_v = svd.matrixV();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_sdls)
|
if (m_sdls) {
|
||||||
InvertSDLS();
|
InvertSDLS();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
InvertDLS();
|
InvertDLS();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IK_QJacobian::ComputeNullProjection()
|
bool IK_QJacobian::ComputeNullProjection()
|
||||||
@ -113,39 +115,49 @@ bool IK_QJacobian::ComputeNullProjection()
|
|||||||
|
|
||||||
// compute null space projection based on V
|
// compute null space projection based on V
|
||||||
int i, j, rank = 0;
|
int i, j, rank = 0;
|
||||||
for (i = 0; i < m_svd_w.size(); i++)
|
for (i = 0; i < m_svd_w.size(); i++) {
|
||||||
if (m_svd_w[i] > epsilon)
|
if (m_svd_w[i] > epsilon) {
|
||||||
rank++;
|
rank++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rank < m_task_size)
|
if (rank < m_task_size) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
MatrixXd basis(m_svd_v.rows(), rank);
|
MatrixXd basis(m_svd_v.rows(), rank);
|
||||||
int b = 0;
|
int b = 0;
|
||||||
|
|
||||||
for (i = 0; i < m_svd_w.size(); i++)
|
for (i = 0; i < m_svd_w.size(); i++) {
|
||||||
if (m_svd_w[i] > epsilon) {
|
if (m_svd_w[i] > epsilon) {
|
||||||
for (j = 0; j < m_svd_v.rows(); j++)
|
for (j = 0; j < m_svd_v.rows(); j++) {
|
||||||
basis(j, b) = m_svd_v(j, i);
|
basis(j, b) = m_svd_v(j, i);
|
||||||
|
}
|
||||||
b++;
|
b++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_nullspace = basis * basis.transpose();
|
m_nullspace = basis * basis.transpose();
|
||||||
|
|
||||||
for (i = 0; i < m_nullspace.rows(); i++)
|
for (i = 0; i < m_nullspace.rows(); i++) {
|
||||||
for (j = 0; j < m_nullspace.cols(); j++)
|
for (j = 0; j < m_nullspace.cols(); j++) {
|
||||||
if (i == j)
|
if (i == j) {
|
||||||
m_nullspace(i, j) = 1.0 - m_nullspace(i, j);
|
m_nullspace(i, j) = 1.0 - m_nullspace(i, j);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
m_nullspace(i, j) = -m_nullspace(i, j);
|
m_nullspace(i, j) = -m_nullspace(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_QJacobian::SubTask(IK_QJacobian &jacobian)
|
void IK_QJacobian::SubTask(IK_QJacobian &jacobian)
|
||||||
{
|
{
|
||||||
if (!ComputeNullProjection())
|
if (!ComputeNullProjection()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// restrict lower priority jacobian
|
// restrict lower priority jacobian
|
||||||
jacobian.Restrict(m_d_theta, m_nullspace);
|
jacobian.Restrict(m_d_theta, m_nullspace);
|
||||||
@ -157,8 +169,9 @@ void IK_QJacobian::SubTask(IK_QJacobian &jacobian)
|
|||||||
// SDLS, to avoid shaking when the primary task is near singularities,
|
// SDLS, to avoid shaking when the primary task is near singularities,
|
||||||
// doesn't work well at all
|
// doesn't work well at all
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < m_d_theta.size(); i++)
|
for (i = 0; i < m_d_theta.size(); i++) {
|
||||||
m_d_theta[i] = m_d_theta[i] + /*m_min_damp * */ jacobian.AngleUpdate(i);
|
m_d_theta[i] = m_d_theta[i] + /*m_min_damp * */ jacobian.AngleUpdate(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_QJacobian::Restrict(VectorXd &d_theta, MatrixXd &nullspace)
|
void IK_QJacobian::Restrict(VectorXd &d_theta, MatrixXd &nullspace)
|
||||||
@ -209,8 +222,9 @@ void IK_QJacobian::InvertSDLS()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < m_svd_w.size(); i++) {
|
for (i = 0; i < m_svd_w.size(); i++) {
|
||||||
if (m_svd_w[i] <= epsilon)
|
if (m_svd_w[i] <= epsilon) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
double wInv = 1.0 / m_svd_w[i];
|
double wInv = 1.0 / m_svd_w[i];
|
||||||
double alpha = 0.0;
|
double alpha = 0.0;
|
||||||
@ -246,16 +260,18 @@ void IK_QJacobian::InvertSDLS()
|
|||||||
// find largest absolute dTheta
|
// find largest absolute dTheta
|
||||||
// multiply with weight to prevent unnecessary damping
|
// multiply with weight to prevent unnecessary damping
|
||||||
abs_dtheta = fabs(m_d_theta_tmp[j]) * m_weight_sqrt[j];
|
abs_dtheta = fabs(m_d_theta_tmp[j]) * m_weight_sqrt[j];
|
||||||
if (abs_dtheta > max_dtheta)
|
if (abs_dtheta > max_dtheta) {
|
||||||
max_dtheta = abs_dtheta;
|
max_dtheta = abs_dtheta;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
M *= wInv;
|
M *= wInv;
|
||||||
|
|
||||||
// compute damping term and damp the dTheta's
|
// compute damping term and damp the dTheta's
|
||||||
double gamma = max_angle_change;
|
double gamma = max_angle_change;
|
||||||
if (N < M)
|
if (N < M) {
|
||||||
gamma *= N / M;
|
gamma *= N / M;
|
||||||
|
}
|
||||||
|
|
||||||
double damp = (gamma < max_dtheta) ? gamma / max_dtheta : 1.0;
|
double damp = (gamma < max_dtheta) ? gamma / max_dtheta : 1.0;
|
||||||
|
|
||||||
@ -265,15 +281,17 @@ void IK_QJacobian::InvertSDLS()
|
|||||||
// better to go a little to slow than to far
|
// better to go a little to slow than to far
|
||||||
|
|
||||||
double dofdamp = damp / m_weight[j];
|
double dofdamp = damp / m_weight[j];
|
||||||
if (dofdamp > 1.0)
|
if (dofdamp > 1.0) {
|
||||||
dofdamp = 1.0;
|
dofdamp = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
m_d_theta[j] += 0.80 * dofdamp * m_d_theta_tmp[j];
|
m_d_theta[j] += 0.80 * dofdamp * m_d_theta_tmp[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (damp < m_min_damp)
|
if (damp < m_min_damp) {
|
||||||
m_min_damp = damp;
|
m_min_damp = damp;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// weight + prevent from doing angle updates with angles > max_angle_change
|
// weight + prevent from doing angle updates with angles > max_angle_change
|
||||||
double max_angle = 0.0, abs_angle;
|
double max_angle = 0.0, abs_angle;
|
||||||
@ -283,16 +301,18 @@ void IK_QJacobian::InvertSDLS()
|
|||||||
|
|
||||||
abs_angle = fabs(m_d_theta[j]);
|
abs_angle = fabs(m_d_theta[j]);
|
||||||
|
|
||||||
if (abs_angle > max_angle)
|
if (abs_angle > max_angle) {
|
||||||
max_angle = abs_angle;
|
max_angle = abs_angle;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (max_angle > max_angle_change) {
|
if (max_angle > max_angle_change) {
|
||||||
double damp = (max_angle_change) / (max_angle_change + max_angle);
|
double damp = (max_angle_change) / (max_angle_change + max_angle);
|
||||||
|
|
||||||
for (j = 0; j < m_dof; j++)
|
for (j = 0; j < m_dof; j++) {
|
||||||
m_d_theta[j] *= damp;
|
m_d_theta[j] *= damp;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_QJacobian::InvertDLS()
|
void IK_QJacobian::InvertDLS()
|
||||||
@ -322,26 +342,31 @@ void IK_QJacobian::InvertDLS()
|
|||||||
double w_min = std::numeric_limits<double>::max();
|
double w_min = std::numeric_limits<double>::max();
|
||||||
|
|
||||||
for (i = 0; i < m_svd_w.size(); i++) {
|
for (i = 0; i < m_svd_w.size(); i++) {
|
||||||
if (m_svd_w[i] > epsilon && m_svd_w[i] < w_min)
|
if (m_svd_w[i] > epsilon && m_svd_w[i] < w_min) {
|
||||||
w_min = m_svd_w[i];
|
w_min = m_svd_w[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// compute lambda damping term
|
// compute lambda damping term
|
||||||
|
|
||||||
double d = x_length / max_angle_change;
|
double d = x_length / max_angle_change;
|
||||||
double lambda;
|
double lambda;
|
||||||
|
|
||||||
if (w_min <= d / 2)
|
if (w_min <= d / 2) {
|
||||||
lambda = d / 2;
|
lambda = d / 2;
|
||||||
else if (w_min < d)
|
}
|
||||||
|
else if (w_min < d) {
|
||||||
lambda = sqrt(w_min * (d - w_min));
|
lambda = sqrt(w_min * (d - w_min));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
lambda = 0.0;
|
lambda = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
lambda *= lambda;
|
lambda *= lambda;
|
||||||
|
|
||||||
if (lambda > 10)
|
if (lambda > 10) {
|
||||||
lambda = 10;
|
lambda = 10;
|
||||||
|
}
|
||||||
|
|
||||||
// immediately multiply with Beta, so we can do matrix*vector products
|
// immediately multiply with Beta, so we can do matrix*vector products
|
||||||
// rather than matrix*matrix products
|
// rather than matrix*matrix products
|
||||||
@ -358,13 +383,15 @@ void IK_QJacobian::InvertDLS()
|
|||||||
// compute V*Winv*Ut*Beta
|
// compute V*Winv*Ut*Beta
|
||||||
m_svd_u_beta[i] *= wInv;
|
m_svd_u_beta[i] *= wInv;
|
||||||
|
|
||||||
for (j = 0; j < m_d_theta.size(); j++)
|
for (j = 0; j < m_d_theta.size(); j++) {
|
||||||
m_d_theta[j] += m_svd_v(j, i) * m_svd_u_beta[i];
|
m_d_theta[j] += m_svd_v(j, i) * m_svd_u_beta[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (j = 0; j < m_d_theta.size(); j++)
|
for (j = 0; j < m_d_theta.size(); j++) {
|
||||||
m_d_theta[j] *= m_weight[j];
|
m_d_theta[j] *= m_weight[j];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_QJacobian::Lock(int dof_id, double delta)
|
void IK_QJacobian::Lock(int dof_id, double delta)
|
||||||
@ -392,9 +419,10 @@ double IK_QJacobian::AngleUpdateNorm() const
|
|||||||
|
|
||||||
for (i = 0; i < m_d_theta.size(); i++) {
|
for (i = 0; i < m_d_theta.size(); i++) {
|
||||||
dtheta_abs = fabs(m_d_theta[i] * m_d_norm_weight[i]);
|
dtheta_abs = fabs(m_d_theta[i] * m_d_norm_weight[i]);
|
||||||
if (dtheta_abs > mx)
|
if (dtheta_abs > mx) {
|
||||||
mx = dtheta_abs;
|
mx = dtheta_abs;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return mx;
|
return mx;
|
||||||
}
|
}
|
||||||
|
@ -23,13 +23,16 @@ double IK_QJacobianSolver::ComputeScale()
|
|||||||
std::vector<IK_QSegment *>::iterator seg;
|
std::vector<IK_QSegment *>::iterator seg;
|
||||||
double length = 0.0f;
|
double length = 0.0f;
|
||||||
|
|
||||||
for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
|
for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
|
||||||
length += (*seg)->MaxExtension();
|
length += (*seg)->MaxExtension();
|
||||||
|
}
|
||||||
|
|
||||||
if (length == 0.0)
|
if (length == 0.0) {
|
||||||
return 1.0;
|
return 1.0;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return 1.0 / length;
|
return 1.0 / length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_QJacobianSolver::Scale(double scale, std::list<IK_QTask *> &tasks)
|
void IK_QJacobianSolver::Scale(double scale, std::list<IK_QTask *> &tasks)
|
||||||
@ -37,11 +40,13 @@ void IK_QJacobianSolver::Scale(double scale, std::list<IK_QTask *> &tasks)
|
|||||||
std::list<IK_QTask *>::iterator task;
|
std::list<IK_QTask *>::iterator task;
|
||||||
std::vector<IK_QSegment *>::iterator seg;
|
std::vector<IK_QSegment *>::iterator seg;
|
||||||
|
|
||||||
for (task = tasks.begin(); task != tasks.end(); task++)
|
for (task = tasks.begin(); task != tasks.end(); task++) {
|
||||||
(*task)->Scale(scale);
|
(*task)->Scale(scale);
|
||||||
|
}
|
||||||
|
|
||||||
for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
|
for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
|
||||||
(*seg)->Scale(scale);
|
(*seg)->Scale(scale);
|
||||||
|
}
|
||||||
|
|
||||||
m_rootmatrix.translation() *= scale;
|
m_rootmatrix.translation() *= scale;
|
||||||
m_goal *= scale;
|
m_goal *= scale;
|
||||||
@ -53,8 +58,9 @@ void IK_QJacobianSolver::AddSegmentList(IK_QSegment *seg)
|
|||||||
m_segments.push_back(seg);
|
m_segments.push_back(seg);
|
||||||
|
|
||||||
IK_QSegment *child;
|
IK_QSegment *child;
|
||||||
for (child = seg->Child(); child; child = child->Sibling())
|
for (child = seg->Child(); child; child = child->Sibling()) {
|
||||||
AddSegmentList(child);
|
AddSegmentList(child);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask *> &tasks)
|
bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask *> &tasks)
|
||||||
@ -71,8 +77,9 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask *> &tasks)
|
|||||||
num_dof += (*seg)->NumberOfDoF();
|
num_dof += (*seg)->NumberOfDoF();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_dof == 0)
|
if (num_dof == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// compute task ids and assign weights to task
|
// compute task ids and assign weights to task
|
||||||
int primary_size = 0;
|
int primary_size = 0;
|
||||||
@ -96,39 +103,47 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask *> &tasks)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primary_size == 0 || FuzzyZero(primary_weight))
|
if (primary_size == 0 || FuzzyZero(primary_weight)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_secondary_enabled = (secondary > 0);
|
m_secondary_enabled = (secondary > 0);
|
||||||
|
|
||||||
// rescale weights of tasks to sum up to 1
|
// rescale weights of tasks to sum up to 1
|
||||||
double primary_rescale = 1.0 / primary_weight;
|
double primary_rescale = 1.0 / primary_weight;
|
||||||
double secondary_rescale;
|
double secondary_rescale;
|
||||||
if (FuzzyZero(secondary_weight))
|
if (FuzzyZero(secondary_weight)) {
|
||||||
secondary_rescale = 0.0;
|
secondary_rescale = 0.0;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
secondary_rescale = 1.0 / secondary_weight;
|
secondary_rescale = 1.0 / secondary_weight;
|
||||||
|
}
|
||||||
|
|
||||||
for (task = tasks.begin(); task != tasks.end(); task++) {
|
for (task = tasks.begin(); task != tasks.end(); task++) {
|
||||||
IK_QTask *qtask = *task;
|
IK_QTask *qtask = *task;
|
||||||
|
|
||||||
if (qtask->Primary())
|
if (qtask->Primary()) {
|
||||||
qtask->SetWeight(qtask->Weight() * primary_rescale);
|
qtask->SetWeight(qtask->Weight() * primary_rescale);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
qtask->SetWeight(qtask->Weight() * secondary_rescale);
|
qtask->SetWeight(qtask->Weight() * secondary_rescale);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set matrix sizes
|
// set matrix sizes
|
||||||
m_jacobian.ArmMatrices(num_dof, primary_size);
|
m_jacobian.ArmMatrices(num_dof, primary_size);
|
||||||
if (secondary > 0)
|
if (secondary > 0) {
|
||||||
m_jacobian_sub.ArmMatrices(num_dof, secondary_size);
|
m_jacobian_sub.ArmMatrices(num_dof, secondary_size);
|
||||||
|
}
|
||||||
|
|
||||||
// set dof weights
|
// set dof weights
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
|
for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
|
||||||
for (i = 0; i < (*seg)->NumberOfDoF(); i++)
|
for (i = 0; i < (*seg)->NumberOfDoF(); i++) {
|
||||||
m_jacobian.SetDoFWeight((*seg)->DoFId() + i, (*seg)->Weight(i));
|
m_jacobian.SetDoFWeight((*seg)->DoFId() + i, (*seg)->Weight(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -150,16 +165,19 @@ void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTa
|
|||||||
// solving gives predictable solutions by rotating towards the solution,
|
// solving gives predictable solutions by rotating towards the solution,
|
||||||
// and calling it afterwards ensures the solution is exact.
|
// and calling it afterwards ensures the solution is exact.
|
||||||
|
|
||||||
if (!m_poleconstraint)
|
if (!m_poleconstraint) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// disable pole vector constraint in case of multiple position tasks
|
// disable pole vector constraint in case of multiple position tasks
|
||||||
std::list<IK_QTask *>::iterator task;
|
std::list<IK_QTask *>::iterator task;
|
||||||
int positiontasks = 0;
|
int positiontasks = 0;
|
||||||
|
|
||||||
for (task = tasks.begin(); task != tasks.end(); task++)
|
for (task = tasks.begin(); task != tasks.end(); task++) {
|
||||||
if ((*task)->PositionTask())
|
if ((*task)->PositionTask()) {
|
||||||
positiontasks++;
|
positiontasks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (positiontasks >= 2) {
|
if (positiontasks >= 2) {
|
||||||
m_poleconstraint = false;
|
m_poleconstraint = false;
|
||||||
@ -200,8 +218,9 @@ void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTa
|
|||||||
m_poleangle = angle(mat.row(1), polemat.row(1));
|
m_poleangle = angle(mat.row(1), polemat.row(1));
|
||||||
|
|
||||||
double dt = rootz.dot(mat.row(1) * cos(m_poleangle) + mat.row(0) * sin(m_poleangle));
|
double dt = rootz.dot(mat.row(1) * cos(m_poleangle) + mat.row(0) * sin(m_poleangle));
|
||||||
if (dt > 0.0)
|
if (dt > 0.0) {
|
||||||
m_poleangle = -m_poleangle;
|
m_poleangle = -m_poleangle;
|
||||||
|
}
|
||||||
|
|
||||||
// solve again, with the pole angle we just computed
|
// solve again, with the pole angle we just computed
|
||||||
m_getpoleangle = false;
|
m_getpoleangle = false;
|
||||||
@ -259,16 +278,18 @@ bool IK_QJacobianSolver::UpdateAngles(double &norm)
|
|||||||
minseg->Lock(mindof, m_jacobian, mindelta);
|
minseg->Lock(mindof, m_jacobian, mindelta);
|
||||||
locked = true;
|
locked = true;
|
||||||
|
|
||||||
if (minabsdelta > norm)
|
if (minabsdelta > norm) {
|
||||||
norm = minabsdelta;
|
norm = minabsdelta;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (locked == false)
|
if (locked == false) {
|
||||||
// no locking done, last inner iteration, apply the angles
|
// no locking done, last inner iteration, apply the angles
|
||||||
for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
|
for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
|
||||||
(*seg)->UnLock();
|
(*seg)->UnLock();
|
||||||
(*seg)->UpdateAngleApply();
|
(*seg)->UpdateAngleApply();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// signal if another inner iteration is needed
|
// signal if another inner iteration is needed
|
||||||
return locked;
|
return locked;
|
||||||
@ -298,11 +319,13 @@ bool IK_QJacobianSolver::Solve(IK_QSegment *root,
|
|||||||
|
|
||||||
// compute jacobian
|
// compute jacobian
|
||||||
for (task = tasks.begin(); task != tasks.end(); task++) {
|
for (task = tasks.begin(); task != tasks.end(); task++) {
|
||||||
if ((*task)->Primary())
|
if ((*task)->Primary()) {
|
||||||
(*task)->ComputeJacobian(m_jacobian);
|
(*task)->ComputeJacobian(m_jacobian);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
(*task)->ComputeJacobian(m_jacobian_sub);
|
(*task)->ComputeJacobian(m_jacobian_sub);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double norm = 0.0;
|
double norm = 0.0;
|
||||||
|
|
||||||
@ -310,9 +333,10 @@ bool IK_QJacobianSolver::Solve(IK_QSegment *root,
|
|||||||
// invert jacobian
|
// invert jacobian
|
||||||
try {
|
try {
|
||||||
m_jacobian.Invert();
|
m_jacobian.Invert();
|
||||||
if (m_secondary_enabled)
|
if (m_secondary_enabled) {
|
||||||
m_jacobian.SubTask(m_jacobian_sub);
|
m_jacobian.SubTask(m_jacobian_sub);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
fprintf(stderr, "IK Exception\n");
|
fprintf(stderr, "IK Exception\n");
|
||||||
return false;
|
return false;
|
||||||
@ -323,13 +347,15 @@ bool IK_QJacobianSolver::Solve(IK_QSegment *root,
|
|||||||
|
|
||||||
// unlock segments again after locking in clamping loop
|
// unlock segments again after locking in clamping loop
|
||||||
std::vector<IK_QSegment *>::iterator seg;
|
std::vector<IK_QSegment *>::iterator seg;
|
||||||
for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
|
for (seg = m_segments.begin(); seg != m_segments.end(); seg++) {
|
||||||
(*seg)->UnLock();
|
(*seg)->UnLock();
|
||||||
|
}
|
||||||
|
|
||||||
// compute angle update norm
|
// compute angle update norm
|
||||||
double maxnorm = m_jacobian.AngleUpdateNorm();
|
double maxnorm = m_jacobian.AngleUpdateNorm();
|
||||||
if (maxnorm > norm)
|
if (maxnorm > norm) {
|
||||||
norm = maxnorm;
|
norm = maxnorm;
|
||||||
|
}
|
||||||
|
|
||||||
// check for convergence
|
// check for convergence
|
||||||
if (norm < 1e-3 && iterations > 10) {
|
if (norm < 1e-3 && iterations > 10) {
|
||||||
@ -338,8 +364,9 @@ bool IK_QJacobianSolver::Solve(IK_QSegment *root,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_poleconstraint)
|
if (m_poleconstraint) {
|
||||||
root->PrependBasis(m_rootmatrix.linear());
|
root->PrependBasis(m_rootmatrix.linear());
|
||||||
|
}
|
||||||
|
|
||||||
Scale(1.0f / scale, tasks);
|
Scale(1.0f / scale, tasks);
|
||||||
|
|
||||||
|
@ -40,8 +40,9 @@ void IK_QSegment::Reset()
|
|||||||
m_translation = m_orig_translation;
|
m_translation = m_orig_translation;
|
||||||
SetBasis(m_basis);
|
SetBasis(m_basis);
|
||||||
|
|
||||||
for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling)
|
for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling) {
|
||||||
seg->Reset();
|
seg->Reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_QSegment::SetTransform(const Vector3d &start,
|
void IK_QSegment::SetTransform(const Vector3d &start,
|
||||||
@ -73,20 +74,24 @@ Vector3d IK_QSegment::TranslationChange() const
|
|||||||
|
|
||||||
IK_QSegment::~IK_QSegment()
|
IK_QSegment::~IK_QSegment()
|
||||||
{
|
{
|
||||||
if (m_parent)
|
if (m_parent) {
|
||||||
m_parent->RemoveChild(this);
|
m_parent->RemoveChild(this);
|
||||||
|
}
|
||||||
|
|
||||||
for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling)
|
for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling) {
|
||||||
seg->m_parent = NULL;
|
seg->m_parent = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_QSegment::SetParent(IK_QSegment *parent)
|
void IK_QSegment::SetParent(IK_QSegment *parent)
|
||||||
{
|
{
|
||||||
if (m_parent == parent)
|
if (m_parent == parent) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_parent)
|
if (m_parent) {
|
||||||
m_parent->RemoveChild(this);
|
m_parent->RemoveChild(this);
|
||||||
|
}
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
m_sibling = parent->m_child;
|
m_sibling = parent->m_child;
|
||||||
@ -103,19 +108,23 @@ void IK_QSegment::SetComposite(IK_QSegment *seg)
|
|||||||
|
|
||||||
void IK_QSegment::RemoveChild(IK_QSegment *child)
|
void IK_QSegment::RemoveChild(IK_QSegment *child)
|
||||||
{
|
{
|
||||||
if (m_child == NULL)
|
if (m_child == NULL) {
|
||||||
return;
|
return;
|
||||||
else if (m_child == child)
|
}
|
||||||
|
else if (m_child == child) {
|
||||||
m_child = m_child->m_sibling;
|
m_child = m_child->m_sibling;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
IK_QSegment *seg = m_child;
|
IK_QSegment *seg = m_child;
|
||||||
|
|
||||||
while (seg->m_sibling != child)
|
while (seg->m_sibling != child) {
|
||||||
seg = seg->m_sibling;
|
seg = seg->m_sibling;
|
||||||
|
}
|
||||||
|
|
||||||
if (child == seg->m_sibling)
|
if (child == seg->m_sibling) {
|
||||||
seg->m_sibling = child->m_sibling;
|
seg->m_sibling = child->m_sibling;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_QSegment::UpdateTransform(const Affine3d &global)
|
void IK_QSegment::UpdateTransform(const Affine3d &global)
|
||||||
@ -128,8 +137,9 @@ void IK_QSegment::UpdateTransform(const Affine3d &global)
|
|||||||
m_global_transform.translate(m_translation);
|
m_global_transform.translate(m_translation);
|
||||||
|
|
||||||
// update child transforms
|
// update child transforms
|
||||||
for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling)
|
for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling) {
|
||||||
seg->UpdateTransform(m_global_transform);
|
seg->UpdateTransform(m_global_transform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_QSegment::PrependBasis(const Matrix3d &mat)
|
void IK_QSegment::PrependBasis(const Matrix3d &mat)
|
||||||
@ -161,8 +171,9 @@ Vector3d IK_QSphericalSegment::Axis(int dof) const
|
|||||||
|
|
||||||
void IK_QSphericalSegment::SetLimit(int axis, double lmin, double lmax)
|
void IK_QSphericalSegment::SetLimit(int axis, double lmin, double lmax)
|
||||||
{
|
{
|
||||||
if (lmin > lmax)
|
if (lmin > lmax) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (axis == 1) {
|
if (axis == 1) {
|
||||||
lmin = Clamp(lmin, -M_PI, M_PI);
|
lmin = Clamp(lmin, -M_PI, M_PI);
|
||||||
@ -201,8 +212,9 @@ void IK_QSphericalSegment::SetWeight(int axis, double weight)
|
|||||||
|
|
||||||
bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
|
bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
|
||||||
{
|
{
|
||||||
if (m_locked[0] && m_locked[1] && m_locked[2])
|
if (m_locked[0] && m_locked[1] && m_locked[2]) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3d dq;
|
Vector3d dq;
|
||||||
dq.x() = jacobian.AngleUpdate(m_DoF_id);
|
dq.x() = jacobian.AngleUpdate(m_DoF_id);
|
||||||
@ -244,20 +256,25 @@ bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &d
|
|||||||
|
|
||||||
m_new_basis = m_basis * M;
|
m_new_basis = m_basis * M;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
m_new_basis = m_basis;
|
m_new_basis = m_basis;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_limit_y == false && m_limit_x == false && m_limit_z == false)
|
if (m_limit_y == false && m_limit_x == false && m_limit_z == false) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3d a = SphericalRangeParameters(m_new_basis);
|
Vector3d a = SphericalRangeParameters(m_new_basis);
|
||||||
|
|
||||||
if (m_locked[0])
|
if (m_locked[0]) {
|
||||||
a.x() = m_locked_ax;
|
a.x() = m_locked_ax;
|
||||||
if (m_locked[1])
|
}
|
||||||
|
if (m_locked[1]) {
|
||||||
a.y() = m_locked_ay;
|
a.y() = m_locked_ay;
|
||||||
if (m_locked[2])
|
}
|
||||||
|
if (m_locked[2]) {
|
||||||
a.z() = m_locked_az;
|
a.z() = m_locked_az;
|
||||||
|
}
|
||||||
|
|
||||||
double ax = a.x(), ay = a.y(), az = a.z();
|
double ax = a.x(), ay = a.y(), az = a.z();
|
||||||
|
|
||||||
@ -275,9 +292,10 @@ bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &d
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_limit_x && m_limit_z) {
|
if (m_limit_x && m_limit_z) {
|
||||||
if (EllipseClamp(ax, az, m_min, m_max))
|
if (EllipseClamp(ax, az, m_min, m_max)) {
|
||||||
clamp[0] = clamp[2] = true;
|
clamp[0] = clamp[2] = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (m_limit_x) {
|
else if (m_limit_x) {
|
||||||
if (ax < m_min[0]) {
|
if (ax < m_min[0]) {
|
||||||
ax = m_min[0];
|
ax = m_min[0];
|
||||||
@ -300,8 +318,9 @@ bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &d
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (clamp[0] == false && clamp[1] == false && clamp[2] == false) {
|
if (clamp[0] == false && clamp[1] == false && clamp[2] == false) {
|
||||||
if (m_locked[0] || m_locked[1] || m_locked[2])
|
if (m_locked[0] || m_locked[1] || m_locked[2]) {
|
||||||
m_new_basis = ComputeSwingMatrix(ax, az) * ComputeTwistMatrix(ay);
|
m_new_basis = ComputeSwingMatrix(ax, az) * ComputeTwistMatrix(ay);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,8 +333,9 @@ bool IK_QSphericalSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &d
|
|||||||
m_locked_az = az;
|
m_locked_az = az;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_locked[1] && clamp[1])
|
if (!m_locked[1] && clamp[1]) {
|
||||||
m_locked_ay = ay;
|
m_locked_ay = ay;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -368,22 +388,27 @@ Vector3d IK_QRevoluteSegment::Axis(int) const
|
|||||||
|
|
||||||
bool IK_QRevoluteSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
|
bool IK_QRevoluteSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
|
||||||
{
|
{
|
||||||
if (m_locked[0])
|
if (m_locked[0]) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_new_angle = m_angle + jacobian.AngleUpdate(m_DoF_id);
|
m_new_angle = m_angle + jacobian.AngleUpdate(m_DoF_id);
|
||||||
|
|
||||||
clamp[0] = false;
|
clamp[0] = false;
|
||||||
|
|
||||||
if (m_limit == false)
|
if (m_limit == false) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_new_angle > m_max)
|
if (m_new_angle > m_max) {
|
||||||
delta[0] = m_max - m_angle;
|
delta[0] = m_max - m_angle;
|
||||||
else if (m_new_angle < m_min)
|
}
|
||||||
|
else if (m_new_angle < m_min) {
|
||||||
delta[0] = m_min - m_angle;
|
delta[0] = m_min - m_angle;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
clamp[0] = true;
|
clamp[0] = true;
|
||||||
m_new_angle = m_angle + delta[0];
|
m_new_angle = m_angle + delta[0];
|
||||||
@ -405,8 +430,9 @@ void IK_QRevoluteSegment::UpdateAngleApply()
|
|||||||
|
|
||||||
void IK_QRevoluteSegment::SetLimit(int axis, double lmin, double lmax)
|
void IK_QRevoluteSegment::SetLimit(int axis, double lmin, double lmax)
|
||||||
{
|
{
|
||||||
if (lmin > lmax || m_axis != axis)
|
if (lmin > lmax || m_axis != axis) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// clamp and convert to axis angle parameters
|
// clamp and convert to axis angle parameters
|
||||||
lmin = Clamp(lmin, -M_PI, M_PI);
|
lmin = Clamp(lmin, -M_PI, M_PI);
|
||||||
@ -420,8 +446,9 @@ void IK_QRevoluteSegment::SetLimit(int axis, double lmin, double lmax)
|
|||||||
|
|
||||||
void IK_QRevoluteSegment::SetWeight(int axis, double weight)
|
void IK_QRevoluteSegment::SetWeight(int axis, double weight)
|
||||||
{
|
{
|
||||||
if (axis == m_axis)
|
if (axis == m_axis) {
|
||||||
m_weight[0] = weight;
|
m_weight[0] = weight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IK_QSwingSegment
|
// IK_QSwingSegment
|
||||||
@ -441,8 +468,9 @@ Vector3d IK_QSwingSegment::Axis(int dof) const
|
|||||||
|
|
||||||
bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
|
bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
|
||||||
{
|
{
|
||||||
if (m_locked[0] && m_locked[1])
|
if (m_locked[0] && m_locked[1]) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3d dq;
|
Vector3d dq;
|
||||||
dq.x() = jacobian.AngleUpdate(m_DoF_id);
|
dq.x() = jacobian.AngleUpdate(m_DoF_id);
|
||||||
@ -482,11 +510,13 @@ bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta
|
|||||||
|
|
||||||
RemoveTwist(m_new_basis);
|
RemoveTwist(m_new_basis);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
m_new_basis = m_basis;
|
m_new_basis = m_basis;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_limit_x == false && m_limit_z == false)
|
if (m_limit_x == false && m_limit_z == false) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3d a = SphericalRangeParameters(m_new_basis);
|
Vector3d a = SphericalRangeParameters(m_new_basis);
|
||||||
double ax = 0, az = 0;
|
double ax = 0, az = 0;
|
||||||
@ -497,9 +527,10 @@ bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta
|
|||||||
ax = a.x();
|
ax = a.x();
|
||||||
az = a.z();
|
az = a.z();
|
||||||
|
|
||||||
if (EllipseClamp(ax, az, m_min, m_max))
|
if (EllipseClamp(ax, az, m_min, m_max)) {
|
||||||
clamp[0] = clamp[1] = true;
|
clamp[0] = clamp[1] = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (m_limit_x) {
|
else if (m_limit_x) {
|
||||||
if (ax < m_min[0]) {
|
if (ax < m_min[0]) {
|
||||||
ax = m_min[0];
|
ax = m_min[0];
|
||||||
@ -521,8 +552,9 @@ bool IK_QSwingSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clamp[0] == false && clamp[1] == false)
|
if (clamp[0] == false && clamp[1] == false) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_new_basis = ComputeSwingMatrix(ax, az);
|
m_new_basis = ComputeSwingMatrix(ax, az);
|
||||||
|
|
||||||
@ -547,8 +579,9 @@ void IK_QSwingSegment::UpdateAngleApply()
|
|||||||
|
|
||||||
void IK_QSwingSegment::SetLimit(int axis, double lmin, double lmax)
|
void IK_QSwingSegment::SetLimit(int axis, double lmin, double lmax)
|
||||||
{
|
{
|
||||||
if (lmin > lmax)
|
if (lmin > lmax) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// clamp and convert to axis angle parameters
|
// clamp and convert to axis angle parameters
|
||||||
lmin = Clamp(lmin, -M_PI, M_PI);
|
lmin = Clamp(lmin, -M_PI, M_PI);
|
||||||
@ -581,10 +614,12 @@ void IK_QSwingSegment::SetLimit(int axis, double lmin, double lmax)
|
|||||||
|
|
||||||
void IK_QSwingSegment::SetWeight(int axis, double weight)
|
void IK_QSwingSegment::SetWeight(int axis, double weight)
|
||||||
{
|
{
|
||||||
if (axis == 0)
|
if (axis == 0) {
|
||||||
m_weight[0] = weight;
|
m_weight[0] = weight;
|
||||||
else if (axis == 2)
|
}
|
||||||
|
else if (axis == 2) {
|
||||||
m_weight[1] = weight;
|
m_weight[1] = weight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IK_QElbowSegment
|
// IK_QElbowSegment
|
||||||
@ -616,21 +651,25 @@ Vector3d IK_QElbowSegment::Axis(int dof) const
|
|||||||
{
|
{
|
||||||
if (dof == 0) {
|
if (dof == 0) {
|
||||||
Vector3d v;
|
Vector3d v;
|
||||||
if (m_axis == 0)
|
if (m_axis == 0) {
|
||||||
v = Vector3d(m_cos_twist, 0, m_sin_twist);
|
v = Vector3d(m_cos_twist, 0, m_sin_twist);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
v = Vector3d(-m_sin_twist, 0, m_cos_twist);
|
v = Vector3d(-m_sin_twist, 0, m_cos_twist);
|
||||||
|
}
|
||||||
|
|
||||||
return m_global_transform.linear() * v;
|
return m_global_transform.linear() * v;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
return m_global_transform.linear().col(1);
|
return m_global_transform.linear().col(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IK_QElbowSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
|
bool IK_QElbowSegment::UpdateAngle(const IK_QJacobian &jacobian, Vector3d &delta, bool *clamp)
|
||||||
{
|
{
|
||||||
if (m_locked[0] && m_locked[1])
|
if (m_locked[0] && m_locked[1]) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
clamp[0] = clamp[1] = false;
|
clamp[0] = clamp[1] = false;
|
||||||
|
|
||||||
@ -699,8 +738,9 @@ void IK_QElbowSegment::UpdateAngleApply()
|
|||||||
|
|
||||||
void IK_QElbowSegment::SetLimit(int axis, double lmin, double lmax)
|
void IK_QElbowSegment::SetLimit(int axis, double lmin, double lmax)
|
||||||
{
|
{
|
||||||
if (lmin > lmax)
|
if (lmin > lmax) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// clamp and convert to axis angle parameters
|
// clamp and convert to axis angle parameters
|
||||||
lmin = Clamp(lmin, -M_PI, M_PI);
|
lmin = Clamp(lmin, -M_PI, M_PI);
|
||||||
@ -720,10 +760,12 @@ void IK_QElbowSegment::SetLimit(int axis, double lmin, double lmax)
|
|||||||
|
|
||||||
void IK_QElbowSegment::SetWeight(int axis, double weight)
|
void IK_QElbowSegment::SetWeight(int axis, double weight)
|
||||||
{
|
{
|
||||||
if (axis == m_axis)
|
if (axis == m_axis) {
|
||||||
m_weight[0] = weight;
|
m_weight[0] = weight;
|
||||||
else if (axis == 1)
|
}
|
||||||
|
else if (axis == 1) {
|
||||||
m_weight[1] = weight;
|
m_weight[1] = weight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IK_QTranslateSegment
|
// IK_QTranslateSegment
|
||||||
@ -819,15 +861,18 @@ void IK_QTranslateSegment::SetWeight(int axis, double weight)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < m_num_DoF; i++)
|
for (i = 0; i < m_num_DoF; i++) {
|
||||||
if (m_axis[i] == axis)
|
if (m_axis[i] == axis) {
|
||||||
m_weight[i] = weight;
|
m_weight[i] = weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_QTranslateSegment::SetLimit(int axis, double lmin, double lmax)
|
void IK_QTranslateSegment::SetLimit(int axis, double lmin, double lmax)
|
||||||
{
|
{
|
||||||
if (lmax < lmin)
|
if (lmax < lmin) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_min[axis] = lmin;
|
m_min[axis] = lmin;
|
||||||
m_max[axis] = lmax;
|
m_max[axis] = lmax;
|
||||||
|
@ -43,8 +43,9 @@ void IK_QPositionTask::ComputeJacobian(IK_QJacobian &jacobian)
|
|||||||
Vector3d d_pos = m_goal - pos;
|
Vector3d d_pos = m_goal - pos;
|
||||||
double length = d_pos.norm();
|
double length = d_pos.norm();
|
||||||
|
|
||||||
if (length > m_clamp_length)
|
if (length > m_clamp_length) {
|
||||||
d_pos = (m_clamp_length / length) * d_pos;
|
d_pos = (m_clamp_length / length) * d_pos;
|
||||||
|
}
|
||||||
|
|
||||||
jacobian.SetBetas(m_id, m_size, m_weight * d_pos);
|
jacobian.SetBetas(m_id, m_size, m_weight * d_pos);
|
||||||
|
|
||||||
@ -58,8 +59,9 @@ void IK_QPositionTask::ComputeJacobian(IK_QJacobian &jacobian)
|
|||||||
for (i = 0; i < seg->NumberOfDoF(); i++) {
|
for (i = 0; i < seg->NumberOfDoF(); i++) {
|
||||||
Vector3d axis = seg->Axis(i) * m_weight;
|
Vector3d axis = seg->Axis(i) * m_weight;
|
||||||
|
|
||||||
if (seg->Translational())
|
if (seg->Translational()) {
|
||||||
jacobian.SetDerivatives(m_id, seg->DoFId() + i, axis, 1e2);
|
jacobian.SetDerivatives(m_id, seg->DoFId() + i, axis, 1e2);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
Vector3d pa = p.cross(axis);
|
Vector3d pa = p.cross(axis);
|
||||||
jacobian.SetDerivatives(m_id, seg->DoFId() + i, pa, 1e0);
|
jacobian.SetDerivatives(m_id, seg->DoFId() + i, pa, 1e0);
|
||||||
@ -104,16 +106,18 @@ void IK_QOrientationTask::ComputeJacobian(IK_QJacobian &jacobian)
|
|||||||
int i;
|
int i;
|
||||||
const IK_QSegment *seg;
|
const IK_QSegment *seg;
|
||||||
|
|
||||||
for (seg = m_segment; seg; seg = seg->Parent())
|
for (seg = m_segment; seg; seg = seg->Parent()) {
|
||||||
for (i = 0; i < seg->NumberOfDoF(); i++) {
|
for (i = 0; i < seg->NumberOfDoF(); i++) {
|
||||||
|
|
||||||
if (seg->Translational())
|
if (seg->Translational()) {
|
||||||
jacobian.SetDerivatives(m_id, seg->DoFId() + i, Vector3d(0, 0, 0), 1e2);
|
jacobian.SetDerivatives(m_id, seg->DoFId() + i, Vector3d(0, 0, 0), 1e2);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
Vector3d axis = seg->Axis(i) * m_weight;
|
Vector3d axis = seg->Axis(i) * m_weight;
|
||||||
jacobian.SetDerivatives(m_id, seg->DoFId() + i, axis, 1e0);
|
jacobian.SetDerivatives(m_id, seg->DoFId() + i, axis, 1e0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IK_QCenterOfMassTask
|
// IK_QCenterOfMassTask
|
||||||
@ -125,8 +129,9 @@ IK_QCenterOfMassTask::IK_QCenterOfMassTask(bool primary,
|
|||||||
: IK_QTask(3, primary, true, segment), m_goal_center(goal_center)
|
: IK_QTask(3, primary, true, segment), m_goal_center(goal_center)
|
||||||
{
|
{
|
||||||
m_total_mass_inv = ComputeTotalMass(m_segment);
|
m_total_mass_inv = ComputeTotalMass(m_segment);
|
||||||
if (!FuzzyZero(m_total_mass_inv))
|
if (!FuzzyZero(m_total_mass_inv)) {
|
||||||
m_total_mass_inv = 1.0 / m_total_mass_inv;
|
m_total_mass_inv = 1.0 / m_total_mass_inv;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double IK_QCenterOfMassTask::ComputeTotalMass(const IK_QSegment *segment)
|
double IK_QCenterOfMassTask::ComputeTotalMass(const IK_QSegment *segment)
|
||||||
@ -134,8 +139,9 @@ double IK_QCenterOfMassTask::ComputeTotalMass(const IK_QSegment *segment)
|
|||||||
double mass = /*seg->Mass()*/ 1.0;
|
double mass = /*seg->Mass()*/ 1.0;
|
||||||
|
|
||||||
const IK_QSegment *seg;
|
const IK_QSegment *seg;
|
||||||
for (seg = segment->Child(); seg; seg = seg->Sibling())
|
for (seg = segment->Child(); seg; seg = seg->Sibling()) {
|
||||||
mass += ComputeTotalMass(seg);
|
mass += ComputeTotalMass(seg);
|
||||||
|
}
|
||||||
|
|
||||||
return mass;
|
return mass;
|
||||||
}
|
}
|
||||||
@ -145,8 +151,9 @@ Vector3d IK_QCenterOfMassTask::ComputeCenter(const IK_QSegment *segment)
|
|||||||
Vector3d center = /*seg->Mass()**/ segment->GlobalStart();
|
Vector3d center = /*seg->Mass()**/ segment->GlobalStart();
|
||||||
|
|
||||||
const IK_QSegment *seg;
|
const IK_QSegment *seg;
|
||||||
for (seg = segment->Child(); seg; seg = seg->Sibling())
|
for (seg = segment->Child(); seg; seg = seg->Sibling()) {
|
||||||
center += ComputeCenter(seg);
|
center += ComputeCenter(seg);
|
||||||
|
}
|
||||||
|
|
||||||
return center;
|
return center;
|
||||||
}
|
}
|
||||||
@ -162,8 +169,9 @@ void IK_QCenterOfMassTask::JacobianSegment(IK_QJacobian &jacobian,
|
|||||||
Vector3d axis = segment->Axis(i) * m_weight;
|
Vector3d axis = segment->Axis(i) * m_weight;
|
||||||
axis *= /*segment->Mass()**/ m_total_mass_inv;
|
axis *= /*segment->Mass()**/ m_total_mass_inv;
|
||||||
|
|
||||||
if (segment->Translational())
|
if (segment->Translational()) {
|
||||||
jacobian.SetDerivatives(m_id, segment->DoFId() + i, axis, 1e2);
|
jacobian.SetDerivatives(m_id, segment->DoFId() + i, axis, 1e2);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
Vector3d pa = axis.cross(p);
|
Vector3d pa = axis.cross(p);
|
||||||
jacobian.SetDerivatives(m_id, segment->DoFId() + i, pa, 1e0);
|
jacobian.SetDerivatives(m_id, segment->DoFId() + i, pa, 1e0);
|
||||||
@ -171,8 +179,9 @@ void IK_QCenterOfMassTask::JacobianSegment(IK_QJacobian &jacobian,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const IK_QSegment *seg;
|
const IK_QSegment *seg;
|
||||||
for (seg = segment->Child(); seg; seg = seg->Sibling())
|
for (seg = segment->Child(); seg; seg = seg->Sibling()) {
|
||||||
JacobianSegment(jacobian, center, seg);
|
JacobianSegment(jacobian, center, seg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_QCenterOfMassTask::ComputeJacobian(IK_QJacobian &jacobian)
|
void IK_QCenterOfMassTask::ComputeJacobian(IK_QJacobian &jacobian)
|
||||||
|
@ -35,23 +35,29 @@ static IK_QSegment *CreateSegment(int flag, bool translate)
|
|||||||
|
|
||||||
IK_QSegment *seg;
|
IK_QSegment *seg;
|
||||||
|
|
||||||
if (ndof == 0)
|
if (ndof == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
else if (ndof == 1) {
|
else if (ndof == 1) {
|
||||||
int axis;
|
int axis;
|
||||||
|
|
||||||
if (flag & IK_XDOF)
|
if (flag & IK_XDOF) {
|
||||||
axis = 0;
|
axis = 0;
|
||||||
else if (flag & IK_YDOF)
|
}
|
||||||
|
else if (flag & IK_YDOF) {
|
||||||
axis = 1;
|
axis = 1;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
axis = 2;
|
axis = 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (translate)
|
if (translate) {
|
||||||
seg = new IK_QTranslateSegment(axis);
|
seg = new IK_QTranslateSegment(axis);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
seg = new IK_QRevoluteSegment(axis);
|
seg = new IK_QRevoluteSegment(axis);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (ndof == 2) {
|
else if (ndof == 2) {
|
||||||
int axis1, axis2;
|
int axis1, axis2;
|
||||||
|
|
||||||
@ -64,21 +70,26 @@ static IK_QSegment *CreateSegment(int flag, bool translate)
|
|||||||
axis2 = 2;
|
axis2 = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (translate)
|
if (translate) {
|
||||||
seg = new IK_QTranslateSegment(axis1, axis2);
|
seg = new IK_QTranslateSegment(axis1, axis2);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (axis1 + axis2 == 2)
|
if (axis1 + axis2 == 2) {
|
||||||
seg = new IK_QSwingSegment();
|
seg = new IK_QSwingSegment();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
seg = new IK_QElbowSegment((axis1 == 0) ? 0 : 2);
|
seg = new IK_QElbowSegment((axis1 == 0) ? 0 : 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (translate)
|
if (translate) {
|
||||||
seg = new IK_QTranslateSegment();
|
seg = new IK_QTranslateSegment();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
seg = new IK_QSphericalSegment();
|
seg = new IK_QSphericalSegment();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return seg;
|
return seg;
|
||||||
}
|
}
|
||||||
@ -90,10 +101,12 @@ IK_Segment *IK_CreateSegment(int flag)
|
|||||||
|
|
||||||
IK_QSegment *seg;
|
IK_QSegment *seg;
|
||||||
|
|
||||||
if (rot == NULL && trans == NULL)
|
if (rot == NULL && trans == NULL) {
|
||||||
seg = new IK_QNullSegment();
|
seg = new IK_QNullSegment();
|
||||||
else if (rot == NULL)
|
}
|
||||||
|
else if (rot == NULL) {
|
||||||
seg = trans;
|
seg = trans;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
seg = rot;
|
seg = rot;
|
||||||
|
|
||||||
@ -112,8 +125,9 @@ void IK_FreeSegment(IK_Segment *seg)
|
|||||||
{
|
{
|
||||||
IK_QSegment *qseg = (IK_QSegment *)seg;
|
IK_QSegment *qseg = (IK_QSegment *)seg;
|
||||||
|
|
||||||
if (qseg->Composite())
|
if (qseg->Composite()) {
|
||||||
delete qseg->Composite();
|
delete qseg->Composite();
|
||||||
|
}
|
||||||
delete qseg;
|
delete qseg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,10 +136,12 @@ void IK_SetParent(IK_Segment *seg, IK_Segment *parent)
|
|||||||
IK_QSegment *qseg = (IK_QSegment *)seg;
|
IK_QSegment *qseg = (IK_QSegment *)seg;
|
||||||
IK_QSegment *qparent = (IK_QSegment *)parent;
|
IK_QSegment *qparent = (IK_QSegment *)parent;
|
||||||
|
|
||||||
if (qparent && qparent->Composite())
|
if (qparent && qparent->Composite()) {
|
||||||
qseg->SetParent(qparent->Composite());
|
qseg->SetParent(qparent->Composite());
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
qseg->SetParent(qparent);
|
qseg->SetParent(qparent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_SetTransform(
|
void IK_SetTransform(
|
||||||
@ -163,8 +179,9 @@ void IK_SetTransform(
|
|||||||
qseg->SetTransform(mstart, mrest, mbasis, 0.0);
|
qseg->SetTransform(mstart, mrest, mbasis, 0.0);
|
||||||
qseg->Composite()->SetTransform(cstart, cbasis, cbasis, mlength);
|
qseg->Composite()->SetTransform(cstart, cbasis, cbasis, mlength);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
qseg->SetTransform(mstart, mrest, mbasis, mlength);
|
qseg->SetTransform(mstart, mrest, mbasis, mlength);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_SetLimit(IK_Segment *seg, IK_SegmentAxis axis, float lmin, float lmax)
|
void IK_SetLimit(IK_Segment *seg, IK_SegmentAxis axis, float lmin, float lmax)
|
||||||
@ -173,49 +190,61 @@ void IK_SetLimit(IK_Segment *seg, IK_SegmentAxis axis, float lmin, float lmax)
|
|||||||
|
|
||||||
if (axis >= IK_TRANS_X) {
|
if (axis >= IK_TRANS_X) {
|
||||||
if (!qseg->Translational()) {
|
if (!qseg->Translational()) {
|
||||||
if (qseg->Composite() && qseg->Composite()->Translational())
|
if (qseg->Composite() && qseg->Composite()->Translational()) {
|
||||||
qseg = qseg->Composite();
|
qseg = qseg->Composite();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (axis == IK_TRANS_X)
|
if (axis == IK_TRANS_X) {
|
||||||
axis = IK_X;
|
axis = IK_X;
|
||||||
else if (axis == IK_TRANS_Y)
|
}
|
||||||
|
else if (axis == IK_TRANS_Y) {
|
||||||
axis = IK_Y;
|
axis = IK_Y;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
axis = IK_Z;
|
axis = IK_Z;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qseg->SetLimit(axis, lmin, lmax);
|
qseg->SetLimit(axis, lmin, lmax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_SetStiffness(IK_Segment *seg, IK_SegmentAxis axis, float stiffness)
|
void IK_SetStiffness(IK_Segment *seg, IK_SegmentAxis axis, float stiffness)
|
||||||
{
|
{
|
||||||
if (stiffness < 0.0f)
|
if (stiffness < 0.0f) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (stiffness > (1.0 - IK_STRETCH_STIFF_EPS))
|
if (stiffness > (1.0 - IK_STRETCH_STIFF_EPS)) {
|
||||||
stiffness = (1.0 - IK_STRETCH_STIFF_EPS);
|
stiffness = (1.0 - IK_STRETCH_STIFF_EPS);
|
||||||
|
}
|
||||||
|
|
||||||
IK_QSegment *qseg = (IK_QSegment *)seg;
|
IK_QSegment *qseg = (IK_QSegment *)seg;
|
||||||
double weight = 1.0f - stiffness;
|
double weight = 1.0f - stiffness;
|
||||||
|
|
||||||
if (axis >= IK_TRANS_X) {
|
if (axis >= IK_TRANS_X) {
|
||||||
if (!qseg->Translational()) {
|
if (!qseg->Translational()) {
|
||||||
if (qseg->Composite() && qseg->Composite()->Translational())
|
if (qseg->Composite() && qseg->Composite()->Translational()) {
|
||||||
qseg = qseg->Composite();
|
qseg = qseg->Composite();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (axis == IK_TRANS_X)
|
if (axis == IK_TRANS_X) {
|
||||||
axis = IK_X;
|
axis = IK_X;
|
||||||
else if (axis == IK_TRANS_Y)
|
}
|
||||||
|
else if (axis == IK_TRANS_Y) {
|
||||||
axis = IK_Y;
|
axis = IK_Y;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
axis = IK_Z;
|
axis = IK_Z;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qseg->SetWeight(axis, weight);
|
qseg->SetWeight(axis, weight);
|
||||||
}
|
}
|
||||||
@ -224,8 +253,9 @@ void IK_GetBasisChange(IK_Segment *seg, float basis_change[][3])
|
|||||||
{
|
{
|
||||||
IK_QSegment *qseg = (IK_QSegment *)seg;
|
IK_QSegment *qseg = (IK_QSegment *)seg;
|
||||||
|
|
||||||
if (qseg->Translational() && qseg->Composite())
|
if (qseg->Translational() && qseg->Composite()) {
|
||||||
qseg = qseg->Composite();
|
qseg = qseg->Composite();
|
||||||
|
}
|
||||||
|
|
||||||
const Matrix3d &change = qseg->BasisChange();
|
const Matrix3d &change = qseg->BasisChange();
|
||||||
|
|
||||||
@ -245,8 +275,9 @@ void IK_GetTranslationChange(IK_Segment *seg, float *translation_change)
|
|||||||
{
|
{
|
||||||
IK_QSegment *qseg = (IK_QSegment *)seg;
|
IK_QSegment *qseg = (IK_QSegment *)seg;
|
||||||
|
|
||||||
if (!qseg->Translational() && qseg->Composite())
|
if (!qseg->Translational() && qseg->Composite()) {
|
||||||
qseg = qseg->Composite();
|
qseg = qseg->Composite();
|
||||||
|
}
|
||||||
|
|
||||||
const Vector3d &change = qseg->TranslationChange();
|
const Vector3d &change = qseg->TranslationChange();
|
||||||
|
|
||||||
@ -257,8 +288,9 @@ void IK_GetTranslationChange(IK_Segment *seg, float *translation_change)
|
|||||||
|
|
||||||
IK_Solver *IK_CreateSolver(IK_Segment *root)
|
IK_Solver *IK_CreateSolver(IK_Segment *root)
|
||||||
{
|
{
|
||||||
if (root == NULL)
|
if (root == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
IK_QSolver *solver = new IK_QSolver();
|
IK_QSolver *solver = new IK_QSolver();
|
||||||
solver->root = (IK_QSegment *)root;
|
solver->root = (IK_QSegment *)root;
|
||||||
@ -268,30 +300,34 @@ IK_Solver *IK_CreateSolver(IK_Segment *root)
|
|||||||
|
|
||||||
void IK_FreeSolver(IK_Solver *solver)
|
void IK_FreeSolver(IK_Solver *solver)
|
||||||
{
|
{
|
||||||
if (solver == NULL)
|
if (solver == NULL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||||
std::list<IK_QTask *> &tasks = qsolver->tasks;
|
std::list<IK_QTask *> &tasks = qsolver->tasks;
|
||||||
std::list<IK_QTask *>::iterator task;
|
std::list<IK_QTask *>::iterator task;
|
||||||
|
|
||||||
for (task = tasks.begin(); task != tasks.end(); task++)
|
for (task = tasks.begin(); task != tasks.end(); task++) {
|
||||||
delete (*task);
|
delete (*task);
|
||||||
|
}
|
||||||
|
|
||||||
delete qsolver;
|
delete qsolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float weight)
|
void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float weight)
|
||||||
{
|
{
|
||||||
if (solver == NULL || tip == NULL)
|
if (solver == NULL || tip == NULL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||||
IK_QSegment *qtip = (IK_QSegment *)tip;
|
IK_QSegment *qtip = (IK_QSegment *)tip;
|
||||||
|
|
||||||
// in case of composite segment the second segment is the tip
|
// in case of composite segment the second segment is the tip
|
||||||
if (qtip->Composite())
|
if (qtip->Composite()) {
|
||||||
qtip = qtip->Composite();
|
qtip = qtip->Composite();
|
||||||
|
}
|
||||||
|
|
||||||
Vector3d pos(goal[0], goal[1], goal[2]);
|
Vector3d pos(goal[0], goal[1], goal[2]);
|
||||||
|
|
||||||
@ -302,15 +338,17 @@ void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float w
|
|||||||
|
|
||||||
void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[][3], float weight)
|
void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[][3], float weight)
|
||||||
{
|
{
|
||||||
if (solver == NULL || tip == NULL)
|
if (solver == NULL || tip == NULL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||||
IK_QSegment *qtip = (IK_QSegment *)tip;
|
IK_QSegment *qtip = (IK_QSegment *)tip;
|
||||||
|
|
||||||
// in case of composite segment the second segment is the tip
|
// in case of composite segment the second segment is the tip
|
||||||
if (qtip->Composite())
|
if (qtip->Composite()) {
|
||||||
qtip = qtip->Composite();
|
qtip = qtip->Composite();
|
||||||
|
}
|
||||||
|
|
||||||
// convert from blender column major
|
// convert from blender column major
|
||||||
Matrix3d rot = CreateMatrix(goal[0][0],
|
Matrix3d rot = CreateMatrix(goal[0][0],
|
||||||
@ -335,15 +373,17 @@ void IK_SolverSetPoleVectorConstraint(IK_Solver *solver,
|
|||||||
float poleangle,
|
float poleangle,
|
||||||
int getangle)
|
int getangle)
|
||||||
{
|
{
|
||||||
if (solver == NULL || tip == NULL)
|
if (solver == NULL || tip == NULL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||||
IK_QSegment *qtip = (IK_QSegment *)tip;
|
IK_QSegment *qtip = (IK_QSegment *)tip;
|
||||||
|
|
||||||
// in case of composite segment the second segment is the tip
|
// in case of composite segment the second segment is the tip
|
||||||
if (qtip->Composite())
|
if (qtip->Composite()) {
|
||||||
qtip = qtip->Composite();
|
qtip = qtip->Composite();
|
||||||
|
}
|
||||||
|
|
||||||
Vector3d qgoal(goal[0], goal[1], goal[2]);
|
Vector3d qgoal(goal[0], goal[1], goal[2]);
|
||||||
Vector3d qpolegoal(polegoal[0], polegoal[1], polegoal[2]);
|
Vector3d qpolegoal(polegoal[0], polegoal[1], polegoal[2]);
|
||||||
@ -353,8 +393,9 @@ void IK_SolverSetPoleVectorConstraint(IK_Solver *solver,
|
|||||||
|
|
||||||
float IK_SolverGetPoleAngle(IK_Solver *solver)
|
float IK_SolverGetPoleAngle(IK_Solver *solver)
|
||||||
{
|
{
|
||||||
if (solver == NULL)
|
if (solver == NULL) {
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||||
|
|
||||||
@ -384,8 +425,9 @@ static void IK_SolverAddCenterOfMass(IK_Solver *solver,
|
|||||||
|
|
||||||
int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations)
|
int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations)
|
||||||
{
|
{
|
||||||
if (solver == NULL)
|
if (solver == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
IK_QSolver *qsolver = (IK_QSolver *)solver;
|
||||||
|
|
||||||
@ -394,8 +436,9 @@ int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations)
|
|||||||
std::list<IK_QTask *> &tasks = qsolver->tasks;
|
std::list<IK_QTask *> &tasks = qsolver->tasks;
|
||||||
double tol = tolerance;
|
double tol = tolerance;
|
||||||
|
|
||||||
if (!jacobian.Setup(root, tasks))
|
if (!jacobian.Setup(root, tasks)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool result = jacobian.Solve(root, tasks, tol, max_iterations);
|
bool result = jacobian.Solve(root, tasks, tol, max_iterations);
|
||||||
|
|
||||||
|
@ -307,10 +307,10 @@ TEST(ArrayND, MultiplyElementsGeneric) {
|
|||||||
MultiplyElements(A, B, &C);
|
MultiplyElements(A, B, &C);
|
||||||
|
|
||||||
ArrayND<double, 5>::Index cIndex;
|
ArrayND<double, 5>::Index cIndex;
|
||||||
for (int d0 = 0; d0 < shape[0]; ++d0)
|
for (int d0 = 0; d0 < shape[0]; ++d0) {
|
||||||
for (int d1 = 0; d1 < shape[1]; ++d1)
|
for (int d1 = 0; d1 < shape[1]; ++d1) {
|
||||||
for (int d2 = 0; d2 < shape[2]; ++d2)
|
for (int d2 = 0; d2 < shape[2]; ++d2) {
|
||||||
for (int d3 = 0; d3 < shape[3]; ++d3)
|
for (int d3 = 0; d3 < shape[3]; ++d3) {
|
||||||
for (int d4 = 0; d4 < shape[4]; ++d4) {
|
for (int d4 = 0; d4 < shape[4]; ++d4) {
|
||||||
cIndex(0) = d0;
|
cIndex(0) = d0;
|
||||||
cIndex(1) = d1;
|
cIndex(1) = d1;
|
||||||
@ -319,6 +319,10 @@ TEST(ArrayND, MultiplyElementsGeneric) {
|
|||||||
cIndex(4) = d4;
|
cIndex(4) = d4;
|
||||||
EXPECT_EQ(2.2, C(cIndex));
|
EXPECT_EQ(2.2, C(cIndex));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -331,18 +331,21 @@ void LaplaceFilter(unsigned char* src,
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int strength) {
|
int strength) {
|
||||||
for (int y = 1; y < height - 1; y++)
|
for (int y = 1; y < height - 1; y++) {
|
||||||
for (int x = 1; x < width - 1; x++) {
|
for (int x = 1; x < width - 1; x++) {
|
||||||
const unsigned char* s = &src[y * width + x];
|
const unsigned char* s = &src[y * width + x];
|
||||||
int l = 128 + s[-width - 1] + s[-width] + s[-width + 1] + s[1] -
|
int l = 128 + s[-width - 1] + s[-width] + s[-width + 1] + s[1] -
|
||||||
8 * s[0] + s[1] + s[width - 1] + s[width] + s[width + 1];
|
8 * s[0] + s[1] + s[width - 1] + s[width] + s[width + 1];
|
||||||
int d = ((256 - strength) * s[0] + strength * l) / 256;
|
int d = ((256 - strength) * s[0] + strength * l) / 256;
|
||||||
if (d < 0)
|
if (d < 0) {
|
||||||
d = 0;
|
d = 0;
|
||||||
if (d > 255)
|
}
|
||||||
|
if (d > 255) {
|
||||||
d = 255;
|
d = 255;
|
||||||
|
}
|
||||||
dst[y * width + x] = d;
|
dst[y * width + x] = d;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace libmv
|
} // namespace libmv
|
||||||
|
@ -38,8 +38,9 @@ TEST(Tuple, InitFromPointer) {
|
|||||||
float vals[3] = {1.0f, 2.0f, 3.0f};
|
float vals[3] = {1.0f, 2.0f, 3.0f};
|
||||||
|
|
||||||
Tuple<float, 3> t(vals);
|
Tuple<float, 3> t(vals);
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++) {
|
||||||
EXPECT_EQ(t(i), vals[i]);
|
EXPECT_EQ(t(i), vals[i]);
|
||||||
|
}
|
||||||
|
|
||||||
Tuple<int, 3> b(t);
|
Tuple<int, 3> b(t);
|
||||||
EXPECT_EQ(b(0), int(vals[0]));
|
EXPECT_EQ(b(0), int(vals[0]));
|
||||||
|
@ -33,10 +33,12 @@ void PreconditionerFromPoints(const Mat& points, Mat3* T) {
|
|||||||
|
|
||||||
// If variance is equal to 0.0 set scaling factor to identity.
|
// If variance is equal to 0.0 set scaling factor to identity.
|
||||||
// -> Else it will provide nan value (because division by 0).
|
// -> Else it will provide nan value (because division by 0).
|
||||||
if (variance(0) < 1e-8)
|
if (variance(0) < 1e-8) {
|
||||||
xfactor = mean(0) = 1.0;
|
xfactor = mean(0) = 1.0;
|
||||||
if (variance(1) < 1e-8)
|
}
|
||||||
|
if (variance(1) < 1e-8) {
|
||||||
yfactor = mean(1) = 1.0;
|
yfactor = mean(1) = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
*T << xfactor, 0, -xfactor * mean(0),
|
*T << xfactor, 0, -xfactor * mean(0),
|
||||||
|
@ -63,8 +63,9 @@ TEST(Homography2DTest, Rotation45AndTranslationXY) {
|
|||||||
|
|
||||||
Mat x2 = x1;
|
Mat x2 = x1;
|
||||||
// Transform point from ground truth matrix
|
// Transform point from ground truth matrix
|
||||||
for (int i = 0; i < x2.cols(); ++i)
|
for (int i = 0; i < x2.cols(); ++i) {
|
||||||
x2.col(i) = m * x1.col(i);
|
x2.col(i) = m * x1.col(i);
|
||||||
|
}
|
||||||
|
|
||||||
Mat3 homography_mat;
|
Mat3 homography_mat;
|
||||||
EXPECT_TRUE(Homography2DFromCorrespondencesLinear(x1, x2, &homography_mat));
|
EXPECT_TRUE(Homography2DFromCorrespondencesLinear(x1, x2, &homography_mat));
|
||||||
@ -128,8 +129,9 @@ TEST(Homography2DTest, AffineGeneral5) {
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
Mat x2 = x1;
|
Mat x2 = x1;
|
||||||
for (int i = 0; i < x2.cols(); ++i)
|
for (int i = 0; i < x2.cols(); ++i) {
|
||||||
x2.col(i) = m * x1.col(i);
|
x2.col(i) = m * x1.col(i);
|
||||||
|
}
|
||||||
|
|
||||||
Mat3 homography_mat;
|
Mat3 homography_mat;
|
||||||
EXPECT_TRUE(Homography2DFromCorrespondencesLinear(x1, x2, &homography_mat));
|
EXPECT_TRUE(Homography2DFromCorrespondencesLinear(x1, x2, &homography_mat));
|
||||||
@ -165,8 +167,9 @@ TEST(Homography2DTest, HomographyGeneral) {
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
Mat x2 = x1;
|
Mat x2 = x1;
|
||||||
for (int i = 0; i < x2.cols(); ++i)
|
for (int i = 0; i < x2.cols(); ++i) {
|
||||||
x2.col(i) = m * x1.col(i);
|
x2.col(i) = m * x1.col(i);
|
||||||
|
}
|
||||||
|
|
||||||
Mat3 homography_mat;
|
Mat3 homography_mat;
|
||||||
EXPECT_TRUE(Homography2DFromCorrespondencesLinear(x1, x2, &homography_mat));
|
EXPECT_TRUE(Homography2DFromCorrespondencesLinear(x1, x2, &homography_mat));
|
||||||
|
@ -90,8 +90,9 @@ NViewDataSet NRealisticCamerasFull(int nviews,
|
|||||||
d.X *= 0.6;
|
d.X *= 0.6;
|
||||||
|
|
||||||
Vecu all_point_ids(npoints);
|
Vecu all_point_ids(npoints);
|
||||||
for (size_t j = 0; j < npoints; ++j)
|
for (size_t j = 0; j < npoints; ++j) {
|
||||||
all_point_ids[j] = j;
|
all_point_ids[j] = j;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < nviews; ++i) {
|
for (size_t i = 0; i < nviews; ++i) {
|
||||||
Vec3 camera_center, t, jitter, lookdir;
|
Vec3 camera_center, t, jitter, lookdir;
|
||||||
|
@ -221,31 +221,38 @@ void DetectMORAVEC(const FloatImage& grayscale_image,
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
score /= 256; // normalize
|
score /= 256; // normalize
|
||||||
if (pattern) // find only features similar to pattern
|
if (pattern) { // find only features similar to pattern
|
||||||
score -= SAD(s, pattern, stride, 16);
|
score -= SAD(s, pattern, stride, 16);
|
||||||
if (score <= 16)
|
}
|
||||||
|
if (score <= 16) {
|
||||||
continue; // filter very self-similar features
|
continue; // filter very self-similar features
|
||||||
|
}
|
||||||
score -= 16; // translate to score/histogram values
|
score -= 16; // translate to score/histogram values
|
||||||
if (score > 255)
|
if (score > 255) {
|
||||||
score = 255; // clip
|
score = 255; // clip
|
||||||
|
}
|
||||||
ubyte* c = &scores[y * width + x];
|
ubyte* c = &scores[y * width + x];
|
||||||
for (int i = -distance; i < 0; i++) {
|
for (int i = -distance; i < 0; i++) {
|
||||||
for (int j = -distance; j < distance; j++) {
|
for (int j = -distance; j < distance; j++) {
|
||||||
int s = c[i * width + j];
|
int s = c[i * width + j];
|
||||||
if (s == 0)
|
if (s == 0) {
|
||||||
continue;
|
continue;
|
||||||
if (s >= score)
|
}
|
||||||
|
if (s >= score) {
|
||||||
goto nonmax;
|
goto nonmax;
|
||||||
|
}
|
||||||
c[i * width + j] = 0;
|
c[i * width + j] = 0;
|
||||||
histogram[s]--;
|
histogram[s]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0, j = -distance; j < 0; j++) {
|
for (int i = 0, j = -distance; j < 0; j++) {
|
||||||
int s = c[i * width + j];
|
int s = c[i * width + j];
|
||||||
if (s == 0)
|
if (s == 0) {
|
||||||
continue;
|
continue;
|
||||||
if (s >= score)
|
}
|
||||||
|
if (s >= score) {
|
||||||
goto nonmax;
|
goto nonmax;
|
||||||
|
}
|
||||||
c[i * width + j] = 0;
|
c[i * width + j] = 0;
|
||||||
histogram[s]--;
|
histogram[s]--;
|
||||||
}
|
}
|
||||||
|
@ -184,8 +184,9 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks& _tracks,
|
|||||||
<< current_keyframe << " and " << candidate_image;
|
<< current_keyframe << " and " << candidate_image;
|
||||||
|
|
||||||
// Not enough points to construct fundamental matrix
|
// Not enough points to construct fundamental matrix
|
||||||
if (x1.cols() < 8 || x2.cols() < 8)
|
if (x1.cols() < 8 || x2.cols() < 8) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// STEP 1: Correspondence ratio constraint
|
// STEP 1: Correspondence ratio constraint
|
||||||
int Tc = tracked_markers.size();
|
int Tc = tracked_markers.size();
|
||||||
@ -195,8 +196,9 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks& _tracks,
|
|||||||
LG << "Correspondence between " << current_keyframe << " and "
|
LG << "Correspondence between " << current_keyframe << " and "
|
||||||
<< candidate_image << ": " << Rc;
|
<< candidate_image << ": " << Rc;
|
||||||
|
|
||||||
if (Rc < Tmin || Rc > Tmax)
|
if (Rc < Tmin || Rc > Tmax) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Mat3 H, F;
|
Mat3 H, F;
|
||||||
|
|
||||||
@ -246,8 +248,9 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks& _tracks,
|
|||||||
LG << "GRIC values for frames " << current_keyframe << " and "
|
LG << "GRIC values for frames " << current_keyframe << " and "
|
||||||
<< candidate_image << ", H-GRIC: " << GRIC_H << ", F-GRIC: " << GRIC_F;
|
<< candidate_image << ", H-GRIC: " << GRIC_H << ", F-GRIC: " << GRIC_F;
|
||||||
|
|
||||||
if (GRIC_H <= GRIC_F)
|
if (GRIC_H <= GRIC_F) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(sergey): STEP 4: PELC criterion
|
// TODO(sergey): STEP 4: PELC criterion
|
||||||
|
|
||||||
@ -386,8 +389,9 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks& _tracks,
|
|||||||
<< candidate_image << ": " << Sc;
|
<< candidate_image << ": " << Sc;
|
||||||
|
|
||||||
// Pairing with a lower Sc indicates a better choice
|
// Pairing with a lower Sc indicates a better choice
|
||||||
if (Sc > Sc_best_candidate)
|
if (Sc > Sc_best_candidate) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Sc_best_candidate = Sc;
|
Sc_best_candidate = Sc;
|
||||||
|
|
||||||
@ -405,8 +409,9 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks& _tracks,
|
|||||||
if (next_keyframe == -1) {
|
if (next_keyframe == -1) {
|
||||||
next_keyframe = current_keyframe + 10;
|
next_keyframe = current_keyframe + 10;
|
||||||
|
|
||||||
if (next_keyframe >= max_image)
|
if (next_keyframe >= max_image) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
LG << "Starting searching for keyframes starting from " << next_keyframe;
|
LG << "Starting searching for keyframes starting from " << next_keyframe;
|
||||||
} else {
|
} else {
|
||||||
|
@ -130,17 +130,18 @@ static void CompleteReconstructionLogProgress(
|
|||||||
if (update_callback) {
|
if (update_callback) {
|
||||||
char message[256];
|
char message[256];
|
||||||
|
|
||||||
if (step)
|
if (step) {
|
||||||
snprintf(message,
|
snprintf(message,
|
||||||
sizeof(message),
|
sizeof(message),
|
||||||
"Completing solution %d%% | %s",
|
"Completing solution %d%% | %s",
|
||||||
(int)(progress * 100),
|
(int)(progress * 100),
|
||||||
step);
|
step);
|
||||||
else
|
} else {
|
||||||
snprintf(message,
|
snprintf(message,
|
||||||
sizeof(message),
|
sizeof(message),
|
||||||
"Completing solution %d%%",
|
"Completing solution %d%%",
|
||||||
(int)(progress * 100));
|
(int)(progress * 100));
|
||||||
|
}
|
||||||
|
|
||||||
update_callback->invoke(progress, message);
|
update_callback->invoke(progress, message);
|
||||||
}
|
}
|
||||||
|
@ -117,8 +117,9 @@ bool EuclideanResect(const vector<Marker>& markers,
|
|||||||
LG << "No fallback; failing resection for " << markers[0].image;
|
LG << "No fallback; failing resection for " << markers[0].image;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!final_pass)
|
if (!final_pass) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
// Euclidean resection failed. Fall back to projective resection, which is
|
// Euclidean resection failed. Fall back to projective resection, which is
|
||||||
// less reliable but better conditioned when there are many points.
|
// less reliable but better conditioned when there are many points.
|
||||||
Mat34 P;
|
Mat34 P;
|
||||||
|
@ -77,9 +77,10 @@ vector<Marker> Tracks::MarkersInBothImages(int image1, int image2) const {
|
|||||||
vector<Marker> markers;
|
vector<Marker> markers;
|
||||||
for (int i = 0; i < markers_.size(); ++i) {
|
for (int i = 0; i < markers_.size(); ++i) {
|
||||||
int image = markers_[i].image;
|
int image = markers_[i].image;
|
||||||
if (image == image1 || image == image2)
|
if (image == image1 || image == image2) {
|
||||||
markers.push_back(markers_[i]);
|
markers.push_back(markers_[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return markers;
|
return markers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1595,11 +1595,12 @@ bool SamplePlanarPatch(const FloatImage& image,
|
|||||||
float mask_value =
|
float mask_value =
|
||||||
SampleLinear(*mask, image_position(1), image_position(0), 0);
|
SampleLinear(*mask, image_position(1), image_position(0), 0);
|
||||||
|
|
||||||
for (int d = 0; d < image.Depth(); d++)
|
for (int d = 0; d < image.Depth(); d++) {
|
||||||
(*patch)(r, c, d) *= mask_value;
|
(*patch)(r, c, d) *= mask_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Vec3 warped_position = canonical_homography.inverse() * Vec3(xs[4], ys[4], 1);
|
Vec3 warped_position = canonical_homography.inverse() * Vec3(xs[4], ys[4], 1);
|
||||||
warped_position /= warped_position(2);
|
warped_position /= warped_position(2);
|
||||||
|
@ -44,9 +44,10 @@ int MANTA::with_debug(0);
|
|||||||
MANTA::MANTA(int *res, FluidModifierData *fmd)
|
MANTA::MANTA(int *res, FluidModifierData *fmd)
|
||||||
: mCurrentID(++solverID), mMaxRes(fmd->domain->maxres)
|
: mCurrentID(++solverID), mMaxRes(fmd->domain->maxres)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "FLUID: " << mCurrentID << " with res(" << res[0] << ", " << res[1] << ", " << res[2]
|
cout << "FLUID: " << mCurrentID << " with res(" << res[0] << ", " << res[1] << ", " << res[2]
|
||||||
<< ")" << endl;
|
<< ")" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
FluidDomainSettings *fds = fmd->domain;
|
FluidDomainSettings *fds = fmd->domain;
|
||||||
fds->fluid = this;
|
fds->fluid = this;
|
||||||
@ -177,12 +178,15 @@ MANTA::MANTA(int *res, FluidModifierData *fmd)
|
|||||||
if (mUsingLiquid) {
|
if (mUsingLiquid) {
|
||||||
initSuccess &= initDomain();
|
initSuccess &= initDomain();
|
||||||
initSuccess &= initLiquid();
|
initSuccess &= initLiquid();
|
||||||
if (mUsingObstacle)
|
if (mUsingObstacle) {
|
||||||
initSuccess &= initObstacle();
|
initSuccess &= initObstacle();
|
||||||
if (mUsingInvel)
|
}
|
||||||
|
if (mUsingInvel) {
|
||||||
initSuccess &= initInVelocity();
|
initSuccess &= initInVelocity();
|
||||||
if (mUsingOutflow)
|
}
|
||||||
|
if (mUsingOutflow) {
|
||||||
initSuccess &= initOutflow();
|
initSuccess &= initOutflow();
|
||||||
|
}
|
||||||
|
|
||||||
if (mUsingDrops || mUsingBubbles || mUsingFloats || mUsingTracers) {
|
if (mUsingDrops || mUsingBubbles || mUsingFloats || mUsingTracers) {
|
||||||
mUpresParticle = fds->particle_scale;
|
mUpresParticle = fds->particle_scale;
|
||||||
@ -228,18 +232,24 @@ MANTA::MANTA(int *res, FluidModifierData *fmd)
|
|||||||
if (mUsingSmoke) {
|
if (mUsingSmoke) {
|
||||||
initSuccess &= initDomain();
|
initSuccess &= initDomain();
|
||||||
initSuccess &= initSmoke();
|
initSuccess &= initSmoke();
|
||||||
if (mUsingHeat)
|
if (mUsingHeat) {
|
||||||
initSuccess &= initHeat();
|
initSuccess &= initHeat();
|
||||||
if (mUsingFire)
|
}
|
||||||
|
if (mUsingFire) {
|
||||||
initSuccess &= initFire();
|
initSuccess &= initFire();
|
||||||
if (mUsingColors)
|
}
|
||||||
|
if (mUsingColors) {
|
||||||
initSuccess &= initColors();
|
initSuccess &= initColors();
|
||||||
if (mUsingObstacle)
|
}
|
||||||
|
if (mUsingObstacle) {
|
||||||
initSuccess &= initObstacle();
|
initSuccess &= initObstacle();
|
||||||
if (mUsingInvel)
|
}
|
||||||
|
if (mUsingInvel) {
|
||||||
initSuccess &= initInVelocity();
|
initSuccess &= initInVelocity();
|
||||||
if (mUsingOutflow)
|
}
|
||||||
|
if (mUsingOutflow) {
|
||||||
initSuccess &= initOutflow();
|
initSuccess &= initOutflow();
|
||||||
|
}
|
||||||
|
|
||||||
if (mUsingGuiding) {
|
if (mUsingGuiding) {
|
||||||
mResGuiding = (fds->guide_parent) ? fds->guide_res : fds->res;
|
mResGuiding = (fds->guide_parent) ? fds->guide_res : fds->res;
|
||||||
@ -256,12 +266,14 @@ MANTA::MANTA(int *res, FluidModifierData *fmd)
|
|||||||
/* Initialize Mantaflow variables in Python. */
|
/* Initialize Mantaflow variables in Python. */
|
||||||
initSuccess &= initNoise();
|
initSuccess &= initNoise();
|
||||||
initSuccess &= initSmokeNoise();
|
initSuccess &= initSmokeNoise();
|
||||||
if (mUsingFire)
|
if (mUsingFire) {
|
||||||
initSuccess &= initFireHigh();
|
initSuccess &= initFireHigh();
|
||||||
if (mUsingColors)
|
}
|
||||||
|
if (mUsingColors) {
|
||||||
initSuccess &= initColorsHigh();
|
initSuccess &= initColorsHigh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* All requested initializations must not fail in constructor. */
|
/* All requested initializations must not fail in constructor. */
|
||||||
BLI_assert(initSuccess);
|
BLI_assert(initSuccess);
|
||||||
(void)initSuccess; /* Ignored in release. */
|
(void)initSuccess; /* Ignored in release. */
|
||||||
@ -543,9 +555,10 @@ bool MANTA::initLiquidSndParts(FluidModifierData *fmd)
|
|||||||
|
|
||||||
MANTA::~MANTA()
|
MANTA::~MANTA()
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "~FLUID: " << mCurrentID << " with res(" << mResX << ", " << mResY << ", " << mResZ
|
cout << "~FLUID: " << mCurrentID << " with res(" << mResX << ", " << mResY << ", " << mResZ
|
||||||
<< ")" << endl;
|
<< ")" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
/* Destruction string for Python. */
|
/* Destruction string for Python. */
|
||||||
string tmpString = "";
|
string tmpString = "";
|
||||||
@ -689,8 +702,9 @@ bool MANTA::runPythonString(vector<string> commands)
|
|||||||
|
|
||||||
void MANTA::initializeMantaflow()
|
void MANTA::initializeMantaflow()
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "Fluid: Initializing Mantaflow framework" << endl;
|
cout << "Fluid: Initializing Mantaflow framework" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
string filename = "manta_scene_" + to_string(mCurrentID) + ".py";
|
string filename = "manta_scene_" + to_string(mCurrentID) + ".py";
|
||||||
vector<string> fill = vector<string>();
|
vector<string> fill = vector<string>();
|
||||||
@ -707,8 +721,9 @@ void MANTA::initializeMantaflow()
|
|||||||
|
|
||||||
void MANTA::terminateMantaflow()
|
void MANTA::terminateMantaflow()
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "Fluid: Releasing Mantaflow framework" << endl;
|
cout << "Fluid: Releasing Mantaflow framework" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||||
Pb::finalize(false); /* Namespace from Mantaflow (registry). */
|
Pb::finalize(false); /* Namespace from Mantaflow (registry). */
|
||||||
@ -718,8 +733,9 @@ void MANTA::terminateMantaflow()
|
|||||||
|
|
||||||
static string getCacheFileEnding(char cache_format)
|
static string getCacheFileEnding(char cache_format)
|
||||||
{
|
{
|
||||||
if (MANTA::with_debug)
|
if (MANTA::with_debug) {
|
||||||
cout << "MANTA::getCacheFileEnding()" << endl;
|
cout << "MANTA::getCacheFileEnding()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
switch (cache_format) {
|
switch (cache_format) {
|
||||||
case FLUID_DOMAIN_FILE_UNI:
|
case FLUID_DOMAIN_FILE_UNI:
|
||||||
@ -746,14 +762,16 @@ static string getBooleanString(int value)
|
|||||||
|
|
||||||
void MANTA::initializeRNAMap(FluidModifierData *fmd)
|
void MANTA::initializeRNAMap(FluidModifierData *fmd)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::initializeRNAMap()" << endl;
|
cout << "MANTA::initializeRNAMap()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
mRNAMap["ID"] = to_string(mCurrentID);
|
mRNAMap["ID"] = to_string(mCurrentID);
|
||||||
|
|
||||||
if (!fmd) {
|
if (!fmd) {
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "Fluid: No modifier data given in RNA map setup - returning early" << endl;
|
cout << "Fluid: No modifier data given in RNA map setup - returning early" << endl;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,39 +779,50 @@ void MANTA::initializeRNAMap(FluidModifierData *fmd)
|
|||||||
bool is2D = (fds->solver_res == 2);
|
bool is2D = (fds->solver_res == 2);
|
||||||
|
|
||||||
string borderCollisions = "";
|
string borderCollisions = "";
|
||||||
if ((fds->border_collisions & FLUID_DOMAIN_BORDER_LEFT) == 0)
|
if ((fds->border_collisions & FLUID_DOMAIN_BORDER_LEFT) == 0) {
|
||||||
borderCollisions += "x";
|
borderCollisions += "x";
|
||||||
if ((fds->border_collisions & FLUID_DOMAIN_BORDER_RIGHT) == 0)
|
}
|
||||||
|
if ((fds->border_collisions & FLUID_DOMAIN_BORDER_RIGHT) == 0) {
|
||||||
borderCollisions += "X";
|
borderCollisions += "X";
|
||||||
if ((fds->border_collisions & FLUID_DOMAIN_BORDER_FRONT) == 0)
|
}
|
||||||
|
if ((fds->border_collisions & FLUID_DOMAIN_BORDER_FRONT) == 0) {
|
||||||
borderCollisions += "y";
|
borderCollisions += "y";
|
||||||
if ((fds->border_collisions & FLUID_DOMAIN_BORDER_BACK) == 0)
|
}
|
||||||
|
if ((fds->border_collisions & FLUID_DOMAIN_BORDER_BACK) == 0) {
|
||||||
borderCollisions += "Y";
|
borderCollisions += "Y";
|
||||||
if ((fds->border_collisions & FLUID_DOMAIN_BORDER_BOTTOM) == 0)
|
}
|
||||||
|
if ((fds->border_collisions & FLUID_DOMAIN_BORDER_BOTTOM) == 0) {
|
||||||
borderCollisions += "z";
|
borderCollisions += "z";
|
||||||
if ((fds->border_collisions & FLUID_DOMAIN_BORDER_TOP) == 0)
|
}
|
||||||
|
if ((fds->border_collisions & FLUID_DOMAIN_BORDER_TOP) == 0) {
|
||||||
borderCollisions += "Z";
|
borderCollisions += "Z";
|
||||||
|
}
|
||||||
|
|
||||||
string particleTypesStr = "";
|
string particleTypesStr = "";
|
||||||
if (fds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY)
|
if (fds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) {
|
||||||
particleTypesStr += "PtypeSpray";
|
particleTypesStr += "PtypeSpray";
|
||||||
|
}
|
||||||
if (fds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) {
|
if (fds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) {
|
||||||
if (!particleTypesStr.empty())
|
if (!particleTypesStr.empty()) {
|
||||||
particleTypesStr += "|";
|
particleTypesStr += "|";
|
||||||
|
}
|
||||||
particleTypesStr += "PtypeBubble";
|
particleTypesStr += "PtypeBubble";
|
||||||
}
|
}
|
||||||
if (fds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) {
|
if (fds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) {
|
||||||
if (!particleTypesStr.empty())
|
if (!particleTypesStr.empty()) {
|
||||||
particleTypesStr += "|";
|
particleTypesStr += "|";
|
||||||
|
}
|
||||||
particleTypesStr += "PtypeFoam";
|
particleTypesStr += "PtypeFoam";
|
||||||
}
|
}
|
||||||
if (fds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) {
|
if (fds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) {
|
||||||
if (!particleTypesStr.empty())
|
if (!particleTypesStr.empty()) {
|
||||||
particleTypesStr += "|";
|
particleTypesStr += "|";
|
||||||
|
}
|
||||||
particleTypesStr += "PtypeTracer";
|
particleTypesStr += "PtypeTracer";
|
||||||
}
|
}
|
||||||
if (particleTypesStr.empty())
|
if (particleTypesStr.empty()) {
|
||||||
particleTypesStr = "0";
|
particleTypesStr = "0";
|
||||||
|
}
|
||||||
|
|
||||||
int particleTypes = (FLUID_DOMAIN_PARTICLE_SPRAY | FLUID_DOMAIN_PARTICLE_BUBBLE |
|
int particleTypes = (FLUID_DOMAIN_PARTICLE_SPRAY | FLUID_DOMAIN_PARTICLE_BUBBLE |
|
||||||
FLUID_DOMAIN_PARTICLE_FOAM | FLUID_DOMAIN_PARTICLE_TRACER);
|
FLUID_DOMAIN_PARTICLE_FOAM | FLUID_DOMAIN_PARTICLE_TRACER);
|
||||||
@ -804,20 +833,26 @@ void MANTA::initializeRNAMap(FluidModifierData *fmd)
|
|||||||
float domainSize = MAX3(fds->global_size[0], fds->global_size[1], fds->global_size[2]);
|
float domainSize = MAX3(fds->global_size[0], fds->global_size[1], fds->global_size[2]);
|
||||||
|
|
||||||
string vdbCompressionMethod = "Compression_None";
|
string vdbCompressionMethod = "Compression_None";
|
||||||
if (fds->openvdb_compression == VDB_COMPRESSION_NONE)
|
if (fds->openvdb_compression == VDB_COMPRESSION_NONE) {
|
||||||
vdbCompressionMethod = "Compression_None";
|
vdbCompressionMethod = "Compression_None";
|
||||||
else if (fds->openvdb_compression == VDB_COMPRESSION_ZIP)
|
}
|
||||||
|
else if (fds->openvdb_compression == VDB_COMPRESSION_ZIP) {
|
||||||
vdbCompressionMethod = "Compression_Zip";
|
vdbCompressionMethod = "Compression_Zip";
|
||||||
else if (fds->openvdb_compression == VDB_COMPRESSION_BLOSC)
|
}
|
||||||
|
else if (fds->openvdb_compression == VDB_COMPRESSION_BLOSC) {
|
||||||
vdbCompressionMethod = "Compression_Blosc";
|
vdbCompressionMethod = "Compression_Blosc";
|
||||||
|
}
|
||||||
|
|
||||||
string vdbPrecisionHalf = "Precision_Half";
|
string vdbPrecisionHalf = "Precision_Half";
|
||||||
if (fds->openvdb_data_depth == VDB_PRECISION_FULL_FLOAT)
|
if (fds->openvdb_data_depth == VDB_PRECISION_FULL_FLOAT) {
|
||||||
vdbPrecisionHalf = "Precision_Full";
|
vdbPrecisionHalf = "Precision_Full";
|
||||||
else if (fds->openvdb_data_depth == VDB_PRECISION_HALF_FLOAT)
|
}
|
||||||
|
else if (fds->openvdb_data_depth == VDB_PRECISION_HALF_FLOAT) {
|
||||||
vdbPrecisionHalf = "Precision_Half";
|
vdbPrecisionHalf = "Precision_Half";
|
||||||
else if (fds->openvdb_data_depth == VDB_PRECISION_MINI_FLOAT)
|
}
|
||||||
|
else if (fds->openvdb_data_depth == VDB_PRECISION_MINI_FLOAT) {
|
||||||
vdbPrecisionHalf = "Precision_Mini";
|
vdbPrecisionHalf = "Precision_Mini";
|
||||||
|
}
|
||||||
|
|
||||||
mRNAMap["USING_SMOKE"] = getBooleanString(fds->type == FLUID_DOMAIN_TYPE_GAS);
|
mRNAMap["USING_SMOKE"] = getBooleanString(fds->type == FLUID_DOMAIN_TYPE_GAS);
|
||||||
mRNAMap["USING_LIQUID"] = getBooleanString(fds->type == FLUID_DOMAIN_TYPE_LIQUID);
|
mRNAMap["USING_LIQUID"] = getBooleanString(fds->type == FLUID_DOMAIN_TYPE_LIQUID);
|
||||||
@ -1120,8 +1155,9 @@ string MANTA::getRealValue(const string &varName)
|
|||||||
|
|
||||||
string MANTA::parseLine(const string &line)
|
string MANTA::parseLine(const string &line)
|
||||||
{
|
{
|
||||||
if (line.size() == 0)
|
if (line.size() == 0) {
|
||||||
return "";
|
return "";
|
||||||
|
}
|
||||||
string res = "";
|
string res = "";
|
||||||
int currPos = 0, start_del = 0, end_del = -1;
|
int currPos = 0, start_del = 0, end_del = -1;
|
||||||
bool readingVar = false;
|
bool readingVar = false;
|
||||||
@ -1145,8 +1181,9 @@ string MANTA::parseLine(const string &line)
|
|||||||
|
|
||||||
string MANTA::parseScript(const string &setup_string, FluidModifierData *fmd)
|
string MANTA::parseScript(const string &setup_string, FluidModifierData *fmd)
|
||||||
{
|
{
|
||||||
if (MANTA::with_debug)
|
if (MANTA::with_debug) {
|
||||||
cout << "MANTA::parseScript()" << endl;
|
cout << "MANTA::parseScript()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
istringstream f(setup_string);
|
istringstream f(setup_string);
|
||||||
ostringstream res;
|
ostringstream res;
|
||||||
@ -1182,8 +1219,9 @@ static string escapePath(string const &s)
|
|||||||
|
|
||||||
bool MANTA::writeConfiguration(FluidModifierData *fmd, int framenr)
|
bool MANTA::writeConfiguration(FluidModifierData *fmd, int framenr)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::writeConfiguration()" << endl;
|
cout << "MANTA::writeConfiguration()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
FluidDomainSettings *fds = fmd->domain;
|
FluidDomainSettings *fds = fmd->domain;
|
||||||
|
|
||||||
@ -1223,8 +1261,9 @@ bool MANTA::writeConfiguration(FluidModifierData *fmd, int framenr)
|
|||||||
|
|
||||||
bool MANTA::writeData(FluidModifierData *fmd, int framenr)
|
bool MANTA::writeData(FluidModifierData *fmd, int framenr)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::writeData()" << endl;
|
cout << "MANTA::writeData()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
@ -1251,8 +1290,9 @@ bool MANTA::writeData(FluidModifierData *fmd, int framenr)
|
|||||||
|
|
||||||
bool MANTA::writeNoise(FluidModifierData *fmd, int framenr)
|
bool MANTA::writeNoise(FluidModifierData *fmd, int framenr)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::writeNoise()" << endl;
|
cout << "MANTA::writeNoise()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
@ -1273,8 +1313,9 @@ bool MANTA::writeNoise(FluidModifierData *fmd, int framenr)
|
|||||||
|
|
||||||
bool MANTA::readConfiguration(FluidModifierData *fmd, int framenr)
|
bool MANTA::readConfiguration(FluidModifierData *fmd, int framenr)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::readConfiguration()" << endl;
|
cout << "MANTA::readConfiguration()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
FluidDomainSettings *fds = fmd->domain;
|
FluidDomainSettings *fds = fmd->domain;
|
||||||
float dummy;
|
float dummy;
|
||||||
@ -1283,8 +1324,9 @@ bool MANTA::readConfiguration(FluidModifierData *fmd, int framenr)
|
|||||||
string format = FLUID_DOMAIN_EXTENSION_UNI;
|
string format = FLUID_DOMAIN_EXTENSION_UNI;
|
||||||
string file = getFile(fmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_NAME_CONFIG, format, framenr);
|
string file = getFile(fmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_NAME_CONFIG, format, framenr);
|
||||||
|
|
||||||
if (!hasConfig(fmd, framenr))
|
if (!hasConfig(fmd, framenr)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
gzFile gzf = (gzFile)BLI_gzopen(file.c_str(), "rb"); /* Do some compression. */
|
gzFile gzf = (gzFile)BLI_gzopen(file.c_str(), "rb"); /* Do some compression. */
|
||||||
if (!gzf) {
|
if (!gzf) {
|
||||||
@ -1316,11 +1358,13 @@ bool MANTA::readConfiguration(FluidModifierData *fmd, int framenr)
|
|||||||
|
|
||||||
bool MANTA::readData(FluidModifierData *fmd, int framenr, bool resumable)
|
bool MANTA::readData(FluidModifierData *fmd, int framenr, bool resumable)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::readData()" << endl;
|
cout << "MANTA::readData()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mUsingSmoke && !mUsingLiquid)
|
if (!mUsingSmoke && !mUsingLiquid) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
@ -1332,8 +1376,9 @@ bool MANTA::readData(FluidModifierData *fmd, int framenr, bool resumable)
|
|||||||
string resumable_cache = (!resumable) ? "False" : "True";
|
string resumable_cache = (!resumable) ? "False" : "True";
|
||||||
|
|
||||||
/* Sanity check: Are cache files present? */
|
/* Sanity check: Are cache files present? */
|
||||||
if (!hasData(fmd, framenr))
|
if (!hasData(fmd, framenr)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (mUsingSmoke) {
|
if (mUsingSmoke) {
|
||||||
ss.str("");
|
ss.str("");
|
||||||
@ -1356,11 +1401,13 @@ bool MANTA::readData(FluidModifierData *fmd, int framenr, bool resumable)
|
|||||||
|
|
||||||
bool MANTA::readNoise(FluidModifierData *fmd, int framenr, bool resumable)
|
bool MANTA::readNoise(FluidModifierData *fmd, int framenr, bool resumable)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::readNoise()" << endl;
|
cout << "MANTA::readNoise()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mUsingSmoke || !mUsingNoise)
|
if (!mUsingSmoke || !mUsingNoise) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
@ -1375,8 +1422,9 @@ bool MANTA::readNoise(FluidModifierData *fmd, int framenr, bool resumable)
|
|||||||
string volume_format = getCacheFileEnding(format);
|
string volume_format = getCacheFileEnding(format);
|
||||||
|
|
||||||
/* Sanity check: Are cache files present? */
|
/* Sanity check: Are cache files present? */
|
||||||
if (!hasNoise(fmd, framenr))
|
if (!hasNoise(fmd, framenr)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss << "smoke_load_noise_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
|
ss << "smoke_load_noise_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
|
||||||
@ -1388,11 +1436,13 @@ bool MANTA::readNoise(FluidModifierData *fmd, int framenr, bool resumable)
|
|||||||
|
|
||||||
bool MANTA::readMesh(FluidModifierData *fmd, int framenr)
|
bool MANTA::readMesh(FluidModifierData *fmd, int framenr)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::readMesh()" << endl;
|
cout << "MANTA::readMesh()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mUsingLiquid || !mUsingMesh)
|
if (!mUsingLiquid || !mUsingMesh) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
@ -1403,8 +1453,9 @@ bool MANTA::readMesh(FluidModifierData *fmd, int framenr)
|
|||||||
string volume_format = getCacheFileEnding(fds->cache_data_format);
|
string volume_format = getCacheFileEnding(fds->cache_data_format);
|
||||||
|
|
||||||
/* Sanity check: Are cache files present? */
|
/* Sanity check: Are cache files present? */
|
||||||
if (!hasMesh(fmd, framenr))
|
if (!hasMesh(fmd, framenr)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss << "liquid_load_mesh_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
|
ss << "liquid_load_mesh_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
|
||||||
@ -1423,13 +1474,16 @@ bool MANTA::readMesh(FluidModifierData *fmd, int framenr)
|
|||||||
|
|
||||||
bool MANTA::readParticles(FluidModifierData *fmd, int framenr, bool resumable)
|
bool MANTA::readParticles(FluidModifierData *fmd, int framenr, bool resumable)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::readParticles()" << endl;
|
cout << "MANTA::readParticles()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mUsingLiquid)
|
if (!mUsingLiquid) {
|
||||||
return false;
|
return false;
|
||||||
if (!mUsingDrops && !mUsingBubbles && !mUsingFloats && !mUsingTracers)
|
}
|
||||||
|
if (!mUsingDrops && !mUsingBubbles && !mUsingFloats && !mUsingTracers) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
@ -1444,8 +1498,9 @@ bool MANTA::readParticles(FluidModifierData *fmd, int framenr, bool resumable)
|
|||||||
string volume_format = getCacheFileEnding(format);
|
string volume_format = getCacheFileEnding(format);
|
||||||
|
|
||||||
/* Sanity check: Are cache files present? */
|
/* Sanity check: Are cache files present? */
|
||||||
if (!hasParticles(fmd, framenr))
|
if (!hasParticles(fmd, framenr)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss << "liquid_load_particles_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
|
ss << "liquid_load_particles_" << mCurrentID << "('" << escapePath(directory) << "', " << framenr
|
||||||
@ -1457,13 +1512,16 @@ bool MANTA::readParticles(FluidModifierData *fmd, int framenr, bool resumable)
|
|||||||
|
|
||||||
bool MANTA::readGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
|
bool MANTA::readGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::readGuiding()" << endl;
|
cout << "MANTA::readGuiding()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mUsingGuiding)
|
if (!mUsingGuiding) {
|
||||||
return false;
|
return false;
|
||||||
if (!fmd)
|
}
|
||||||
|
if (!fmd) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
@ -1474,8 +1532,9 @@ bool MANTA::readGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
|
|||||||
string volume_format = getCacheFileEnding(fds->cache_data_format);
|
string volume_format = getCacheFileEnding(fds->cache_data_format);
|
||||||
|
|
||||||
/* Sanity check: Are cache files present? */
|
/* Sanity check: Are cache files present? */
|
||||||
if (!hasGuiding(fmd, framenr, sourceDomain))
|
if (!hasGuiding(fmd, framenr, sourceDomain)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (sourceDomain) {
|
if (sourceDomain) {
|
||||||
ss.str("");
|
ss.str("");
|
||||||
@ -1494,8 +1553,9 @@ bool MANTA::readGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
|
|||||||
|
|
||||||
bool MANTA::bakeData(FluidModifierData *fmd, int framenr)
|
bool MANTA::bakeData(FluidModifierData *fmd, int framenr)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::bakeData()" << endl;
|
cout << "MANTA::bakeData()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
string tmpString, finalString;
|
string tmpString, finalString;
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
@ -1524,8 +1584,9 @@ bool MANTA::bakeData(FluidModifierData *fmd, int framenr)
|
|||||||
|
|
||||||
bool MANTA::bakeNoise(FluidModifierData *fmd, int framenr)
|
bool MANTA::bakeNoise(FluidModifierData *fmd, int framenr)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::bakeNoise()" << endl;
|
cout << "MANTA::bakeNoise()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
@ -1550,8 +1611,9 @@ bool MANTA::bakeNoise(FluidModifierData *fmd, int framenr)
|
|||||||
|
|
||||||
bool MANTA::bakeMesh(FluidModifierData *fmd, int framenr)
|
bool MANTA::bakeMesh(FluidModifierData *fmd, int framenr)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::bakeMesh()" << endl;
|
cout << "MANTA::bakeMesh()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
@ -1576,8 +1638,9 @@ bool MANTA::bakeMesh(FluidModifierData *fmd, int framenr)
|
|||||||
|
|
||||||
bool MANTA::bakeParticles(FluidModifierData *fmd, int framenr)
|
bool MANTA::bakeParticles(FluidModifierData *fmd, int framenr)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::bakeParticles()" << endl;
|
cout << "MANTA::bakeParticles()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
@ -1605,8 +1668,9 @@ bool MANTA::bakeParticles(FluidModifierData *fmd, int framenr)
|
|||||||
|
|
||||||
bool MANTA::bakeGuiding(FluidModifierData *fmd, int framenr)
|
bool MANTA::bakeGuiding(FluidModifierData *fmd, int framenr)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::bakeGuiding()" << endl;
|
cout << "MANTA::bakeGuiding()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
@ -1636,12 +1700,15 @@ bool MANTA::updateVariables(FluidModifierData *fmd)
|
|||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
|
|
||||||
tmpString += fluid_variables;
|
tmpString += fluid_variables;
|
||||||
if (mUsingSmoke)
|
if (mUsingSmoke) {
|
||||||
tmpString += smoke_variables;
|
tmpString += smoke_variables;
|
||||||
if (mUsingLiquid)
|
}
|
||||||
|
if (mUsingLiquid) {
|
||||||
tmpString += liquid_variables;
|
tmpString += liquid_variables;
|
||||||
if (mUsingGuiding)
|
}
|
||||||
|
if (mUsingGuiding) {
|
||||||
tmpString += fluid_variables_guiding;
|
tmpString += fluid_variables_guiding;
|
||||||
|
}
|
||||||
if (mUsingNoise) {
|
if (mUsingNoise) {
|
||||||
tmpString += fluid_variables_noise;
|
tmpString += fluid_variables_noise;
|
||||||
tmpString += smoke_variables_noise;
|
tmpString += smoke_variables_noise;
|
||||||
@ -1651,8 +1718,9 @@ bool MANTA::updateVariables(FluidModifierData *fmd)
|
|||||||
tmpString += fluid_variables_particles;
|
tmpString += fluid_variables_particles;
|
||||||
tmpString += liquid_variables_particles;
|
tmpString += liquid_variables_particles;
|
||||||
}
|
}
|
||||||
if (mUsingMesh)
|
if (mUsingMesh) {
|
||||||
tmpString += fluid_variables_mesh;
|
tmpString += fluid_variables_mesh;
|
||||||
|
}
|
||||||
|
|
||||||
finalString = parseScript(tmpString, fmd);
|
finalString = parseScript(tmpString, fmd);
|
||||||
pythonCommands.push_back(finalString);
|
pythonCommands.push_back(finalString);
|
||||||
@ -1662,8 +1730,9 @@ bool MANTA::updateVariables(FluidModifierData *fmd)
|
|||||||
|
|
||||||
bool MANTA::exportSmokeScript(FluidModifierData *fmd)
|
bool MANTA::exportSmokeScript(FluidModifierData *fmd)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::exportSmokeScript()" << endl;
|
cout << "MANTA::exportSmokeScript()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
char cacheDir[FILE_MAX] = "\0";
|
char cacheDir[FILE_MAX] = "\0";
|
||||||
char cacheDirScript[FILE_MAX] = "\0";
|
char cacheDirScript[FILE_MAX] = "\0";
|
||||||
@ -1696,53 +1765,68 @@ bool MANTA::exportSmokeScript(FluidModifierData *fmd)
|
|||||||
if (noise) {
|
if (noise) {
|
||||||
manta_script += fluid_variables_noise + smoke_variables_noise;
|
manta_script += fluid_variables_noise + smoke_variables_noise;
|
||||||
}
|
}
|
||||||
if (guiding)
|
if (guiding) {
|
||||||
manta_script += fluid_variables_guiding;
|
manta_script += fluid_variables_guiding;
|
||||||
|
}
|
||||||
|
|
||||||
/* Solvers. */
|
/* Solvers. */
|
||||||
manta_script += header_solvers + fluid_solver;
|
manta_script += header_solvers + fluid_solver;
|
||||||
if (noise)
|
if (noise) {
|
||||||
manta_script += fluid_solver_noise;
|
manta_script += fluid_solver_noise;
|
||||||
if (guiding)
|
}
|
||||||
|
if (guiding) {
|
||||||
manta_script += fluid_solver_guiding;
|
manta_script += fluid_solver_guiding;
|
||||||
|
}
|
||||||
|
|
||||||
/* Grids. */
|
/* Grids. */
|
||||||
manta_script += header_grids + fluid_alloc + smoke_alloc;
|
manta_script += header_grids + fluid_alloc + smoke_alloc;
|
||||||
if (noise) {
|
if (noise) {
|
||||||
manta_script += smoke_alloc_noise;
|
manta_script += smoke_alloc_noise;
|
||||||
if (colors)
|
if (colors) {
|
||||||
manta_script += smoke_alloc_colors_noise;
|
manta_script += smoke_alloc_colors_noise;
|
||||||
if (fire)
|
}
|
||||||
|
if (fire) {
|
||||||
manta_script += smoke_alloc_fire_noise;
|
manta_script += smoke_alloc_fire_noise;
|
||||||
}
|
}
|
||||||
if (heat)
|
}
|
||||||
|
if (heat) {
|
||||||
manta_script += smoke_alloc_heat;
|
manta_script += smoke_alloc_heat;
|
||||||
if (colors)
|
}
|
||||||
|
if (colors) {
|
||||||
manta_script += smoke_alloc_colors;
|
manta_script += smoke_alloc_colors;
|
||||||
if (fire)
|
}
|
||||||
|
if (fire) {
|
||||||
manta_script += smoke_alloc_fire;
|
manta_script += smoke_alloc_fire;
|
||||||
if (guiding)
|
}
|
||||||
|
if (guiding) {
|
||||||
manta_script += fluid_alloc_guiding;
|
manta_script += fluid_alloc_guiding;
|
||||||
if (obstacle)
|
}
|
||||||
|
if (obstacle) {
|
||||||
manta_script += fluid_alloc_obstacle;
|
manta_script += fluid_alloc_obstacle;
|
||||||
if (invel)
|
}
|
||||||
|
if (invel) {
|
||||||
manta_script += fluid_alloc_invel;
|
manta_script += fluid_alloc_invel;
|
||||||
if (outflow)
|
}
|
||||||
|
if (outflow) {
|
||||||
manta_script += fluid_alloc_outflow;
|
manta_script += fluid_alloc_outflow;
|
||||||
|
}
|
||||||
|
|
||||||
/* Noise field. */
|
/* Noise field. */
|
||||||
if (noise)
|
if (noise) {
|
||||||
manta_script += smoke_wavelet_noise;
|
manta_script += smoke_wavelet_noise;
|
||||||
|
}
|
||||||
|
|
||||||
/* Time. */
|
/* Time. */
|
||||||
manta_script += header_time + fluid_time_stepping + fluid_adapt_time_step;
|
manta_script += header_time + fluid_time_stepping + fluid_adapt_time_step;
|
||||||
|
|
||||||
/* Import. */
|
/* Import. */
|
||||||
manta_script += header_import + fluid_file_import + fluid_cache_helper + smoke_load_data;
|
manta_script += header_import + fluid_file_import + fluid_cache_helper + smoke_load_data;
|
||||||
if (noise)
|
if (noise) {
|
||||||
manta_script += smoke_load_noise;
|
manta_script += smoke_load_noise;
|
||||||
if (guiding)
|
}
|
||||||
|
if (guiding) {
|
||||||
manta_script += fluid_load_guiding;
|
manta_script += fluid_load_guiding;
|
||||||
|
}
|
||||||
|
|
||||||
/* Pre/Post Steps. */
|
/* Pre/Post Steps. */
|
||||||
manta_script += header_prepost + fluid_pre_step + fluid_post_step;
|
manta_script += header_prepost + fluid_pre_step + fluid_post_step;
|
||||||
@ -1773,8 +1857,9 @@ bool MANTA::exportSmokeScript(FluidModifierData *fmd)
|
|||||||
|
|
||||||
bool MANTA::exportLiquidScript(FluidModifierData *fmd)
|
bool MANTA::exportLiquidScript(FluidModifierData *fmd)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::exportLiquidScript()" << endl;
|
cout << "MANTA::exportLiquidScript()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
char cacheDir[FILE_MAX] = "\0";
|
char cacheDir[FILE_MAX] = "\0";
|
||||||
char cacheDirScript[FILE_MAX] = "\0";
|
char cacheDirScript[FILE_MAX] = "\0";
|
||||||
@ -1807,44 +1892,60 @@ bool MANTA::exportLiquidScript(FluidModifierData *fmd)
|
|||||||
|
|
||||||
/* Variables. */
|
/* Variables. */
|
||||||
manta_script += header_variables + fluid_variables + liquid_variables;
|
manta_script += header_variables + fluid_variables + liquid_variables;
|
||||||
if (mesh)
|
if (mesh) {
|
||||||
manta_script += fluid_variables_mesh;
|
manta_script += fluid_variables_mesh;
|
||||||
if (drops || bubble || floater || tracer)
|
}
|
||||||
|
if (drops || bubble || floater || tracer) {
|
||||||
manta_script += fluid_variables_particles + liquid_variables_particles;
|
manta_script += fluid_variables_particles + liquid_variables_particles;
|
||||||
if (guiding)
|
}
|
||||||
|
if (guiding) {
|
||||||
manta_script += fluid_variables_guiding;
|
manta_script += fluid_variables_guiding;
|
||||||
if (viscosity)
|
}
|
||||||
|
if (viscosity) {
|
||||||
manta_script += fluid_variables_viscosity;
|
manta_script += fluid_variables_viscosity;
|
||||||
|
}
|
||||||
|
|
||||||
/* Solvers. */
|
/* Solvers. */
|
||||||
manta_script += header_solvers + fluid_solver;
|
manta_script += header_solvers + fluid_solver;
|
||||||
if (mesh)
|
if (mesh) {
|
||||||
manta_script += fluid_solver_mesh;
|
manta_script += fluid_solver_mesh;
|
||||||
if (drops || bubble || floater || tracer)
|
}
|
||||||
|
if (drops || bubble || floater || tracer) {
|
||||||
manta_script += fluid_solver_particles;
|
manta_script += fluid_solver_particles;
|
||||||
if (guiding)
|
}
|
||||||
|
if (guiding) {
|
||||||
manta_script += fluid_solver_guiding;
|
manta_script += fluid_solver_guiding;
|
||||||
if (viscosity)
|
}
|
||||||
|
if (viscosity) {
|
||||||
manta_script += fluid_solver_viscosity;
|
manta_script += fluid_solver_viscosity;
|
||||||
|
}
|
||||||
|
|
||||||
/* Grids. */
|
/* Grids. */
|
||||||
manta_script += header_grids + fluid_alloc + liquid_alloc;
|
manta_script += header_grids + fluid_alloc + liquid_alloc;
|
||||||
if (mesh)
|
if (mesh) {
|
||||||
manta_script += liquid_alloc_mesh;
|
manta_script += liquid_alloc_mesh;
|
||||||
if (drops || bubble || floater || tracer)
|
}
|
||||||
|
if (drops || bubble || floater || tracer) {
|
||||||
manta_script += liquid_alloc_particles;
|
manta_script += liquid_alloc_particles;
|
||||||
if (guiding)
|
}
|
||||||
|
if (guiding) {
|
||||||
manta_script += fluid_alloc_guiding;
|
manta_script += fluid_alloc_guiding;
|
||||||
if (obstacle)
|
}
|
||||||
|
if (obstacle) {
|
||||||
manta_script += fluid_alloc_obstacle;
|
manta_script += fluid_alloc_obstacle;
|
||||||
if (fractions)
|
}
|
||||||
|
if (fractions) {
|
||||||
manta_script += fluid_alloc_fractions;
|
manta_script += fluid_alloc_fractions;
|
||||||
if (invel)
|
}
|
||||||
|
if (invel) {
|
||||||
manta_script += fluid_alloc_invel;
|
manta_script += fluid_alloc_invel;
|
||||||
if (outflow)
|
}
|
||||||
|
if (outflow) {
|
||||||
manta_script += fluid_alloc_outflow;
|
manta_script += fluid_alloc_outflow;
|
||||||
if (viscosity)
|
}
|
||||||
|
if (viscosity) {
|
||||||
manta_script += liquid_alloc_viscosity;
|
manta_script += liquid_alloc_viscosity;
|
||||||
|
}
|
||||||
|
|
||||||
/* Domain init. */
|
/* Domain init. */
|
||||||
manta_script += header_gridinit + liquid_init_phi;
|
manta_script += header_gridinit + liquid_init_phi;
|
||||||
@ -1854,22 +1955,27 @@ bool MANTA::exportLiquidScript(FluidModifierData *fmd)
|
|||||||
|
|
||||||
/* Import. */
|
/* Import. */
|
||||||
manta_script += header_import + fluid_file_import + fluid_cache_helper + liquid_load_data;
|
manta_script += header_import + fluid_file_import + fluid_cache_helper + liquid_load_data;
|
||||||
if (mesh)
|
if (mesh) {
|
||||||
manta_script += liquid_load_mesh;
|
manta_script += liquid_load_mesh;
|
||||||
if (drops || bubble || floater || tracer)
|
}
|
||||||
|
if (drops || bubble || floater || tracer) {
|
||||||
manta_script += liquid_load_particles;
|
manta_script += liquid_load_particles;
|
||||||
if (guiding)
|
}
|
||||||
|
if (guiding) {
|
||||||
manta_script += fluid_load_guiding;
|
manta_script += fluid_load_guiding;
|
||||||
|
}
|
||||||
|
|
||||||
/* Pre/Post Steps. */
|
/* Pre/Post Steps. */
|
||||||
manta_script += header_prepost + fluid_pre_step + fluid_post_step;
|
manta_script += header_prepost + fluid_pre_step + fluid_post_step;
|
||||||
|
|
||||||
/* Steps. */
|
/* Steps. */
|
||||||
manta_script += header_steps + liquid_adaptive_step + liquid_step;
|
manta_script += header_steps + liquid_adaptive_step + liquid_step;
|
||||||
if (mesh)
|
if (mesh) {
|
||||||
manta_script += liquid_step_mesh;
|
manta_script += liquid_step_mesh;
|
||||||
if (drops || bubble || floater || tracer)
|
}
|
||||||
|
if (drops || bubble || floater || tracer) {
|
||||||
manta_script += liquid_step_particles;
|
manta_script += liquid_step_particles;
|
||||||
|
}
|
||||||
|
|
||||||
/* Main. */
|
/* Main. */
|
||||||
manta_script += header_main + liquid_standalone + fluid_standalone;
|
manta_script += header_main + liquid_standalone + fluid_standalone;
|
||||||
@ -1899,9 +2005,10 @@ bool MANTA::exportLiquidScript(FluidModifierData *fmd)
|
|||||||
static PyObject *callPythonFunction(string varName, string functionName, bool isAttribute = false)
|
static PyObject *callPythonFunction(string varName, string functionName, bool isAttribute = false)
|
||||||
{
|
{
|
||||||
if ((varName == "") || (functionName == "")) {
|
if ((varName == "") || (functionName == "")) {
|
||||||
if (MANTA::with_debug)
|
if (MANTA::with_debug) {
|
||||||
cout << "Fluid: Missing Python variable name and/or function name -- name is: " << varName
|
cout << "Fluid: Missing Python variable name and/or function name -- name is: " << varName
|
||||||
<< ", function name is: " << functionName << endl;
|
<< ", function name is: " << functionName << endl;
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1950,8 +2057,9 @@ static PyObject *callPythonFunction(string varName, string functionName, bool is
|
|||||||
* If it's not function will handle the reference count decrement of that argument. */
|
* If it's not function will handle the reference count decrement of that argument. */
|
||||||
static void *pyObjectToPointer(PyObject *inputObject)
|
static void *pyObjectToPointer(PyObject *inputObject)
|
||||||
{
|
{
|
||||||
if (!inputObject)
|
if (!inputObject) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||||
|
|
||||||
@ -1975,8 +2083,9 @@ static void *pyObjectToPointer(PyObject *inputObject)
|
|||||||
* If it's not function will handle the reference count decrement of that argument. */
|
* If it's not function will handle the reference count decrement of that argument. */
|
||||||
static double pyObjectToDouble(PyObject *inputObject)
|
static double pyObjectToDouble(PyObject *inputObject)
|
||||||
{
|
{
|
||||||
if (!inputObject)
|
if (!inputObject) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||||
|
|
||||||
@ -1993,8 +2102,9 @@ static double pyObjectToDouble(PyObject *inputObject)
|
|||||||
* If it's not function will handle the reference count decrement of that argument. */
|
* If it's not function will handle the reference count decrement of that argument. */
|
||||||
static long pyObjectToLong(PyObject *inputObject)
|
static long pyObjectToLong(PyObject *inputObject)
|
||||||
{
|
{
|
||||||
if (!inputObject)
|
if (!inputObject) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||||
|
|
||||||
@ -2012,8 +2122,9 @@ template<class T> static T *getPointer(string pyObjectName, string pyFunctionNam
|
|||||||
|
|
||||||
int MANTA::getFrame()
|
int MANTA::getFrame()
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::getFrame()" << endl;
|
cout << "MANTA::getFrame()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
string func = "frame";
|
string func = "frame";
|
||||||
string id = to_string(mCurrentID);
|
string id = to_string(mCurrentID);
|
||||||
@ -2024,8 +2135,9 @@ int MANTA::getFrame()
|
|||||||
|
|
||||||
float MANTA::getTimestep()
|
float MANTA::getTimestep()
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::getTimestep()" << endl;
|
cout << "MANTA::getTimestep()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
string func = "timestep";
|
string func = "timestep";
|
||||||
string id = to_string(mCurrentID);
|
string id = to_string(mCurrentID);
|
||||||
@ -2044,8 +2156,9 @@ bool MANTA::needsRealloc(FluidModifierData *fmd)
|
|||||||
|
|
||||||
void MANTA::adaptTimestep()
|
void MANTA::adaptTimestep()
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::adaptTimestep()" << endl;
|
cout << "MANTA::adaptTimestep()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
vector<string> pythonCommands;
|
vector<string> pythonCommands;
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
@ -2058,8 +2171,9 @@ void MANTA::adaptTimestep()
|
|||||||
|
|
||||||
void MANTA::updatePointers(FluidModifierData *fmd, bool flush)
|
void MANTA::updatePointers(FluidModifierData *fmd, bool flush)
|
||||||
{
|
{
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "MANTA::updatePointers()" << endl;
|
cout << "MANTA::updatePointers()" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
FluidDomainSettings *fds = fmd->domain;
|
FluidDomainSettings *fds = fmd->domain;
|
||||||
|
|
||||||
@ -2214,8 +2328,9 @@ bool MANTA::hasData(FluidModifierData *fmd, int framenr)
|
|||||||
string filename = (mUsingSmoke) ? FLUID_NAME_DENSITY : FLUID_NAME_PP;
|
string filename = (mUsingSmoke) ? FLUID_NAME_DENSITY : FLUID_NAME_PP;
|
||||||
exists = BLI_exists(getFile(fmd, FLUID_DOMAIN_DIR_DATA, filename, extension, framenr).c_str());
|
exists = BLI_exists(getFile(fmd, FLUID_DOMAIN_DIR_DATA, filename, extension, framenr).c_str());
|
||||||
}
|
}
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "Fluid: Has Data: " << exists << endl;
|
cout << "Fluid: Has Data: " << exists << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
@ -2240,8 +2355,9 @@ bool MANTA::hasNoise(FluidModifierData *fmd, int framenr)
|
|||||||
getFile(fmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_DENSITY_NOISE, extension, framenr)
|
getFile(fmd, FLUID_DOMAIN_DIR_NOISE, FLUID_NAME_DENSITY_NOISE, extension, framenr)
|
||||||
.c_str());
|
.c_str());
|
||||||
}
|
}
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "Fluid: Has Noise: " << exists << endl;
|
cout << "Fluid: Has Noise: " << exists << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
@ -2257,8 +2373,9 @@ bool MANTA::hasMesh(FluidModifierData *fmd, int framenr)
|
|||||||
exists = BLI_exists(
|
exists = BLI_exists(
|
||||||
getFile(fmd, FLUID_DOMAIN_DIR_MESH, FLUID_NAME_LMESH, extension, framenr).c_str());
|
getFile(fmd, FLUID_DOMAIN_DIR_MESH, FLUID_NAME_LMESH, extension, framenr).c_str());
|
||||||
}
|
}
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "Fluid: Has Mesh: " << exists << endl;
|
cout << "Fluid: Has Mesh: " << exists << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
@ -2283,8 +2400,9 @@ bool MANTA::hasParticles(FluidModifierData *fmd, int framenr)
|
|||||||
getFile(fmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_NAME_PP_PARTICLES, extension, framenr)
|
getFile(fmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_NAME_PP_PARTICLES, extension, framenr)
|
||||||
.c_str());
|
.c_str());
|
||||||
}
|
}
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "Fluid: Has Particles: " << exists << endl;
|
cout << "Fluid: Has Particles: " << exists << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
@ -2302,8 +2420,9 @@ bool MANTA::hasGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
|
|||||||
exists = BLI_exists(getFile(fmd, subdirectory, filename, extension, framenr).c_str());
|
exists = BLI_exists(getFile(fmd, subdirectory, filename, extension, framenr).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (with_debug)
|
if (with_debug) {
|
||||||
cout << "Fluid: Has Guiding: " << exists << endl;
|
cout << "Fluid: Has Guiding: " << exists << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
|
@ -142,10 +142,12 @@ int FallbackImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr * /*config*/)
|
|||||||
const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * /*config*/,
|
const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * /*config*/,
|
||||||
int index)
|
int index)
|
||||||
{
|
{
|
||||||
if (index == 0)
|
if (index == 0) {
|
||||||
return "Linear";
|
return "Linear";
|
||||||
else if (index == 1)
|
}
|
||||||
|
else if (index == 1) {
|
||||||
return "sRGB";
|
return "sRGB";
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -153,24 +155,33 @@ const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *
|
|||||||
OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr * /*config*/,
|
OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr * /*config*/,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
if (strcmp(name, "scene_linear") == 0)
|
if (strcmp(name, "scene_linear") == 0) {
|
||||||
return COLORSPACE_LINEAR;
|
return COLORSPACE_LINEAR;
|
||||||
else if (strcmp(name, "color_picking") == 0)
|
}
|
||||||
|
else if (strcmp(name, "color_picking") == 0) {
|
||||||
return COLORSPACE_SRGB;
|
return COLORSPACE_SRGB;
|
||||||
else if (strcmp(name, "texture_paint") == 0)
|
}
|
||||||
|
else if (strcmp(name, "texture_paint") == 0) {
|
||||||
return COLORSPACE_LINEAR;
|
return COLORSPACE_LINEAR;
|
||||||
else if (strcmp(name, "default_byte") == 0)
|
}
|
||||||
|
else if (strcmp(name, "default_byte") == 0) {
|
||||||
return COLORSPACE_SRGB;
|
return COLORSPACE_SRGB;
|
||||||
else if (strcmp(name, "default_float") == 0)
|
}
|
||||||
|
else if (strcmp(name, "default_float") == 0) {
|
||||||
return COLORSPACE_LINEAR;
|
return COLORSPACE_LINEAR;
|
||||||
else if (strcmp(name, "default_sequencer") == 0)
|
}
|
||||||
|
else if (strcmp(name, "default_sequencer") == 0) {
|
||||||
return COLORSPACE_SRGB;
|
return COLORSPACE_SRGB;
|
||||||
else if (strcmp(name, "Linear") == 0)
|
}
|
||||||
|
else if (strcmp(name, "Linear") == 0) {
|
||||||
return COLORSPACE_LINEAR;
|
return COLORSPACE_LINEAR;
|
||||||
else if (strcmp(name, "sRGB") == 0)
|
}
|
||||||
|
else if (strcmp(name, "sRGB") == 0) {
|
||||||
return COLORSPACE_SRGB;
|
return COLORSPACE_SRGB;
|
||||||
else if (strcmp(name, "data") == 0)
|
}
|
||||||
|
else if (strcmp(name, "data") == 0) {
|
||||||
return COLORSPACE_DATA;
|
return COLORSPACE_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -368,12 +379,14 @@ void FallbackImpl::cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
|
|||||||
for (x = 0; x < width; x++) {
|
for (x = 0; x < width; x++) {
|
||||||
float *pixel = pixels + channels * (y * width + x);
|
float *pixel = pixels + channels * (y * width + x);
|
||||||
|
|
||||||
if (channels == 4)
|
if (channels == 4) {
|
||||||
cpuProcessorApplyRGBA(cpu_processor, pixel);
|
cpuProcessorApplyRGBA(cpu_processor, pixel);
|
||||||
else if (channels == 3)
|
}
|
||||||
|
else if (channels == 3) {
|
||||||
cpuProcessorApplyRGB(cpu_processor, pixel);
|
cpuProcessorApplyRGB(cpu_processor, pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FallbackImpl::cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
|
void FallbackImpl::cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
|
||||||
@ -391,12 +404,14 @@ void FallbackImpl::cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_
|
|||||||
for (x = 0; x < width; x++) {
|
for (x = 0; x < width; x++) {
|
||||||
float *pixel = pixels + channels * (y * width + x);
|
float *pixel = pixels + channels * (y * width + x);
|
||||||
|
|
||||||
if (channels == 4)
|
if (channels == 4) {
|
||||||
cpuProcessorApplyRGBA_predivide(cpu_processor, pixel);
|
cpuProcessorApplyRGBA_predivide(cpu_processor, pixel);
|
||||||
else if (channels == 3)
|
}
|
||||||
|
else if (channels == 3) {
|
||||||
cpuProcessorApplyRGB(cpu_processor, pixel);
|
cpuProcessorApplyRGB(cpu_processor, pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FallbackImpl::cpuProcessorApplyRGB(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
|
void FallbackImpl::cpuProcessorApplyRGB(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
|
||||||
|
@ -56,9 +56,10 @@ OCIO_ConstConfigRcPtr *OCIOImpl::getCurrentConfig(void)
|
|||||||
try {
|
try {
|
||||||
*config = GetCurrentConfig();
|
*config = GetCurrentConfig();
|
||||||
|
|
||||||
if (*config)
|
if (*config) {
|
||||||
return (OCIO_ConstConfigRcPtr *)config;
|
return (OCIO_ConstConfigRcPtr *)config;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception &exception) {
|
catch (Exception &exception) {
|
||||||
OCIO_reportException(exception);
|
OCIO_reportException(exception);
|
||||||
}
|
}
|
||||||
@ -85,9 +86,10 @@ OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(void)
|
|||||||
try {
|
try {
|
||||||
*config = Config::CreateFromEnv();
|
*config = Config::CreateFromEnv();
|
||||||
|
|
||||||
if (*config)
|
if (*config) {
|
||||||
return (OCIO_ConstConfigRcPtr *)config;
|
return (OCIO_ConstConfigRcPtr *)config;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception &exception) {
|
catch (Exception &exception) {
|
||||||
OCIO_reportException(exception);
|
OCIO_reportException(exception);
|
||||||
}
|
}
|
||||||
@ -104,9 +106,10 @@ OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromFile(const char *filename)
|
|||||||
try {
|
try {
|
||||||
*config = Config::CreateFromFile(filename);
|
*config = Config::CreateFromFile(filename);
|
||||||
|
|
||||||
if (*config)
|
if (*config) {
|
||||||
return (OCIO_ConstConfigRcPtr *)config;
|
return (OCIO_ConstConfigRcPtr *)config;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception &exception) {
|
catch (Exception &exception) {
|
||||||
OCIO_reportException(exception);
|
OCIO_reportException(exception);
|
||||||
}
|
}
|
||||||
@ -153,9 +156,10 @@ OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *
|
|||||||
try {
|
try {
|
||||||
*cs = (*(ConstConfigRcPtr *)config)->getColorSpace(name);
|
*cs = (*(ConstConfigRcPtr *)config)->getColorSpace(name);
|
||||||
|
|
||||||
if (*cs)
|
if (*cs) {
|
||||||
return (OCIO_ConstColorSpaceRcPtr *)cs;
|
return (OCIO_ConstColorSpaceRcPtr *)cs;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception &exception) {
|
catch (Exception &exception) {
|
||||||
OCIO_reportException(exception);
|
OCIO_reportException(exception);
|
||||||
}
|
}
|
||||||
@ -372,9 +376,10 @@ OCIO_ConstLookRcPtr *OCIOImpl::configGetLook(OCIO_ConstConfigRcPtr *config, cons
|
|||||||
try {
|
try {
|
||||||
*look = (*(ConstConfigRcPtr *)config)->getLook(name);
|
*look = (*(ConstConfigRcPtr *)config)->getLook(name);
|
||||||
|
|
||||||
if (*look)
|
if (*look) {
|
||||||
return (OCIO_ConstLookRcPtr *)look;
|
return (OCIO_ConstLookRcPtr *)look;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception &exception) {
|
catch (Exception &exception) {
|
||||||
OCIO_reportException(exception);
|
OCIO_reportException(exception);
|
||||||
}
|
}
|
||||||
@ -522,9 +527,10 @@ OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfig
|
|||||||
try {
|
try {
|
||||||
*processor = (*(ConstConfigRcPtr *)config)->getProcessor(srcName, dstName);
|
*processor = (*(ConstConfigRcPtr *)config)->getProcessor(srcName, dstName);
|
||||||
|
|
||||||
if (*processor)
|
if (*processor) {
|
||||||
return (OCIO_ConstProcessorRcPtr *)processor;
|
return (OCIO_ConstProcessorRcPtr *)processor;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception &exception) {
|
catch (Exception &exception) {
|
||||||
OCIO_reportException(exception);
|
OCIO_reportException(exception);
|
||||||
}
|
}
|
||||||
@ -738,9 +744,10 @@ OCIO_ConstProcessorRcPtr *OCIOImpl::createDisplayProcessor(OCIO_ConstConfigRcPtr
|
|||||||
try {
|
try {
|
||||||
*p = config->getProcessor(group);
|
*p = config->getProcessor(group);
|
||||||
|
|
||||||
if (*p)
|
if (*p) {
|
||||||
return (OCIO_ConstProcessorRcPtr *)p;
|
return (OCIO_ConstProcessorRcPtr *)p;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception &exception) {
|
catch (Exception &exception) {
|
||||||
OCIO_reportException(exception);
|
OCIO_reportException(exception);
|
||||||
}
|
}
|
||||||
|
@ -110,24 +110,33 @@ GLStencilTableSSBO::GLStencilTableSSBO(LimitStencilTable const *limitStencilTabl
|
|||||||
|
|
||||||
GLStencilTableSSBO::~GLStencilTableSSBO()
|
GLStencilTableSSBO::~GLStencilTableSSBO()
|
||||||
{
|
{
|
||||||
if (_sizes)
|
if (_sizes) {
|
||||||
glDeleteBuffers(1, &_sizes);
|
glDeleteBuffers(1, &_sizes);
|
||||||
if (_offsets)
|
}
|
||||||
|
if (_offsets) {
|
||||||
glDeleteBuffers(1, &_offsets);
|
glDeleteBuffers(1, &_offsets);
|
||||||
if (_indices)
|
}
|
||||||
|
if (_indices) {
|
||||||
glDeleteBuffers(1, &_indices);
|
glDeleteBuffers(1, &_indices);
|
||||||
if (_weights)
|
}
|
||||||
|
if (_weights) {
|
||||||
glDeleteBuffers(1, &_weights);
|
glDeleteBuffers(1, &_weights);
|
||||||
if (_duWeights)
|
}
|
||||||
|
if (_duWeights) {
|
||||||
glDeleteBuffers(1, &_duWeights);
|
glDeleteBuffers(1, &_duWeights);
|
||||||
if (_dvWeights)
|
}
|
||||||
|
if (_dvWeights) {
|
||||||
glDeleteBuffers(1, &_dvWeights);
|
glDeleteBuffers(1, &_dvWeights);
|
||||||
if (_duuWeights)
|
}
|
||||||
|
if (_duuWeights) {
|
||||||
glDeleteBuffers(1, &_duuWeights);
|
glDeleteBuffers(1, &_duuWeights);
|
||||||
if (_duvWeights)
|
}
|
||||||
|
if (_duvWeights) {
|
||||||
glDeleteBuffers(1, &_duvWeights);
|
glDeleteBuffers(1, &_duvWeights);
|
||||||
if (_dvvWeights)
|
}
|
||||||
|
if (_dvvWeights) {
|
||||||
glDeleteBuffers(1, &_dvvWeights);
|
glDeleteBuffers(1, &_dvvWeights);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -363,8 +372,9 @@ bool GLComputeEvaluator::EvalStencils(GLuint srcBuffer,
|
|||||||
int end) const
|
int end) const
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!_stencilKernel.program)
|
if (!_stencilKernel.program) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
int count = end - start;
|
int count = end - start;
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
return true;
|
return true;
|
||||||
@ -381,16 +391,21 @@ bool GLComputeEvaluator::EvalStencils(GLuint srcBuffer,
|
|||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, offsetsBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, offsetsBuffer);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, indicesBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, indicesBuffer);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, weightsBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, weightsBuffer);
|
||||||
if (duWeightsBuffer)
|
if (duWeightsBuffer) {
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 8, duWeightsBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 8, duWeightsBuffer);
|
||||||
if (dvWeightsBuffer)
|
}
|
||||||
|
if (dvWeightsBuffer) {
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 9, dvWeightsBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 9, dvWeightsBuffer);
|
||||||
if (duuWeightsBuffer)
|
}
|
||||||
|
if (duuWeightsBuffer) {
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 13, duuWeightsBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 13, duuWeightsBuffer);
|
||||||
if (duvWeightsBuffer)
|
}
|
||||||
|
if (duvWeightsBuffer) {
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 14, duvWeightsBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 14, duvWeightsBuffer);
|
||||||
if (dvvWeightsBuffer)
|
}
|
||||||
|
if (dvvWeightsBuffer) {
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 15, dvvWeightsBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 15, dvvWeightsBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
GLint activeProgram;
|
GLint activeProgram;
|
||||||
glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
|
glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
|
||||||
@ -485,8 +500,9 @@ bool GLComputeEvaluator::EvalPatches(GLuint srcBuffer,
|
|||||||
GLuint patchParamsBuffer) const
|
GLuint patchParamsBuffer) const
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!_patchKernel.program)
|
if (!_patchKernel.program) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, srcBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, srcBuffer);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, dstBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, dstBuffer);
|
||||||
@ -578,8 +594,9 @@ bool GLComputeEvaluator::_StencilKernel::Compile(BufferDescriptor const &srcDesc
|
|||||||
|
|
||||||
program = compileKernel(
|
program = compileKernel(
|
||||||
srcDesc, dstDesc, duDesc, dvDesc, duuDesc, duvDesc, dvvDesc, kernelDefine, workGroupSize);
|
srcDesc, dstDesc, duDesc, dvDesc, duuDesc, duvDesc, dvvDesc, kernelDefine, workGroupSize);
|
||||||
if (program == 0)
|
if (program == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// cache uniform locations (TODO: use uniform block)
|
// cache uniform locations (TODO: use uniform block)
|
||||||
uniformStart = glGetUniformLocation(program, "batchStart");
|
uniformStart = glGetUniformLocation(program, "batchStart");
|
||||||
@ -623,8 +640,9 @@ bool GLComputeEvaluator::_PatchKernel::Compile(BufferDescriptor const &srcDesc,
|
|||||||
|
|
||||||
program = compileKernel(
|
program = compileKernel(
|
||||||
srcDesc, dstDesc, duDesc, dvDesc, duuDesc, duvDesc, dvvDesc, kernelDefine, workGroupSize);
|
srcDesc, dstDesc, duDesc, dvDesc, duuDesc, duvDesc, dvvDesc, kernelDefine, workGroupSize);
|
||||||
if (program == 0)
|
if (program == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// cache uniform locations
|
// cache uniform locations
|
||||||
uniformSrcOffset = glGetUniformLocation(program, "srcOffset");
|
uniformSrcOffset = glGetUniformLocation(program, "srcOffset");
|
||||||
|
Loading…
Reference in New Issue
Block a user