*Updated UI options and added UI options to:
authorAndre Susano Pinto <andresusanopinto@gmail.com>
Thu, 1 Oct 2009 18:30:59 +0000 (18:30 +0000)
committerAndre Susano Pinto <andresusanopinto@gmail.com>
Thu, 1 Oct 2009 18:30:59 +0000 (18:30 +0000)
control whether instances are used or not
control whether vertexs are stored localy or not

*Removed unsused code

14 files changed:
release/scripts/ui/buttons_scene.py
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_scene.c
source/blender/render/SConscript
source/blender/render/extern/include/RE_raytrace.h
source/blender/render/intern/raytrace/rayobject.cpp
source/blender/render/intern/raytrace/rayobject_bih.cpp [deleted file]
source/blender/render/intern/raytrace/rayobject_bvh.cpp [deleted file]
source/blender/render/intern/raytrace/rayobject_qbvh.cpp
source/blender/render/intern/raytrace/rayobject_svbvh.cpp
source/blender/render/intern/raytrace/rayobject_vbvh.cpp
source/blender/render/intern/source/rayobject_blibvh.c
source/blender/render/intern/source/rayobject_octree.c
source/blender/render/intern/source/rayshade.c

index 88947aac86c824372d1494037ba162847c2647c6..10a0efae33d85cf935fe6b3e0d8dcd2b15f9c614 100644 (file)
@@ -171,8 +171,11 @@ class SCENE_PT_performance(RenderButtonsPanel):
                sub.itemR(rd, "free_image_textures")
                sub = col.column()
                sub.active = rd.render_raytracing
-               sub.itemL(text="Ray Tracing Octree:")
-               sub.itemR(rd, "octree_resolution", text="")
+               sub.itemL(text="Acceleration structure:")
+               sub.itemR(rd, "raytrace_structure", text="")
+               sub.itemR(rd, "use_instances", text="Instance support")
+               sub.itemR(rd, "use_local_coords", text="Local coords")
+               sub.itemR(rd, "octree_resolution", text="Octree resolution")
 
 class SCENE_PT_post_processing(RenderButtonsPanel):
        __label__ = "Post Processing"
