Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "light.h" 00020 #include "mesh.h" 00021 #include "object.h" 00022 #include "scene.h" 00023 00024 #include "blender_sync.h" 00025 #include "blender_util.h" 00026 00027 #include "util_foreach.h" 00028 00029 CCL_NAMESPACE_BEGIN 00030 00031 /* Utilities */ 00032 00033 bool BlenderSync::object_is_modified(BL::Object b_ob) 00034 { 00035 /* test if we can instance or if the object is modified */ 00036 if(ccl::object_is_modified(b_ob, b_scene, preview)) { 00037 /* modifiers */ 00038 return true; 00039 } 00040 else { 00041 /* object level material links */ 00042 BL::Object::material_slots_iterator slot; 00043 for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) 00044 if(slot->link() == BL::MaterialSlot::link_OBJECT) 00045 return true; 00046 } 00047 00048 return false; 00049 } 00050 00051 bool BlenderSync::object_is_mesh(BL::Object b_ob) 00052 { 00053 BL::ID b_ob_data = b_ob.data(); 00054 00055 return (b_ob_data && (b_ob_data.is_a(&RNA_Mesh) || 00056 b_ob_data.is_a(&RNA_Curve) || b_ob_data.is_a(&RNA_MetaBall))); 00057 } 00058 00059 bool BlenderSync::object_is_light(BL::Object b_ob) 00060 { 00061 BL::ID b_ob_data = b_ob.data(); 00062 00063 return (b_ob_data && b_ob_data.is_a(&RNA_Lamp)); 00064 } 00065 00066 static uint object_ray_visibility(BL::Object b_ob) 00067 { 00068 PointerRNA cvisibility = RNA_pointer_get(&b_ob.ptr, "cycles_visibility"); 00069 uint flag = 0; 00070 00071 flag |= get_boolean(cvisibility, "camera")? PATH_RAY_CAMERA: 0; 00072 flag |= get_boolean(cvisibility, "diffuse")? PATH_RAY_DIFFUSE: 0; 00073 flag |= get_boolean(cvisibility, "glossy")? PATH_RAY_GLOSSY: 0; 00074 flag |= get_boolean(cvisibility, "transmission")? PATH_RAY_TRANSMIT: 0; 00075 flag |= get_boolean(cvisibility, "shadow")? PATH_RAY_SHADOW: 0; 00076 00077 return flag; 00078 } 00079 00080 /* Light */ 00081 00082 void BlenderSync::sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm) 00083 { 00084 /* test if we need to sync */ 00085 Light *light; 00086 ObjectKey key(b_parent, b_index, b_ob); 00087 00088 if(!light_map.sync(&light, b_ob, b_parent, key)) 00089 return; 00090 00091 BL::Lamp b_lamp(b_ob.data()); 00092 00093 /* type */ 00094 switch(b_lamp.type()) { 00095 case BL::Lamp::type_POINT: { 00096 BL::PointLamp b_point_lamp(b_lamp); 00097 light->size = b_point_lamp.shadow_soft_size(); 00098 light->type = LIGHT_POINT; 00099 break; 00100 } 00101 case BL::Lamp::type_SPOT: { 00102 BL::SpotLamp b_spot_lamp(b_lamp); 00103 light->size = b_spot_lamp.shadow_soft_size(); 00104 light->type = LIGHT_POINT; 00105 break; 00106 } 00107 case BL::Lamp::type_HEMI: { 00108 light->type = LIGHT_DISTANT; 00109 light->size = 0.0f; 00110 break; 00111 } 00112 case BL::Lamp::type_SUN: { 00113 BL::SunLamp b_sun_lamp(b_lamp); 00114 light->size = b_sun_lamp.shadow_soft_size(); 00115 light->type = LIGHT_DISTANT; 00116 break; 00117 } 00118 case BL::Lamp::type_AREA: { 00119 BL::AreaLamp b_area_lamp(b_lamp); 00120 light->size = 1.0f; 00121 light->axisu = make_float3(tfm.x.x, tfm.y.x, tfm.z.x); 00122 light->axisv = make_float3(tfm.x.y, tfm.y.y, tfm.z.y); 00123 light->sizeu = b_area_lamp.size(); 00124 if(b_area_lamp.shape() == BL::AreaLamp::shape_RECTANGLE) 00125 light->sizev = b_area_lamp.size_y(); 00126 else 00127 light->sizev = light->sizeu; 00128 light->type = LIGHT_AREA; 00129 break; 00130 } 00131 } 00132 00133 /* location and (inverted!) direction */ 00134 light->co = make_float3(tfm.x.w, tfm.y.w, tfm.z.w); 00135 light->dir = -make_float3(tfm.x.z, tfm.y.z, tfm.z.z); 00136 00137 /* shader */ 00138 vector<uint> used_shaders; 00139 00140 find_shader(b_lamp, used_shaders, scene->default_light); 00141 00142 if(used_shaders.size() == 0) 00143 used_shaders.push_back(scene->default_light); 00144 00145 light->shader = used_shaders[0]; 00146 00147 /* shadow */ 00148 PointerRNA clamp = RNA_pointer_get(&b_lamp.ptr, "cycles"); 00149 light->cast_shadow = get_boolean(clamp, "cast_shadow"); 00150 00151 /* tag */ 00152 light->tag_update(scene); 00153 } 00154 00155 /* Object */ 00156 00157 void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag) 00158 { 00159 /* light is handled separately */ 00160 if(object_is_light(b_ob)) { 00161 sync_light(b_parent, b_index, b_ob, tfm); 00162 return; 00163 } 00164 00165 /* only interested in object that we can create meshes from */ 00166 if(!object_is_mesh(b_ob)) 00167 return; 00168 00169 /* test if we need to sync */ 00170 ObjectKey key(b_parent, b_index, b_ob); 00171 Object *object; 00172 bool object_updated = false; 00173 00174 if(object_map.sync(&object, b_ob, b_parent, key)) 00175 object_updated = true; 00176 00177 /* mesh sync */ 00178 object->mesh = sync_mesh(b_ob, object_updated); 00179 00180 /* object sync */ 00181 if(object_updated || (object->mesh && object->mesh->need_update)) { 00182 object->name = b_ob.name().c_str(); 00183 object->tfm = tfm; 00184 00185 /* visibility flags for both parent */ 00186 object->visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL; 00187 if(b_parent.ptr.data != b_ob.ptr.data) 00188 object->visibility &= object_ray_visibility(b_parent); 00189 00190 /* camera flag is not actually used, instead is tested 00191 against render layer flags */ 00192 if(object->visibility & PATH_RAY_CAMERA) { 00193 object->visibility |= layer_flag << PATH_RAY_LAYER_SHIFT; 00194 object->visibility &= ~PATH_RAY_CAMERA; 00195 } 00196 00197 object->tag_update(scene); 00198 } 00199 } 00200 00201 /* Object Loop */ 00202 00203 void BlenderSync::sync_objects(BL::SpaceView3D b_v3d) 00204 { 00205 /* layer data */ 00206 uint scene_layer = render_layers.front().scene_layer; 00207 00208 /* prepare for sync */ 00209 light_map.pre_sync(); 00210 mesh_map.pre_sync(); 00211 object_map.pre_sync(); 00212 mesh_synced.clear(); 00213 00214 /* object loop */ 00215 BL::Scene::objects_iterator b_ob; 00216 00217 for(b_scene.objects.begin(b_ob); b_ob != b_scene.objects.end(); ++b_ob) { 00218 bool hide = (b_v3d)? b_ob->hide(): b_ob->hide_render(); 00219 uint ob_layer = get_layer(b_ob->layers()); 00220 00221 if(!hide && (ob_layer & scene_layer)) { 00222 if(b_ob->is_duplicator()) { 00223 /* dupli objects */ 00224 object_create_duplilist(*b_ob, b_scene); 00225 00226 BL::Object::dupli_list_iterator b_dup; 00227 int b_index = 0; 00228 00229 for(b_ob->dupli_list.begin(b_dup); b_dup != b_ob->dupli_list.end(); ++b_dup) { 00230 Transform tfm = get_transform(b_dup->matrix()); 00231 BL::Object b_dup_ob = b_dup->object(); 00232 bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render(); 00233 00234 if(!(b_dup->hide() || dup_hide)) 00235 sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer); 00236 00237 b_index++; 00238 } 00239 00240 object_free_duplilist(*b_ob); 00241 00242 hide = true; 00243 } 00244 00245 /* check if we should render or hide particle emitter */ 00246 BL::Object::particle_systems_iterator b_psys; 00247 bool render_emitter = false; 00248 00249 for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) { 00250 if(b_psys->settings().use_render_emitter()) { 00251 hide = false; 00252 render_emitter = true; 00253 } 00254 else if(!render_emitter) 00255 hide = true; 00256 } 00257 00258 if(!hide) { 00259 /* object itself */ 00260 Transform tfm = get_transform(b_ob->matrix_world()); 00261 sync_object(*b_ob, 0, *b_ob, tfm, ob_layer); 00262 } 00263 } 00264 } 00265 00266 /* handle removed data and modified pointers */ 00267 if(light_map.post_sync()) 00268 scene->light_manager->tag_update(scene); 00269 if(mesh_map.post_sync()) 00270 scene->mesh_manager->tag_update(scene); 00271 if(object_map.post_sync()) 00272 scene->object_manager->tag_update(scene); 00273 mesh_synced.clear(); 00274 } 00275 00276 CCL_NAMESPACE_END 00277