Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Susano Pinto <andresusanopinto@gmail.com>2009-09-25 02:55:57 +0400
committerAndre Susano Pinto <andresusanopinto@gmail.com>2009-09-25 02:55:57 +0400
commit1305715d2d84f67027b870f263cef3a7f009c056 (patch)
tree50076f8e30adb6f12735fc486abfa11e138511ec /source/blender/render/intern
parentd3e88cb3e0d4117ab845a7c77254a5ab05ce1657 (diff)
*Added VlakPrimitive (this rayobject rimitive only stores ObjectRenderInstance and VlakRen pointers)
- it difers from RayFace that localy stored the vertex coordinates. - basicaly this reduces memory usage
Diffstat (limited to 'source/blender/render/intern')
-rw-r--r--source/blender/render/intern/include/rayobject.h27
-rw-r--r--source/blender/render/intern/include/render_types.h3
-rw-r--r--source/blender/render/intern/raytrace/rayobject.cpp (renamed from source/blender/render/intern/source/rayobject.c)52
-rw-r--r--source/blender/render/intern/source/rayshade.c88
-rw-r--r--source/blender/render/intern/source/renderdatabase.c5
5 files changed, 129 insertions, 46 deletions
diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h
index dbd68fe8b8b..337f9ca3fdd 100644
--- a/source/blender/render/intern/include/rayobject.h
+++ b/source/blender/render/intern/include/rayobject.h
@@ -57,17 +57,18 @@ extern "C" {
In order to allow a mixture of RayFace+RayObjects,
all RayObjects must be 4byte aligned, allowing us to use the
- 2 least significant bits (with the mask 0x02) to define the
+ 2 least significant bits (with the mask 0x03) to define the
type of RayObject.
- This leads to 4 possible types of RayObject, but at the moment
- only 2 are used:
+ This leads to 4 possible types of RayObject:
- addr&2 - type of object
+ addr&3 - type of object
0 Self (reserved for each structure)
- 1 RayFace
+ 1 RayFace (tri/quad primitive)
2 RayObject (generic with API callbacks)
- 3 RayObject_Vlak
+ 3 VlakPrimitive
+ (vlak primitive - to be used when we have a vlak describing the data
+ eg.: on render code)
0 means it's reserved and has it own meaning inside each ray acceleration structure
(this way each structure can use the allign offset to determine if a node represents a
@@ -83,26 +84,16 @@ extern "C" {
/* used to unalign a given ray object */
#define RE_rayobject_unalignRayFace(o) ((RayObject*)(((intptr_t)o)|1))
#define RE_rayobject_unalignRayAPI(o) ((RayObject*)(((intptr_t)o)|2))
-#define RE_rayobject_unalignRayVlak(o) ((RayObject*)(((intptr_t)o)|3))
+#define RE_rayobject_unalignVlakPrimitive(o) ((RayObject*)(((intptr_t)o)|3))
/* used to test the type of ray object */
#define RE_rayobject_isAligned(o) ((((intptr_t)o)&3) == 0)
#define RE_rayobject_isRayFace(o) ((((intptr_t)o)&3) == 1)
#define RE_rayobject_isRayAPI(o) ((((intptr_t)o)&3) == 2)
-#define RE_rayobject_isRayVlak(o) ((((intptr_t)o)&3) == 3)
+#define RE_rayobject_isVlakPrimitive(o) ((((intptr_t)o)&3) == 3)
/*
- * This ray object represents faces directly from a given VlakRen structure.
- * Thus allowing to save memory, but making code dependant on render structures
-typedef struct RayVlak
-{
- struct ObjectInstanceRen *ob;
- struct VlakRen *face;
-} RayVlak;
- */
-
-/*
* This rayobject represents a generic object. With it's own callbacks for raytrace operations.
* It's suitable to implement things like LOD.
*/
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 67c69259213..8c106f60e1d 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -172,6 +172,7 @@ struct Render
/* octree tables and variables for raytrace */
struct RayObject *raytree;
struct RayFace *rayfaces;
+ struct VlakPrimitive *rayprimitives;
float maxdist; /* needed for keeping an incorrect behaviour of SUN and HEMI lights (avoid breaking old scenes) */
/* occlusion tree */
@@ -289,6 +290,7 @@ typedef struct ObjectRen {
/* used on makeraytree */
struct RayObject *raytree;
struct RayFace *rayfaces;
+ struct VlakPrimitive *rayprimitives;
struct ObjectInstanceRen *rayobi;
} ObjectRen;
@@ -313,6 +315,7 @@ typedef struct ObjectInstanceRen {
/* used on makeraytree */
struct RayObject *raytree;
+ int transform_primitives;
} ObjectInstanceRen;
diff --git a/source/blender/render/intern/source/rayobject.c b/source/blender/render/intern/raytrace/rayobject.cpp
index df457a37123..dc5128b2d1f 100644
--- a/source/blender/render/intern/source/rayobject.c
+++ b/source/blender/render/intern/raytrace/rayobject.cpp
@@ -30,6 +30,7 @@
#include "BKE_utildefines.h"
#include "BLI_arithb.h"
+#include "DNA_material_types.h"
#include "RE_raytrace.h"
#include "render_types.h"
@@ -141,7 +142,6 @@ static int intersection2(VlakRen *face, float r0, float r1, float r2, float rx1,
return 0;
}
-#include "DNA_material_types.h"
static int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr)
{
/* for baking selected to active non-traceable materials might still
@@ -178,7 +178,7 @@ static int rayface_check_cullface(RayFace *face, Isect *is)
/* ray - triangle or quad intersection */
/* this function shall only modify Isect if it detects an hit */
-static int intersect_rayface(RayFace *face, Isect *is)
+static int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is)
{
float co1[3],co2[3],co3[3],co4[3];
float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2;
@@ -301,8 +301,8 @@ static int intersect_rayface(RayFace *face, Isect *is)
{
if(labda < 0.1f && is->orig.ob == face->ob)
{
- VlakRen * a = is->orig.face;
- VlakRen * b = face->face;
+ VlakRen * a = (VlakRen*)is->orig.face;
+ VlakRen * b = (VlakRen*)face->face;
/* so there's a shared edge or vertex, let's intersect ray with face
itself, if that's true we can safely return 1, otherwise we assume
@@ -327,7 +327,7 @@ static int intersect_rayface(RayFace *face, Isect *is)
is->hit.ob = face->ob;
is->hit.face = face->face;
#ifdef RT_USE_LAST_HIT
- is->last_hit = (RayObject*) RE_rayobject_unalignRayFace(face);
+ is->last_hit = hit_obj;
#endif
return 1;
}
@@ -361,6 +361,14 @@ RayObject* RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float
return RE_rayobject_unalignRayFace(rayface);
}
+RayObject* RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr)
+{
+ face->ob = obi;
+ face->face = vlr;
+ return RE_rayobject_unalignVlakPrimitive(face);
+}
+
+
int RE_rayobject_raycast(RayObject *r, Isect *isec)
{
int i;
@@ -416,7 +424,25 @@ int RE_rayobject_intersect(RayObject *r, Isect *i)
{
if(RE_rayobject_isRayFace(r))
{
- return intersect_rayface( (RayFace*) RE_rayobject_align(r), i);
+ return intersect_rayface(r, (RayFace*) RE_rayobject_align(r), i);
+ }
+ else if(RE_rayobject_isVlakPrimitive(r))
+ {
+ //TODO optimize (useless copy to RayFace to avoid duplicate code)
+ VlakPrimitive *face = (VlakPrimitive*) RE_rayobject_align(r);
+ RayFace nface;
+ RE_rayface_from_vlak(&nface, face->ob, face->face);
+
+ if(face->ob->transform_primitives)
+ {
+ Mat4MulVecfl(face->ob->mat, nface.v1);
+ Mat4MulVecfl(face->ob->mat, nface.v2);
+ Mat4MulVecfl(face->ob->mat, nface.v3);
+ if(RE_rayface_isQuad(&nface))
+ Mat4MulVecfl(face->ob->mat, nface.v4);
+ }
+
+ return intersect_rayface(r, &nface, i);
}
else if(RE_rayobject_isRayAPI(r))
{
@@ -455,6 +481,16 @@ void RE_rayobject_merge_bb(RayObject *r, float *min, float *max)
DO_MINMAX( face->v3, min, max );
if(RE_rayface_isQuad(face)) DO_MINMAX( face->v4, min, max );
}
+ else if(RE_rayobject_isVlakPrimitive(r))
+ {
+ VlakPrimitive *face = (VlakPrimitive*) RE_rayobject_align(r);
+ VlakRen *vlr = face->face;
+
+ DO_MINMAX( vlr->v1->co, min, max );
+ DO_MINMAX( vlr->v2->co, min, max );
+ DO_MINMAX( vlr->v3->co, min, max );
+ if(vlr->v4) DO_MINMAX( vlr->v4->co, min, max );
+ }
else if(RE_rayobject_isRayAPI(r))
{
r = RE_rayobject_align( r );
@@ -465,7 +501,7 @@ void RE_rayobject_merge_bb(RayObject *r, float *min, float *max)
float RE_rayobject_cost(RayObject *r)
{
- if(RE_rayobject_isRayFace(r))
+ if(RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r))
{
return 1.0;
}
@@ -479,7 +515,7 @@ float RE_rayobject_cost(RayObject *r)
void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max)
{
- if(RE_rayobject_isRayFace(r))
+ if(RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r))
{
return;
}
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 8cb11d11762..18278d90e72 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -61,6 +61,8 @@
#include "rayobject.h"
#include "raycounter.h"
+
+#define USE_VLAK_PRIMITIVES 1
#define RAY_TRA 1
#define RAY_TRAFLIP 2
@@ -133,6 +135,11 @@ void freeraytree(Render *re)
MEM_freeN(re->rayfaces);
re->rayfaces = NULL;
}
+ if(re->rayprimitives)
+ {
+ MEM_freeN(re->rayprimitives);
+ re->rayprimitives = NULL;
+ }
for(obi=re->instancetable.first; obi; obi=obi->next)
{
@@ -203,6 +210,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
{
RayObject *raytree;
RayFace *face;
+ VlakPrimitive *vlakprimitive;
int v;
//Count faces
@@ -217,7 +225,11 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
//Create Ray cast accelaration structure
raytree = obr->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces );
- face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces");
+ if(USE_VLAK_PRIMITIVES)
+ vlakprimitive = obr->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen primitives");
+ else
+ face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces");
+
obr->rayobi = obi;
for(v=0;v<obr->totvlak;v++)
@@ -225,17 +237,26 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
if(is_raytraceable_vlr(re, vlr))
{
- RE_rayface_from_vlak( face, obi, vlr );
- RE_rayobject_add( raytree, RE_rayobject_unalignRayFace(face) );
- face++;
+ if(USE_VLAK_PRIMITIVES)
+ {
+ RE_rayobject_add( raytree, RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr ) );
+ vlakprimitive++;
+ }
+ else
+ {
+ RE_rayface_from_vlak( face, obi, vlr );
+ RE_rayobject_add( raytree, RE_rayobject_unalignRayFace(face) );
+ face++;
+ }
}
}
RE_rayobject_done( raytree );
}
- if(obi->flag & R_TRANSFORMED)
+ if((obi->flag & R_TRANSFORMED) && obi->raytree == NULL)
{
+ obi->transform_primitives = 0;
obi->raytree = RE_rayobject_instance_create( obr->raytree, obi->mat, obi, obi->obr->rayobi );
}
@@ -271,7 +292,8 @@ static void makeraytree_single(Render *re)
ObjectInstanceRen *obi;
RayObject *raytree;
RayFace *face;
- int faces = 0, obs = 0;
+ VlakPrimitive *vlakprimitive;
+ int faces = 0, obs = 0, special = 0;
for(obi=re->instancetable.first; obi; obi=obi->next)
if(is_raytraceable(re, obi))
@@ -282,7 +304,7 @@ static void makeraytree_single(Render *re)
if(has_special_rayobject(re, obi))
{
- faces++;
+ special++;
}
else
{
@@ -296,9 +318,16 @@ static void makeraytree_single(Render *re)
}
//Create raytree
- raytree = re->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces );
+ raytree = re->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces+special );
- face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces");
+ if(USE_VLAK_PRIMITIVES)
+ {
+ vlakprimitive = re->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "Raytrace vlak-primitives");
+ }
+ else
+ {
+ face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces");
+ }
for(obi=re->instancetable.first; obi; obi=obi->next)
if(is_raytraceable(re, obi))
@@ -312,28 +341,46 @@ static void makeraytree_single(Render *re)
{
int v;
ObjectRen *obr = obi->obr;
+
+ if(obi->flag & R_TRANSFORMED)
+ {
+ obi->transform_primitives = 1;
+ }
for(v=0;v<obr->totvlak;v++)
{
VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
if(is_raytraceable_vlr(re, vlr))
{
- RE_rayface_from_vlak(face, obi, vlr);
- if((obi->flag & R_TRANSFORMED))
+ if(USE_VLAK_PRIMITIVES)
{
- Mat4MulVecfl(obi->mat, face->v1);
- Mat4MulVecfl(obi->mat, face->v2);
- Mat4MulVecfl(obi->mat, face->v3);
- if(RE_rayface_isQuad(face))
- Mat4MulVecfl(obi->mat, face->v4);
+ RayObject *obj = RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr );
+ RE_rayobject_add( raytree, obj );
+ vlakprimitive++;
+ }
+ else
+ {
+ RE_rayface_from_vlak(face, obi, vlr);
+ if((obi->flag & R_TRANSFORMED))
+ {
+ Mat4MulVecfl(obi->mat, face->v1);
+ Mat4MulVecfl(obi->mat, face->v2);
+ Mat4MulVecfl(obi->mat, face->v3);
+ if(RE_rayface_isQuad(face))
+ Mat4MulVecfl(obi->mat, face->v4);
+ }
+
+ RE_rayobject_add( raytree, RE_rayobject_unalignRayFace(face) );
+ face++;
}
-
- RE_rayobject_add( raytree, RE_rayobject_unalignRayFace(face) );
- face++;
}
}
}
}
+
+ re->i.infostr= "Raytree.. building";
+ re->stats_draw(re->sdh, &re->i);
+
RE_rayobject_done( raytree );
}
@@ -342,7 +389,7 @@ void makeraytree(Render *re)
float min[3], max[3], sub[3];
int i;
- re->i.infostr= "Make raytree";
+ re->i.infostr= "Raytree.. preparing";
re->stats_draw(re->sdh, &re->i);
BENCH(makeraytree_single(re), tree_build);
@@ -359,6 +406,7 @@ void makeraytree(Render *re)
re->maxdist = sqrt( sub[0]*sub[0] + sub[1]*sub[1] + sub[2]*sub[2] );
re->i.infostr= "Raytree finished";
+ re->stats_draw(re->sdh, &re->i);
}
void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 5f21a0e2e1a..784e42685b7 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -879,6 +879,11 @@ void free_renderdata_tables(Render *re)
MEM_freeN(obr->rayfaces);
obr->rayfaces = NULL;
}
+ if(obr->rayprimitives)
+ {
+ MEM_freeN(obr->rayprimitives);
+ obr->rayprimitives = NULL;
+ }
if(obr->raytree)
{
RE_rayobject_free(obr->raytree);