index 09e9f599d03fba7324b69ae1f9c916ae24b55bff..27ee5d471339c00ad4a942c068a4e570b3ae73a3 100644 (file)
@@ -242,12 +242,23 @@ typedef struct RenderData {
         */
        int mode;
 
-       /* render engine (deprecated), octree resolution */
-       short renderer, ocres;
-       short raystructure;
-       short raytrace_tree_type;
-       short pad4[2];
+       /**
+        * Flags for raytrace settings. Use bit-masking to access the settings.
+        */
+       int raytrace_options;
+       
+       /**
+        * Raytrace acceleration structure
+        */
+       short raytrace_structure;
 
+       /* renderer (deprecated) */
+       short renderer;
+
+       /* octree resolution */
+       short ocres;
+       short pad4;
+       
        /**
         * What to do with the sky/background. Picks sky/premul/key
         * blending for the background
@@ -260,6 +271,7 @@ typedef struct RenderData {
        short osa;
 
        short frs_sec, edgeint;
+
        
        /* safety, border and display rect */
        rctf safety, border;
@@ -808,7 +820,10 @@ typedef struct Scene {
 #define R_RAYSTRUCTURE_VBVH                            3
 #define R_RAYSTRUCTURE_SIMD_SVBVH              4       /* needs SIMD */
 #define R_RAYSTRUCTURE_SIMD_QBVH               5       /* needs SIMD */
-#define R_RAYSTRUCTURE_BIH                             6
+
+/* raytrace_options */
+#define R_RAYTRACE_USE_LOCAL_COORDS            0x0001
+#define R_RAYTRACE_USE_INSTANCES               0x0002
 
 /* scemode (int now) */
 #define R_DOSEQ                                0x0001
index ffe07d4de6249acbd16c76dead22e7bdc8164aa7..267e29d701815422552a00d1b2fc0886285ab7a9 100644 (file)
@@ -1185,7 +1185,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
                {R_RAYSTRUCTURE_VBVH, "R_RAYSTRUCTURE_VBVH", 0, "vBVH", ""},
                {R_RAYSTRUCTURE_SIMD_SVBVH, "R_RAYSTRUCTURE_SIMD_SVBVH", 0, "SIMD SVBVH", "Requires SIMD"},
                {R_RAYSTRUCTURE_SIMD_QBVH, "R_RAYSTRUCTURE_SIMD_QBVH", 0, "SIMD QBVH", "Requires SIMD"},
-               {R_RAYSTRUCTURE_BIH, "R_RAYSTRUCTURE_BIH", 0, "BIH", ""},
                {0, NULL, 0, NULL, NULL}
                };
 
@@ -1618,11 +1617,22 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
        RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
 
        prop= RNA_def_property(srna, "raytrace_structure", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_sdna(prop, NULL, "raystructure");
+       RNA_def_property_enum_sdna(prop, NULL, "raytrace_structure");
        RNA_def_property_enum_items(prop, raytrace_structure_items);
        RNA_def_property_ui_text(prop, "Raytrace Acceleration Structure", "Type of raytrace accelerator structure.");
        RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
 
+       prop= RNA_def_property(srna, "use_instances", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "raytrace_options", R_RAYTRACE_USE_INSTANCES);
+       RNA_def_property_ui_text(prop, "Use Instances", "Instance support leads to effective memory reduction when using duplicates.");
+       RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+       prop= RNA_def_property(srna, "use_local_coords", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "raytrace_options", R_RAYTRACE_USE_LOCAL_COORDS);
+       RNA_def_property_ui_text(prop, "Use Local Coords", "Vertex coordinates are stored localy on each primitive. Increases memory usage, but may have impact on speed.");
+       RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+
        prop= RNA_def_property(srna, "antialiasing", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "mode", R_OSA);
        RNA_def_property_ui_text(prop, "Anti-Aliasing", "Render and combine multiple samples per pixel to prevent jagged edges.");
index a15dada1bec3af4f68d9c0b4fc4e454a2a33898c..4ad7694cbbfb225436159762b4e5136c36bb7da6 100644 (file)
@@ -1,8 +1,8 @@
 #!/usr/bin/python
 Import ('env')
 
-cflags = ['-msse2','-mfpmath=sse']
-cxxflags = ['-msse2','-mfpmath=sse']
+cflags = ['-O2','-msse2','-mfpmath=sse']
+cxxflags = ['-O2','-msse2','-mfpmath=sse']
 sources = env.Glob('intern/source/*.c')
 raysources = env.Glob('intern/raytrace/*.cpp')
 
index edf343b6be7d6bb0f810008ece6af75d62814614..6a171a98f12a4eee277f4e5d6eb6a2919a2f7a51 100644 (file)
@@ -85,11 +85,9 @@ RayObject* RE_rayobject_octree_create(int ocres, int size);
 RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob);
 
 RayObject* RE_rayobject_blibvh_create(int size);       /* BLI_kdopbvh.c   */
-RayObject* RE_rayobject_bvh_create(int size);          /* raytrace/rayobject_bvh.c */
 RayObject* RE_rayobject_vbvh_create(int size);         /* raytrace/rayobject_vbvh.c */
-RayObject* RE_rayobject_qbvh_create(int size);         /* raytrace/rayobject_qbvh.c */
 RayObject* RE_rayobject_svbvh_create(int size);                /* raytrace/rayobject_svbvh.c */
-RayObject* RE_rayobject_bih_create(int size);          /* rayobject_bih.c */
+RayObject* RE_rayobject_qbvh_create(int size);         /* raytrace/rayobject_qbvh.c */
 
 
 /*
index c32f61e8f0a777d3a019a119e8659f91cae4e3c1..34faa2951ceff995da481d033ccf952d0f2cec5f 100644 (file)
@@ -142,7 +142,7 @@ static int intersection2(VlakRen *face, float r0, float r1, float r2, float rx1,
        return 0;
 }
 
-static int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr)
+static inline int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr)
 {
        /* for baking selected to active non-traceable materials might still
         * be in the raytree */
@@ -156,7 +156,7 @@ static int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr)
                return (is->lay & obi->lay);
 }
 
-static int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr)
+static inline int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr)
 {
        /* solid material types only */
        if (vlr->mat->material_type == MA_TYPE_SURFACE)
@@ -165,7 +165,7 @@ static int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen
                return 0;
 }
 
-static int rayface_check_cullface(RayFace *face, Isect *is)
+static inline int rayface_check_cullface(RayFace *face, Isect *is)
 {
        float nor[3];
        
@@ -189,7 +189,7 @@ static int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is)
        if(is->orig.ob == face->ob && is->orig.face == face->face)
                return 0;
                
-/*
+
        if(is->skip & RE_SKIP_VLR_RENDER_CHECK)
        {
                if(vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face ) == 0)
@@ -205,7 +205,7 @@ static int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is)
                if(rayface_check_cullface(face, is) == 0)
                        return 0;
        }
-*/
+
        RE_RC_COUNT(is->raycounter->faces.test);
 
        //Load coords
