forked from bartvdbraak/blender
svn merge -r 12856:12937 https://svn.blender.org/svnroot/bf-blender/trunk/blender
This commit is contained in:
commit
a8a5776160
@ -291,20 +291,20 @@ void BMF_BitmapFont::DrawStringBuf(char *str, int posx, int posy, float *col, un
|
||||
if (fbuf) {
|
||||
float *pixel, *max;
|
||||
unsigned char c;
|
||||
int x, y;
|
||||
int xi, yi;
|
||||
|
||||
max = fbuf + (4 * (w * h));
|
||||
|
||||
while ((c = (unsigned char) *str++)) {
|
||||
BMF_CharData & cd = m_fontData->chars[c];
|
||||
if (cd.data_offset != -1) {
|
||||
for (y = 0; y < cd.height; y++) {
|
||||
unsigned char* chrRow = &m_fontData->bitmap_data[cd.data_offset + ((cd.width+7)/8)*y];
|
||||
for (x = cd.xorig; x < cd.width; x++) {
|
||||
pixel = fbuf + 4 * (((posy + y - cd.yorig) * w) + (posx + x));
|
||||
for (yi = 0; yi < cd.height; yi++) {
|
||||
unsigned char* chrRow = &m_fontData->bitmap_data[cd.data_offset + ((cd.width+7)/8)*yi];
|
||||
for (xi = cd.xorig; xi < cd.width; xi++) {
|
||||
pixel = fbuf + 4 * (((posy + yi - cd.yorig) * w) + (posx + xi));
|
||||
if ((pixel < max) && (pixel > fbuf)) {
|
||||
int byteIdx = x/8;
|
||||
int bitIdx = 7 - (x%8);
|
||||
int byteIdx = xi/8;
|
||||
int bitIdx = 7 - (xi%8);
|
||||
|
||||
if (chrRow[byteIdx]&(1<<bitIdx)) {
|
||||
pixel[0] = col[0];
|
||||
|
@ -13,11 +13,10 @@
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
|
||||
#if !defined(linux) && (defined (__sparc) || defined (__sparc__))
|
||||
#if (defined (__sun__) || defined (__sun)) || (!defined(linux) && (defined (__sparc) || defined (__sparc__)))
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
|
||||
// just use default rounding for platforms where its not available
|
||||
#ifndef round
|
||||
#define round(x) (x)
|
||||
|
@ -11,11 +11,10 @@
|
||||
#include "solver_relax.h"
|
||||
#include "particletracer.h"
|
||||
|
||||
#if !defined(linux) && (defined (__sparc) || defined (__sparc__))
|
||||
#if (defined (__sun__) || defined (__sun)) || (!defined(linux) && (defined (__sparc) || defined (__sparc__)))
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
//! coarse step functions
|
||||
/*****************************************************************************/
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "loop_tools.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !defined(linux) && (defined (__sparc) || defined (__sparc__))
|
||||
#if (defined (__sun__) || defined (__sun)) || (!defined(linux) && (defined (__sparc) || defined (__sparc__)))
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
|
@ -91,8 +91,9 @@ extern struct ListBase editNurb;
|
||||
void mainqenter (unsigned short event, short val);
|
||||
void waitcursor(int);
|
||||
void allqueue(unsigned short event, short val);
|
||||
#define REDRAWVIEW3D 0x4010
|
||||
#define REDRAWBUTSEDIT 0x4019
|
||||
#define REDRAWVIEW3D 0x4010
|
||||
#define REDRAWBUTSOBJECT 0x4018
|
||||
#define REDRAWBUTSEDIT 0x4019
|
||||
struct Material;
|
||||
extern struct Material defmaterial;
|
||||
|
||||
|
@ -294,6 +294,7 @@ struct Object *modifiers_isDeformedByArmature(struct Object *ob);
|
||||
struct Object *modifiers_isDeformedByLattice(struct Object *ob);
|
||||
int modifiers_usesArmature(struct Object *ob, struct bArmature *arm);
|
||||
int modifiers_isDeformed(struct Object *ob);
|
||||
void modifier_freeTemporaryData(struct ModifierData *md);
|
||||
|
||||
int modifiers_indexInObject(struct Object *ob, struct ModifierData *md);
|
||||
|
||||
|
@ -169,6 +169,8 @@ typedef struct ParticleThreadContext {
|
||||
|
||||
int from, cfrom, distr;
|
||||
|
||||
struct ParticleData *tpars;
|
||||
|
||||
/* path caching */
|
||||
int editupdate, between, steps;
|
||||
int totchild, totparent;
|
||||
@ -203,15 +205,18 @@ void psys_disable_all(struct Object *ob);
|
||||
void psys_enable_all(struct Object *ob);
|
||||
int psys_ob_has_hair(struct Object *ob);
|
||||
int psys_in_edit_mode(struct ParticleSystem *psys);
|
||||
int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys);
|
||||
|
||||
void psys_free_settings(struct ParticleSettings *part);
|
||||
void free_child_path_cache(struct ParticleSystem *psys);
|
||||
void psys_free_path_cache(struct ParticleSystem *psys);
|
||||
void psys_free_render_memory(struct Object *ob, struct ParticleSystem *psys);
|
||||
void free_hair(struct ParticleSystem *psys);
|
||||
void free_keyed_keys(struct ParticleSystem *psys);
|
||||
void psys_free(struct Object * ob, struct ParticleSystem * psys);
|
||||
|
||||
void psys_particles_to_render_backup(struct Object *ob, struct ParticleSystem *psys);
|
||||
void psys_render_backup_to_particles(struct Object *ob, struct ParticleSystem *psys);
|
||||
|
||||
void clear_particles_from_cache(struct Object *ob, struct ParticleSystem *psys, int cfra);
|
||||
//void psys_remove_from_particle_list(struct Object *ob, short nbr, struct ParticleSystem *psys);
|
||||
|
||||
@ -280,6 +285,7 @@ void psys_particle_on_dm(struct Object *ob, struct DerivedMesh *dm, int from, in
|
||||
void initialize_particle(struct ParticleData *pa, int p, struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd);
|
||||
void reset_particle(struct ParticleData *pa, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd, struct Object *ob, float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot);
|
||||
|
||||
void psys_calc_dmfaces(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
|
||||
int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, float *fw, struct LinkNode *node);
|
||||
|
||||
/* ParticleEffectorCache->type */
|
||||
|
@ -1877,7 +1877,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
|
||||
int needMapping, CustomDataMask dataMask)
|
||||
{
|
||||
Mesh *me = ob->data;
|
||||
ModifierData *md = modifiers_getVirtualModifierList(ob);
|
||||
ModifierData *firstmd, *md;
|
||||
LinkNode *datamasks, *curr;
|
||||
CustomDataMask mask;
|
||||
float (*deformedVerts)[3] = NULL;
|
||||
@ -1886,6 +1886,8 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
|
||||
int fluidsimMeshUsed = 0;
|
||||
int required_mode;
|
||||
|
||||
md = firstmd = modifiers_getVirtualModifierList(ob);
|
||||
|
||||
modifiers_clearErrors(ob);
|
||||
|
||||
/* we always want to keep original indices */
|
||||
@ -2097,6 +2099,9 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
|
||||
}
|
||||
}
|
||||
|
||||
for(md=firstmd; md; md=md->next)
|
||||
modifier_freeTemporaryData(md);
|
||||
|
||||
/* Yay, we are done. If we have a DerivedMesh and deformed vertices
|
||||
* need to apply these back onto the DerivedMesh. If we have no
|
||||
* DerivedMesh then we need to build one.
|
||||
|
@ -292,14 +292,6 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i
|
||||
dob->index= index;
|
||||
ob->lay= lay;
|
||||
|
||||
/* allowing duplicators for particle systems... a bit silly still */
|
||||
{
|
||||
PartEff *paf= give_parteff(ob);
|
||||
if(paf) {
|
||||
Mat4Invert(ob->imat, ob->obmat);
|
||||
Mat4CpyMat4(paf->imat, ob->imat);
|
||||
}
|
||||
}
|
||||
return dob;
|
||||
}
|
||||
|
||||
@ -809,7 +801,7 @@ ListBase *object_duplilist(Scene *sce, Object *ob)
|
||||
|
||||
group_duplilist(duplilist, ob, 0); /* now recursive */
|
||||
|
||||
/* make copy already, because in group dupli's deform displists can be makde, requiring parent matrices */
|
||||
/* make copy already, because in group dupli's deform displists can be made, requiring parent matrices */
|
||||
for(dob= duplilist->first; dob; dob= dob->next)
|
||||
Mat4CpyMat4(dob->ob->obmat, dob->mat);
|
||||
}
|
||||
|
@ -1480,7 +1480,7 @@ void makeBevelList(Object *ob)
|
||||
|
||||
while(nu) {
|
||||
if(nu->pntsu<=1) {
|
||||
bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList");
|
||||
bl= MEM_callocN(sizeof(BevList)+1*sizeof(BevPoint), "makeBevelList");
|
||||
BLI_addtail(&(cu->bev), bl);
|
||||
bl->nr= 0;
|
||||
} else {
|
||||
@ -1490,8 +1490,7 @@ void makeBevelList(Object *ob)
|
||||
resolu= nu->resolu;
|
||||
|
||||
if((nu->type & 7)==CU_POLY) {
|
||||
|
||||
len= nu->pntsu;
|
||||
|
||||
bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList");
|
||||
BLI_addtail(&(cu->bev), bl);
|
||||
|
||||
@ -1544,7 +1543,7 @@ void makeBevelList(Object *ob)
|
||||
bevp->z= prevbezt->vec[1][2];
|
||||
bevp->alfa= prevbezt->alfa;
|
||||
bevp->f1= SELECT;
|
||||
bevp->f2= SELECT;
|
||||
bevp->f2= 0;
|
||||
bevp++;
|
||||
bl->nr++;
|
||||
bl->flag= 1;
|
||||
|
@ -1900,7 +1900,7 @@ static void dag_object_time_update_flags(Object *ob)
|
||||
ParticleSystem *psys= ob->particlesystem.first;
|
||||
|
||||
for(; psys; psys=psys->next) {
|
||||
if(psys->flag & PSYS_ENABLED) {
|
||||
if(psys_check_enabled(ob, psys)) {
|
||||
ob->recalc |= OB_RECALC_DATA;
|
||||
break;
|
||||
}
|
||||
|
@ -5358,7 +5358,7 @@ static void particleSystemModifier_deformVerts(
|
||||
else
|
||||
return;
|
||||
|
||||
if((psys->flag&PSYS_ENABLED)==0)
|
||||
if(!psys_check_enabled(ob, psys))
|
||||
return;
|
||||
|
||||
if(dm==0){
|
||||
@ -7513,3 +7513,14 @@ int modifiers_usesPointCache(Object *ob)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void modifier_freeTemporaryData(ModifierData *md)
|
||||
{
|
||||
if(md->type == eModifierType_Armature) {
|
||||
ArmatureModifierData *amd= (ArmatureModifierData*)md;
|
||||
|
||||
if(amd->prevCos)
|
||||
MEM_freeN(amd->prevCos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2201,7 +2201,7 @@ void object_handle_update(Object *ob)
|
||||
|
||||
psys= ob->particlesystem.first;
|
||||
while(psys) {
|
||||
if(psys->flag & PSYS_ENABLED) {
|
||||
if(psys_check_enabled(ob, psys)) {
|
||||
particle_system_update(ob, psys);
|
||||
psys= psys->next;
|
||||
}
|
||||
|
@ -77,6 +77,7 @@
|
||||
#include "BKE_bad_level_calls.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
|
||||
#include "blendef.h"
|
||||
#include "RE_render_ext.h"
|
||||
@ -248,6 +249,23 @@ int psys_in_edit_mode(ParticleSystem *psys)
|
||||
{
|
||||
return ((G.f & G_PARTICLEEDIT) && psys==psys_get_current(OBACT) && psys->edit);
|
||||
}
|
||||
int psys_check_enabled(Object *ob, ParticleSystem *psys)
|
||||
{
|
||||
ParticleSystemModifierData *psmd;
|
||||
|
||||
if(!(psys->flag & PSYS_ENABLED))
|
||||
return 0;
|
||||
|
||||
psmd= psys_get_modifier(ob, psys);
|
||||
if(G.rendering) {
|
||||
if(!psys->renderdata || !(psmd->modifier.mode & eModifierMode_Render))
|
||||
return 0;
|
||||
}
|
||||
else if(!(psmd->modifier.mode & eModifierMode_Realtime))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* Freeing stuff */
|
||||
@ -301,27 +319,6 @@ void psys_free_path_cache(ParticleSystem *psys)
|
||||
}
|
||||
free_child_path_cache(psys);
|
||||
}
|
||||
void psys_free_render_memory(Object *ob, ParticleSystem *psys)
|
||||
{
|
||||
ParticleSystemModifierData *psmd;
|
||||
|
||||
/* this is a bad function, but saves a lot of memory rendering.
|
||||
* particles should really be generated on the fly with render
|
||||
* settings! */
|
||||
psys_free_path_cache(psys);
|
||||
|
||||
if(psys->child){
|
||||
MEM_freeN(psys->child);
|
||||
psys->child=0;
|
||||
psys->totchild=0;
|
||||
}
|
||||
|
||||
psmd= psys_get_modifier(ob, psys);
|
||||
psmd->flag &= ~eParticleSystemFlag_psys_updated;
|
||||
|
||||
psys->recalc |= PSYS_ALLOC|PSYS_DISTR;
|
||||
//DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
|
||||
}
|
||||
/* free everything */
|
||||
void psys_free(Object *ob, ParticleSystem * psys)
|
||||
{
|
||||
@ -366,6 +363,92 @@ void psys_free(Object *ob, ParticleSystem * psys)
|
||||
}
|
||||
}
|
||||
|
||||
/* these two functions move away particle data and bring it back after
|
||||
* rendering, to make different render settings possible without
|
||||
* removing the previous data. this should be solved properly once */
|
||||
|
||||
typedef struct ParticleRenderDataup {
|
||||
ChildParticle *child;
|
||||
ParticleCacheKey **pathcache;
|
||||
ParticleCacheKey **childcache;
|
||||
int totchild, totcached, totchildcache;
|
||||
DerivedMesh *dm;
|
||||
int totdmvert, totdmedge, totdmface;
|
||||
} ParticleRenderDataup;
|
||||
|
||||
void psys_particles_to_render_backup(Object *ob, ParticleSystem *psys)
|
||||
{
|
||||
ParticleRenderDataup *data;
|
||||
ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
|
||||
|
||||
if(!G.rendering)
|
||||
return;
|
||||
|
||||
data= MEM_callocN(sizeof(ParticleRenderDataup), "ParticleRenderDataup");
|
||||
|
||||
data->child= psys->child;
|
||||
data->totchild= psys->totchild;
|
||||
data->pathcache= psys->pathcache;
|
||||
data->totcached= psys->totcached;
|
||||
data->childcache= psys->childcache;
|
||||
data->totchildcache= psys->totchildcache;
|
||||
|
||||
if(psmd->dm)
|
||||
data->dm= CDDM_copy(psmd->dm);
|
||||
data->totdmvert= psmd->totdmvert;
|
||||
data->totdmedge= psmd->totdmedge;
|
||||
data->totdmface= psmd->totdmface;
|
||||
|
||||
psys->child= NULL;
|
||||
psys->pathcache= NULL;
|
||||
psys->childcache= NULL;
|
||||
psys->totchild= psys->totcached= psys->totchildcache= 0;
|
||||
|
||||
psys->renderdata= data;
|
||||
}
|
||||
|
||||
void psys_render_backup_to_particles(Object *ob, ParticleSystem *psys)
|
||||
{
|
||||
ParticleRenderDataup *data;
|
||||
ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
|
||||
|
||||
data= psys->renderdata;
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
if(psmd->dm) {
|
||||
psmd->dm->needsFree= 1;
|
||||
psmd->dm->release(psmd->dm);
|
||||
}
|
||||
|
||||
psys_free_path_cache(psys);
|
||||
|
||||
if(psys->child){
|
||||
MEM_freeN(psys->child);
|
||||
psys->child= 0;
|
||||
psys->totchild= 0;
|
||||
}
|
||||
|
||||
psys->child= data->child;
|
||||
psys->totchild= data->totchild;
|
||||
psys->pathcache= data->pathcache;
|
||||
psys->totcached= data->totcached;
|
||||
psys->childcache= data->childcache;
|
||||
psys->totchildcache= data->totchildcache;
|
||||
|
||||
psmd->dm= data->dm;
|
||||
psmd->totdmvert= data->totdmvert;
|
||||
psmd->totdmedge= data->totdmedge;
|
||||
psmd->totdmface= data->totdmface;
|
||||
psmd->flag &= ~eParticleSystemFlag_psys_updated;
|
||||
|
||||
if(psys->part->from==PART_FROM_FACE && psmd->dm)
|
||||
psys_calc_dmfaces(ob, psmd->dm, psys);
|
||||
|
||||
MEM_freeN(data);
|
||||
psys->renderdata= NULL;
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* Interpolated Particles */
|
||||
/************************************************/
|
||||
@ -691,12 +774,13 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float *
|
||||
#define PARTICLE_ERROR(_nor, _vec) _vec[0]=_vec[1]=_vec[2]=0.0; if(_nor){ _nor[0]=_nor[1]=0.0; _nor[2]=1.0; }
|
||||
void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor)
|
||||
{
|
||||
float (*orcodata)[3] = dm->getVertDataArray(dm, CD_ORCO);
|
||||
float (*orcodata)[3];
|
||||
|
||||
if(index < 0){ /* 'no dm' error has happened! */
|
||||
PARTICLE_ERROR(nor, vec);
|
||||
return;
|
||||
}
|
||||
orcodata= dm->getVertDataArray(dm, CD_ORCO);
|
||||
|
||||
if (dm->deformedOnly || index_dmcache == DMCACHE_ISCHILD) {
|
||||
/* this works for meshes with deform verts only - constructive modifiers wont work properly*/
|
||||
@ -1406,7 +1490,7 @@ int psys_threads_init_path(ParticleThread *threads, float cfra, int editupdate)
|
||||
|
||||
/*---start figuring out what is actually wanted---*/
|
||||
if(psys_in_edit_mode(psys))
|
||||
if(G.rendering==0 && (psys->edit==NULL || pset->flag & PE_SHOW_CHILD)==0)
|
||||
if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_SHOW_CHILD)==0)
|
||||
totchild=0;
|
||||
|
||||
if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
|
||||
@ -1415,7 +1499,7 @@ int psys_threads_init_path(ParticleThread *threads, float cfra, int editupdate)
|
||||
between=1;
|
||||
}
|
||||
|
||||
if(G.rendering)
|
||||
if(psys->renderdata)
|
||||
steps=(int)pow(2.0,(double)part->ren_step);
|
||||
else{
|
||||
totchild=(int)((float)totchild*(float)part->disp/100.0f);
|
||||
@ -1870,7 +1954,7 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
|
||||
if((psys->flag & PSYS_HAIR_DONE)==0 && (psys->flag & PSYS_KEYED)==0)
|
||||
return;
|
||||
|
||||
if(G.rendering)
|
||||
if(psys->renderdata)
|
||||
steps = (int)pow(2.0, (double)psys->part->ren_step);
|
||||
else if(psys_in_edit_mode(psys)){
|
||||
edit=psys->edit;
|
||||
@ -2290,7 +2374,7 @@ void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData
|
||||
psys_particle_on_dm(ob, dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco, 0);
|
||||
|
||||
/* see psys_face_mat for why this function is called */
|
||||
transform_mesh_orco_verts(ob->data, orco, 1, 1);
|
||||
transform_mesh_orco_verts(ob->data, &orco, 1, 1);
|
||||
VECCOPY(hairmat[3],orco);
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ static int get_current_display_percentage(ParticleSystem *psys)
|
||||
{
|
||||
ParticleSettings *part=psys->part;
|
||||
|
||||
if(G.rendering || (part->child_nbr && part->childtype))
|
||||
if(psys->renderdata || (part->child_nbr && part->childtype))
|
||||
return 100;
|
||||
|
||||
if(part->phystype==PART_PHYS_KEYED){
|
||||
@ -136,7 +136,7 @@ static void alloc_particles(ParticleSystem *psys, int new_totpart)
|
||||
}
|
||||
psys->particles=newpars;
|
||||
|
||||
child_nbr= (G.rendering)? psys->part->ren_child_nbr: psys->part->child_nbr;
|
||||
child_nbr= (psys->renderdata)? psys->part->ren_child_nbr: psys->part->child_nbr;
|
||||
if(child_nbr && psys->part->childtype){
|
||||
if(psys->child)
|
||||
MEM_freeN(psys->child);
|
||||
@ -155,7 +155,7 @@ static void alloc_particles(ParticleSystem *psys, int new_totpart)
|
||||
}
|
||||
|
||||
/* only run this if from == PART_FROM_FACE */
|
||||
static void psys_calc_dmfaces(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
|
||||
void psys_calc_dmfaces(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
|
||||
{
|
||||
/* use for building derived mesh face-origin info,
|
||||
node - the allocated links - total derived mesh face count
|
||||
@ -472,7 +472,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
|
||||
ParticleThreadContext *ctx= thread->ctx;
|
||||
Object *ob= ctx->ob;
|
||||
DerivedMesh *dm= ctx->dm;
|
||||
ParticleData *tpars=0, *tpa;
|
||||
ParticleData *tpa;
|
||||
ParticleSettings *part= ctx->psys->part;
|
||||
float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3], ornor1[3];
|
||||
float cur_d, min_d;
|
||||
@ -494,6 +494,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
|
||||
int w, maxw;
|
||||
|
||||
psys_particle_on_dm(ctx->ob,ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
|
||||
transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
|
||||
maxw = BLI_kdtree_find_n_nearest(ctx->tree,3,orco1,NULL,ptn);
|
||||
|
||||
for(w=0; w<maxw; w++){
|
||||
@ -586,7 +587,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
|
||||
//pa->verts[1]=0;
|
||||
//pa->verts[2]=0;
|
||||
|
||||
tpa=tpars+ctx->index[p];
|
||||
tpa=ctx->tpars+ctx->index[p];
|
||||
pa->num=ctx->index[p];
|
||||
pa->fuv[0]=tpa->fuv[0];
|
||||
pa->fuv[1]=tpa->fuv[1];
|
||||
@ -633,6 +634,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
|
||||
do_seams= (part->flag&PART_CHILD_SEAMS && ctx->seams);
|
||||
|
||||
psys_particle_on_dm(ob,dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,0,0,orco1,ornor1);
|
||||
transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
|
||||
maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,orco1,ornor1,ptn);
|
||||
|
||||
maxd=ptn[maxw-1].dist;
|
||||
@ -778,7 +780,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
|
||||
Object *ob= ctx->ob;
|
||||
ParticleSystem *psys= ctx->psys;
|
||||
Object *tob;
|
||||
ParticleData *pa=0, *tpars;
|
||||
ParticleData *pa=0, *tpars= 0;
|
||||
ParticleSettings *part;
|
||||
ParticleSystem *tpsys;
|
||||
ParticleSeam *seams= 0;
|
||||
@ -820,6 +822,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
|
||||
|
||||
for(p=0,pa=psys->particles; p<totpart; p++,pa++){
|
||||
psys_particle_on_dm(ob,dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor);
|
||||
transform_mesh_orco_verts((Mesh*)ob->data, &orco, 1, 1);
|
||||
BLI_kdtree_insert(tree, p, orco, ornor);
|
||||
}
|
||||
|
||||
@ -874,7 +877,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
|
||||
}
|
||||
else{
|
||||
/* no need to figure out distribution */
|
||||
int child_nbr= (G.rendering)? part->ren_child_nbr: part->child_nbr;
|
||||
int child_nbr= (psys->renderdata)? part->ren_child_nbr: part->child_nbr;
|
||||
|
||||
for(i=0; i<child_nbr; i++){
|
||||
for(p=0; p<psys->totpart; p++,cpa++){
|
||||
@ -923,8 +926,10 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
|
||||
tree=BLI_kdtree_new(totvert);
|
||||
|
||||
for(p=0; p<totvert; p++){
|
||||
if(orcodata)
|
||||
if(orcodata) {
|
||||
VECCOPY(co,orcodata[p])
|
||||
transform_mesh_orco_verts((Mesh*)ob->data, &co, 1, 1);
|
||||
}
|
||||
else
|
||||
VECCOPY(co,mv[p].co)
|
||||
BLI_kdtree_insert(tree,p,co,NULL);
|
||||
@ -990,7 +995,8 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
|
||||
|
||||
/* 2.1 */
|
||||
if((part->flag&PART_EDISTR || children) && ELEM(from,PART_FROM_PARTICLE,PART_FROM_VERT)==0){
|
||||
float totarea=0.0, *co1, *co2, *co3, *co4;
|
||||
MVert *v1, *v2, *v3, *v4;
|
||||
float totarea=0.0, co1[3], co2[3], co3[3], co4[3];
|
||||
float (*orcodata)[3];
|
||||
|
||||
orcodata= dm->getVertDataArray(dm, CD_ORCO);
|
||||
@ -999,21 +1005,31 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
|
||||
MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
|
||||
|
||||
if(orcodata) {
|
||||
co1= orcodata[mf->v1];
|
||||
co2= orcodata[mf->v2];
|
||||
co3= orcodata[mf->v3];
|
||||
VECCOPY(co1, orcodata[mf->v1]);
|
||||
VECCOPY(co2, orcodata[mf->v2]);
|
||||
VECCOPY(co3, orcodata[mf->v3]);
|
||||
transform_mesh_orco_verts((Mesh*)ob->data, &co1, 1, 1);
|
||||
transform_mesh_orco_verts((Mesh*)ob->data, &co2, 1, 1);
|
||||
transform_mesh_orco_verts((Mesh*)ob->data, &co3, 1, 1);
|
||||
}
|
||||
else {
|
||||
co1= ((MVert*)dm->getVertData(dm,mf->v1,CD_MVERT))->co;
|
||||
co2= ((MVert*)dm->getVertData(dm,mf->v2,CD_MVERT))->co;
|
||||
co3= ((MVert*)dm->getVertData(dm,mf->v3,CD_MVERT))->co;
|
||||
v1= (MVert*)dm->getVertData(dm,mf->v1,CD_MVERT);
|
||||
v2= (MVert*)dm->getVertData(dm,mf->v2,CD_MVERT);
|
||||
v3= (MVert*)dm->getVertData(dm,mf->v3,CD_MVERT);
|
||||
VECCOPY(co1, v1->co);
|
||||
VECCOPY(co2, v2->co);
|
||||
VECCOPY(co3, v3->co);
|
||||
}
|
||||
|
||||
if (mf->v4){
|
||||
if(orcodata)
|
||||
co4= orcodata[mf->v4];
|
||||
else
|
||||
co4= ((MVert*)dm->getVertData(dm,mf->v4,CD_MVERT))->co;
|
||||
if(orcodata) {
|
||||
VECCOPY(co4, orcodata[mf->v4]);
|
||||
transform_mesh_orco_verts((Mesh*)ob->data, &co4, 1, 1);
|
||||
}
|
||||
else {
|
||||
v4= (MVert*)dm->getVertData(dm,mf->v4,CD_MVERT);
|
||||
VECCOPY(co4, v4->co);
|
||||
}
|
||||
cur= AreaQ3Dfl(co1, co2, co3, co4);
|
||||
}
|
||||
else
|
||||
@ -1096,9 +1112,9 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
|
||||
}
|
||||
}
|
||||
else {
|
||||
float step, pos;
|
||||
double step, pos;
|
||||
|
||||
step= (totpart <= 1)? 0.5f: 1.0f/(totpart-1);
|
||||
step= (totpart <= 1)? 0.5: 1.0/(totpart-1);
|
||||
pos= 0.0f;
|
||||
i= 0;
|
||||
|
||||
@ -1157,6 +1173,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
|
||||
ctx->cfrom= cfrom;
|
||||
ctx->distr= distr;
|
||||
ctx->dm= dm;
|
||||
ctx->tpars= tpars;
|
||||
|
||||
seed= 31415926 + ctx->psys->seed;
|
||||
|
||||
@ -1434,9 +1451,6 @@ static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleS
|
||||
initialize_particle(pa,p,ob,psys,psmd);
|
||||
|
||||
/* store the derived mesh face index for each particle */
|
||||
//if(psys->part->from==PART_FROM_FACE)
|
||||
// psys_calc_dmfaces(ob, psmd->dm, psys);
|
||||
|
||||
icu=find_ipocurve(psys->part->ipo,PART_EMIT_FREQ);
|
||||
if(icu){
|
||||
float time=psys->part->sta, end=psys->part->end;
|
||||
@ -1715,9 +1729,6 @@ static void reset_all_particles(Object *ob, ParticleSystem *psys, ParticleSystem
|
||||
float *vg_tan=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_TAN);
|
||||
float *vg_rot=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_ROT);
|
||||
|
||||
//if (psys->part->from == PART_FROM_FACE)
|
||||
// psys_calc_dmfaces(ob, psmd->dm, psys);
|
||||
|
||||
for(p=from, pa=psys->particles+from; p<totpart; p++, pa++)
|
||||
reset_particle(pa, psys, psmd, ob, dtime, cfra, vg_vel, vg_tan, vg_rot);
|
||||
|
||||
@ -4167,7 +4178,7 @@ static void psys_update_path_cache(Object *ob, ParticleSystemModifierData *psmd,
|
||||
ParticleSettings *part=psys->part;
|
||||
ParticleEditSettings *pset=&G.scene->toolsettings->particle;
|
||||
int distr=0,alloc=0;
|
||||
int child_nbr= (G.rendering)? part->ren_child_nbr: part->child_nbr;
|
||||
int child_nbr= (psys->renderdata)? part->ren_child_nbr: part->child_nbr;
|
||||
|
||||
if((psys->part->childtype && psys->totchild != psys->totpart*child_nbr) || psys->recalc&PSYS_ALLOC)
|
||||
alloc=1;
|
||||
@ -4205,11 +4216,10 @@ static void hair_step(Object *ob, ParticleSystemModifierData *psmd, ParticleSyst
|
||||
{
|
||||
ParticleSettings *part = psys->part;
|
||||
|
||||
if(psys->recalc & PSYS_DISTR) {
|
||||
if(psys->recalc & PSYS_DISTR)
|
||||
/* need this for changing subsurf levels */
|
||||
psys_calc_dmfaces(ob, psmd->dm, psys);
|
||||
}
|
||||
|
||||
|
||||
if(psys->effectors.first)
|
||||
psys_end_effectors(psys);
|
||||
|
||||
@ -4377,6 +4387,10 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
|
||||
|
||||
psys->recalc &= ~PSYS_TYPE;
|
||||
alloc = 1;
|
||||
|
||||
/* this is a bad level call, but currently type change
|
||||
* can happen after redraw, so force redraw from here */
|
||||
allqueue(REDRAWBUTSOBJECT, 0);
|
||||
}
|
||||
else
|
||||
oldtotpart = psys->totpart;
|
||||
@ -4386,7 +4400,7 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
|
||||
else
|
||||
totpart = psys->part->totpart;
|
||||
|
||||
child_nbr= (G.rendering)? part->ren_child_nbr: part->child_nbr;
|
||||
child_nbr= (psys->renderdata)? part->ren_child_nbr: part->child_nbr;
|
||||
if(oldtotpart != totpart || psys->recalc&PSYS_ALLOC || (psys->part->childtype && psys->totchild != psys->totpart*child_nbr))
|
||||
alloc = 1;
|
||||
|
||||
@ -4428,7 +4442,7 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
|
||||
/* set particles to be not calculated */
|
||||
disp= (float)get_current_display_percentage(psys)/50.0f-1.0f;
|
||||
|
||||
if(disp<1.0f) for(p=0, pa=psys->particles; p<totpart; p++,pa++){
|
||||
for(p=0, pa=psys->particles; p<totpart; p++,pa++){
|
||||
if(pa->r_rot[0] > disp)
|
||||
pa->flag |= PARS_NO_DISP;
|
||||
else
|
||||
@ -4436,12 +4450,9 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
|
||||
}
|
||||
|
||||
/* ok now we're all set so let's go */
|
||||
if(psys->totpart) {
|
||||
//if(psys->part->from==PART_FROM_FACE) {
|
||||
// psys_calc_dmfaces(ob, psmd->dm, psys);
|
||||
//}
|
||||
if(psys->totpart)
|
||||
dynamics_step(ob,psys,psmd,cfra,vg_vel,vg_tan,vg_rot,vg_size);
|
||||
}
|
||||
|
||||
psys->recalc = 0;
|
||||
psys->cfra=cfra;
|
||||
|
||||
@ -4513,21 +4524,24 @@ void particle_system_update(Object *ob, ParticleSystem *psys){
|
||||
|
||||
ParticleSystemModifierData *psmd=0;
|
||||
float cfra;
|
||||
|
||||
if((psys->flag & PSYS_ENABLED)==0) return;
|
||||
|
||||
psmd=psys_get_modifier(ob,psys);
|
||||
if(!psys_check_enabled(ob, psys))
|
||||
return;
|
||||
|
||||
cfra=bsystem_time(ob,(float)CFRA,0.0);
|
||||
psmd= psys_get_modifier(ob, psys);
|
||||
|
||||
/* system was already updated from modifier stack */
|
||||
if(psmd->flag&eParticleSystemFlag_psys_updated){
|
||||
if(psmd->flag&eParticleSystemFlag_psys_updated) {
|
||||
psmd->flag &= ~eParticleSystemFlag_psys_updated;
|
||||
/* make sure it really was updated to cfra */
|
||||
if(psys->cfra==cfra)
|
||||
return;
|
||||
}
|
||||
|
||||
if(!psmd->dm)
|
||||
return;
|
||||
|
||||
/* baked path softbody */
|
||||
if(psys->part->type==PART_HAIR && psys->soft)
|
||||
psys_to_softbody(ob, psys, 0);
|
||||
@ -4561,6 +4575,6 @@ void particle_system_update(Object *ob, ParticleSystem *psys){
|
||||
|
||||
system_step(ob,psys,psmd,cfra);
|
||||
|
||||
Mat4CpyMat4(psys->imat, ob->imat); /* used for duplicators */
|
||||
Mat4Invert(psys->imat, ob->obmat); /* used for duplicators */
|
||||
}
|
||||
|
||||
|
@ -368,7 +368,7 @@ void BLI_setInterruptCallBack(int (*f)(void));
|
||||
char *BLI_strcasestr(const char *s, const char *find);
|
||||
int BLI_strcasecmp(const char *s1, const char *s2);
|
||||
int BLI_strncasecmp(const char *s1, const char *s2, int n);
|
||||
void BLI_timestr(double time, char *str);
|
||||
void BLI_timestr(double _time, char *str); /* time var is global */
|
||||
|
||||
/**
|
||||
* Trick to address 32 GB with an int (only for malloced pointers)
|
||||
|
@ -1621,13 +1621,13 @@ void BLI_string_to_utf8(char *original, char *utf_8, char *code)
|
||||
}
|
||||
#endif // WITH_ICONV
|
||||
|
||||
void BLI_timestr(double time, char *str)
|
||||
void BLI_timestr(double _time, char *str)
|
||||
{
|
||||
/* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
|
||||
int hr= ((int) time) / (60*60);
|
||||
int min= ( ((int) time) / 60 ) % 60;
|
||||
int sec= ((int) (time)) % 60;
|
||||
int hun= ((int) (time * 100.0)) % 100;
|
||||
int hr= ( (int) _time) / (60*60);
|
||||
int min= (((int) _time) / 60 ) % 60;
|
||||
int sec= ( (int) (_time)) % 60;
|
||||
int hun= ( (int) (_time * 100.0)) % 100;
|
||||
|
||||
if (hr) {
|
||||
sprintf(str, "%.2d:%.2d:%.2d.%.2d",hr,min,sec,hun);
|
||||
|
@ -7109,6 +7109,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
oldnewmap_insert(fd->libmap, psys->part, psys->part, 0);
|
||||
|
||||
part->id.us--;
|
||||
part->id.flag |= (ob->id.flag & LIB_NEEDLINK);
|
||||
|
||||
psys->totpart=0;
|
||||
psys->flag=PSYS_ENABLED|PSYS_CURRENT;
|
||||
|
@ -84,8 +84,11 @@ void delete_armature(void);
|
||||
void deselectall_armature(int toggle, int doundo);
|
||||
void deselectall_posearmature (struct Object *ob, int test, int doundo);
|
||||
int draw_armature(struct Base *base, int dt);
|
||||
|
||||
void extrude_armature(int forked);
|
||||
void subdivide_armature(int numcuts);
|
||||
void fill_bones_armature(void);
|
||||
void merge_armature(void);
|
||||
|
||||
void free_editArmature(void);
|
||||
|
||||
|
@ -57,11 +57,7 @@
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#if defined(__sun__) && !defined(__sparc__)
|
||||
#include <mesa/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
* these should be phased out. cpack should be replaced in
|
||||
|
@ -230,7 +230,7 @@ typedef struct TransInfo {
|
||||
// for manipulator exceptions, like scaling using center point, drawing help lines
|
||||
#define T_USES_MANIPULATOR (1 << 7)
|
||||
|
||||
/* restrictions flags */
|
||||
/* restrictions flags */
|
||||
#define T_ALL_RESTRICTIONS ((1 << 8)|(1 << 9)|(1 << 10))
|
||||
#define T_NO_CONSTRAINT (1 << 8)
|
||||
#define T_NULL_ONE (1 << 9)
|
||||
@ -239,14 +239,17 @@ typedef struct TransInfo {
|
||||
#define T_PROP_EDIT (1 << 11)
|
||||
#define T_PROP_CONNECTED (1 << 12)
|
||||
|
||||
/* if MMB is pressed or not */
|
||||
/* if MMB is pressed or not */
|
||||
#define T_MMB_PRESSED (1 << 13)
|
||||
|
||||
#define T_V3D_ALIGN (1 << 14)
|
||||
#define T_2D_EDIT (1 << 15) /* for 2d views like uv or ipo */
|
||||
/* for 2d views like uv or ipo */
|
||||
#define T_2D_EDIT (1 << 15)
|
||||
#define T_CLIP_UV (1 << 16)
|
||||
|
||||
#define T_FREE_CUSTOMDATA (1 << 17)
|
||||
/* auto-ik is on */
|
||||
#define T_AUTOIK (1 << 18)
|
||||
|
||||
/* ******************************************************************************** */
|
||||
|
||||
@ -375,6 +378,8 @@ void sort_trans_data_dist(TransInfo *t);
|
||||
void add_tdi_poin(float *poin, float *old, float delta);
|
||||
void special_aftertrans_update(TransInfo *t);
|
||||
|
||||
void transform_autoik_update(TransInfo *t, short mode);
|
||||
|
||||
/* auto-keying stuff used by special_aftertrans_update */
|
||||
void autokeyframe_ob_cb_func(struct Object *ob, int tmode);
|
||||
void autokeyframe_pose_cb_func(struct Object *ob, int tmode, short targetless_ik);
|
||||
@ -458,3 +463,4 @@ char handleNumInput(NumInput *n, unsigned short event);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -126,7 +126,8 @@ typedef struct bKinematicConstraint {
|
||||
Object *tar;
|
||||
short iterations; /* Maximum number of iterations to try */
|
||||
short flag; /* Like CONSTRAINT_IK_TIP */
|
||||
int rootbone; /* index to rootbone, if zero go all the way to mother bone */
|
||||
short rootbone; /* index to rootbone, if zero go all the way to mother bone */
|
||||
short max_rootbone; /* for auto-ik, maximum length of chain */
|
||||
char subtarget[32]; /* String to specify sub-object target */
|
||||
|
||||
Object *poletar; /* Pole vector target */
|
||||
|
@ -43,11 +43,20 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* generic - all structs which are used in linked-lists used this */
|
||||
typedef struct Link
|
||||
{
|
||||
struct Link *next,*prev;
|
||||
} Link;
|
||||
|
||||
|
||||
/* use this when it is not worth defining a custom one... */
|
||||
typedef struct LinkData
|
||||
{
|
||||
struct LinkData *next, *prev;
|
||||
void *data;
|
||||
} LinkData;
|
||||
|
||||
/* never change the size of this! genfile.c detects pointerlen with it */
|
||||
typedef struct ListBase
|
||||
{
|
||||
|
@ -279,6 +279,7 @@ extern Object workob;
|
||||
#define OB_DUPLIFACES 512
|
||||
#define OB_DUPLIFACES_SCALE 1024
|
||||
#define OB_DUPLIPARTS 2048
|
||||
#define OB_RENDER_DUPLI 4096
|
||||
|
||||
/* (short) ipoflag */
|
||||
#define OB_DRAWKEY 1
|
||||
@ -342,6 +343,8 @@ extern Object workob;
|
||||
#define OB_CIRCLE 3
|
||||
#define OB_SINGLE_ARROW 4
|
||||
#define OB_CUBE 5
|
||||
#define OB_EMPTY_SPHERE 6
|
||||
#define OB_EMPTY_CONE 7
|
||||
|
||||
/* boundtype */
|
||||
#define OB_BOUND_BOX 0
|
||||
@ -453,3 +456,4 @@ extern Object workob;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -198,6 +198,9 @@ typedef struct ParticleSystem{
|
||||
|
||||
/* if you change these remember to update array lengths to PSYS_TOT_VG! */
|
||||
short vgroup[11], vg_neg, rt3[2];
|
||||
|
||||
/* temporary storage during render */
|
||||
void *renderdata;
|
||||
}ParticleSystem;
|
||||
|
||||
/* general particle maximums */
|
||||
|
@ -363,7 +363,8 @@ typedef struct ToolSettings {
|
||||
short uvcalc_mapalign;
|
||||
short uvcalc_flag;
|
||||
|
||||
short pad2;
|
||||
/* Auto-IK */
|
||||
short autoik_chainlen;
|
||||
|
||||
/* Image Paint (8 byte aligned please!) */
|
||||
struct ImagePaintSettings imapaint;
|
||||
@ -443,6 +444,10 @@ typedef struct SculptData
|
||||
/* Symmetry is separate from the other BrushData because the same
|
||||
settings are always used for all brush types */
|
||||
char symm;
|
||||
|
||||
/* Added to store if the 'Rake' setting has been set */
|
||||
char rake;
|
||||
char pad[7];
|
||||
} SculptData;
|
||||
|
||||
typedef struct Scene {
|
||||
|
@ -51,7 +51,7 @@ static void node_shader_exec_geom(void *data, bNode *node, bNodeStack **in, bNod
|
||||
if(data) {
|
||||
ShadeInput *shi= ((ShaderCallData *)data)->shi;
|
||||
NodeGeometry *ngeo= (NodeGeometry*)node->storage;
|
||||
ShadeInputUV *suv= &shi->uv[0];
|
||||
ShadeInputUV *suv= &shi->uv[shi->actuv];
|
||||
static float defaultvcol[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
static float front= 0.0;
|
||||
int i;
|
||||
|
@ -362,47 +362,34 @@ static char Method_Exit_doc[] = "() - Exit the windowing interface";
|
||||
*/
|
||||
PyObject *M_Button_List = NULL;
|
||||
|
||||
/*
|
||||
* here we engage in some macro trickery to define the PyMethodDef table
|
||||
*/
|
||||
|
||||
#define _MethodDef(func, prefix) \
|
||||
{#func, prefix##_##func, METH_VARARGS, prefix##_##func##_doc}
|
||||
|
||||
/* So that _MethodDef(delete, Scene) expands to:
|
||||
* {"delete", Scene_delete, METH_VARARGS, Scene_delete_doc} */
|
||||
|
||||
#undef MethodDef
|
||||
#define MethodDef(func) _MethodDef(func, Method)
|
||||
|
||||
static struct PyMethodDef Draw_methods[] = {
|
||||
MethodDef( Create ),
|
||||
MethodDef( UIBlock ),
|
||||
MethodDef( Button ),
|
||||
MethodDef( Toggle ),
|
||||
MethodDef( Menu ),
|
||||
MethodDef( Slider ),
|
||||
MethodDef( Scrollbar ),
|
||||
MethodDef( ColorPicker ),
|
||||
MethodDef( Normal ),
|
||||
MethodDef( Number ),
|
||||
MethodDef( String ),
|
||||
MethodDef( GetStringWidth ),
|
||||
MethodDef( Text ),
|
||||
MethodDef( Label ),
|
||||
MethodDef( PupMenu ),
|
||||
MethodDef( PupIntInput ),
|
||||
MethodDef( PupFloatInput ),
|
||||
MethodDef( PupStrInput ),
|
||||
MethodDef( PupBlock ),
|
||||
MethodDef( Image ),
|
||||
{"Create", (PyCFunction)Method_Create, METH_VARARGS, Method_Create_doc},
|
||||
{"UIBlock", (PyCFunction)Method_UIBlock, METH_VARARGS, Method_UIBlock_doc},
|
||||
{"Button", (PyCFunction)Method_Button, METH_VARARGS, Method_Button_doc},
|
||||
{"Toggle", (PyCFunction)Method_Toggle, METH_VARARGS, Method_Toggle_doc},
|
||||
{"Menu", (PyCFunction)Method_Menu, METH_VARARGS, Method_Menu_doc},
|
||||
{"Slider", (PyCFunction)Method_Slider, METH_VARARGS, Method_Slider_doc},
|
||||
{"Scrollbar", (PyCFunction)Method_Scrollbar, METH_VARARGS, Method_Scrollbar_doc},
|
||||
{"ColorPicker", (PyCFunction)Method_ColorPicker, METH_VARARGS, Method_ColorPicker_doc},
|
||||
{"Normal", (PyCFunction)Method_Normal, METH_VARARGS, Method_Normal_doc},
|
||||
{"Number", (PyCFunction)Method_Number, METH_VARARGS, Method_Number_doc},
|
||||
{"String", (PyCFunction)Method_String, METH_VARARGS, Method_String_doc},
|
||||
{"GetStringWidth", (PyCFunction)Method_GetStringWidth, METH_VARARGS, Method_GetStringWidth_doc},
|
||||
{"Text", (PyCFunction)Method_Text, METH_VARARGS, Method_Text_doc},
|
||||
{"Label", (PyCFunction)Method_Label, METH_VARARGS, Method_Label_doc},
|
||||
{"PupMenu", (PyCFunction)Method_PupMenu, METH_VARARGS, Method_PupMenu_doc},
|
||||
{"PupIntInput", (PyCFunction)Method_PupIntInput, METH_VARARGS, Method_PupIntInput_doc},
|
||||
{"PupFloatInput", (PyCFunction)Method_PupFloatInput, METH_VARARGS, Method_PupFloatInput_doc},
|
||||
{"PupStrInput", (PyCFunction)Method_PupStrInput, METH_VARARGS, Method_PupStrInput_doc},
|
||||
{"PupBlock", (PyCFunction)Method_PupBlock, METH_VARARGS, Method_PupBlock_doc},
|
||||
{"Image", (PyCFunction)Method_Image, METH_VARARGS, Method_Image_doc},
|
||||
{"Exit", (PyCFunction)Method_Exit, METH_NOARGS, Method_Exit_doc},
|
||||
MethodDef( Redraw ),
|
||||
{"Redraw", (PyCFunction)Method_Redraw, METH_VARARGS, Method_Redraw_doc},
|
||||
{"Draw", (PyCFunction)Method_Draw, METH_NOARGS, Method_Draw_doc},
|
||||
MethodDef( Register ),
|
||||
{"Register", (PyCFunction)Method_Register, METH_VARARGS, Method_Register_doc},
|
||||
{"PushButton", (PyCFunction)Method_Button, METH_VARARGS, Method_Button_doc},
|
||||
MethodDef( BeginAlign ),
|
||||
MethodDef( EndAlign),
|
||||
{"BeginAlign", (PyCFunction)Method_BeginAlign, METH_VARARGS, Method_BeginAlign_doc},
|
||||
{"EndAlign", (PyCFunction)Method_EndAlign, METH_VARARGS, Method_EndAlign_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -287,7 +287,7 @@ static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args
|
||||
VectorObject *pt, *line_1, *line_2;
|
||||
float pt_in[3], pt_out[3], l1[3], l2[3];
|
||||
float lambda;
|
||||
PyObject *ret, *val1, *val2;
|
||||
PyObject *ret;
|
||||
|
||||
if( !PyArg_ParseTuple ( args, "O!O!O!",
|
||||
&vector_Type, &pt,
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <BKE_main.h>
|
||||
#include <BKE_curve.h>
|
||||
#include <BKE_library.h>
|
||||
#include <BKE_utildefines.h>
|
||||
#include "BIF_space.h"
|
||||
|
||||
#include "Ipocurve.h"
|
||||
@ -60,9 +61,6 @@
|
||||
#define KEY_TYPE_CURVE 1
|
||||
#define KEY_TYPE_LATTICE 2
|
||||
|
||||
/* macro from blenkernel/intern/key.c:98 */
|
||||
#define GS(a) (*((short *)(a)))
|
||||
|
||||
static int Key_compare( BPy_Key * a, BPy_Key * b );
|
||||
static PyObject *Key_repr( BPy_Key * self );
|
||||
static void Key_dealloc( BPy_Key * self );
|
||||
|
@ -5394,7 +5394,7 @@ static PyObject *MFaceSeq_delete( BPy_MFaceSeq * self, PyObject *args )
|
||||
return EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"sequence must contain at least one int or MFace" );
|
||||
|
||||
face_table = (unsigned int *)MEM_callocN( len*sizeof( unsigned int ),
|
||||
face_table = MEM_callocN( len*sizeof( unsigned int ),
|
||||
"face_table" );
|
||||
|
||||
/* get the indices of faces to be removed */
|
||||
@ -5517,15 +5517,12 @@ static PyObject *MFaceSeq_delete( BPy_MFaceSeq * self, PyObject *args )
|
||||
++face_count;
|
||||
}
|
||||
}
|
||||
|
||||
/* for each face, deselect each edge */
|
||||
|
||||
/* for each remaining face, select all edges */
|
||||
tmpface = mesh->mface;
|
||||
fface = (struct fourEdges *)face_edges;
|
||||
for( i = mesh->totface; i--; ++tmpface, ++fface ) {
|
||||
if( tmpface->v1 != UINT_MAX ) {
|
||||
FaceEdges (*face)[4];
|
||||
face = (void *)face_edges;
|
||||
face += face_table[i];
|
||||
fface->v[0]->sel = 1;
|
||||
fface->v[1]->sel = 1;
|
||||
fface->v[2]->sel = 1;
|
||||
@ -5533,7 +5530,6 @@ static PyObject *MFaceSeq_delete( BPy_MFaceSeq * self, PyObject *args )
|
||||
fface->v[3]->sel = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* now mark the selected edges for deletion */
|
||||
|
||||
edge_count = 0;
|
||||
|
@ -536,7 +536,7 @@ static int Sequence_setImages( BPy_Sequence * self, PyObject *value )
|
||||
Strip *strip;
|
||||
StripElem *se;
|
||||
int i;
|
||||
PyObject *list, *item;
|
||||
PyObject *list;
|
||||
char *basepath, *name;
|
||||
|
||||
if (self->seq->type != SEQ_IMAGE) {
|
||||
@ -564,6 +564,8 @@ static int Sequence_setImages( BPy_Sequence * self, PyObject *value )
|
||||
name = PyString_AsString(PyList_GetItem(list, i));
|
||||
if (name) {
|
||||
strncpy(se->name, name, sizeof(se->name));
|
||||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -912,8 +912,8 @@ void inithemiwindows()
|
||||
memset(vw, 0, sizeof(RadView));
|
||||
vw->rectx= RG.hemires;
|
||||
vw->recty= RG.hemires;
|
||||
vw->rectz= MEM_mallocN(4*vw->rectx*vw->recty, "initwindows");
|
||||
vw->rect= MEM_mallocN(4*vw->rectx*vw->recty, "initwindows");
|
||||
vw->rectz= MEM_mallocN(sizeof(int)*vw->rectx*vw->recty, "initwindows");
|
||||
vw->rect= MEM_mallocN(sizeof(int)*vw->rectx*vw->recty, "initwindows");
|
||||
vw->mynear= RG.maxsize/2000.0;
|
||||
vw->myfar= 2.0*RG.maxsize;
|
||||
vw->wx1= -vw->mynear;
|
||||
|
@ -87,6 +87,7 @@ static float maxenergy;
|
||||
static VlakRen *findshoot_rr(Render *re)
|
||||
{
|
||||
RadFace *rf;
|
||||
ObjectRen *obr;
|
||||
VlakRen *vlr=NULL, *shoot;
|
||||
float energy;
|
||||
int a;
|
||||
@ -94,19 +95,21 @@ static VlakRen *findshoot_rr(Render *re)
|
||||
shoot= NULL;
|
||||
maxenergy= 0.0;
|
||||
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
|
||||
if(vlr->radface) {
|
||||
rf= vlr->radface;
|
||||
rf->flag &= ~RAD_SHOOT;
|
||||
|
||||
energy= rf->unshot[0]*rf->area;
|
||||
energy+= rf->unshot[1]*rf->area;
|
||||
energy+= rf->unshot[2]*rf->area;
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
|
||||
if(vlr->radface) {
|
||||
rf= vlr->radface;
|
||||
rf->flag &= ~RAD_SHOOT;
|
||||
|
||||
energy= rf->unshot[0]*rf->area;
|
||||
energy+= rf->unshot[1]*rf->area;
|
||||
energy+= rf->unshot[2]*rf->area;
|
||||
|
||||
if(energy>maxenergy) {
|
||||
shoot= vlr;
|
||||
maxenergy= energy;
|
||||
if(energy>maxenergy) {
|
||||
shoot= vlr;
|
||||
maxenergy= energy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -122,22 +125,22 @@ static VlakRen *findshoot_rr(Render *re)
|
||||
|
||||
static void backface_test_rr(Render *re, VlakRen *shoot)
|
||||
{
|
||||
ObjectRen *obr;
|
||||
VlakRen *vlr=NULL;
|
||||
RadFace *rf;
|
||||
float tvec[3];
|
||||
int a;
|
||||
|
||||
/* backface testing */
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
|
||||
if(vlr->radface) {
|
||||
if(vlr!=shoot) {
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
|
||||
if(vlr->radface && vlr!=shoot) {
|
||||
rf= vlr->radface;
|
||||
VecSubf(tvec, shoot->radface->cent, rf->cent);
|
||||
|
||||
if( tvec[0]*rf->norm[0]+ tvec[1]*rf->norm[1]+ tvec[2]*rf->norm[2] < 0.0) {
|
||||
if(tvec[0]*rf->norm[0]+ tvec[1]*rf->norm[1]+ tvec[2]*rf->norm[2] < 0.0)
|
||||
rf->flag |= RAD_BACKFACE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -145,17 +148,20 @@ static void backface_test_rr(Render *re, VlakRen *shoot)
|
||||
|
||||
static void clear_backface_test_rr(Render *re)
|
||||
{
|
||||
ObjectRen *obr;
|
||||
VlakRen *vlr=NULL;
|
||||
RadFace *rf;
|
||||
int a;
|
||||
|
||||
/* backface flag clear */
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
|
||||
|
||||
if(vlr->radface) {
|
||||
rf= vlr->radface;
|
||||
rf->flag &= ~RAD_BACKFACE;
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
|
||||
|
||||
if(vlr->radface) {
|
||||
rf= vlr->radface;
|
||||
rf->flag &= ~RAD_BACKFACE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,6 +171,7 @@ extern RadView hemitop, hemiside; // radfactors.c
|
||||
/* hemi-zbuffering, delivers formfactors array */
|
||||
static void makeformfactors_rr(Render *re, VlakRen *shoot)
|
||||
{
|
||||
ObjectRen *obr;
|
||||
VlakRen *vlr=NULL;
|
||||
RadFace *rf;
|
||||
float len, vec[3], up[3], side[3], tar[5][3], *fp;
|
||||
@ -207,16 +214,18 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
|
||||
/* convert factors to real radiosity */
|
||||
fp= RG.formfactors;
|
||||
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
|
||||
|
||||
if(vlr->radface) {
|
||||
rf= vlr->radface;
|
||||
if(*fp!=0.0 && rf->area!=0.0) {
|
||||
*fp *= shoot->radface->area/rf->area;
|
||||
if(*fp>1.0) *fp= 1.0001;
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
|
||||
|
||||
if(vlr->radface) {
|
||||
rf= vlr->radface;
|
||||
if(*fp!=0.0 && rf->area!=0.0) {
|
||||
*fp *= shoot->radface->area/rf->area;
|
||||
if(*fp>1.0) *fp= 1.0001;
|
||||
}
|
||||
fp++;
|
||||
}
|
||||
fp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -224,6 +233,7 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
|
||||
/* based at RG.formfactors array, distribute shoot energy over other faces */
|
||||
static void applyformfactors_rr(Render *re, VlakRen *shoot)
|
||||
{
|
||||
ObjectRen *obr;
|
||||
VlakRen *vlr=NULL;
|
||||
RadFace *rf;
|
||||
float *fp, *ref, unr, ung, unb, r, g, b;
|
||||
@ -235,30 +245,32 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot)
|
||||
|
||||
fp= RG.formfactors;
|
||||
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
|
||||
|
||||
if(vlr->radface) {
|
||||
rf= vlr->radface;
|
||||
if(*fp!= 0.0) {
|
||||
|
||||
ref= &(vlr->mat->r);
|
||||
|
||||
r= (*fp)*unr*ref[0];
|
||||
g= (*fp)*ung*ref[1];
|
||||
b= (*fp)*unb*ref[2];
|
||||
|
||||
// if(rf->flag & RAD_BACKFACE) {
|
||||
|
||||
rf->totrad[0]+= r;
|
||||
rf->totrad[1]+= g;
|
||||
rf->totrad[2]+= b;
|
||||
|
||||
rf->unshot[0]+= r;
|
||||
rf->unshot[1]+= g;
|
||||
rf->unshot[2]+= b;
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
|
||||
|
||||
if(vlr->radface) {
|
||||
rf= vlr->radface;
|
||||
if(*fp!= 0.0) {
|
||||
|
||||
ref= &(vlr->mat->r);
|
||||
|
||||
r= (*fp)*unr*ref[0];
|
||||
g= (*fp)*ung*ref[1];
|
||||
b= (*fp)*unb*ref[2];
|
||||
|
||||
// if(rf->flag & RAD_BACKFACE) {
|
||||
|
||||
rf->totrad[0]+= r;
|
||||
rf->totrad[1]+= g;
|
||||
rf->totrad[2]+= b;
|
||||
|
||||
rf->unshot[0]+= r;
|
||||
rf->unshot[1]+= g;
|
||||
rf->unshot[2]+= b;
|
||||
}
|
||||
fp++;
|
||||
}
|
||||
fp++;
|
||||
}
|
||||
}
|
||||
/* shoot energy has been shot */
|
||||
@ -313,6 +325,7 @@ static RadFace *radfaces=NULL;
|
||||
|
||||
static void initradfaces(Render *re)
|
||||
{
|
||||
ObjectRen *obr;
|
||||
VlakRen *vlr= NULL;
|
||||
RadFace *rf;
|
||||
int a, b;
|
||||
@ -326,58 +339,62 @@ static void initradfaces(Render *re)
|
||||
RG.max[0]= RG.max[1]= RG.max[2]= -1.0e20;
|
||||
|
||||
/* count first for fast malloc */
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
|
||||
|
||||
if(vlr->mat->mode & MA_RADIO) {
|
||||
if(vlr->mat->emit > 0.0) {
|
||||
RG.totpatch++;
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
|
||||
|
||||
if(vlr->mat->mode & MA_RADIO) {
|
||||
if(vlr->mat->emit > 0.0) {
|
||||
RG.totpatch++;
|
||||
}
|
||||
RG.totelem++;
|
||||
}
|
||||
RG.totelem++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printf(" Rad elems: %d emittors %d\n", RG.totelem, RG.totpatch);
|
||||
if(RG.totelem==0 || RG.totpatch==0) return;
|
||||
|
||||
/* make/init radfaces */
|
||||
rf=radfaces= MEM_callocN(RG.totelem*sizeof(RadFace), "radfaces");
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
|
||||
|
||||
if(vlr->mat->mode & MA_RADIO) {
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
|
||||
|
||||
/* during render, vlr->n gets flipped/corrected, we cannot have that */
|
||||
if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm);
|
||||
else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm);
|
||||
|
||||
rf->totrad[0]= vlr->mat->emit*vlr->mat->r;
|
||||
rf->totrad[1]= vlr->mat->emit*vlr->mat->g;
|
||||
rf->totrad[2]= vlr->mat->emit*vlr->mat->b;
|
||||
VECCOPY(rf->unshot, rf->totrad);
|
||||
|
||||
if(vlr->v4) {
|
||||
rf->area= AreaQ3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co);
|
||||
CalcCent4f(rf->cent, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co);
|
||||
}
|
||||
else {
|
||||
rf->area= AreaT3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co);
|
||||
CalcCent3f(rf->cent, vlr->v1->co, vlr->v2->co, vlr->v3->co);
|
||||
}
|
||||
|
||||
RG.totenergy+= rf->unshot[0]*rf->area;
|
||||
RG.totenergy+= rf->unshot[1]*rf->area;
|
||||
RG.totenergy+= rf->unshot[2]*rf->area;
|
||||
|
||||
for(b=0; b<3; b++) {
|
||||
RG.min[b]= MIN2(RG.min[b], rf->cent[b]);
|
||||
RG.max[b]= MAX2(RG.max[b], rf->cent[b]);
|
||||
}
|
||||
if(vlr->mat->mode & MA_RADIO) {
|
||||
|
||||
/* during render, vlr->n gets flipped/corrected, we cannot have that */
|
||||
if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm);
|
||||
else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm);
|
||||
|
||||
rf->totrad[0]= vlr->mat->emit*vlr->mat->r;
|
||||
rf->totrad[1]= vlr->mat->emit*vlr->mat->g;
|
||||
rf->totrad[2]= vlr->mat->emit*vlr->mat->b;
|
||||
VECCOPY(rf->unshot, rf->totrad);
|
||||
|
||||
if(vlr->v4) {
|
||||
rf->area= AreaQ3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co);
|
||||
CalcCent4f(rf->cent, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co);
|
||||
}
|
||||
else {
|
||||
rf->area= AreaT3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co);
|
||||
CalcCent3f(rf->cent, vlr->v1->co, vlr->v2->co, vlr->v3->co);
|
||||
}
|
||||
|
||||
RG.totenergy+= rf->unshot[0]*rf->area;
|
||||
RG.totenergy+= rf->unshot[1]*rf->area;
|
||||
RG.totenergy+= rf->unshot[2]*rf->area;
|
||||
|
||||
for(b=0; b<3; b++) {
|
||||
RG.min[b]= MIN2(RG.min[b], rf->cent[b]);
|
||||
RG.max[b]= MAX2(RG.max[b], rf->cent[b]);
|
||||
}
|
||||
|
||||
// uncommented; this isnt satisfying, but i leave it in the code for now (ton)
|
||||
// if(vlr->mat->translucency!=0.0) rf->flag |= RAD_TWOSIDED;
|
||||
|
||||
vlr->radface= rf++;
|
||||
// uncommented; this isnt satisfying, but i leave it in the code for now (ton)
|
||||
// if(vlr->mat->translucency!=0.0) rf->flag |= RAD_TWOSIDED;
|
||||
|
||||
vlr->radface= rf++;
|
||||
}
|
||||
}
|
||||
}
|
||||
RG.size[0]= (RG.max[0]- RG.min[0]);
|
||||
@ -408,6 +425,7 @@ static void vecaddfac(float *vec, float *v1, float *v2, float fac)
|
||||
|
||||
static void make_vertex_rad_values(Render *re)
|
||||
{
|
||||
ObjectRen *obr;
|
||||
VertRen *v1=NULL;
|
||||
VlakRen *vlr=NULL;
|
||||
RadFace *rf;
|
||||
@ -418,54 +436,55 @@ static void make_vertex_rad_values(Render *re)
|
||||
RG.radfactor= RG.radfac*pow(64*64, RG.igamma)/128.0; /* compatible with radio-tool */
|
||||
|
||||
/* accumulate vertexcolors */
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
|
||||
|
||||
if(vlr->radface) {
|
||||
rf= vlr->radface;
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
|
||||
|
||||
/* apply correction */
|
||||
rf->totrad[0]= RG.radfactor*pow( rf->totrad[0], RG.igamma);
|
||||
rf->totrad[1]= RG.radfactor*pow( rf->totrad[1], RG.igamma);
|
||||
rf->totrad[2]= RG.radfactor*pow( rf->totrad[2], RG.igamma);
|
||||
|
||||
/* correct rf->rad values for color */
|
||||
if(vlr->mat->r > 0.0) rf->totrad[0]/= vlr->mat->r;
|
||||
if(vlr->mat->g > 0.0) rf->totrad[1]/= vlr->mat->g;
|
||||
if(vlr->mat->b > 0.0) rf->totrad[2]/= vlr->mat->b;
|
||||
|
||||
col= RE_vertren_get_rad(re, vlr->v1, 1);
|
||||
vecaddfac(col, col, rf->totrad, rf->area);
|
||||
col[3]+= rf->area;
|
||||
|
||||
col= RE_vertren_get_rad(re, vlr->v2, 1);
|
||||
vecaddfac(col, col, rf->totrad, rf->area);
|
||||
col[3]+= rf->area;
|
||||
|
||||
col= RE_vertren_get_rad(re, vlr->v3, 1);
|
||||
vecaddfac(col, col, rf->totrad, rf->area);
|
||||
col[3]+= rf->area;
|
||||
|
||||
if(vlr->v4) {
|
||||
col= RE_vertren_get_rad(re, vlr->v4, 1);
|
||||
if(vlr->radface) {
|
||||
rf= vlr->radface;
|
||||
|
||||
/* apply correction */
|
||||
rf->totrad[0]= RG.radfactor*pow( rf->totrad[0], RG.igamma);
|
||||
rf->totrad[1]= RG.radfactor*pow( rf->totrad[1], RG.igamma);
|
||||
rf->totrad[2]= RG.radfactor*pow( rf->totrad[2], RG.igamma);
|
||||
|
||||
/* correct rf->rad values for color */
|
||||
if(vlr->mat->r > 0.0) rf->totrad[0]/= vlr->mat->r;
|
||||
if(vlr->mat->g > 0.0) rf->totrad[1]/= vlr->mat->g;
|
||||
if(vlr->mat->b > 0.0) rf->totrad[2]/= vlr->mat->b;
|
||||
|
||||
col= RE_vertren_get_rad(obr, vlr->v1, 1);
|
||||
vecaddfac(col, col, rf->totrad, rf->area);
|
||||
col[3]+= rf->area;
|
||||
|
||||
col= RE_vertren_get_rad(obr, vlr->v2, 1);
|
||||
vecaddfac(col, col, rf->totrad, rf->area);
|
||||
col[3]+= rf->area;
|
||||
|
||||
col= RE_vertren_get_rad(obr, vlr->v3, 1);
|
||||
vecaddfac(col, col, rf->totrad, rf->area);
|
||||
col[3]+= rf->area;
|
||||
|
||||
if(vlr->v4) {
|
||||
col= RE_vertren_get_rad(obr, vlr->v4, 1);
|
||||
vecaddfac(col, col, rf->totrad, rf->area);
|
||||
col[3]+= rf->area;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* make vertex colors */
|
||||
for(a=0; a<obr->totvert; a++) {
|
||||
if((a & 255)==0) v1= RE_findOrAddVert(obr, a); else v1++;
|
||||
|
||||
col= RE_vertren_get_rad(obr, v1, 0);
|
||||
if(col && col[3]>0.0) {
|
||||
col[0]/= col[3];
|
||||
col[1]/= col[3];
|
||||
col[2]/= col[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* make vertex colors */
|
||||
for(a=0; a<re->totvert; a++) {
|
||||
if((a & 255)==0) v1= RE_findOrAddVert(re, a); else v1++;
|
||||
|
||||
col= RE_vertren_get_rad(re, v1, 0);
|
||||
if(col && col[3]>0.0) {
|
||||
col[0]/= col[3];
|
||||
col[1]/= col[3];
|
||||
col[2]/= col[3];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* main call, extern */
|
||||
|
@ -41,6 +41,19 @@ typedef void RayTree;
|
||||
/* abstraction of face type */
|
||||
typedef void RayFace;
|
||||
|
||||
/* object numbers above this are transformed */
|
||||
#define RE_RAY_TRANSFORM_OFFS 0x8000000
|
||||
|
||||
/* convert from pointer to index in array and back, with offset if the
|
||||
* instance is transformed */
|
||||
#define RAY_OBJECT_SET(re, obi) \
|
||||
((obi == NULL)? 0: \
|
||||
((obi - (re)->objectinstance) + ((obi->flag & R_TRANSFORMED)? RE_RAY_TRANSFORM_OFFS: 0)))
|
||||
|
||||
#define RAY_OBJECT_GET(re, i) \
|
||||
((re)->objectinstance + ((i >= RE_RAY_TRANSFORM_OFFS)? i-RE_RAY_TRANSFORM_OFFS: i))
|
||||
|
||||
|
||||
/* struct for intersection data */
|
||||
typedef struct Isect {
|
||||
float start[3]; /* start+vec = end, in ray_tree_intersect */
|
||||
@ -50,8 +63,11 @@ typedef struct Isect {
|
||||
float labda, u, v; /* distance to hitpoint, uv weights */
|
||||
|
||||
RayFace *face; /* face is where to intersect with */
|
||||
int ob;
|
||||
RayFace *faceorig; /* start face */
|
||||
int oborig;
|
||||
RayFace *face_last; /* for shadow optimize, last intersected face */
|
||||
int ob_last;
|
||||
|
||||
short isect; /* which half of quad */
|
||||
short mode; /* RE_RAYSHADOW, RE_RAYMIRROR, RE_RAYSHADOW_TRA */
|
||||
@ -62,6 +78,7 @@ typedef struct Isect {
|
||||
|
||||
/* octree only */
|
||||
RayFace *facecontr;
|
||||
int obcontr;
|
||||
float ddalabda;
|
||||
short faceisect; /* flag if facecontr was done or not */
|
||||
|
||||
@ -73,18 +90,21 @@ typedef struct Isect {
|
||||
typedef void (*RayCoordsFunc)(RayFace *face,
|
||||
float **v1, float **v2, float **v3, float **v4);
|
||||
typedef int (*RayCheckFunc)(Isect *is, RayFace *face);
|
||||
typedef float *(*RayObjectTransformFunc)(void *userdata, int ob);
|
||||
|
||||
/* tree building and freeing */
|
||||
RayTree *RE_ray_tree_create(int ocres, int totface, float *min, float *max,
|
||||
RayCoordsFunc coordfunc, RayCheckFunc checkfunc);
|
||||
void RE_ray_tree_add_face(RayTree *tree, RayFace *face);
|
||||
RayCoordsFunc coordfunc, RayCheckFunc checkfunc,
|
||||
RayObjectTransformFunc transformfunc, void *userdata);
|
||||
void RE_ray_tree_add_face(RayTree *tree, int ob, RayFace *face);
|
||||
void RE_ray_tree_done(RayTree *tree);
|
||||
void RE_ray_tree_free(RayTree *tree);
|
||||
|
||||
/* intersection with full tree and single face */
|
||||
int RE_ray_tree_intersect(RayTree *tree, Isect *is);
|
||||
int RE_ray_tree_intersect_check(RayTree *tree, Isect *is, RayCheckFunc check);
|
||||
int RE_ray_face_intersection(Isect *is, RayCoordsFunc coordsfunc);
|
||||
int RE_ray_face_intersection(Isect *is, RayObjectTransformFunc transformfunc,
|
||||
RayCoordsFunc coordsfunc);
|
||||
|
||||
/* retrieve the diameter of the tree structure, for setting intersection
|
||||
end distance */
|
||||
|
@ -64,8 +64,11 @@ struct ShadeInputCopy {
|
||||
|
||||
struct Material *mat;
|
||||
struct VlakRen *vlr;
|
||||
struct ObjectInstanceRen *obi;
|
||||
struct ObjectRen *obr;
|
||||
int facenr;
|
||||
float facenor[3]; /* copy from face */
|
||||
short flippednor; /* is facenor flipped? */
|
||||
struct VertRen *v1, *v2, *v3; /* vertices can be in any order for quads... */
|
||||
short i1, i2, i3; /* original vertex indices */
|
||||
short puno;
|
||||
@ -93,8 +96,11 @@ typedef struct ShadeInput
|
||||
|
||||
struct Material *mat;
|
||||
struct VlakRen *vlr;
|
||||
struct ObjectInstanceRen *obi;
|
||||
struct ObjectRen *obr;
|
||||
int facenr;
|
||||
float facenor[3]; /* copy from face */
|
||||
short flippednor; /* is facenor flipped? */
|
||||
struct VertRen *v1, *v2, *v3; /* vertices can be in any order for quads... */
|
||||
short i1, i2, i3; /* original vertex indices */
|
||||
short puno;
|
||||
@ -130,7 +136,7 @@ typedef struct ShadeInput
|
||||
|
||||
ShadeInputUV uv[8]; /* 8 = MAX_MTFACE */
|
||||
ShadeInputCol col[8]; /* 8 = MAX_MCOL */
|
||||
int totuv, totcol;
|
||||
int totuv, totcol, actuv, actcol;
|
||||
|
||||
/* dx/dy OSA coordinates */
|
||||
float dxco[3], dyco[3];
|
||||
|
@ -49,6 +49,7 @@ struct VertTableNode;
|
||||
struct VlakTableNode;
|
||||
struct GHash;
|
||||
struct RenderBuckets;
|
||||
struct ObjectInstanceRen;
|
||||
|
||||
#define TABLEINITSIZE 1024
|
||||
#define LAMPINITSIZE 256
|
||||
@ -81,13 +82,15 @@ typedef struct RenderPart
|
||||
/* result of part rendering */
|
||||
RenderResult *result;
|
||||
|
||||
int *recto; /* object table for objects */
|
||||
int *rectp; /* polygon index table */
|
||||
int *rectz; /* zbuffer */
|
||||
long *rectdaps; /* delta acum buffer for pixel structs */
|
||||
int *rectbacko; /* object table for backside sss */
|
||||
int *rectbackp; /* polygon index table for backside sss */
|
||||
int *rectbackz; /* zbuffer for backside sss */
|
||||
long *rectall; /* buffer for all faces for sss */
|
||||
|
||||
|
||||
rcti disprect; /* part coordinates within total picture */
|
||||
int rectx, recty; /* the size */
|
||||
short crop, ready; /* crop is amount of pixels we crop, for filter */
|
||||
@ -161,21 +164,19 @@ struct Render
|
||||
|
||||
/* render database */
|
||||
int totvlak, totvert, tothalo, totstrand, totlamp;
|
||||
struct HaloRen **sortedhalos;
|
||||
|
||||
ListBase lights; /* GroupObject pointers */
|
||||
ListBase lampren; /* storage, for free */
|
||||
|
||||
int vertnodeslen;
|
||||
struct VertTableNode *vertnodes;
|
||||
int vlaknodeslen;
|
||||
struct VlakTableNode *vlaknodes;
|
||||
int strandnodeslen;
|
||||
struct StrandTableNode *strandnodes;
|
||||
int blohalen;
|
||||
struct HaloRen **bloha;
|
||||
ListBase objecttable;
|
||||
ListBase strandbufs;
|
||||
struct RenderBuckets *strandbuckets;
|
||||
|
||||
struct ObjectInstanceRen *objectinstance;
|
||||
ListBase instancetable;
|
||||
struct GHash *objecthash;
|
||||
int totinstance;
|
||||
|
||||
struct Image *backbuf, *bakebuf;
|
||||
|
||||
struct GHash *orco_hash;
|
||||
@ -235,23 +236,48 @@ typedef struct ShadBuf {
|
||||
} ShadBuf;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* lookup of objects in database */
|
||||
|
||||
typedef struct ObjectRen {
|
||||
struct ObjectRen *next, *prev;
|
||||
struct Object *ob, *par;
|
||||
int index, startvert, endvert, startface, endface, startstrand, endstrand;
|
||||
float *vectors;
|
||||
struct Scene *sce;
|
||||
int index, psysindex;
|
||||
|
||||
int totvert, totvlak, totstrand, tothalo;
|
||||
int vertnodeslen, vlaknodeslen, strandnodeslen, blohalen;
|
||||
struct VertTableNode *vertnodes;
|
||||
struct VlakTableNode *vlaknodes;
|
||||
struct StrandTableNode *strandnodes;
|
||||
struct HaloRen **bloha;
|
||||
ListBase strandbufs;
|
||||
|
||||
char (*mtface)[32];
|
||||
char (*mcol)[32];
|
||||
int actmtface, actmcol;
|
||||
} ObjectRen;
|
||||
|
||||
typedef struct ObjectInstanceRen {
|
||||
struct ObjectInstanceRen *next, *prev;
|
||||
|
||||
ObjectRen *obr;
|
||||
Object *ob, *par;
|
||||
int index, psysindex;
|
||||
|
||||
float mat[4][4], imat[3][3];
|
||||
short flag;
|
||||
|
||||
float *vectors;
|
||||
int totvector;
|
||||
} ObjectInstanceRen;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct VertRen
|
||||
{
|
||||
float co[3];
|
||||
float n[3];
|
||||
float ho[4];
|
||||
float *orco;
|
||||
short clip;
|
||||
short clip;
|
||||
unsigned short flag; /* in use for clipping zbuffer parts, temp setting stuff in convertblender.c */
|
||||
float accum; /* accum for radio weighting, and for strand texco static particles */
|
||||
int index; /* index allows extending vertren with any property */
|
||||
@ -279,10 +305,10 @@ typedef struct VlakRen {
|
||||
unsigned int lay;
|
||||
float n[3];
|
||||
struct Material *mat;
|
||||
char noflag, puno;
|
||||
char puno;
|
||||
char flag, ec;
|
||||
RadFace *radface;
|
||||
Object *ob;
|
||||
ObjectRen *obr;
|
||||
int index;
|
||||
} VlakRen;
|
||||
|
||||
@ -312,7 +338,7 @@ typedef struct StrandBuffer {
|
||||
struct StrandVert *vert;
|
||||
int totvert;
|
||||
|
||||
struct Object *ob;
|
||||
struct ObjectRen *obr;
|
||||
struct Material *ma;
|
||||
unsigned int lay;
|
||||
int overrideuv;
|
||||
@ -393,7 +419,7 @@ typedef struct LampRen {
|
||||
short xold[BLENDER_MAX_THREADS], yold[BLENDER_MAX_THREADS]; /* last jitter table for area lights */
|
||||
float area_size, area_sizey, area_sizez;
|
||||
float adapt_thresh;
|
||||
|
||||
|
||||
struct ShadBuf *shb;
|
||||
float *jitter;
|
||||
QMCSampler *qsa;
|
||||
@ -417,8 +443,13 @@ typedef struct LampRen {
|
||||
|
||||
/* ray optim */
|
||||
VlakRen *vlr_last[BLENDER_MAX_THREADS];
|
||||
ObjectInstanceRen *obi_last[BLENDER_MAX_THREADS];
|
||||
|
||||
struct MTex *mtex[MAX_MTEX];
|
||||
|
||||
/* threading */
|
||||
int thread_assigned;
|
||||
int thread_ready;
|
||||
} LampRen;
|
||||
|
||||
/* **************** defines ********************* */
|
||||
@ -435,7 +466,7 @@ typedef struct LampRen {
|
||||
|
||||
/* vlakren->flag (vlak = face in dutch) char!!! */
|
||||
#define R_SMOOTH 1
|
||||
#define R_VISIBLE 2
|
||||
#define R_HIDDEN 2
|
||||
/* strand flag, means special handling */
|
||||
#define R_STRAND 4
|
||||
#define R_NOPUNOFLIP 8
|
||||
@ -446,16 +477,14 @@ typedef struct LampRen {
|
||||
/* vertex normals are tangent or view-corrected vector, for hair strands */
|
||||
#define R_TANGENT 128
|
||||
|
||||
/* vlakren->noflag (char) */
|
||||
#define R_SNPROJ_X 1
|
||||
#define R_SNPROJ_Y 2
|
||||
#define R_SNPROJ_Z 4
|
||||
#define R_FLIPPED_NO 8
|
||||
|
||||
/* strandbuffer->flag */
|
||||
#define R_STRAND_BSPLINE 1
|
||||
#define R_STRAND_B_UNITS 2
|
||||
|
||||
/* objectinstance->flag */
|
||||
#define R_DUPLI_TRANSFORMED 1
|
||||
#define R_ENV_TRANSFORMED 2
|
||||
#define R_TRANSFORMED (1|2)
|
||||
|
||||
#endif /* RENDER_TYPES_H */
|
||||
|
||||
|
@ -49,13 +49,14 @@ struct ShadeResult;
|
||||
struct World;
|
||||
struct RenderPart;
|
||||
struct RenderLayer;
|
||||
struct ObjectRen;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct PixStr
|
||||
{
|
||||
struct PixStr *next;
|
||||
int facenr, z;
|
||||
int obi, facenr, z;
|
||||
unsigned short mask;
|
||||
short shadfac;
|
||||
} PixStr;
|
||||
|
@ -41,6 +41,7 @@ struct MTFace;
|
||||
struct CustomData;
|
||||
struct StrandBuffer;
|
||||
struct StrandRen;
|
||||
struct ObjectInstanceRen;
|
||||
|
||||
#define RE_QUAD_MASK 0x7FFFFFF
|
||||
#define RE_QUAD_OFFS 0x8000000
|
||||
@ -58,71 +59,65 @@ typedef struct VertTableNode {
|
||||
|
||||
typedef struct VlakTableNode {
|
||||
struct VlakRen *vlak;
|
||||
struct MTFace **mtface;
|
||||
struct MCol **mcol;
|
||||
struct MTFace *mtface;
|
||||
struct MCol *mcol;
|
||||
int totmtface, totmcol;
|
||||
float *surfnor;
|
||||
struct CustomDataNames **names;
|
||||
} VlakTableNode;
|
||||
|
||||
typedef struct StrandTableNode {
|
||||
struct StrandRen *strand;
|
||||
float *winspeed;
|
||||
float *surfnor;
|
||||
struct MCol **mcol;
|
||||
float **uv;
|
||||
struct MCol *mcol;
|
||||
float *uv;
|
||||
int totuv, totmcol;
|
||||
struct CustomDataNames **names;
|
||||
} StrandTableNode;
|
||||
|
||||
typedef struct CustomDataNames{
|
||||
struct CustomDataNames *next, *prev;
|
||||
|
||||
char (*mtface)[32];
|
||||
char (*mcol)[32];
|
||||
} CustomDataNames;
|
||||
|
||||
/* renderdatabase.c */
|
||||
void free_renderdata_tables(struct Render *re);
|
||||
void free_renderdata_vertnodes(struct VertTableNode *vertnodes);
|
||||
void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes);
|
||||
|
||||
void set_normalflags(Render *re);
|
||||
void set_normalflags(struct Render *re, struct ObjectRen *obr);
|
||||
void project_renderdata(struct Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets);
|
||||
|
||||
/* functions are not exported... so wrong names */
|
||||
|
||||
struct VlakRen *RE_findOrAddVlak(struct Render *re, int nr);
|
||||
struct VertRen *RE_findOrAddVert(struct Render *re, int nr);
|
||||
struct StrandRen *RE_findOrAddStrand(struct Render *re, int nr);
|
||||
struct HaloRen *RE_findOrAddHalo(struct Render *re, int nr);
|
||||
struct HaloRen *RE_inithalo(struct Render *re, struct Material *ma, float *vec, float *vec1, float *orco, float hasize,
|
||||
float vectsize, int seed);
|
||||
struct HaloRen *RE_inithalo_particle(struct Render *re, struct DerivedMesh *dm, struct Material *ma, float *vec, float *vec1,
|
||||
float *orco, float *uvco, float hasize, float vectsize, int seed);
|
||||
void RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int sve, int eve, int sfa, int efa, int sst, int est);
|
||||
struct StrandBuffer *RE_addStrandBuffer(struct Render *re, struct Object *ob, int totvert);
|
||||
struct VlakRen *RE_findOrAddVlak(struct ObjectRen *obr, int nr);
|
||||
struct VertRen *RE_findOrAddVert(struct ObjectRen *obr, int nr);
|
||||
struct StrandRen *RE_findOrAddStrand(struct ObjectRen *obr, int nr);
|
||||
struct HaloRen *RE_findOrAddHalo(struct ObjectRen *obr, int nr);
|
||||
struct HaloRen *RE_inithalo(struct Render *re, struct ObjectRen *obr, struct Material *ma, float *vec, float *vec1, float *orco, float hasize, float vectsize, int seed);
|
||||
struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, struct Material *ma, float *vec, float *vec1, float *orco, float *uvco, float hasize, float vectsize, int seed);
|
||||
struct StrandBuffer *RE_addStrandBuffer(struct ObjectRen *obr, int totvert);
|
||||
|
||||
float *RE_vertren_get_sticky(struct Render *re, struct VertRen *ver, int verify);
|
||||
float *RE_vertren_get_stress(struct Render *re, struct VertRen *ver, int verify);
|
||||
float *RE_vertren_get_rad(struct Render *re, struct VertRen *ver, int verify);
|
||||
float *RE_vertren_get_strand(struct Render *re, struct VertRen *ver, int verify);
|
||||
float *RE_vertren_get_tangent(struct Render *re, struct VertRen *ver, int verify);
|
||||
float *RE_vertren_get_winspeed(struct Render *re, struct VertRen *ver, int verify);
|
||||
struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex);
|
||||
void RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[][4]);
|
||||
void RE_makeRenderInstances(struct Render *re);
|
||||
void RE_instanceTransformNormal(struct ObjectInstanceRen *obi, float *nor, float *tnor);
|
||||
|
||||
struct MTFace *RE_vlakren_get_tface(struct Render *re, VlakRen *ren, int n, char **name, int verify);
|
||||
struct MCol *RE_vlakren_get_mcol(struct Render *re, VlakRen *ren, int n, char **name, int verify);
|
||||
float *RE_vlakren_get_surfnor(struct Render *re, VlakRen *ren, int verify);
|
||||
float *RE_vertren_get_sticky(struct ObjectRen *obr, struct VertRen *ver, int verify);
|
||||
float *RE_vertren_get_stress(struct ObjectRen *obr, struct VertRen *ver, int verify);
|
||||
float *RE_vertren_get_rad(struct ObjectRen *obr, struct VertRen *ver, int verify);
|
||||
float *RE_vertren_get_strand(struct ObjectRen *obr, struct VertRen *ver, int verify);
|
||||
float *RE_vertren_get_tangent(struct ObjectRen *obr, struct VertRen *ver, int verify);
|
||||
float *RE_vertren_get_winspeed(struct ObjectInstanceRen *obi, struct VertRen *ver, int verify);
|
||||
|
||||
float *RE_strandren_get_winspeed(struct Render *re, struct StrandRen *strand, int verify);
|
||||
float *RE_strandren_get_surfnor(struct Render *re, struct StrandRen *strand, int verify);
|
||||
float *RE_strandren_get_uv(struct Render *re, struct StrandRen *strand, int n, char **name, int verify);
|
||||
struct MCol *RE_strandren_get_mcol(struct Render *re, struct StrandRen *strand, int n, char **name, int verify);
|
||||
struct MTFace *RE_vlakren_get_tface(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
|
||||
struct MCol *RE_vlakren_get_mcol(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
|
||||
float *RE_vlakren_get_surfnor(struct ObjectRen *obr, VlakRen *ren, int verify);
|
||||
int RE_vlakren_get_normal(struct Render *re, struct ObjectInstanceRen *obi, struct VlakRen *vlr, float *nor);
|
||||
|
||||
struct VertRen *RE_vertren_copy(struct Render *re, struct VertRen *ver);
|
||||
struct VlakRen *RE_vlakren_copy(struct Render *re, struct VlakRen *vlr);
|
||||
float *RE_strandren_get_surfnor(struct ObjectRen *obr, struct StrandRen *strand, int verify);
|
||||
float *RE_strandren_get_uv(struct ObjectRen *obr, struct StrandRen *strand, int n, char **name, int verify);
|
||||
struct MCol *RE_strandren_get_mcol(struct ObjectRen *obr, struct StrandRen *strand, int n, char **name, int verify);
|
||||
float *RE_strandren_get_winspeed(struct ObjectInstanceRen *obi, struct StrandRen *strand, int verify);
|
||||
|
||||
void RE_vlakren_set_customdata_names(struct Render *re, struct CustomData *data);
|
||||
struct VertRen *RE_vertren_copy(struct ObjectRen *obr, struct VertRen *ver);
|
||||
struct VlakRen *RE_vlakren_copy(struct ObjectRen *obr, struct VlakRen *vlr);
|
||||
|
||||
void RE_set_customdata_names(struct ObjectRen *obr, struct CustomData *data);
|
||||
|
||||
/* haloren->type: flags */
|
||||
#define HA_ONLYSKY 1
|
||||
|
@ -37,6 +37,8 @@
|
||||
|
||||
#include "render_types.h"
|
||||
|
||||
struct ObjectRen;
|
||||
|
||||
/**
|
||||
* Calculates shadowbuffers for a vector of shadow-giving lamps
|
||||
* @param lar The vector of lamps
|
||||
@ -44,6 +46,8 @@
|
||||
void makeshadowbuf(struct Render *re, LampRen *lar);
|
||||
void freeshadowbuf(struct LampRen *lar);
|
||||
|
||||
void threaded_makeshadowbufs(struct Render *re);
|
||||
|
||||
/**
|
||||
* Determines the shadow factor for a face and lamp. There is some
|
||||
* communication with global variables here.
|
||||
@ -80,6 +84,7 @@ float ISB_getshadow(ShadeInput *shi, ShadBuf *shb);
|
||||
typedef struct ISBSample {
|
||||
float zco[3]; /* coordinate in lampview projection */
|
||||
short *shadfac; /* initialized zero = full lighted */
|
||||
int obi; /* object for face lookup */
|
||||
int facenr; /* index in faces list */
|
||||
} ISBSample;
|
||||
|
||||
@ -87,6 +92,7 @@ typedef struct ISBSample {
|
||||
typedef struct ISBSampleA {
|
||||
float zco[3]; /* coordinate in lampview projection */
|
||||
short *shadfac; /* NULL = full lighted */
|
||||
int obi; /* object for face lookup */
|
||||
int facenr; /* index in faces list */
|
||||
struct ISBSampleA *next; /* in end, we want the first items to align with ISBSample */
|
||||
} ISBSampleA;
|
||||
@ -94,6 +100,7 @@ typedef struct ISBSampleA {
|
||||
/* used for transparent storage only */
|
||||
typedef struct ISBShadfacA {
|
||||
struct ISBShadfacA *next;
|
||||
int obi;
|
||||
int facenr;
|
||||
float shadfac;
|
||||
} ISBShadfacA;
|
||||
|
@ -32,6 +32,7 @@ struct LampRen;
|
||||
struct VlakRen;
|
||||
struct StrandSegment;
|
||||
struct StrandPoint;
|
||||
struct ObjectInstanceRen obi;
|
||||
|
||||
/* shadeinput.c */
|
||||
|
||||
@ -52,12 +53,13 @@ typedef struct ShadeSample {
|
||||
/* also the node shader callback */
|
||||
void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr);
|
||||
|
||||
void shade_input_set_triangle_i(struct ShadeInput *shi, struct VlakRen *vlr, short i1, short i2, short i3);
|
||||
void shade_input_set_triangle(struct ShadeInput *shi, volatile int facenr, int normal_flip);
|
||||
void shade_input_set_triangle_i(struct ShadeInput *shi, struct ObjectInstanceRen *obi, struct VlakRen *vlr, short i1, short i2, short i3);
|
||||
void shade_input_set_triangle(struct ShadeInput *shi, volatile int obi, volatile int facenr, int normal_flip);
|
||||
void shade_input_copy_triangle(struct ShadeInput *shi, struct ShadeInput *from);
|
||||
void shade_input_set_viewco(struct ShadeInput *shi, float x, float y, float z);
|
||||
void shade_input_set_uv(struct ShadeInput *shi);
|
||||
void shade_input_set_normals(struct ShadeInput *shi);
|
||||
void shade_input_flip_normals(struct ShadeInput *shi);
|
||||
void shade_input_set_shade_texco(struct ShadeInput *shi);
|
||||
void shade_input_set_strand(struct ShadeInput *shi, struct StrandRen *strand, struct StrandPoint *spoint);
|
||||
void shade_input_set_strand_texco(struct ShadeInput *shi, struct StrandRen *strand, struct StrandVert *svert, struct StrandPoint *spoint);
|
||||
|
@ -43,6 +43,7 @@ struct RenderPart;
|
||||
struct RenderBuckets;
|
||||
struct RenderPrimitiveIterator;
|
||||
struct ZSpan;
|
||||
struct ObjectInstanceRen;
|
||||
|
||||
typedef struct StrandPoint {
|
||||
/* position within segment */
|
||||
@ -73,6 +74,7 @@ typedef struct StrandSegment {
|
||||
struct StrandVert *v[4];
|
||||
struct StrandRen *strand;
|
||||
struct StrandBuffer *buffer;
|
||||
struct ObjectInstanceRen *obi;
|
||||
float sqadaptcos;
|
||||
|
||||
StrandPoint point1, point2;
|
||||
@ -80,103 +82,7 @@ typedef struct StrandSegment {
|
||||
} StrandSegment;
|
||||
|
||||
void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint);
|
||||
void render_strand_segment(struct Render *re, struct StrandPart *spart, struct ZSpan *zspan, StrandSegment *sseg);
|
||||
void project_strands(Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, int do_buckets);
|
||||
|
||||
struct RenderBuckets *init_buckets(struct Render *re);
|
||||
void add_buckets_primitive(struct RenderBuckets *buckets, float *min, float *max, void *prim);
|
||||
void free_buckets(struct RenderBuckets *buckets);
|
||||
void project_hoco_to_bucket(struct RenderBuckets *buckets, float *hoco, float *bucketco);
|
||||
|
||||
struct RenderPrimitiveIterator *init_primitive_iterator(struct Render *re, struct RenderBuckets *buckets, struct RenderPart *pa);
|
||||
void *next_primitive_iterator(struct RenderPrimitiveIterator *iter);
|
||||
void free_primitive_iterator(struct RenderPrimitiveIterator *iter);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: none of this file.
|
||||
*
|
||||
* Contributor(s): Brecht Van Lommel.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef STRAND_H
|
||||
#define STRAND_H
|
||||
|
||||
struct StrandVert;
|
||||
struct StrandRen;
|
||||
struct StrandBuffer;
|
||||
struct ShadeSample;
|
||||
struct StrandPart;
|
||||
struct Render;
|
||||
struct RenderPart;
|
||||
struct RenderBuckets;
|
||||
struct RenderPrimitiveIterator;
|
||||
struct ZSpan;
|
||||
|
||||
typedef struct StrandPoint {
|
||||
/* position within segment */
|
||||
float t;
|
||||
|
||||
/* camera space */
|
||||
float co[3];
|
||||
float nor[3];
|
||||
float tan[3];
|
||||
float strandco;
|
||||
float width;
|
||||
|
||||
/* derivatives */
|
||||
float dtco[3], dsco[3];
|
||||
float dtstrandco;
|
||||
|
||||
/* outer points */
|
||||
float co1[3], co2[3];
|
||||
float hoco1[4], hoco2[4];
|
||||
float zco1[3], zco2[3];
|
||||
|
||||
/* screen space */
|
||||
float hoco[4];
|
||||
float x, y;
|
||||
} StrandPoint;
|
||||
|
||||
typedef struct StrandSegment {
|
||||
struct StrandVert *v[4];
|
||||
struct StrandRen *strand;
|
||||
struct StrandBuffer *buffer;
|
||||
float sqadaptcos;
|
||||
|
||||
StrandPoint point1, point2;
|
||||
int shaded;
|
||||
} StrandSegment;
|
||||
|
||||
void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint);
|
||||
void render_strand_segment(struct Render *re, struct StrandPart *spart, struct ZSpan *zspan, StrandSegment *sseg);
|
||||
void render_strand_segment(struct Render *re, float winmat[][4], struct StrandPart *spart, struct ZSpan *zspan, StrandSegment *sseg);
|
||||
void project_strands(Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, int do_buckets);
|
||||
|
||||
struct RenderBuckets *init_buckets(struct Render *re);
|
||||
|
@ -35,6 +35,7 @@ struct RenderLayer;
|
||||
struct LampRen;
|
||||
struct VlakRen;
|
||||
struct ListBase;
|
||||
struct ZSpan;
|
||||
|
||||
void fillrect(int *rect, int x, int y, int val);
|
||||
|
||||
@ -46,19 +47,20 @@ void projectvert(float *v1, float winmat[][4], float *adr);
|
||||
void projectverto(float *v1, float winmat[][4], float *adr);
|
||||
int testclip(float *v);
|
||||
|
||||
void set_part_zbuf_clipflag(struct RenderPart *pa);
|
||||
void zbuffer_shadow(struct Render *re, struct LampRen *lar, int *rectz, int size, float jitx, float jity);
|
||||
void zbuffer_solid(struct RenderPart *pa, unsigned int layer, short layflag);
|
||||
void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity);
|
||||
void zbuffer_solid(struct RenderPart *pa, unsigned int layer, short layflag, void (*fillfunc)(struct RenderPart*, struct ZSpan*, int, void*), void *data);
|
||||
|
||||
unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass);
|
||||
unsigned short *zbuffer_strands_shade(struct Render *re, struct RenderPart *pa, struct RenderLayer *rl, float *pass);
|
||||
void convert_zbuf_to_distbuf(struct RenderPart *pa, struct RenderLayer *rl);
|
||||
void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void *, int, int, int, int));
|
||||
void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void*, int, int, int, int, int));
|
||||
|
||||
typedef struct APixstr {
|
||||
unsigned short mask[4]; /* jitter mask */
|
||||
int z[4]; /* distance */
|
||||
int p[4]; /* index */
|
||||
short shadfac[4]; /* optimize storage for irregular shadow */
|
||||
unsigned short mask[4]; /* jitter mask */
|
||||
int z[4]; /* distance */
|
||||
int p[4]; /* index */
|
||||
int obi[4]; /* object instance */
|
||||
short shadfac[4]; /* optimize storage for irregular shadow */
|
||||
struct APixstr *next;
|
||||
} APixstr;
|
||||
|
||||
@ -81,6 +83,7 @@ typedef struct ZSpan {
|
||||
int *rectz, *arectz; /* zbuffers, arectz is for transparant */
|
||||
int *rectz1; /* seconday z buffer for shadowbuffer (2nd closest z) */
|
||||
int *rectp; /* polygon index buffer */
|
||||
int *recto; /* object buffer */
|
||||
APixstr *apixbuf, *curpstr; /* apixbuf for transparent */
|
||||
struct ListBase *apsmbase;
|
||||
|
||||
@ -88,25 +91,31 @@ typedef struct ZSpan {
|
||||
float shad_alpha; /* copy from material, used by irregular shadbuf */
|
||||
int mask, apsmcounter; /* in use by apixbuf */
|
||||
|
||||
float clipcrop; /* for shadow, was in R global before */
|
||||
|
||||
void *sss_handle; /* used by sss */
|
||||
void (*sss_func)(void *, int, int, int, int);
|
||||
void (*sss_func)(void *, int, int, int, int, int);
|
||||
|
||||
void (*zbuffunc)(struct ZSpan *, int, float *, float *, float *, float *);
|
||||
void (*zbuflinefunc)(struct ZSpan *, int, float *, float *);
|
||||
void (*zbuffunc)(struct ZSpan *, int, int, float *, float *, float *, float *);
|
||||
void (*zbuflinefunc)(struct ZSpan *, int, int, float *, float *);
|
||||
|
||||
} ZSpan;
|
||||
|
||||
/* exported to shadbuf.c */
|
||||
void zbufclip4(struct ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, float *f4, int c1, int c2, int c3, int c4);
|
||||
void zbufclip4(struct ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, float *f4, int c1, int c2, int c3, int c4);
|
||||
void zbuf_free_span(struct ZSpan *zspan);
|
||||
|
||||
/* to rendercore.c */
|
||||
void zspan_scanconvert(struct ZSpan *zpan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float) );
|
||||
|
||||
/* exported to edge render... */
|
||||
void zbufclip(struct ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3);
|
||||
void zbuf_alloc_span(struct ZSpan *zspan, int rectx, int recty);
|
||||
void zbufclipwire(struct ZSpan *zspan, int zvlnr, struct VlakRen *vlr);
|
||||
void zbufclip(struct ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3);
|
||||
void zbuf_alloc_span(struct ZSpan *zspan, int rectx, int recty, float clipcrop);
|
||||
void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec, float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4);
|
||||
|
||||
/* exported to shadeinput.c */
|
||||
void zbuf_make_winmat(Render *re, float duplimat[][4], float winmat[][4]);
|
||||
void zbuf_render_project(float winmat[][4], float *co, float *ho);
|
||||
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -148,19 +148,16 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
|
||||
envre->totvlak= re->totvlak;
|
||||
envre->totvert= re->totvert;
|
||||
envre->tothalo= re->tothalo;
|
||||
envre->totstrand= re->totstrand;
|
||||
envre->totlamp= re->totlamp;
|
||||
envre->lights= re->lights;
|
||||
envre->vertnodeslen= re->vertnodeslen;
|
||||
envre->vertnodes= re->vertnodes;
|
||||
envre->blohalen= re->blohalen;
|
||||
envre->bloha= re->bloha;
|
||||
envre->vlaknodeslen= re->vlaknodeslen;
|
||||
envre->vlaknodes= re->vlaknodes;
|
||||
envre->strandnodeslen= re->strandnodeslen;
|
||||
envre->strandnodes= re->strandnodes;
|
||||
envre->objecttable= re->objecttable;
|
||||
envre->strandbuckets= re->strandbuckets;
|
||||
envre->customdata_names= re->customdata_names;
|
||||
envre->raytree= re->raytree;
|
||||
envre->totinstance= re->totinstance;
|
||||
envre->instancetable= re->instancetable;
|
||||
envre->objectinstance= re->objectinstance;
|
||||
|
||||
return envre;
|
||||
}
|
||||
@ -171,19 +168,16 @@ static void envmap_free_render_copy(Render *envre)
|
||||
envre->totvlak= 0;
|
||||
envre->totvert= 0;
|
||||
envre->tothalo= 0;
|
||||
envre->totstrand= 0;
|
||||
envre->totlamp= 0;
|
||||
envre->totinstance= 0;
|
||||
envre->lights.first= envre->lights.last= NULL;
|
||||
envre->vertnodeslen= 0;
|
||||
envre->vertnodes= NULL;
|
||||
envre->blohalen= 0;
|
||||
envre->bloha= NULL;
|
||||
envre->vlaknodeslen= 0;
|
||||
envre->vlaknodes= NULL;
|
||||
envre->strandnodeslen= 0;
|
||||
envre->strandnodes= NULL;
|
||||
envre->objecttable.first= envre->objecttable.last= NULL;
|
||||
envre->strandbuckets= NULL;
|
||||
envre->customdata_names.first= envre->customdata_names.last= NULL;
|
||||
envre->raytree= NULL;
|
||||
envre->instancetable.first= envre->instancetable.last= NULL;
|
||||
envre->objectinstance= NULL;
|
||||
|
||||
RE_FreeRender(envre);
|
||||
}
|
||||
@ -225,11 +219,11 @@ static void envmap_transmatrix(float mat[][4], int part)
|
||||
static void env_rotate_scene(Render *re, float mat[][4], int mode)
|
||||
{
|
||||
GroupObject *go;
|
||||
VlakRen *vlr = NULL;
|
||||
VertRen *ver = NULL;
|
||||
ObjectRen *obr;
|
||||
ObjectInstanceRen *obi;
|
||||
LampRen *lar = NULL;
|
||||
HaloRen *har = NULL;
|
||||
float xn, yn, zn, imat[3][3], pmat[4][4], smat[4][4], tmat[4][4], cmat[3][3];
|
||||
float imat[3][3], pmat[4][4], smat[4][4], tmat[4][4], cmat[3][3];
|
||||
int a;
|
||||
|
||||
if(mode==0) {
|
||||
@ -240,46 +234,36 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode)
|
||||
MTC_Mat4CpyMat4(tmat, mat);
|
||||
MTC_Mat3CpyMat4(imat, mat);
|
||||
}
|
||||
|
||||
for(a=0; a<re->totvert; a++) {
|
||||
if((a & 255)==0) ver= RE_findOrAddVert(re, a);
|
||||
else ver++;
|
||||
|
||||
MTC_Mat4MulVecfl(tmat, ver->co);
|
||||
|
||||
xn= ver->n[0];
|
||||
yn= ver->n[1];
|
||||
zn= ver->n[2];
|
||||
/* no transpose ! */
|
||||
ver->n[0]= imat[0][0]*xn+imat[1][0]*yn+imat[2][0]*zn;
|
||||
ver->n[1]= imat[0][1]*xn+imat[1][1]*yn+imat[2][1]*zn;
|
||||
ver->n[2]= imat[0][2]*xn+imat[1][2]*yn+imat[2][2]*zn;
|
||||
Normalize(ver->n);
|
||||
|
||||
for(obi=re->instancetable.first; obi; obi=obi->next) {
|
||||
/* append or set matrix depending on dupli */
|
||||
if(obi->flag & R_DUPLI_TRANSFORMED)
|
||||
Mat4MulMat4(obi->mat, tmat, obi->mat);
|
||||
else if(mode==1)
|
||||
Mat4CpyMat4(obi->mat, tmat);
|
||||
else
|
||||
Mat4One(obi->mat);
|
||||
|
||||
Mat3CpyMat4(cmat, obi->mat);
|
||||
Mat3Inv(obi->imat, cmat);
|
||||
|
||||
/* indicate the renderer has to use transform matrices */
|
||||
if(mode==0)
|
||||
obi->flag &= ~R_ENV_TRANSFORMED;
|
||||
else
|
||||
obi->flag |= R_ENV_TRANSFORMED;
|
||||
}
|
||||
|
||||
for(a=0; a<re->tothalo; a++) {
|
||||
if((a & 255)==0) har= re->bloha[a>>8];
|
||||
else har++;
|
||||
|
||||
MTC_Mat4MulVecfl(tmat, har->co);
|
||||
}
|
||||
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->tothalo; a++) {
|
||||
if((a & 255)==0) har= obr->bloha[a>>8];
|
||||
else har++;
|
||||
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
|
||||
else vlr++;
|
||||
|
||||
xn= vlr->n[0];
|
||||
yn= vlr->n[1];
|
||||
zn= vlr->n[2];
|
||||
/* no transpose ! */
|
||||
vlr->n[0]= imat[0][0]*xn+imat[1][0]*yn+imat[2][0]*zn;
|
||||
vlr->n[1]= imat[0][1]*xn+imat[1][1]*yn+imat[2][1]*zn;
|
||||
vlr->n[2]= imat[0][2]*xn+imat[1][2]*yn+imat[2][2]*zn;
|
||||
Normalize(vlr->n);
|
||||
MTC_Mat4MulVecfl(tmat, har->co);
|
||||
}
|
||||
}
|
||||
|
||||
set_normalflags(re);
|
||||
|
||||
for(go=re->lights.first; go; go= go->next) {
|
||||
lar= go->lampren;
|
||||
|
||||
@ -314,6 +298,7 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode)
|
||||
|
||||
static void env_layerflags(Render *re, unsigned int notlay)
|
||||
{
|
||||
ObjectRen *obr;
|
||||
VlakRen *vlr = NULL;
|
||||
int a;
|
||||
|
||||
@ -327,23 +312,47 @@ static void env_layerflags(Render *re, unsigned int notlay)
|
||||
|
||||
notlay= ~notlay;
|
||||
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
|
||||
else vlr++;
|
||||
if((vlr->lay & notlay)==0)
|
||||
vlr->flag &= ~R_VISIBLE;
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
|
||||
else vlr++;
|
||||
|
||||
if((vlr->lay & notlay)==0)
|
||||
vlr->flag |= R_HIDDEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void env_hideobject(Render *re, Object *ob)
|
||||
{
|
||||
ObjectRen *obr;
|
||||
VlakRen *vlr = NULL;
|
||||
int a;
|
||||
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
|
||||
else vlr++;
|
||||
if(vlr->ob == ob) vlr->flag &= ~R_VISIBLE;
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
|
||||
else vlr++;
|
||||
|
||||
if(obr->ob == ob)
|
||||
vlr->flag |= R_HIDDEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void env_showobjects(Render *re)
|
||||
{
|
||||
ObjectRen *obr;
|
||||
VlakRen *vlr = NULL;
|
||||
int a;
|
||||
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
|
||||
else vlr++;
|
||||
|
||||
vlr->flag &= ~R_HIDDEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,6 +428,7 @@ static void render_envmap(Render *re, EnvMap *env)
|
||||
}
|
||||
|
||||
/* rotate back */
|
||||
env_showobjects(envre);
|
||||
env_rotate_scene(envre, tmat, 0);
|
||||
|
||||
if(re->test_break()==0) {
|
||||
|
@ -984,6 +984,5 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *dxt, f
|
||||
texres->tb*= fx;
|
||||
}
|
||||
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -1251,7 +1251,6 @@ static void render_tile_processor(Render *re, int firsttile)
|
||||
}
|
||||
|
||||
freeparts(re);
|
||||
R.strandbuckets= NULL;
|
||||
}
|
||||
|
||||
/* calculus for how much 1 pixel rendered should rotate the 3d geometry */
|
||||
@ -1485,7 +1484,6 @@ static void threaded_tile_processor(Render *re)
|
||||
BLI_end_threads(&threads);
|
||||
freeparts(re);
|
||||
re->viewplane= viewplane; /* restore viewplane, modified by pano render */
|
||||
R.strandbuckets= NULL;
|
||||
}
|
||||
|
||||
/* currently only called by preview renders and envmap */
|
||||
|
@ -88,6 +88,13 @@ static int vlr_check_intersect(Isect *is, RayFace *face)
|
||||
return (is->lay & vlr->lay);
|
||||
}
|
||||
|
||||
static float *vlr_get_transform(void *userdata, int i)
|
||||
{
|
||||
ObjectInstanceRen *obi= RAY_OBJECT_GET((Render*)userdata, i);
|
||||
|
||||
return (obi->flag & R_TRANSFORMED)? (float*)obi->mat: NULL;
|
||||
}
|
||||
|
||||
void freeraytree(Render *re)
|
||||
{
|
||||
if(re->raytree) {
|
||||
@ -98,25 +105,46 @@ void freeraytree(Render *re)
|
||||
|
||||
void makeraytree(Render *re)
|
||||
{
|
||||
ObjectInstanceRen *obi;
|
||||
ObjectRen *obr;
|
||||
VlakRen *vlr= NULL;
|
||||
float min[3], max[3];
|
||||
float min[3], max[3], co1[3], co2[3], co3[3], co4[3];
|
||||
double lasttime= PIL_check_seconds_timer();
|
||||
int v, totface = 0;
|
||||
|
||||
INIT_MINMAX(min, max);
|
||||
|
||||
/* first min max raytree space */
|
||||
for(v=0;v<re->totvlak;v++) {
|
||||
if((v & 255)==0) vlr= re->vlaknodes[v>>8].vlak;
|
||||
else vlr++;
|
||||
if(vlr->mat->mode & MA_TRACEBLE) {
|
||||
if((vlr->mat->mode & MA_WIRE)==0) {
|
||||
if(!re->excludeob || vlr->ob != re->excludeob) {
|
||||
DO_MINMAX(vlr->v1->co, min, max);
|
||||
DO_MINMAX(vlr->v2->co, min, max);
|
||||
DO_MINMAX(vlr->v3->co, min, max);
|
||||
for(obi=re->instancetable.first; obi; obi=obi->next) {
|
||||
obr= obi->obr;
|
||||
|
||||
if(re->excludeob && obr->ob == re->excludeob)
|
||||
continue;
|
||||
|
||||
for(v=0;v<obr->totvlak;v++) {
|
||||
if((v & 255)==0) vlr= obr->vlaknodes[v>>8].vlak;
|
||||
else vlr++;
|
||||
if(vlr->mat->mode & MA_TRACEBLE) {
|
||||
if((vlr->mat->mode & MA_WIRE)==0) {
|
||||
VECCOPY(co1, vlr->v1->co);
|
||||
VECCOPY(co2, vlr->v2->co);
|
||||
VECCOPY(co3, vlr->v3->co);
|
||||
|
||||
if(obi->flag & R_TRANSFORMED) {
|
||||
Mat4MulVecfl(obi->mat, co1);
|
||||
Mat4MulVecfl(obi->mat, co2);
|
||||
Mat4MulVecfl(obi->mat, co3);
|
||||
}
|
||||
|
||||
DO_MINMAX(co1, min, max);
|
||||
DO_MINMAX(co2, min, max);
|
||||
DO_MINMAX(co3, min, max);
|
||||
|
||||
if(vlr->v4) {
|
||||
DO_MINMAX(vlr->v4->co, min, max);
|
||||
VECCOPY(co4, vlr->v4->co);
|
||||
if(obi->flag & R_TRANSFORMED)
|
||||
Mat4MulVecfl(obi->mat, co4);
|
||||
DO_MINMAX(co4, min, max);
|
||||
}
|
||||
|
||||
totface++;
|
||||
@ -125,35 +153,42 @@ void makeraytree(Render *re)
|
||||
}
|
||||
}
|
||||
|
||||
re->raytree= RE_ray_tree_create(re->r.ocres, totface, min, max, vlr_face_coords, vlr_check_intersect);
|
||||
re->raytree= RE_ray_tree_create(re->r.ocres, totface, min, max,
|
||||
vlr_face_coords, vlr_check_intersect, vlr_get_transform, re);
|
||||
|
||||
if(min[0] > max[0]) { /* empty raytree */
|
||||
RE_ray_tree_done(re->raytree);
|
||||
return;
|
||||
}
|
||||
|
||||
for(v=0; v<re->totvlak; v++) {
|
||||
if((v & 255)==0) {
|
||||
double time= PIL_check_seconds_timer();
|
||||
for(obi=re->instancetable.first; obi; obi=obi->next) {
|
||||
obr= obi->obr;
|
||||
|
||||
vlr= re->vlaknodes[v>>8].vlak;
|
||||
if(re->test_break())
|
||||
break;
|
||||
if(time-lasttime>1.0f) {
|
||||
char str[32];
|
||||
sprintf(str, "Filling Octree: %d", v);
|
||||
re->i.infostr= str;
|
||||
re->stats_draw(&re->i);
|
||||
re->i.infostr= NULL;
|
||||
lasttime= time;
|
||||
if(re->excludeob && obr->ob == re->excludeob)
|
||||
continue;
|
||||
|
||||
for(v=0; v<obr->totvlak; v++) {
|
||||
if((v & 255)==0) {
|
||||
double time= PIL_check_seconds_timer();
|
||||
|
||||
vlr= obr->vlaknodes[v>>8].vlak;
|
||||
if(re->test_break())
|
||||
break;
|
||||
if(time-lasttime>1.0f) {
|
||||
char str[32];
|
||||
sprintf(str, "Filling Octree: %d", v);
|
||||
re->i.infostr= str;
|
||||
re->stats_draw(&re->i);
|
||||
re->i.infostr= NULL;
|
||||
lasttime= time;
|
||||
}
|
||||
}
|
||||
else vlr++;
|
||||
|
||||
if(vlr->mat->mode & MA_TRACEBLE)
|
||||
if((vlr->mat->mode & MA_WIRE)==0)
|
||||
RE_ray_tree_add_face(re->raytree, RAY_OBJECT_SET(re, obi), vlr);
|
||||
}
|
||||
else vlr++;
|
||||
|
||||
if(vlr->mat->mode & MA_TRACEBLE)
|
||||
if((vlr->mat->mode & MA_WIRE)==0)
|
||||
if(!re->excludeob || vlr->ob != re->excludeob)
|
||||
RE_ray_tree_add_face(re->raytree, (RayFace*)vlr);
|
||||
}
|
||||
|
||||
RE_ray_tree_done(re->raytree);
|
||||
@ -165,7 +200,8 @@ void makeraytree(Render *re)
|
||||
static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
|
||||
{
|
||||
VlakRen *vlr= (VlakRen*)is->face;
|
||||
int osatex= 0, norflip;
|
||||
ObjectInstanceRen *obi= RAY_OBJECT_GET(&R, is->ob);
|
||||
int osatex= 0;
|
||||
|
||||
/* set up view vector */
|
||||
VECCOPY(shi->view, is->vec);
|
||||
@ -177,6 +213,8 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
|
||||
|
||||
Normalize(shi->view);
|
||||
|
||||
shi->obi= obi;
|
||||
shi->obr= obi->obr;
|
||||
shi->vlr= vlr;
|
||||
shi->mat= vlr->mat;
|
||||
memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); // note, keep this synced with render_types.h
|
||||
@ -194,35 +232,26 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
|
||||
shi->dyno[0]= shi->dyno[1]= shi->dyno[2]= 0.0f;
|
||||
}
|
||||
|
||||
/* face normal, check for flip, need to set puno here */
|
||||
norflip= (vlr->n[0]*shi->view[0]+vlr->n[1]*shi->view[1]+vlr->n[2]*shi->view[2]) < 0.0f;
|
||||
|
||||
if(norflip)
|
||||
shi->puno= vlr->puno ^ 15;// only flip lower 4 bits
|
||||
else
|
||||
shi->puno= vlr->puno;
|
||||
|
||||
if(vlr->v4) {
|
||||
if(is->isect==2)
|
||||
shade_input_set_triangle_i(shi, vlr, 2, 1, 3);
|
||||
shade_input_set_triangle_i(shi, obi, vlr, 2, 1, 3);
|
||||
else
|
||||
shade_input_set_triangle_i(shi, vlr, 0, 1, 3);
|
||||
shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 3);
|
||||
}
|
||||
else {
|
||||
shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
|
||||
shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
|
||||
}
|
||||
|
||||
/* shade_input_set_triangle_i() sets facenor, now we flip */
|
||||
if(norflip) {
|
||||
shi->facenor[0]= -vlr->n[0];
|
||||
shi->facenor[1]= -vlr->n[1];
|
||||
shi->facenor[2]= -vlr->n[2];
|
||||
}
|
||||
|
||||
|
||||
shi->u= is->u;
|
||||
shi->v= is->v;
|
||||
shi->dx_u= shi->dx_v= shi->dy_u= shi->dy_v= 0.0f;
|
||||
|
||||
shade_input_set_normals(shi);
|
||||
|
||||
/* point normals to viewing direction */
|
||||
if(INPR(shi->facenor, shi->view) < 0.0f)
|
||||
shade_input_flip_normals(shi);
|
||||
|
||||
shade_input_set_shade_texco(shi);
|
||||
|
||||
if(is->mode==RE_RAY_SHADOW_TRA)
|
||||
@ -371,7 +400,7 @@ static void ray_fadeout(Isect *is, ShadeInput *shi, float *col, float *blendcol,
|
||||
}
|
||||
|
||||
/* the main recursive tracer itself */
|
||||
static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, float *start, float *vec, float *col, VlakRen *vlr, int traflag)
|
||||
static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, float *start, float *vec, float *col, ObjectInstanceRen *obi, VlakRen *vlr, int traflag)
|
||||
{
|
||||
ShadeInput shi;
|
||||
ShadeResult shr;
|
||||
@ -392,6 +421,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo
|
||||
}
|
||||
isec.mode= RE_RAY_MIRROR;
|
||||
isec.faceorig= (RayFace*)vlr;
|
||||
isec.oborig= RAY_OBJECT_SET(&R, obi);
|
||||
|
||||
if(RE_ray_tree_intersect(R.raytree, &isec)) {
|
||||
float d= 1.0f;
|
||||
@ -441,10 +471,10 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo
|
||||
reflection(refract, shi.vn, shi.view, shi.vn);
|
||||
}
|
||||
traflag |= RAY_TRA;
|
||||
traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.vlr, traflag ^ RAY_TRAFLIP);
|
||||
traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, traflag ^ RAY_TRAFLIP);
|
||||
}
|
||||
else
|
||||
traceray(origshi, origshr, depth-1, shi.co, shi.view, tracol, shi.vlr, 0);
|
||||
traceray(origshi, origshr, depth-1, shi.co, shi.view, tracol, shi.obi, shi.vlr, 0);
|
||||
|
||||
f= shr.alpha; f1= 1.0f-f;
|
||||
nf= d * shi.mat->filter;
|
||||
@ -474,7 +504,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo
|
||||
float mircol[4];
|
||||
|
||||
reflection(ref, shi.vn, shi.view, NULL);
|
||||
traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.vlr, 0);
|
||||
traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.obi, shi.vlr, 0);
|
||||
|
||||
f1= 1.0f-f;
|
||||
|
||||
@ -951,7 +981,7 @@ static void trace_refract(float *col, ShadeInput *shi, ShadeResult *shr)
|
||||
VECCOPY(v_refract_new, v_refract);
|
||||
}
|
||||
|
||||
traceray(shi, shr, shi->mat->ray_depth_tra, shi->co, v_refract_new, sampcol, shi->vlr, RAY_TRA|RAY_TRAFLIP);
|
||||
traceray(shi, shr, shi->mat->ray_depth_tra, shi->co, v_refract_new, sampcol, shi->obi, shi->vlr, RAY_TRA|RAY_TRAFLIP);
|
||||
|
||||
col[0] += sampcol[0];
|
||||
col[1] += sampcol[1];
|
||||
@ -1047,7 +1077,7 @@ static void trace_reflect(float *col, ShadeInput *shi, ShadeResult *shr, float f
|
||||
else
|
||||
reflection(v_reflect, v_nor_new, shi->view, NULL);
|
||||
|
||||
traceray(shi, shr, shi->mat->ray_depth, shi->co, v_reflect, sampcol, shi->vlr, 0);
|
||||
traceray(shi, shr, shi->mat->ray_depth, shi->co, v_reflect, sampcol, shi->obi, shi->vlr, 0);
|
||||
|
||||
|
||||
col[0] += sampcol[0];
|
||||
@ -1223,6 +1253,7 @@ static void ray_trace_shadow_tra(Isect *is, int depth, int traflag)
|
||||
|
||||
/* adapt isect struct */
|
||||
VECCOPY(is->start, shi.co);
|
||||
is->oborig= RAY_OBJECT_SET(&R, shi.obi);
|
||||
is->faceorig= (RayFace*)shi.vlr;
|
||||
|
||||
ray_trace_shadow_tra(is, depth-1, traflag | RAY_TRA);
|
||||
@ -1250,6 +1281,7 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr)
|
||||
accum[0]= accum[1]= accum[2]= 0.0f;
|
||||
isec.mode= RE_RAY_MIRROR;
|
||||
isec.faceorig= (RayFace*)ship->vlr;
|
||||
isec.oborig= RAY_OBJECT_SET(&R, ship->obi);
|
||||
|
||||
for(a=0; a<8*8; a++) {
|
||||
|
||||
@ -1448,7 +1480,9 @@ void ray_ao_qmc(ShadeInput *shi, float *shadfac)
|
||||
int aocolor;
|
||||
|
||||
isec.faceorig= (RayFace*)shi->vlr;
|
||||
isec.oborig= RAY_OBJECT_SET(&R, shi->obi);
|
||||
isec.face_last= NULL;
|
||||
isec.ob_last= 0;
|
||||
isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW;
|
||||
isec.lay= -1;
|
||||
VECCOPY(isec.start, shi->co);
|
||||
@ -1574,7 +1608,9 @@ void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
|
||||
int j= -1, tot, actual=0, skyadded=0, aocolor;
|
||||
|
||||
isec.faceorig= (RayFace*)shi->vlr;
|
||||
isec.oborig= RAY_OBJECT_SET(&R, shi->obi);
|
||||
isec.face_last= NULL;
|
||||
isec.ob_last= 0;
|
||||
isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW;
|
||||
isec.lay= -1;
|
||||
|
||||
@ -1737,6 +1773,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
|
||||
|
||||
while (samples < max_samples) {
|
||||
isec->faceorig= (RayFace*)shi->vlr;
|
||||
isec->oborig= RAY_OBJECT_SET(&R, shi->obi);
|
||||
|
||||
/* manually jitter the start shading co-ord per sample
|
||||
* based on the pre-generated OSA texture sampling offsets,
|
||||
@ -1873,6 +1910,7 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, floa
|
||||
}
|
||||
|
||||
isec->faceorig= (RayFace*)shi->vlr;
|
||||
isec->oborig= RAY_OBJECT_SET(&R, shi->obi);
|
||||
|
||||
vec[0]= jitlamp[0];
|
||||
vec[1]= jitlamp[1];
|
||||
@ -1929,10 +1967,14 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
|
||||
if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1;
|
||||
|
||||
/* only when not mir tracing, first hit optimm */
|
||||
if(shi->depth==0)
|
||||
if(shi->depth==0) {
|
||||
isec.face_last= (RayFace*)lar->vlr_last[shi->thread];
|
||||
else
|
||||
isec.ob_last= RAY_OBJECT_SET(&R, lar->obi_last[shi->thread]);
|
||||
}
|
||||
else {
|
||||
isec.face_last= NULL;
|
||||
isec.ob_last= 0;
|
||||
}
|
||||
|
||||
if(lar->type==LA_SUN || lar->type==LA_HEMI) {
|
||||
maxsize= RE_ray_tree_max_size(R.raytree);
|
||||
@ -1952,6 +1994,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
|
||||
if(lar->ray_totsamp<2) {
|
||||
|
||||
isec.faceorig= (RayFace*)shi->vlr;
|
||||
isec.oborig= RAY_OBJECT_SET(&R, shi->obi);
|
||||
shadfac[3]= 1.0f; // 1.0=full light
|
||||
|
||||
/* set up isec vec */
|
||||
@ -1974,8 +2017,10 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
|
||||
}
|
||||
|
||||
/* for first hit optim, set last interesected shadow face */
|
||||
if(shi->depth==0)
|
||||
if(shi->depth==0) {
|
||||
lar->vlr_last[shi->thread]= (VlakRen*)isec.face_last;
|
||||
lar->obi_last[shi->thread]= RAY_OBJECT_GET(&R, isec.ob_last);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2001,6 +2046,7 @@ void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co)
|
||||
}
|
||||
|
||||
isec.faceorig= (RayFace*)shi->vlr;
|
||||
isec.oborig= RAY_OBJECT_SET(&R, shi->obi);
|
||||
|
||||
/* set up isec vec */
|
||||
VECCOPY(isec.start, shi->co);
|
||||
|
@ -61,6 +61,7 @@ typedef struct OcVal
|
||||
typedef struct Node
|
||||
{
|
||||
struct RayFace *v[8];
|
||||
int ob[8];
|
||||
struct OcVal ov[8];
|
||||
struct Node *next;
|
||||
} Node;
|
||||
@ -76,6 +77,8 @@ typedef struct Octree {
|
||||
char *ocface; /* during building only */
|
||||
RayCoordsFunc coordsfunc;
|
||||
RayCheckFunc checkfunc;
|
||||
RayObjectTransformFunc transformfunc;
|
||||
void *userdata;
|
||||
} Octree;
|
||||
|
||||
/* ******** globals ***************** */
|
||||
@ -230,7 +233,7 @@ static int face_in_node(RayFace *face, short x, short y, short z, float rtf[][3]
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short z, float rtf[][3])
|
||||
static void ocwrite(Octree *oc, int ob, RayFace *face, int quad, short x, short y, short z, float rtf[][3])
|
||||
{
|
||||
Branch *br;
|
||||
Node *no;
|
||||
@ -281,6 +284,7 @@ static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short
|
||||
}
|
||||
|
||||
no->v[a]= face;
|
||||
no->ob[a]= ob;
|
||||
|
||||
if(quad)
|
||||
calc_ocval_face(rtf[0], rtf[1], rtf[2], rtf[3], x>>2, y>>1, z, &no->ov[a]);
|
||||
@ -435,7 +439,7 @@ void RE_ray_tree_free(RayTree *tree)
|
||||
MEM_freeN(oc);
|
||||
}
|
||||
|
||||
RayTree *RE_ray_tree_create(int ocres, int totface, float *min, float *max, RayCoordsFunc coordsfunc, RayCheckFunc checkfunc)
|
||||
RayTree *RE_ray_tree_create(int ocres, int totface, float *min, float *max, RayCoordsFunc coordsfunc, RayCheckFunc checkfunc, RayObjectTransformFunc transformfunc, void *userdata)
|
||||
{
|
||||
Octree *oc;
|
||||
float t00, t01, t02;
|
||||
@ -447,6 +451,8 @@ RayTree *RE_ray_tree_create(int ocres, int totface, float *min, float *max, RayC
|
||||
|
||||
oc->coordsfunc= coordsfunc;
|
||||
oc->checkfunc= checkfunc;
|
||||
oc->transformfunc= transformfunc;
|
||||
oc->userdata= userdata;
|
||||
|
||||
/* only for debug info */
|
||||
raycount=0;
|
||||
@ -486,10 +492,11 @@ RayTree *RE_ray_tree_create(int ocres, int totface, float *min, float *max, RayC
|
||||
return (RayTree*)oc;
|
||||
}
|
||||
|
||||
void RE_ray_tree_add_face(RayTree *tree, RayFace *face)
|
||||
void RE_ray_tree_add_face(RayTree *tree, int ob, RayFace *face)
|
||||
{
|
||||
Octree *oc = (Octree*)tree;
|
||||
float *v1, *v2, *v3, *v4, ocfac[3], rtf[4][3];
|
||||
float co1[3], co2[3], co3[3], co4[3];
|
||||
short rts[4][3], ocmin[6], *ocmax;
|
||||
char *ocface= oc->ocface; // front, top, size view of face, to fill in
|
||||
int a, b, c, oc1, oc2, oc3, oc4, x, y, z, ocres2;
|
||||
@ -503,16 +510,34 @@ void RE_ray_tree_add_face(RayTree *tree, RayFace *face)
|
||||
ocmax= ocmin+3;
|
||||
|
||||
oc->coordsfunc(face, &v1, &v2, &v3, &v4);
|
||||
|
||||
VECCOPY(co1, v1);
|
||||
VECCOPY(co2, v2);
|
||||
VECCOPY(co3, v3);
|
||||
if(v4)
|
||||
VECCOPY(co4, v4);
|
||||
|
||||
if(ob >= RE_RAY_TRANSFORM_OFFS) {
|
||||
float (*mat)[4]= (float(*)[4])oc->transformfunc(oc->userdata, ob);
|
||||
|
||||
if(mat) {
|
||||
Mat4MulVecfl(mat, co1);
|
||||
Mat4MulVecfl(mat, co2);
|
||||
Mat4MulVecfl(mat, co3);
|
||||
if(v4)
|
||||
Mat4MulVecfl(mat, co4);
|
||||
}
|
||||
}
|
||||
|
||||
for(c=0;c<3;c++) {
|
||||
rtf[0][c]= (v1[c]-oc->min[c])*ocfac[c] ;
|
||||
rtf[0][c]= (co1[c]-oc->min[c])*ocfac[c] ;
|
||||
rts[0][c]= (short)rtf[0][c];
|
||||
rtf[1][c]= (v2[c]-oc->min[c])*ocfac[c] ;
|
||||
rtf[1][c]= (co2[c]-oc->min[c])*ocfac[c] ;
|
||||
rts[1][c]= (short)rtf[1][c];
|
||||
rtf[2][c]= (v3[c]-oc->min[c])*ocfac[c] ;
|
||||
rtf[2][c]= (co3[c]-oc->min[c])*ocfac[c] ;
|
||||
rts[2][c]= (short)rtf[2][c];
|
||||
if(v4) {
|
||||
rtf[3][c]= (v4[c]-oc->min[c])*ocfac[c] ;
|
||||
rtf[3][c]= (co4[c]-oc->min[c])*ocfac[c] ;
|
||||
rts[3][c]= (short)rtf[3][c];
|
||||
}
|
||||
}
|
||||
@ -535,7 +560,7 @@ void RE_ray_tree_add_face(RayTree *tree, RayFace *face)
|
||||
}
|
||||
|
||||
if(ocmin[0]==ocmax[0] && ocmin[1]==ocmax[1] && ocmin[2]==ocmax[2]) {
|
||||
ocwrite(oc, face, (v4 != NULL), ocmin[0], ocmin[1], ocmin[2], rtf);
|
||||
ocwrite(oc, ob, face, (v4 != NULL), ocmin[0], ocmin[1], ocmin[2], rtf);
|
||||
}
|
||||
else {
|
||||
|
||||
@ -574,7 +599,7 @@ void RE_ray_tree_add_face(RayTree *tree, RayFace *face)
|
||||
for(z=ocmin[2];z<=ocmax[2];z++) {
|
||||
if(ocface[b+z] && ocface[a+z]) {
|
||||
if(face_in_node(NULL, x, y, z, rtf))
|
||||
ocwrite(oc, face, (v4 != NULL), x,y,z, rtf);
|
||||
ocwrite(oc, ob, face, (v4 != NULL), x,y,z, rtf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -611,9 +636,9 @@ void RE_ray_tree_done(RayTree *tree)
|
||||
/* ************ raytracer **************** */
|
||||
|
||||
/* only for self-intersecting test with current render face (where ray left) */
|
||||
static int intersection2(RayFace *face, RayCoordsFunc coordsfunc, float r0, float r1, float r2, float rx1, float ry1, float rz1)
|
||||
static int intersection2(RayFace *face, int ob, RayObjectTransformFunc transformfunc, RayCoordsFunc coordsfunc, void *userdata, float r0, float r1, float r2, float rx1, float ry1, float rz1)
|
||||
{
|
||||
float *v1, *v2, *v3, *v4;
|
||||
float *v1, *v2, *v3, *v4, co1[3], co2[3], co3[3], co4[3];
|
||||
float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22;
|
||||
float m0, m1, m2, divdet, det, det1;
|
||||
float u1, v, u2;
|
||||
@ -623,17 +648,35 @@ static int intersection2(RayFace *face, RayCoordsFunc coordsfunc, float r0, floa
|
||||
/* happens for baking with non existing face */
|
||||
if(v1==NULL)
|
||||
return 1;
|
||||
|
||||
if (v4) {
|
||||
|
||||
if(v4) {
|
||||
SWAP(float*, v3, v4);
|
||||
}
|
||||
|
||||
VECCOPY(co1, v1);
|
||||
VECCOPY(co2, v2);
|
||||
VECCOPY(co3, v3);
|
||||
if(v4)
|
||||
VECCOPY(co4, v4);
|
||||
|
||||
if(ob >= RE_RAY_TRANSFORM_OFFS) {
|
||||
float (*mat)[4]= (float(*)[4])transformfunc(userdata, ob);
|
||||
|
||||
if(mat) {
|
||||
Mat4MulVecfl(mat, co1);
|
||||
Mat4MulVecfl(mat, co2);
|
||||
Mat4MulVecfl(mat, co3);
|
||||
if(v4)
|
||||
Mat4MulVecfl(mat, co4);
|
||||
}
|
||||
}
|
||||
|
||||
t00= v3[0]-v1[0];
|
||||
t01= v3[1]-v1[1];
|
||||
t02= v3[2]-v1[2];
|
||||
t10= v3[0]-v2[0];
|
||||
t11= v3[1]-v2[1];
|
||||
t12= v3[2]-v2[2];
|
||||
t00= co3[0]-co1[0];
|
||||
t01= co3[1]-co1[1];
|
||||
t02= co3[2]-co1[2];
|
||||
t10= co3[0]-co2[0];
|
||||
t11= co3[1]-co2[1];
|
||||
t12= co3[2]-co2[2];
|
||||
|
||||
x0= t11*r2-t12*r1;
|
||||
x1= t12*r0-t10*r2;
|
||||
@ -641,9 +684,9 @@ static int intersection2(RayFace *face, RayCoordsFunc coordsfunc, float r0, floa
|
||||
|
||||
divdet= t00*x0+t01*x1+t02*x2;
|
||||
|
||||
m0= rx1-v3[0];
|
||||
m1= ry1-v3[1];
|
||||
m2= rz1-v3[2];
|
||||
m0= rx1-co3[0];
|
||||
m1= ry1-co3[1];
|
||||
m2= rz1-co3[2];
|
||||
det1= m0*x0+m1*x1+m2*x2;
|
||||
|
||||
if(divdet!=0.0f) {
|
||||
@ -663,9 +706,9 @@ static int intersection2(RayFace *face, RayCoordsFunc coordsfunc, float r0, floa
|
||||
|
||||
if(v4) {
|
||||
|
||||
t20= v3[0]-v4[0];
|
||||
t21= v3[1]-v4[1];
|
||||
t22= v3[2]-v4[2];
|
||||
t20= co3[0]-co4[0];
|
||||
t21= co3[1]-co4[1];
|
||||
t22= co3[2]-co4[2];
|
||||
|
||||
divdet= t20*x0+t21*x1+t22*x2;
|
||||
if(divdet!=0.0f) {
|
||||
@ -752,10 +795,11 @@ static int intersection_strand(Isect *is)
|
||||
#endif
|
||||
|
||||
/* ray - triangle or quad intersection */
|
||||
int RE_ray_face_intersection(Isect *is, RayCoordsFunc coordsfunc)
|
||||
int RE_ray_face_intersection(Isect *is, RayObjectTransformFunc transformfunc, RayCoordsFunc coordsfunc)
|
||||
{
|
||||
RayFace *face= is->face;
|
||||
float *v1,*v2,*v3,*v4;
|
||||
int ob= is->ob;
|
||||
float *v1,*v2,*v3,*v4,co1[3],co2[3],co3[3],co4[3];
|
||||
float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2;
|
||||
float m0, m1, m2, divdet, det1;
|
||||
short ok=0;
|
||||
@ -767,16 +811,34 @@ int RE_ray_face_intersection(Isect *is, RayCoordsFunc coordsfunc)
|
||||
|
||||
coordsfunc(face, &v1, &v2, &v3, &v4);
|
||||
|
||||
if (v4) {
|
||||
if(v4) {
|
||||
SWAP(float*, v3, v4);
|
||||
}
|
||||
|
||||
t00= v3[0]-v1[0];
|
||||
t01= v3[1]-v1[1];
|
||||
t02= v3[2]-v1[2];
|
||||
t10= v3[0]-v2[0];
|
||||
t11= v3[1]-v2[1];
|
||||
t12= v3[2]-v2[2];
|
||||
VECCOPY(co1, v1);
|
||||
VECCOPY(co2, v2);
|
||||
VECCOPY(co3, v3);
|
||||
if(v4)
|
||||
VECCOPY(co4, v4);
|
||||
|
||||
if(ob) {
|
||||
float (*mat)[4]= (float(*)[4])transformfunc(is->userdata, ob);
|
||||
|
||||
if(mat) {
|
||||
Mat4MulVecfl(mat, co1);
|
||||
Mat4MulVecfl(mat, co2);
|
||||
Mat4MulVecfl(mat, co3);
|
||||
if(v4)
|
||||
Mat4MulVecfl(mat, co4);
|
||||
}
|
||||
}
|
||||
|
||||
t00= co3[0]-co1[0];
|
||||
t01= co3[1]-co1[1];
|
||||
t02= co3[2]-co1[2];
|
||||
t10= co3[0]-co2[0];
|
||||
t11= co3[1]-co2[1];
|
||||
t12= co3[2]-co2[2];
|
||||
|
||||
r0= is->vec[0];
|
||||
r1= is->vec[1];
|
||||
@ -788,9 +850,9 @@ int RE_ray_face_intersection(Isect *is, RayCoordsFunc coordsfunc)
|
||||
|
||||
divdet= t00*x0+t01*x1+t02*x2;
|
||||
|
||||
m0= is->start[0]-v3[0];
|
||||
m1= is->start[1]-v3[1];
|
||||
m2= is->start[2]-v3[2];
|
||||
m0= is->start[0]-co3[0];
|
||||
m1= is->start[1]-co3[1];
|
||||
m2= is->start[2]-co3[2];
|
||||
det1= m0*x0+m1*x1+m2*x2;
|
||||
|
||||
if(divdet!=0.0f) {
|
||||
@ -821,9 +883,9 @@ int RE_ray_face_intersection(Isect *is, RayCoordsFunc coordsfunc)
|
||||
|
||||
if(ok==0 && v4) {
|
||||
|
||||
t20= v3[0]-v4[0];
|
||||
t21= v3[1]-v4[1];
|
||||
t22= v3[2]-v4[2];
|
||||
t20= co3[0]-co4[0];
|
||||
t21= co3[1]-co4[1];
|
||||
t22= co3[2]-co4[2];
|
||||
|
||||
divdet= t20*x0+t21*x1+t22*x2;
|
||||
if(divdet!=0.0f) {
|
||||
@ -874,11 +936,13 @@ int RE_ray_face_intersection(Isect *is, RayCoordsFunc coordsfunc)
|
||||
|
||||
coordsfunc(face, &origv1, &origv2, &origv3, &origv4);
|
||||
|
||||
if(v1==origv1 || v2==origv1 || v3==origv1 || v4==origv1) de++;
|
||||
if(v1==origv2 || v2==origv2 || v3==origv2 || v4==origv2) de++;
|
||||
if(v1==origv3 || v2==origv3 || v3==origv3 || v4==origv3) de++;
|
||||
if(origv4) {
|
||||
if(v1==origv4 || v2==origv4 || v3==origv4 || v4==origv4) de++;
|
||||
if(ob == is->oborig) {
|
||||
if(v1==origv1 || v2==origv1 || v3==origv1 || v4==origv1) de++;
|
||||
if(v1==origv2 || v2==origv2 || v3==origv2 || v4==origv2) de++;
|
||||
if(v1==origv3 || v2==origv3 || v3==origv3 || v4==origv3) de++;
|
||||
if(origv4) {
|
||||
if(v1==origv4 || v2==origv4 || v3==origv4 || v4==origv4) de++;
|
||||
}
|
||||
}
|
||||
if(de) {
|
||||
/* so there's a shared edge or vertex, let's intersect ray with face
|
||||
@ -886,8 +950,9 @@ int RE_ray_face_intersection(Isect *is, RayCoordsFunc coordsfunc)
|
||||
the intersection is invalid, 0 */
|
||||
|
||||
if(is->facecontr==NULL) {
|
||||
is->obcontr= is->oborig;
|
||||
is->facecontr= face;
|
||||
is->faceisect= intersection2(face, coordsfunc, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2]);
|
||||
is->faceisect= intersection2(face, is->oborig, transformfunc, coordsfunc, is->userdata, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2]);
|
||||
}
|
||||
|
||||
if(is->faceisect) return 1;
|
||||
@ -905,6 +970,7 @@ int RE_ray_face_intersection(Isect *is, RayCoordsFunc coordsfunc)
|
||||
static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval, RayCheckFunc checkfunc)
|
||||
{
|
||||
RayFace *face;
|
||||
int ob;
|
||||
short nr=0;
|
||||
OcVal *ov;
|
||||
|
||||
@ -912,18 +978,21 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval, RayCheckFunc c
|
||||
if(is->mode==RE_RAY_SHADOW) {
|
||||
|
||||
face= no->v[0];
|
||||
ob= no->ob[0];
|
||||
while(face) {
|
||||
|
||||
if(is->faceorig != face) {
|
||||
if(!(is->faceorig == face && is->oborig == ob)) {
|
||||
|
||||
if(checkfunc(is, face)) {
|
||||
|
||||
ov= no->ov+nr;
|
||||
if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) {
|
||||
//accepted++;
|
||||
is->ob= ob;
|
||||
is->face= face;
|
||||
|
||||
if(RE_ray_face_intersection(is, oc->coordsfunc)) {
|
||||
if(RE_ray_face_intersection(is, oc->transformfunc, oc->coordsfunc)) {
|
||||
is->ob_last= ob;
|
||||
is->face_last= face;
|
||||
return 1;
|
||||
}
|
||||
@ -939,6 +1008,7 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval, RayCheckFunc c
|
||||
nr=0;
|
||||
}
|
||||
face= no->v[nr];
|
||||
ob= no->ob[nr];
|
||||
}
|
||||
}
|
||||
else { /* else mirror or glass or shadowtra, return closest face */
|
||||
@ -949,16 +1019,18 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval, RayCheckFunc c
|
||||
isect= *is; /* copy for sorting */
|
||||
|
||||
face= no->v[0];
|
||||
ob= no->ob[0];
|
||||
while(face) {
|
||||
|
||||
if(is->faceorig != face) {
|
||||
if(!(is->faceorig == face && is->oborig == ob)) {
|
||||
if(checkfunc(is, face)) {
|
||||
ov= no->ov+nr;
|
||||
if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) {
|
||||
//accepted++;
|
||||
|
||||
isect.ob= ob;
|
||||
isect.face= face;
|
||||
if(RE_ray_face_intersection(&isect, oc->coordsfunc)) {
|
||||
if(RE_ray_face_intersection(&isect, oc->transformfunc, oc->coordsfunc)) {
|
||||
if(isect.labda<is->labda) *is= isect;
|
||||
found= 1;
|
||||
}
|
||||
@ -974,6 +1046,7 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval, RayCheckFunc c
|
||||
nr=0;
|
||||
}
|
||||
face= no->v[nr];
|
||||
ob= no->ob[nr];
|
||||
}
|
||||
|
||||
return found;
|
||||
@ -1123,17 +1196,20 @@ int RE_ray_tree_intersect_check(RayTree *tree, Isect *is, RayCheckFunc checkfunc
|
||||
|
||||
/* do this before intersect calls */
|
||||
is->facecontr= NULL; /* to check shared edge */
|
||||
is->obcontr= 0;
|
||||
is->faceisect= is->isect= 0; /* shared edge, quad half flag */
|
||||
is->userdata= oc->userdata;
|
||||
|
||||
/* only for shadow! */
|
||||
if(is->mode==RE_RAY_SHADOW) {
|
||||
|
||||
/* check with last intersected shadow face */
|
||||
if(is->face_last!=NULL && is->face_last!=is->faceorig) {
|
||||
if(is->face_last!=NULL && !(is->face_last==is->faceorig && is->ob_last==is->oborig)) {
|
||||
if(checkfunc(is, is->face_last)) {
|
||||
is->ob= is->ob_last;
|
||||
is->face= is->face_last;
|
||||
VECSUB(is->vec, is->end, is->start);
|
||||
if(RE_ray_face_intersection(is, oc->coordsfunc)) return 1;
|
||||
if(RE_ray_face_intersection(is, oc->transformfunc, oc->coordsfunc)) return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1349,6 +1425,7 @@ int RE_ray_tree_intersect_check(RayTree *tree, Isect *is, RayCheckFunc checkfunc
|
||||
}
|
||||
|
||||
/* reached end, no intersections found */
|
||||
is->ob_last= 0;
|
||||
is->face_last= NULL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ static void halo_pixelstruct(HaloRen *har, float *rb, float dist, float xn, floa
|
||||
|
||||
static void halo_tile(RenderPart *pa, float *pass, unsigned int lay)
|
||||
{
|
||||
HaloRen *har = NULL;
|
||||
HaloRen *har;
|
||||
rcti disprect= pa->disprect, testrect= pa->disprect;
|
||||
float dist, xsq, ysq, xn, yn, *rb;
|
||||
float col[4];
|
||||
@ -231,9 +231,7 @@ static void halo_tile(RenderPart *pa, float *pass, unsigned int lay)
|
||||
}
|
||||
|
||||
for(a=0; a<R.tothalo; a++) {
|
||||
if((a & 255)==0)
|
||||
har= R.bloha[a>>8];
|
||||
else har++;
|
||||
har= R.sortedhalos[a];
|
||||
|
||||
/* layer test, clip halo with y */
|
||||
if((har->lay & lay)==0);
|
||||
@ -388,8 +386,8 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset,
|
||||
if(shi->totuv) {
|
||||
float mult= (float)count_mask(curmask)/(float)R.osa;
|
||||
fp= rpass->rect + 3*offset;
|
||||
fp[0]+= mult*(0.5f + 0.5f*shi->uv[0].uv[0]);
|
||||
fp[1]+= mult*(0.5f + 0.5f*shi->uv[0].uv[1]);
|
||||
fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]);
|
||||
fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]);
|
||||
fp[2]+= mult;
|
||||
}
|
||||
break;
|
||||
@ -398,7 +396,7 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset,
|
||||
if(shi->vlr) {
|
||||
fp= rpass->rect + offset;
|
||||
if(*fp==0.0f)
|
||||
*fp= (float)shi->vlr->ob->index;
|
||||
*fp= (float)shi->obr->ob->index;
|
||||
}
|
||||
break;
|
||||
case SCE_PASS_VECTOR:
|
||||
@ -463,8 +461,8 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult
|
||||
break;
|
||||
case SCE_PASS_UV:
|
||||
if(shi->totuv) {
|
||||
uvcol[0]= 0.5f + 0.5f*shi->uv[0].uv[0];
|
||||
uvcol[1]= 0.5f + 0.5f*shi->uv[0].uv[1];
|
||||
uvcol[0]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[0];
|
||||
uvcol[1]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[1];
|
||||
uvcol[2]= 1.0f;
|
||||
col= uvcol;
|
||||
}
|
||||
@ -476,7 +474,7 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult
|
||||
case SCE_PASS_INDEXOB:
|
||||
if(shi->vlr) {
|
||||
fp= rpass->rect + offset;
|
||||
*fp= (float)shi->vlr->ob->index;
|
||||
*fp= (float)shi->obr->ob->index;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -615,7 +613,7 @@ static void freeps(ListBase *lb)
|
||||
lb->first= lb->last= NULL;
|
||||
}
|
||||
|
||||
static void addps(ListBase *lb, long *rd, int facenr, int z, unsigned short mask)
|
||||
static void addps(ListBase *lb, long *rd, int obi, int facenr, int z, unsigned short mask)
|
||||
{
|
||||
PixStrMain *psm;
|
||||
PixStr *ps, *last= NULL;
|
||||
@ -624,7 +622,7 @@ static void addps(ListBase *lb, long *rd, int facenr, int z, unsigned short mask
|
||||
ps= (PixStr *)(*rd);
|
||||
|
||||
while(ps) {
|
||||
if( ps->facenr == facenr ) {
|
||||
if( ps->obi == obi && ps->facenr == facenr ) {
|
||||
ps->mask |= mask;
|
||||
return;
|
||||
}
|
||||
@ -645,30 +643,13 @@ static void addps(ListBase *lb, long *rd, int facenr, int z, unsigned short mask
|
||||
else *rd= (long)ps;
|
||||
|
||||
ps->next= NULL;
|
||||
ps->obi= obi;
|
||||
ps->facenr= facenr;
|
||||
ps->z= z;
|
||||
ps->mask = mask;
|
||||
ps->shadfac= 0;
|
||||
}
|
||||
|
||||
static void make_pixelstructs(RenderPart *pa, ListBase *lb)
|
||||
{
|
||||
long *rd= pa->rectdaps;
|
||||
int *rp= pa->rectp;
|
||||
int *rz= pa->rectz;
|
||||
int x, y;
|
||||
int mask= 1<<pa->sample;
|
||||
|
||||
for(y=0; y<pa->recty; y++) {
|
||||
for(x=0; x<pa->rectx; x++, rd++, rp++) {
|
||||
if(*rp) {
|
||||
addps(lb, rd, *rp, *(rz+x), mask);
|
||||
}
|
||||
}
|
||||
rz+= pa->rectx;
|
||||
}
|
||||
}
|
||||
|
||||
static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
|
||||
{
|
||||
float addcol[4];
|
||||
@ -704,7 +685,7 @@ static void convert_to_key_alpha(RenderPart *pa, float *rectf)
|
||||
}
|
||||
|
||||
/* adds only alpha values */
|
||||
static void edge_enhance_tile(RenderPart *pa, float *rectf)
|
||||
void edge_enhance_tile(RenderPart *pa, float *rectf)
|
||||
{
|
||||
/* use zbuffer to define edges, add it to the image */
|
||||
int y, x, col, *rz, *rz1, *rz2, *rz3;
|
||||
@ -835,6 +816,36 @@ static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dma
|
||||
dest[3]= (mul*dest[3]) + source[3];
|
||||
}
|
||||
|
||||
typedef struct ZbufSolidData {
|
||||
RenderLayer *rl;
|
||||
ListBase *psmlist;
|
||||
float *edgerect;
|
||||
} ZbufSolidData;
|
||||
|
||||
void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
|
||||
{
|
||||
ZbufSolidData *sdata= (ZbufSolidData*)data;
|
||||
ListBase *lb= sdata->psmlist;
|
||||
long *rd= pa->rectdaps;
|
||||
int *ro= zspan->recto;
|
||||
int *rp= zspan->rectp;
|
||||
int *rz= zspan->rectz;
|
||||
int x, y;
|
||||
int mask= 1<<sample;
|
||||
|
||||
for(y=0; y<pa->recty; y++) {
|
||||
for(x=0; x<pa->rectx; x++, rd++, rp++, ro++) {
|
||||
if(*rp) {
|
||||
addps(lb, rd, *ro, *rp, *(rz+x), mask);
|
||||
}
|
||||
}
|
||||
rz+= pa->rectx;
|
||||
}
|
||||
|
||||
if(sdata->rl->layflag & SCE_LAY_EDGE)
|
||||
if(R.r.mode & R_EDGE)
|
||||
edge_enhance_tile(pa, sdata->edgerect);
|
||||
}
|
||||
|
||||
/* main call for shading Delta Accum, for OSA */
|
||||
/* supposed to be fully threadable! */
|
||||
@ -845,10 +856,9 @@ void zbufshadeDA_tile(RenderPart *pa)
|
||||
ListBase psmlist= {NULL, NULL};
|
||||
float *edgerect= NULL;
|
||||
|
||||
set_part_zbuf_clipflag(pa);
|
||||
|
||||
/* allocate the necessary buffers */
|
||||
/* zbuffer inits these rects */
|
||||
pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
|
||||
pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
|
||||
pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
|
||||
|
||||
@ -863,14 +873,13 @@ void zbufshadeDA_tile(RenderPart *pa)
|
||||
edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
|
||||
|
||||
/* always fill visibility */
|
||||
for(pa->sample=0; pa->sample<R.osa; pa->sample++) {
|
||||
zbuffer_solid(pa, rl->lay, rl->layflag);
|
||||
make_pixelstructs(pa, &psmlist);
|
||||
|
||||
if(rl->layflag & SCE_LAY_EDGE)
|
||||
if(R.r.mode & R_EDGE)
|
||||
edge_enhance_tile(pa, edgerect);
|
||||
|
||||
for(pa->sample=0; pa->sample<R.osa; pa->sample+=4) {
|
||||
ZbufSolidData sdata;
|
||||
|
||||
sdata.rl= rl;
|
||||
sdata.psmlist= &psmlist;
|
||||
sdata.edgerect= edgerect;
|
||||
zbuffer_solid(pa, rl->lay, rl->layflag, make_pixelstructs, &sdata);
|
||||
if(R.test_break()) break;
|
||||
}
|
||||
|
||||
@ -931,7 +940,7 @@ void zbufshadeDA_tile(RenderPart *pa)
|
||||
}
|
||||
|
||||
/* strand rendering */
|
||||
if((rl->layflag & SCE_LAY_STRAND) && R.strandbufs.first) {
|
||||
if((rl->layflag & SCE_LAY_STRAND) && R.totstrand) {
|
||||
float *fcol, *scol;
|
||||
unsigned short *strandmask, *solidmask= NULL; /* 16 bits, MAX_OSA */
|
||||
int x;
|
||||
@ -998,9 +1007,9 @@ void zbufshadeDA_tile(RenderPart *pa)
|
||||
}
|
||||
|
||||
/* free all */
|
||||
MEM_freeN(pa->recto); pa->recto= NULL;
|
||||
MEM_freeN(pa->rectp); pa->rectp= NULL;
|
||||
MEM_freeN(pa->rectz); pa->rectz= NULL;
|
||||
MEM_freeN(pa->clipflag); pa->clipflag= NULL;
|
||||
|
||||
/* display active layer */
|
||||
rr->renrect.ymin=rr->renrect.ymax= 0;
|
||||
@ -1025,9 +1034,8 @@ void zbufshade_tile(RenderPart *pa)
|
||||
ps.next= NULL;
|
||||
ps.mask= 0xFFFF;
|
||||
|
||||
set_part_zbuf_clipflag(pa);
|
||||
|
||||
/* zbuffer code clears/inits rects */
|
||||
pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
|
||||
pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
|
||||
pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
|
||||
|
||||
@ -1037,7 +1045,7 @@ void zbufshade_tile(RenderPart *pa)
|
||||
shade_sample_initialize(&ssamp, pa, rl);
|
||||
addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
|
||||
|
||||
zbuffer_solid(pa, rl->lay, rl->layflag);
|
||||
zbuffer_solid(pa, rl->lay, rl->layflag, NULL, NULL);
|
||||
|
||||
if(!R.test_break()) { /* NOTE: this if() is not consistant */
|
||||
|
||||
@ -1055,7 +1063,8 @@ void zbufshade_tile(RenderPart *pa)
|
||||
|
||||
if(rl->layflag & SCE_LAY_SOLID) {
|
||||
float *fcol= rl->rectf;
|
||||
int x, y, *rp= pa->rectp, *rz= pa->rectz, offs=0, seed;
|
||||
int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz;
|
||||
int x, y, offs=0, seed;
|
||||
|
||||
/* we set per pixel a fixed seed, for random AO and shadow samples */
|
||||
seed= pa->rectx*pa->disprect.ymin;
|
||||
@ -1065,15 +1074,19 @@ void zbufshade_tile(RenderPart *pa)
|
||||
ISB_create(pa, NULL);
|
||||
|
||||
for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
|
||||
for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, rp++, fcol+=4, offs++) {
|
||||
for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ro++, rz++, rp++, fcol+=4, offs++) {
|
||||
/* per pixel fixed seed */
|
||||
BLI_thread_srandom(pa->thread, seed++);
|
||||
|
||||
if(*rp) {
|
||||
ps.obi= *ro;
|
||||
ps.facenr= *rp;
|
||||
ps.z= *rz;
|
||||
if(shade_samples(&ssamp, &ps, x, y)) {
|
||||
QUATCOPY(fcol, ssamp.shr[0].combined);
|
||||
|
||||
if(!(fcol[0] == fcol[0]))
|
||||
printvecf("fudgecol", fcol);
|
||||
|
||||
/* passes */
|
||||
if(addpassflag)
|
||||
@ -1124,7 +1137,7 @@ void zbufshade_tile(RenderPart *pa)
|
||||
}
|
||||
|
||||
/* strand rendering */
|
||||
if((rl->layflag & SCE_LAY_STRAND) && R.strandbufs.first) {
|
||||
if((rl->layflag & SCE_LAY_STRAND) && R.totstrand) {
|
||||
float *fcol, *scol;
|
||||
int x;
|
||||
|
||||
@ -1169,9 +1182,9 @@ void zbufshade_tile(RenderPart *pa)
|
||||
rr->renrect.ymin=rr->renrect.ymax= 0;
|
||||
rr->renlay= render_get_active_layer(&R, rr);
|
||||
|
||||
MEM_freeN(pa->recto); pa->recto= NULL;
|
||||
MEM_freeN(pa->rectp); pa->rectp= NULL;
|
||||
MEM_freeN(pa->rectz); pa->rectz= NULL;
|
||||
MEM_freeN(pa->clipflag); pa->clipflag= NULL;
|
||||
}
|
||||
|
||||
/* SSS preprocess tile render, fully threadable */
|
||||
@ -1181,7 +1194,7 @@ typedef struct ZBufSSSHandle {
|
||||
int totps;
|
||||
} ZBufSSSHandle;
|
||||
|
||||
static void addps_sss(void *cb_handle, int facenr, int x, int y, int z)
|
||||
static void addps_sss(void *cb_handle, int obi, int facenr, int x, int y, int z)
|
||||
{
|
||||
ZBufSSSHandle *handle = cb_handle;
|
||||
RenderPart *pa= handle->pa;
|
||||
@ -1196,54 +1209,50 @@ static void addps_sss(void *cb_handle, int facenr, int x, int y, int z)
|
||||
if(pa->rectall) {
|
||||
long *rs= pa->rectall + pa->rectx*y + x;
|
||||
|
||||
addps(&handle->psmlist, rs, facenr, z, 0);
|
||||
addps(&handle->psmlist, rs, obi, facenr, z, 0);
|
||||
handle->totps++;
|
||||
}
|
||||
if(pa->rectz) {
|
||||
int *rz= pa->rectz + pa->rectx*y + x;
|
||||
int *rp= pa->rectp + pa->rectx*y + x;
|
||||
int *ro= pa->recto + pa->rectx*y + x;
|
||||
|
||||
if(z < *rz) {
|
||||
if(*rp == 0)
|
||||
handle->totps++;
|
||||
*rz= z;
|
||||
*rp= facenr;
|
||||
*ro= obi;
|
||||
}
|
||||
}
|
||||
if(pa->rectbackz) {
|
||||
int *rz= pa->rectbackz + pa->rectx*y + x;
|
||||
int *rp= pa->rectbackp + pa->rectx*y + x;
|
||||
int *ro= pa->rectbacko + pa->rectx*y + x;
|
||||
|
||||
if(z >= *rz) {
|
||||
if(*rp == 0)
|
||||
handle->totps++;
|
||||
*rz= z;
|
||||
*rp= facenr;
|
||||
*ro= obi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void shade_sample_sss(ShadeSample *ssamp, Material *mat, VlakRen *vlr, int quad, float x, float y, float z, float *co, float *color, float *area)
|
||||
static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRen *obi, VlakRen *vlr, int quad, float x, float y, float z, float *co, float *color, float *area)
|
||||
{
|
||||
ShadeInput *shi= ssamp->shi;
|
||||
ShadeResult shr;
|
||||
float texfac, orthoarea, nor[3];
|
||||
|
||||
/* normal flipping must be disabled to make back scattering work, so that
|
||||
backside faces actually face any lighting from the back */
|
||||
shi->puno= 0;
|
||||
|
||||
/* cache for shadow */
|
||||
shi->samplenr++;
|
||||
|
||||
if(quad)
|
||||
shade_input_set_triangle_i(shi, vlr, 0, 2, 3);
|
||||
shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
|
||||
else
|
||||
shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
|
||||
|
||||
/* we don't want flipped normals, they screw up back scattering */
|
||||
if(vlr->noflag & R_FLIPPED_NO)
|
||||
VecMulf(shi->facenor, -1.0f);
|
||||
shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
|
||||
|
||||
/* center pixel */
|
||||
x += 0.5f;
|
||||
@ -1269,8 +1278,12 @@ static void shade_sample_sss(ShadeSample *ssamp, Material *mat, VlakRen *vlr, in
|
||||
shade_input_set_uv(shi);
|
||||
shade_input_set_normals(shi);
|
||||
|
||||
/* we don't want flipped normals, they screw up back scattering */
|
||||
if(shi->flippednor)
|
||||
shade_input_flip_normals(shi);
|
||||
|
||||
/* not a pretty solution, but fixes common cases */
|
||||
if(vlr->ob && vlr->ob->transflag & OB_NEG_SCALE) {
|
||||
if(shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) {
|
||||
VecMulf(shi->vn, -1.0f);
|
||||
VecMulf(shi->vno, -1.0f);
|
||||
}
|
||||
@ -1311,15 +1324,16 @@ static void shade_sample_sss(ShadeSample *ssamp, Material *mat, VlakRen *vlr, in
|
||||
|
||||
static void zbufshade_sss_free(RenderPart *pa)
|
||||
{
|
||||
MEM_freeN(pa->clipflag); pa->clipflag= NULL;
|
||||
#if 0
|
||||
MEM_freeN(pa->rectall); pa->rectall= NULL;
|
||||
freeps(&handle.psmlist);
|
||||
#else
|
||||
MEM_freeN(pa->rectz); pa->rectz= NULL;
|
||||
MEM_freeN(pa->rectp); pa->rectp= NULL;
|
||||
MEM_freeN(pa->recto); pa->recto= NULL;
|
||||
MEM_freeN(pa->rectbackz); pa->rectbackz= NULL;
|
||||
MEM_freeN(pa->rectbackp); pa->rectbackp= NULL;
|
||||
MEM_freeN(pa->rectbacko); pa->rectbacko= NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1334,15 +1348,13 @@ void zbufshade_sss_tile(RenderPart *pa)
|
||||
Material *mat= re->sss_mat;
|
||||
float (*co)[3], (*color)[3], *area, *fcol= rl->rectf;
|
||||
int x, y, seed, quad, totpoint, display = !(re->r.scemode & R_PREVIEWBUTS);
|
||||
int *rz, *rp, *rbz, *rbp;
|
||||
int *ro, *rz, *rp, *rbo, *rbz, *rbp;
|
||||
#if 0
|
||||
PixStr *ps;
|
||||
long *rs;
|
||||
int z;
|
||||
#endif
|
||||
|
||||
set_part_zbuf_clipflag(pa);
|
||||
|
||||
/* setup pixelstr list and buffer for zbuffering */
|
||||
handle.pa= pa;
|
||||
handle.totps= 0;
|
||||
@ -1353,8 +1365,10 @@ void zbufshade_sss_tile(RenderPart *pa)
|
||||
|
||||
pa->rectall= MEM_callocN(sizeof(long)*pa->rectx*pa->recty+4, "rectall");
|
||||
#else
|
||||
pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
|
||||
pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
|
||||
pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
|
||||
pa->rectbacko= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbacko");
|
||||
pa->rectbackp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackp");
|
||||
pa->rectbackz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackz");
|
||||
#endif
|
||||
@ -1397,8 +1411,10 @@ void zbufshade_sss_tile(RenderPart *pa)
|
||||
#else
|
||||
rz= pa->rectz;
|
||||
rp= pa->rectp;
|
||||
ro= pa->recto;
|
||||
rbz= pa->rectbackz;
|
||||
rbp= pa->rectbackp;
|
||||
rbo= pa->rectbacko;
|
||||
#endif
|
||||
totpoint= 0;
|
||||
|
||||
@ -1411,11 +1427,13 @@ void zbufshade_sss_tile(RenderPart *pa)
|
||||
if(rs) {
|
||||
/* for each sample in this pixel, shade it */
|
||||
for(ps=(PixStr*)*rs; ps; ps=ps->next) {
|
||||
vlr= RE_findOrAddVlak(re, (ps->facenr-1) & RE_QUAD_MASK);
|
||||
ObjectInstanceRen *obi= &re->objectinstance[ps->obi];
|
||||
ObjectRen *obr= obi->obr;
|
||||
vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
|
||||
quad= (ps->facenr & RE_QUAD_OFFS);
|
||||
z= ps->z;
|
||||
|
||||
shade_sample_sss(&ssamp, mat, vlr, quad, x, y, z,
|
||||
shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, z,
|
||||
co[totpoint], color[totpoint], &area[totpoint]);
|
||||
|
||||
totpoint++;
|
||||
@ -1429,11 +1447,14 @@ void zbufshade_sss_tile(RenderPart *pa)
|
||||
#else
|
||||
if(rp) {
|
||||
if(*rp != 0) {
|
||||
ObjectInstanceRen *obi= &re->objectinstance[*ro];
|
||||
ObjectRen *obr= obi->obr;
|
||||
|
||||
/* shade front */
|
||||
vlr= RE_findOrAddVlak(re, (*rp-1) & RE_QUAD_MASK);
|
||||
vlr= RE_findOrAddVlak(obr, (*rp-1) & RE_QUAD_MASK);
|
||||
quad= ((*rp) & RE_QUAD_OFFS);
|
||||
|
||||
shade_sample_sss(&ssamp, mat, vlr, quad, x, y, *rz,
|
||||
shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rz,
|
||||
co[totpoint], color[totpoint], &area[totpoint]);
|
||||
|
||||
VECADD(fcol, fcol, color[totpoint]);
|
||||
@ -1441,16 +1462,19 @@ void zbufshade_sss_tile(RenderPart *pa)
|
||||
totpoint++;
|
||||
}
|
||||
|
||||
rp++; rz++;
|
||||
rp++; rz++; ro++;
|
||||
}
|
||||
|
||||
if(rbp) {
|
||||
if(*rbp != 0 && *rbp != *(rp-1)) {
|
||||
if(*rbp != 0 && !(*rbp == *(rp-1) && *rbo == *(ro-1))) {
|
||||
ObjectInstanceRen *obi= &re->objectinstance[*rbo];
|
||||
ObjectRen *obr= obi->obr;
|
||||
|
||||
/* shade back */
|
||||
vlr= RE_findOrAddVlak(re, (*rbp-1) & RE_QUAD_MASK);
|
||||
vlr= RE_findOrAddVlak(obr, (*rbp-1) & RE_QUAD_MASK);
|
||||
quad= ((*rbp) & RE_QUAD_OFFS);
|
||||
|
||||
shade_sample_sss(&ssamp, mat, vlr, quad, x, y, *rbz,
|
||||
shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rbz,
|
||||
co[totpoint], color[totpoint], &area[totpoint]);
|
||||
|
||||
/* to indicate this is a back sample */
|
||||
@ -1461,7 +1485,7 @@ void zbufshade_sss_tile(RenderPart *pa)
|
||||
totpoint++;
|
||||
}
|
||||
|
||||
rbz++; rbp++;
|
||||
rbz++; rbp++; rbo++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1637,7 +1661,7 @@ void add_halo_flare(Render *re)
|
||||
{
|
||||
RenderResult *rr= re->result;
|
||||
RenderLayer *rl;
|
||||
HaloRen *har = NULL;
|
||||
HaloRen *har;
|
||||
int a, mode, do_draw=0;
|
||||
|
||||
/* for now, we get the first renderlayer in list with halos set */
|
||||
@ -1654,8 +1678,7 @@ void add_halo_flare(Render *re)
|
||||
project_renderdata(&R, projectverto, 0, 0, 0);
|
||||
|
||||
for(a=0; a<R.tothalo; a++) {
|
||||
if((a & 255)==0) har= R.bloha[a>>8];
|
||||
else har++;
|
||||
har= R.sortedhalos[a];
|
||||
|
||||
if(har->flarec) {
|
||||
do_draw= 1;
|
||||
@ -1708,6 +1731,7 @@ void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
|
||||
|
||||
typedef struct BakeShade {
|
||||
ShadeSample ssamp;
|
||||
ObjectInstanceRen *obi;
|
||||
VlakRen *vlr;
|
||||
|
||||
ZSpan *zspan;
|
||||
@ -1723,34 +1747,31 @@ typedef struct BakeShade {
|
||||
float *rect_float;
|
||||
} BakeShade;
|
||||
|
||||
static void bake_set_shade_input(VlakRen *vlr, ShadeInput *shi, int quad, int isect, int x, int y, float u, float v)
|
||||
static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int isect, int x, int y, float u, float v)
|
||||
{
|
||||
if(isect) {
|
||||
/* raytrace intersection with different u,v than scanconvert */
|
||||
if(vlr->v4) {
|
||||
if(quad)
|
||||
shade_input_set_triangle_i(shi, vlr, 2, 1, 3);
|
||||
shade_input_set_triangle_i(shi, obi, vlr, 2, 1, 3);
|
||||
else
|
||||
shade_input_set_triangle_i(shi, vlr, 0, 1, 3);
|
||||
shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 3);
|
||||
}
|
||||
else
|
||||
shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
|
||||
shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
|
||||
}
|
||||
else {
|
||||
/* regular scanconvert */
|
||||
if(quad)
|
||||
shade_input_set_triangle_i(shi, vlr, 0, 2, 3);
|
||||
shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
|
||||
else
|
||||
shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
|
||||
shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
|
||||
}
|
||||
|
||||
/* set up view vector */
|
||||
VECCOPY(shi->view, shi->co);
|
||||
Normalize(shi->view);
|
||||
|
||||
/* no face normal flip */
|
||||
shi->puno= 0;
|
||||
|
||||
/* cache for shadow */
|
||||
shi->samplenr++;
|
||||
|
||||
@ -1760,13 +1781,18 @@ static void bake_set_shade_input(VlakRen *vlr, ShadeInput *shi, int quad, int is
|
||||
shi->ys= y;
|
||||
|
||||
shade_input_set_normals(shi);
|
||||
|
||||
/* no normal flip */
|
||||
if(shi->flippednor)
|
||||
shade_input_flip_normals(shi);
|
||||
}
|
||||
|
||||
static void bake_shade(void *handle, Object *ob, VlakRen *vlr, ShadeInput *shi, int quad, int x, int y, float u, float v, float *tvn, float *ttang)
|
||||
static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int x, int y, float u, float v, float *tvn, float *ttang)
|
||||
{
|
||||
BakeShade *bs= handle;
|
||||
ShadeSample *ssamp= &bs->ssamp;
|
||||
ShadeResult shr;
|
||||
VlakRen *vlr= shi->vlr;
|
||||
|
||||
/* init material vars */
|
||||
memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); // note, keep this synced with render_types.h
|
||||
@ -1850,9 +1876,9 @@ static int bake_check_intersect(Isect *is, RayFace *face)
|
||||
BakeShade *bs = (BakeShade*)is->userdata;
|
||||
|
||||
/* no direction checking for now, doesn't always improve the result
|
||||
* (INPR(vlr->n, bs->dir) > 0.0f); */
|
||||
* (INPR(shi->facenor, bs->dir) > 0.0f); */
|
||||
|
||||
return (vlr->ob != bs->actob);
|
||||
return (vlr->obr->ob != bs->actob);
|
||||
}
|
||||
|
||||
static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *dir, float sign, float *hitco)
|
||||
@ -1884,7 +1910,8 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
|
||||
{
|
||||
BakeShade *bs= handle;
|
||||
VlakRen *vlr= bs->vlr;
|
||||
Object *ob= vlr->ob;
|
||||
ObjectInstanceRen *obi= bs->obi;
|
||||
Object *ob= obi->obr->ob;
|
||||
float l, *v1, *v2, *v3, tvn[3], ttang[3];
|
||||
int quad;
|
||||
ShadeSample *ssamp= &bs->ssamp;
|
||||
@ -1913,8 +1940,11 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
|
||||
shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
|
||||
shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
|
||||
|
||||
if(obi->flag & R_TRANSFORMED)
|
||||
Mat4MulVecfl(obi->mat, shi->co);
|
||||
|
||||
quad= bs->quad;
|
||||
bake_set_shade_input(vlr, shi, quad, 0, x, y, u, v);
|
||||
bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v);
|
||||
|
||||
if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) {
|
||||
shade_input_set_shade_texco(shi);
|
||||
@ -1940,6 +1970,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
|
||||
VECCOPY(isec.start, shi->co);
|
||||
isec.mode= RE_RAY_MIRROR;
|
||||
isec.faceorig= (RayFace*)vlr;
|
||||
isec.oborig= RAY_OBJECT_SET(&R, obi);
|
||||
isec.userdata= bs;
|
||||
|
||||
if(bake_intersect_tree(R.raytree, &isec, shi->vn, sign, co)) {
|
||||
@ -1954,77 +1985,86 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
|
||||
/* if hit, we shade from the new point, otherwise from point one starting face */
|
||||
if(hit) {
|
||||
vlr= (VlakRen*)minisec.face;
|
||||
obi= RAY_OBJECT_GET(&R, minisec.ob);
|
||||
quad= (minisec.isect == 2);
|
||||
VECCOPY(shi->co, minco);
|
||||
|
||||
u= -minisec.u;
|
||||
v= -minisec.v;
|
||||
bake_set_shade_input(vlr, shi, quad, 1, x, y, u, v);
|
||||
bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v);
|
||||
}
|
||||
}
|
||||
|
||||
if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT)
|
||||
bake_shade(handle, ob, vlr, shi, quad, x, y, u, v, tvn, ttang);
|
||||
bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang);
|
||||
else
|
||||
bake_shade(handle, ob, vlr, shi, quad, x, y, u, v, 0, 0);
|
||||
bake_shade(handle, ob, shi, quad, x, y, u, v, 0, 0);
|
||||
}
|
||||
|
||||
static int get_next_bake_face(BakeShade *bs)
|
||||
{
|
||||
ObjectRen *obr;
|
||||
VlakRen *vlr;
|
||||
MTFace *tface;
|
||||
static int v= 0, vdone= 0;
|
||||
static ObjectInstanceRen *obi= NULL;
|
||||
|
||||
if(bs==NULL) {
|
||||
vlr= NULL;
|
||||
v= vdone= 0;
|
||||
obi= R.instancetable.first;
|
||||
return 0;
|
||||
}
|
||||
|
||||
BLI_lock_thread(LOCK_CUSTOM1);
|
||||
|
||||
for(; v<R.totvlak; v++) {
|
||||
vlr= RE_findOrAddVlak(&R, v);
|
||||
|
||||
if((bs->actob && bs->actob == vlr->ob) || (!bs->actob && (vlr->ob->flag & SELECT))) {
|
||||
tface= RE_vlakren_get_tface(&R, vlr, 0, NULL, 0);
|
||||
|
||||
if(tface && tface->tpage) {
|
||||
Image *ima= tface->tpage;
|
||||
ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
|
||||
float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
if(ibuf==NULL)
|
||||
continue;
|
||||
|
||||
if(ibuf->rect==NULL && ibuf->rect_float==NULL)
|
||||
continue;
|
||||
|
||||
if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
|
||||
continue;
|
||||
|
||||
/* find the image for the first time? */
|
||||
if(ima->id.flag & LIB_DOIT) {
|
||||
ima->id.flag &= ~LIB_DOIT;
|
||||
for(; obi; obi=obi->next, v=0) {
|
||||
obr= obi->obr;
|
||||
|
||||
for(; v<obr->totvlak; v++) {
|
||||
vlr= RE_findOrAddVlak(obr, v);
|
||||
|
||||
if((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
|
||||
tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
|
||||
|
||||
if(tface && tface->tpage) {
|
||||
Image *ima= tface->tpage;
|
||||
ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
|
||||
float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
/* we either fill in float or char, this ensures things go fine */
|
||||
if(ibuf->rect_float)
|
||||
imb_freerectImBuf(ibuf);
|
||||
/* clear image */
|
||||
if(R.r.bake_flag & R_BAKE_CLEAR)
|
||||
IMB_rectfill(ibuf, vec);
|
||||
|
||||
/* might be read by UI to set active image for display */
|
||||
R.bakebuf= ima;
|
||||
}
|
||||
|
||||
bs->vlr= vlr;
|
||||
|
||||
bs->vdone++; /* only for error message if nothing was rendered */
|
||||
v++;
|
||||
|
||||
BLI_unlock_thread(LOCK_CUSTOM1);
|
||||
return 1;
|
||||
if(ibuf==NULL)
|
||||
continue;
|
||||
|
||||
if(ibuf->rect==NULL && ibuf->rect_float==NULL)
|
||||
continue;
|
||||
|
||||
if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
|
||||
continue;
|
||||
|
||||
/* find the image for the first time? */
|
||||
if(ima->id.flag & LIB_DOIT) {
|
||||
ima->id.flag &= ~LIB_DOIT;
|
||||
|
||||
/* we either fill in float or char, this ensures things go fine */
|
||||
if(ibuf->rect_float)
|
||||
imb_freerectImBuf(ibuf);
|
||||
/* clear image */
|
||||
if(R.r.bake_flag & R_BAKE_CLEAR)
|
||||
IMB_rectfill(ibuf, vec);
|
||||
|
||||
/* might be read by UI to set active image for display */
|
||||
R.bakebuf= ima;
|
||||
}
|
||||
|
||||
bs->obi= obi;
|
||||
bs->vlr= vlr;
|
||||
|
||||
bs->vdone++; /* only for error message if nothing was rendered */
|
||||
v++;
|
||||
|
||||
BLI_unlock_thread(LOCK_CUSTOM1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2037,7 +2077,9 @@ static int get_next_bake_face(BakeShade *bs)
|
||||
static void shade_tface(BakeShade *bs)
|
||||
{
|
||||
VlakRen *vlr= bs->vlr;
|
||||
MTFace *tface= RE_vlakren_get_tface(&R, vlr, 0, NULL, 0);
|
||||
ObjectInstanceRen *obi= bs->obi;
|
||||
ObjectRen *obr= obi->obr;
|
||||
MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
|
||||
Image *ima= tface->tpage;
|
||||
float vec[4][2];
|
||||
int a, i1, i2, i3;
|
||||
@ -2048,7 +2090,7 @@ static void shade_tface(BakeShade *bs)
|
||||
bs->ibuf= BKE_image_get_ibuf(ima, NULL);
|
||||
/* note, these calls only free/fill contents of zspan struct, not zspan itself */
|
||||
zbuf_free_span(bs->zspan);
|
||||
zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y);
|
||||
zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
|
||||
}
|
||||
|
||||
bs->rectx= bs->ibuf->x;
|
||||
@ -2099,6 +2141,10 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob)
|
||||
ListBase threads;
|
||||
Image *ima;
|
||||
int a, vdone=0;
|
||||
|
||||
/* initialize render global */
|
||||
R= *re;
|
||||
R.bakebuf= NULL;
|
||||
|
||||
/* initialize static vars */
|
||||
get_next_bake_face(NULL);
|
||||
@ -2107,10 +2153,6 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob)
|
||||
for(ima= G.main->image.first; ima; ima= ima->id.next)
|
||||
ima->id.flag |= LIB_DOIT;
|
||||
|
||||
/* initialize render global */
|
||||
R= *re;
|
||||
R.bakebuf= NULL;
|
||||
|
||||
BLI_init_threads(&threads, do_bake_thread, re->r.threads);
|
||||
|
||||
/* get the threads running */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -42,6 +42,8 @@
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_rand.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "renderpipeline.h"
|
||||
#include "render_types.h"
|
||||
#include "renderdatabase.h"
|
||||
@ -279,72 +281,82 @@ static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square)
|
||||
/* sets start/end clipping. lar->shb should be initialized */
|
||||
static void shadowbuf_autoclip(Render *re, LampRen *lar)
|
||||
{
|
||||
ObjectInstanceRen *obi;
|
||||
ObjectRen *obr;
|
||||
VlakRen *vlr= NULL;
|
||||
VertRen *ver= NULL;
|
||||
Material *ma= NULL;
|
||||
float minz, maxz, vec[3], viewmat[4][4];
|
||||
float minz, maxz, vec[3], viewmat[4][4], obviewmat[4][4];
|
||||
unsigned int lay = -1;
|
||||
int a, ok= 1;
|
||||
int i, a, ok= 1;
|
||||
char *clipflag;
|
||||
|
||||
minz= 1.0e30f; maxz= -1.0e30f;
|
||||
Mat4CpyMat4(viewmat, lar->shb->viewmat);
|
||||
|
||||
if(lar->mode & LA_LAYER) lay= lar->lay;
|
||||
|
||||
/* clear clip, is being set if face is visible (clip is calculated for real later) */
|
||||
for(a=0; a<re->totvert; a++) {
|
||||
if((a & 255)==0) ver= RE_findOrAddVert(re, a);
|
||||
else ver++;
|
||||
|
||||
ver->clip= 0;
|
||||
}
|
||||
|
||||
/* set clip in vertices when face visible */
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
|
||||
else vlr++;
|
||||
|
||||
/* note; these conditions are copied from zbuffer_shadow() */
|
||||
if(vlr->mat!= ma) {
|
||||
ma= vlr->mat;
|
||||
ok= 1;
|
||||
if((ma->mode & MA_SHADBUF)==0) ok= 0;
|
||||
}
|
||||
|
||||
if(ok && (vlr->lay & lay)) {
|
||||
vlr->v1->clip= 1;
|
||||
vlr->v2->clip= 1;
|
||||
vlr->v3->clip= 1;
|
||||
if(vlr->v4) vlr->v4->clip= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate min and max */
|
||||
for(a=0; a< re->totvert;a++) {
|
||||
if((a & 255)==0) ver= RE_findOrAddVert(re, a);
|
||||
else ver++;
|
||||
|
||||
if(ver->clip) {
|
||||
VECCOPY(vec, ver->co);
|
||||
Mat4MulVecfl(viewmat, vec);
|
||||
/* Z on visible side of lamp space */
|
||||
if(vec[2] < 0.0f) {
|
||||
float inpr, z= -vec[2];
|
||||
|
||||
/* since vec is rotated in lampspace, this is how to get the cosine of angle */
|
||||
/* precision is set 20% larger */
|
||||
vec[2]*= 1.2f;
|
||||
Normalize(vec);
|
||||
inpr= - vec[2];
|
||||
|
||||
if(inpr>=lar->spotsi) {
|
||||
if(z<minz) minz= z;
|
||||
if(z>maxz) maxz= z;
|
||||
clipflag= MEM_callocN(sizeof(char)*re->totvert, "autoclipflag");
|
||||
|
||||
/* set clip in vertices when face visible */
|
||||
for(i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) {
|
||||
obr= obi->obr;
|
||||
|
||||
if(obi->flag & R_TRANSFORMED)
|
||||
Mat4MulMat4(obviewmat, obi->mat, viewmat);
|
||||
else
|
||||
Mat4CpyMat4(obviewmat, viewmat);
|
||||
|
||||
memset(clipflag, 0, sizeof(char)*obr->totvert);
|
||||
|
||||
/* clear clip, is being set if face is visible (clip is calculated for real later) */
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
|
||||
else vlr++;
|
||||
|
||||
/* note; these conditions are copied from zbuffer_shadow() */
|
||||
if(vlr->mat!= ma) {
|
||||
ma= vlr->mat;
|
||||
ok= 1;
|
||||
if((ma->mode & MA_SHADBUF)==0) ok= 0;
|
||||
}
|
||||
|
||||
if(ok && (vlr->lay & lay)) {
|
||||
clipflag[vlr->v1->index]= 1;
|
||||
clipflag[vlr->v2->index]= 1;
|
||||
clipflag[vlr->v3->index]= 1;
|
||||
if(vlr->v4) clipflag[vlr->v4->index]= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate min and max */
|
||||
for(a=0; a< obr->totvert;a++) {
|
||||
if((a & 255)==0) ver= RE_findOrAddVert(obr, a);
|
||||
else ver++;
|
||||
|
||||
if(clipflag[a]) {
|
||||
VECCOPY(vec, ver->co);
|
||||
Mat4MulVecfl(obviewmat, vec);
|
||||
/* Z on visible side of lamp space */
|
||||
if(vec[2] < 0.0f) {
|
||||
float inpr, z= -vec[2];
|
||||
|
||||
/* since vec is rotated in lampspace, this is how to get the cosine of angle */
|
||||
/* precision is set 20% larger */
|
||||
vec[2]*= 1.2f;
|
||||
Normalize(vec);
|
||||
inpr= - vec[2];
|
||||
|
||||
if(inpr>=lar->spotsi) {
|
||||
if(z<minz) minz= z;
|
||||
if(z>maxz) maxz= z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(clipflag);
|
||||
|
||||
/* set clipping min and max */
|
||||
if(minz < maxz) {
|
||||
@ -369,9 +381,6 @@ void makeshadowbuf(Render *re, LampRen *lar)
|
||||
float wsize, *jitbuf, twozero[2]= {0.0f, 0.0f}, angle, temp;
|
||||
int *rectz, samples;
|
||||
|
||||
/* XXXX EVIL! this global is used in clippyra(), zbuf.c */
|
||||
R.clipcrop= 1.0f;
|
||||
|
||||
if(lar->bufflag & (LA_SHADBUF_AUTO_START|LA_SHADBUF_AUTO_END))
|
||||
shadowbuf_autoclip(re, lar);
|
||||
|
||||
@ -391,38 +400,132 @@ void makeshadowbuf(Render *re, LampRen *lar)
|
||||
MTC_Mat4MulMat4(shb->persmat, shb->viewmat, shb->winmat);
|
||||
|
||||
if(ELEM(lar->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY)) {
|
||||
/* jitter, weights */
|
||||
/* jitter, weights - not threadsafe! */
|
||||
BLI_lock_thread(LOCK_CUSTOM1);
|
||||
shb->jit= give_jitter_tab(shb->samp);
|
||||
make_jitter_weight_tab(shb, lar->filtertype);
|
||||
BLI_unlock_thread(LOCK_CUSTOM1);
|
||||
|
||||
shb->totbuf= lar->buffers;
|
||||
if(shb->totbuf==4) jitbuf= give_jitter_tab(2);
|
||||
else if(shb->totbuf==9) jitbuf= give_jitter_tab(3);
|
||||
else jitbuf= twozero;
|
||||
|
||||
/* temp, will be restored */
|
||||
MTC_Mat4SwapMat4(shb->persmat, re->winmat);
|
||||
|
||||
project_renderdata(re, projectvert, 0, 0, 0);
|
||||
|
||||
/* zbuffering */
|
||||
rectz= MEM_mapallocN(sizeof(int)*shb->size*shb->size, "makeshadbuf");
|
||||
|
||||
for(samples=0; samples<shb->totbuf; samples++) {
|
||||
zbuffer_shadow(re, lar, rectz, shb->size, jitbuf[2*samples], jitbuf[2*samples+1]);
|
||||
zbuffer_shadow(re, shb->persmat, lar, rectz, shb->size, jitbuf[2*samples], jitbuf[2*samples+1]);
|
||||
/* create Z tiles (for compression): this system is 24 bits!!! */
|
||||
compress_shadowbuf(shb, rectz, lar->mode & LA_SQUARE);
|
||||
|
||||
if(re->test_break())
|
||||
break;
|
||||
}
|
||||
|
||||
MEM_freeN(rectz);
|
||||
|
||||
/* old matrix back */
|
||||
MTC_Mat4SwapMat4(shb->persmat, re->winmat);
|
||||
|
||||
/* printf("lampbuf %d\n", sizeoflampbuf(shb)); */
|
||||
}
|
||||
}
|
||||
|
||||
static void *do_shadow_thread(void *re_v)
|
||||
{
|
||||
Render *re= (Render*)re_v;
|
||||
LampRen *lar;
|
||||
|
||||
do {
|
||||
BLI_lock_thread(LOCK_CUSTOM1);
|
||||
for(lar=re->lampren.first; lar; lar=lar->next) {
|
||||
if(lar->shb && !lar->thread_assigned) {
|
||||
lar->thread_assigned= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
BLI_unlock_thread(LOCK_CUSTOM1);
|
||||
|
||||
/* if type is irregular, this only sets the perspective matrix and autoclips */
|
||||
if(lar) {
|
||||
makeshadowbuf(re, lar);
|
||||
BLI_lock_thread(LOCK_CUSTOM1);
|
||||
lar->thread_ready= 1;
|
||||
BLI_unlock_thread(LOCK_CUSTOM1);
|
||||
}
|
||||
} while(lar && !re->test_break());
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static volatile int g_break= 0;
|
||||
static int thread_break(void)
|
||||
{
|
||||
return g_break;
|
||||
}
|
||||
|
||||
void threaded_makeshadowbufs(Render *re)
|
||||
{
|
||||
ListBase threads;
|
||||
LampRen *lar;
|
||||
int a, totthread= 0;
|
||||
int (*test_break)(void);
|
||||
|
||||
/* count number of threads to use */
|
||||
if(G.rendering) {
|
||||
for(lar=re->lampren.first; lar; lar= lar->next)
|
||||
if(lar->shb)
|
||||
totthread++;
|
||||
|
||||
totthread= MIN2(totthread, re->r.threads);
|
||||
}
|
||||
else
|
||||
totthread= 1; /* preview render */
|
||||
|
||||
if(totthread <= 1) {
|
||||
for(lar=re->lampren.first; lar; lar= lar->next) {
|
||||
if(re->test_break()) break;
|
||||
if(lar->shb) {
|
||||
/* if type is irregular, this only sets the perspective matrix and autoclips */
|
||||
makeshadowbuf(re, lar);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* swap test break function */
|
||||
test_break= re->test_break;
|
||||
re->test_break= thread_break;
|
||||
|
||||
for(lar=re->lampren.first; lar; lar= lar->next) {
|
||||
lar->thread_assigned= 0;
|
||||
lar->thread_ready= 0;
|
||||
}
|
||||
|
||||
BLI_init_threads(&threads, do_shadow_thread, totthread);
|
||||
|
||||
for(a=0; a<totthread; a++)
|
||||
BLI_insert_thread(&threads, re);
|
||||
|
||||
/* keep rendering as long as there are shadow buffers not ready */
|
||||
do {
|
||||
if((g_break=test_break()))
|
||||
break;
|
||||
|
||||
PIL_sleep_ms(50);
|
||||
|
||||
BLI_lock_thread(LOCK_CUSTOM1);
|
||||
for(lar=re->lampren.first; lar; lar= lar->next)
|
||||
if(lar->shb && !lar->thread_ready)
|
||||
break;
|
||||
BLI_unlock_thread(LOCK_CUSTOM1);
|
||||
} while(lar);
|
||||
|
||||
BLI_end_threads(&threads);
|
||||
|
||||
/* unset threadsafety */
|
||||
re->test_break= test_break;
|
||||
g_break= 0;
|
||||
}
|
||||
}
|
||||
|
||||
void freeshadowbuf(LampRen *lar)
|
||||
{
|
||||
if(lar->shb) {
|
||||
@ -884,6 +987,7 @@ typedef struct ISBBranch {
|
||||
typedef struct BSPFace {
|
||||
Boxf box;
|
||||
float *v1, *v2, *v3, *v4;
|
||||
int obi; /* object for face lookup */
|
||||
int facenr; /* index to retrieve VlakRen */
|
||||
int type; /* only for strand now */
|
||||
short shad_alpha, is_full;
|
||||
@ -1063,7 +1167,7 @@ static int isb_bsp_insert(ISBBranch *root, MemArena *memarena, ISBSample *sample
|
||||
/* insert */
|
||||
bspn->samples[bspn->totsamp]= sample;
|
||||
bspn->totsamp++;
|
||||
|
||||
|
||||
/* split if allowed and needed */
|
||||
if(bspn->totsamp==BSPMAX_SAMPLE) {
|
||||
if(i==BSPMAX_DEPTH) {
|
||||
@ -1262,7 +1366,7 @@ static void isb_bsp_face_inside(ISBBranch *bspn, BSPFace *face)
|
||||
for(a=bspn->totsamp-1; a>=0; a--) {
|
||||
ISBSample *samp= bspn->samples[a];
|
||||
|
||||
if(samp->facenr!=face->facenr && samp->shadfac) {
|
||||
if((samp->facenr!=face->facenr || samp->obi!=face->obi) && samp->shadfac) {
|
||||
if(face->box.zmin < samp->zco[2]) {
|
||||
if(BLI_in_rctf((rctf *)&face->box, samp->zco[0], samp->zco[1])) {
|
||||
int inshadow= 0;
|
||||
@ -1308,7 +1412,7 @@ static void isb_bsp_recalc_box(ISBBranch *root)
|
||||
}
|
||||
|
||||
/* callback function for zbuf clip */
|
||||
static void isb_bsp_test_strand(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
|
||||
static void isb_bsp_test_strand(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4)
|
||||
{
|
||||
BSPFace face;
|
||||
|
||||
@ -1316,6 +1420,7 @@ static void isb_bsp_test_strand(ZSpan *zspan, int zvlnr, float *v1, float *v2, f
|
||||
face.v2= v2;
|
||||
face.v3= v3;
|
||||
face.v4= v4;
|
||||
face.obi= obi;
|
||||
face.facenr= zvlnr & ~RE_QUAD_OFFS;
|
||||
face.type= R_STRAND;
|
||||
if(R.osa)
|
||||
@ -1341,7 +1446,7 @@ static void isb_bsp_test_strand(ZSpan *zspan, int zvlnr, float *v1, float *v2, f
|
||||
}
|
||||
|
||||
/* callback function for zbuf clip */
|
||||
static void isb_bsp_test_face(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
|
||||
static void isb_bsp_test_face(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4)
|
||||
{
|
||||
BSPFace face;
|
||||
|
||||
@ -1349,6 +1454,7 @@ static void isb_bsp_test_face(ZSpan *zspan, int zvlnr, float *v1, float *v2, flo
|
||||
face.v2= v2;
|
||||
face.v3= v3;
|
||||
face.v4= v4;
|
||||
face.obi= obi;
|
||||
face.facenr= zvlnr & ~RE_QUAD_OFFS;
|
||||
face.type= 0;
|
||||
if(R.osa)
|
||||
@ -1386,13 +1492,15 @@ static int testclip_minmax(float *ho, float *minmax)
|
||||
/* main loop going over all faces and check in bsp overlaps, fill in shadfac values */
|
||||
static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
|
||||
{
|
||||
ObjectInstanceRen *obi;
|
||||
ObjectRen *obr;
|
||||
ShadBuf *shb= lar->shb;
|
||||
ZSpan zspan, zspanstrand;
|
||||
VlakRen *vlr= NULL;
|
||||
Material *ma= NULL;
|
||||
float minmaxf[4];
|
||||
float minmaxf[4], winmat[4][4];
|
||||
int size= shb->size;
|
||||
int a, ok=1, lay= -1;
|
||||
int i, a, ok=1, lay= -1;
|
||||
|
||||
/* further optimize, also sets minz maxz */
|
||||
isb_bsp_recalc_box(root);
|
||||
@ -1406,7 +1514,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
|
||||
if(lar->mode & LA_LAYER) lay= lar->lay;
|
||||
|
||||
/* (ab)use zspan, since we use zbuffer clipping code */
|
||||
zbuf_alloc_span(&zspan, size, size);
|
||||
zbuf_alloc_span(&zspan, size, size, re->clipcrop);
|
||||
|
||||
zspan.zmulx= ((float)size)/2.0f;
|
||||
zspan.zmuly= ((float)size)/2.0f;
|
||||
@ -1422,74 +1530,90 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
|
||||
zspan.zbuffunc= isb_bsp_test_face;
|
||||
zspanstrand.zbuffunc= isb_bsp_test_strand;
|
||||
|
||||
for(a=0; a<re->totvlak; a++) {
|
||||
|
||||
if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
|
||||
else vlr++;
|
||||
|
||||
/* note, these conditions are copied in shadowbuf_autoclip() */
|
||||
if(vlr->mat!= ma) {
|
||||
ma= vlr->mat;
|
||||
ok= 1;
|
||||
if((ma->mode & MA_SHADBUF)==0) ok= 0;
|
||||
if(ma->mode & MA_WIRE) ok= 0;
|
||||
zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha;
|
||||
}
|
||||
|
||||
if(ok && (vlr->lay & lay)) {
|
||||
float hoco[4][4];
|
||||
int c1, c2, c3, c4=0;
|
||||
int d1, d2, d3, d4=0;
|
||||
int partclip;
|
||||
for(i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) {
|
||||
obr= obi->obr;
|
||||
|
||||
if(obi->flag & R_TRANSFORMED)
|
||||
Mat4MulMat4(winmat, obi->mat, shb->persmat);
|
||||
else
|
||||
Mat4CpyMat4(winmat, shb->persmat);
|
||||
|
||||
for(a=0; a<obr->totvlak; a++) {
|
||||
|
||||
/* create hocos per face, it is while render */
|
||||
projectvert(vlr->v1->co, shb->persmat, hoco[0]); d1= testclip_minmax(hoco[0], minmaxf);
|
||||
projectvert(vlr->v2->co, shb->persmat, hoco[1]); d2= testclip_minmax(hoco[1], minmaxf);
|
||||
projectvert(vlr->v3->co, shb->persmat, hoco[2]); d3= testclip_minmax(hoco[2], minmaxf);
|
||||
if(vlr->v4) {
|
||||
projectvert(vlr->v4->co, shb->persmat, hoco[3]); d4= testclip_minmax(hoco[3], minmaxf);
|
||||
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
|
||||
else vlr++;
|
||||
|
||||
/* note, these conditions are copied in shadowbuf_autoclip() */
|
||||
if(vlr->mat!= ma) {
|
||||
ma= vlr->mat;
|
||||
ok= 1;
|
||||
if((ma->mode & MA_SHADBUF)==0) ok= 0;
|
||||
if(ma->mode & MA_WIRE) ok= 0;
|
||||
zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha;
|
||||
}
|
||||
|
||||
/* minmax clipping */
|
||||
if(vlr->v4) partclip= d1 & d2 & d3 & d4;
|
||||
else partclip= d1 & d2 & d3;
|
||||
|
||||
if(partclip==0) {
|
||||
if(ok && (vlr->lay & lay)) {
|
||||
float hoco[4][4];
|
||||
int c1, c2, c3, c4=0;
|
||||
int d1, d2, d3, d4=0;
|
||||
int partclip;
|
||||
|
||||
/* window clipping */
|
||||
c1= testclip(hoco[0]);
|
||||
c2= testclip(hoco[1]);
|
||||
c3= testclip(hoco[2]);
|
||||
if(vlr->v4)
|
||||
c4= testclip(hoco[3]);
|
||||
|
||||
/* ***** NO WIRE YET */
|
||||
if(ma->mode & MA_WIRE)
|
||||
zbufclipwire(&zspan, a+1, vlr);
|
||||
else if(vlr->v4) {
|
||||
if(vlr->flag & R_STRAND)
|
||||
zbufclip4(&zspanstrand, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
|
||||
else
|
||||
zbufclip4(&zspan, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
|
||||
/* create hocos per face, it is while render */
|
||||
projectvert(vlr->v1->co, winmat, hoco[0]); d1= testclip_minmax(hoco[0], minmaxf);
|
||||
projectvert(vlr->v2->co, winmat, hoco[1]); d2= testclip_minmax(hoco[1], minmaxf);
|
||||
projectvert(vlr->v3->co, winmat, hoco[2]); d3= testclip_minmax(hoco[2], minmaxf);
|
||||
if(vlr->v4) {
|
||||
projectvert(vlr->v4->co, winmat, hoco[3]); d4= testclip_minmax(hoco[3], minmaxf);
|
||||
}
|
||||
else
|
||||
zbufclip(&zspan, a+1, hoco[0], hoco[1], hoco[2], c1, c2, c3);
|
||||
|
||||
/* minmax clipping */
|
||||
if(vlr->v4) partclip= d1 & d2 & d3 & d4;
|
||||
else partclip= d1 & d2 & d3;
|
||||
|
||||
if(partclip==0) {
|
||||
|
||||
/* window clipping */
|
||||
c1= testclip(hoco[0]);
|
||||
c2= testclip(hoco[1]);
|
||||
c3= testclip(hoco[2]);
|
||||
if(vlr->v4)
|
||||
c4= testclip(hoco[3]);
|
||||
|
||||
/* ***** NO WIRE YET */
|
||||
if(ma->mode & MA_WIRE) {
|
||||
if(vlr->v4)
|
||||
zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
|
||||
else
|
||||
zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], 0, c1, c2, c3, 0);
|
||||
}
|
||||
else if(vlr->v4) {
|
||||
if(vlr->flag & R_STRAND)
|
||||
zbufclip4(&zspanstrand, i, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
|
||||
else
|
||||
zbufclip4(&zspan, i, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
|
||||
}
|
||||
else
|
||||
zbufclip(&zspan, i, a+1, hoco[0], hoco[1], hoco[2], c1, c2, c3);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zbuf_free_span(&zspan);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* returns 1 when the viewpixel is visible in lampbuffer */
|
||||
static int viewpixel_to_lampbuf(ShadBuf *shb, VlakRen *vlr, float x, float y, float *co)
|
||||
static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *vlr, float x, float y, float *co)
|
||||
{
|
||||
float hoco[4], *v1= vlr->v1->co, *nor= vlr->n;
|
||||
float hoco[4], v1[3], nor[3];
|
||||
float dface, fac, siz;
|
||||
|
||||
RE_vlakren_get_normal(&R, obi, vlr, nor);
|
||||
VECCOPY(v1, vlr->v1->co);
|
||||
if(obi->flag & R_TRANSFORMED)
|
||||
Mat4MulVecfl(obi->mat, v1);
|
||||
|
||||
/* from shadepixel() */
|
||||
dface= v1[0]*nor[0] + v1[1]*nor[1] + v1[2]*nor[2];
|
||||
hoco[3]= 1.0f;
|
||||
@ -1550,7 +1674,7 @@ static int viewpixel_to_lampbuf(ShadBuf *shb, VlakRen *vlr, float x, float y, fl
|
||||
}
|
||||
|
||||
/* storage of shadow results, solid osa and transp case */
|
||||
static void isb_add_shadfac(ISBShadfacA **isbsapp, MemArena *mem, int facenr, short shadfac, short samples)
|
||||
static void isb_add_shadfac(ISBShadfacA **isbsapp, MemArena *mem, int obi, int facenr, short shadfac, short samples)
|
||||
{
|
||||
ISBShadfacA *new;
|
||||
float shadfacf;
|
||||
@ -1562,6 +1686,7 @@ static void isb_add_shadfac(ISBShadfacA **isbsapp, MemArena *mem, int facenr, sh
|
||||
shadfacf= ((float)shadfac)/(4096.0);
|
||||
|
||||
new= BLI_memarena_alloc(mem, sizeof(ISBShadfacA));
|
||||
new->obi= obi;
|
||||
new->facenr= facenr & ~RE_QUAD_OFFS;
|
||||
new->shadfac= shadfacf;
|
||||
if(*isbsapp)
|
||||
@ -1619,7 +1744,7 @@ static void isb_make_buffer(RenderPart *pa, LampRen *lar)
|
||||
ISBBranch root;
|
||||
MemArena *memarena;
|
||||
long *rd;
|
||||
int *rectp, x, y, sindex, sample, bsp_err=0;
|
||||
int *recto, *rectp, x, y, sindex, sample, bsp_err=0;
|
||||
|
||||
/* storage for shadow, per thread */
|
||||
isbdata= shb->isb_result[pa->thread];
|
||||
@ -1669,11 +1794,14 @@ static void isb_make_buffer(RenderPart *pa, LampRen *lar)
|
||||
ps= ps->next;
|
||||
}
|
||||
if(ps && ps->facenr>0) {
|
||||
VlakRen *vlr= RE_findOrAddVlak(&R, (ps->facenr-1) & RE_QUAD_MASK);
|
||||
ObjectInstanceRen *obi= &R.objectinstance[ps->obi];
|
||||
ObjectRen *obr= obi->obr;
|
||||
VlakRen *vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
|
||||
|
||||
samp= samplebuf[sample] + sindex;
|
||||
/* convert image plane pixel location to lamp buffer space */
|
||||
if(viewpixel_to_lampbuf(shb, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], samp->zco)) {
|
||||
if(viewpixel_to_lampbuf(shb, obi, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], samp->zco)) {
|
||||
samp->obi= ps->obi;
|
||||
samp->facenr= ps->facenr & ~RE_QUAD_OFFS;
|
||||
ps->shadfac= 0;
|
||||
samp->shadfac= &ps->shadfac;
|
||||
@ -1685,14 +1813,18 @@ static void isb_make_buffer(RenderPart *pa, LampRen *lar)
|
||||
}
|
||||
else {
|
||||
rectp= pa->rectp + sindex;
|
||||
recto= pa->recto + sindex;
|
||||
if(*rectp>0) {
|
||||
VlakRen *vlr= RE_findOrAddVlak(&R, (*rectp-1) & RE_QUAD_MASK);
|
||||
ObjectInstanceRen *obi= &R.objectinstance[*recto];
|
||||
ObjectRen *obr= obi->obr;
|
||||
VlakRen *vlr= RE_findOrAddVlak(obr, (*rectp-1) & RE_QUAD_MASK);
|
||||
float xs= (float)(x + pa->disprect.xmin);
|
||||
float ys= (float)(y + pa->disprect.ymin);
|
||||
|
||||
samp= samplebuf[0] + sindex;
|
||||
/* convert image plane pixel location to lamp buffer space */
|
||||
if(viewpixel_to_lampbuf(shb, vlr, xs, ys, samp->zco)) {
|
||||
if(viewpixel_to_lampbuf(shb, obi, vlr, xs, ys, samp->zco)) {
|
||||
samp->obi= *recto;
|
||||
samp->facenr= *rectp & ~RE_QUAD_OFFS;
|
||||
samp->shadfac= isbdata->shadfacs + sindex;
|
||||
bound_rectf((rctf *)&root.box, samp->zco);
|
||||
@ -1729,7 +1861,7 @@ static void isb_make_buffer(RenderPart *pa, LampRen *lar)
|
||||
PixStr *ps= (PixStr *)(*rd);
|
||||
while(ps) {
|
||||
if(ps->shadfac)
|
||||
isb_add_shadfac(isbsa, isbdata->memarena, ps->facenr, ps->shadfac, count_mask(ps->mask));
|
||||
isb_add_shadfac(isbsa, isbdata->memarena, ps->obi, ps->facenr, ps->shadfac, count_mask(ps->mask));
|
||||
ps= ps->next;
|
||||
}
|
||||
}
|
||||
@ -1857,7 +1989,9 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la
|
||||
int a;
|
||||
for(a=0; a<4; a++) {
|
||||
if(apn->p[a]) {
|
||||
VlakRen *vlr= RE_findOrAddVlak(&R, (apn->p[a]-1) & RE_QUAD_MASK);
|
||||
ObjectInstanceRen *obi= &R.objectinstance[apn->obi[a]];
|
||||
ObjectRen *obr= obi->obr;
|
||||
VlakRen *vlr= RE_findOrAddVlak(obr, (apn->p[a]-1) & RE_QUAD_MASK);
|
||||
float zco[3];
|
||||
|
||||
/* here we store shadfac, easier to create the end storage buffer. needs zero'ed, multiple shadowbufs use it */
|
||||
@ -1870,8 +2004,9 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la
|
||||
if(apn->mask[a] & mask) {
|
||||
|
||||
/* convert image plane pixel location to lamp buffer space */
|
||||
if(viewpixel_to_lampbuf(shb, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], zco)) {
|
||||
if(viewpixel_to_lampbuf(shb, obi, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], zco)) {
|
||||
samp= isb_alloc_sample_transp(samplebuf[sample] + sindex, memarena);
|
||||
samp->obi= apn->obi[a];
|
||||
samp->facenr= apn->p[a] & ~RE_QUAD_OFFS;
|
||||
samp->shadfac= &apn->shadfac[a];
|
||||
|
||||
@ -1884,9 +2019,10 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la
|
||||
else {
|
||||
|
||||
/* convert image plane pixel location to lamp buffer space */
|
||||
if(viewpixel_to_lampbuf(shb, vlr, xs, ys, zco)) {
|
||||
if(viewpixel_to_lampbuf(shb, obi, vlr, xs, ys, zco)) {
|
||||
|
||||
samp= isb_alloc_sample_transp(samplebuf[0] + sindex, memarena);
|
||||
samp->obi= apn->obi[a];
|
||||
samp->facenr= apn->p[a] & ~RE_QUAD_OFFS;
|
||||
samp->shadfac= &apn->shadfac[a];
|
||||
|
||||
@ -1930,9 +2066,9 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la
|
||||
for(a=0; a<4; a++) {
|
||||
if(apn->p[a] && apn->shadfac[a]) {
|
||||
if(R.osa)
|
||||
isb_add_shadfac(isbsa, isbdata->memarena, apn->p[a], apn->shadfac[a], count_mask(apn->mask[a]));
|
||||
isb_add_shadfac(isbsa, isbdata->memarena, apn->obi[a], apn->p[a], apn->shadfac[a], count_mask(apn->mask[a]));
|
||||
else
|
||||
isb_add_shadfac(isbsa, isbdata->memarena, apn->p[a], apn->shadfac[a], 0);
|
||||
isb_add_shadfac(isbsa, isbdata->memarena, apn->obi[a], apn->p[a], apn->shadfac[a], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1977,10 +2113,11 @@ float ISB_getshadow(ShadeInput *shi, ShadBuf *shb)
|
||||
}
|
||||
else {
|
||||
int sindex= y*isbdata->rectx + x;
|
||||
int obi= shi->obi - R.objectinstance;
|
||||
ISBShadfacA *isbsa= *(isbdata->shadfaca + sindex);
|
||||
|
||||
while(isbsa) {
|
||||
if(isbsa->facenr==shi->facenr+1)
|
||||
if(isbsa->facenr==shi->facenr+1 && isbsa->obi==obi)
|
||||
return isbsa->shadfac>=1.0f?0.0f:1.0f - isbsa->shadfac;
|
||||
isbsa= isbsa->next;
|
||||
}
|
||||
@ -2044,7 +2181,3 @@ void ISB_free(RenderPart *pa)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "shading.h"
|
||||
#include "strand.h"
|
||||
#include "texture.h"
|
||||
#include "zbuf.h"
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
|
||||
@ -122,7 +123,6 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
|
||||
if(shi->depth==0) {
|
||||
if(R.r.mode & R_RAYTRACE) {
|
||||
if(shi->ray_mirror!=0.0f || ((shi->mat->mode & MA_RAYTRANSP) && shr->alpha!=1.0f)) {
|
||||
|
||||
/* ray trace works on combined, but gives pass info */
|
||||
ray_trace(shi, shr);
|
||||
}
|
||||
@ -209,14 +209,28 @@ void vlr_set_uv_indices(VlakRen *vlr, int *i1, int *i2, int *i3)
|
||||
}
|
||||
}
|
||||
|
||||
static void normal_transform(float imat[][3], float *nor)
|
||||
{
|
||||
float xn, yn, zn;
|
||||
|
||||
xn= nor[0];
|
||||
yn= nor[1];
|
||||
zn= nor[2];
|
||||
|
||||
nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
|
||||
nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
|
||||
nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
|
||||
}
|
||||
|
||||
/* copy data from face to ShadeInput, general case */
|
||||
/* indices 0 1 2 3 only. shi->puno should be set! */
|
||||
void shade_input_set_triangle_i(ShadeInput *shi, VlakRen *vlr, short i1, short i2, short i3)
|
||||
/* indices 0 1 2 3 only */
|
||||
void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen *vlr, short i1, short i2, short i3)
|
||||
{
|
||||
VertRen **vpp= &vlr->v1;
|
||||
|
||||
shi->vlr= vlr;
|
||||
shi->obi= obi;
|
||||
shi->obr= obi->obr;
|
||||
|
||||
shi->v1= vpp[i1];
|
||||
shi->v2= vpp[i2];
|
||||
@ -231,39 +245,44 @@ void shade_input_set_triangle_i(ShadeInput *shi, VlakRen *vlr, short i1, short i
|
||||
|
||||
shi->osatex= (shi->mat->texco & TEXCO_OSA);
|
||||
shi->mode= shi->mat->mode_l; /* or-ed result for all nodes */
|
||||
|
||||
/* facenormal copy, can get flipped */
|
||||
shi->flippednor= RE_vlakren_get_normal(&R, obi, vlr, shi->facenor);
|
||||
|
||||
/* copy of original pre-flipped normal, for geometry->front/back node output */
|
||||
VECCOPY(shi->orignor, shi->facenor);
|
||||
if(shi->flippednor)
|
||||
VECMUL(shi->orignor, -1.0f);
|
||||
|
||||
/* calculate vertexnormals */
|
||||
if(vlr->flag & R_SMOOTH) {
|
||||
float *n1= shi->v1->n, *n2= shi->v2->n, *n3= shi->v3->n;
|
||||
char p1, p2, p3;
|
||||
|
||||
p1= 1<<i1;
|
||||
p2= 1<<i2;
|
||||
p3= 1<<i3;
|
||||
|
||||
if(shi->puno & p1) {
|
||||
shi->n1[0]= -n1[0]; shi->n1[1]= -n1[1]; shi->n1[2]= -n1[2];
|
||||
} else {
|
||||
VECCOPY(shi->n1, n1);
|
||||
VECCOPY(shi->n1, shi->v1->n);
|
||||
VECCOPY(shi->n2, shi->v2->n);
|
||||
VECCOPY(shi->n3, shi->v3->n);
|
||||
|
||||
if(obi->flag & R_TRANSFORMED) {
|
||||
normal_transform(obi->imat, shi->n1);
|
||||
normal_transform(obi->imat, shi->n2);
|
||||
normal_transform(obi->imat, shi->n3);
|
||||
}
|
||||
if(shi->puno & p2) {
|
||||
shi->n2[0]= -n2[0]; shi->n2[1]= -n2[1]; shi->n2[2]= -n2[2];
|
||||
} else {
|
||||
VECCOPY(shi->n2, n2);
|
||||
|
||||
if(!(vlr->flag & (R_NOPUNOFLIP|R_TANGENT))) {
|
||||
if(INPR(shi->facenor, shi->n1) < 0.0f) {
|
||||
shi->n1[0]= -shi->n1[0];
|
||||
shi->n1[1]= -shi->n1[1];
|
||||
shi->n1[2]= -shi->n1[2];
|
||||
}
|
||||
if(INPR(shi->facenor, shi->n2) < 0.0f) {
|
||||
shi->n2[0]= -shi->n2[0];
|
||||
shi->n2[1]= -shi->n2[1];
|
||||
shi->n2[2]= -shi->n2[2];
|
||||
}
|
||||
if(INPR(shi->facenor, shi->n3) < 0.0f) {
|
||||
shi->n3[0]= -shi->n3[0];
|
||||
shi->n3[1]= -shi->n3[1];
|
||||
shi->n3[2]= -shi->n3[2];
|
||||
}
|
||||
}
|
||||
if(shi->puno & p3) {
|
||||
shi->n3[0]= -n3[0]; shi->n3[1]= -n3[1]; shi->n3[2]= -n3[2];
|
||||
} else {
|
||||
VECCOPY(shi->n3, n3);
|
||||
}
|
||||
}
|
||||
/* facenormal copy, can get flipped */
|
||||
VECCOPY(shi->facenor, vlr->n);
|
||||
|
||||
/* copy of original pre-flipped normal, for geometry->front/back node output */
|
||||
VECCOPY(shi->orignor, vlr->n);
|
||||
if (vlr->noflag & R_FLIPPED_NO) {
|
||||
VECMUL(shi->orignor, -1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,26 +291,25 @@ void shade_input_set_triangle_i(ShadeInput *shi, VlakRen *vlr, short i1, short i
|
||||
*/
|
||||
|
||||
/* copy data from face to ShadeInput, scanline case */
|
||||
void shade_input_set_triangle(ShadeInput *shi, volatile int facenr, int normal_flip)
|
||||
void shade_input_set_triangle(ShadeInput *shi, volatile int obi, volatile int facenr, int normal_flip)
|
||||
{
|
||||
if(facenr>0) {
|
||||
shi->obi= &R.objectinstance[obi];
|
||||
shi->obr= shi->obi->obr;
|
||||
shi->facenr= (facenr-1) & RE_QUAD_MASK;
|
||||
if( shi->facenr < R.totvlak ) {
|
||||
VlakRen *vlr= RE_findOrAddVlak(&R, shi->facenr);
|
||||
|
||||
shi->puno= normal_flip?vlr->puno:0;
|
||||
if( shi->facenr < shi->obr->totvlak ) {
|
||||
VlakRen *vlr= RE_findOrAddVlak(shi->obr, shi->facenr);
|
||||
|
||||
if(facenr & RE_QUAD_OFFS)
|
||||
shade_input_set_triangle_i(shi, vlr, 0, 2, 3);
|
||||
shade_input_set_triangle_i(shi, shi->obi, vlr, 0, 2, 3);
|
||||
else
|
||||
shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
|
||||
shade_input_set_triangle_i(shi, shi->obi, vlr, 0, 1, 2);
|
||||
}
|
||||
else
|
||||
shi->vlr= NULL; /* general signal we got sky */
|
||||
}
|
||||
else
|
||||
shi->vlr= NULL; /* general signal we got sky */
|
||||
|
||||
}
|
||||
|
||||
/* full osa case: copy static info */
|
||||
@ -310,8 +328,6 @@ void shade_input_set_strand(ShadeInput *shi, StrandRen *strand, StrandPoint *spo
|
||||
shi->osatex= (shi->mat->texco & TEXCO_OSA);
|
||||
shi->mode= shi->mat->mode_l; /* or-ed result for all nodes */
|
||||
|
||||
shi->puno= 0; /* always faces camera automatically */
|
||||
|
||||
/* shade_input_set_viewco equivalent */
|
||||
VECCOPY(shi->co, spoint->co);
|
||||
VECCOPY(shi->view, shi->co);
|
||||
@ -343,6 +359,7 @@ void shade_input_set_strand(ShadeInput *shi, StrandRen *strand, StrandPoint *spo
|
||||
void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert *svert, StrandPoint *spoint)
|
||||
{
|
||||
StrandBuffer *strandbuf= strand->buffer;
|
||||
ObjectRen *obr= strandbuf->obr;
|
||||
StrandVert *sv;
|
||||
int mode= shi->mode; /* or-ed result for all nodes */
|
||||
short texco= shi->mat->texco;
|
||||
@ -360,7 +377,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
|
||||
}
|
||||
|
||||
if(mode & MA_STR_SURFDIFF) {
|
||||
float *surfnor= RE_strandren_get_surfnor(&R, strand, 0);
|
||||
float *surfnor= RE_strandren_get_surfnor(obr, strand, 0);
|
||||
|
||||
if(surfnor)
|
||||
VECCOPY(shi->surfnor, surfnor)
|
||||
@ -378,7 +395,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
|
||||
if(R.r.mode & R_SPEED) {
|
||||
float *speed;
|
||||
|
||||
speed= RE_strandren_get_winspeed(&R, strand, 0);
|
||||
speed= RE_strandren_get_winspeed(shi->obi, strand, 0);
|
||||
if(speed)
|
||||
QUATCOPY(shi->winspeed, speed)
|
||||
else
|
||||
@ -423,7 +440,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
|
||||
shi->totcol= 0;
|
||||
|
||||
if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP)) {
|
||||
for (i=0; (mcol=RE_strandren_get_mcol(&R, strand, i, &name, 0)); i++) {
|
||||
for (i=0; (mcol=RE_strandren_get_mcol(obr, strand, i, &name, 0)); i++) {
|
||||
ShadeInputCol *scol= &shi->col[i];
|
||||
char *cp= (char*)mcol;
|
||||
|
||||
@ -447,7 +464,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; (uv=RE_strandren_get_uv(&R, strand, i, &name, 0)); i++) {
|
||||
for (i=0; (uv=RE_strandren_get_uv(obr, strand, i, &name, 0)); i++) {
|
||||
ShadeInputUV *suv= &shi->uv[i];
|
||||
|
||||
shi->totuv++;
|
||||
@ -569,7 +586,12 @@ void shade_input_set_viewco(ShadeInput *shi, float x, float y, float z)
|
||||
calc_renderco_zbuf(shi->co, shi->view, z);
|
||||
}
|
||||
else {
|
||||
float dface, *v1= shi->v1->co;
|
||||
float dface, v1[3];
|
||||
|
||||
VECCOPY(v1, shi->v1->co);
|
||||
|
||||
if(shi->obi->flag & R_TRANSFORMED)
|
||||
Mat4MulVecfl(shi->obi->mat, v1);
|
||||
|
||||
dface= v1[0]*shi->facenor[0]+v1[1]*shi->facenor[1]+v1[2]*shi->facenor[2];
|
||||
|
||||
@ -652,9 +674,19 @@ void shade_input_set_uv(ShadeInput *shi)
|
||||
{
|
||||
VlakRen *vlr= shi->vlr;
|
||||
|
||||
if( (vlr->flag & R_SMOOTH) || (shi->mat->texco & NEED_UV) || (shi->passflag & SCE_PASS_UV)) {
|
||||
float *v1= shi->v1->co, *v2= shi->v2->co, *v3= shi->v3->co;
|
||||
|
||||
if((vlr->flag & R_SMOOTH) || (shi->mat->texco & NEED_UV) || (shi->passflag & SCE_PASS_UV)) {
|
||||
float v1[3], v2[3], v3[3];
|
||||
|
||||
VECCOPY(v1, shi->v1->co);
|
||||
VECCOPY(v2, shi->v2->co);
|
||||
VECCOPY(v3, shi->v3->co);
|
||||
|
||||
if(shi->obi->flag & R_TRANSFORMED) {
|
||||
Mat4MulVecfl(shi->obi->mat, v1);
|
||||
Mat4MulVecfl(shi->obi->mat, v2);
|
||||
Mat4MulVecfl(shi->obi->mat, v3);
|
||||
}
|
||||
|
||||
/* exception case for wire render of edge */
|
||||
if(vlr->v2==vlr->v3) {
|
||||
float lend, lenc;
|
||||
@ -679,55 +711,35 @@ void shade_input_set_uv(ShadeInput *shi)
|
||||
}
|
||||
else {
|
||||
/* most of this could become re-used for faces */
|
||||
float detsh, t00, t10, t01, t11;
|
||||
|
||||
if(vlr->noflag & R_SNPROJ_X) {
|
||||
t00= v3[0]-v1[0]; t01= v3[1]-v1[1];
|
||||
t10= v3[0]-v2[0]; t11= v3[1]-v2[1];
|
||||
}
|
||||
else if(vlr->noflag & R_SNPROJ_Y) {
|
||||
t00= v3[0]-v1[0]; t01= v3[2]-v1[2];
|
||||
t10= v3[0]-v2[0]; t11= v3[2]-v2[2];
|
||||
}
|
||||
else {
|
||||
t00= v3[1]-v1[1]; t01= v3[2]-v1[2];
|
||||
t10= v3[1]-v2[1]; t11= v3[2]-v2[2];
|
||||
}
|
||||
|
||||
float detsh, t00, t10, t01, t11, xn, yn, zn;
|
||||
int axis1, axis2;
|
||||
|
||||
/* find most stable axis to project */
|
||||
xn= fabs(shi->facenor[0]);
|
||||
yn= fabs(shi->facenor[1]);
|
||||
zn= fabs(shi->facenor[2]);
|
||||
|
||||
if(zn>=xn && zn>=yn) { axis1= 0; axis2= 1; }
|
||||
else if(yn>=xn && yn>=zn) { axis1= 0; axis2= 2; }
|
||||
else { axis1= 1; axis2= 2; }
|
||||
|
||||
/* compute u,v and derivatives */
|
||||
t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];
|
||||
t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];
|
||||
|
||||
detsh= 1.0f/(t00*t11-t10*t01);
|
||||
t00*= detsh; t01*=detsh;
|
||||
t10*=detsh; t11*=detsh;
|
||||
|
||||
if(vlr->noflag & R_SNPROJ_X) {
|
||||
shi->u= (shi->co[0]-v3[0])*t11-(shi->co[1]-v3[1])*t10;
|
||||
shi->v= (shi->co[1]-v3[1])*t00-(shi->co[0]-v3[0])*t01;
|
||||
if(shi->osatex) {
|
||||
shi->dx_u= shi->dxco[0]*t11- shi->dxco[1]*t10;
|
||||
shi->dx_v= shi->dxco[1]*t00- shi->dxco[0]*t01;
|
||||
shi->dy_u= shi->dyco[0]*t11- shi->dyco[1]*t10;
|
||||
shi->dy_v= shi->dyco[1]*t00- shi->dyco[0]*t01;
|
||||
}
|
||||
}
|
||||
else if(vlr->noflag & R_SNPROJ_Y) {
|
||||
shi->u= (shi->co[0]-v3[0])*t11-(shi->co[2]-v3[2])*t10;
|
||||
shi->v= (shi->co[2]-v3[2])*t00-(shi->co[0]-v3[0])*t01;
|
||||
if(shi->osatex) {
|
||||
shi->dx_u= shi->dxco[0]*t11- shi->dxco[2]*t10;
|
||||
shi->dx_v= shi->dxco[2]*t00- shi->dxco[0]*t01;
|
||||
shi->dy_u= shi->dyco[0]*t11- shi->dyco[2]*t10;
|
||||
shi->dy_v= shi->dyco[2]*t00- shi->dyco[0]*t01;
|
||||
}
|
||||
}
|
||||
else {
|
||||
shi->u= (shi->co[1]-v3[1])*t11-(shi->co[2]-v3[2])*t10;
|
||||
shi->v= (shi->co[2]-v3[2])*t00-(shi->co[1]-v3[1])*t01;
|
||||
if(shi->osatex) {
|
||||
shi->dx_u= shi->dxco[1]*t11- shi->dxco[2]*t10;
|
||||
shi->dx_v= shi->dxco[2]*t00- shi->dxco[1]*t01;
|
||||
shi->dy_u= shi->dyco[1]*t11- shi->dyco[2]*t10;
|
||||
shi->dy_v= shi->dyco[2]*t00- shi->dyco[1]*t01;
|
||||
}
|
||||
|
||||
shi->u= (shi->co[axis1]-v3[axis1])*t11-(shi->co[axis2]-v3[axis2])*t10;
|
||||
shi->v= (shi->co[axis2]-v3[axis2])*t00-(shi->co[axis1]-v3[axis1])*t01;
|
||||
if(shi->osatex) {
|
||||
shi->dx_u= shi->dxco[axis1]*t11- shi->dxco[axis2]*t10;
|
||||
shi->dx_v= shi->dxco[axis2]*t00- shi->dxco[axis1]*t01;
|
||||
shi->dy_u= shi->dyco[axis1]*t11- shi->dyco[axis2]*t10;
|
||||
shi->dy_v= shi->dyco[axis2]*t00- shi->dyco[axis1]*t01;
|
||||
}
|
||||
|
||||
/* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */
|
||||
CLAMP(shi->u, -2.0f, 1.0f);
|
||||
CLAMP(shi->v, -2.0f, 1.0f);
|
||||
@ -750,17 +762,36 @@ void shade_input_set_normals(ShadeInput *shi)
|
||||
|
||||
Normalize(shi->vn);
|
||||
}
|
||||
else {
|
||||
else
|
||||
VECCOPY(shi->vn, shi->facenor);
|
||||
}
|
||||
|
||||
/* used in nodes */
|
||||
VECCOPY(shi->vno, shi->vn);
|
||||
|
||||
}
|
||||
|
||||
/* use by raytrace, sss, bake to flip into the right direction */
|
||||
void shade_input_flip_normals(ShadeInput *shi)
|
||||
{
|
||||
shi->facenor[0]= -shi->facenor[0];
|
||||
shi->facenor[1]= -shi->facenor[1];
|
||||
shi->facenor[2]= -shi->facenor[2];
|
||||
|
||||
shi->vn[0]= -shi->vn[0];
|
||||
shi->vn[1]= -shi->vn[1];
|
||||
shi->vn[2]= -shi->vn[2];
|
||||
|
||||
shi->vno[0]= -shi->vno[0];
|
||||
shi->vno[1]= -shi->vno[1];
|
||||
shi->vno[2]= -shi->vno[2];
|
||||
|
||||
shi->flippednor= !shi->flippednor;
|
||||
}
|
||||
|
||||
void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
{
|
||||
ObjectInstanceRen *obi= shi->obi;
|
||||
ObjectRen *obr= shi->obr;
|
||||
VertRen *v1= shi->v1, *v2= shi->v2, *v3= shi->v3;
|
||||
float u= shi->u, v= shi->v;
|
||||
float l= 1.0f+u+v, dl;
|
||||
@ -788,13 +819,17 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
if (mode & (MA_TANGENT_V|MA_NORMAP_TANG) || R.flag & R_NEED_TANGENT) {
|
||||
float *s1, *s2, *s3;
|
||||
|
||||
s1= RE_vertren_get_tangent(&R, v1, 0);
|
||||
s2= RE_vertren_get_tangent(&R, v2, 0);
|
||||
s3= RE_vertren_get_tangent(&R, v3, 0);
|
||||
s1= RE_vertren_get_tangent(obr, v1, 0);
|
||||
s2= RE_vertren_get_tangent(obr, v2, 0);
|
||||
s3= RE_vertren_get_tangent(obr, v3, 0);
|
||||
if(s1 && s2 && s3) {
|
||||
shi->tang[0]= (l*s3[0] - u*s1[0] - v*s2[0]);
|
||||
shi->tang[1]= (l*s3[1] - u*s1[1] - v*s2[1]);
|
||||
shi->tang[2]= (l*s3[2] - u*s1[2] - v*s2[2]);
|
||||
|
||||
if(obi->flag & R_TRANSFORMED)
|
||||
normal_transform(obi->imat, shi->tang);
|
||||
|
||||
/* qdn: normalize just in case */
|
||||
Normalize(shi->tang);
|
||||
}
|
||||
@ -806,13 +841,17 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
if (mode & (MA_TANGENT_V|MA_NORMAP_TANG) || R.flag & R_NEED_TANGENT) {
|
||||
/* qdn: flat faces have tangents too,
|
||||
could pick either one, using average here */
|
||||
float *s1 = RE_vertren_get_tangent(&R, v1, 0);
|
||||
float *s2 = RE_vertren_get_tangent(&R, v2, 0);
|
||||
float *s3 = RE_vertren_get_tangent(&R, v3, 0);
|
||||
float *s1 = RE_vertren_get_tangent(obr, v1, 0);
|
||||
float *s2 = RE_vertren_get_tangent(obr, v2, 0);
|
||||
float *s3 = RE_vertren_get_tangent(obr, v3, 0);
|
||||
if (s1 && s2 && s3) {
|
||||
shi->tang[0] = (s1[0] + s2[0] + s3[0]);
|
||||
shi->tang[1] = (s1[1] + s2[1] + s3[1]);
|
||||
shi->tang[2] = (s1[2] + s2[2] + s3[2]);
|
||||
|
||||
if(obi->flag & R_TRANSFORMED)
|
||||
normal_transform(obi->imat, shi->tang);
|
||||
|
||||
Normalize(shi->tang);
|
||||
}
|
||||
else shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
|
||||
@ -820,10 +859,13 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
}
|
||||
|
||||
if(mode & MA_STR_SURFDIFF) {
|
||||
float *surfnor= RE_vlakren_get_surfnor(&R, shi->vlr, 0);
|
||||
float *surfnor= RE_vlakren_get_surfnor(obr, shi->vlr, 0);
|
||||
|
||||
if(surfnor)
|
||||
if(surfnor) {
|
||||
VECCOPY(shi->surfnor, surfnor)
|
||||
if(obi->flag & R_TRANSFORMED)
|
||||
normal_transform(obi->imat, shi->surfnor);
|
||||
}
|
||||
else
|
||||
VECCOPY(shi->surfnor, shi->vn)
|
||||
|
||||
@ -833,9 +875,9 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
if(R.r.mode & R_SPEED) {
|
||||
float *s1, *s2, *s3;
|
||||
|
||||
s1= RE_vertren_get_winspeed(&R, v1, 0);
|
||||
s2= RE_vertren_get_winspeed(&R, v2, 0);
|
||||
s3= RE_vertren_get_winspeed(&R, v3, 0);
|
||||
s1= RE_vertren_get_winspeed(obi, v1, 0);
|
||||
s2= RE_vertren_get_winspeed(obi, v2, 0);
|
||||
s3= RE_vertren_get_winspeed(obi, v3, 0);
|
||||
if(s1 && s2 && s3) {
|
||||
shi->winspeed[0]= (l*s3[0] - u*s1[0] - v*s2[0]);
|
||||
shi->winspeed[1]= (l*s3[1] - u*s1[1] - v*s2[1]);
|
||||
@ -912,9 +954,11 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
|
||||
shi->totuv= 0;
|
||||
shi->totcol= 0;
|
||||
shi->actuv= obr->actmtface;
|
||||
shi->actcol= obr->actmcol;
|
||||
|
||||
if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP)) {
|
||||
for (i=0; (mcol=RE_vlakren_get_mcol(&R, vlr, i, &name, 0)); i++) {
|
||||
for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)); i++) {
|
||||
ShadeInputCol *scol= &shi->col[i];
|
||||
char *cp1, *cp2, *cp3;
|
||||
|
||||
@ -944,7 +988,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; (tface=RE_vlakren_get_tface(&R, vlr, i, &name, 0)); i++) {
|
||||
for (i=0; (tface=RE_vlakren_get_tface(obr, vlr, i, &name, 0)); i++) {
|
||||
ShadeInputUV *suv= &shi->uv[i];
|
||||
float *uv1, *uv2, *uv3;
|
||||
|
||||
@ -977,7 +1021,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
suv->dyuv[1]= 2.0f*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]);
|
||||
}
|
||||
|
||||
if((mode & MA_FACETEXTURE) && i==0) {
|
||||
if((mode & MA_FACETEXTURE) && i==obr->actmtface) {
|
||||
if((mode & (MA_VERTEXCOL|MA_VERTEXCOLP))==0) {
|
||||
shi->vcol[0]= 1.0f;
|
||||
shi->vcol[1]= 1.0f;
|
||||
@ -1015,22 +1059,20 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
if(mode & MA_RADIO) {
|
||||
float *r1, *r2, *r3;
|
||||
|
||||
r1= RE_vertren_get_rad(&R, v1, 0);
|
||||
r2= RE_vertren_get_rad(&R, v2, 0);
|
||||
r3= RE_vertren_get_rad(&R, v3, 0);
|
||||
r1= RE_vertren_get_rad(obr, v1, 0);
|
||||
r2= RE_vertren_get_rad(obr, v2, 0);
|
||||
r3= RE_vertren_get_rad(obr, v3, 0);
|
||||
|
||||
if(r1 && r2 && r3) {
|
||||
shi->rad[0]= (l*r3[0] - u*r1[0] - v*r2[0]);
|
||||
shi->rad[1]= (l*r3[1] - u*r1[1] - v*r2[1]);
|
||||
shi->rad[2]= (l*r3[2] - u*r1[2] - v*r2[2]);
|
||||
}
|
||||
else {
|
||||
else
|
||||
shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0f;
|
||||
}
|
||||
|
||||
if(texco & TEXCO_REFL) {
|
||||
/* mirror reflection color textures (and envmap) */
|
||||
@ -1040,9 +1082,9 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
if(texco & TEXCO_STRESS) {
|
||||
float *s1, *s2, *s3;
|
||||
|
||||
s1= RE_vertren_get_stress(&R, v1, 0);
|
||||
s2= RE_vertren_get_stress(&R, v2, 0);
|
||||
s3= RE_vertren_get_stress(&R, v3, 0);
|
||||
s1= RE_vertren_get_stress(obr, v1, 0);
|
||||
s2= RE_vertren_get_stress(obr, v2, 0);
|
||||
s3= RE_vertren_get_stress(obr, v3, 0);
|
||||
if(s1 && s2 && s3) {
|
||||
shi->stress= l*s3[0] - u*s1[0] - v*s2[0];
|
||||
if(shi->stress<1.0f) shi->stress-= 1.0f;
|
||||
@ -1058,9 +1100,8 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0f;
|
||||
}
|
||||
|
||||
/* this only avalailable for scanline renders */
|
||||
if(shi->depth==0) {
|
||||
@ -1082,22 +1123,32 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
if(texco & TEXCO_STICKY) {
|
||||
float *s1, *s2, *s3;
|
||||
|
||||
s1= RE_vertren_get_sticky(&R, v1, 0);
|
||||
s2= RE_vertren_get_sticky(&R, v2, 0);
|
||||
s3= RE_vertren_get_sticky(&R, v3, 0);
|
||||
s1= RE_vertren_get_sticky(obr, v1, 0);
|
||||
s2= RE_vertren_get_sticky(obr, v2, 0);
|
||||
s3= RE_vertren_get_sticky(obr, v3, 0);
|
||||
|
||||
if(s1 && s2 && s3) {
|
||||
float winmat[4][4], ho1[4], ho2[4], ho3[4];
|
||||
float Zmulx, Zmuly;
|
||||
float hox, hoy, l, dl, u, v;
|
||||
float s00, s01, s10, s11, detsh;
|
||||
|
||||
/* old globals, localized now */
|
||||
Zmulx= ((float)R.winx)/2.0f; Zmuly= ((float)R.winy)/2.0f;
|
||||
|
||||
if(shi->obi->flag & R_TRANSFORMED)
|
||||
zbuf_make_winmat(&R, shi->obi->mat, winmat);
|
||||
else
|
||||
zbuf_make_winmat(&R, NULL, winmat);
|
||||
|
||||
zbuf_render_project(winmat, v1->co, ho1);
|
||||
zbuf_render_project(winmat, v2->co, ho2);
|
||||
zbuf_render_project(winmat, v3->co, ho3);
|
||||
|
||||
s00= v3->ho[0]/v3->ho[3] - v1->ho[0]/v1->ho[3];
|
||||
s01= v3->ho[1]/v3->ho[3] - v1->ho[1]/v1->ho[3];
|
||||
s10= v3->ho[0]/v3->ho[3] - v2->ho[0]/v2->ho[3];
|
||||
s11= v3->ho[1]/v3->ho[3] - v2->ho[1]/v2->ho[3];
|
||||
s00= ho3[0]/ho3[3] - ho1[0]/ho1[3];
|
||||
s01= ho3[1]/ho3[3] - ho1[1]/ho1[3];
|
||||
s10= ho3[0]/ho3[3] - ho2[0]/ho2[3];
|
||||
s11= ho3[1]/ho3[3] - ho2[1]/ho2[3];
|
||||
|
||||
detsh= s00*s11-s10*s01;
|
||||
s00/= detsh; s01/=detsh;
|
||||
@ -1106,8 +1157,8 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
/* recalc u and v again */
|
||||
hox= x/Zmulx -1.0f;
|
||||
hoy= y/Zmuly -1.0f;
|
||||
u= (hox - v3->ho[0]/v3->ho[3])*s11 - (hoy - v3->ho[1]/v3->ho[3])*s10;
|
||||
v= (hoy - v3->ho[1]/v3->ho[3])*s00 - (hox - v3->ho[0]/v3->ho[3])*s01;
|
||||
u= (hox - ho3[0]/ho3[3])*s11 - (hoy - ho3[1]/ho3[3])*s10;
|
||||
v= (hoy - ho3[1]/ho3[3])*s00 - (hox - ho3[0]/ho3[3])*s01;
|
||||
l= 1.0f+u+v;
|
||||
|
||||
shi->sticky[0]= l*s3[0]-u*s1[0]-v*s2[0];
|
||||
@ -1197,7 +1248,7 @@ static void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, in
|
||||
ssamp->tot= 0;
|
||||
|
||||
for(shi= ssamp->shi; ps; ps= ps->next) {
|
||||
shade_input_set_triangle(shi, ps->facenr, 1);
|
||||
shade_input_set_triangle(shi, ps->obi, ps->facenr, 1);
|
||||
|
||||
if(shi->vlr) { /* NULL happens for env material or for 'all z' */
|
||||
unsigned short curmask= ps->mask;
|
||||
|
@ -1262,7 +1262,7 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
|
||||
if(ma->mode & MA_SHADOW) {
|
||||
if(lar->type==LA_HEMI || lar->type==LA_AREA);
|
||||
else if((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) {
|
||||
float thresh= vlr->ob->smoothresh;
|
||||
float thresh= shi->obr->ob->smoothresh;
|
||||
if(inp>thresh)
|
||||
phongcorr= (inp-thresh)/(inp*(1.0f-thresh));
|
||||
else
|
||||
|
@ -59,7 +59,7 @@ void merge_transp_passes(RenderLayer *rl, ShadeResult *shr);
|
||||
void add_transp_passes(RenderLayer *rl, int offset, ShadeResult *shr, float alpha);
|
||||
void hoco_to_zco(ZSpan *zspan, float *zco, float *hoco);
|
||||
void zspan_scanconvert_strand(ZSpan *zspan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float, float) );
|
||||
void zbufsinglewire(ZSpan *zspan, int zvlnr, float *ho1, float *ho2);
|
||||
void zbufsinglewire(ZSpan *zspan, ObjectRen *obr, int zvlnr, float *ho1, float *ho2);
|
||||
int addtosamp_shr(ShadeResult *samp_shr, ShadeSample *ssamp, int addpassflag);
|
||||
void add_transp_speed(RenderLayer *rl, int offset, float *speed, float alpha, long *rdrect);
|
||||
void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl, float *rectf);
|
||||
@ -210,6 +210,7 @@ typedef struct RenderPrimitiveIterator {
|
||||
BucketPrims *bpr;
|
||||
int bprindex;
|
||||
|
||||
ObjectInstanceRen *obi;
|
||||
StrandRen *strand;
|
||||
int index, tot;
|
||||
} RenderPrimitiveIterator;
|
||||
@ -239,7 +240,9 @@ RenderPrimitiveIterator *init_primitive_iterator(Render *re, RenderBuckets *buck
|
||||
}
|
||||
else {
|
||||
iter->index= 0;
|
||||
iter->tot= re->totstrand;
|
||||
iter->obi= re->instancetable.first;
|
||||
if(iter->obi)
|
||||
iter->tot= iter->obi->obr->totstrand;
|
||||
}
|
||||
|
||||
return iter;
|
||||
@ -264,9 +267,22 @@ void *next_primitive_iterator(RenderPrimitiveIterator *iter)
|
||||
return iter->bpr->prim[iter->bprindex++];
|
||||
}
|
||||
else {
|
||||
if(!iter->obi)
|
||||
return NULL;
|
||||
|
||||
if(iter->index >= iter->tot) {
|
||||
while((iter->obi=iter->obi->next) && !iter->obi->obr->totstrand)
|
||||
iter->obi= iter->obi->next;
|
||||
|
||||
if(iter->obi)
|
||||
iter->tot= iter->obi->obr->totstrand;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(iter->index < iter->tot) {
|
||||
if((iter->index & 255)==0)
|
||||
iter->strand= iter->re->strandnodes[iter->index>>8].strand;
|
||||
iter->strand= iter->obi->obr->strandnodes[iter->index>>8].strand;
|
||||
else
|
||||
iter->strand++;
|
||||
|
||||
@ -318,8 +334,15 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint)
|
||||
VECCOPY(p[2], sseg->v[2]->co);
|
||||
VECCOPY(p[3], sseg->v[3]->co);
|
||||
|
||||
if(sseg->obi->flag & R_TRANSFORMED) {
|
||||
Mat4MulVecfl(sseg->obi->mat, p[0]);
|
||||
Mat4MulVecfl(sseg->obi->mat, p[1]);
|
||||
Mat4MulVecfl(sseg->obi->mat, p[2]);
|
||||
Mat4MulVecfl(sseg->obi->mat, p[3]);
|
||||
}
|
||||
|
||||
if(t == 0.0f) {
|
||||
VECCOPY(spoint->co, sseg->v[1]->co);
|
||||
VECCOPY(spoint->co, p[1]);
|
||||
spoint->strandco= sseg->v[1]->strandco;
|
||||
|
||||
spoint->dtstrandco= (sseg->v[2]->strandco - sseg->v[0]->strandco);
|
||||
@ -327,7 +350,7 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint)
|
||||
spoint->dtstrandco *= 0.5f;
|
||||
}
|
||||
else if(t == 1.0f) {
|
||||
VECCOPY(spoint->co, sseg->v[2]->co);
|
||||
VECCOPY(spoint->co, p[2]);
|
||||
spoint->strandco= sseg->v[2]->strandco;
|
||||
|
||||
spoint->dtstrandco= (sseg->v[3]->strandco - sseg->v[1]->strandco);
|
||||
@ -408,7 +431,7 @@ typedef struct StrandPart {
|
||||
|
||||
typedef struct StrandSortSegment {
|
||||
struct StrandSortSegment *next;
|
||||
int strand, segment;
|
||||
int obi, strand, segment;
|
||||
float z;
|
||||
} StrandSortSegment;
|
||||
|
||||
@ -474,22 +497,22 @@ static void interpolate_shade_result(ShadeResult *shr1, ShadeResult *shr2, float
|
||||
}
|
||||
}
|
||||
|
||||
static void add_strand_obindex(RenderLayer *rl, int offset, Object *ob)
|
||||
static void add_strand_obindex(RenderLayer *rl, int offset, ObjectRen *obr)
|
||||
{
|
||||
RenderPass *rpass;
|
||||
|
||||
for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
|
||||
if(rpass->passtype == SCE_PASS_INDEXOB) {
|
||||
float *fp= rpass->rect + offset;
|
||||
*fp= (float)ob->index;
|
||||
*fp= (float)obr->ob->index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void do_strand_point_project(Render *re, ZSpan *zspan, float *co, float *hoco, float *zco)
|
||||
static void do_strand_point_project(float winmat[][4], ZSpan *zspan, float *co, float *hoco, float *zco)
|
||||
{
|
||||
projectvert(co, re->winmat, hoco);
|
||||
projectvert(co, winmat, hoco);
|
||||
hoco_to_zco(zspan, zco, hoco);
|
||||
}
|
||||
|
||||
@ -606,16 +629,16 @@ static void do_strand_blend(void *handle, int x, int y, float u, float v, float
|
||||
#endif
|
||||
|
||||
if(spart->addpassflag & SCE_PASS_INDEXOB)
|
||||
add_strand_obindex(spart->rl, offset, buffer->ob);
|
||||
add_strand_obindex(spart->rl, offset, buffer->obr);
|
||||
}
|
||||
}
|
||||
|
||||
static int strand_test_clip(Render *re, ZSpan *zspan, float *bounds, float *co, float *zcomp)
|
||||
static int strand_test_clip(float winmat[][4], ZSpan *zspan, float *bounds, float *co, float *zcomp)
|
||||
{
|
||||
float hoco[4];
|
||||
int clipflag= 0;
|
||||
|
||||
projectvert(co, re->winmat, hoco);
|
||||
projectvert(co, winmat, hoco);
|
||||
|
||||
/* we compare z without perspective division for segment sorting */
|
||||
*zcomp= hoco[2];
|
||||
@ -625,6 +648,8 @@ static int strand_test_clip(Render *re, ZSpan *zspan, float *bounds, float *co,
|
||||
else if(hoco[1] > bounds[3]*hoco[3]) clipflag |= 4;
|
||||
else if(hoco[1]< bounds[2]*hoco[3]) clipflag |= 8;
|
||||
|
||||
clipflag |= testclip(hoco);
|
||||
|
||||
return clipflag;
|
||||
}
|
||||
|
||||
@ -635,12 +660,15 @@ void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, Str
|
||||
VlakRen vlr;
|
||||
|
||||
memset(&vlr, 0, sizeof(vlr));
|
||||
vlr.flag= R_SMOOTH|R_VISIBLE;
|
||||
vlr.flag= R_SMOOTH;
|
||||
vlr.lay= sseg->strand->buffer->lay;
|
||||
vlr.ob= sseg->strand->buffer->ob;
|
||||
vlr.obr= sseg->strand->buffer->obr;
|
||||
if(sseg->buffer->ma->mode & MA_TANGENT_STR)
|
||||
vlr.flag |= R_TANGENT;
|
||||
|
||||
shi->vlr= &vlr;
|
||||
shi->obi= sseg->obi;
|
||||
shi->obr= sseg->obi->obr;
|
||||
|
||||
/* cache for shadow */
|
||||
shi->samplenr++;
|
||||
@ -660,7 +688,7 @@ void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, Str
|
||||
/* include lamphalos for strand, since halo layer was added already */
|
||||
if(re->flag & R_LAMPHALO)
|
||||
if(shi->layflag & SCE_LAY_HALO)
|
||||
renderspothalo(shi, shr->combined, shr->combined[3]);
|
||||
renderspothalo(shi, shr->combined, shr->combined[3]);
|
||||
}
|
||||
|
||||
static void do_scanconvert_strand(Render *re, StrandPart *spart, ZSpan *zspan, float t, float dt, float *co1, float *co2, float *co3, float *co4, int sample)
|
||||
@ -703,7 +731,7 @@ static void do_scanconvert_strand(Render *re, StrandPart *spart, ZSpan *zspan, f
|
||||
zspan_scanconvert_strand(zspan, spart, jco1, jco3, jco4, do_strand_blend);
|
||||
}
|
||||
|
||||
static void strand_render(Render *re, StrandPart *spart, ZSpan *zspan, StrandPoint *p1, StrandPoint *p2)
|
||||
static void strand_render(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, StrandPoint *p1, StrandPoint *p2)
|
||||
{
|
||||
if(spart) {
|
||||
float t= p2->t;
|
||||
@ -720,16 +748,16 @@ static void strand_render(Render *re, StrandPart *spart, ZSpan *zspan, StrandPoi
|
||||
else {
|
||||
float hoco1[4], hoco2[3];
|
||||
|
||||
projectvert(p1->co, re->winmat, hoco1);
|
||||
projectvert(p2->co, re->winmat, hoco2);
|
||||
projectvert(p1->co, winmat, hoco1);
|
||||
projectvert(p2->co, winmat, hoco2);
|
||||
|
||||
/* render both strand and single pixel wire to counter aliasing */
|
||||
zbufclip4(zspan, 0, p1->hoco2, p1->hoco1, p2->hoco1, p2->hoco2, 0, 0, 0, 0);
|
||||
zbufsinglewire(zspan, 0, hoco1, hoco2);
|
||||
zbufclip4(zspan, 0, 0, p1->hoco2, p1->hoco1, p2->hoco1, p2->hoco2, 0, 0, 0, 0);
|
||||
zbufsinglewire(zspan, 0, 0, hoco1, hoco2);
|
||||
}
|
||||
}
|
||||
|
||||
static int strand_segment_recursive(Render *re, StrandPart *spart, ZSpan *zspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth)
|
||||
static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth)
|
||||
{
|
||||
StrandPoint p;
|
||||
StrandBuffer *buffer= sseg->buffer;
|
||||
@ -758,23 +786,23 @@ static int strand_segment_recursive(Render *re, StrandPart *spart, ZSpan *zspan,
|
||||
return 0;
|
||||
|
||||
if(spart) {
|
||||
do_strand_point_project(re, zspan, p.co1, p.hoco1, p.zco1);
|
||||
do_strand_point_project(re, zspan, p.co2, p.hoco2, p.zco2);
|
||||
do_strand_point_project(winmat, zspan, p.co1, p.hoco1, p.zco1);
|
||||
do_strand_point_project(winmat, zspan, p.co2, p.hoco2, p.zco2);
|
||||
}
|
||||
else {
|
||||
projectvert(p.co1, re->winmat, p.hoco1);
|
||||
projectvert(p.co2, re->winmat, p.hoco2);
|
||||
projectvert(p.co1, winmat, p.hoco1);
|
||||
projectvert(p.co2, winmat, p.hoco2);
|
||||
}
|
||||
|
||||
if(!strand_segment_recursive(re, spart, zspan, sseg, p1, &p, depth+1))
|
||||
strand_render(re, spart, zspan, p1, &p);
|
||||
if(!strand_segment_recursive(re, spart, zspan, sseg, &p, p2, depth+1))
|
||||
strand_render(re, spart, zspan, &p, p2);
|
||||
if(!strand_segment_recursive(re, winmat, spart, zspan, sseg, p1, &p, depth+1))
|
||||
strand_render(re, winmat, spart, zspan, p1, &p);
|
||||
if(!strand_segment_recursive(re, winmat, spart, zspan, sseg, &p, p2, depth+1))
|
||||
strand_render(re, winmat, spart, zspan, &p, p2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void render_strand_segment(Render *re, StrandPart *spart, ZSpan *zspan, StrandSegment *sseg)
|
||||
void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, StrandSegment *sseg)
|
||||
{
|
||||
StrandBuffer *buffer= sseg->buffer;
|
||||
StrandPoint *p1= &sseg->point1;
|
||||
@ -789,20 +817,20 @@ void render_strand_segment(Render *re, StrandPart *spart, ZSpan *zspan, StrandSe
|
||||
strand_project_point(buffer->winmat, buffer->winx, buffer->winy, p2);
|
||||
|
||||
if(spart) {
|
||||
do_strand_point_project(re, zspan, p1->co1, p1->hoco1, p1->zco1);
|
||||
do_strand_point_project(re, zspan, p1->co2, p1->hoco2, p1->zco2);
|
||||
do_strand_point_project(re, zspan, p2->co1, p2->hoco1, p2->zco1);
|
||||
do_strand_point_project(re, zspan, p2->co2, p2->hoco2, p2->zco2);
|
||||
do_strand_point_project(winmat, zspan, p1->co1, p1->hoco1, p1->zco1);
|
||||
do_strand_point_project(winmat, zspan, p1->co2, p1->hoco2, p1->zco2);
|
||||
do_strand_point_project(winmat, zspan, p2->co1, p2->hoco1, p2->zco1);
|
||||
do_strand_point_project(winmat, zspan, p2->co2, p2->hoco2, p2->zco2);
|
||||
}
|
||||
else {
|
||||
projectvert(p1->co1, re->winmat, p1->hoco1);
|
||||
projectvert(p1->co2, re->winmat, p1->hoco2);
|
||||
projectvert(p2->co1, re->winmat, p2->hoco1);
|
||||
projectvert(p2->co2, re->winmat, p2->hoco2);
|
||||
projectvert(p1->co1, winmat, p1->hoco1);
|
||||
projectvert(p1->co2, winmat, p1->hoco2);
|
||||
projectvert(p2->co1, winmat, p2->hoco1);
|
||||
projectvert(p2->co2, winmat, p2->hoco2);
|
||||
}
|
||||
|
||||
if(!strand_segment_recursive(re, spart, zspan, sseg, p1, p2, 0))
|
||||
strand_render(re, spart, zspan, p1, p2);
|
||||
if(!strand_segment_recursive(re, winmat, spart, zspan, sseg, p1, p2, 0))
|
||||
strand_render(re, winmat, spart, zspan, p1, p2);
|
||||
}
|
||||
|
||||
static void zbuffer_strands_filter(Render *re, RenderPart *pa, RenderLayer *rl, StrandPart *spart, float *pass)
|
||||
@ -878,7 +906,9 @@ static void zbuffer_strands_filter(Render *re, RenderPart *pa, RenderLayer *rl,
|
||||
/* render call to fill in strands */
|
||||
unsigned short *zbuffer_strands_shade(Render *re, RenderPart *pa, RenderLayer *rl, float *pass)
|
||||
{
|
||||
struct RenderPrimitiveIterator *iter;
|
||||
//struct RenderPrimitiveIterator *iter;
|
||||
ObjectRen *obr;
|
||||
ObjectInstanceRen *obi;
|
||||
ZSpan zspan;
|
||||
StrandRen *strand=0;
|
||||
StrandVert *svert;
|
||||
@ -886,12 +916,12 @@ unsigned short *zbuffer_strands_shade(Render *re, RenderPart *pa, RenderLayer *r
|
||||
StrandSegment sseg;
|
||||
StrandSortSegment *sortsegments = NULL, *sortseg, *firstseg;
|
||||
MemArena *memarena;
|
||||
float z[4], bounds[4];
|
||||
int a, b, resultsize, totsegment, clip[4];
|
||||
float z[4], bounds[4], winmat[4][4];
|
||||
int a, b, i, resultsize, totsegment, clip[4];
|
||||
|
||||
if(re->test_break())
|
||||
return NULL;
|
||||
if(re->strandbufs.first == NULL)
|
||||
if(re->totstrand == 0)
|
||||
return NULL;
|
||||
|
||||
/* setup StrandPart */
|
||||
@ -937,7 +967,7 @@ unsigned short *zbuffer_strands_shade(Render *re, RenderPart *pa, RenderLayer *r
|
||||
spart.ssamp2.tot= 1;
|
||||
spart.ssamp.tot= 1;
|
||||
|
||||
zbuf_alloc_span(&zspan, pa->rectx, pa->recty);
|
||||
zbuf_alloc_span(&zspan, pa->rectx, pa->recty, re->clipcrop);
|
||||
|
||||
/* needed for transform from hoco to zbuffer co */
|
||||
zspan.zmulx= ((float)re->winx)/2.0;
|
||||
@ -957,57 +987,75 @@ unsigned short *zbuffer_strands_shade(Render *re, RenderPart *pa, RenderLayer *r
|
||||
bounds[3]= (2*pa->disprect.ymax - re->winy+1)/(float)re->winy;
|
||||
|
||||
/* sort segments */
|
||||
iter= init_primitive_iterator(re, re->strandbuckets, pa);
|
||||
//iter= init_primitive_iterator(re, re->strandbuckets, pa);
|
||||
|
||||
memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
|
||||
firstseg= NULL;
|
||||
sortseg= sortsegments;
|
||||
totsegment= 0;
|
||||
|
||||
while((strand = next_primitive_iterator(iter))) {
|
||||
if(re->test_break())
|
||||
break;
|
||||
//while((strand = next_primitive_iterator(iter))) {
|
||||
for(obi=re->instancetable.first, i=0; obi; obi=obi->next, i++) {
|
||||
obr= obi->obr;
|
||||
|
||||
if(strand->clip)
|
||||
continue;
|
||||
if(obi->flag & R_TRANSFORMED)
|
||||
zbuf_make_winmat(re, obi->mat, winmat);
|
||||
else
|
||||
zbuf_make_winmat(re, NULL, winmat);
|
||||
|
||||
svert= strand->vert;
|
||||
for(a=0; a<obr->totstrand; a++) {
|
||||
if((a & 255)==0) strand= obr->strandnodes[a>>8].strand;
|
||||
else strand++;
|
||||
|
||||
/* keep clipping and z depth for 4 control points */
|
||||
clip[1]= strand_test_clip(re, &zspan, bounds, svert->co, &z[1]);
|
||||
clip[2]= strand_test_clip(re, &zspan, bounds, (svert+1)->co, &z[2]);
|
||||
clip[0]= clip[1]; z[0]= z[1];
|
||||
if(re->test_break())
|
||||
break;
|
||||
|
||||
for(b=0; b<strand->totvert-1; b++, svert++) {
|
||||
/* compute 4th point clipping and z depth */
|
||||
if(b < strand->totvert-2) {
|
||||
clip[3]= strand_test_clip(re, &zspan, bounds, (svert+2)->co, &z[3]);
|
||||
}
|
||||
else {
|
||||
clip[3]= clip[2]; z[3]= z[2];
|
||||
}
|
||||
#if 0
|
||||
if(strand->clip)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
/* check clipping and add to sortsegments buffer */
|
||||
if(!(clip[0] & clip[1] & clip[2] & clip[3])) {
|
||||
sortseg= BLI_memarena_alloc(memarena, sizeof(StrandSortSegment));
|
||||
sortseg->strand= strand->index;
|
||||
sortseg->segment= b;
|
||||
svert= strand->vert;
|
||||
|
||||
sortseg->z= 0.5f*(z[1] + z[2]);
|
||||
|
||||
sortseg->next= firstseg;
|
||||
firstseg= sortseg;
|
||||
totsegment++;
|
||||
}
|
||||
|
||||
/* shift clipping and z depth */
|
||||
/* keep clipping and z depth for 4 control points */
|
||||
clip[1]= strand_test_clip(winmat, &zspan, bounds, svert->co, &z[1]);
|
||||
clip[2]= strand_test_clip(winmat, &zspan, bounds, (svert+1)->co, &z[2]);
|
||||
clip[0]= clip[1]; z[0]= z[1];
|
||||
clip[1]= clip[2]; z[1]= z[2];
|
||||
clip[2]= clip[3]; z[2]= z[3];
|
||||
|
||||
for(b=0; b<strand->totvert-1; b++, svert++) {
|
||||
/* compute 4th point clipping and z depth */
|
||||
if(b < strand->totvert-2) {
|
||||
clip[3]= strand_test_clip(winmat, &zspan, bounds, (svert+2)->co, &z[3]);
|
||||
}
|
||||
else {
|
||||
clip[3]= clip[2]; z[3]= z[2];
|
||||
}
|
||||
|
||||
/* check clipping and add to sortsegments buffer */
|
||||
if(!(clip[0] & clip[1] & clip[2] & clip[3])) {
|
||||
sortseg= BLI_memarena_alloc(memarena, sizeof(StrandSortSegment));
|
||||
sortseg->obi= i;
|
||||
sortseg->strand= strand->index;
|
||||
sortseg->segment= b;
|
||||
|
||||
sortseg->z= 0.5f*(z[1] + z[2]);
|
||||
|
||||
sortseg->next= firstseg;
|
||||
firstseg= sortseg;
|
||||
totsegment++;
|
||||
}
|
||||
|
||||
/* shift clipping and z depth */
|
||||
clip[0]= clip[1]; z[0]= z[1];
|
||||
clip[1]= clip[2]; z[1]= z[2];
|
||||
clip[2]= clip[3]; z[2]= z[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
free_primitive_iterator(iter);
|
||||
#endif
|
||||
|
||||
if(!re->test_break()) {
|
||||
/* convert list to array and sort */
|
||||
@ -1028,7 +1076,12 @@ unsigned short *zbuffer_strands_shade(Render *re, RenderPart *pa, RenderLayer *r
|
||||
if(re->test_break())
|
||||
break;
|
||||
|
||||
sseg.strand= RE_findOrAddStrand(re, sortseg->strand);
|
||||
obi= &re->objectinstance[sortseg->obi];
|
||||
obr= obi->obr;
|
||||
zbuf_make_winmat(re, NULL, winmat);
|
||||
|
||||
sseg.obi= obi;
|
||||
sseg.strand= RE_findOrAddStrand(obr, sortseg->strand);
|
||||
sseg.buffer= sseg.strand->buffer;
|
||||
sseg.sqadaptcos= sseg.buffer->adaptcos;
|
||||
sseg.sqadaptcos *= sseg.sqadaptcos;
|
||||
@ -1042,7 +1095,7 @@ unsigned short *zbuffer_strands_shade(Render *re, RenderPart *pa, RenderLayer *r
|
||||
|
||||
spart.segment= &sseg;
|
||||
|
||||
render_strand_segment(re, &spart, &zspan, &sseg);
|
||||
render_strand_segment(re, winmat, &spart, &zspan, &sseg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1072,6 +1125,8 @@ unsigned short *zbuffer_strands_shade(Render *re, RenderPart *pa, RenderLayer *r
|
||||
|
||||
void project_strands(Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, int do_buckets)
|
||||
{
|
||||
#if 0
|
||||
ObjectRen *obr;
|
||||
StrandRen *strand = NULL;
|
||||
StrandVert *svert;
|
||||
float hoco[4], min[2], max[2], bucketco[2], vec[3];
|
||||
@ -1083,84 +1138,92 @@ void project_strands(Render *re, void (*projectfunc)(float *, float mat[][4], fl
|
||||
re->strandbuckets= NULL;
|
||||
}
|
||||
|
||||
if(re->totstrand == 0)
|
||||
return;
|
||||
|
||||
if(do_buckets)
|
||||
re->strandbuckets= init_buckets(re);
|
||||
|
||||
/* calculate view coordinates (and zbuffer value) */
|
||||
for(a=0; a<re->totstrand; a++) {
|
||||
if((a & 255)==0) strand= re->strandnodes[a>>8].strand;
|
||||
else strand++;
|
||||
for(obr=re->objecttable.first; obr; obr=obr->next) {
|
||||
for(a=0; a<obr->totstrand; a++) {
|
||||
if((a & 255)==0) strand= obr->strandnodes[a>>8].strand;
|
||||
else strand++;
|
||||
|
||||
strand->clip= ~0;
|
||||
strand->clip= ~0;
|
||||
|
||||
#if 0
|
||||
if(!(strand->buffer->flag & R_STRAND_BSPLINE)) {
|
||||
INIT_MINMAX(bmin, bmax);
|
||||
svert= strand->vert;
|
||||
for(b=0; b<strand->totvert; b++, svert++)
|
||||
DO_MINMAX(svert->co, bmin, bmax)
|
||||
if(!(strand->buffer->flag & R_STRAND_BSPLINE)) {
|
||||
INIT_MINMAX(bmin, bmax);
|
||||
svert= strand->vert;
|
||||
for(b=0; b<strand->totvert; b++, svert++)
|
||||
DO_MINMAX(svert->co, bmin, bmax)
|
||||
|
||||
bpad[0]= (bmax[0]-bmin[0])*0.2f;
|
||||
bpad[1]= (bmax[1]-bmin[1])*0.2f;
|
||||
bpad[2]= (bmax[2]-bmin[2])*0.2f;
|
||||
}
|
||||
else
|
||||
bpad[0]= bpad[1]= bpad[2]= 0.0f;
|
||||
|
||||
ma= strand->buffer->ma;
|
||||
width= MAX2(ma->strand_sta, ma->strand_end);
|
||||
if(strand->buffer->flag & R_STRAND_B_UNITS) {
|
||||
bpad[0] += 0.5f*width;
|
||||
bpad[1] += 0.5f*width;
|
||||
bpad[2] += 0.5f*width;
|
||||
}
|
||||
#endif
|
||||
|
||||
INIT_MINMAX2(min, max);
|
||||
svert= strand->vert;
|
||||
for(b=0; b<strand->totvert; b++, svert++) {
|
||||
//VECADD(vec, svert->co, bpad);
|
||||
|
||||
/* same as VertRen */
|
||||
if(do_pano) {
|
||||
vec[0]= re->panoco*svert->co[0] + re->panosi*svert->co[2];
|
||||
vec[1]= svert->co[1];
|
||||
vec[2]= -re->panosi*svert->co[0] + re->panoco*svert->co[2];
|
||||
bpad[0]= (bmax[0]-bmin[0])*0.2f;
|
||||
bpad[1]= (bmax[1]-bmin[1])*0.2f;
|
||||
bpad[2]= (bmax[2]-bmin[2])*0.2f;
|
||||
}
|
||||
else
|
||||
VECCOPY(vec, svert->co)
|
||||
bpad[0]= bpad[1]= bpad[2]= 0.0f;
|
||||
|
||||
/* Go from wcs to hcs ... */
|
||||
projectfunc(vec, re->winmat, hoco);
|
||||
/* ... and clip in that system. */
|
||||
strand->clip &= testclip(hoco);
|
||||
|
||||
if(do_buckets) {
|
||||
project_hoco_to_bucket(re->strandbuckets, hoco, bucketco);
|
||||
DO_MINMAX2(bucketco, min, max);
|
||||
}
|
||||
}
|
||||
|
||||
if(do_buckets) {
|
||||
#if 0
|
||||
if(strand->buffer->flag & R_STRAND_BSPLINE) {
|
||||
min[0] -= width;
|
||||
min[1] -= width;
|
||||
max[0] += width;
|
||||
max[1] += width;
|
||||
}
|
||||
else {
|
||||
/* catmull-rom stays within 1.2f bounds in object space,
|
||||
* is this still true after projection? */
|
||||
min[0] -= width + (max[0]-min[0])*0.2f;
|
||||
min[1] -= width + (max[1]-min[1])*0.2f;
|
||||
max[0] += width + (max[0]-min[0])*0.2f;
|
||||
max[1] += width + (max[1]-min[1])*0.2f;
|
||||
ma= strand->buffer->ma;
|
||||
width= MAX2(ma->strand_sta, ma->strand_end);
|
||||
if(strand->buffer->flag & R_STRAND_B_UNITS) {
|
||||
bpad[0] += 0.5f*width;
|
||||
bpad[1] += 0.5f*width;
|
||||
bpad[2] += 0.5f*width;
|
||||
}
|
||||
#endif
|
||||
|
||||
add_buckets_primitive(re->strandbuckets, min, max, strand);
|
||||
INIT_MINMAX2(min, max);
|
||||
svert= strand->vert;
|
||||
for(b=0; b<strand->totvert; b++, svert++) {
|
||||
//VECADD(vec, svert->co, bpad);
|
||||
|
||||
/* same as VertRen */
|
||||
if(do_pano) {
|
||||
vec[0]= re->panoco*svert->co[0] + re->panosi*svert->co[2];
|
||||
vec[1]= svert->co[1];
|
||||
vec[2]= -re->panosi*svert->co[0] + re->panoco*svert->co[2];
|
||||
}
|
||||
else
|
||||
VECCOPY(vec, svert->co)
|
||||
|
||||
/* Go from wcs to hcs ... */
|
||||
projectfunc(vec, re->winmat, hoco);
|
||||
/* ... and clip in that system. */
|
||||
strand->clip &= testclip(hoco);
|
||||
|
||||
#if 0
|
||||
if(do_buckets) {
|
||||
project_hoco_to_bucket(re->strandbuckets, hoco, bucketco);
|
||||
DO_MINMAX2(bucketco, min, max);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
if(do_buckets) {
|
||||
if(strand->buffer->flag & R_STRAND_BSPLINE) {
|
||||
min[0] -= width;
|
||||
min[1] -= width;
|
||||
max[0] += width;
|
||||
max[1] += width;
|
||||
}
|
||||
else {
|
||||
/* catmull-rom stays within 1.2f bounds in object space,
|
||||
* is this still true after projection? */
|
||||
min[0] -= width + (max[0]-min[0])*0.2f;
|
||||
min[1] -= width + (max[1]-min[1])*0.2f;
|
||||
max[0] += width + (max[0]-min[0])*0.2f;
|
||||
max[1] += width + (max[1]-min[1])*0.2f;
|
||||
}
|
||||
|
||||
add_buckets_primitive(re->strandbuckets, min, max, strand);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -755,16 +755,16 @@ static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex
|
||||
}
|
||||
|
||||
|
||||
static int cubemap_glob(VlakRen *vlr, float x, float y, float z, float *adr1, float *adr2)
|
||||
static int cubemap_glob(float *n, float x, float y, float z, float *adr1, float *adr2)
|
||||
{
|
||||
float x1, y1, z1, nor[3];
|
||||
int ret;
|
||||
|
||||
if(vlr==NULL) {
|
||||
if(n==NULL) {
|
||||
nor[0]= x; nor[1]= y; nor[2]= z; // use local render coord
|
||||
}
|
||||
else {
|
||||
VECCOPY(nor, vlr->n);
|
||||
VECCOPY(nor, n);
|
||||
}
|
||||
MTC_Mat4Mul3Vecfl(R.viewinv, nor);
|
||||
|
||||
@ -793,7 +793,7 @@ static int cubemap_glob(VlakRen *vlr, float x, float y, float z, float *adr1, fl
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* mtex argument only for projection switches */
|
||||
static int cubemap(MTex *mtex, VlakRen *vlr, float x, float y, float z, float *adr1, float *adr2)
|
||||
static int cubemap(MTex *mtex, VlakRen *vlr, float *n, float x, float y, float z, float *adr1, float *adr2)
|
||||
{
|
||||
int proj[4]={0, ME_PROJXY, ME_PROJXZ, ME_PROJYZ}, ret= 0;
|
||||
|
||||
@ -811,7 +811,7 @@ static int cubemap(MTex *mtex, VlakRen *vlr, float x, float y, float z, float *a
|
||||
else if( fabs(nor[0])<fabs(nor[1]) && fabs(nor[2])<fabs(nor[1]) ) vlr->puno |= ME_PROJXZ;
|
||||
else vlr->puno |= ME_PROJYZ;
|
||||
}
|
||||
else return cubemap_glob(vlr, x, y, z, adr1, adr2);
|
||||
else return cubemap_glob(n, x, y, z, adr1, adr2);
|
||||
}
|
||||
|
||||
if(mtex) {
|
||||
@ -843,7 +843,7 @@ static int cubemap(MTex *mtex, VlakRen *vlr, float x, float y, float z, float *a
|
||||
}
|
||||
}
|
||||
else {
|
||||
return cubemap_glob(vlr, x, y, z, adr1, adr2);
|
||||
return cubemap_glob(n, x, y, z, adr1, adr2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -851,14 +851,14 @@ static int cubemap(MTex *mtex, VlakRen *vlr, float x, float y, float z, float *a
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int cubemap_ob(Object *ob, VlakRen *vlr, float x, float y, float z, float *adr1, float *adr2)
|
||||
static int cubemap_ob(Object *ob, float *n, float x, float y, float z, float *adr1, float *adr2)
|
||||
{
|
||||
float x1, y1, z1, nor[3];
|
||||
int ret;
|
||||
|
||||
if(vlr==NULL) return 0;
|
||||
if(n==NULL) return 0;
|
||||
|
||||
VECCOPY(nor, vlr->n);
|
||||
VECCOPY(nor, n);
|
||||
if(ob) MTC_Mat4Mul3Vecfl(ob->imat, nor);
|
||||
|
||||
x1= fabs(nor[0]);
|
||||
@ -885,7 +885,7 @@ static int cubemap_ob(Object *ob, VlakRen *vlr, float x, float y, float z, float
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float *dyt)
|
||||
static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *n, float *dxt, float *dyt)
|
||||
{
|
||||
Tex *tex;
|
||||
Object *ob= NULL;
|
||||
@ -907,9 +907,9 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float
|
||||
else if(wrap==MTEX_TUBE) tubemap(t[0], t[1], t[2], &fx, &fy);
|
||||
else if(wrap==MTEX_SPHERE) spheremap(t[0], t[1], t[2], &fx, &fy);
|
||||
else {
|
||||
if(texco==TEXCO_OBJECT) cubemap_ob(ob, vlr, t[0], t[1], t[2], &fx, &fy);
|
||||
else if(texco==TEXCO_GLOB) cubemap_glob(vlr, t[0], t[1], t[2], &fx, &fy);
|
||||
else cubemap(mtex, vlr, t[0], t[1], t[2], &fx, &fy);
|
||||
if(texco==TEXCO_OBJECT) cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy);
|
||||
else if(texco==TEXCO_GLOB) cubemap_glob(n, t[0], t[1], t[2], &fx, &fy);
|
||||
else cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy);
|
||||
}
|
||||
|
||||
/* repeat */
|
||||
@ -998,9 +998,9 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float
|
||||
}
|
||||
else {
|
||||
|
||||
if(texco==TEXCO_OBJECT) proj = cubemap_ob(ob, vlr, t[0], t[1], t[2], &fx, &fy);
|
||||
else if (texco==TEXCO_GLOB) proj = cubemap_glob(vlr, t[0], t[1], t[2], &fx, &fy);
|
||||
else proj = cubemap(mtex, vlr, t[0], t[1], t[2], &fx, &fy);
|
||||
if(texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy);
|
||||
else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, t[0], t[1], t[2], &fx, &fy);
|
||||
else proj = cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy);
|
||||
|
||||
if(proj==1) {
|
||||
SWAP(float, dxt[1], dxt[2]);
|
||||
@ -1230,7 +1230,7 @@ int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, Te
|
||||
dyt_l[0]= dyt_l[1]= dyt_l[2]= 0.0f;
|
||||
}
|
||||
|
||||
do_2d_mapping(&mtex, texvec_l, NULL, dxt_l, dyt_l);
|
||||
do_2d_mapping(&mtex, texvec_l, NULL, NULL, dxt_l, dyt_l);
|
||||
|
||||
return multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres);
|
||||
}
|
||||
@ -1466,7 +1466,7 @@ void do_material_tex(ShadeInput *shi)
|
||||
co= shi->gl; dx= shi->dxco; dy= shi->dyco;
|
||||
}
|
||||
else if(mtex->texco==TEXCO_UV) {
|
||||
ShadeInputUV *suv= &shi->uv[0];
|
||||
ShadeInputUV *suv= &shi->uv[shi->actuv];
|
||||
int i;
|
||||
|
||||
if(mtex->uvname[0] != 0) {
|
||||
@ -1549,7 +1549,7 @@ void do_material_tex(ShadeInput *shi)
|
||||
else dxt[2]= dyt[2]= 0.0;
|
||||
}
|
||||
|
||||
do_2d_mapping(mtex, texvec, shi->vlr, dxt, dyt);
|
||||
do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt);
|
||||
|
||||
/* translate and scale */
|
||||
texvec[0]= mtex->size[0]*(texvec[0]-0.5) +mtex->ofs[0]+0.5;
|
||||
@ -1669,10 +1669,10 @@ void do_material_tex(ShadeInput *shi)
|
||||
if(mtex->texflag & MTEX_VIEWSPACE) {
|
||||
// rotate to global coords
|
||||
if(mtex->texco==TEXCO_ORCO || mtex->texco==TEXCO_UV) {
|
||||
if(shi->vlr && shi->vlr->ob) {
|
||||
if(shi->vlr && shi->obr->ob) {
|
||||
float len= Normalize(texres.nor);
|
||||
// can be optimized... (ton)
|
||||
Mat4Mul3Vecfl(shi->vlr->ob->obmat, texres.nor);
|
||||
Mat4Mul3Vecfl(shi->obr->ob->obmat, texres.nor);
|
||||
Mat4Mul3Vecfl(R.viewmat, texres.nor);
|
||||
Normalize(texres.nor);
|
||||
VecMulf(texres.nor, len);
|
||||
@ -1762,8 +1762,8 @@ void do_material_tex(ShadeInput *shi)
|
||||
Mat4Mul3Vecfl(R.viewmat, nor);
|
||||
}
|
||||
else if(mtex->normapspace == MTEX_NSPACE_OBJECT) {
|
||||
if(shi->vlr && shi->vlr->ob)
|
||||
Mat4Mul3Vecfl(shi->vlr->ob->obmat, nor);
|
||||
if(shi->vlr && shi->vlr->obr->ob)
|
||||
Mat4Mul3Vecfl(shi->vlr->obr->ob->obmat, nor);
|
||||
Mat4Mul3Vecfl(R.viewmat, nor);
|
||||
}
|
||||
|
||||
@ -1985,7 +1985,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf)
|
||||
|
||||
}
|
||||
|
||||
if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
|
||||
if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
|
||||
|
||||
rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres);
|
||||
|
||||
@ -2156,7 +2156,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f
|
||||
else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
|
||||
|
||||
/* texture */
|
||||
if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
|
||||
if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
|
||||
|
||||
rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres);
|
||||
|
||||
@ -2336,7 +2336,7 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf)
|
||||
|
||||
/* texture */
|
||||
if(tex->type==TEX_IMAGE) {
|
||||
do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
|
||||
do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
|
||||
}
|
||||
|
||||
rgb= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres);
|
||||
@ -2421,7 +2421,7 @@ int externtex(MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *t
|
||||
|
||||
/* texture */
|
||||
if(tex->type==TEX_IMAGE) {
|
||||
do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
|
||||
do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
|
||||
}
|
||||
|
||||
rgb= multitex(tex, texvec, dxt, dyt, 0, &texr);
|
||||
@ -2454,6 +2454,7 @@ void render_realtime_texture(ShadeInput *shi, Image *ima)
|
||||
static int firsttime= 1;
|
||||
Tex *tex;
|
||||
float texvec[3], dx[2], dy[2];
|
||||
ShadeInputUV *suv= &shi->uv[shi->actuv];
|
||||
|
||||
if(firsttime) {
|
||||
firsttime= 0;
|
||||
@ -2465,14 +2466,14 @@ void render_realtime_texture(ShadeInput *shi, Image *ima)
|
||||
|
||||
if(shi->ys & 1) tex= &tex1; else tex= &tex2; // threadsafe
|
||||
|
||||
texvec[0]= 0.5+0.5*shi->uv[0].uv[0];
|
||||
texvec[1]= 0.5+0.5*shi->uv[0].uv[1];
|
||||
texvec[0]= 0.5+0.5*suv->uv[0];
|
||||
texvec[1]= 0.5+0.5*suv->uv[1];
|
||||
texvec[2] = 0; // initalize it because imagewrap looks at it.
|
||||
if(shi->osatex) {
|
||||
dx[0]= 0.5*shi->uv[0].dxuv[0];
|
||||
dx[1]= 0.5*shi->uv[0].dxuv[1];
|
||||
dy[0]= 0.5*shi->uv[0].dyuv[0];
|
||||
dy[1]= 0.5*shi->uv[0].dyuv[1];
|
||||
dx[0]= 0.5*suv->dxuv[0];
|
||||
dx[1]= 0.5*suv->dxuv[1];
|
||||
dy[0]= 0.5*suv->dyuv[0];
|
||||
dy[1]= 0.5*suv->dyuv[1];
|
||||
}
|
||||
|
||||
texr.nor= NULL;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1641,19 +1641,6 @@ void modifiers_explodeFacepa(void *arg1, void *arg2)
|
||||
emd->flag |= eExplodeFlag_CalcFaces;
|
||||
}
|
||||
|
||||
static void modifiers_psysEnable(void *ob_v, void *md_v)
|
||||
{
|
||||
ParticleSystemModifierData *psmd = (ParticleSystemModifierData*) md_v;
|
||||
|
||||
if(psmd->modifier.mode & eModifierMode_Realtime) {
|
||||
psmd->psys->flag |= PSYS_ENABLED;
|
||||
}
|
||||
else {
|
||||
psmd->psys->flag &= ~PSYS_ENABLED;
|
||||
PE_free_particle_edit(psmd->psys);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco, int *yco, int index, int cageIndex, int lastCageIndex)
|
||||
{
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
@ -1693,8 +1680,6 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
|
||||
if ((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) {
|
||||
uiDefIconButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, ICON_SCENE, x+10+buttonWidth-60, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
|
||||
but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, VICON_VIEW3D, x+10+buttonWidth-40, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
|
||||
if (md->type==eModifierType_ParticleSystem)
|
||||
uiButSetFunc(but, modifiers_psysEnable, ob, md);
|
||||
if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
|
||||
uiDefIconButBitI(block, TOG, eModifierMode_Editmode, B_MODIFIER_RECALC, VICON_EDIT, x+10+buttonWidth-20, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
|
||||
}
|
||||
@ -4956,7 +4941,7 @@ static void editing_panel_links(Object *ob)
|
||||
xco, 154, 130,20, 0, 0, 0, 0, 0, "");
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButC(block, MENU, REDRAWVIEW3D, "Empty Drawtype%t|Arrows%x1|Single Arrow%x4|Plain Axes%x2|Circle%x3|Cube%x5",
|
||||
uiDefButC(block, MENU, REDRAWVIEW3D, "Empty Drawtype%t|Arrows%x1|Single Arrow%x4|Plain Axes%x2|Circle%x3|Cube%x5|Sphere%x6|Cone%x7",
|
||||
xco, 128, 140, 20, &ob->empty_drawtype, 0, 0, 0, 0, "The Empty 3D View display style");
|
||||
uiDefButF(block, NUM, REDRAWVIEW3D, "Size:",
|
||||
xco, 108, 140, 21, &ob->empty_drawsize, 0.01, 10.0, 1, 0, "The size to display the Empty");
|
||||
@ -5220,9 +5205,16 @@ void sculptmode_draw_interface_textures(uiBlock *block, unsigned short cx, unsig
|
||||
if(sd->texrept != SCULPTREPT_3D) {
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block,NUM,0, "Angle", cx,cy,115,19, &mtex->warpfac, 0,360,100,0, "Rotate texture counterclockwise");
|
||||
/*Moved inside, so that following buttons aren't made bigger for no reason*/
|
||||
cy-= 20;
|
||||
}
|
||||
cy-= 20;
|
||||
|
||||
|
||||
/* Added Rake button. Needs to be turned off if 3D is on / disappear*/
|
||||
if(sd->texrept != SCULPTREPT_3D){
|
||||
uiDefButC(block,TOG,B_NOP, "Rake", cx,cy,115,19, &sd->rake, 0,0,0,0,"Rotate the brush in the direction of motion");
|
||||
cy-=20;
|
||||
}
|
||||
|
||||
if(sd->texrept != SCULPTREPT_DRAG) {
|
||||
uiBlockBeginAlign(block);
|
||||
but= uiDefIconButC(block, TOG, REDRAWBUTSEDIT, sd->texsep ? ICON_UNLOCKED : ICON_LOCKED, cx,cy,20,19, &sd->texsep,0,0,0,0, "Locks the texture sizes together");
|
||||
|
@ -940,29 +940,29 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
|
||||
else {
|
||||
strcpy (data->subtarget, "");
|
||||
}
|
||||
|
||||
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
|
||||
/* Settings */
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, CONSTRAINT_IK_TIP, B_CONSTRAINT_TEST, "Use Tail", *xco, *yco-92, 137, 19, &data->flag, 0, 0, 0, 0, "Include Bone's tail als last element in Chain");
|
||||
uiDefButI(block, NUM, B_CONSTRAINT_TEST, "ChainLen:", *xco, *yco-112,137,19, &data->rootbone, 0, 255, 0, 0, "If not zero, the amount of bones in this chain");
|
||||
|
||||
uiDefButS(block, NUM, B_CONSTRAINT_TEST, "ChainLen:", *xco, *yco-112,137,19, &data->rootbone, 0, 255, 0, 0, "If not zero, the amount of bones in this chain");
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "PosW ", *xco+147, *yco-92, 137, 19, &data->weight, 0.01, 1.0, 2, 2, "For Tree-IK: weight of position control for this target");
|
||||
uiDefButBitS(block, TOG, CONSTRAINT_IK_ROT, B_CONSTRAINT_TEST, "Rot", *xco+147, *yco-112, 40,19, &data->flag, 0, 0, 0, 0, "Chain follows rotation of target");
|
||||
uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "W ", *xco+187, *yco-112, 97, 19, &data->orientweight, 0.01, 1.0, 2, 2, "For Tree-IK: Weight of orientation control for this target");
|
||||
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
|
||||
|
||||
uiDefButBitS(block, TOG, CONSTRAINT_IK_STRETCH, B_CONSTRAINT_TEST, "Stretch", *xco, *yco-137,137,19, &data->flag, 0, 0, 0, 0, "Enable IK stretching");
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco+147, *yco-137, 137, 19, &data->iterations, 1, 10000, 0, 0, "Maximum number of solving iterations");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
|
||||
/* Pole Vector */
|
||||
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Pole Target:", *xco+147, *yco-24, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
|
||||
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+147, *yco-44, 137, 19, &data->poletar, "Pole Target Object");
|
||||
if (is_armature_target(data->poletar)) {
|
||||
@ -2858,15 +2858,6 @@ void do_effects_panels(unsigned short event)
|
||||
break;
|
||||
case B_PART_ENABLE:
|
||||
if(psys) {
|
||||
ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
|
||||
if(psys->flag & PSYS_ENABLED) {
|
||||
psmd->modifier.mode |= eModifierMode_Realtime;
|
||||
}
|
||||
else {
|
||||
psmd->modifier.mode &= ~eModifierMode_Realtime;
|
||||
PE_free_particle_edit(psys);
|
||||
}
|
||||
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWBUTSOBJECT, 0);
|
||||
@ -3488,7 +3479,7 @@ static void sb_clear_cache(void *ob_v, void *actsoft_v)
|
||||
static void object_softbodies(Object *ob)
|
||||
{
|
||||
SoftBody *sb=ob->soft;
|
||||
ParticleSystem *psys;
|
||||
ParticleSystem *psys=NULL;
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
static int val;
|
||||
@ -3521,7 +3512,7 @@ static void object_softbodies(Object *ob)
|
||||
MEM_freeN(menustr);
|
||||
}
|
||||
|
||||
if(psys_cur){
|
||||
if(psys_cur && psys){
|
||||
if(*softflag & OB_SB_ENABLE)
|
||||
val=1;
|
||||
else
|
||||
|
@ -143,6 +143,8 @@ static void draw_bounding_volume(Object *ob);
|
||||
|
||||
static void drawcube_size(float size);
|
||||
static void drawcircle_size(float size);
|
||||
static void draw_empty_sphere(float size);
|
||||
static void draw_empty_cone(float size);
|
||||
|
||||
/* ************* Setting OpenGL Material ************ */
|
||||
|
||||
@ -412,6 +414,14 @@ void drawaxes(float size, int flag, char drawtype)
|
||||
drawcircle_size(size);
|
||||
break;
|
||||
|
||||
case OB_EMPTY_SPHERE:
|
||||
draw_empty_sphere(size);
|
||||
break;
|
||||
|
||||
case OB_EMPTY_CONE:
|
||||
draw_empty_cone(size);
|
||||
break;
|
||||
|
||||
case OB_ARROWS:
|
||||
default:
|
||||
for (axis=0; axis<3; axis++) {
|
||||
@ -2995,7 +3005,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys)
|
||||
part=psys->part;
|
||||
pars=psys->particles;
|
||||
|
||||
if(part==0 || (psys->flag & PSYS_ENABLED)==0)
|
||||
if(part==0 || !psys_check_enabled(ob, psys))
|
||||
return;
|
||||
|
||||
if(pars==0) return;
|
||||
@ -3984,6 +3994,45 @@ static void drawnurb(Base *base, Nurb *nurb, int dt)
|
||||
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
/* draw a sphere for use as an empty drawtype */
|
||||
static void draw_empty_sphere (float size)
|
||||
{
|
||||
float cent=0;
|
||||
GLUquadricObj *qobj = gluNewQuadric();
|
||||
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(cent, cent, cent);
|
||||
glScalef(size, size, size);
|
||||
gluSphere(qobj, 1.0, 8, 5);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
gluDeleteQuadric(qobj);
|
||||
}
|
||||
|
||||
/* draw a cone for use as an empty drawtype */
|
||||
static void draw_empty_cone (float size)
|
||||
{
|
||||
float cent=0;
|
||||
float radius;
|
||||
GLUquadricObj *qobj = gluNewQuadric();
|
||||
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
|
||||
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
radius = size;
|
||||
glTranslatef(cent,cent, cent);
|
||||
glScalef(radius, 2.0*size, radius);
|
||||
glRotatef(-90., 1.0, 0.0, 0.0);
|
||||
gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
gluDeleteQuadric(qobj);
|
||||
}
|
||||
|
||||
/* draw points on curve speed handles */
|
||||
static void curve_draw_speed(Object *ob)
|
||||
{
|
||||
@ -5504,4 +5553,3 @@ void draw_object_instance(Object *ob, int dt, int outline)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -725,54 +725,97 @@ static void draw_cursor(SpaceText *st) {
|
||||
|
||||
static void calc_text_rcts(SpaceText *st)
|
||||
{
|
||||
short barheight, barstart, blank_lines;
|
||||
int lbarstart, lbarh, ltexth;
|
||||
int pix_available, pix_top_margin, pix_bottom_margin;
|
||||
int lhlstart, lhlend, ltexth;
|
||||
short barheight, barstart, hlstart, hlend, blank_lines;
|
||||
short pix_available, pix_top_margin, pix_bottom_margin, pix_bardiff;
|
||||
|
||||
lbarstart= st->top;
|
||||
lbarh= st->viewlines;
|
||||
pix_top_margin = 8;
|
||||
pix_bottom_margin = 4;
|
||||
pix_available = curarea->winy - pix_top_margin - pix_bottom_margin;
|
||||
ltexth= txt_get_span(st->text->lines.first, st->text->lines.last);
|
||||
blank_lines = st->viewlines / 2;
|
||||
|
||||
if(ltexth + blank_lines < lbarstart + st->viewlines)
|
||||
blank_lines = lbarstart + st->viewlines - ltexth;
|
||||
/* when resizing a vieport with the bar at the bottom to a greater height more blank lines will be added */
|
||||
if (ltexth + blank_lines < st->top + st->viewlines) {
|
||||
blank_lines = st->top + st->viewlines - ltexth;
|
||||
}
|
||||
|
||||
ltexth += blank_lines;
|
||||
|
||||
barstart = (lbarstart*pix_available)/ltexth;
|
||||
barheight = (lbarh*pix_available)/ltexth;
|
||||
if (barheight<20){
|
||||
barstart = ((pix_available + barheight - 20 )*lbarstart)/ltexth;
|
||||
barheight=20;
|
||||
barheight = (st->viewlines*pix_available) / ltexth;
|
||||
pix_bardiff = 0;
|
||||
if (barheight < 20) {
|
||||
pix_bardiff = 20 - barheight; /* take into account the now non-linear sizing of the bar */
|
||||
barheight = 20;
|
||||
}
|
||||
barstart = ((pix_available - pix_bardiff) * st->top) / ltexth;
|
||||
|
||||
st->txtbar.xmin= 5;
|
||||
st->txtbar.xmax= 17;
|
||||
st->txtbar.ymax= curarea->winy - pix_top_margin - barstart;
|
||||
st->txtbar.ymin= st->txtbar.ymax - barheight;
|
||||
st->txtbar.xmin = 5;
|
||||
st->txtbar.xmax = 17;
|
||||
st->txtbar.ymax = curarea->winy - pix_top_margin - barstart;
|
||||
st->txtbar.ymin = st->txtbar.ymax - barheight;
|
||||
|
||||
CLAMP(st->txtbar.ymin, pix_bottom_margin, curarea->winy - pix_top_margin);
|
||||
CLAMP(st->txtbar.ymax, pix_bottom_margin, curarea->winy - pix_top_margin);
|
||||
|
||||
st->pix_per_line= (float) ltexth/curarea->winy;
|
||||
st->pix_per_line= (float) ltexth/pix_available;
|
||||
if (st->pix_per_line<.1) st->pix_per_line=.1f;
|
||||
|
||||
lbarstart= MIN2(txt_get_span(st->text->lines.first, st->text->curl),
|
||||
lhlstart = MIN2(txt_get_span(st->text->lines.first, st->text->curl),
|
||||
txt_get_span(st->text->lines.first, st->text->sell));
|
||||
lbarh= abs(txt_get_span(st->text->lines.first, st->text->curl)-txt_get_span(st->text->lines.first, st->text->sell));
|
||||
|
||||
barheight= (lbarh*pix_available)/ltexth;
|
||||
if (barheight<2) barheight=2;
|
||||
|
||||
barstart= (lbarstart*pix_available)/ltexth;
|
||||
lhlend = MAX2(txt_get_span(st->text->lines.first, st->text->curl),
|
||||
txt_get_span(st->text->lines.first, st->text->sell));
|
||||
|
||||
hlstart = (lhlstart * pix_available) / ltexth;
|
||||
hlend = (lhlend * pix_available) / ltexth;
|
||||
|
||||
/* the scrollbar is non-linear sized */
|
||||
if (pix_bardiff > 0) {
|
||||
/* the start of the highlight is in the current viewport */
|
||||
if (lhlstart >= st->top && lhlstart <= st->top + st->viewlines) {
|
||||
/* speed the progresion of the start of the highlight through the scrollbar */
|
||||
hlstart = ( ( (pix_available - pix_bardiff) * lhlstart) / ltexth) + (pix_bardiff * (lhlstart - st->top) / st->viewlines);
|
||||
}
|
||||
else if (lhlstart > st->top + st->viewlines && hlstart < barstart + barheight && hlstart > barstart) {
|
||||
/* push hl start down */
|
||||
hlstart = barstart + barheight;
|
||||
}
|
||||
else if (lhlend > st->top && lhlstart < st->top && hlstart > barstart) {
|
||||
/*fill out start */
|
||||
hlstart = barstart;
|
||||
}
|
||||
|
||||
if (hlend <= hlstart) {
|
||||
hlend = hlstart + 2;
|
||||
}
|
||||
|
||||
/* the end of the highlight is in the current viewport */
|
||||
if (lhlend >= st->top && lhlend <= st->top + st->viewlines) {
|
||||
/* speed the progresion of the end of the highlight through the scrollbar */
|
||||
hlend = (((pix_available - pix_bardiff )*lhlend)/ltexth) + (pix_bardiff * (lhlend - st->top)/st->viewlines);
|
||||
}
|
||||
else if (lhlend < st->top && hlend >= barstart - 2 && hlend < barstart + barheight) {
|
||||
/* push hl end up */
|
||||
hlend = barstart;
|
||||
}
|
||||
else if (lhlend > st->top + st->viewlines && lhlstart < st->top + st->viewlines && hlend < barstart + barheight) {
|
||||
/* fill out end */
|
||||
hlend = barstart + barheight;
|
||||
}
|
||||
|
||||
if (hlend <= hlstart) {
|
||||
hlstart = hlend - 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (hlend - hlstart < 2) {
|
||||
hlend = hlstart + 2;
|
||||
}
|
||||
|
||||
st->txtscroll.xmin= 5;
|
||||
st->txtscroll.xmax= 17;
|
||||
st->txtscroll.ymax= curarea->winy-barstart;
|
||||
st->txtscroll.ymin= st->txtscroll.ymax - barheight;
|
||||
st->txtscroll.ymax= curarea->winy - pix_top_margin - hlstart;
|
||||
st->txtscroll.ymin= curarea->winy - pix_top_margin - hlend;
|
||||
|
||||
CLAMP(st->txtscroll.ymin, pix_bottom_margin, curarea->winy - pix_top_margin);
|
||||
CLAMP(st->txtscroll.ymax, pix_bottom_margin, curarea->winy - pix_top_margin);
|
||||
|
@ -261,7 +261,7 @@ void editbones_to_armature (ListBase *list, Object *ob)
|
||||
if (fBone->parent==eBone)
|
||||
fBone->parent= eBone->parent;
|
||||
}
|
||||
printf("Warning; removed zero sized bone: %s\n", eBone->name);
|
||||
printf("Warning: removed zero sized bone: %s\n", eBone->name);
|
||||
BLI_freelinkN (list, eBone);
|
||||
}
|
||||
}
|
||||
@ -1488,7 +1488,7 @@ static EditBone *add_editbone(char *name)
|
||||
|
||||
EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone");
|
||||
|
||||
BLI_strncpy (bone->name, name, 32);
|
||||
BLI_strncpy(bone->name, name, 32);
|
||||
unique_editbone_name(&G.edbo, bone->name);
|
||||
|
||||
BLI_addtail(&G.edbo, bone);
|
||||
@ -1663,6 +1663,19 @@ void addvert_armature(void)
|
||||
while(get_mbut()&R_MOUSE);
|
||||
}
|
||||
|
||||
/* adds an EditBone between the nominated locations (should be in the right space) */
|
||||
static EditBone *add_points_bone (float head[], float tail[])
|
||||
{
|
||||
EditBone *ebo;
|
||||
|
||||
ebo= add_editbone("Bone");
|
||||
|
||||
VECCOPY(ebo->head, head);
|
||||
VECCOPY(ebo->tail, tail);
|
||||
|
||||
return ebo;
|
||||
}
|
||||
|
||||
|
||||
static EditBone *get_named_editbone(char *name)
|
||||
{
|
||||
@ -1858,6 +1871,375 @@ void adduplicate_armature(void)
|
||||
|
||||
|
||||
/* *************** END Adding stuff in editmode *************** */
|
||||
/* ************** Add/Remove stuff in editmode **************** */
|
||||
|
||||
/* temporary data-structure for merge/fill bones */
|
||||
typedef struct EditBonePoint {
|
||||
struct EditBonePoint *next, *prev;
|
||||
|
||||
EditBone *head_owner; /* EditBone which uses this point as a 'head' point */
|
||||
EditBone *tail_owner; /* EditBone which uses this point as a 'tail' point */
|
||||
|
||||
float vec[3]; /* the actual location of the point in local/EditMode space */
|
||||
} EditBonePoint;
|
||||
|
||||
/* find chain-tips (i.e. bones without children) */
|
||||
static void chains_find_tips (ListBase *list)
|
||||
{
|
||||
EditBone *curBone, *ebo;
|
||||
LinkData *ld;
|
||||
|
||||
/* note: this is potentially very slow ... there's got to be a better way */
|
||||
for (curBone= G.edbo.first; curBone; curBone= curBone->next) {
|
||||
short stop= 0;
|
||||
|
||||
/* is this bone contained within any existing chain? (skip if so) */
|
||||
for (ld= list->first; ld; ld= ld->next) {
|
||||
for (ebo= ld->data; ebo; ebo= ebo->parent) {
|
||||
if (ebo == curBone) {
|
||||
stop= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stop) break;
|
||||
}
|
||||
/* skip current bone if it is part of an existing chain */
|
||||
if (stop) continue;
|
||||
|
||||
/* is any existing chain part of the chain formed by this bone? */
|
||||
stop= 0;
|
||||
for (ebo= curBone->parent; ebo; ebo= ebo->parent) {
|
||||
for (ld= list->first; ld; ld= ld->next) {
|
||||
if (ld->data == ebo) {
|
||||
ld->data= curBone;
|
||||
stop= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stop) break;
|
||||
}
|
||||
/* current bone has already been added to a chain? */
|
||||
if (stop) continue;
|
||||
|
||||
/* add current bone to a new chain */
|
||||
ld= MEM_callocN(sizeof(LinkData), "BoneChain");
|
||||
ld->data= curBone;
|
||||
BLI_addtail(list, ld);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void fill_add_joint (EditBone *ebo, short eb_tail, ListBase *points)
|
||||
{
|
||||
EditBonePoint *ebp;
|
||||
float vec[3];
|
||||
short found= 0;
|
||||
|
||||
if (eb_tail) {
|
||||
VECCOPY(vec, ebo->tail);
|
||||
}
|
||||
else {
|
||||
VECCOPY(vec, ebo->head);
|
||||
}
|
||||
|
||||
// FIXME: this algorithm sucks... it misses things it shouldn't
|
||||
for (ebp= points->first; ebp; ebp= ebp->next) {
|
||||
if (VecEqual(ebp->vec, vec)) {
|
||||
if (eb_tail) {
|
||||
if ((ebp->head_owner) && (ebp->head_owner->parent == ebo)) {
|
||||
/* so this bone's tail owner is this bone*/
|
||||
ebp->tail_owner= ebo;
|
||||
found= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((ebp->tail_owner) && (ebo->parent == ebp->tail_owner)) {
|
||||
/* so this bone's head owner is this bone */
|
||||
ebp->head_owner= ebo;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate a new point if no existing point was related */
|
||||
if (found == 0) {
|
||||
ebp= MEM_callocN(sizeof(EditBonePoint), "EditBonePoint");
|
||||
|
||||
if (eb_tail) {
|
||||
VECCOPY(ebp->vec, ebo->tail);
|
||||
ebp->tail_owner= ebo;
|
||||
}
|
||||
else {
|
||||
VECCOPY(ebp->vec, ebo->head);
|
||||
ebp->head_owner= ebo;
|
||||
}
|
||||
|
||||
BLI_addtail(points, ebp);
|
||||
}
|
||||
}
|
||||
|
||||
/* bone adding between selected joints */
|
||||
void fill_bones_armature(void)
|
||||
{
|
||||
bArmature *arm= G.obedit->data;
|
||||
EditBone *ebo, *newbone=NULL;
|
||||
ListBase points = {NULL, NULL};
|
||||
int count;
|
||||
|
||||
/* loop over all bones, and only consider if visible */
|
||||
for (ebo= G.edbo.first; ebo; ebo= ebo->next) {
|
||||
if ((arm->layer & ebo->layer) && !(ebo->flag & BONE_HIDDEN_A)) {
|
||||
if (!(ebo->flag & BONE_CONNECTED) && (ebo->flag & BONE_ROOTSEL))
|
||||
fill_add_joint(ebo, 0, &points);
|
||||
if (ebo->flag & BONE_TIPSEL)
|
||||
fill_add_joint(ebo, 1, &points);
|
||||
}
|
||||
}
|
||||
|
||||
/* the number of joints determines how we fill:
|
||||
* 1) between joint and cursor (joint=head, cursor=tail)
|
||||
* 2) between the two joints (order is dependent on active-bone/hierachy)
|
||||
* 3+) error (a smarter method involving finding chains needs to be worked out
|
||||
*/
|
||||
count= BLI_countlist(&points);
|
||||
|
||||
if (count == 0) {
|
||||
error("No joints selected");
|
||||
return;
|
||||
}
|
||||
else if (count == 1) {
|
||||
EditBonePoint *ebp;
|
||||
float curs[3];
|
||||
|
||||
/* Get Points - selected joint */
|
||||
ebp= (EditBonePoint *)points.first;
|
||||
|
||||
/* Get points - cursor (tail) */
|
||||
VECCOPY (curs, give_cursor());
|
||||
|
||||
Mat4Invert(G.obedit->imat, G.obedit->obmat);
|
||||
Mat4MulVecfl(G.obedit->imat, curs);
|
||||
|
||||
/* Create a bone */
|
||||
newbone= add_points_bone(ebp->vec, curs);
|
||||
}
|
||||
else if (count == 2) {
|
||||
EditBonePoint *ebp, *ebp2;
|
||||
float head[3], tail[3];
|
||||
|
||||
/* check that the points don't belong to the same bone */
|
||||
ebp= (EditBonePoint *)points.first;
|
||||
ebp2= ebp->next;
|
||||
|
||||
if ((ebp->head_owner==ebp2->tail_owner) && (ebp->head_owner!=NULL)) {
|
||||
error("Same bone selected...");
|
||||
BLI_freelistN(&points);
|
||||
return;
|
||||
}
|
||||
if ((ebp->tail_owner==ebp2->head_owner) && (ebp->tail_owner!=NULL)) {
|
||||
error("Same bone selected...");
|
||||
BLI_freelistN(&points);
|
||||
return;
|
||||
}
|
||||
|
||||
/* find which one should be the 'head' */
|
||||
if ((ebp->head_owner && ebp2->head_owner) || (ebp->tail_owner && ebp2->tail_owner)) {
|
||||
/* rule: whichever one is closer to 3d-cursor */
|
||||
float curs[3];
|
||||
float vecA[3], vecB[3];
|
||||
float distA, distB;
|
||||
|
||||
/* get cursor location */
|
||||
VECCOPY (curs, give_cursor());
|
||||
|
||||
Mat4Invert(G.obedit->imat, G.obedit->obmat);
|
||||
Mat4MulVecfl(G.obedit->imat, curs);
|
||||
|
||||
/* get distances */
|
||||
VecSubf(vecA, ebp->vec, curs);
|
||||
VecSubf(vecB, ebp2->vec, curs);
|
||||
distA= VecLength(vecA);
|
||||
distB= VecLength(vecB);
|
||||
|
||||
/* compare distances - closer one therefore acts as direction for bone to go */
|
||||
if (distA < distB) {
|
||||
VECCOPY(head, ebp2->vec);
|
||||
VECCOPY(tail, ebp->vec);
|
||||
}
|
||||
else {
|
||||
VECCOPY(head, ebp->vec);
|
||||
VECCOPY(tail, ebp2->vec);
|
||||
}
|
||||
}
|
||||
else if (ebp->head_owner) {
|
||||
VECCOPY(head, ebp->vec);
|
||||
VECCOPY(tail, ebp2->vec);
|
||||
}
|
||||
else if (ebp2->head_owner) {
|
||||
VECCOPY(head, ebp2->vec);
|
||||
VECCOPY(tail, ebp->vec);
|
||||
}
|
||||
|
||||
/* add new bone */
|
||||
newbone= add_points_bone(head, tail);
|
||||
}
|
||||
else {
|
||||
// FIXME.. figure out a method for multiple bones
|
||||
error("Too many points selected");
|
||||
printf("Points selected: %d \n", count);
|
||||
BLI_freelistN(&points);
|
||||
return;
|
||||
}
|
||||
|
||||
/* free points */
|
||||
BLI_freelistN(&points);
|
||||
|
||||
/* undo + updates */
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
BIF_undo_push("Fill Bones");
|
||||
}
|
||||
|
||||
/* this function merges between two bones, removes them and those in-between,
|
||||
* and adjusts the parent relationships for those in-between
|
||||
*/
|
||||
static void bones_merge(EditBone *start, EditBone *end, ListBase *chains)
|
||||
{
|
||||
EditBone *ebo, *ebone, *newbone;
|
||||
LinkData *chain;
|
||||
float head[3], tail[3];
|
||||
|
||||
/* check if same bone */
|
||||
if (start == end) {
|
||||
printf("Error: same bone! \n");
|
||||
printf("\tstart = %s, end = %s \n", start->name, end->name);
|
||||
}
|
||||
|
||||
/* step 1: add a new bone
|
||||
* - head = head/tail of start (default head)
|
||||
* - tail = head/tail of end (default tail)
|
||||
* - parent = parent of start
|
||||
*/
|
||||
if ((start->flag & BONE_TIPSEL) && !(start->flag & (BONE_SELECTED|BONE_ACTIVE))) {
|
||||
VECCOPY(head, start->tail);
|
||||
}
|
||||
else {
|
||||
VECCOPY(head, start->head);
|
||||
}
|
||||
if ((end->flag & BONE_ROOTSEL) && !(end->flag & (BONE_SELECTED|BONE_ACTIVE))) {
|
||||
VECCOPY(tail, end->head);
|
||||
}
|
||||
else {
|
||||
VECCOPY(tail, end->tail);
|
||||
}
|
||||
newbone= add_points_bone(head, tail);
|
||||
newbone->parent = start->parent;
|
||||
|
||||
/* step 2: parent children of in-between bones to newbone */
|
||||
for (chain= chains->first; chain; chain= chain->next) {
|
||||
/* ick: we need to check if parent of each bone in chain is */
|
||||
for (ebo= chain->data; ebo; ebo= ebo->parent) {
|
||||
short found= 0;
|
||||
|
||||
/* try to find which bone from the list to be removed, is the parent */
|
||||
for (ebone= end; ebone; ebone= ebone->parent) {
|
||||
if (ebo->parent == ebone) {
|
||||
found= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* adjust this bone's parent to newbone then */
|
||||
if (found) {
|
||||
ebo->parent= newbone;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* step 3: delete all bones between and including start and end */
|
||||
for (ebo= end; ebo; ebo= ebone) {
|
||||
ebone= (ebo == start) ? (NULL) : (ebo->parent);
|
||||
BLI_freelinkN(&G.edbo, ebo);
|
||||
}
|
||||
}
|
||||
|
||||
/* bone merging - has a menu! */
|
||||
void merge_armature(void)
|
||||
{
|
||||
bArmature *arm= G.obedit->data;
|
||||
short val= 0;
|
||||
|
||||
/* process a menu to determine how to merge */
|
||||
// TODO: there's room for more modes of merging stuff...
|
||||
val= pupmenu("Merge Selected Bones%t|Within Chains%x1");
|
||||
if (val <= 0) return;
|
||||
|
||||
if (val == 1) {
|
||||
/* go down chains, merging bones */
|
||||
ListBase chains = {NULL, NULL};
|
||||
LinkData *chain, *nchain;
|
||||
EditBone *ebo;
|
||||
|
||||
/* get chains (ends on chains) */
|
||||
chains_find_tips(&chains);
|
||||
if (chains.first == NULL) return;
|
||||
|
||||
/* each 'chain' is the last bone in the chain (with no children) */
|
||||
for (chain= chains.first; chain; chain= nchain) {
|
||||
EditBone *bstart= NULL, *bend= NULL;
|
||||
|
||||
/* temporarily remove chain from list of chains */
|
||||
nchain= chain->next;
|
||||
BLI_remlink(&chains, chain);
|
||||
|
||||
/* only consider bones that are visible and selected */
|
||||
for (ebo= chain->data; ebo; ebo= ebo->parent) {
|
||||
/* check if visible + selected */
|
||||
if ( (arm->layer & ebo->layer) && !(ebo->flag & BONE_HIDDEN_A) &&
|
||||
((ebo->flag & BONE_CONNECTED) || (ebo->parent==NULL)) &&
|
||||
(ebo->flag & (BONE_SELECTED|BONE_ACTIVE)) )
|
||||
{
|
||||
/* set either end or start (end gets priority, unless it is already set) */
|
||||
if (bend == NULL)
|
||||
bend= ebo;
|
||||
else
|
||||
bstart= ebo;
|
||||
}
|
||||
else {
|
||||
/* chain is broken... merge any continous segments then clear */
|
||||
if (bstart && bend)
|
||||
bones_merge(bstart, bend, &chains);
|
||||
|
||||
bstart = NULL;
|
||||
bend = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* merge from bstart to bend if something not merged */
|
||||
if (bstart && bend)
|
||||
bones_merge(bstart, bend, &chains);
|
||||
|
||||
/* put back link */
|
||||
BLI_insertlinkbefore(&chains, nchain, chain);
|
||||
}
|
||||
|
||||
BLI_freelistN(&chains);
|
||||
}
|
||||
|
||||
/* undo + updates */
|
||||
countall();
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
BIF_undo_push("Merge Bones");
|
||||
}
|
||||
|
||||
/* ************** END Add/Remove stuff in editmode ************ */
|
||||
/* *************** Tools in editmode *********** */
|
||||
|
||||
|
||||
|
@ -2823,54 +2823,87 @@ void convertmenu(void)
|
||||
DAG_scene_sort(G.scene);
|
||||
}
|
||||
|
||||
/* Change subdivision properties of mesh object ob, if
|
||||
* level==-1 then toggle subsurf, else set to level.
|
||||
* *set allows to toggle multiple selections
|
||||
*/
|
||||
static void object_flip_subdivison(Object *ob, int *set, int level, int mode, int ingroup)
|
||||
/* Change subdivision or particle properties of mesh object ob, if level==-1
|
||||
* then toggle subsurf, else set to level set allows to toggle multiple
|
||||
* selections */
|
||||
|
||||
static void object_has_subdivision_particles(Object *ob, int *havesubdiv, int *havepart, int depth)
|
||||
{
|
||||
if(ob->type==OB_MESH) {
|
||||
if(modifiers_findByType(ob, eModifierType_Subsurf))
|
||||
*havesubdiv= 1;
|
||||
if(modifiers_findByType(ob, eModifierType_ParticleSystem))
|
||||
*havepart= 1;
|
||||
}
|
||||
|
||||
if(ob->dup_group && depth <= 4) {
|
||||
GroupObject *go;
|
||||
|
||||
for(go= ob->dup_group->gobject.first; go; go= go->next)
|
||||
object_has_subdivision_particles(go->ob, havesubdiv, havepart, depth+1);
|
||||
}
|
||||
}
|
||||
|
||||
static void object_flip_subdivison_particles(Object *ob, int *set, int level, int mode, int particles, int depth)
|
||||
{
|
||||
ModifierData *md;
|
||||
|
||||
if(ob->type==OB_MESH) {
|
||||
md = modifiers_findByType(ob, eModifierType_Subsurf);
|
||||
|
||||
if (md) {
|
||||
SubsurfModifierData *smd = (SubsurfModifierData*) md;
|
||||
if(particles) {
|
||||
for(md=ob->modifiers.first; md; md=md->next) {
|
||||
if(md->type == eModifierType_ParticleSystem) {
|
||||
ParticleSystemModifierData *psmd = (ParticleSystemModifierData*)md;
|
||||
|
||||
if (level == -1) {
|
||||
if(*set == -1)
|
||||
*set= smd->modifier.mode&(mode);
|
||||
|
||||
if (*set) {
|
||||
smd->modifier.mode &= ~(mode);
|
||||
} else {
|
||||
smd->modifier.mode |= (mode);
|
||||
if(*set == -1)
|
||||
*set= psmd->modifier.mode&(mode);
|
||||
|
||||
if (*set)
|
||||
psmd->modifier.mode &= ~(mode);
|
||||
else
|
||||
psmd->modifier.mode |= (mode);
|
||||
}
|
||||
} else {
|
||||
smd->levels = level;
|
||||
}
|
||||
}
|
||||
else if(!ingroup && *set != 0) {
|
||||
SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf);
|
||||
}
|
||||
else {
|
||||
md = modifiers_findByType(ob, eModifierType_Subsurf);
|
||||
|
||||
BLI_addtail(&ob->modifiers, smd);
|
||||
if (md) {
|
||||
SubsurfModifierData *smd = (SubsurfModifierData*) md;
|
||||
|
||||
if (level!=-1) {
|
||||
smd->levels = level;
|
||||
if (level == -1) {
|
||||
if(*set == -1)
|
||||
*set= smd->modifier.mode&(mode);
|
||||
|
||||
if (*set)
|
||||
smd->modifier.mode &= ~(mode);
|
||||
else
|
||||
smd->modifier.mode |= (mode);
|
||||
} else {
|
||||
smd->levels = level;
|
||||
}
|
||||
}
|
||||
else if(depth == 0 && *set != 0) {
|
||||
SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf);
|
||||
|
||||
BLI_addtail(&ob->modifiers, smd);
|
||||
|
||||
if (level!=-1) {
|
||||
smd->levels = level;
|
||||
}
|
||||
|
||||
if(*set == -1)
|
||||
*set= 1;
|
||||
}
|
||||
|
||||
if(*set == -1)
|
||||
*set= 1;
|
||||
}
|
||||
|
||||
ob->recalc |= OB_RECALC_DATA;
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
|
||||
}
|
||||
|
||||
if(ob->dup_group) {
|
||||
if(ob->dup_group && depth<=4) {
|
||||
GroupObject *go;
|
||||
|
||||
for(go= ob->dup_group->gobject.first; go; go= go->next)
|
||||
object_flip_subdivison(go->ob, set, level, mode, 1);
|
||||
object_flip_subdivison_particles(go->ob, set, level, mode, particles, depth+1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2882,16 +2915,34 @@ void flip_subdivison(int level)
|
||||
{
|
||||
Base *base;
|
||||
int set= -1;
|
||||
int mode;
|
||||
int mode, pupmode, particles= 0, havesubdiv= 0, havepart= 0;
|
||||
|
||||
if(G.qual & LR_ALTKEY)
|
||||
mode= eModifierMode_Realtime;
|
||||
else
|
||||
mode= eModifierMode_Render|eModifierMode_Realtime;
|
||||
|
||||
if(level == -1) {
|
||||
for(base= G.scene->base.first; base; base= base->next)
|
||||
if(((level==-1) && (TESTBASE(base))) || (TESTBASELIB(base)))
|
||||
object_has_subdivision_particles(base->object, &havesubdiv, &havepart, 0);
|
||||
}
|
||||
else
|
||||
havesubdiv= 1;
|
||||
|
||||
if(havesubdiv && havepart) {
|
||||
pupmode= pupmenu("Switch%t|Subsurf %x1|Particle Systems %x2");
|
||||
if(pupmode <= 0)
|
||||
return;
|
||||
else if(pupmode == 2)
|
||||
particles= 1;
|
||||
}
|
||||
else if(havepart)
|
||||
particles= 1;
|
||||
|
||||
for(base= G.scene->base.first; base; base= base->next)
|
||||
if(((level==-1) && (TESTBASE(base))) || (TESTBASELIB(base)))
|
||||
object_flip_subdivison(base->object, &set, level, mode, 0);
|
||||
object_flip_subdivison_particles(base->object, &set, level, mode, particles, 0);
|
||||
|
||||
countall();
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
@ -2900,7 +2951,10 @@ void flip_subdivison(int level)
|
||||
allqueue(REDRAWBUTSOBJECT, 0);
|
||||
DAG_scene_flush_update(G.scene, screen_view3d_layers());
|
||||
|
||||
BIF_undo_push("Switch subsurf on/off");
|
||||
if(particles)
|
||||
BIF_undo_push("Switch particles on/off");
|
||||
else
|
||||
BIF_undo_push("Switch subsurf on/off");
|
||||
}
|
||||
|
||||
static void copymenu_properties(Object *ob)
|
||||
|
@ -157,7 +157,7 @@ void PE_change_act(void *ob_v, void *act_v)
|
||||
if((psys=BLI_findlink(&ob->particlesystem,act))) {
|
||||
psys->flag |= PSYS_CURRENT;
|
||||
|
||||
if(psys->flag & PSYS_ENABLED) {
|
||||
if(psys_check_enabled(ob, psys)) {
|
||||
if(G.f & G_PARTICLEEDIT && !psys->edit)
|
||||
PE_create_particle_edit(ob, psys);
|
||||
PE_recalc_world_cos(ob, psys);
|
||||
@ -186,7 +186,7 @@ ParticleSystem *PE_get_current(Object *ob)
|
||||
psys->flag |= PSYS_CURRENT;
|
||||
}
|
||||
|
||||
if(psys && (psys->flag & PSYS_ENABLED) && ob == OBACT && (G.f & G_PARTICLEEDIT))
|
||||
if(psys && psys_check_enabled(ob, psys) && ob == OBACT && (G.f & G_PARTICLEEDIT))
|
||||
if(psys->part->type == PART_HAIR && psys->flag & PSYS_EDITED)
|
||||
if(psys->edit == NULL)
|
||||
PE_create_particle_edit(ob, psys);
|
||||
@ -1102,7 +1102,7 @@ void PE_set_particle_edit(void)
|
||||
|
||||
if((G.f & G_PARTICLEEDIT)==0){
|
||||
if(psys && psys->part->type == PART_HAIR && psys->flag & PSYS_EDITED) {
|
||||
if(psys->flag & PSYS_ENABLED) {
|
||||
if(psys_check_enabled(ob, psys)) {
|
||||
if(psys->edit==0)
|
||||
PE_create_particle_edit(ob, psys);
|
||||
PE_recalc_world_cos(ob, psys);
|
||||
@ -2121,7 +2121,7 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe
|
||||
int i, k, n = 0, totpart = psys->totpart;
|
||||
short dmx = 0, dmy = 0;
|
||||
short mx = mval[0] - curarea->winx / 2, my = mval[1] - curarea->winy / 2;
|
||||
float co1[3], co2[3], vec[4], min_d, imat[4][4], dx, dy;
|
||||
float co1[3], co2[3], vec[4], min_d, imat[4][4];
|
||||
float framestep, timestep = psys_get_timestep(psys->part);
|
||||
short size = pset->brush[PE_BRUSH_ADD].size;
|
||||
short size2 = size*size;
|
||||
@ -2151,20 +2151,22 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe
|
||||
/* create intersection coordinates in view Z direction at mouse coordinates */
|
||||
/* Thanks to who ever wrote the "Mouse Location 3D Space" tutorial in "Blender 3D: Blending Into Python/Cookbook". */
|
||||
if(G.vd->persp){
|
||||
dx = G.vd->persmat[3][3] * (2.0f*(mx+dmx)/curarea->winx) - G.vd->persmat[3][0];
|
||||
dy = G.vd->persmat[3][3] * (2.0f*(my+dmy)/curarea->winy) - G.vd->persmat[3][1];
|
||||
vec[0]= (2.0f*(mx+dmx)/curarea->winx);
|
||||
vec[1]= (2.0f*(my+dmy)/curarea->winy);
|
||||
vec[2]= -1.0f;
|
||||
vec[3]= 1.0f;
|
||||
|
||||
co2[0]=G.vd->persinv[0][0]*dx + G.vd->persinv[1][0]*dy;
|
||||
co2[1]=G.vd->persinv[0][1]*dx + G.vd->persinv[1][1]*dy;
|
||||
co2[2]=G.vd->persinv[0][2]*dx + G.vd->persinv[1][2]*dy;
|
||||
Mat4MulVec4fl(G.vd->persinv, vec);
|
||||
VecMulf(vec, 1.0f/vec[3]);
|
||||
|
||||
VECCOPY(co1,G.vd->viewinv[3]);
|
||||
VECCOPY(co1, G.vd->viewinv[3]);
|
||||
VECSUB(vec, vec, co1);
|
||||
Normalize(vec);
|
||||
|
||||
VECSUB(vec,co2,co1)
|
||||
|
||||
VECADDFAC(co2,co1,vec,1000.0f);
|
||||
VECADDFAC(co1, G.vd->viewinv[3], vec, G.vd->near);
|
||||
VECADDFAC(co2, G.vd->viewinv[3], vec, G.vd->far);
|
||||
}
|
||||
else{
|
||||
else {
|
||||
vec[0] = 2.0f*(mx+dmx)/curarea->winx;
|
||||
vec[1] = 2.0f*(my+dmy)/curarea->winy;
|
||||
vec[2] = 0.0f;
|
||||
|
@ -3765,8 +3765,8 @@ static void do_view3d_edit_armaturemenu(void *arg, int event)
|
||||
case 17: /* move to layer */
|
||||
pose_movetolayer();
|
||||
break;
|
||||
case 18:
|
||||
uv_autocalc_tface();
|
||||
case 18: /* merge bones */
|
||||
merge_armature();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3838,6 +3838,8 @@ static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extrude Forked|Shift E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Merge|Alt M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Fill Between Joints|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
@ -3850,11 +3852,7 @@ static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Switch Armature Layers|Shift M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Move Bone To Layer|M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "UV Unwrap|U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
|
||||
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefIconTextBlockBut(block, view3d_edit_armature_parentmenu, NULL, ICON_RIGHTARROW_THIN, "Parent", 0, yco-=20, 120, 19, "");
|
||||
|
@ -173,8 +173,8 @@ float BIF_GetStringWidth(BMF_Font* font, char *str, int translate)
|
||||
}
|
||||
|
||||
void BIF_GetBoundingBox(struct BMF_Font* font, char* str, int translate, rctf *bbox){
|
||||
float dummy;
|
||||
#ifdef INTERNATIONAL
|
||||
float dummy;
|
||||
if(G.ui_international == TRUE)
|
||||
if(translate && (U.transopts & USER_TR_BUTTONS))
|
||||
FTF_GetBoundingBox(str, &bbox->xmin, &bbox->ymin, &dummy, &bbox->xmax, &bbox->ymax, &dummy, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
|
||||
|
@ -426,14 +426,14 @@ static void heat_ray_tree_create(LaplacianSystem *sys)
|
||||
DO_MINMAX(sys->heat.verts[a], min, max);
|
||||
|
||||
tree= RE_ray_tree_create(64, me->totface, min, max,
|
||||
heat_ray_coords_func, heat_ray_check_func);
|
||||
heat_ray_coords_func, heat_ray_check_func, NULL, NULL);
|
||||
|
||||
sys->heat.vface= MEM_callocN(sizeof(MFace*)*me->totvert, "HeatVFaces");
|
||||
|
||||
HeatSys= sys;
|
||||
|
||||
for(a=0, mface=me->mface; a<me->totface; a++, mface++) {
|
||||
RE_ray_tree_add_face(tree, mface);
|
||||
RE_ray_tree_add_face(tree, 0, mface);
|
||||
|
||||
sys->heat.vface[mface->v1]= mface;
|
||||
sys->heat.vface[mface->v2]= mface;
|
||||
|
@ -1154,7 +1154,7 @@ void pose_relax()
|
||||
int do_loc = 0;
|
||||
int do_quat = 0;
|
||||
int flag = 0;*/
|
||||
int do_w, do_x, do_y, do_z;
|
||||
int do_x, do_y, do_z;
|
||||
|
||||
if (!ob) return;
|
||||
|
||||
|
@ -176,6 +176,7 @@ SculptData *sculpt_data(void)
|
||||
|
||||
void sculpt_init_session(void);
|
||||
void init_editdata(EditData *e, short *, short *);
|
||||
void sculpt_undo_push(const short);
|
||||
|
||||
SculptSession *sculpt_session(void)
|
||||
{
|
||||
@ -225,6 +226,7 @@ void sculptmode_init(Scene *sce)
|
||||
sd->flags= SCULPT_DRAW_BRUSH;
|
||||
sd->tablet_size=3;
|
||||
sd->tablet_strength=10;
|
||||
sd->rake=0;
|
||||
}
|
||||
|
||||
void sculptmode_free_session(Scene *);
|
||||
@ -267,6 +269,11 @@ void sculptmode_free_all(Scene *sce)
|
||||
|
||||
sculptmode_free_session(sce);
|
||||
|
||||
if(projverts) {
|
||||
MEM_freeN(projverts);
|
||||
projverts = NULL;
|
||||
}
|
||||
|
||||
for(a=0; a<MAX_MTEX; a++) {
|
||||
MTex *mtex= sd->mtex[a];
|
||||
if(mtex) {
|
||||
@ -882,7 +889,7 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
|
||||
/* Mark area around the brush as damaged. projverts are marked if they are
|
||||
inside the area and the damaged rectangle in 2D screen coordinates is
|
||||
added to damaged_rects. */
|
||||
void sculptmode_add_damaged_rect(EditData *e)
|
||||
void sculpt_add_damaged_rect(EditData *e)
|
||||
{
|
||||
short p[2];
|
||||
const float radius= brush_size();
|
||||
@ -910,6 +917,36 @@ void sculptmode_add_damaged_rect(EditData *e)
|
||||
}
|
||||
}
|
||||
|
||||
/* Clears the depth buffer in each modified area. */
|
||||
void sculpt_clear_damaged_areas(SculptSession *ss)
|
||||
{
|
||||
RectNode *rn= NULL;
|
||||
|
||||
for(rn = ss->damaged_rects.first; rn; rn = rn->next) {
|
||||
rcti clp = rn->r;
|
||||
rcti *win = &curarea->winrct;
|
||||
|
||||
clp.xmin += win->xmin;
|
||||
clp.xmax += win->xmin;
|
||||
clp.ymin += win->ymin;
|
||||
clp.ymax += win->ymin;
|
||||
|
||||
if(clp.xmin < win->xmax && clp.xmax > win->xmin &&
|
||||
clp.ymin < win->ymax && clp.ymax > win->ymin) {
|
||||
if(clp.xmin < win->xmin) clp.xmin = win->xmin;
|
||||
if(clp.ymin < win->ymin) clp.ymin = win->ymin;
|
||||
if(clp.xmax > win->xmax) clp.xmax = win->xmax;
|
||||
if(clp.ymax > win->ymax) clp.ymax = win->ymax;
|
||||
|
||||
glScissor(clp.xmin + 1, clp.ymin + 1,
|
||||
clp.xmax - clp.xmin - 2,
|
||||
clp.ymax - clp.ymin - 2);
|
||||
}
|
||||
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void do_brush_action(EditData e)
|
||||
{
|
||||
int i;
|
||||
@ -922,7 +959,7 @@ void do_brush_action(EditData e)
|
||||
KeyBlock *keyblock= ob_get_keyblock(OBACT);
|
||||
SculptSession *ss = sculpt_session();
|
||||
|
||||
sculptmode_add_damaged_rect(&e);
|
||||
sculpt_add_damaged_rect(&e);
|
||||
|
||||
/* Build a list of all vertices that are potentially within the brush's
|
||||
area of influence. Only do this once for the grab brush. */
|
||||
@ -1531,8 +1568,9 @@ void sculptmode_update_all_projverts(float *vertcosnos)
|
||||
Mesh *me= get_mesh(OBACT);
|
||||
unsigned i;
|
||||
|
||||
if(projverts) MEM_freeN(projverts);
|
||||
projverts= MEM_mallocN(sizeof(ProjVert)*me->totvert,"ProjVerts");
|
||||
if(!projverts)
|
||||
projverts = MEM_mallocN(sizeof(ProjVert)*me->totvert,"ProjVerts");
|
||||
|
||||
for(i=0; i<me->totvert; ++i) {
|
||||
project(vertcosnos ? &vertcosnos[i * 6] : me->mvert[i].co, projverts[i].co);
|
||||
projverts[i].inside= 0;
|
||||
@ -1645,13 +1683,13 @@ void sculpt(void)
|
||||
SculptData *sd= sculpt_data();
|
||||
SculptSession *ss= sculpt_session();
|
||||
Object *ob= OBACT;
|
||||
short mouse[2], mvalo[2], firsttime=1, mousebut;
|
||||
/* lastSigMouse is for the rake, to store the last place the mouse movement was significant */
|
||||
short mouse[2], mvalo[2], lastSigMouse[2],firsttime=1, mousebut;
|
||||
short modifier_calculations= 0;
|
||||
EditData e;
|
||||
RectNode *rn= NULL;
|
||||
short spacing= 32000;
|
||||
int scissor_box[4];
|
||||
|
||||
float offsetRot;
|
||||
if(!(G.f & G_SCULPTMODE) || G.obedit || !ob || ob->id.lib || !get_mesh(ob) || (get_mesh(ob)->totface == 0))
|
||||
return;
|
||||
if(!(ob->lay & G.vd->lay))
|
||||
@ -1676,9 +1714,12 @@ void sculpt(void)
|
||||
ss->vertexcosnos = NULL;
|
||||
|
||||
/* Check that vertex users are up-to-date */
|
||||
if(ob != active_ob || ss->vertex_users_size != get_mesh(ob)->totvert) {
|
||||
if(ob != active_ob || !ss->vertex_users || ss->vertex_users_size != get_mesh(ob)->totvert) {
|
||||
sculptmode_free_vertexusers(ss);
|
||||
calc_vertex_users();
|
||||
if(projverts)
|
||||
MEM_freeN(projverts);
|
||||
projverts = NULL;
|
||||
active_ob= ob;
|
||||
}
|
||||
|
||||
@ -1689,9 +1730,6 @@ void sculpt(void)
|
||||
|
||||
getmouseco_areawin(mvalo);
|
||||
|
||||
/* Make sure sculptdata has been init'd properly */
|
||||
if(!ss->vertex_users) calc_vertex_users();
|
||||
|
||||
/* Init texture
|
||||
FIXME: Shouldn't be doing this every time! */
|
||||
if(sd->texrept!=SCULPTREPT_3D)
|
||||
@ -1700,7 +1738,8 @@ void sculpt(void)
|
||||
getmouseco_areawin(mouse);
|
||||
mvalo[0]= mouse[0];
|
||||
mvalo[1]= mouse[1];
|
||||
|
||||
lastSigMouse[0]=mouse[0];
|
||||
lastSigMouse[1]=mouse[1];
|
||||
mousebut = L_MOUSE;
|
||||
|
||||
/* If modifier_calculations is true, then extra time must be spent
|
||||
@ -1729,9 +1768,19 @@ void sculpt(void)
|
||||
|
||||
/* Get original scissor box */
|
||||
glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
|
||||
|
||||
|
||||
/* For raking, get the original angle*/
|
||||
offsetRot=tex_angle();
|
||||
|
||||
while (get_mbut() & mousebut) {
|
||||
getmouseco_areawin(mouse);
|
||||
/* If rake, and the mouse has moved over 10 pixels (euclidean) (prevents jitter) then get the new angle */
|
||||
if (sd->rake && (pow(lastSigMouse[0]-mouse[0],2)+pow(lastSigMouse[1]-mouse[1],2))>100){
|
||||
/*Nasty looking, but just orig + new angle really*/
|
||||
set_tex_angle(offsetRot+180.+to_deg(atan2((float)(mouse[1]-lastSigMouse[1]),(float)(mouse[0]-lastSigMouse[0]))));
|
||||
lastSigMouse[0]=mouse[0];
|
||||
lastSigMouse[1]=mouse[1];
|
||||
}
|
||||
|
||||
if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] || sculptmode_brush()->airbrush) {
|
||||
firsttime= 0;
|
||||
@ -1771,28 +1820,7 @@ void sculpt(void)
|
||||
/* Draw the stored image to the screen */
|
||||
glAccum(GL_RETURN, 1);
|
||||
|
||||
/* Clear each of the area(s) modified by the brush */
|
||||
for(rn=ss->damaged_rects.first; rn; rn= rn->next) {
|
||||
rcti clp= rn->r;
|
||||
rcti *win= &curarea->winrct;
|
||||
|
||||
clp.xmin+= win->xmin;
|
||||
clp.xmax+= win->xmin;
|
||||
clp.ymin+= win->ymin;
|
||||
clp.ymax+= win->ymin;
|
||||
|
||||
if(clp.xmin<win->xmax && clp.xmax>win->xmin &&
|
||||
clp.ymin<win->ymax && clp.ymax>win->ymin) {
|
||||
if(clp.xmin<win->xmin) clp.xmin= win->xmin;
|
||||
if(clp.ymin<win->ymin) clp.ymin= win->ymin;
|
||||
if(clp.xmax>win->xmax) clp.xmax= win->xmax;
|
||||
if(clp.ymax>win->ymax) clp.ymax= win->ymax;
|
||||
glScissor(clp.xmin+1, clp.ymin+1,
|
||||
clp.xmax-clp.xmin-2,clp.ymax-clp.ymin-2);
|
||||
}
|
||||
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
sculpt_clear_damaged_areas(ss);
|
||||
|
||||
/* Draw all the polygons that are inside the modified area(s) */
|
||||
glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]);
|
||||
@ -1828,14 +1856,15 @@ void sculpt(void)
|
||||
else BIF_wait_for_statechange();
|
||||
}
|
||||
|
||||
/* Set the rotation of the brush back to what it was before any rake */
|
||||
set_tex_angle(offsetRot);
|
||||
|
||||
if(sd->flags & SCULPT_INPUT_SMOOTH) {
|
||||
sculpt_stroke_apply_all(&e);
|
||||
calc_damaged_verts(&ss->damaged_verts,e.grabdata);
|
||||
BLI_freelistN(&ss->damaged_rects);
|
||||
}
|
||||
|
||||
if(projverts) MEM_freeN(projverts);
|
||||
projverts= NULL;
|
||||
if(e.layer_disps) MEM_freeN(e.layer_disps);
|
||||
if(e.layer_store) MEM_freeN(e.layer_store);
|
||||
/* Free GrabData */
|
||||
@ -1847,7 +1876,16 @@ void sculpt(void)
|
||||
}
|
||||
sculpt_stroke_free();
|
||||
|
||||
switch(G.scene->sculptdata.brush_type) {
|
||||
sculpt_undo_push(G.scene->sculptdata.brush_type);
|
||||
|
||||
if(G.vd->depths) G.vd->depths->damaged= 1;
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
|
||||
void sculpt_undo_push(const short brush_type)
|
||||
{
|
||||
switch(brush_type) {
|
||||
case DRAW_BRUSH:
|
||||
BIF_undo_push("Draw Brush"); break;
|
||||
case SMOOTH_BRUSH:
|
||||
@ -1865,10 +1903,6 @@ void sculpt(void)
|
||||
default:
|
||||
BIF_undo_push("Sculpting"); break;
|
||||
}
|
||||
|
||||
if(G.vd->depths) G.vd->depths->damaged= 1;
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
|
||||
void set_sculptmode(void)
|
||||
|
@ -1893,7 +1893,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
}
|
||||
|
||||
}
|
||||
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) addsegment_nurb();
|
||||
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
|
||||
addsegment_nurb();
|
||||
}
|
||||
else if(G.obedit->type == OB_ARMATURE) {
|
||||
fill_bones_armature();
|
||||
}
|
||||
}
|
||||
else if(G.qual==LR_CTRLKEY)
|
||||
sort_faces();
|
||||
@ -2156,10 +2161,13 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
pose_movetolayer();
|
||||
}
|
||||
else if (G.qual==LR_ALTKEY) {
|
||||
if(G.obedit->type==OB_MESH) {
|
||||
if (G.obedit->type == OB_MESH) {
|
||||
mergemenu();
|
||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||
}
|
||||
else if (G.obedit->type == OB_ARMATURE) {
|
||||
merge_armature();
|
||||
}
|
||||
}
|
||||
else if ((G.qual==0) || (G.qual==LR_CTRLKEY)) {
|
||||
mirrormenu();
|
||||
|
@ -815,7 +815,10 @@ static void transformEvent(unsigned short event, short val) {
|
||||
break;
|
||||
case PAGEUPKEY:
|
||||
case WHEELDOWNMOUSE:
|
||||
if(Trans.flag & T_PROP_EDIT) {
|
||||
if (Trans.flag & T_AUTOIK) {
|
||||
transform_autoik_update(&Trans, 1);
|
||||
}
|
||||
else if(Trans.flag & T_PROP_EDIT) {
|
||||
Trans.propsize*= 1.1f;
|
||||
calculatePropRatio(&Trans);
|
||||
}
|
||||
@ -831,7 +834,10 @@ static void transformEvent(unsigned short event, short val) {
|
||||
break;
|
||||
case PAGEDOWNKEY:
|
||||
case WHEELUPMOUSE:
|
||||
if(Trans.flag & T_PROP_EDIT) {
|
||||
if (Trans.flag & T_AUTOIK) {
|
||||
transform_autoik_update(&Trans, -1);
|
||||
}
|
||||
else if (Trans.flag & T_PROP_EDIT) {
|
||||
Trans.propsize*= 0.90909090f;
|
||||
calculatePropRatio(&Trans);
|
||||
}
|
||||
@ -2509,6 +2515,7 @@ void initTranslation(TransInfo *t)
|
||||
static void headerTranslation(TransInfo *t, float vec[3], char *str) {
|
||||
char tvec[60];
|
||||
char distvec[20];
|
||||
char autoik[20];
|
||||
float dvec[3];
|
||||
float dist;
|
||||
|
||||
@ -2529,24 +2536,35 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) {
|
||||
sprintf(distvec, "%.4e", dist);
|
||||
else
|
||||
sprintf(distvec, "%.4f", dist);
|
||||
|
||||
if(t->flag & T_AUTOIK) {
|
||||
short chainlen= G.scene->toolsettings->autoik_chainlen;
|
||||
|
||||
if(chainlen)
|
||||
sprintf(autoik, "AutoIK-Len: %d", chainlen);
|
||||
else
|
||||
strcpy(autoik, "");
|
||||
}
|
||||
else
|
||||
strcpy(autoik, "");
|
||||
|
||||
if (t->con.mode & CON_APPLY) {
|
||||
switch(t->num.idx_max) {
|
||||
case 0:
|
||||
sprintf(str, "D: %s (%s)%s %s", &tvec[0], distvec, t->con.text, t->proptext);
|
||||
sprintf(str, "D: %s (%s)%s %s %s", &tvec[0], distvec, t->con.text, t->proptext, &autoik[0]);
|
||||
break;
|
||||
case 1:
|
||||
sprintf(str, "D: %s D: %s (%s)%s %s", &tvec[0], &tvec[20], distvec, t->con.text, t->proptext);
|
||||
sprintf(str, "D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[20], distvec, t->con.text, t->proptext, &autoik[0]);
|
||||
break;
|
||||
case 2:
|
||||
sprintf(str, "D: %s D: %s D: %s (%s)%s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext);
|
||||
sprintf(str, "D: %s D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext, &autoik[0]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(t->flag & T_2D_EDIT)
|
||||
sprintf(str, "Dx: %s Dy: %s (%s)%s %s", &tvec[0], &tvec[20], distvec, t->con.text, t->proptext);
|
||||
else
|
||||
sprintf(str, "Dx: %s Dy: %s Dz: %s (%s)%s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext);
|
||||
sprintf(str, "Dx: %s Dy: %s Dz: %s (%s)%s %s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext, &autoik[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2592,7 +2610,7 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
|
||||
int Translation(TransInfo *t, short mval[2])
|
||||
{
|
||||
float tvec[3];
|
||||
char str[200];
|
||||
char str[250];
|
||||
|
||||
if(t->flag & T_SHIFT_MOD) {
|
||||
float dvec[3];
|
||||
@ -4094,3 +4112,4 @@ void BIF_TransformSetUndo(char *str)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -696,6 +696,61 @@ static void set_pose_transflags(TransInfo *t, Object *ob)
|
||||
t->mode= TFM_ROTATION;
|
||||
}
|
||||
|
||||
|
||||
/* -------- Auto-IK ---------- */
|
||||
|
||||
/* adjust pose-channel's auto-ik chainlen */
|
||||
static void pchan_autoik_adjust (bPoseChannel *pchan, short chainlen)
|
||||
{
|
||||
bConstraint *con;
|
||||
|
||||
/* don't bother to search if no valid constraints */
|
||||
if ((pchan->constflag & (PCHAN_HAS_IK|PCHAN_HAS_TARGET))==0)
|
||||
return;
|
||||
|
||||
/* check if pchan has ik-constraint */
|
||||
for (con= pchan->constraints.first; con; con= con->next) {
|
||||
if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
|
||||
bKinematicConstraint *data= con->data;
|
||||
|
||||
/* only accept if a temporary one (for auto-ik) */
|
||||
if (data->flag & CONSTRAINT_IK_TEMP) {
|
||||
/* chainlen is new chainlen, but is limited by maximum chainlen */
|
||||
if ((chainlen==0) || (chainlen > data->max_rootbone))
|
||||
data->rootbone= data->max_rootbone;
|
||||
else
|
||||
data->rootbone= chainlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* change the chain-length of auto-ik */
|
||||
void transform_autoik_update (TransInfo *t, short mode)
|
||||
{
|
||||
short *chainlen= &G.scene->toolsettings->autoik_chainlen;
|
||||
bPoseChannel *pchan;
|
||||
|
||||
/* mode determines what change to apply to chainlen */
|
||||
if (mode == 1) {
|
||||
/* mode=1 is from WHEELMOUSEDOWN... increases len */
|
||||
(*chainlen)++;
|
||||
}
|
||||
else if (mode == -1) {
|
||||
/* mode==-1 is from WHEELMOUSEUP... decreases len */
|
||||
if (*chainlen > 0) (*chainlen)--;
|
||||
}
|
||||
|
||||
/* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
|
||||
if (ELEM(NULL, t->poseobj, t->poseobj->pose))
|
||||
return;
|
||||
|
||||
/* apply to all pose-channels */
|
||||
for (pchan=t->poseobj->pose->chanbase.first; pchan; pchan=pchan->next) {
|
||||
pchan_autoik_adjust(pchan, *chainlen);
|
||||
}
|
||||
}
|
||||
|
||||
/* frees temporal IKs */
|
||||
static void pose_grab_with_ik_clear(Object *ob)
|
||||
{
|
||||
@ -723,19 +778,19 @@ static void pose_grab_with_ik_clear(Object *ob)
|
||||
}
|
||||
}
|
||||
|
||||
/* adds the IK to pchan */
|
||||
static void pose_grab_with_ik_add(bPoseChannel *pchan)
|
||||
/* adds the IK to pchan - returns if added */
|
||||
static short pose_grab_with_ik_add(bPoseChannel *pchan)
|
||||
{
|
||||
bKinematicConstraint *data;
|
||||
bConstraint *con;
|
||||
|
||||
if (pchan == NULL) { // Sanity check
|
||||
return;
|
||||
}
|
||||
/* Sanity check */
|
||||
if (pchan == NULL)
|
||||
return 0;
|
||||
|
||||
/* rule: not if there's already an IK on this channel */
|
||||
for (con= pchan->constraints.first; con; con= con->next)
|
||||
if(con->type==CONSTRAINT_TYPE_KINEMATIC)
|
||||
if (con->type==CONSTRAINT_TYPE_KINEMATIC)
|
||||
break;
|
||||
|
||||
if (con) {
|
||||
@ -743,7 +798,7 @@ static void pose_grab_with_ik_add(bPoseChannel *pchan)
|
||||
data= has_targetless_ik(pchan);
|
||||
if (data)
|
||||
data->flag |= CONSTRAINT_IK_AUTO;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
|
||||
@ -765,73 +820,79 @@ static void pose_grab_with_ik_add(bPoseChannel *pchan)
|
||||
data->rootbone++;
|
||||
pchan= pchan->parent;
|
||||
}
|
||||
|
||||
/* make a copy of maximum chain-length */
|
||||
data->max_rootbone= data->rootbone;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* bone is a canditate to get IK, but we don't do it if it has children connected */
|
||||
static void pose_grab_with_ik_children(bPose *pose, Bone *bone)
|
||||
static short pose_grab_with_ik_children(bPose *pose, Bone *bone)
|
||||
{
|
||||
Bone *bonec;
|
||||
int wentdeeper= 0;
|
||||
short wentdeeper=0, added=0;
|
||||
|
||||
/* go deeper if children & children are connected */
|
||||
for(bonec= bone->childbase.first; bonec; bonec= bonec->next) {
|
||||
if(bonec->flag & BONE_CONNECTED) {
|
||||
for (bonec= bone->childbase.first; bonec; bonec= bonec->next) {
|
||||
if (bonec->flag & BONE_CONNECTED) {
|
||||
wentdeeper= 1;
|
||||
pose_grab_with_ik_children(pose, bonec);
|
||||
added+= pose_grab_with_ik_children(pose, bonec);
|
||||
}
|
||||
}
|
||||
if(wentdeeper==0) {
|
||||
if (wentdeeper==0) {
|
||||
bPoseChannel *pchan= get_pose_channel(pose, bone->name);
|
||||
if(pchan)
|
||||
pose_grab_with_ik_add(pchan);
|
||||
if (pchan)
|
||||
added+= pose_grab_with_ik_add(pchan);
|
||||
}
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
/* main call which adds temporal IK chains */
|
||||
static void pose_grab_with_ik(Object *ob)
|
||||
static short pose_grab_with_ik(Object *ob)
|
||||
{
|
||||
bArmature *arm;
|
||||
bPoseChannel *pchan, *pchansel= NULL;
|
||||
Bone *bonec;
|
||||
|
||||
if(ob==NULL || ob->pose==NULL || (ob->flag & OB_POSEMODE)==0)
|
||||
return;
|
||||
if (ob==NULL || ob->pose==NULL || (ob->flag & OB_POSEMODE)==0)
|
||||
return 0;
|
||||
|
||||
arm = ob->data;
|
||||
|
||||
/* rule: only one Bone */
|
||||
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||
if(pchan->bone->layer & arm->layer) {
|
||||
if(pchan->bone->flag & BONE_SELECTED) {
|
||||
if(pchansel)
|
||||
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||
if (pchan->bone->layer & arm->layer) {
|
||||
if (pchan->bone->flag & BONE_SELECTED) {
|
||||
if (pchansel)
|
||||
break;
|
||||
pchansel= pchan;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(pchan || pchansel==NULL) return;
|
||||
if (pchan || pchansel==NULL) return 0;
|
||||
|
||||
/* rule: no IK for solitary (unconnected) bone */
|
||||
for(bonec=pchansel->bone->childbase.first; bonec; bonec=bonec->next) {
|
||||
if(bonec->flag & BONE_CONNECTED) {
|
||||
for (bonec=pchansel->bone->childbase.first; bonec; bonec=bonec->next) {
|
||||
if (bonec->flag & BONE_CONNECTED) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((pchansel->bone->flag & BONE_CONNECTED)==0 && (bonec == NULL)) return;
|
||||
if ((pchansel->bone->flag & BONE_CONNECTED)==0 && (bonec == NULL)) return 0;
|
||||
|
||||
/* rule: if selected Bone is not a root bone, it gets a temporal IK */
|
||||
if(pchansel->parent) {
|
||||
if (pchansel->parent) {
|
||||
/* only adds if there's no IK yet */
|
||||
pose_grab_with_ik_add(pchansel);
|
||||
return pose_grab_with_ik_add(pchansel);
|
||||
}
|
||||
else {
|
||||
/* rule: go over the children and add IK to the tips */
|
||||
pose_grab_with_ik_children(ob->pose, pchansel->bone);
|
||||
return pose_grab_with_ik_children(ob->pose, pchansel->bone);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* only called with pose mode active object now */
|
||||
static void createTransPose(TransInfo *t, Object *ob)
|
||||
{
|
||||
@ -839,6 +900,7 @@ static void createTransPose(TransInfo *t, Object *ob)
|
||||
bPoseChannel *pchan;
|
||||
TransData *td;
|
||||
TransDataExtension *tdx;
|
||||
short ik_on= 0;
|
||||
int i;
|
||||
|
||||
t->total= 0;
|
||||
@ -856,8 +918,10 @@ static void createTransPose(TransInfo *t, Object *ob)
|
||||
if (!(ob->lay & G.vd->lay)) return;
|
||||
|
||||
/* do we need to add temporal IK chains? */
|
||||
if((arm->flag & ARM_AUTO_IK) && t->mode==TFM_TRANSLATION)
|
||||
pose_grab_with_ik(ob);
|
||||
if ((arm->flag & ARM_AUTO_IK) && t->mode==TFM_TRANSLATION) {
|
||||
ik_on= pose_grab_with_ik(ob);
|
||||
if (ik_on) t->flag |= T_AUTOIK;
|
||||
}
|
||||
|
||||
/* set flags and count total (warning, can change transform to rotate) */
|
||||
set_pose_transflags(t, ob);
|
||||
@ -891,6 +955,8 @@ static void createTransPose(TransInfo *t, Object *ob)
|
||||
|
||||
if(td != (t->data+t->total)) printf("Bone selection count error\n");
|
||||
|
||||
/* initialise initial auto=ik chainlen's? */
|
||||
if (ik_on) transform_autoik_update(t, 0);
|
||||
}
|
||||
|
||||
/* ********************* armature ************** */
|
||||
@ -1500,6 +1566,7 @@ static void createTransParticleVerts(TransInfo *t)
|
||||
if(k==0 && pset->flag & PE_LOCK_FIRST)
|
||||
td->protectflag |= OB_LOCK_LOC;
|
||||
|
||||
td->ob = ob;
|
||||
td->ext = tx;
|
||||
td->tdi = NULL;
|
||||
if(t->mode == TFM_BAKE_TIME) {
|
||||
@ -3544,3 +3611,4 @@ void createTransData(TransInfo *t)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -471,12 +471,13 @@ void TargetSnapMedian(TransInfo *t)
|
||||
if ((t->tsnap.status & TARGET_INIT) == 0)
|
||||
{
|
||||
TransData *td = NULL;
|
||||
int i;
|
||||
|
||||
t->tsnap.snapTarget[0] = 0;
|
||||
t->tsnap.snapTarget[1] = 0;
|
||||
t->tsnap.snapTarget[2] = 0;
|
||||
|
||||
for (td = t->data; td != NULL && td->flag & TD_SELECTED ; td++)
|
||||
for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
|
||||
{
|
||||
VecAddf(t->tsnap.snapTarget, t->tsnap.snapTarget, td->iloc);
|
||||
}
|
||||
@ -514,7 +515,8 @@ void TargetSnapClosest(TransInfo *t)
|
||||
// More than one selected item
|
||||
else
|
||||
{
|
||||
for (td = t->data; td != NULL && td->flag & TD_SELECTED ; td++)
|
||||
int i;
|
||||
for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
|
||||
{
|
||||
float loc[3];
|
||||
float dist;
|
||||
|
@ -8,8 +8,6 @@ extern "C" {
|
||||
void YAF_switchPlugin();
|
||||
void YAF_switchFile();
|
||||
int YAF_exportScene(Render* re);
|
||||
void YAF_addDupliMtx(Object* obj);
|
||||
int YAF_objectKnownData(Object* obj);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -11,6 +11,4 @@ extern "C"
|
||||
void YAF_switchPlugin() { YAFBLEND = &byplugin; }
|
||||
void YAF_switchFile() { YAFBLEND = &byfile; }
|
||||
int YAF_exportScene(Render* re) { return (int)YAFBLEND->exportScene(re); }
|
||||
void YAF_addDupliMtx(Object* obj) { YAFBLEND->addDupliMtx(obj); }
|
||||
int YAF_objectKnownData(Object* obj) { return (int)YAFBLEND->objectKnownData(obj); }
|
||||
}
|
||||
|
@ -1230,7 +1230,8 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
|
||||
string matname(face0mat->id.name);
|
||||
// use name in imgtex_shader list if 'TexFace' enabled for this material
|
||||
if (face0mat->mode & MA_FACETEXTURE) {
|
||||
MTFace* tface = RE_vlakren_get_tface(re, face0, 0, NULL, 0);
|
||||
ObjectRen *obr = face0->obr;
|
||||
MTFace* tface = RE_vlakren_get_tface(obr, face0, obr->actmtface, NULL, 0);
|
||||
if (tface) {
|
||||
Image* fimg = (Image*)tface->tpage;
|
||||
if (fimg) matname = imgtex_shader[string(face0mat->id.name) + string(fimg->id.name)];
|
||||
@ -1407,12 +1408,13 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
|
||||
fci2!=VLR_list.end();++fci2)
|
||||
{
|
||||
VlakRen* vlr = *fci2;
|
||||
ObjectRen *obr = vlr->obr;
|
||||
Material* fmat = vlr->mat;
|
||||
bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
|
||||
string fmatname(fmat->id.name);
|
||||
// use name in imgtex_shader list if 'TexFace' enabled for this face material
|
||||
if (fmat->mode & MA_FACETEXTURE) {
|
||||
MTFace* tface = RE_vlakren_get_tface(re, vlr, 0, NULL, 0);
|
||||
MTFace* tface = RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
|
||||
if (tface) {
|
||||
Image* fimg = (Image*)tface->tpage;
|
||||
if (fimg) fmatname = imgtex_shader[fmatname + string(fimg->id.name)];
|
||||
@ -1437,14 +1439,14 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
|
||||
}
|
||||
else if (vlr->flag & R_FACE_SPLIT) { ui2++; ui3++; }
|
||||
|
||||
MTFace* uvc = RE_vlakren_get_tface(re, vlr, 0, NULL, 0); // possible uvcoords (v upside down)
|
||||
MTFace* uvc = RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0); // possible uvcoords (v upside down)
|
||||
if (uvc) {
|
||||
ostr << " u_a=\"" << uvc->uv[ui1][0] << "\" v_a=\"" << 1-uvc->uv[ui1][1] << "\""
|
||||
<< " u_b=\"" << uvc->uv[ui2][0] << "\" v_b=\"" << 1-uvc->uv[ui2][1] << "\""
|
||||
<< " u_c=\"" << uvc->uv[ui3][0] << "\" v_c=\"" << 1-uvc->uv[ui3][1] << "\"";
|
||||
}
|
||||
|
||||
MCol *mcol= RE_vlakren_get_mcol(re, vlr, 0, NULL, 0);
|
||||
MCol *mcol= RE_vlakren_get_mcol(obr, vlr, obr->actmcol, NULL, 0);
|
||||
|
||||
// since Blender seems to need vcols when uvs are used, for yafray only export when the material actually uses vcols
|
||||
if ((EXPORT_VCOL) && mcol) {
|
||||
|
@ -1109,7 +1109,8 @@ void yafrayPluginRender_t::genUVcoords(vector<yafray::GFLOAT> &uvcoords, VlakRen
|
||||
|
||||
void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol, VlakRen *vlr, bool comple)
|
||||
{
|
||||
MCol *mcol= RE_vlakren_get_mcol(re, vlr, 0, NULL, 0);
|
||||
ObjectRen *obr= vlr->obr;
|
||||
MCol *mcol= RE_vlakren_get_mcol(obr, vlr, obr->actmcol, NULL, 0);
|
||||
|
||||
if (mcol)
|
||||
{
|
||||
@ -1145,12 +1146,13 @@ void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,ve
|
||||
map<VertRen*, int> &vert_idx,VlakRen *vlr,
|
||||
int has_orco,bool has_uv)
|
||||
{
|
||||
ObjectRen *obr= vlr->obr;
|
||||
Material* fmat = vlr->mat;
|
||||
bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
|
||||
string fmatname(fmat->id.name);
|
||||
// use name in imgtex_shader list if 'TexFace' enabled for this face material
|
||||
if (fmat->mode & MA_FACETEXTURE) {
|
||||
MTFace* tface = RE_vlakren_get_tface(re, vlr, 0, NULL, 0);
|
||||
MTFace* tface = RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
|
||||
if (tface) {
|
||||
Image* fimg = (Image*)tface->tpage;
|
||||
if (fimg) fmatname = imgtex_shader[fmatname + string(fimg->id.name)];
|
||||
@ -1171,7 +1173,7 @@ void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,ve
|
||||
faceshader.push_back(shaders.size()-1);
|
||||
}
|
||||
|
||||
MTFace* uvc = RE_vlakren_get_tface(re, vlr, 0, NULL, 0); // possible uvcoords (v upside down)
|
||||
MTFace* uvc = RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0); // possible uvcoords (v upside down)
|
||||
int idx1, idx2, idx3;
|
||||
|
||||
idx1 = vert_idx.find(vlr->v1)->second;
|
||||
@ -1192,11 +1194,12 @@ void yafrayPluginRender_t::genCompleFace(vector<int> &faces,/*vector<string> &sh
|
||||
map<VertRen*, int> &vert_idx,VlakRen *vlr,
|
||||
int has_orco,bool has_uv)
|
||||
{
|
||||
ObjectRen *obr= vlr->obr;
|
||||
Material* fmat = vlr->mat;
|
||||
bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
|
||||
|
||||
faceshader.push_back(faceshader.back());
|
||||
MTFace* uvc = RE_vlakren_get_tface(re, vlr, 0, NULL, 0); // possible uvcoords (v upside down)
|
||||
MTFace* uvc = RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0); // possible uvcoords (v upside down)
|
||||
int idx1, idx2, idx3;
|
||||
idx1 = vert_idx.find(vlr->v3)->second;
|
||||
idx2 = vert_idx.find(vlr->v4)->second;
|
||||
@ -1338,8 +1341,9 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
|
||||
fci!=VLR_list.end();++fci)
|
||||
{
|
||||
VlakRen* vlr = *fci;
|
||||
ObjectRen *obr = vlr->obr;
|
||||
genVertices(verts, vidx, vert_idx, vlr, has_orco, obj);
|
||||
if(RE_vlakren_get_tface(re, vlr, 0, NULL, 0)) has_uv=true;
|
||||
if(RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0)) has_uv=true;
|
||||
}
|
||||
// all faces using the index list created above
|
||||
vector<int> faces;
|
||||
@ -1382,7 +1386,6 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
|
||||
// write all objects
|
||||
void yafrayPluginRender_t::writeAllObjects()
|
||||
{
|
||||
|
||||
// first all objects except dupliverts (and main instance object for dups)
|
||||
for (map<Object*, vector<VlakRen*> >::const_iterator obi=all_objects.begin();
|
||||
obi!=all_objects.end(); ++obi)
|
||||
@ -1437,7 +1440,6 @@ void yafrayPluginRender_t::writeAllObjects()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void yafrayPluginRender_t::writeAreaLamp(LampRen* lamp, int num, float iview[4][4])
|
||||
|
@ -73,7 +73,20 @@ bool yafrayRender_t::exportScene(Render* re)
|
||||
// as well as associating them again with the original Object.
|
||||
bool yafrayRender_t::getAllMatTexObs()
|
||||
{
|
||||
ObjectInstanceRen *obi;
|
||||
ObjectRen *obr;
|
||||
VlakRen* vlr;
|
||||
float mat[4][4];
|
||||
|
||||
// convert blender object instances to dupli matrices
|
||||
for(obi=(ObjectInstanceRen*)re->instancetable.first; obi; obi=obi->next) {
|
||||
if(obi->flag & R_DUPLI_TRANSFORMED) {
|
||||
// compute object matrix with dupli transform, need to transform
|
||||
// obi->mat out of view space for it
|
||||
MTC_Mat4MulSerie(mat, re->viewinv, obi->mat, re->viewmat, obi->obr->ob->obmat, 0, 0, 0, 0);
|
||||
addDupliMtx(obi->obr->ob, mat);
|
||||
}
|
||||
}
|
||||
|
||||
// Blender does not include object which have total 0 alpha materials,
|
||||
// however, the objects might have been included in the dupliMtx list,
|
||||
@ -84,69 +97,72 @@ bool yafrayRender_t::getAllMatTexObs()
|
||||
// but on the other hand that could also hide the real problem of course...
|
||||
map<string, Object*> renderobs;
|
||||
|
||||
for (int i=0; i < re->totvlak; i++) {
|
||||
for(obr=(ObjectRen*)re->objecttable.first; obr; obr=obr->next) {
|
||||
for (int i=0; i < obr->totvlak; i++) {
|
||||
|
||||
if ((i & 255)==0) vlr=re->vlaknodes[i>>8].vlak; else vlr++;
|
||||
if ((i & 255)==0) vlr=obr->vlaknodes[i>>8].vlak; else vlr++;
|
||||
|
||||
// ---- The materials & textures
|
||||
// in this case, probably every face has a material assigned, which can be the default material,
|
||||
// so checking that this is !0 is probably not necessary, but just in case...
|
||||
Material* matr = vlr->mat;
|
||||
if (matr) {
|
||||
// The default assigned material seems to be nameless, no MA id, an empty string.
|
||||
// Since this name is needed in yafray, make it 'blender_default'
|
||||
if (strlen(matr->id.name)==0)
|
||||
used_materials["blender_default"] = matr;
|
||||
else
|
||||
used_materials[matr->id.name] = matr;
|
||||
// textures, all active channels
|
||||
for (int m=0;m<MAX_MTEX;m++) {
|
||||
if (matr->septex & (1<<m)) continue; // only active channels
|
||||
MTex* mx = matr->mtex[m];
|
||||
// if no mtex, ignore
|
||||
if (mx==NULL) continue;
|
||||
// if no tex, ignore
|
||||
Tex* tx = mx->tex;
|
||||
if (tx==NULL) continue;
|
||||
short txtp = tx->type;
|
||||
// if texture type not available in yafray, ignore
|
||||
if ((txtp==0) ||
|
||||
(txtp==TEX_MAGIC) ||
|
||||
(txtp==TEX_PLUGIN) ||
|
||||
(txtp==TEX_ENVMAP)) continue;
|
||||
// if texture is stucci, only export if 'nor' enabled
|
||||
if ((txtp==TEX_STUCCI) && !((mx->mapto & MAP_NORM) || (mx->maptoneg & MAP_NORM))) continue;
|
||||
// In the case of an image texture, check that there is an actual image, otherwise ignore.
|
||||
// Stupid error was here (...if (txtp & TEX_IMAGE)...),
|
||||
// which happened to work sofar, but not anymore with the extended texture support..
|
||||
if ((txtp==TEX_IMAGE) && (!tx->ima)) continue;
|
||||
used_textures[tx->id.name] = mx;
|
||||
}
|
||||
}
|
||||
|
||||
// Make list of faces per object, ignore <3 vert faces, duplicate vertex sorting done later.
|
||||
// ignore null object pointers.
|
||||
// Also make list of facetexture images (material 'TexFace').
|
||||
if (vlr->ob) {
|
||||
int nv = 0; // number of vertices
|
||||
MTFace *tface;
|
||||
|
||||
if (vlr->v4) nv=4; else if (vlr->v3) nv=3;
|
||||
if (nv) {
|
||||
renderobs[vlr->ob->id.name] = vlr->ob;
|
||||
all_objects[vlr->ob].push_back(vlr);
|
||||
|
||||
tface= RE_vlakren_get_tface(re, vlr, 0, NULL, 0);
|
||||
if (tface && tface->tpage) {
|
||||
Material* fmat = vlr->mat;
|
||||
|
||||
// only save if TexFace enabled
|
||||
if(fmat && (fmat->mode & MA_FACETEXTURE))
|
||||
imagetex[tface->tpage].insert(fmat);
|
||||
// ---- The materials & textures
|
||||
// in this case, probably every face has a material assigned, which can be the default material,
|
||||
// so checking that this is !0 is probably not necessary, but just in case...
|
||||
Material* matr = vlr->mat;
|
||||
if (matr) {
|
||||
// The default assigned material seems to be nameless, no MA id, an empty string.
|
||||
// Since this name is needed in yafray, make it 'blender_default'
|
||||
if (strlen(matr->id.name)==0)
|
||||
used_materials["blender_default"] = matr;
|
||||
else
|
||||
used_materials[matr->id.name] = matr;
|
||||
// textures, all active channels
|
||||
for (int m=0;m<MAX_MTEX;m++) {
|
||||
if (matr->septex & (1<<m)) continue; // only active channels
|
||||
MTex* mx = matr->mtex[m];
|
||||
// if no mtex, ignore
|
||||
if (mx==NULL) continue;
|
||||
// if no tex, ignore
|
||||
Tex* tx = mx->tex;
|
||||
if (tx==NULL) continue;
|
||||
short txtp = tx->type;
|
||||
// if texture type not available in yafray, ignore
|
||||
if ((txtp==0) ||
|
||||
(txtp==TEX_MAGIC) ||
|
||||
(txtp==TEX_PLUGIN) ||
|
||||
(txtp==TEX_ENVMAP)) continue;
|
||||
// if texture is stucci, only export if 'nor' enabled
|
||||
if ((txtp==TEX_STUCCI) && !((mx->mapto & MAP_NORM) || (mx->maptoneg & MAP_NORM))) continue;
|
||||
// In the case of an image texture, check that there is an actual image, otherwise ignore.
|
||||
// Stupid error was here (...if (txtp & TEX_IMAGE)...),
|
||||
// which happened to work sofar, but not anymore with the extended texture support..
|
||||
if ((txtp==TEX_IMAGE) && (!tx->ima)) continue;
|
||||
used_textures[tx->id.name] = mx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make list of faces per object, ignore <3 vert faces, duplicate vertex sorting done later.
|
||||
// ignore null object pointers.
|
||||
// Also make list of facetexture images (material 'TexFace').
|
||||
if (vlr->obr->ob) {
|
||||
int nv = 0; // number of vertices
|
||||
MTFace *tface;
|
||||
|
||||
if (vlr->v4) nv=4; else if (vlr->v3) nv=3;
|
||||
if (nv) {
|
||||
ObjectRen *obr= vlr->obr;
|
||||
renderobs[obr->ob->id.name] = obr->ob;
|
||||
all_objects[obr->ob].push_back(vlr);
|
||||
|
||||
tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
|
||||
if (tface && tface->tpage) {
|
||||
Material* fmat = vlr->mat;
|
||||
|
||||
// only save if TexFace enabled
|
||||
if(fmat && (fmat->mode & MA_FACETEXTURE))
|
||||
imagetex[tface->tpage].insert(fmat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// now remove any objects from dupliMtx_list which are not in the renderlist
|
||||
@ -187,16 +203,16 @@ bool yafrayRender_t::getAllMatTexObs()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void yafrayRender_t::addDupliMtx(Object* obj)
|
||||
void yafrayRender_t::addDupliMtx(Object* obj, float mat[][4])
|
||||
{
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
dupliMtx_list[obj->id.name].push_back(obj->obmat[i][j]);
|
||||
dupliMtx_list[obj->id.name].push_back(mat[i][j]);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
bool yafrayRender_t::objectKnownData(Object* obj)
|
||||
{
|
||||
// if object data already known, no need to include in renderlist, otherwise save object datapointer
|
||||
@ -217,3 +233,5 @@ bool yafrayRender_t::objectKnownData(Object* obj)
|
||||
objectData[obj->data] = obj;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -62,7 +62,7 @@ class yafrayRender_t
|
||||
|
||||
// mtds
|
||||
bool exportScene(Render* re);
|
||||
void addDupliMtx(Object* obj);
|
||||
void addDupliMtx(Object* obj, float mat[][4]);
|
||||
bool objectKnownData(Object* obj);
|
||||
|
||||
protected:
|
||||
|
@ -184,13 +184,14 @@ ifeq ($(OS),solaris)
|
||||
REL_CFLAGS += -O1
|
||||
REL_CCFLAGS += -O1
|
||||
NAN_DEPEND = true
|
||||
ifeq ($(CPU),sparc)
|
||||
#ifeq ($(CPU),sparc)
|
||||
ifeq ($(CPU),$(findstring $(CPU), "sparc"))
|
||||
OPENGL_HEADERS = /usr/openwin/share/include
|
||||
CPPFLAGS += -DSUN_OGL_NO_VERTEX_MACROS
|
||||
JAVA_HEADERS = /usr/java/include
|
||||
JAVA_SYSTEM_HEADERS = /usr/java/include/solaris
|
||||
else
|
||||
OPENGL_HEADERS = /usr/X11/include
|
||||
OPENGL_HEADERS = $(LCGDIR)/mesa/include
|
||||
endif
|
||||
AR = ar
|
||||
ARFLAGS = ruv
|
||||
|
@ -142,7 +142,9 @@ endif
|
||||
endif
|
||||
else
|
||||
ifeq ($(OS), solaris)
|
||||
export NAN_OPENEXR ?= /usr/local
|
||||
# this only exists at the moment for i386-64 CPU Types at the moment
|
||||
export NAN_OPENEXR ?= $(LCGDIR)/openexr
|
||||
|
||||
export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a $(NAN_OPENEXR)/lib/libIlmThread.a -lrt
|
||||
else
|
||||
export NAN_OPENEXR ?= /usr/local
|
||||
@ -469,8 +471,8 @@ endif
|
||||
|
||||
export ID = $(shell /usr/ucb/whoami)
|
||||
export HOST = $(shell hostname)
|
||||
export NAN_PYTHON ?= /usr/local
|
||||
export NAN_PYTHON_VERSION ?= 2.3
|
||||
export NAN_PYTHON ?= $(LCGDIR)/python
|
||||
export NAN_PYTHON_VERSION ?= 2.5
|
||||
export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
|
||||
export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
|
||||
export NAN_OPENAL ?= $(LCGDIR)/openal
|
||||
@ -480,7 +482,7 @@ endif
|
||||
export NAN_TIFF ?= /usr
|
||||
export NAN_ODE ?= $(LCGDIR)/ode
|
||||
export NAN_TERRAPLAY ?=
|
||||
export NAN_MESA ?= /usr/src/Mesa-3.1
|
||||
export NAN_MESA ?= $(LCGDIR)/mesa
|
||||
export NAN_ZLIB ?= $(LCGDIR)/zlib
|
||||
export NAN_NSPR ?= $(LCGDIR)/nspr
|
||||
export NAN_FREETYPE ?= $(LCGDIR)/freetype
|
||||
|
@ -117,10 +117,10 @@ ifeq ($(OS),openbsd)
|
||||
endif
|
||||
|
||||
ifeq ($(OS),solaris)
|
||||
ifeq ($(CPU), i386)
|
||||
LLIBS = -L/usr/X11/lib
|
||||
endif
|
||||
LLIBS += -lGLU -lGL -lXmu -lXext -lXi -lX11 -lc -lm -ldl -lsocket -lnsl
|
||||
ifeq (x86_64, $(findstring x86_64, $(CPU)))
|
||||
LLIBS = -lrt
|
||||
endif
|
||||
LLIBS += -L$(NAN_MESA)/lib -lGLU -lGL -lXmu -lXext -lXi -lX11 -lc -lm -ldl -lsocket -lnsl
|
||||
DYNLDFLAGS = -shared $(LDFLAGS)
|
||||
endif
|
||||
|
||||
|
@ -46,7 +46,7 @@ def validate_arguments(args, bc):
|
||||
'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH',
|
||||
'WITH_BF_STATICOPENGL', 'BF_OPENGL', 'BF_OPENGL_INC', 'BF_OPENGL_LIB', 'BF_OPENGL_LIBPATH', 'BF_OPENGL_LIB_STATIC', 'BF_OPENGL_LINKFLAGS',
|
||||
'WITH_BF_FTGL', 'BF_FTGL', 'BF_FTGL_INC', 'BF_FTGL_LIB',
|
||||
'WITH_BF_FFMPEG',
|
||||
'WITH_BF_BPYAPI_V24X',
|
||||
'WITH_BF_PLAYER',
|
||||
'CFLAGS', 'CCFLAGS', 'CPPFLAGS',
|
||||
'REL_CFLAGS', 'REL_CCFLAGS',
|
||||
@ -174,6 +174,7 @@ def read_opts(cfg, args):
|
||||
('BF_FFMPEG_INC', 'FFMPEG includes', ''),
|
||||
('BF_FFMPEG_LIBPATH', 'FFMPEG library path', ''),
|
||||
|
||||
(BoolOption('WITH_BF_BPYAPI_V24X', 'Compile Blender 2.4x python api if true', 'true')),
|
||||
|
||||
(BoolOption('WITH_BF_JPEG', 'Use JPEG if true', 'true')),
|
||||
('BF_JPEG', 'JPEG base path', ''),
|
||||
|
Loading…
Reference in New Issue
Block a user