Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenloader/intern/versioning_cycles.c
| Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
| #include "readfile.h" | #include "readfile.h" | ||||
| static float *cycles_node_socket_float_value(bNodeSocket *socket) | static float *cycles_node_socket_float_value(bNodeSocket *socket) | ||||
| { | { | ||||
| bNodeSocketValueFloat *socket_data = socket->default_value; | bNodeSocketValueFloat *socket_data = socket->default_value; | ||||
| return &socket_data->value; | return &socket_data->value; | ||||
| } | } | ||||
| static float *cycles_node_socket_rgba_value(bNodeSocket *socket) | |||||
| { | |||||
| bNodeSocketValueRGBA *socket_data = socket->default_value; | |||||
| return socket_data->value; | |||||
| } | |||||
| static IDProperty *cycles_properties_from_ID(ID *id) | static IDProperty *cycles_properties_from_ID(ID *id) | ||||
| { | { | ||||
| IDProperty *idprop = IDP_GetProperties(id, false); | IDProperty *idprop = IDP_GetProperties(id, false); | ||||
| return (idprop) ? IDP_GetPropertyTypeFromGroup(idprop, "cycles", IDP_GROUP) : NULL; | return (idprop) ? IDP_GetPropertyTypeFromGroup(idprop, "cycles", IDP_GROUP) : NULL; | ||||
| } | } | ||||
| static float cycles_property_float(IDProperty *idprop, const char *name, float default_value) | static float cycles_property_float(IDProperty *idprop, const char *name, float default_value) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 199 Lines • ▼ Show 20 Lines | for (bNodeLink *link = ntree->links.last; link; link = prevlink) { | ||||
| need_update = true; | need_update = true; | ||||
| } | } | ||||
| if (need_update) { | if (need_update) { | ||||
| ntreeUpdateTree(NULL, ntree); | ntreeUpdateTree(NULL, ntree); | ||||
| } | } | ||||
| } | } | ||||
| static void light_emission_node_to_energy(Light *light, float *energy, float color[3]) | |||||
| { | |||||
| *energy = 1.0; | |||||
| copy_v3_fl(color, 1.0f); | |||||
| /* If nodetree has animation or drivers, don't try to convert. */ | |||||
| bNodeTree *ntree = light->nodetree; | |||||
| if (ntree == NULL || ntree->adt) { | |||||
| return; | |||||
| } | |||||
| /* Find emission node */ | |||||
| bNode *output_node = ntreeShaderOutputNode(ntree, SHD_OUTPUT_CYCLES); | |||||
| if (output_node == NULL) { | |||||
| return; | |||||
| } | |||||
| bNode *emission_node = NULL; | |||||
| for (bNodeLink *link = ntree->links.first; link; link = link->next) { | |||||
| if (link->tonode == output_node && link->fromnode->type == SH_NODE_EMISSION) { | |||||
| emission_node = link->fromnode; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (emission_node == NULL) { | |||||
| return; | |||||
| } | |||||
| /* Don't convert if anything is linked */ | |||||
| bNodeSocket *strength_socket = nodeFindSocket(emission_node, SOCK_IN, "Strength"); | |||||
| bNodeSocket *color_socket = nodeFindSocket(emission_node, SOCK_IN, "Color"); | |||||
| if ((strength_socket->flag & SOCK_IN_USE) || (color_socket->flag & SOCK_IN_USE)) { | |||||
| return; | |||||
| } | |||||
| float *strength_value = cycles_node_socket_float_value(strength_socket); | |||||
| float *color_value = cycles_node_socket_rgba_value(color_socket); | |||||
| *energy = *strength_value; | |||||
| copy_v3_v3(color, color_value); | |||||
| *strength_value = 1.0f; | |||||
| copy_v4_fl(color_value, 1.0f); | |||||
| light->use_nodes = false; | |||||
| } | |||||
| static void light_emission_unify(Light *light, const char *engine) | |||||
| { | |||||
| if (light->type != LA_SUN) { | |||||
| light->energy *= 100.0f; | |||||
| } | |||||
| /* Attempt to extract constant energy and color from nodes. */ | |||||
| bool use_nodes = light->use_nodes; | |||||
| float energy, color[3]; | |||||
| light_emission_node_to_energy(light, &energy, color); | |||||
| if (STREQ(engine, "CYCLES")) { | |||||
| if (use_nodes) { | |||||
| /* Energy extracted from nodes */ | |||||
| light->energy = energy; | |||||
| copy_v3_v3(&light->r, color); | |||||
| } | |||||
| else { | |||||
| /* Default cycles multipliers if there are no nodes */ | |||||
| if (light->type == LA_SUN) { | |||||
| light->energy = 1.0f; | |||||
| } | |||||
| else { | |||||
| light->energy = 100.0f; | |||||
| } | |||||
| } | |||||
| } | |||||
| else { | |||||
| /* Disable nodes if scene was configured for Eevee */ | |||||
| light->use_nodes = false; | |||||
| } | |||||
| } | |||||
| void blo_do_versions_cycles(FileData *UNUSED(fd), Library *UNUSED(lib), Main *bmain) | void blo_do_versions_cycles(FileData *UNUSED(fd), Library *UNUSED(lib), Main *bmain) | ||||
| { | { | ||||
| /* Particle shape shared with Eevee. */ | /* Particle shape shared with Eevee. */ | ||||
| if (!MAIN_VERSION_ATLEAST(bmain, 280, 16)) { | if (!MAIN_VERSION_ATLEAST(bmain, 280, 16)) { | ||||
| for (ParticleSettings *part = bmain->particles.first; part; part = part->id.next) { | for (ParticleSettings *part = bmain->particles.first; part; part = part->id.next) { | ||||
| IDProperty *cpart = cycles_properties_from_ID(&part->id); | IDProperty *cpart = cycles_properties_from_ID(&part->id); | ||||
| if (cpart) { | if (cpart) { | ||||
| ▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | FOREACH_NODETREE_BEGIN (bmain, ntree, id) { | ||||
| } | } | ||||
| if (!MAIN_VERSION_ATLEAST(bmain, 279, 5)) { | if (!MAIN_VERSION_ATLEAST(bmain, 279, 5)) { | ||||
| ambient_occlusion_node_relink(ntree); | ambient_occlusion_node_relink(ntree); | ||||
| } | } | ||||
| } | } | ||||
| FOREACH_NODETREE_END; | FOREACH_NODETREE_END; | ||||
| } | } | ||||
| if (!MAIN_VERSION_ATLEAST(bmain, 280, 60)) { | |||||
| /* Unfiy Cycles and Eevee settings. */ | |||||
| /* TODO: weak */ | |||||
| Scene *scene = bmain->scenes.first; | |||||
| const char *engine = (scene) ? scene->r.engine : "CYCLES"; | |||||
| for (Light *light = bmain->lights.first; light; light = light->id.next) { | |||||
| light_emission_unify(light, engine); | |||||
| } | |||||
| } | |||||
| } | } | ||||