diff --git a/source/blender/render/intern/raytrace/rayobject_bih.cpp b/source/blender/render/intern/raytrace/rayobject_bih.cpp
deleted file mode 100644 (file)
index efbf706..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/**
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. 
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2009 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): AndrĂ© Pinto.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#include <assert.h>
-#include <stdio.h>
-
-#include "MEM_guardedalloc.h"
-#include "BKE_utildefines.h"
-#include "BLI_arithb.h"
-#include "RE_raytrace.h"
-#include "rayobject_rtbuild.h"
-#include "rayobject.h"
-
-#define BIH_NCHILDS    4
-typedef struct BIHTree BIHTree;
-
-static int  bih_intersect(BIHTree *obj, Isect *isec);
-static void bih_add(BIHTree *o, RayObject *ob);
-static void bih_done(BIHTree *o);
-static void bih_free(BIHTree *o);
-static void bih_bb(BIHTree *o, float *min, float *max);
-
-static RayObjectAPI bih_api =
-{
-       (RE_rayobject_raycast_callback) bih_intersect,
-       (RE_rayobject_add_callback)     bih_add,
-       (RE_rayobject_done_callback)    bih_done,
-       (RE_rayobject_free_callback)    bih_free,
-       (RE_rayobject_merge_bb_callback)bih_bb
-};
-
-typedef struct BIHNode BIHNode;
-struct BIHNode
-{
-       BIHNode *child[BIH_NCHILDS];
-       float bi[BIH_NCHILDS][2];
-       int split_axis;
-};
-
-struct BIHTree
-{
-       RayObject rayobj;
-
-       BIHNode *root;
-
-       BIHNode *node_alloc, *node_next;
-       RTBuilder *builder;
-
-       float bb[2][3];
-};
-
-
-RayObject *RE_rayobject_bih_create(int size)
-{
-       BIHTree *obj= (BIHTree*)MEM_callocN(sizeof(BIHTree), "BIHTree");
-       assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */       
-       
-       obj->rayobj.api = &bih_api;
-       obj->root = NULL;
-       
-       obj->node_alloc = obj->node_next = NULL;
-       obj->builder    = rtbuild_create( size );
-       
-       return RE_rayobject_unalignRayAPI((RayObject*) obj);
-}
-
-static void bih_free(BIHTree *obj)
-{
-       if(obj->builder)
-               rtbuild_free(obj->builder);
-
-       if(obj->node_alloc)
-               MEM_freeN(obj->node_alloc);
-
-       MEM_freeN(obj);
-}
-
-static void bih_bb(BIHTree *obj, float *min, float *max)
-{
-       DO_MIN(obj->bb[0], min);
-       DO_MAX(obj->bb[1], max);
-}
-
-/*
- * Tree transverse
- */
-static int dfs_raycast(const BIHNode *const node, Isect *isec, float tmin, float tmax)
-{
-       int i;
-       int hit = 0;
-
-       const int *const offset = isec->bv_index + node->split_axis*2;
-
-       //TODO diving heuristic
-       for(i=0; i<BIH_NCHILDS; i++)
-       {
-
-               float t1 = (node->bi[i][offset[0]] - isec->start[node->split_axis]) * isec->idot_axis[node->split_axis];
-               float t2 = (node->bi[i][offset[1]] - isec->start[node->split_axis]) * isec->idot_axis[node->split_axis];
-
-               if(t1 < tmin) t1 = tmin; //t1 = MAX2(t1, tmin);
-               if(t2 > tmax) t2 = tmax; //t2 = MIN2(t2, tmax);
-
-               if(t1 <= t2)
-               {
-                               if(RE_rayobject_isAligned(node->child[i]))
-                               {
-                                       if(node->child[i] == 0) break;
-                                       
-                                       hit |= dfs_raycast(node->child[i], isec, t1, t2);
-                                       if(hit && isec->mode == RE_RAY_SHADOW) return hit;
-                               }
-                               else
-                               {
-                                       hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec);
-                                       if(hit && isec->mode == RE_RAY_SHADOW) return hit;
-                               }
-
-                               if(tmax > isec->labda)
-                                       tmax = isec->labda;
-               }
-       }
-
-       return hit;
-}
-
-static int bih_intersect(BIHTree *obj, Isect *isec)
-{
-       if(RE_rayobject_isAligned(obj->root))
-               return dfs_raycast(obj->root, isec, 0, isec->labda);
-       else
-               return RE_rayobject_intersect( (RayObject*)obj->root, isec);
-}
-
-
-/*
- * Builds a BIH tree from builder object
- */
-static void bih_add(BIHTree *obj, RayObject *ob)
-{
-       rtbuild_add( obj->builder, ob );
-}
-
-static BIHNode *bih_new_node(BIHTree *tree, int nid)
-{
-       BIHNode *node = tree->node_alloc + nid - 1;
-       assert(RE_rayobject_isAligned(node));
-       if(node+1 > tree->node_next)
-               tree->node_next = node+1;
-               
-       return node;
-}
-
-static int child_id(int pid, int nchild)
-{
-       //N child of node A = A * K + (2 - K) + N, (0 <= N < K)
-       return pid*BIH_NCHILDS+(2-BIH_NCHILDS)+nchild;
-}
-
-static BIHNode *bih_rearrange(BIHTree *tree, RTBuilder *builder, int nid, float *bb)
-{
-       if(rtbuild_size(builder) == 1)
-       {
-               RayObject *child = rtbuild_get_primitive( builder, 0 );
-               assert(!RE_rayobject_isAligned(child));
-
-               INIT_MINMAX(bb, bb+3);
-               RE_rayobject_merge_bb( (RayObject*)child, bb, bb+3);
-
-               return (BIHNode*)child;
-       }
-       else
-       {
-               int i;
-               int nc = rtbuild_mean_split_largest_axis(builder, BIH_NCHILDS);
-               RTBuilder tmp;
-       
-               BIHNode *parent = bih_new_node(tree, nid);
-
-               INIT_MINMAX(bb, bb+3);
-               parent->split_axis = builder->split_axis;
-               for(i=0; i<nc; i++)
-               {
-                       float cbb[6];
-                       parent->child[i] = bih_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), cbb );
-
-                       parent->bi[i][0] = cbb[parent->split_axis];
-                       parent->bi[i][1] = cbb[parent->split_axis+3];
-
-                       DO_MIN(cbb  , bb);
-                       DO_MAX(cbb+3, bb+3);
-               }
-               for(; i<BIH_NCHILDS; i++)
-               {
-                       parent->bi[i][0] =  1.0;
-                       parent->bi[i][1] = -1.0;
-                       parent->child[i] = 0;
-               }
-
-               return parent;
-       }
-}
-
-static void bih_done(BIHTree *obj)
-{
-       int needed_nodes;
-       assert(obj->root == NULL && obj->node_alloc == NULL && obj->builder);
-
-       //TODO exact calculate needed nodes
-       needed_nodes = (rtbuild_size(obj->builder)+1)*2;
-       assert(needed_nodes > 0);
-
-       obj->node_alloc = (BIHNode*)MEM_mallocN( sizeof(BIHNode)*needed_nodes, "BIHTree.Nodes");
-       obj->node_next  = obj->node_alloc;
-
-       obj->root = bih_rearrange( obj, obj->builder, 1, (float*)obj->bb );
-
-       rtbuild_free( obj->builder );
-       obj->builder = NULL;
-       
-       assert(obj->node_alloc+needed_nodes >= obj->node_next);
-}
-
diff --git a/source/blender/render/intern/raytrace/rayobject_bvh.cpp b/source/blender/render/intern/raytrace/rayobject_bvh.cpp
deleted file mode 100644 (file)
index a7e96f6..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/**
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. 
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2009 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): AndrĂ© Pinto.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#include <assert.h>
-
-#include "RE_raytrace.h"
-#include "rayobject_rtbuild.h"
-#include "rayobject.h"
-#include "MEM_guardedalloc.h"
-#include "BKE_utildefines.h"
-#include "BLI_arithb.h"
-#include "BLI_memarena.h"
-#include "bvh.h"
-
-#define BVH_NCHILDS 2
-#define RAY_BB_TEST_COST (0.2f)
-#define DFS_STACK_SIZE 64
-#define DYNAMIC_ALLOC
-
-//#define rtbuild_split        rtbuild_mean_split_largest_axis         /* objects mean split on the longest axis, childs BB are allowed to overlap */
-//#define rtbuild_split        rtbuild_median_split_largest_axis       /* space median split on the longest axis, childs BB are allowed to overlap */
-#define rtbuild_split  rtbuild_heuristic_object_split          /* split objects using heuristic */
-
-struct BVHNode
-{
-       BVHNode *child[BVH_NCHILDS];
-       float   bb[6];
-       int split_axis;
-};
-
-struct BVHTree
-{
-       RayObject rayobj;
-
-       BVHNode *root;
-
-       MemArena *node_arena;
-
-       float cost;
-       RTBuilder *builder;
-};
-
-/*
- * Push nodes (used on dfs)
- */
-template<class Node>
-inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos)
-{
-       //push nodes in reverse visit order
-       if(isec->idot_axis[node->split_axis] < 0.0f)
-       {
-               int i;
-               for(i=0; i<BVH_NCHILDS; i++)
-                       if(node->child[i] == 0)
-                               break;
-                       else
-                               stack[stack_pos++] = node->child[i];
-       }
-       else
-       {
-               int i;  
-               for(i=BVH_NCHILDS-1; i>=0; i--)
-                       if(node->child[i] != 0)
-                               stack[stack_pos++] = node->child[i];
-       }
-}
-
-/*
- * BVH done
- */
-static BVHNode *bvh_new_node(BVHTree *tree, int nid)
-{
-       BVHNode *node = (BVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode));
-       return node;
-}
-
-static int child_id(int pid, int nchild)
-{
-       //N child of node A = A * K + (2 - K) + N, (0 <= N < K)
-    return pid*BVH_NCHILDS+(2-BVH_NCHILDS)+nchild;
-}
-        
-
-static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float *cost)
-{
-       *cost = 0;
-       if(rtbuild_size(builder) == 0)
-               return 0;
-
-       if(rtbuild_size(builder) == 1)
-       {
-               RayObject *child = rtbuild_get_primitive( builder, 0 );
-
-               if(RE_rayobject_isRayFace(child))
-               {
-                       int i;
-                       BVHNode *parent = bvh_new_node(tree, nid);
-                       parent->split_axis = 0;
-
-                       INIT_MINMAX(parent->bb, parent->bb+3);
-
-                       for(i=0; i<1; i++)
-                       {
-                               parent->child[i] = (BVHNode*)rtbuild_get_primitive( builder, i );
-                               bvh_node_merge_bb(parent->child[i], parent->bb, parent->bb+3);
-                       }
-                       for(; i<BVH_NCHILDS; i++)
-                               parent->child[i] = 0;
-
-                       *cost = RE_rayobject_cost(child)+RAY_BB_TEST_COST;
-                       return parent;
-               }
-               else
-               {
-                       assert(!RE_rayobject_isAligned(child));
-                       //Its a sub-raytrace structure, assume it has it own raycast
-                       //methods and adding a Bounding Box arround is unnecessary
-
-                       *cost = RE_rayobject_cost(child);
-                       return (BVHNode*)child;
-               }
-       }
-       else
-       {
-               int i;
-               RTBuilder tmp;
-               BVHNode *parent = bvh_new_node(tree, nid);
-               int nc = rtbuild_split(builder, BVH_NCHILDS); 
-
-
-               INIT_MINMAX(parent->bb, parent->bb+3);
-               parent->split_axis = builder->split_axis;
-               for(i=0; i<nc; i++)
-               {
-                       float cbb[6];
-                       float tcost;
-                       parent->child[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), &tcost );
-                       
-                       INIT_MINMAX(cbb, cbb+3);
-                       bvh_node_merge_bb(parent->child[i], cbb, cbb+3);
-                       DO_MIN(cbb,   parent->bb);
-                       DO_MAX(cbb+3, parent->bb+3);
-                       
-                       *cost += tcost*bb_area(cbb, cbb+3);
-               }
-               for(; i<BVH_NCHILDS; i++)
-                       parent->child[i] = 0;
-
-               *cost /= bb_area(parent->bb, parent->bb+3);
-               *cost += nc*RAY_BB_TEST_COST;
-               return parent;
-       }
-
-       assert(false);
-}
-
-template<>
-void bvh_done<BVHTree>(BVHTree *obj)
-{
-       int needed_nodes = (rtbuild_size(obj->builder)+1)*2;
-       if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE)
-               needed_nodes = BLI_MEMARENA_STD_BUFSIZE;
-
-       obj->node_arena = BLI_memarena_new(needed_nodes);
-       BLI_memarena_use_malloc(obj->node_arena);
-
-       
-       obj->root = bvh_rearrange( obj, obj->builder, 1, &obj->cost );
-       
-       rtbuild_free( obj->builder );
-       obj->builder = NULL;
-}
-
-template<>
-int bvh_intersect<BVHTree>(BVHTree *obj, Isect* isec)
-{
-       if(RE_rayobject_isAligned(obj->root))
-               return bvh_node_stack_raycast<BVHNode,64,true>(obj->root, isec);
-       else
-               return RE_rayobject_intersect( (RayObject*) obj->root, isec );
-}
-
-
-/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */
-static RayObjectAPI bvh_api =
-{
-       (RE_rayobject_raycast_callback) ((int(*)(BVHTree*,Isect*)) &bvh_intersect<BVHTree>),
-       (RE_rayobject_add_callback)     ((void(*)(BVHTree*,RayObject*)) &bvh_add<BVHTree>),
-       (RE_rayobject_done_callback)    ((void(*)(BVHTree*))       &bvh_done<BVHTree>),
-       (RE_rayobject_free_callback)    ((void(*)(BVHTree*))       &bvh_free<BVHTree>),
-       (RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) &bvh_bb<BVHTree>),
-       (RE_rayobject_cost_callback)    ((float(*)(BVHTree*))      &bvh_cost<BVHTree>)
-};
-
-
-RayObject *RE_rayobject_bvh_create(int size)
-{
-       BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree");
-       assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */       
-       
-       obj->rayobj.api = &bvh_api;
-       obj->root = NULL;
-       
-       obj->node_arena = NULL;
-       obj->builder    = rtbuild_create( size );
-       
-       return RE_rayobject_unalignRayAPI((RayObject*) obj);
-}
index 53579d2915f7bc5538c420e9faffc47a19d2036b..59daf9dc9624d50134a4bbbf3f46df2e8e29ebbb 100644 (file)
@@ -44,17 +44,6 @@ struct QBVHTree
 };
 
 
-/*
- * Cost to test N childs
- */
-struct PackCost
-{
-       float operator()(int n)
-       {
-               return (n / 4) + ((n % 4) > 2 ? 1 : n%4);
-       }
-};
-
 template<>
 void bvh_done<QBVHTree>(QBVHTree *obj)
 {
@@ -68,21 +57,11 @@ void bvh_done<QBVHTree>(QBVHTree *obj)
                                           BLI_memarena_use_malloc(arena2);
                                           BLI_memarena_use_align(arena2, 16);
 
-       //Build and optimize the tree
-       
-       if(0)
-       {
-               VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder);     
-               pushup_simd<VBVHNode,4>(root);                                     
-               obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root);
-       }
-       else
-       {
-               //Finds the optimal packing of this tree using a given cost model
-               OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena1).transform(obj->builder);                   
-               VBVH_optimalPackSIMD<OVBVHNode,PackCost>(PackCost()).transform(root);
-               obj->root = Reorganize_SVBVH<OVBVHNode>(arena2).transform(root);
-       }
+       //Build and optimize the tree   
+       //TODO do this in 1 pass (half memory usage during building)    
+       VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder);     
+       pushup_simd<VBVHNode,4>(root);                                     
+       obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root);
        
        //Cleanup
        BLI_memarena_free(arena1);      
index 1bcffddd0ac845159dc30e7e865a1500be0d188a..f806fcf93ef791949e50d69dc7b28a292d752a5d 100644 (file)
@@ -43,6 +43,17 @@ struct SVBVHTree
        RTBuilder *builder;
 };
 
+/*
+ * Cost to test N childs
+ */
+struct PackCost
+{
+       float operator()(int n)
+       {
+               return (n / 4) + ((n % 4) > 2 ? 1 : n%4);
+       }
+};
+
 
 template<>
 void bvh_done<SVBVHTree>(SVBVHTree *obj)
@@ -58,16 +69,27 @@ void bvh_done<SVBVHTree>(SVBVHTree *obj)
                                           BLI_memarena_use_align(arena2, 16);
 
        //Build and optimize the tree
-       VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder);
-       reorganize(root);
-       remove_useless(root, &root);
-       bvh_refit(root);
+       if(0)
+       {
+               VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder);
+               reorganize(root);
+               remove_useless(root, &root);
+               bvh_refit(root);
        
-       pushup(root);
-       pushdown(root);
-       pushup_simd<VBVHNode,4>(root);
+               pushup(root);
+               pushdown(root);
+               pushup_simd<VBVHNode,4>(root);
        
-       obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root);
+               obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root);
+       }
+       else
+       {
+               //Finds the optimal packing of this tree using a given cost model
+               //TODO this uses quite a lot of memory, find ways to reduce memory usage during building
+               OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena1).transform(obj->builder);                   
+               VBVH_optimalPackSIMD<OVBVHNode,PackCost>(PackCost()).transform(root);
+               obj->root = Reorganize_SVBVH<OVBVHNode>(arena2).transform(root);
+       }
 
        
        //Free data
index 4e51de0da074808c01c774617e7200274812204f..5260abf67aed3c347a110283b7e610cc416ee062 100644 (file)
@@ -58,6 +58,16 @@ struct VBVHTree
        RTBuilder *builder;
 };
 
+/*
+ * Cost to test N childs
+ */
+struct PackCost
+{
+       float operator()(int n)
+       {
+               return n;
+       }
+};
 
 template<>
 void bvh_done<VBVHTree>(VBVHTree *obj)
@@ -67,24 +77,42 @@ void bvh_done<VBVHTree>(VBVHTree *obj)
        //TODO find a away to exactly calculate the needed memory
        MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
                                           BLI_memarena_use_malloc(arena1);
-
        
        //Build and optimize the tree
-       VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder);
+       if(1)
+       {
+               VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder);
 
-       reorganize(root);
-       remove_useless(root, &root);
-       bvh_refit(root);
+               reorganize(root);
+               remove_useless(root, &root);
+               bvh_refit(root);
        
-       pushup(root);
-       pushdown(root);
+               pushup(root);
+               pushdown(root);
+               obj->root = root;
+       }
+       else
+       {
+/*
+       TODO
+               MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+                                                  BLI_memarena_use_malloc(arena2);
+                                                  
+               //Finds the optimal packing of this tree using a given cost model
+               //TODO this uses quite a lot of memory, find ways to reduce memory usage during building
+               OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena2).transform(obj->builder);                   
+               VBVH_optimalPackSIMD<OVBVHNode,PackCost>(PackCost()).transform(root);
+               obj->root = Reorganize_VBVH<OVBVHNode>(arena1).transform(root);
+               
+               BLI_memarena_free(arena2);
+ */
+       }
 
        //Cleanup
        rtbuild_free( obj->builder );
        obj->builder = NULL;
 
        obj->node_arena = arena1;
-       obj->root = root;
        obj->cost = 1.0;        
 }
 
index 6e789862207fc91a16fd2274f54ccda969385b36..487193ef1f299ec937d082d3767fa1d713084131 100644 (file)
@@ -42,13 +42,26 @@ static void RE_rayobject_blibvh_done(RayObject *o);
 static void RE_rayobject_blibvh_free(RayObject *o);
 static void RE_rayobject_blibvh_bb(RayObject *o, float *min, float *max);
 
+static float RE_rayobject_blibvh_cost(RayObject *o)
+{
+       //TODO calculate the expected cost to raycast on this structure
+       return 1.0;
+}
+
+static void RE_rayobject_blibvh_hint_bb(RayObject *o, RayHint *hint, float *min, float *max)
+{
+       return;
+}
+
 static RayObjectAPI bvh_api =
 {
        RE_rayobject_blibvh_intersect,
        RE_rayobject_blibvh_add,
        RE_rayobject_blibvh_done,
        RE_rayobject_blibvh_free,
-       RE_rayobject_blibvh_bb
+       RE_rayobject_blibvh_bb,
+       RE_rayobject_blibvh_cost,
+       RE_rayobject_blibvh_hint_bb
 };
 
 typedef struct BVHObject
index 4246dd522db19288858cda8465add61f1c9059d7..2f0a1a3f53b58a6dc6bd324cdba5edef99c4ac70 100644 (file)
@@ -90,13 +90,28 @@ static void RE_rayobject_octree_done(RayObject *o);
 static void RE_rayobject_octree_free(RayObject *o);
 static void RE_rayobject_octree_bb(RayObject *o, float *min, float *max);
 
+/*
+ * This function is not expected to be called by current code state.
+ */
+static float RE_rayobject_octree_cost(RayObject *o)
+{
+       return 1.0;
+}
+
+static void RE_rayobject_octree_hint_bb(RayObject *o, RayHint *hint, float *min, float *max)
+{
+       return;
+}
+
 static RayObjectAPI octree_api =
 {
        RE_rayobject_octree_intersect,
        RE_rayobject_octree_add,
        RE_rayobject_octree_done,
        RE_rayobject_octree_free,
-       RE_rayobject_octree_bb
+       RE_rayobject_octree_bb,
+       RE_rayobject_octree_cost,
+       RE_rayobject_octree_hint_bb
 };
 
 /* **************** ocval method ******************* */
index d84a2d9210a468b6f0f6380def6646af009e4c3b..641085d8cd6c2bc5c4b26c0b2b02918407b3ffd7 100644 (file)
@@ -62,7 +62,6 @@
 #include "raycounter.h"
 
 
-#define USE_VLAK_PRIMITIVES 1
 #define RAY_TRA                1
 #define RAY_TRAFLIP    2
 
@@ -78,15 +77,12 @@ RayObject *  RE_rayobject_create(int type, int size)
        if(type == R_RAYSTRUCTURE_AUTO)
        {
                //TODO
-//             if(detect_simd())
-//                     type = R_RAYSTRUCTURE_SIMD_SVBVH;
-//             else
-//                     type = R_RAYSTRUCTURE_VBVH;
-
-                       type = R_RAYSTRUCTURE_SIMD_QBVH;
+               //if(detect_simd())
+                       type = R_RAYSTRUCTURE_SIMD_SVBVH;
+               //else
+               //      type = R_RAYSTRUCTURE_VBVH;
        }
-       
-       
+               
        if(type == R_RAYSTRUCTURE_OCTREE)
        {
                //TODO dynamic ocres
@@ -108,10 +104,7 @@ RayObject *  RE_rayobject_create(int type, int size)
        {
                return RE_rayobject_qbvh_create(size);
        }
-       if(type == R_RAYSTRUCTURE_BIH)
-       {
-//             return RE_rayobject_bih_create(size);
-       }
+       assert( NULL );
        
        return NULL;
 }
@@ -209,8 +202,8 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
        if(obr->raytree == NULL)
        {
                RayObject *raytree;
-               RayFace *face;
-               VlakPrimitive *vlakprimitive;
+               RayFace *face = NULL;
+               VlakPrimitive *vlakprimitive = NULL;
                int v;
                
                //Count faces
@@ -224,8 +217,8 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
                assert( faces > 0 );
 
                //Create Ray cast accelaration structure                
-               raytree = obr->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces );
-               if(USE_VLAK_PRIMITIVES)
+               raytree = obr->raytree = RE_rayobject_create( re->r.raytrace_structure, faces );
+               if(  (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
                        vlakprimitive = obr->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen primitives");
                else
                        face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces");
@@ -237,7 +230,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
                        VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
                        if(is_raytraceable_vlr(re, vlr))
                        {
-                               if(USE_VLAK_PRIMITIVES)
+                               if(  (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
                                {
                                        RE_rayobject_add( raytree, RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr ) );
                                        vlakprimitive++;
@@ -266,7 +259,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
 
 static int has_special_rayobject(Render *re, ObjectInstanceRen *obi)
 {
-       if( (obi->flag & R_TRANSFORMED) )
+       if( (obi->flag & R_TRANSFORMED) && (re->r.raytrace_options & R_RAYTRACE_USE_INSTANCES) )
        {
                ObjectRen *obr = obi->obr;
                int v, faces = 0;
@@ -291,8 +284,8 @@ static void makeraytree_single(Render *re)
 {
        ObjectInstanceRen *obi;
        RayObject *raytree;
-       RayFace *face;
-       VlakPrimitive *vlakprimitive;
+       RayFace *face = NULL;
+       VlakPrimitive *vlakprimitive = NULL;
        int faces = 0, obs = 0, special = 0;
 
        for(obi=re->instancetable.first; obi; obi=obi->next)
@@ -318,9 +311,9 @@ static void makeraytree_single(Render *re)
        }
        
        //Create raytree
-       raytree = re->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces+special );
+       raytree = re->raytree = RE_rayobject_create( re->r.raytrace_structure, faces+special );
 
-       if(USE_VLAK_PRIMITIVES)
+       if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
        {
                vlakprimitive = re->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "Raytrace vlak-primitives");
        }
@@ -352,7 +345,7 @@ static void makeraytree_single(Render *re)
                                VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
                                if(is_raytraceable_vlr(re, vlr))
                                {
-                                       if(USE_VLAK_PRIMITIVES)
+                                       if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
                                        {
                                                RayObject *obj = RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr );
                                                RE_rayobject_add( raytree, obj );
@@ -392,6 +385,11 @@ void makeraytree(Render *re)
        re->i.infostr= "Raytree.. preparing";
        re->stats_draw(re->sdh, &re->i);
 
+       /* disable options not yet suported by octree,
+          they might actually never be supported (unless people really need it) */
+       if(re->r.raytrace_structure == R_RAYSTRUCTURE_OCTREE)
+               re->r.raytrace_options &= ~( R_RAYTRACE_USE_INSTANCES | R_RAYTRACE_USE_LOCAL_COORDS);
+
        BENCH(makeraytree_single(re), tree_build);
                
        //Calculate raytree max_size