diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-04-20 19:06:46 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-04-20 19:06:46 +0400 |
commit | 874c29cea8e6f9bc411fccf2d6f4cb07e94328d0 (patch) | |
tree | 5971e577cf7c02e05a1e37b5ad058c71a6744877 /source/blender | |
parent | 7555bfa793a2b0fc187c6211c56986f35b2d7b09 (diff) | |
parent | c5bc4e4fb1a33eda8c31f2ea02e91f32f74c8fa5 (diff) |
2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r19323:HEAD
Notes:
* blenderbuttons and ICON_SNAP_PEEL_OBJECT were not merged.
Diffstat (limited to 'source/blender')
106 files changed, 2084 insertions, 1368 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 1c5cc2ff311..8c54c35473c 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -44,6 +44,7 @@ #include "DNA_customdata_types.h" #include "BKE_customdata.h" +#include "BKE_bvhutils.h" struct MVert; struct MEdge; @@ -70,6 +71,7 @@ struct DerivedMesh { int numVertData, numEdgeData, numFaceData; int needsFree; /* checked on ->release, is set to 0 for cached results */ int deformedOnly; /* set by modifier stack if only deformed from original */ + BVHCache bvhCache; /* Misc. Queries */ diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h index b3ce5447e68..957cd8ef9bd 100644 --- a/source/blender/blenkernel/BKE_bmesh.h +++ b/source/blender/blenkernel/BKE_bmesh.h @@ -3,7 +3,7 @@ * * BMesh modeler structure and functions. * - * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/BKE_bmeshCustomData.h b/source/blender/blenkernel/BKE_bmeshCustomData.h index 4f5f2641f54..e910fc13ed4 100644 --- a/source/blender/blenkernel/BKE_bmeshCustomData.h +++ b/source/blender/blenkernel/BKE_bmeshCustomData.h @@ -3,7 +3,7 @@ * * BMesh modeler structure and functions. * - * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/BKE_booleanops.h b/source/blender/blenkernel/BKE_booleanops.h index b51ee2646fc..a32f21af859 100644 --- a/source/blender/blenkernel/BKE_booleanops.h +++ b/source/blender/blenkernel/BKE_booleanops.h @@ -43,8 +43,7 @@ int NewBooleanMesh(struct Scene *scene, struct Base *base, struct Base *base_sel /* Performs a boolean between two mesh objects, it is assumed that both objects are in fact mesh object. On success returns a DerivedMesh. On failure returns NULL and reports an error. */ -struct DerivedMesh *NewBooleanDerivedMesh(struct Object *ob, - struct Object *ob_select, - int op); +struct DerivedMesh *NewBooleanDerivedMesh(struct DerivedMesh *dm, struct Object *ob, struct DerivedMesh *dm_select, struct Object *ob_select, + int int_op_type); #endif diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h index dd9ea61f24b..66c8d99959a 100644 --- a/source/blender/blenkernel/BKE_bvhutils.h +++ b/source/blender/blenkernel/BKE_bvhutils.h @@ -31,6 +31,7 @@ #define BKE_BVHUTILS_H #include "BLI_kdopbvh.h" +#include "BLI_linklist.h" /* * This header encapsulates necessary code to buld a BVH @@ -52,7 +53,7 @@ typedef struct BVHTreeFromMesh BVHTree_RayCastCallback raycast_callback; /* Mesh represented on this BVHTree */ - struct DerivedMesh *mesh; + struct DerivedMesh *mesh; /* Vertex array, so that callbacks have instante access to data */ struct MVert *vert; @@ -61,6 +62,9 @@ typedef struct BVHTreeFromMesh /* radius for raycast */ float sphere_radius; + /* Private data */ + int cached; + } BVHTreeFromMesh; /* @@ -74,7 +78,7 @@ typedef struct BVHTreeFromMesh * * free_bvhtree_from_mesh should be called when the tree is no longer needed. */ -void bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis); +BVHTree* bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis); /* * Builds a bvh tree where nodes are the faces of the given mesh. @@ -84,15 +88,50 @@ void bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMesh *m * so that the coordinates and rays are first translated on the mesh local coordinates. * Reason for this is that later bvh_from_mesh_* might use a cache system and so it becames possible to reuse * a BVHTree. + * + * The returned value is the same as in data->tree, its only returned to make it easier to test + * the success * * free_bvhtree_from_mesh should be called when the tree is no longer needed. */ -void bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis); +BVHTree* bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis); /* * Frees data allocated by a call to bvhtree_from_mesh_*. */ void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data); + +/* + * BVHCache + */ + +//Using local coordinates +#define BVHTREE_FROM_FACES 0 +#define BVHTREE_FROM_VERTICES 1 + +typedef LinkNode* BVHCache; + + +/* + * Queries a bvhcache for the chache bvhtree of the request type + */ +BVHTree *bvhcache_find(BVHCache *cache, int type); + +/* + * Inserts a BVHTree of the given type under the cache + * After that the caller no longer needs to worry when to free the BVHTree + * as that will be done when the cache is freed. + * + * A call to this assumes that there was no previous cached tree of the given type + */ +void bvhcache_insert(BVHCache *cache, BVHTree *tree, int type); + +/* + * inits and frees a bvhcache + */ +void bvhcache_init(BVHCache *cache); +void bvhcache_free(BVHCache *cache); + #endif diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 791cf40f8a0..e09be838f06 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -1,7 +1,7 @@ /** * BKE_cloth.h * - * $Id: BKE_cloth.h,v 1.1 2007/08/01 02:07:27 daniel Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h index 2518c1d6939..e4eed084a3d 100644 --- a/source/blender/blenkernel/BKE_collision.h +++ b/source/blender/blenkernel/BKE_collision.h @@ -1,7 +1,7 @@ /** * BKE_cloth.h * - * $Id: BKE_cloth.h,v 1.1 2007/08/01 02:07:27 daniel Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index b17f4a76198..e5a8df1a932 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -47,6 +47,10 @@ struct BevList; #define SEGMENTSU(nu) ( ((nu)->flagu & CU_CYCLIC) ? (nu)->pntsu : (nu)->pntsu-1 ) #define SEGMENTSV(nu) ( ((nu)->flagv & CU_CYCLIC) ? (nu)->pntsv : (nu)->pntsv-1 ) +#define CU_DO_TILT(cu, nu) (((nu->type & CU_2D) && (cu->flag & CU_3D)==0) ? 0 : 1) +#define CU_DO_RADIUS(cu, nu) ((CU_DO_TILT(cu, nu) || cu->bevobj || cu->ext1!=0.0 || cu->ext2!=0.0) ? 1:0) + + void unlink_curve( struct Curve *cu); void free_curve( struct Curve *cu); void BKE_free_editfont(struct Curve *cu); @@ -65,7 +69,7 @@ void duplicateNurblist( struct ListBase *lb1, struct ListBase *lb2); void test2DNurb( struct Nurb *nu); void minmaxNurb( struct Nurb *nu, float *min, float *max); -void makeknots( struct Nurb *nu, short uv, short type); +void makeknots( struct Nurb *nu, short uv); void makeNurbfaces(struct Nurb *nu, float *coord_array, int rowstride); void makeNurbcurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 8bf6d91e325..db4d948216e 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -1,7 +1,7 @@ /* BKE_particle.h * * - * $Id: BKE_particle.h $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -180,7 +180,7 @@ typedef struct ParticleThreadContext { /* path caching */ int editupdate, between, steps; - int totchild, totparent; + int totchild, totparent, parent_pass; float cfra; @@ -195,6 +195,19 @@ typedef struct ParticleThread { int num, tot; } ParticleThread; +typedef struct ParticleBillboardData +{ + struct Object *ob; + float vec[3], vel[3]; + float offset[2]; + float size, tilt, random, time; + int uv[3]; + int lock, num; + int totnum; + short align, uv_split, anim, split_offset; +} +ParticleBillboardData; + /* ----------- functions needed outside particlesystem ---------------- */ /* particle.c */ int count_particles(struct ParticleSystem *psys); @@ -268,6 +281,8 @@ void psys_threads_free(ParticleThread *threads); void psys_thread_distribute_particle(ParticleThread *thread, struct ParticleData *pa, struct ChildParticle *cpa, int p); void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *keys, int i); +void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]); + /* particle_system.c */ int psys_count_keyed_targets(struct Object *ob, struct ParticleSystem *psys); void psys_get_reactor_target(struct Object *ob, struct ParticleSystem *psys, struct Object **target_ob, struct ParticleSystem **target_psys); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 734687adafb..70eba5006d6 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -38,6 +38,7 @@ struct Base; struct AviCodecData; struct QuicktimeCodecData; struct RenderData; +struct Text; /* note; doesn't work when scene is empty */ #define SETLOOPER(s, b) sce= s, b= (Base*)sce->base.first; b; b= (Base*)(b->next?b->next:sce->set?(sce=sce->set)->base.first:NULL) @@ -73,5 +74,7 @@ int get_render_child_particle_number(struct RenderData *r, int num); int get_render_shadow_samples(struct RenderData *r, int samples); float get_render_aosss_error(struct RenderData *r, float error); +void free_dome_warp_text(struct Text *txt); + #endif diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index 103b78f0d6e..eb0e3c4ef00 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -35,6 +35,8 @@ #include "BKE_customdata.h" struct DerivedMesh; struct Object; +struct DerivedMesh *object_get_derived_final(struct Scene *scene, struct Object *ob, CustomDataMask dataMask); + /* SpaceTransform stuff */ /* @@ -59,7 +61,7 @@ struct Object; * space_transform_invert_normal(&data, &no); * */ - +struct Object; typedef struct SpaceTransform { @@ -92,6 +94,8 @@ void space_transform_invert(const struct SpaceTransform *data, float *co); struct Object; struct Scene; struct DerivedMesh; +struct MVert; +struct MDeformVert; struct ShrinkwrapModifierData; struct MDeformVert; struct BVHTree; @@ -102,8 +106,8 @@ typedef struct ShrinkwrapCalcData ShrinkwrapModifierData *smd; //shrinkwrap modifier data struct Object *ob; //object we are applying shrinkwrap to - struct DerivedMesh *original; //mesh before shrinkwrap + MVert *vert; //Array of verts being projected (to fetch normals or other data) float (*vertexCos)[3]; //vertexs being shrinkwraped int numVerts; @@ -120,6 +124,17 @@ typedef struct ShrinkwrapCalcData void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts); /* + * This function casts a ray in the given BVHTree.. but it takes into consideration the space_transform, that is: + * + * if transf was configured with "space_transform_setup( &transf, ob1, ob2 )" + * then the input (vert, dir, BVHTreeRayHit) must be defined in ob1 coordinates space + * and the BVHTree must be built in ob2 coordinate space. + * + * Thus it provides an easy way to cast the same ray across several trees (where each tree was built on its own coords space) + */ +int normal_projection_project_vertex(char options, const float *vert, const float *dir, const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata); + +/* * NULL initializers to local data */ #define NULL_ShrinkwrapCalcData {NULL, } diff --git a/source/blender/blenkernel/BKE_suggestions.h b/source/blender/blenkernel/BKE_suggestions.h index d58b8f58bf5..473e3f547f2 100644 --- a/source/blender/blenkernel/BKE_suggestions.h +++ b/source/blender/blenkernel/BKE_suggestions.h @@ -1,5 +1,5 @@ /** - * $Id: $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 1ea9cfae78e..86ff3a43045 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -15,49 +15,51 @@ incs += ' ../gpu #/extern/glew/include' incs += ' ' + env['BF_OPENGL_INC'] incs += ' ' + env['BF_ZLIB_INC'] -defs = '' +defs = [] if not env['WITH_BF_PYTHON']: - defs += 'DISABLE_PYTHON' + defs.append('DISABLE_PYTHON') else: incs += ' ../python' incs += ' ' + env['BF_PYTHON_INC'] + if env['BF_DEBUG']: + defs.append('_DEBUG') if env['WITH_BF_QUICKTIME']: - incs += ' ../quicktime' + incs += ' ../quicktime' if env['WITH_BF_SDL']: incs += ' ' + env['BF_SDL_INC'] else: - defs += ' DISABLE_SDL' + defs.append('DISABLE_SDL') if env['WITH_BF_INTERNATIONAL']: - defs += ' WITH_FREETYPE2' + defs.append('WITH_FREETYPE2') if env['WITH_BF_OPENEXR']: - defs += ' WITH_OPENEXR' + defs.append('WITH_OPENEXR') if env['WITH_BF_OPENJPEG']: - defs += ' WITH_OPENJPEG' + defs.append('WITH_OPENJPEG') if env['WITH_BF_DDS']: - defs += ' WITH_DDS' + defs.append('WITH_DDS') if env['WITH_BF_FFMPEG']: - defs += ' WITH_FFMPEG' - incs += ' ' + env['BF_FFMPEG_INC'] + defs.append('WITH_FFMPEG') + incs += ' ' + env['BF_FFMPEG_INC'] if env['WITH_BF_QUICKTIME']: - defs += ' WITH_QUICKTIME' - incs += ' ' + env['BF_QUICKTIME_INC'] + defs.append('WITH_QUICKTIME') + incs += ' ' + env['BF_QUICKTIME_INC'] if env['WITH_BF_BULLET']: - defs += ' WITH_BULLET' + defs.append('WITH_BULLET') if env['BF_NO_ELBEEM']: - defs += ' DISABLE_ELBEEM' + defs.append('DISABLE_ELBEEM') if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] -env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = Split(defs), libtype=['core'], priority = [165] ) +env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [165] ) diff --git a/source/blender/blenkernel/intern/BME_Customdata.c b/source/blender/blenkernel/intern/BME_Customdata.c index 1fc8a4071dc..ea149e03959 100644 --- a/source/blender/blenkernel/intern/BME_Customdata.c +++ b/source/blender/blenkernel/intern/BME_Customdata.c @@ -3,7 +3,7 @@ * * Custom Data functions for Bmesh * - * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/intern/BME_conversions.c b/source/blender/blenkernel/intern/BME_conversions.c index 1e332bcf393..177bb4a136b 100644 --- a/source/blender/blenkernel/intern/BME_conversions.c +++ b/source/blender/blenkernel/intern/BME_conversions.c @@ -3,7 +3,7 @@ * * BMesh mesh level functions. * - * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/intern/BME_eulers.c b/source/blender/blenkernel/intern/BME_eulers.c index 801e0b8bdec..d0b4ab6a9ca 100644 --- a/source/blender/blenkernel/intern/BME_eulers.c +++ b/source/blender/blenkernel/intern/BME_eulers.c @@ -3,7 +3,7 @@ * * BMesh Euler construction API. * - * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/intern/BME_mesh.c b/source/blender/blenkernel/intern/BME_mesh.c index ad46a7c1eb7..f635cfcfcd2 100644 --- a/source/blender/blenkernel/intern/BME_mesh.c +++ b/source/blender/blenkernel/intern/BME_mesh.c @@ -3,7 +3,7 @@ * * BMesh mesh level functions. * - * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/intern/BME_structure.c b/source/blender/blenkernel/intern/BME_structure.c index ca27f5efd10..22ee48e4f7e 100644 --- a/source/blender/blenkernel/intern/BME_structure.c +++ b/source/blender/blenkernel/intern/BME_structure.c @@ -3,7 +3,7 @@ * * Low level routines for manipulating the BMesh structure. * - * $Id: BME_structure.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/intern/BME_tools.c b/source/blender/blenkernel/intern/BME_tools.c index 3ddd790e90b..a41307de183 100644 --- a/source/blender/blenkernel/intern/BME_tools.c +++ b/source/blender/blenkernel/intern/BME_tools.c @@ -3,7 +3,7 @@ * * Functions for changing the topology of a mesh. * - * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index cbdbe19f0b9..fd92360f6c2 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -76,6 +76,7 @@ #include "BKE_texture.h" #include "BKE_utildefines.h" #include "BKE_particle.h" +#include "BKE_bvhutils.h" #include "BLO_sys_types.h" // for intptr_t support @@ -177,6 +178,8 @@ void DM_init_funcs(DerivedMesh *dm) dm->getVertDataArray = DM_get_vert_data_layer; dm->getEdgeDataArray = DM_get_edge_data_layer; dm->getFaceDataArray = DM_get_face_data_layer; + + bvhcache_init(&dm->bvhCache); } void DM_init(DerivedMesh *dm, @@ -213,6 +216,8 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source, int DM_release(DerivedMesh *dm) { if (dm->needsFree) { + bvhcache_free(&dm->bvhCache); + CustomData_free(&dm->vertData, dm->numVertData); CustomData_free(&dm->edgeData, dm->numEdgeData); CustomData_free(&dm->faceData, dm->numFaceData); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index cffd97c70b1..1aceca454d2 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -226,14 +226,16 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK cu= ob->data; if(cu->path==NULL || cu->path->data==NULL) { printf("no path!\n"); + return 0; } path= cu->path; fp= path->data; /* test for cyclic */ bl= cu->bev.first; + if (!bl) return 0; if (!bl->nr) return 0; - if(bl && bl->poly> -1) cycl= 1; + if(bl->poly> -1) cycl= 1; ctime *= (path->len-1); @@ -759,7 +761,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p float ctime, pa_time, scale = 1.0f; float tmat[4][4], mat[4][4], pamat[4][4], size=0.0; float (*obmat)[4], (*oldobmat)[4]; - int lay, a, b, k, step_nbr = 0, counter, hair = 0; + int lay, a, b, counter, hair = 0; int totpart, totchild, totgroup=0, pa_num; if(psys==0) return; @@ -787,11 +789,6 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if((part->draw_as == PART_DRAW_OB && part->dup_ob) || (part->draw_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first)) { - if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) && part->draw & PART_DRAW_KEYS) - step_nbr = part->keys_step; - else - step_nbr = 0; - /* if we have a hair particle system, use the path cache */ if(part->type == PART_HAIR) { if(psys->flag & PSYS_HAIR_DONE) @@ -871,76 +868,65 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p oldobmat= obcopy.obmat; } - for(k=0; k<=step_nbr; k++, counter++) { - if(hair) { - /* hair we handle separate and compute transform based on hair keys */ - if(a < totpart) { - cache = psys->pathcache[a]; - psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale); - } - else { - cache = psys->childcache[a-totpart]; - psys_get_dupli_path_transform(par, psys, psmd, 0, cpa, cache, pamat, &scale); - } - - VECCOPY(pamat[3], cache->co); - pamat[3][3]= 1.0f; - - } - else if(step_nbr) { - /* other keys */ - state.time = (float)k / (float)step_nbr; - psys_get_particle_on_path(scene, par, psys, a, &state, 0); - - QuatToMat4(state.rot, pamat); - VECCOPY(pamat[3], state.co); - pamat[3][3]= 1.0f; + if(hair) { + /* hair we handle separate and compute transform based on hair keys */ + if(a < totpart) { + cache = psys->pathcache[a]; + psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale); } else { - /* first key */ - state.time = -1.0; - if(psys_get_particle_state(scene, par, psys, a, &state, 0) == 0) - continue; - - QuatToMat4(state.rot, pamat); - VECCOPY(pamat[3], state.co); - pamat[3][3]= 1.0f; + cache = psys->childcache[a-totpart]; + psys_get_dupli_path_transform(par, psys, psmd, 0, cpa, cache, pamat, &scale); } - if(part->draw_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) { - for(go= part->dup_group->gobject.first, b=0; go; go= go->next, b++) { - Mat4MulMat4(tmat, oblist[b]->obmat, pamat); - Mat4MulFloat3((float *)tmat, size*scale); - if(par_space_mat) - Mat4MulMat4(mat, tmat, par_space_mat); - else - Mat4CpyMat4(mat, tmat); + VECCOPY(pamat[3], cache->co); + pamat[3][3]= 1.0f; + + } + else { + /* first key */ + state.time = ctime; + if(psys_get_particle_state(scene, par, psys, a, &state, 0) == 0) + continue; - dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated); - Mat4CpyMat4(dob->omat, obcopylist[b].obmat); - if(G.rendering) - psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco); - } - } - else { - /* to give ipos in object correct offset */ - where_is_object_time(scene, ob, ctime-pa_time); - - Mat4CpyMat4(mat, pamat); + QuatToMat4(state.rot, pamat); + VECCOPY(pamat[3], state.co); + pamat[3][3]= 1.0f; + } - Mat4MulMat4(tmat, obmat, mat); + if(part->draw_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) { + for(go= part->dup_group->gobject.first, b=0; go; go= go->next, b++) { + Mat4MulMat4(tmat, oblist[b]->obmat, pamat); Mat4MulFloat3((float *)tmat, size*scale); if(par_space_mat) Mat4MulMat4(mat, tmat, par_space_mat); else Mat4CpyMat4(mat, tmat); - dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS, animated); - Mat4CpyMat4(dob->omat, oldobmat); + dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated); + Mat4CpyMat4(dob->omat, obcopylist[b].obmat); if(G.rendering) psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco); } } + else { + /* to give ipos in object correct offset */ + where_is_object_time(scene, ob, ctime-pa_time); + + Mat4CpyMat4(mat, pamat); + + Mat4MulMat4(tmat, obmat, mat); + Mat4MulFloat3((float *)tmat, size*scale); + if(par_space_mat) + Mat4MulMat4(mat, tmat, par_space_mat); + else + Mat4CpyMat4(mat, tmat); + + dob= new_dupli_object(lb, ob, mat, ob->lay, counter, OB_DUPLIPARTS, animated); + Mat4CpyMat4(dob->omat, oldobmat); + if(G.rendering) + psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco); + } } /* restore objects since they were changed in where_is_object_time */ diff --git a/source/blender/blenkernel/intern/bmesh_private.h b/source/blender/blenkernel/intern/bmesh_private.h index f34ef0090f3..dd7d20bcf15 100644 --- a/source/blender/blenkernel/intern/bmesh_private.h +++ b/source/blender/blenkernel/intern/bmesh_private.h @@ -3,7 +3,7 @@ * * low level, 'private' function prototypes for bmesh kernel. * - * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/intern/booleanops.c b/source/blender/blenkernel/intern/booleanops.c index e57dfea8eaf..27b78c6644c 100644 --- a/source/blender/blenkernel/intern/booleanops.c +++ b/source/blender/blenkernel/intern/booleanops.c @@ -65,7 +65,7 @@ */ typedef struct { - Mesh *mesh; + DerivedMesh *dm; Object *ob; int pos; } VertexIt; @@ -93,13 +93,13 @@ static void VertexIt_Destruct(CSG_VertexIteratorDescriptor * iterator) static int VertexIt_Done(CSG_IteratorPtr it) { VertexIt * iterator = (VertexIt *)it; - return(iterator->pos >= iterator->mesh->totvert); + return(iterator->pos >= iterator->dm->getNumVerts(iterator->dm)); } static void VertexIt_Fill(CSG_IteratorPtr it, CSG_IVertex *vert) { VertexIt * iterator = (VertexIt *)it; - MVert *verts = iterator->mesh->mvert; + MVert *verts = iterator->dm->getVertArray(iterator->dm); float global_pos[3]; @@ -127,7 +127,7 @@ static void VertexIt_Reset(CSG_IteratorPtr it) iterator->pos = 0; } -static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, Object *ob) +static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, DerivedMesh *dm, Object *ob) { VertexIt *it; @@ -139,8 +139,8 @@ static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, Object *ob) return; } // assign blender specific variables - it->ob = ob; - it->mesh = ob->data; + it->dm = dm; + it->ob = ob; // needed for obmat transformations it->pos = 0; @@ -149,7 +149,7 @@ static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, Object *ob) output->Fill = VertexIt_Fill; output->Done = VertexIt_Done; output->Reset = VertexIt_Reset; - output->num_elements = it->mesh->totvert; + output->num_elements = it->dm->getNumVerts(it->dm); output->it = it; } @@ -158,7 +158,7 @@ static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, Object *ob) */ typedef struct { - Mesh *mesh; + DerivedMesh *dm; int pos; int offset; } FaceIt; @@ -177,14 +177,14 @@ static int FaceIt_Done(CSG_IteratorPtr it) { // assume CSG_IteratorPtr is of the correct type. FaceIt * iterator = (FaceIt *)it; - return(iterator->pos >= iterator->mesh->totface); + return(iterator->pos >= iterator->dm->getNumFaces(iterator->dm)); } static void FaceIt_Fill(CSG_IteratorPtr it, CSG_IFace *face) { // assume CSG_IteratorPtr is of the correct type. FaceIt *face_it = (FaceIt *)it; - MFace *mfaces = face_it->mesh->mface; + MFace *mfaces = face_it->dm->getFaceArray(face_it->dm); MFace *mface = &mfaces[face_it->pos]; face->vertex_index[0] = mface->v1; @@ -213,7 +213,7 @@ static void FaceIt_Reset(CSG_IteratorPtr it) } static void FaceIt_Construct( - CSG_FaceIteratorDescriptor *output, Object *ob, int offset) + CSG_FaceIteratorDescriptor *output, DerivedMesh *dm, int offset) { FaceIt *it; if (output == 0) return; @@ -224,7 +224,7 @@ static void FaceIt_Construct( return ; } // assign blender specific variables - it->mesh = ob->data; + it->dm = dm; it->offset = offset; it->pos = 0; @@ -233,7 +233,7 @@ static void FaceIt_Construct( output->Fill = FaceIt_Fill; output->Done = FaceIt_Done; output->Reset = FaceIt_Reset; - output->num_elements = it->mesh->totface; + output->num_elements = it->dm->getNumFaces(it->dm); output->it = it; } @@ -276,7 +276,7 @@ static Object *AddNewBlenderMesh(Scene *scene, Base *base) } static void InterpCSGFace( - DerivedMesh *dm, Mesh *orig_me, int index, int orig_index, int nr, + DerivedMesh *dm, DerivedMesh *orig_dm, int index, int orig_index, int nr, float mapmat[][4]) { float obco[3], *co[4], *orig_co[4], w[4][4]; @@ -284,13 +284,13 @@ static void InterpCSGFace( int j; mface = CDDM_get_face(dm, index); - orig_mface = orig_me->mface + orig_index; + orig_mface = orig_dm->getFaceArray(orig_dm) + orig_index; // get the vertex coordinates from the original mesh - orig_co[0] = (orig_me->mvert + orig_mface->v1)->co; - orig_co[1] = (orig_me->mvert + orig_mface->v2)->co; - orig_co[2] = (orig_me->mvert + orig_mface->v3)->co; - orig_co[3] = (orig_mface->v4)? (orig_me->mvert + orig_mface->v4)->co: NULL; + orig_co[0] = (orig_dm->getVertArray(orig_dm) + orig_mface->v1)->co; + orig_co[1] = (orig_dm->getVertArray(orig_dm) + orig_mface->v2)->co; + orig_co[2] = (orig_dm->getVertArray(orig_dm) + orig_mface->v3)->co; + orig_co[3] = (orig_mface->v4)? (orig_dm->getVertArray(orig_dm) + orig_mface->v4)->co: NULL; // get the vertex coordinates from the new derivedmesh co[0] = CDDM_get_vert(dm, mface->v1)->co; @@ -308,7 +308,7 @@ static void InterpCSGFace( InterpWeightsQ3Dfl(orig_co[0], orig_co[1], orig_co[2], orig_co[3], obco, w[j]); } - CustomData_interp(&orig_me->fdata, &dm->faceData, &orig_index, NULL, (float*)w, 1, index); + CustomData_interp(&orig_dm->faceData, &dm->faceData, &orig_index, NULL, (float*)w, 1, index); } /* Iterate over the CSG Output Descriptors and create a new DerivedMesh @@ -320,27 +320,28 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( float mapmat[][4], Material **mat, int *totmat, + DerivedMesh *dm1, Object *ob1, + DerivedMesh *dm2, Object *ob2) { - DerivedMesh *dm; + DerivedMesh *result, *orig_dm; GHash *material_hash = NULL; Mesh *me1= (Mesh*)ob1->data; Mesh *me2= (Mesh*)ob2->data; int i; // create a new DerivedMesh - dm = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements); - - CustomData_merge(&me1->fdata, &dm->faceData, CD_MASK_DERIVEDMESH, - CD_DEFAULT, face_it->num_elements); - CustomData_merge(&me2->fdata, &dm->faceData, CD_MASK_DERIVEDMESH, - CD_DEFAULT, face_it->num_elements); + result = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements); + CustomData_merge(&dm1->faceData, &result->faceData, CD_MASK_DERIVEDMESH, + CD_DEFAULT, face_it->num_elements); + CustomData_merge(&dm2->faceData, &result->faceData, CD_MASK_DERIVEDMESH, + CD_DEFAULT, face_it->num_elements); // step through the vertex iterators: for (i = 0; !vertex_it->Done(vertex_it->it); i++) { CSG_IVertex csgvert; - MVert *mvert = CDDM_get_vert(dm, i); + MVert *mvert = CDDM_get_vert(result, i); // retrieve a csg vertex from the boolean module vertex_it->Fill(vertex_it->it, &csgvert); @@ -371,15 +372,16 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( face_it->Step(face_it->it); // find the original mesh and data - orig_ob = (csgface.orig_face < me1->totface)? ob1: ob2; + orig_ob = (csgface.orig_face < dm1->getNumFaces(dm1))? ob1: ob2; + orig_dm = (csgface.orig_face < dm1->getNumFaces(dm1))? dm1: dm2; orig_me = (orig_ob == ob1)? me1: me2; - orig_index = (orig_ob == ob1)? csgface.orig_face: csgface.orig_face - me1->totface; + orig_index = (orig_ob == ob1)? csgface.orig_face: csgface.orig_face - dm1->getNumFaces(dm1); // copy all face layers, including mface - CustomData_copy_data(&orig_me->fdata, &dm->faceData, orig_index, i, 1); + CustomData_copy_data(&orig_dm->faceData, &result->faceData, orig_index, i, 1); // set mface - mface = CDDM_get_face(dm, i); + mface = CDDM_get_face(result, i); mface->v1 = csgface.vertex_index[0]; mface->v2 = csgface.vertex_index[1]; mface->v3 = csgface.vertex_index[2]; @@ -400,29 +402,30 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( else mface->mat_nr = 0; - InterpCSGFace(dm, orig_me, i, orig_index, csgface.vertex_number, + InterpCSGFace(result, orig_dm, i, orig_index, csgface.vertex_number, (orig_me == me2)? mapmat: NULL); - test_index_face(mface, &dm->faceData, i, csgface.vertex_number); + test_index_face(mface, &result->faceData, i, csgface.vertex_number); } if (material_hash) BLI_ghash_free(material_hash, NULL, NULL); - CDDM_calc_edges(dm); - CDDM_calc_normals(dm); + CDDM_calc_edges(result); + CDDM_calc_normals(result); - return dm; + return result; } static void BuildMeshDescriptors( + struct DerivedMesh *dm, struct Object *ob, int face_offset, struct CSG_FaceIteratorDescriptor * face_it, struct CSG_VertexIteratorDescriptor * vertex_it) { - VertexIt_Construct(vertex_it,ob); - FaceIt_Construct(face_it,ob,face_offset); + VertexIt_Construct(vertex_it,dm, ob); + FaceIt_Construct(face_it,dm,face_offset); } static void FreeMeshDescriptors( @@ -434,19 +437,17 @@ static void FreeMeshDescriptors( } DerivedMesh *NewBooleanDerivedMesh_intern( - struct Object *ob, struct Object *ob_select, + DerivedMesh *dm, struct Object *ob, DerivedMesh *dm_select, struct Object *ob_select, int int_op_type, Material **mat, int *totmat) { float inv_mat[4][4]; float map_mat[4][4]; - DerivedMesh *dm = NULL; - Mesh *me1 = get_mesh(ob_select); - Mesh *me2 = get_mesh(ob); + DerivedMesh *result = NULL; - if (me1 == NULL || me2 == NULL) return 0; - if (!me1->totface || !me2->totface) return 0; + if (dm == NULL || dm_select == NULL) return 0; + if (!dm->getNumFaces(dm) || !dm_select->getNumFaces(dm_select)) return 0; // we map the final object back into ob's local coordinate space. For this // we need to compute the inverse transform from global to ob (inv_mat), @@ -477,8 +478,8 @@ DerivedMesh *NewBooleanDerivedMesh_intern( default : op_type = e_csg_intersection; } - BuildMeshDescriptors(ob_select, 0, &fd_1, &vd_1); - BuildMeshDescriptors(ob, me1->totface, &fd_2, &vd_2); + BuildMeshDescriptors(dm_select, ob_select, 0, &fd_1, &vd_1); + BuildMeshDescriptors(dm, ob, dm_select->getNumFaces(dm_select) , &fd_2, &vd_2); bool_op = CSG_NewBooleanFunction(); @@ -492,8 +493,8 @@ DerivedMesh *NewBooleanDerivedMesh_intern( // iterate through results of operation and insert // into new object - dm = ConvertCSGDescriptorsToDerivedMesh( - &fd_o, &vd_o, inv_mat, map_mat, mat, totmat, ob_select, ob); + result = ConvertCSGDescriptorsToDerivedMesh( + &fd_o, &vd_o, inv_mat, map_mat, mat, totmat, dm_select, ob_select, dm, ob); // free up the memory CSG_FreeVertexDescriptor(&vd_o); @@ -508,7 +509,7 @@ DerivedMesh *NewBooleanDerivedMesh_intern( FreeMeshDescriptors(&fd_2, &vd_2); } - return dm; + return result; } int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type) @@ -517,24 +518,30 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type) int a, maxmat, totmat= 0; Object *ob_new, *ob, *ob_select; Material **mat; + DerivedMesh *result; + DerivedMesh *dm_select; DerivedMesh *dm; ob= base->object; ob_select= base_select->object; + dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + dm_select = mesh_create_derived_view(scene, ob_select, 0); // no modifiers in editmode ?? + maxmat= ob->totcol + ob_select->totcol; mat= (Material**)MEM_mallocN(sizeof(Material*)*maxmat, "NewBooleanMeshMat"); /* put some checks in for nice user feedback */ - if((!(get_mesh(ob)->totface)) || (!(get_mesh(ob_select)->totface))) + if (dm == NULL || dm_select == NULL) return 0; + if (!dm->getNumFaces(dm) || !dm_select->getNumFaces(dm_select)) { MEM_freeN(mat); return -1; } - dm= NewBooleanDerivedMesh_intern(ob, ob_select, int_op_type, mat, &totmat); + result= NewBooleanDerivedMesh_intern(dm, ob, dm_select, ob_select, int_op_type, mat, &totmat); - if (dm == NULL) { + if (result == NULL) { MEM_freeN(mat); return 0; } @@ -543,8 +550,11 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type) ob_new= AddNewBlenderMesh(scene, base_select); me_new= ob_new->data; - DM_to_mesh(dm, me_new); + DM_to_mesh(result, me_new); + result->release(result); + dm->release(dm); + dm_select->release(dm_select); /* add materials to object */ for (a = 0; a < totmat; a++) @@ -558,9 +568,9 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type) return 1; } -DerivedMesh *NewBooleanDerivedMesh(struct Object *ob, struct Object *ob_select, +DerivedMesh *NewBooleanDerivedMesh(DerivedMesh *dm, struct Object *ob, DerivedMesh *dm_select, struct Object *ob_select, int int_op_type) { - return NewBooleanDerivedMesh_intern(ob, ob_select, int_op_type, NULL, NULL); + return NewBooleanDerivedMesh_intern(dm, ob, dm_select, ob_select, int_op_type, NULL, NULL); } diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index ae449843d2a..d9e005811d0 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -30,6 +30,7 @@ #include <stdio.h> #include <string.h> #include <math.h> +#include <assert.h> #include "BKE_bvhutils.h" @@ -45,6 +46,8 @@ #include "BKE_global.h" #include "BLI_arithb.h" +#include "BLI_linklist.h" +#include "MEM_guardedalloc.h" /* Math stuff for ray casting on mesh faces and for nearest surface */ @@ -480,30 +483,47 @@ static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *r * BVH builders */ // Builds a bvh tree.. where nodes are the vertexs of the given mesh -void bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis) +BVHTree* bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis) { - int i; - int numVerts= mesh->getNumVerts(mesh); - MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT); - BVHTree *tree = NULL; + BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_VERTICES); - memset(data, 0, sizeof(*data)); + //Not in cache + if(tree == NULL) + { + int i; + int numVerts= mesh->getNumVerts(mesh); + MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT); - if(vert == NULL) + if(vert != NULL) + { + tree = BLI_bvhtree_new(numVerts, epsilon, tree_type, axis); + + if(tree != NULL) + { + for(i = 0; i < numVerts; i++) + BLI_bvhtree_insert(tree, i, vert[i].co, 1); + + BLI_bvhtree_balance(tree); + + //Save on cache for later use +// printf("BVHTree built and saved on cache\n"); + bvhcache_insert(&mesh->bvhCache, tree, BVHTREE_FROM_VERTICES); + } + } + } + else { - printf("bvhtree cant be build: cant get a vertex array"); - return; +// printf("BVHTree is already build, using cached tree\n"); } - tree = BLI_bvhtree_new(numVerts, epsilon, tree_type, axis); - if(tree != NULL) - { - for(i = 0; i < numVerts; i++) - BLI_bvhtree_insert(tree, i, vert[i].co, 1); - BLI_bvhtree_balance(tree); + //Setup BVHTreeFromMesh + memset(data, 0, sizeof(*data)); + data->tree = tree; - data->tree = tree; + if(data->tree) + { + data->cached = TRUE; //a NULL nearest callback works fine //remeber the min distance to point is the same as the min distance to BV of point @@ -516,43 +536,62 @@ void bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float eps data->sphere_radius = epsilon; } + + return data->tree; } // Builds a bvh tree.. where nodes are the faces of the given mesh. -void bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis) +BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis) { - int i; - int numFaces= mesh->getNumFaces(mesh); - MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT); - MFace *face = mesh->getFaceDataArray(mesh, CD_MFACE); - BVHTree *tree = NULL; - - memset(data, 0, sizeof(*data)); + BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_FACES); - if(vert == NULL && face == NULL) + //Not in cache + if(tree == NULL) { - printf("bvhtree cant be build: cant get a vertex/face array"); - return; - } + int i; + int numFaces= mesh->getNumFaces(mesh); + MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT); + MFace *face = mesh->getFaceDataArray(mesh, CD_MFACE); - /* Create a bvh-tree of the given target */ - tree = BLI_bvhtree_new(numFaces, epsilon, tree_type, axis); - if(tree != NULL) - { - for(i = 0; i < numFaces; i++) + if(vert != NULL && face != NULL) { - float co[4][3]; - VECCOPY(co[0], vert[ face[i].v1 ].co); - VECCOPY(co[1], vert[ face[i].v2 ].co); - VECCOPY(co[2], vert[ face[i].v3 ].co); - if(face[i].v4) - VECCOPY(co[3], vert[ face[i].v4 ].co); + /* Create a bvh-tree of the given target */ + tree = BLI_bvhtree_new(numFaces, epsilon, tree_type, axis); + if(tree != NULL) + { + for(i = 0; i < numFaces; i++) + { + float co[4][3]; + VECCOPY(co[0], vert[ face[i].v1 ].co); + VECCOPY(co[1], vert[ face[i].v2 ].co); + VECCOPY(co[2], vert[ face[i].v3 ].co); + if(face[i].v4) + VECCOPY(co[3], vert[ face[i].v4 ].co); - BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3); + BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3); + } + BLI_bvhtree_balance(tree); + + //Save on cache for later use +// printf("BVHTree built and saved on cache\n"); + bvhcache_insert(&mesh->bvhCache, tree, BVHTREE_FROM_FACES); + } } - BLI_bvhtree_balance(tree); + } + else + { +// printf("BVHTree is already build, using cached tree\n"); + } + + + //Setup BVHTreeFromMesh + memset(data, 0, sizeof(*data)); + data->tree = tree; + + if(data->tree) + { + data->cached = TRUE; - data->tree = tree; data->nearest_callback = mesh_faces_nearest_point; data->raycast_callback = mesh_faces_spherecast; @@ -562,6 +601,8 @@ void bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float eps data->sphere_radius = epsilon; } + return data->tree; + } // Frees data allocated by a call to bvhtree_from_mesh_*. @@ -569,9 +610,78 @@ void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data) { if(data->tree) { - BLI_bvhtree_free(data->tree); + if(!data->cached) + BLI_bvhtree_free(data->tree); + memset( data, 0, sizeof(data) ); } } +/* BVHCache */ +typedef struct BVHCacheItem +{ + int type; + BVHTree *tree; + +} BVHCacheItem; + +static void bvhcacheitem_set_if_match(void *_cached, void *_search) +{ + BVHCacheItem * cached = (BVHCacheItem *)_cached; + BVHCacheItem * search = (BVHCacheItem *)_search; + + if(search->type == cached->type) + { + search->tree = cached->tree; + } +} + +BVHTree *bvhcache_find(BVHCache *cache, int type) +{ + BVHCacheItem item; + item.type = type; + item.tree = NULL; + + BLI_linklist_apply(*cache, bvhcacheitem_set_if_match, &item); + return item.tree; +} + +void bvhcache_insert(BVHCache *cache, BVHTree *tree, int type) +{ + BVHCacheItem *item = NULL; + + assert( tree != NULL ); + assert( bvhcache_find(cache, type) == NULL ); + + item = MEM_mallocN(sizeof(BVHCacheItem), "BVHCacheItem"); + assert( item != NULL ); + + item->type = type; + item->tree = tree; + + BLI_linklist_prepend( cache, item ); +} + + +void bvhcache_init(BVHCache *cache) +{ + *cache = NULL; +} + +static void bvhcacheitem_free(void *_item) +{ + BVHCacheItem *item = (BVHCacheItem *)_item; + + BLI_bvhtree_free(item->tree); + MEM_freeN(item); +} + + +void bvhcache_free(BVHCache *cache) +{ + BLI_linklist_free(*cache, (LinkNodeFreeFP)bvhcacheitem_free); + *cache = NULL; +} + + diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index dd8fd88f76c..c055a0ca6a7 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -41,6 +41,7 @@ #include "DNA_armature_types.h" #include "DNA_constraint_types.h" +#include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_action_types.h" #include "DNA_curve_types.h" @@ -65,6 +66,8 @@ #include "BKE_global.h" #include "BKE_library.h" #include "BKE_idprop.h" +#include "BKE_shrinkwrap.h" +#include "BKE_mesh.h" #ifndef DISABLE_PYTHON #include "BPY_extern.h" @@ -387,7 +390,7 @@ void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4 /* ------------ General Target Matrix Tools ---------- */ /* function that sets the given matrix based on given vertex group in mesh */ -static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4]) +static void contarget_get_mesh_mat (Scene *scene, Object *ob, char *substring, float mat[][4]) { DerivedMesh *dm; Mesh *me= ob->data; @@ -396,6 +399,7 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4]) float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3]; float imat[3][3], tmat[3][3]; int dgroup; + short freeDM = 0; /* initialize target matrix using target matrix */ Mat4CpyMat4(mat, ob->obmat); @@ -408,10 +412,19 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4]) if (em) { /* target is in editmode, so get a special derived mesh */ dm = CDDM_from_editmesh(em, ob->data); + freeDM= 1; } else { - /* when not in EditMode, this should exist */ - dm = (DerivedMesh *)ob->derivedFinal; + /* when not in EditMode, use the 'final' derived mesh + * - check if the custom data masks for derivedFinal mean that we can just use that + * (this is more effficient + sufficient for most cases) + */ + if (ob->lastDataMask != CD_MASK_DERIVEDMESH) { + dm = mesh_get_derived_final(scene, ob, CD_MASK_DERIVEDMESH); + freeDM= 1; + } + else + dm = (DerivedMesh *)ob->derivedFinal; } /* only continue if there's a valid DerivedMesh */ @@ -477,10 +490,10 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4]) } /* free temporary DerivedMesh created (in EditMode case) */ - if (em) { - if (dm) dm->release(dm); + if (dm && freeDM) + dm->release(dm); + if (em) BKE_mesh_end_editmesh(me, em); - } } /* function that sets the given matrix based on given vertex group in lattice */ @@ -542,7 +555,7 @@ static void contarget_get_lattice_mat (Object *ob, char *substring, float mat[][ /* generic function to get the appropriate matrix for most target cases */ /* The cases where the target can be object data have not been implemented */ -static void constraint_target_to_mat4 (Object *ob, char *substring, float mat[][4], short from, short to, float headtail) +static void constraint_target_to_mat4 (Scene *scene, Object *ob, char *substring, float mat[][4], short from, short to, float headtail) { /* Case OBJECT */ if (!strlen(substring)) { @@ -559,7 +572,7 @@ static void constraint_target_to_mat4 (Object *ob, char *substring, float mat[][ * way as constraints can only really affect things on object/bone level. */ else if (ob->type == OB_MESH) { - contarget_get_mesh_mat(ob, substring, mat); + contarget_get_mesh_mat(scene, ob, substring, mat); constraint_mat_convertspace(ob, NULL, mat, from, to); } else if (ob->type == OB_LATTICE) { @@ -641,7 +654,7 @@ static bConstraintTypeInfo CTI_CONSTRNAME = { static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime) { if (VALID_CONS_TARGET(ct)) - constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail); + constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail); else if (ct) Mat4One(ct->matrix); } @@ -1056,7 +1069,7 @@ static void kinematic_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstra bKinematicConstraint *data= con->data; if (VALID_CONS_TARGET(ct)) - constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail); + constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail); else if (ct) { if (data->flag & CONSTRAINT_IK_AUTO) { Object *ob= cob->ob; @@ -1746,7 +1759,7 @@ static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintT /* firstly calculate the matrix the normal way, then let the py-function override * this matrix if it needs to do so */ - constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail); + constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail); /* only execute target calculation if allowed */ #ifndef DISABLE_PYTHON @@ -1853,7 +1866,7 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint Mat4One(ct->matrix); /* get the transform matrix of the target */ - constraint_target_to_mat4(ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail); + constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail); /* determine where in transform range target is */ /* data->type is mapped as follows for backwards compatability: @@ -3108,6 +3121,165 @@ static bConstraintTypeInfo CTI_TRANSFORM = { transform_evaluate /* evaluate */ }; +/* ---------- Shrinkwrap Constraint ----------- */ + +static int shrinkwrap_get_tars (bConstraint *con, ListBase *list) +{ + if (con && list) { + bShrinkwrapConstraint *data = con->data; + bConstraintTarget *ct; + + SINGLETARGETNS_GET_TARS(con, data->target, ct, list) + + return 1; + } + + return 0; +} + + +static void shrinkwrap_flush_tars (bConstraint *con, ListBase *list, short nocopy) +{ + if (con && list) { + bShrinkwrapConstraint *data = con->data; + bConstraintTarget *ct= list->first; + + SINGLETARGETNS_FLUSH_TARS(con, data->target, ct, list, nocopy) + } +} + + +static void shrinkwrap_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime) +{ + bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *) con->data; + + if( VALID_CONS_TARGET(ct) && (ct->tar->type == OB_MESH) ) + { + int fail = FALSE; + float co[3] = {0.0f, 0.0f, 0.0f}; + float no[3] = {0.0f, 0.0f, 0.0f}; + float dist; + + SpaceTransform transform; + DerivedMesh *target = object_get_derived_final(cob->scene, ct->tar, CD_MASK_BAREMESH); + BVHTreeRayHit hit; + BVHTreeNearest nearest; + + BVHTreeFromMesh treeData; + memset( &treeData, 0, sizeof(treeData) ); + + nearest.index = -1; + nearest.dist = FLT_MAX; + + hit.index = -1; + hit.dist = 100000.0f; //TODO should use FLT_MAX.. but normal projection doenst yet supports it + + Mat4One(ct->matrix); + + if(target != NULL) + { + space_transform_from_matrixs(&transform, cob->matrix, ct->tar->obmat); + + switch(scon->shrinkType) + { + case MOD_SHRINKWRAP_NEAREST_SURFACE: + case MOD_SHRINKWRAP_NEAREST_VERTEX: + + if(scon->shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX) + bvhtree_from_mesh_verts(&treeData, target, 0.0, 2, 6); + else + bvhtree_from_mesh_faces(&treeData, target, 0.0, 2, 6); + + if(treeData.tree == NULL) + { + fail = TRUE; + break; + } + + space_transform_apply(&transform, co); + + BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData); + + dist = VecLenf(co, nearest.co); + VecLerpf(co, co, nearest.co, (dist - scon->dist)/dist); /* linear interpolation */ + space_transform_invert(&transform, co); + break; + + case MOD_SHRINKWRAP_PROJECT: + if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS) no[0] = 1.0f; + if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS) no[1] = 1.0f; + if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS) no[2] = 1.0f; + + if(INPR(no,no) < FLT_EPSILON) + { + fail = TRUE; + break; + } + + Normalize(no); + + + bvhtree_from_mesh_faces(&treeData, target, scon->dist, 4, 6); + if(treeData.tree == NULL) + { + fail = TRUE; + break; + } + + if(normal_projection_project_vertex(0, co, no, &transform, treeData.tree, &hit, treeData.raycast_callback, &treeData) == FALSE) + { + fail = TRUE; + break; + } + VECCOPY(co, hit.co); + break; + } + + free_bvhtree_from_mesh(&treeData); + + target->release(target); + + if(fail == TRUE) + { + /* Don't move the point */ + co[0] = co[1] = co[2] = 0.0f; + } + + /* co is in local object coordinates, change it to global and update target position */ + VecMat4MulVecfl(co, cob->matrix, co); + VECCOPY(ct->matrix[3], co); + } + } +} + +static void shrinkwrap_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets) +{ + bConstraintTarget *ct= targets->first; + + /* only evaluate if there is a target */ + if (VALID_CONS_TARGET(ct)) + { + VECCOPY(cob->matrix[3], ct->matrix[3]); + } +} + +static bConstraintTypeInfo CTI_SHRINKWRAP = { + CONSTRAINT_TYPE_SHRINKWRAP, /* type */ + sizeof(bShrinkwrapConstraint), /* size */ + "Shrinkwrap", /* name */ + "bShrinkwrapConstraint", /* struct name */ + NULL, /* free data */ + NULL, /* relink data */ + NULL, /* copy data */ + NULL, /* new data */ + shrinkwrap_get_tars, /* get constraint targets */ + shrinkwrap_flush_tars, /* flush constraint targets */ + shrinkwrap_get_tarmat, /* get a target matrix */ + shrinkwrap_evaluate /* evaluate */ +}; + + + /* ************************* Constraints Type-Info *************************** */ /* All of the constraints api functions use bConstraintTypeInfo structs to carry out * and operations that involve constraint specific code. @@ -3139,6 +3311,7 @@ static void constraints_init_typeinfo () { constraintsTypeInfo[17]= &CTI_RIGIDBODYJOINT; /* RigidBody Constraint */ constraintsTypeInfo[18]= &CTI_CLAMPTO; /* ClampTo Constraint */ constraintsTypeInfo[19]= &CTI_TRANSFORM; /* Transformation Constraint */ + constraintsTypeInfo[20]= &CTI_SHRINKWRAP; /* Shrinkwrap Constraint */ } /* This function should be used for getting the appropriate type-info when only diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 30cb4016061..fab9669d55f 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -591,8 +591,8 @@ static void makecyclicknots(float *knots, short pnts, short order) } -/* type - 0: uniform, 1: endpoints, 2: bezier, note, cyclic nurbs are always uniform */ -void makeknots(Nurb *nu, short uv, short type) + +void makeknots(Nurb *nu, short uv) { if( (nu->type & 7)==CU_NURBS ) { if(uv == 1) { @@ -603,7 +603,7 @@ void makeknots(Nurb *nu, short uv, short type) calcknots(nu->knotsu, nu->pntsu, nu->orderu, 0); /* cyclic should be uniform */ makecyclicknots(nu->knotsu, nu->pntsu, nu->orderu); } else { - calcknots(nu->knotsu, nu->pntsu, nu->orderu, type); + calcknots(nu->knotsu, nu->pntsu, nu->orderu, nu->flagu>>1); } } else nu->knotsu= NULL; @@ -616,7 +616,7 @@ void makeknots(Nurb *nu, short uv, short type) calcknots(nu->knotsv, nu->pntsv, nu->orderv, 0); /* cyclic should be uniform */ makecyclicknots(nu->knotsv, nu->pntsv, nu->orderv); } else { - calcknots(nu->knotsv, nu->pntsv, nu->orderv, type); + calcknots(nu->knotsv, nu->pntsv, nu->orderv, nu->flagv>>1); } } else nu->knotsv= NULL; @@ -1572,8 +1572,8 @@ void makeBevelList(Object *ob) while(nu) { /* check if we will calculate tilt data */ - do_tilt = ((nu->type & CU_2D) && (cu->flag & CU_3D)==0) ? 0 : 1; - do_radius = (do_tilt || cu->bevobj) ? 1 : 0; /* normal display uses the radius, better just to calculate them */ + do_tilt = CU_DO_TILT(cu, nu); + do_radius = CU_DO_RADIUS(cu, nu); /* normal display uses the radius, better just to calculate them */ /* check we are a single point? also check we are not a surface and that the orderu is sane, * enforced in the UI but can go wrong possibly */ @@ -2370,7 +2370,7 @@ void sethandlesNurb(ListBase *editnurb, short code) if(code==1 || code==2) { nu= editnurb->first; while(nu) { - if( (nu->type & 7)==1) { + if( (nu->type & 7)==CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -2400,7 +2400,7 @@ void sethandlesNurb(ListBase *editnurb, short code) } else { /* Toggle */ while(nu) { - if( (nu->type & 7)==1) { + if( (nu->type & 7)==CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { @@ -2417,7 +2417,7 @@ void sethandlesNurb(ListBase *editnurb, short code) } nu= editnurb->first; while(nu) { - if( (nu->type & 7)==1) { + if( (nu->type & 7)==CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 5217464c2c9..077a0c437d4 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -299,24 +299,22 @@ static float wind_func(struct RNG *rng, float strength) return ret; } - +/* maxdist: zero effect from this distance outwards (if usemax) */ +/* mindist: full effect up to this distance (if usemin) */ +/* power: falloff with formula 1/r^power */ static float falloff_func(float fac, int usemin, float mindist, int usemax, float maxdist, float power) { - if(!usemin) - mindist= 0.0f; + /* first quick checks */ + if(usemax && fac > maxdist) + return 0.0f; - if(fac < mindist) { + if(usemin && fac < mindist) return 1.0f; - } - else if(usemax) { - if(fac>maxdist || (maxdist-mindist)<=0.0f) - return 0.0f; - fac= (fac-mindist)/(maxdist-mindist); - return 1.0f - (float)pow((double)fac, (double)power); - } - else - return pow((double)1.0f+fac-mindist, (double)-power); + if(!usemin) + mindist = 0.0; + + return pow((double)1.0+fac-mindist, (double)-power); } static float falloff_func_dist(PartDeflect *pd, float fac) @@ -443,14 +441,11 @@ void do_physical_effector(Scene *scene, Object *ob, float *opco, short type, flo else VecCopyf(mag_vec,vec_to_part); - Normalize(mag_vec); - VecMulf(mag_vec,force_val*falloff); VecSubf(field,field,mag_vec); VecCopyf(mag_vec,velocity); - /* 1.9 is an experimental value to get critical damping at damp=1.0 */ - VecMulf(mag_vec,damp*1.9f*(float)sqrt(force_val)); + VecMulf(mag_vec,damp*2.0f*(float)sqrt(force_val)); VecSubf(field,field,mag_vec); break; case PFIELD_CHARGE: diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 7f062ff5a9b..6578feeeed1 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -6022,6 +6022,80 @@ static void collisionModifier_deformVerts( } + +/* Surface */ + +static void surfaceModifier_initData(ModifierData *md) +{ + SurfaceModifierData *surmd = (SurfaceModifierData*) md; + + surmd->bvhtree = NULL; +} + +static void surfaceModifier_freeData(ModifierData *md) +{ + SurfaceModifierData *surmd = (SurfaceModifierData*) md; + + if (surmd) + { + if(surmd->bvhtree) { + free_bvhtree_from_mesh(surmd->bvhtree); + MEM_freeN(surmd->bvhtree); + } + + surmd->dm->release(surmd->dm); + + surmd->bvhtree = NULL; + surmd->dm = NULL; + } +} + +static int surfaceModifier_dependsOnTime(ModifierData *md) +{ + return 1; +} + +static void surfaceModifier_deformVerts( + ModifierData *md, Object *ob, DerivedMesh *derivedData, + float (*vertexCos)[3], int numVerts) +{ + SurfaceModifierData *surmd = (SurfaceModifierData*) md; + unsigned int numverts = 0, i = 0; + + if(surmd->dm) + surmd->dm->release(surmd->dm); + + /* if possible use/create DerivedMesh */ + if(derivedData) surmd->dm = CDDM_copy(derivedData); + else if(ob->type==OB_MESH) surmd->dm = CDDM_from_mesh(ob->data, ob); + + if(!ob->pd) + { + printf("surfaceModifier_deformVerts: Should not happen!\n"); + return; + } + + if(surmd->dm) + { + CDDM_apply_vert_coords(surmd->dm, vertexCos); + CDDM_calc_normals(surmd->dm); + + numverts = surmd->dm->getNumVerts ( surmd->dm ); + + /* convert to global coordinates */ + for(i = 0; i<numverts; i++) + Mat4MulVecfl(ob->obmat, CDDM_get_vert(surmd->dm, i)->co); + + if(surmd->bvhtree) + free_bvhtree_from_mesh(surmd->bvhtree); + else + surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh"); + + bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6); + } +} + + /* Boolean */ static void booleanModifier_copyData(ModifierData *md, ModifierData *target) @@ -6070,22 +6144,44 @@ static DerivedMesh *booleanModifier_applyModifier( { // XXX doesn't handle derived data BooleanModifierData *bmd = (BooleanModifierData*) md; + DerivedMesh *dm = mesh_get_derived_final(md->scene, bmd->object, CD_MASK_BAREMESH); /* we do a quick sanity check */ - if(((Mesh *)ob->data)->totface > 3 - && bmd->object && ((Mesh *)bmd->object->data)->totface > 3) { - DerivedMesh *result = NewBooleanDerivedMesh(bmd->object, ob, + if(dm && (derivedData->getNumFaces(derivedData) > 3) + && bmd->object && dm->getNumFaces(dm) > 3) { + DerivedMesh *result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob, 1 + bmd->operation); + if(dm) + dm->release(dm); + /* if new mesh returned, return it; otherwise there was * an error, so delete the modifier object */ if(result) return result; else bmd->object = NULL; - } + } + + if(dm) + dm->release(dm); - return derivedData; + return derivedData; +} + +CustomDataMask booleanModifier_requiredDataMask(ModifierData *md) +{ + CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE); + + dataMask |= (1 << CD_MDEFORMVERT); + + /* particles only need this if they are after a non deform modifier, and + * the modifier stack will only create them in that case. */ +// dataMask |= CD_MASK_ORIGSPACE; + +// dataMask |= CD_MASK_ORCO; + + return dataMask; } /* Particles */ @@ -6379,6 +6475,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier( if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)){ float min_r[3], max_r[3]; + INIT_MINMAX(min_r, max_r); dm->getMinMax(dm, min_r, max_r); min_co=min_r[track]; max_co=max_r[track]; @@ -7189,7 +7286,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, pa= pars+i; /* get particle state */ - psys_particle_on_emitter(psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0); + psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc0,nor,0,0,0,0); Mat4MulVecfl(ob->obmat,loc0); state.time=cfra; @@ -7245,7 +7342,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, *mf = source; - test_index_face(mf, &explode->faceData, i, (mf->v4 ? 4 : 3)); + test_index_face(mf, &explode->faceData, i, (orig_v4 ? 4 : 3)); } MEM_printmemlist_stats(); @@ -8268,16 +8365,24 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->deformVerts = collisionModifier_deformVerts; // mti->copyData = collisionModifier_copyData; + mti = INIT_TYPE(Surface); + mti->type = eModifierTypeType_OnlyDeform; + mti->initData = surfaceModifier_initData; + mti->flags = eModifierTypeFlag_AcceptsMesh; + mti->dependsOnTime = surfaceModifier_dependsOnTime; + mti->freeData = surfaceModifier_freeData; + mti->deformVerts = surfaceModifier_deformVerts; + mti = INIT_TYPE(Boolean); mti->type = eModifierTypeType_Nonconstructive; mti->flags = eModifierTypeFlag_AcceptsMesh - | eModifierTypeFlag_RequiresOriginalData | eModifierTypeFlag_UsesPointCache; mti->copyData = booleanModifier_copyData; mti->isDisabled = booleanModifier_isDisabled; mti->applyModifier = booleanModifier_applyModifier; mti->foreachObjectLink = booleanModifier_foreachObjectLink; mti->updateDepgraph = booleanModifier_updateDepgraph; + mti->requiredDataMask = booleanModifier_requiredDataMask; mti = INIT_TYPE(MeshDeform); mti->type = eModifierTypeType_OnlyDeform; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 1acad4e9e86..941e73982a5 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1739,7 +1739,8 @@ void ntreeSolveOrder(bNodeTree *ntree) might be different for editor or for "real" use... */ } -/* should be callback! */ +/* Should be callback! */ +/* Do not call execs here */ void NodeTagChanged(bNodeTree *ntree, bNode *node) { if(ntree->type==NTREE_COMPOSIT) { @@ -1753,8 +1754,6 @@ void NodeTagChanged(bNodeTree *ntree, bNode *node) } node->need_exec= 1; } - else if(ntree->type == NTREE_TEXTURE) - ntreeTexUpdatePreviews(ntree); } void NodeTagIDChanged(bNodeTree *ntree, ID *id) @@ -2067,6 +2066,11 @@ void ntreeBeginExecTree(bNodeTree *ntree) /* tag used outputs, so we know when we can skip operations */ for(node= ntree->nodes.first; node; node= node->next) { bNodeSocket *sock; + + /* composite has own need_exec tag handling */ + if(ntree->type!=NTREE_COMPOSIT) + node->need_exec= 1; + for(sock= node->inputs.first; sock; sock= sock->next) { if(sock->link) { ns= ntree->stack + sock->link->fromsock->stack_index; @@ -2075,9 +2079,22 @@ void ntreeBeginExecTree(bNodeTree *ntree) } else sock->ns.sockettype= sock->type; + + if(sock->link) { + bNodeLink *link= sock->link; + /* this is the test for a cyclic case */ + if(link->fromnode && link->tonode) { + if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF); + else { + node->need_exec= 0; + } + } + } } + if(node->type==NODE_GROUP && node->id) group_tag_used_outputs(node, ntree->stack); + } if(ntree->type==NTREE_COMPOSIT) @@ -2160,13 +2177,15 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread) } for(node= ntree->nodes.first; node; node= node->next) { - if(node->typeinfo->execfunc) { - node_get_stack(node, stack, nsin, nsout); - node->typeinfo->execfunc(callerdata, node, nsin, nsout); - } - else if(node->type==NODE_GROUP && node->id) { - node_get_stack(node, stack, nsin, nsout); - node_group_execute(stack, callerdata, node, nsin, nsout); + if(node->need_exec) { + if(node->typeinfo->execfunc) { + node_get_stack(node, stack, nsin, nsout); + node->typeinfo->execfunc(callerdata, node, nsin, nsout); + } + else if(node->type==NODE_GROUP && node->id) { + node_get_stack(node, stack, nsin, nsout); + node_group_execute(stack, callerdata, node, nsin, nsout); + } } } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 2b1dcc782c6..7d998a481f6 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1,7 +1,7 @@ /* particle.c * * - * $Id: particle.c $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -1460,7 +1460,7 @@ static void do_prekink(ParticleKey *state, ParticleKey *par, float *par_rot, flo case PART_KINK_WAVE: vec[axis]=1.0; if(obmat) - Mat4MulVecfl(obmat,vec); + Mat4Mul3Vecfl(obmat,vec); if(par_rot) QuatMulVecf(par_rot,vec); @@ -1806,10 +1806,13 @@ void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSys int from=PART_FROM_FACE; totparent=(int)(totchild*part->parents*0.3); + if(G.rendering && part->child_nbr && part->ren_child_nbr) + totparent*=(float)part->child_nbr/(float)part->ren_child_nbr; + tree=BLI_kdtree_new(totparent); for(p=0,cpa=psys->child; p<totparent; p++,cpa++){ - psys_particle_on_emitter(psmd,from,cpa->num,-1,cpa->fuv,cpa->foffset,co,0,0,0,orco,0); + psys_particle_on_emitter(psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0); BLI_kdtree_insert(tree, p, orco, NULL); } @@ -1873,6 +1876,10 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ totparent=(int)(totchild*part->parents*0.3); + + if(G.rendering && part->child_nbr && part->ren_child_nbr) + totparent*=(float)part->child_nbr/(float)part->ren_child_nbr; + /* part->parents could still be 0 so we can't test with totparent */ between=1; } @@ -1905,6 +1912,7 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in ctx->steps= steps; ctx->totchild= totchild; ctx->totparent= totparent; + ctx->parent_pass= 0; ctx->cfra= cfra; psys->lattice = psys_get_lattice(scene, ob, psys); @@ -1944,14 +1952,14 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *state, *par = NULL, *key[4]; ParticleData *pa=NULL; ParticleTexture ptex; - float *cpa_fuv=0; + float *cpa_fuv=0, *par_rot=0; float co[3], orco[3], ornor[3], t, rough_t, cpa_1st[3], dvec[3]; float branch_begin, branch_end, branch_prob, branchfac, rough_rand; float pa_rough1, pa_rough2, pa_roughe; float length, pa_length, pa_clump, pa_kink, pa_effector; float max_length = 1.0f, cur_length = 0.0f; float eff_length, eff_vec[3]; - int k, cpa_num, guided=0; + int k, cpa_num, guided = 0; short cpa_from; if(part->flag & PART_BRANCHING) { @@ -2055,9 +2063,10 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ptex.clump=1.0; ptex.kink=1.0; ptex.rough= 1.0; + ptex.exist= 1.0; get_cpa_texture(ctx->dm,ctx->ma,cpa_num,cpa_fuv,orco,&ptex, - MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH); + MAP_PA_DENS|MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH); pa_length=ptex.length; pa_clump=ptex.clump; @@ -2067,6 +2076,11 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, pa_roughe=ptex.rough; pa_effector= 1.0f; + if(ptex.exist < cpa->rand[1]) { + keys->steps = -1; + return; + } + if(ctx->vg_length) pa_length*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_length); if(ctx->vg_clump) @@ -2137,15 +2151,16 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, t=(float)k/(float)ctx->steps; if(ctx->totparent){ - if(i>=ctx->totparent) - /* this is not threadsafe, but should only happen for - * branching particles particles, which are not threaded */ + if(i>=ctx->totparent) { + /* this is now threadsafe, virtual parents are calculated before rest of children */ par = cache[cpa->parent] + k; + } else par=0; } else if(cpa->parent>=0){ par=pcache[cpa->parent]+k; + par_rot = par->rot; } /* apply different deformations to the child path */ @@ -2155,7 +2170,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, if(guided==0){ if(part->kink) - do_prekink((ParticleKey*)state, (ParticleKey*)par, par->rot, t, + do_prekink((ParticleKey*)state, (ParticleKey*)par, par_rot, t, part->kink_freq * pa_kink, part->kink_shape, part->kink_amp, part->kink, part->kink_axis, ob->obmat); do_clump((ParticleKey*)state, (ParticleKey*)par, t, part->clumpfac, part->clumppow, pa_clump); @@ -2254,10 +2269,15 @@ static void *exec_child_path_cache(void *data) ParticleSystem *psys= ctx->psys; ParticleCacheKey **cache= psys->childcache; ChildParticle *cpa; - int i, totchild= ctx->totchild; + int i, totchild= ctx->totchild, first= 0; + + if(thread->tot > 1){ + first= ctx->parent_pass? 0 : ctx->totparent; + totchild= ctx->parent_pass? ctx->totparent : ctx->totchild; + } - cpa= psys->child + thread->num; - for(i=thread->num; i<totchild; i+=thread->tot, cpa+=thread->tot) + cpa= psys->child + first + thread->num; + for(i=first+thread->num; i<totchild; i+=thread->tot, cpa+=thread->tot) psys_thread_create_path(thread, cpa, cache[i], i); return 0; @@ -2296,6 +2316,22 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa totthread= pthreads[0].tot; if(totthread > 1) { + + /* make virtual child parents thread safe by calculating them first */ + if(totparent) { + BLI_init_threads(&threads, exec_child_path_cache, totthread); + + for(i=0; i<totthread; i++) { + pthreads[i].ctx->parent_pass = 1; + BLI_insert_thread(&threads, &pthreads[i]); + } + + BLI_end_threads(&threads); + + for(i=0; i<totthread; i++) + pthreads[i].ctx->parent_pass = 0; + } + BLI_init_threads(&threads, exec_child_path_cache, totthread); for(i=0; i<totthread; i++) @@ -3171,6 +3207,8 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float ptex->kink= texture_value_blend(def,ptex->kink,value,var,blend,neg & MAP_PA_KINK); if((event & mtex->pmapto) & MAP_PA_ROUGH) ptex->rough= texture_value_blend(def,ptex->rough,value,var,blend,neg & MAP_PA_ROUGH); + if((event & mtex->pmapto) & MAP_PA_DENS) + ptex->exist= texture_value_blend(def,ptex->exist,value,var,blend,neg & MAP_PA_DENS); } } if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); } @@ -3178,6 +3216,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float if(event & MAP_PA_CLUMP) { CLAMP(ptex->clump,0.0,1.0); } if(event & MAP_PA_KINK) { CLAMP(ptex->kink,0.0,1.0); } if(event & MAP_PA_ROUGH) { CLAMP(ptex->rough,0.0,1.0); } + if(event & MAP_PA_DENS) { CLAMP(ptex->exist,0.0,1.0); } } void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleData *pa, ParticleTexture *ptex, int event) { @@ -3496,6 +3535,10 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ totparent=(int)(totchild*part->parents*0.3); + + if(G.rendering && part->child_nbr && part->ren_child_nbr) + totparent*=(float)part->child_nbr/(float)part->ren_child_nbr; + /* part->parents could still be 0 so we can't test with totparent */ between=1; } @@ -3872,3 +3915,76 @@ void psys_get_dupli_path_transform(Object *ob, ParticleSystem *psys, ParticleSys *scale= len; } +void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]) +{ + float onevec[3] = {0.0f,0.0f,0.0f}, tvec[3], tvec2[3]; + + xvec[0] = 1.0f; xvec[1] = 0.0f; xvec[2] = 0.0f; + yvec[0] = 0.0f; yvec[1] = 1.0f; yvec[2] = 0.0f; + + if(bb->align < PART_BB_VIEW) + onevec[bb->align]=1.0f; + + if(bb->lock && (bb->align == PART_BB_VIEW)) { + VECCOPY(xvec, bb->ob->obmat[0]); + Normalize(xvec); + + VECCOPY(yvec, bb->ob->obmat[1]); + Normalize(yvec); + + VECCOPY(zvec, bb->ob->obmat[2]); + Normalize(zvec); + } + else if(bb->align == PART_BB_VEL) { + float temp[3]; + + VECCOPY(temp, bb->vel); + Normalize(temp); + + VECSUB(zvec, bb->ob->obmat[3], bb->vec); + + if(bb->lock) { + float fac = -Inpf(zvec, temp); + + VECADDFAC(zvec, zvec, temp, fac); + } + Normalize(zvec); + + Crossf(xvec,temp,zvec); + Normalize(xvec); + + Crossf(yvec,zvec,xvec); + } + else { + VECSUB(zvec, bb->ob->obmat[3], bb->vec); + if(bb->lock) + zvec[bb->align] = 0.0f; + Normalize(zvec); + + if(bb->align < PART_BB_VIEW) + Crossf(xvec, onevec, zvec); + else + Crossf(xvec, bb->ob->obmat[1], zvec); + Normalize(xvec); + + Crossf(yvec,zvec,xvec); + } + + VECCOPY(tvec, xvec); + VECCOPY(tvec2, yvec); + + VecMulf(xvec, cos(bb->tilt * (float)M_PI)); + VecMulf(tvec2, sin(bb->tilt * (float)M_PI)); + VECADD(xvec, xvec, tvec2); + + VecMulf(yvec, cos(bb->tilt * (float)M_PI)); + VecMulf(tvec, -sin(bb->tilt * (float)M_PI)); + VECADD(yvec, yvec, tvec); + + VecMulf(xvec, bb->size); + VecMulf(yvec, bb->size); + + VECADDFAC(center, bb->vec, xvec, bb->offset[0]); + VECADDFAC(center, center, yvec, bb->offset[1]); +} + diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 928730fb1f0..f8b1852b728 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -1,7 +1,7 @@ /* particle_system.c * * - * $Id: particle_system.c $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -75,6 +75,7 @@ #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_scene.h" +#include "BKE_bvhutils.h" #include "PIL_time.h" @@ -1294,7 +1295,8 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive MEM_freeN(sum); /* for hair, sort by origindex, allows optimizations in rendering */ - if(part->type == PART_HAIR) { + /* however with virtual parents the children need to be in random order */ + if(part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents!=0.0)) { COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX); if(COMPARE_ORIG_INDEX) qsort(index, totpart, sizeof(int), compare_orig_index); @@ -1611,7 +1613,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps NormalQuat(pa->r_rot); - if(part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){ + if(part->type!=PART_HAIR && part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){ /* any unique random number will do (r_ave[0]) */ if(ptex.exist < 0.5*(1.0+pa->r_ave[0])) pa->flag |= PARS_UNEXIST; @@ -1733,6 +1735,8 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic VECSUB(p_vel,pa->r_ve,p_vel); Normalize(p_vel); VecMulf(p_vel,speed); + + VECCOPY(pa->fuv,loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */ } else{ /* get precise emitter matrix if particle is born */ @@ -2447,7 +2451,6 @@ void psys_end_effectors(ParticleSystem *psys) if(ec->rng) rng_free(ec->rng); - } BLI_freelistN(lb); @@ -2486,7 +2489,12 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations"); for(p=0,pa=psys->particles; p<totpart; p++, pa++){ - psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0); + if(part->from == PART_FROM_PARTICLE) { + VECCOPY(loc, pa->fuv); + } + else + psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0); + Mat4MulVecfl(ob->obmat,loc); ec->distances[p]=VecLenf(loc,vec); VECSUB(loc,loc,vec); @@ -2539,6 +2547,7 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene, ParticleData *epa; ParticleKey estate; PartDeflect *pd; + SurfaceModifierData *surmd = NULL; ListBase *lb=&psys->effectors; ParticleEffectorCache *ec; float distance, vec_to_part[3]; @@ -2566,8 +2575,34 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene, if(psys->part->type!=PART_HAIR && psys->part->integrator) where_is_object_time(scene, eob,cfra); - /* use center of object for distance calculus */ - VecSubf(vec_to_part, state->co, eob->obmat[3]); + if(pd && pd->flag&PFIELD_SURFACE) { + surmd = (SurfaceModifierData *)modifiers_findByType ( eob, eModifierType_Surface ); + } + if(surmd) { + /* closest point in the object surface is an effector */ + BVHTreeNearest nearest; + float velocity[3]; + + nearest.index = -1; + nearest.dist = FLT_MAX; + + /* using velocity corrected location allows for easier sliding over effector surface */ + VecCopyf(velocity, state->vel); + VecMulf(velocity, psys_get_timestep(psys->part)); + VecAddf(vec_to_part, state->co, velocity); + + BLI_bvhtree_find_nearest(surmd->bvhtree->tree, vec_to_part, &nearest, surmd->bvhtree->nearest_callback, surmd->bvhtree); + + if(nearest.index != -1) { + VecSubf(vec_to_part, state->co, nearest.co); + } + else + vec_to_part[0] = vec_to_part[1] = vec_to_part[2] = 0.0f; + } + else + /* use center of object for distance calculus */ + VecSubf(vec_to_part, state->co, eob->obmat[3]); + distance = VecLength(vec_to_part); falloff=effector_falloff(pd,eob->obmat[2],vec_to_part); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 22f26741c55..5c936c3ab39 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -243,6 +243,11 @@ Scene *add_scene(char *name) sce->r.threads= 1; sce->r.stereomode = 1; // no stereo + sce->r.domeangle = 180; + sce->r.domemode = 1; + sce->r.domesize = 1.0f; + sce->r.domeres = 4; + sce->r.domeresbuf = 1.0f; sce->r.simplify_subsurf= 6; sce->r.simplify_particles= 1.0f; @@ -708,3 +713,14 @@ float get_render_aosss_error(RenderData *r, float error) return error; } +void free_dome_warp_text(struct Text *txt) +{ + Scene *scene; + + scene = G.main->scene.first; + while(scene) { + if (scene->r.dometext == txt) + scene->r.dometext = NULL; + scene = scene->id.next; + } +}
\ No newline at end of file diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 0d9a6a7bc48..8bf56f136bc 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -38,6 +38,7 @@ #include "DNA_modifier_types.h" #include "DNA_meshdata_types.h" #include "DNA_mesh_types.h" +#include "DNA_scene_types.h" #include "BKE_shrinkwrap.h" #include "BKE_DerivedMesh.h" @@ -47,6 +48,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_displist.h" #include "BKE_global.h" +#include "BKE_mesh.h" #include "BKE_subsurf.h" #include "BLI_arithb.h" @@ -93,7 +95,7 @@ typedef void ( *Shrinkwrap_ForeachVertexCallback) (DerivedMesh *target, float *c /* get derived mesh */ //TODO is anyfunction that does this? returning the derivedFinal witouth we caring if its in edit mode or not? -static DerivedMesh *object_get_derived_final(struct Scene *scene, Object *ob, CustomDataMask dataMask) +DerivedMesh *object_get_derived_final(struct Scene *scene, Object *ob, CustomDataMask dataMask) { Mesh *me= ob->data; EditMesh *em = BKE_mesh_get_editmesh(me); @@ -151,7 +153,6 @@ static float squared_dist(const float *a, const float *b) return INPR(tmp, tmp); } - /* * Shrinkwrap to the nearest vertex * @@ -186,8 +187,17 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) float weight = vertexgroup_get_vertex_weight(calc->dvert, i, calc->vgroup); if(weight == 0.0f) continue; - VECCOPY(tmp_co, co); - space_transform_apply(&calc->local2target, tmp_co); //Convert the coordinates to the tree coordinates + + //Convert the vertex to tree coordinates + if(calc->vert) + { + VECCOPY(tmp_co, calc->vert[i].co); + } + else + { + VECCOPY(tmp_co, co); + } + space_transform_apply(&calc->local2target, tmp_co); //Use local proximity heuristics (to reduce the nearest search) // @@ -290,174 +300,117 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, struct S int i; //Options about projection direction - const char use_normal = calc->smd->shrinkOpts; - float proj_axis[3] = {0.0f, 0.0f, 0.0f}; - MVert *vert = NULL; //Needed in case of vertex normal - DerivedMesh* ss_mesh = NULL; + const char use_normal = calc->smd->shrinkOpts; + float proj_axis[3] = {0.0f, 0.0f, 0.0f}; //Raycast and tree stuff BVHTreeRayHit hit; - BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh; //target + BVHTreeFromMesh treeData= NULL_BVHTreeFromMesh; //auxiliar target - DerivedMesh * aux_mesh = NULL; - BVHTreeFromMesh auxData= NULL_BVHTreeFromMesh; + DerivedMesh *auxMesh = NULL; + BVHTreeFromMesh auxData = NULL_BVHTreeFromMesh; SpaceTransform local2aux; -do -{ + //If the user doesn't allows to project in any direction of projection axis + //then theres nothing todo. + if((use_normal & (MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR | MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR)) == 0) + return; + //Prepare data to retrieve the direction in which we should project each vertex if(calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) { - //No Mvert information: jump to "free memory and return" part - if(calc->original == NULL) break; - - if(calc->smd->subsurfLevels) - { - SubsurfModifierData smd; - memset(&smd, 0, sizeof(smd)); - smd.subdivType = ME_CC_SUBSURF; //catmull clark - smd.levels = calc->smd->subsurfLevels; //levels - - ss_mesh = subsurf_make_derived_from_derived(calc->original, &smd, FALSE, NULL, 0, 0); - - if(ss_mesh) - { - vert = ss_mesh->getVertDataArray(ss_mesh, CD_MVERT); - if(vert) - { - //TRICKY: this code assumes subsurface will have the transformed original vertices - //in their original order at the end of the vert array. - vert = vert - + ss_mesh->getNumVerts(ss_mesh) - - calc->original->getNumVerts(calc->original); - } - } - - //To make sure we are not letting any memory behind - assert(smd.emCache == NULL); - assert(smd.mCache == NULL); - } - else - vert = calc->original->getVertDataArray(calc->original, CD_MVERT); - - //Not able to get vert information: jump to "free memory and return" part - if(vert == NULL) break; + if(calc->vert == NULL) return; } else { - //The code supports any axis that is a combination of X,Y,Z.. altought currently UI only allows to set the 3 diferent axis + //The code supports any axis that is a combination of X,Y,Z + //altought currently UI only allows to set the 3 diferent axis if(calc->smd->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS) proj_axis[0] = 1.0f; if(calc->smd->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS) proj_axis[1] = 1.0f; if(calc->smd->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS) proj_axis[2] = 1.0f; Normalize(proj_axis); - //Invalid projection direction: jump to "free memory and return" part - if(INPR(proj_axis, proj_axis) < FLT_EPSILON) break; + //Invalid projection direction + if(INPR(proj_axis, proj_axis) < FLT_EPSILON) + return; } - //If the user doesn't allows to project in any direction of projection axis... then theres nothing todo. - if((use_normal & (MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR | MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR)) == 0) - break; //jump to "free memory and return" part - - - //Build target tree - BENCH(bvhtree_from_mesh_faces(&treeData, calc->target, calc->keepDist, 4, 6)); - if(treeData.tree == NULL) - break; //jump to "free memory and return" part - - - //Build auxiliar target if(calc->smd->auxTarget) { + auxMesh = object_get_derived_final(scene, calc->smd->auxTarget, CD_MASK_BAREMESH); space_transform_setup( &local2aux, calc->ob, calc->smd->auxTarget); - - aux_mesh = CDDM_copy( object_get_derived_final(scene, calc->smd->auxTarget, CD_MASK_BAREMESH) ); //TODO currently we need a copy in case object_get_derived_final returns an emDM that does not defines getVertArray or getFace array - if(aux_mesh) - BENCH(bvhtree_from_mesh_faces(&auxData, aux_mesh, 0.0, 4, 6)); - else - printf("Auxiliar target finalDerived mesh is null\n"); } + //After sucessufuly build the trees, start projection vertexs + if( bvhtree_from_mesh_faces(&treeData, calc->target, calc->keepDist, 4, 6) + && (auxMesh == NULL || bvhtree_from_mesh_faces(&auxData, auxMesh, 0.0, 4, 6))) + { - //Now, everything is ready to project the vertexs! #ifndef __APPLE__ #pragma omp parallel for private(i,hit) schedule(static) #endif - for(i = 0; i<calc->numVerts; ++i) - { - float *co = calc->vertexCos[i]; - float tmp_co[3], tmp_no[3]; - float lim = 10000.0f; //TODO: we should use FLT_MAX here, but sweepsphere code isnt prepared for that - float weight = vertexgroup_get_vertex_weight(calc->dvert, i, calc->vgroup); - - if(weight == 0.0f) continue; - - if(ss_mesh) - { - VECCOPY(tmp_co, vert[i].co); - } - else + for(i = 0; i<calc->numVerts; ++i) { - VECCOPY(tmp_co, co); - } + float *co = calc->vertexCos[i]; + float tmp_co[3], tmp_no[3]; + float weight = vertexgroup_get_vertex_weight(calc->dvert, i, calc->vgroup); + if(weight == 0.0f) continue; - if(vert) - NormalShortToFloat(tmp_no, vert[i].no); - else - VECCOPY( tmp_no, proj_axis ); - + if(calc->vert) + { + VECCOPY(tmp_co, calc->vert[i].co); + if(calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) + NormalShortToFloat(tmp_no, calc->vert[i].no); + else + VECCOPY(tmp_no, proj_axis); + } + else + { + VECCOPY(tmp_co, co); + VECCOPY(tmp_no, proj_axis); + } - hit.index = -1; - hit.dist = lim; + hit.index = -1; + hit.dist = 10000.0f; //TODO: we should use FLT_MAX here, but sweepsphere code isnt prepared for that - //Project over positive direction of axis - if(use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR) - { + //Project over positive direction of axis + if(use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR) + { - if(auxData.tree) - normal_projection_project_vertex(0, tmp_co, tmp_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData); + if(auxData.tree) + normal_projection_project_vertex(0, tmp_co, tmp_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData); - normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, tmp_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData); - } + normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, tmp_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData); + } - //Project over negative direction of axis - if(use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR) - { - float inv_no[3] = { -tmp_no[0], -tmp_no[1], -tmp_no[2] }; + //Project over negative direction of axis + if(use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR) + { + float inv_no[3] = { -tmp_no[0], -tmp_no[1], -tmp_no[2] }; - if(auxData.tree) - normal_projection_project_vertex(0, tmp_co, inv_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData); + if(auxData.tree) + normal_projection_project_vertex(0, tmp_co, inv_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData); - normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, inv_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData); - } + normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, inv_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData); + } - if(hit.index != -1) - { - VecLerpf(co, co, hit.co, weight); + if(hit.index != -1) + { + VecLerpf(co, co, hit.co, weight); + } } } - -//Simple do{} while(0) structure to allow to easily jump to the "free memory and return" part -} while(0); - //free data structures - free_bvhtree_from_mesh(&treeData); free_bvhtree_from_mesh(&auxData); - - if(aux_mesh) - aux_mesh->release(aux_mesh); - - if(ss_mesh) - ss_mesh->release(ss_mesh); } /* @@ -473,8 +426,6 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh; BVHTreeNearest nearest = NULL_BVHTreeNearest; - - //Create a bvh-tree of the given target BENCH(bvhtree_from_mesh_faces( &treeData, calc->target, 0.0, 2, 6)); if(treeData.tree == NULL) @@ -500,7 +451,14 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) if(weight == 0.0f) continue; //Convert the vertex to tree coordinates - VECCOPY(tmp_co, co); + if(calc->vert) + { + VECCOPY(tmp_co, calc->vert[i].co); + } + else + { + VECCOPY(tmp_co, co); + } space_transform_apply(&calc->local2target, tmp_co); //Use local proximity heuristics (to reduce the nearest search) @@ -539,53 +497,89 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) } } - free_bvhtree_from_mesh(&treeData); } /* Main shrinkwrap function */ -void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, struct Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) +void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { - + + DerivedMesh *ss_mesh = NULL; ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData; - + //remove loop dependencies on derived meshs (TODO should this be done elsewhere?) if(smd->target == ob) smd->target = NULL; if(smd->auxTarget == ob) smd->auxTarget = NULL; - - + + //Configure Shrinkwrap calc data calc.smd = smd; calc.ob = ob; - calc.original = dm; calc.numVerts = numVerts; calc.vertexCos = vertexCos; - + //DeformVertex calc.vgroup = get_named_vertexgroup_num(calc.ob, calc.smd->vgroup_name); - if(calc.original) + if(dm) { - calc.dvert = calc.original->getVertDataArray(calc.original, CD_MDEFORMVERT); + calc.dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); } else if(calc.ob->type == OB_LATTICE) { calc.dvert = lattice_get_deform_verts(calc.ob); } - - + + if(smd->target) { - //TODO currently we need a copy in case object_get_derived_final returns an emDM that does not defines getVertArray or getFace array - calc.target = CDDM_copy( object_get_derived_final(scene, smd->target, CD_MASK_BAREMESH) ); - - //TODO there might be several "bugs" on non-uniform scales matrixs.. because it will no longer be nearest surface, not sphere projection + calc.target = object_get_derived_final(scene, smd->target, CD_MASK_BAREMESH); + + //TODO there might be several "bugs" on non-uniform scales matrixs + //because it will no longer be nearest surface, not sphere projection //because space has been deformed space_transform_setup(&calc.local2target, ob, smd->target); - - calc.keepDist = smd->keepDist; //TODO: smd->keepDist is in global units.. must change to local + + //TODO: smd->keepDist is in global units.. must change to local + calc.keepDist = smd->keepDist; + } + + + + calc.vgroup = get_named_vertexgroup_num(calc.ob, smd->vgroup_name); + + if(dm != NULL) + { + //Setup arrays to get vertexs positions, normals and deform weights + calc.vert = dm->getVertDataArray(dm, CD_MVERT); + calc.dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + + //Using vertexs positions/normals as if a subsurface was applied + if(smd->subsurfLevels) + { + SubsurfModifierData ssmd; + memset(&ssmd, 0, sizeof(ssmd)); + ssmd.subdivType = ME_CC_SUBSURF; //catmull clark + ssmd.levels = smd->subsurfLevels; //levels + + ss_mesh = subsurf_make_derived_from_derived(dm, &ssmd, FALSE, NULL, 0, 0); + + if(ss_mesh) + { + calc.vert = ss_mesh->getVertDataArray(ss_mesh, CD_MVERT); + if(calc.vert) + { + //TRICKY: this code assumes subsurface will have the transformed original vertices + //in their original order at the end of the vert array. + calc.vert = calc.vert + ss_mesh->getNumVerts(ss_mesh) - dm->getNumVerts(dm); + } + } + + //Just to make sure we are not letting any memory behind + assert(ssmd.emCache == NULL); + assert(ssmd.mCache == NULL); + } } - - + //Projecting target defined - lets work! if(calc.target) { @@ -593,20 +587,20 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, struct Scene *scene, { case MOD_SHRINKWRAP_NEAREST_SURFACE: BENCH(shrinkwrap_calc_nearest_surface_point(&calc)); - break; - + break; + case MOD_SHRINKWRAP_PROJECT: BENCH(shrinkwrap_calc_normal_projection(&calc, scene)); - break; - + break; + case MOD_SHRINKWRAP_NEAREST_VERTEX: BENCH(shrinkwrap_calc_nearest_vertex(&calc)); - break; + break; } } - + //free memory - if(calc.target) - calc.target->release( calc.target ); + if(ss_mesh) + ss_mesh->release(ss_mesh); } diff --git a/source/blender/blenkernel/intern/suggestions.c b/source/blender/blenkernel/intern/suggestions.c index 6530909336c..dee33656332 100644 --- a/source/blender/blenkernel/intern/suggestions.c +++ b/source/blender/blenkernel/intern/suggestions.c @@ -1,5 +1,5 @@ /** - * $Id: $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 7278460c61c..8bad269a85e 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -107,6 +107,8 @@ World *add_world(char *name) wrld->ao_approx_error= 0.25f; wrld->physicsEngine= WOPHY_BULLET;//WOPHY_SUMO; Bullet by default + wrld->mode = WO_DBVT_CULLING; // DBVT culling by default + wrld->occlusionRes = 128; wrld->preview = NULL; return wrld; diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 8fd2426a1b6..472a6612a50 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -29,11 +29,11 @@ #include <stdlib.h> -#include <ffmpeg/avformat.h> -#include <ffmpeg/avcodec.h> -#include <ffmpeg/rational.h> -#include <ffmpeg/swscale.h> -#include <ffmpeg/opt.h> +#include <libavformat/avformat.h> +#include <libavcodec/avcodec.h> +#include <libavutil/rational.h> +#include <libswscale/swscale.h> +#include <libavcodec/opt.h> #if LIBAVFORMAT_VERSION_INT < (49 << 16) #define FFMPEG_OLD_FRAME_RATE 1 @@ -284,8 +284,8 @@ static AVFrame* generate_video_frame(uint8_t* pixels) int height = c->height; AVFrame* rgb_frame; - if (c->pix_fmt != PIX_FMT_RGBA32) { - rgb_frame = alloc_picture(PIX_FMT_RGBA32, width, height); + if (c->pix_fmt != PIX_FMT_BGR32) { + rgb_frame = alloc_picture(PIX_FMT_BGR32, width, height); if (!rgb_frame) { G.afbreek=1; //XXX error("Couldn't allocate temporary frame"); @@ -309,9 +309,9 @@ static AVFrame* generate_video_frame(uint8_t* pixels) uint8_t* end = src + width * 4; while (src != end) { target[3] = src[3]; - target[2] = src[0]; + target[2] = src[2]; target[1] = src[1]; - target[0] = src[2]; + target[0] = src[0]; target += 4; src += 4; @@ -325,9 +325,9 @@ static AVFrame* generate_video_frame(uint8_t* pixels) uint8_t* src = rendered_frame + width * 4 * y; uint8_t* end = src + width * 4; while (src != end) { - target[3] = src[2]; + target[3] = src[0]; target[2] = src[1]; - target[1] = src[0]; + target[1] = src[2]; target[0] = src[3]; target += 4; @@ -336,7 +336,7 @@ static AVFrame* generate_video_frame(uint8_t* pixels) } } - if (c->pix_fmt != PIX_FMT_RGBA32) { + if (c->pix_fmt != PIX_FMT_BGR32) { sws_scale(img_convert_ctx, rgb_frame->data, rgb_frame->linesize, 0, c->height, current_frame->data, current_frame->linesize); @@ -492,9 +492,11 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex c->pix_fmt = PIX_FMT_YUV420P; } - if (!strcmp(of->oformat->name, "mp4") || - !strcmp(of->oformat->name, "mov") || - !strcmp(of->oformat->name, "3gp")) { + if ((of->oformat->flags & AVFMT_GLOBALHEADER) +// || !strcmp(of->oformat->name, "mp4") +// || !strcmp(of->oformat->name, "mov") +// || !strcmp(of->oformat->name, "3gp") + ) { fprintf(stderr, "Using global header\n"); c->flags |= CODEC_FLAG_GLOBAL_HEADER; } @@ -508,7 +510,7 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex /* xasp & yasp got float lately... */ - c->sample_aspect_ratio = av_d2q( + st->sample_aspect_ratio = c->sample_aspect_ratio = av_d2q( ((double) rd->xasp / (double) rd->yasp), 255); set_ffmpeg_properties(rd, c, "video"); @@ -526,7 +528,7 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex current_frame = alloc_picture(c->pix_fmt, c->width, c->height); img_convert_ctx = sws_getContext(c->width, c->height, - PIX_FMT_RGBA32, + PIX_FMT_BGR32, c->width, c->height, c->pix_fmt, SWS_BICUBIC, diff --git a/source/blender/blenlib/BLI_noise.h b/source/blender/blenlib/BLI_noise.h index f419746bc13..9f72c5e7b54 100644 --- a/source/blender/blenlib/BLI_noise.h +++ b/source/blender/blenlib/BLI_noise.h @@ -26,7 +26,6 @@ * * ***** END GPL LICENSE BLOCK ***** * - * $Id: $ */ #ifndef BLI_NOISE_H diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index 1bae821ae55..c7026b21494 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -26,7 +26,6 @@ * * ***** END GPL LICENSE BLOCK ***** * - * $Id: $ */ #ifndef BLI_RECT_H diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 2c114ea6971..4b7b5914b60 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -179,6 +179,7 @@ void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd) bezt->vec[2][1] = (dy + (2 * ftoutline.points[l+1].y)* scale) / 3.0; bezt->h1= bezt->h2= HD_ALIGN; + bezt->radius= 1.0f; bezt++; } } @@ -265,6 +266,7 @@ void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd) { bezt->h1= bezt->h2= HD_ALIGN; } + bezt->radius= 1.0f; bezt++; } } diff --git a/source/blender/blenlib/intern/psfont.c b/source/blender/blenlib/intern/psfont.c index 54d7f8ec1af..39d38e4cf3a 100644 --- a/source/blender/blenlib/intern/psfont.c +++ b/source/blender/blenlib/intern/psfont.c @@ -2094,6 +2094,7 @@ static VFontData *objfnt_to_vfontdata(objfnt *fnt) while(a--) { if(bezt->h1!=HD_ALIGN && bezt->h2==HD_ALIGN) bezt->h2= 0; else if(bezt->h2!=HD_ALIGN && bezt->h1==HD_ALIGN) bezt->h1= 0; + bezt->radius= 1.0f; bezt++; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 5ea83f0375f..5c176c4a72b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2152,6 +2152,13 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist) data->tar = newlibadr(fd, id->lib, data->tar); } break; + case CONSTRAINT_TYPE_SHRINKWRAP: + { + bShrinkwrapConstraint *data; + data= ((bShrinkwrapConstraint*)con->data); + data->target = newlibadr(fd, id->lib, data->target); + } + break; case CONSTRAINT_TYPE_NULL: break; } @@ -3484,6 +3491,12 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) collmd->mfaces = NULL; } + else if (md->type==eModifierType_Surface) { + SurfaceModifierData *surmd = (SurfaceModifierData*) md; + + surmd->dm = NULL; + surmd->bvhtree = NULL; + } else if (md->type==eModifierType_Hook) { HookModifierData *hmd = (HookModifierData*) md; @@ -3820,7 +3833,9 @@ static void lib_link_scene(FileData *fd, Main *main) srl->mat_override= newlibadr_us(fd, sce->id.lib, srl->mat_override); srl->light_override= newlibadr_us(fd, sce->id.lib, srl->light_override); } - + /*Game Settings: Dome Warp Text*/ + sce->r.dometext= newlibadr_us(fd, sce->id.lib, sce->r.dometext); + sce->id.flag -= LIB_NEEDLINK; } @@ -5702,8 +5717,7 @@ static void do_versions_gpencil_2_50(Main *main, bScreen *screen) /* add regions */ for(sa= screen->areabase.first; sa; sa= sa->next) { - sl= sa->spacedata.first; - for(sl; sl; sl= sl->next) { + for(sl= sa->spacedata.first; sl; sl= sl->next) { if (sl->spacetype==SPACE_VIEW3D) { View3D *v3d= (View3D*) sl; if(v3d->gpd) { @@ -8801,6 +8815,35 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 3)) { + Object *ob; + + /* Adjustments needed after Bullets update */ + for(ob = main->object.first; ob; ob= ob->id.next) { + ob->damping *= 0.635f; + ob->rdamping = 0.1 + (0.59f * ob->rdamping); + } + } + + if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 4)) { + Scene *sce; + World *wrld; + + /* Dome (Fisheye) default parameters */ + for (sce= main->scene.first; sce; sce= sce->id.next) { + sce->r.domeangle = 180; + sce->r.domemode = 1; + sce->r.domesize = 1.0f; + sce->r.domeres = 4; + sce->r.domeresbuf = 1.0f; + } + /* DBVT culling by default */ + for(wrld=main->world.first; wrld; wrld= wrld->id.next) { + wrld->mode |= WO_DBVT_CULLING; + wrld->occlusionRes = 128; + } + } + if (main->versionfile < 250) { bScreen *screen; Scene *scene; @@ -8921,7 +8964,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } - + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ @@ -9568,6 +9611,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb) expand_doit(fd, mainvar, data->tar); } break; + case CONSTRAINT_TYPE_SHRINKWRAP: + { + bShrinkwrapConstraint *data = (bShrinkwrapConstraint*)curcon->data; + expand_doit(fd, mainvar, data->target); + } + break; default: break; } @@ -9797,6 +9846,9 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) expand_doit(fd, mainvar, srl->mat_override); expand_doit(fd, mainvar, srl->light_override); } + + if(sce->r.dometext) + expand_doit(fd, mainvar, sce->r.dometext); } static void expand_camera(FileData *fd, Main *mainvar, Camera *ca) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index d7d7ad79239..f93ad5eaf2b 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1434,9 +1434,9 @@ static void write_textures(WriteData *wd, ListBase *idbase) if (tex->adt) write_animdata(wd, tex->adt); /* direct data */ - if(tex->plugin) writestruct(wd, DATA, "PluginTex", 1, tex->plugin); + if(tex->type == TEX_PLUGIN && tex->plugin) writestruct(wd, DATA, "PluginTex", 1, tex->plugin); if(tex->coba) writestruct(wd, DATA, "ColorBand", 1, tex->coba); - if(tex->env) writestruct(wd, DATA, "EnvMap", 1, tex->env); + if(tex->type == TEX_ENVMAP && tex->env) writestruct(wd, DATA, "EnvMap", 1, tex->env); /* nodetree is integral part of texture, no libdata */ if(tex->nodetree) { @@ -1832,7 +1832,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase) writestruct(wd, DATA, "SpaceFile", 1, sl); } else if(sl->spacetype==SPACE_SEQ) { - SpaceSeq *sseq= (SpaceSeq *)sl; writestruct(wd, DATA, "SpaceSeq", 1, sl); } else if(sl->spacetype==SPACE_OUTLINER) { @@ -1878,7 +1877,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase) writestruct(wd, DATA, "SpaceTime", 1, sl); } else if(sl->spacetype==SPACE_NODE){ - SpaceNode *snode= (SpaceNode *)sl; writestruct(wd, DATA, "SpaceNode", 1, sl); } sl= sl->next; diff --git a/source/blender/editors/armature/BIF_generate.h b/source/blender/editors/armature/BIF_generate.h index bc655a4cdff..bde079c45fb 100644 --- a/source/blender/editors/armature/BIF_generate.h +++ b/source/blender/editors/armature/BIF_generate.h @@ -1,5 +1,5 @@ /** - * $Id: $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/editors/armature/BIF_retarget.h b/source/blender/editors/armature/BIF_retarget.h index 049ddf5baa5..c39f410424a 100644 --- a/source/blender/editors/armature/BIF_retarget.h +++ b/source/blender/editors/armature/BIF_retarget.h @@ -1,5 +1,5 @@ /** - * $Id: $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/editors/armature/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c index a1990814a02..6d271375c64 100644 --- a/source/blender/editors/armature/editarmature_generate.c +++ b/source/blender/editors/armature/editarmature_generate.c @@ -1,5 +1,5 @@ /** - * $Id: editarmature_generate.c $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -53,14 +53,14 @@ void setBoneRollFromNormal(EditBone *bone, float *no, float invmat[][4], float t { if (no != NULL && !VecIsNull(no)) { - float tangent[3], cotangent[3], normal[3]; + float tangent[3], vec[3], normal[3]; VECCOPY(normal, no); Mat3MulVecfl(tmat, normal); VecSubf(tangent, bone->tail, bone->head); - Crossf(cotangent, tangent, normal); - Crossf(normal, cotangent, tangent); + Projf(vec, tangent, normal); + VecSubf(normal, normal, vec); Normalize(normal); diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index 4da7eaf9440..68e8b45e7d2 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -206,12 +206,12 @@ float rollBoneByQuatAligned(EditBone *bone, float old_up_axis[3], float qrot[4], } } -float rollBoneByQuatJoint(RigEdge *edge, RigEdge *previous, float qrot[4], float qroll[4]) +float rollBoneByQuatJoint(RigEdge *edge, RigEdge *previous, float qrot[4], float qroll[4], float up_axis[3]) { if (previous == NULL) { - QuatOne(qroll); - return rollBoneByQuat(edge->bone, edge->up_axis, qrot); + /* default to up_axis if no previous */ + return rollBoneByQuatAligned(edge->bone, edge->up_axis, qrot, qroll, up_axis); } else { @@ -228,9 +228,8 @@ float rollBoneByQuatJoint(RigEdge *edge, RigEdge *previous, float qrot[4], float } else { - /* SHOULDN'T BE HERE */ - QuatOne(qroll); - return rollBoneByQuat(edge->bone, edge->up_axis, qrot); + /* default to up_axis if first bone in the chain is an offset */ + return rollBoneByQuatAligned(edge->bone, edge->up_axis, qrot, qroll, up_axis); } VecSubf(vec_second, edge->bone->tail, edge->bone->head); @@ -1859,7 +1858,7 @@ static void repositionBone(bContext *C, RigGraph *rigg, RigEdge *edge, float vec } else if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_JOINT) { - bone->roll = rollBoneByQuatJoint(edge, edge->next, qrot, qroll); + bone->roll = rollBoneByQuatJoint(edge, edge->prev, qrot, qroll, up_axis); } else { diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 5d0b954046c..45605ad472d 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -1,5 +1,5 @@ /** - * $Id: $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -293,7 +293,7 @@ char *BIF_listTemplates(bContext *C) while (!BLI_ghashIterator_isDone(&ghi)) { Object *ob = BLI_ghashIterator_getValue(&ghi); - int key = (int)BLI_ghashIterator_getKey(&ghi); + int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi)); p += sprintf(p, "|%s%%x%i", ob->id.name+2, key); @@ -314,7 +314,7 @@ int BIF_currentTemplate(bContext *C) while (!BLI_ghashIterator_isDone(&ghi)) { Object *ob = BLI_ghashIterator_getValue(&ghi); - int key = (int)BLI_ghashIterator_getKey(&ghi); + int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi)); if (ob == scene->toolsettings->skgen_template) { @@ -1035,7 +1035,22 @@ void sk_drawStroke(SK_Stroke *stk, int id, float color[3], int start, int end) } glEnd(); - + +#if 0 + glColor3f(0, 0, 1); + glBegin(GL_LINES); + + for (i = 0; i < stk->nb_points; i++) + { + float *p = stk->points[i].p; + float *no = stk->points[i].no; + glVertex3fv(p); + glVertex3f(p[0] + no[0], p[1] + no[1], p[2] + no[2]); + } + + glEnd(); +#endif + glColor3f(0, 0, 0); glBegin(GL_POINTS); @@ -1998,7 +2013,7 @@ void sk_convertStroke(bContext *C, SK_Stroke *stk) Mat4MulVecfl(invmat, bone->head); Mat4MulVecfl(invmat, bone->tail); - setBoneRollFromNormal(bone, pt->no, invmat, tmat); + setBoneRollFromNormal(bone, head->no, invmat, tmat); } new_parent = bone; diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 09edc5549c1..3d8d446c579 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -1237,7 +1237,6 @@ static short pose_select_same_layer (Object *ob) return changed; } - void pose_select_grouped (Scene *scene, short nr) { short changed = 0; @@ -1669,9 +1668,7 @@ void pose_special_editmenu(Scene *scene) pose_clear_paths(ob); } else if(nr==5) { - rest_pose(ob->pose); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - BIF_undo_push("Clear User Transform Pose"); + pose_clear_user_transforms(scene, ob); } else if(nr==6) { pose_relax(); @@ -1682,3 +1679,29 @@ void pose_special_editmenu(Scene *scene) #endif } +/* Restore selected pose-bones to 'action'-defined pose */ +void pose_clear_user_transforms(Scene *scene, Object *ob) +{ + bArmature *arm= ob->data; + bPoseChannel *pchan; + + if (ob->pose == NULL) + return; + + /* find selected bones */ + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if (pchan->bone && (pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) { + /* just clear the BONE_UNKEYED flag, allowing this bone to get overwritten by actions again */ + pchan->bone->flag &= ~BONE_UNKEYED; + } + } + + /* clear pose locking flag + * - this will only clear the user-defined pose in the selected bones, where BONE_UNKEYED has been cleared + */ + ob->pose->flag |= POSE_DO_UNLOCK; + + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + BIF_undo_push("Clear User Transform"); +} + diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 8c9a282d4ef..72806a79c50 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -652,7 +652,7 @@ static int deleteflagNurb(bContext *C, wmOperator *op, int flag) nu->bp= newbp; clamp_nurb_order_v(nu); - makeknots(nu, 2, nu->flagv>>1); + makeknots(nu, 2); } else { /* is the nurb in V direction selected */ @@ -698,7 +698,7 @@ static int deleteflagNurb(bContext *C, wmOperator *op, int flag) nu->pntsu= newu; clamp_nurb_order_u(nu); } - makeknots(nu, 1, nu->flagu>>1); + makeknots(nu, 1); } } } @@ -746,7 +746,7 @@ static short extrudeflagNurb(ListBase *editnurb, int flag) nu->pntsv= 2; nu->orderv= 2; - makeknots(nu, 2, nu->flagv>>1); + makeknots(nu, 2); } } else { @@ -789,7 +789,7 @@ static short extrudeflagNurb(ListBase *editnurb, int flag) MEM_freeN(nu->bp); nu->bp= newbp; nu->pntsv++; - makeknots(nu, 2, nu->flagv>>1); + makeknots(nu, 2); } else if(v==0 || v== nu->pntsu-1) { /* collumn in v-direction selected */ ok= 1; @@ -816,7 +816,7 @@ static short extrudeflagNurb(ListBase *editnurb, int flag) MEM_freeN(nu->bp); nu->bp= newbp; nu->pntsu++; - makeknots(nu, 1, nu->flagu>>1); + makeknots(nu, 1); } } } @@ -911,7 +911,7 @@ static void adduplicateflagNurb(Object *obedit, short flag) /* knots */ newnu->knotsu= NULL; - makeknots(newnu, 1, newnu->flagu>>1); + makeknots(newnu, 1); } bp++; } @@ -975,14 +975,14 @@ static void adduplicateflagNurb(Object *obedit, short flag) if(nu->pntsu==newnu->pntsu && nu->knotsu) { newnu->knotsu= MEM_dupallocN( nu->knotsu ); } else { - makeknots(newnu, 1, newnu->flagu>>1); + makeknots(newnu, 1); } } if (check_valid_nurb_v(newnu)) { if(nu->pntsv==newnu->pntsv && nu->knotsv) { newnu->knotsv= MEM_dupallocN( nu->knotsv ); } else { - makeknots(newnu, 2, newnu->flagv>>1); + makeknots(newnu, 2); } } } @@ -1962,8 +1962,8 @@ static int subdivide_exec(bContext *C, wmOperator *op) nu->bp= bpnew; nu->pntsu+= amount; - if(nu->type & 4) { - makeknots(nu, 1, nu->flagu>>1); + if(nu->type & CU_NURBS) { + makeknots(nu, 1); } } } /* End of 'else if(nu->pntsv==1)' */ @@ -2074,8 +2074,8 @@ static int subdivide_exec(bContext *C, wmOperator *op) nu->bp= bpnew; nu->pntsu= 2*nu->pntsu-1; nu->pntsv= 2*nu->pntsv-1; - makeknots(nu, 1, nu->flagu>>1); - makeknots(nu, 2, nu->flagv>>1); + makeknots(nu, 1); + makeknots(nu, 2); } /* End of 'if(sel== nu->pntsu*nu->pntsv)' (subdivide entire NURB) */ else { /* subdivide in v direction? */ @@ -2118,7 +2118,7 @@ static int subdivide_exec(bContext *C, wmOperator *op) MEM_freeN(nu->bp); nu->bp= bpnew; nu->pntsv+= sel; - makeknots(nu, 2, nu->flagv>>1); + makeknots(nu, 2); } else { /* or in u direction? */ @@ -2158,7 +2158,7 @@ static int subdivide_exec(bContext *C, wmOperator *op) MEM_freeN(nu->bp); nu->bp= bpnew; nu->pntsu+= sel; - makeknots(nu, 1, nu->flagu>>1); /* shift knots + makeknots(nu, 1); /* shift knots forward */ } } @@ -2316,7 +2316,7 @@ static int convertspline(short type, Nurb *nu) BPoint *bp; int a, c, nr; - if((nu->type & 7)==0) { /* Poly */ + if((nu->type & 7)==CU_POLY) { if(type==CU_BEZIER) { /* to Bezier with vecthandles */ nr= nu->pntsu; bezt = @@ -2337,16 +2337,16 @@ static int convertspline(short type, Nurb *nu) nu->bp= 0; nu->pntsu= nr; nu->type &= ~7; - nu->type |= 1; + nu->type |= CU_BEZIER; calchandlesNurb(nu); } else if(type==CU_NURBS) { nu->type &= ~7; - nu->type+= 4; + nu->type |= CU_NURBS; nu->orderu= 4; nu->flagu &= CU_CYCLIC; /* disable all flags except for cyclic */ nu->flagu += 4; - makeknots(nu, 1, nu->flagu>>1); + makeknots(nu, 1); a= nu->pntsu*nu->pntsv; bp= nu->bp; while(a--) { @@ -2400,7 +2400,7 @@ static int convertspline(short type, Nurb *nu) if(type== 4) { nu->flagu &= CU_CYCLIC; /* disable all flags except for cyclic */ nu->flagu += 4; - makeknots(nu, 1, nu->flagu>>1); + makeknots(nu, 1); } } } @@ -2442,7 +2442,7 @@ static int convertspline(short type, Nurb *nu) nu->knotsu= NULL; nu->pntsu= nr; nu->type &= ~7; - nu->type+= 1; + nu->type |= CU_BEZIER; } } } @@ -2803,12 +2803,12 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu } } - if((nu1->type & 7)==4) { + if((nu1->type & 7)==CU_NURBS) { /* merge knots */ - makeknots(nu1, 1, nu1->flagu>>1); + makeknots(nu1, 1); /* make knots, for merged curved for example */ - makeknots(nu1, 2, nu1->flagv>>1); + makeknots(nu1, 2); } MEM_freeN(temp); @@ -2991,9 +2991,9 @@ static int make_segment_exec(bContext *C, wmOperator *op) BLI_remlink(editnurb, nu2); /* now join the knots */ - if((nu1->type & 7)==4) { + if((nu1->type & 7)==CU_NURBS) { if(nu1->knotsu==NULL) { - makeknots(nu1, 1, nu1->flagu>>1); + makeknots(nu1, 1); } else { fp= MEM_mallocN(sizeof(float)*KNOTSU(nu1), "addsegment3"); @@ -3216,7 +3216,7 @@ static int spin_nurb(bContext *C, Scene *scene, Object *obedit, float *dvec, sho if(isNurbsel(nu)) { nu->orderv= 4; nu->flagv |= CU_CYCLIC; - makeknots(nu, 2, nu->flagv>>1); + makeknots(nu, 2); } } } @@ -3352,7 +3352,7 @@ static int addvert_Nurb(bContext *C, short mode, float location[3]) if(bp) { nu->pntsu++; - makeknots(nu, 1, nu->flagu>>1); + makeknots(nu, 1); if(mode=='e') { VECCOPY(newbp->vec, bp->vec); @@ -3492,7 +3492,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) for(nu= editnurb->first; nu; nu= nu->next) { if( nu->pntsu>1 || nu->pntsv>1) { - if( (nu->type & 7)==0 ) { + if( (nu->type & 7)==CU_POLY ) { a= nu->pntsu; bp= nu->bp; while(a--) { @@ -3522,7 +3522,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) while(a--) { if( bp->f1 & SELECT ) { nu->flagu ^= CU_CYCLIC; - makeknots(nu, 1, nu->flagu>>1); /* 1==u type is ignored for cyclic curves */ + makeknots(nu, 1); /* 1==u type is ignored for cyclic curves */ break; } bp++; @@ -3537,11 +3537,11 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op) if( bp->f1 & SELECT) { if(direction==0 && nu->pntsu>1) { nu->flagu ^= CU_CYCLIC; - makeknots(nu, 1, nu->flagu>>1); /* 1==u type is ignored for cyclic curves */ + makeknots(nu, 1); /* 1==u type is ignored for cyclic curves */ } if(direction==1 && nu->pntsv>1) { nu->flagv ^= CU_CYCLIC; - makeknots(nu, 2, nu->flagv>>1); /* 2==v type is ignored for cyclic curves */ + makeknots(nu, 2); /* 2==v type is ignored for cyclic curves */ } break; } @@ -4349,7 +4349,7 @@ static int delete_exec(bContext *C, wmOperator *op) clamp_nurb_order_u(nu); }*/ } - makeknots(nu, 1, nu->flagu>>1); + makeknots(nu, 1); } nu= next; } @@ -4810,7 +4810,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) if(cutype==CU_NURBS) { nu->knotsu= 0; /* makeknots allocates */ - makeknots(nu, 1, nu->flagu>>1); + makeknots(nu, 1); } } @@ -4845,7 +4845,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) if(cutype==CU_NURBS) { nu->knotsu= 0; /* makeknots allocates */ - makeknots(nu, 1, nu->flagu>>1); + makeknots(nu, 1); } break; @@ -4930,7 +4930,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) bp++; } - makeknots(nu, 1, nu->flagu>>1); + makeknots(nu, 1); } break; case CU_PRIM_PATCH: /* 4x4 patch */ @@ -4967,8 +4967,8 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) } } - makeknots(nu, 1, nu->flagu>>1); - makeknots(nu, 2, nu->flagv>>1); + makeknots(nu, 1); + makeknots(nu, 2); } break; case CU_PRIM_TUBE: /* tube */ @@ -5030,7 +5030,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) bp++; } nu->flagu= 4; - makeknots(nu, 1, nu->flagu>>1); + makeknots(nu, 1); BLI_addtail(editnurb, nu); /* temporal for spin */ if(newname && (U.flag & USER_ADD_VIEWALIGNED) == 0) @@ -5038,7 +5038,7 @@ Nurb *add_nurbs_primitive(bContext *C, int type, int newname) else spin_nurb(C, scene, obedit, 0, 0); - makeknots(nu, 2, nu->flagv>>1); + makeknots(nu, 2); a= nu->pntsu*nu->pntsv; bp= nu->bp; diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 2b63c1f2d3b..fd59539bb56 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -133,8 +133,10 @@ void gp_ui_delstroke_cb (void *gpd, void *gpl) { bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0); + if (gpf->framenum != CFRA) return; + gpencil_layer_setactive(gpd, gpl); - gpencil_frame_delete_laststroke(gpf); + gpencil_frame_delete_laststroke(gpl, gpf); scrarea_queue_winredraw(curarea); } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index fc3c8b1dc77..f3868b1f01c 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -2603,11 +2603,13 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float rad, int beaut } } } - sort[hold]->f &= ~SELECT; - sort[hold]->f2 |= EDGENEW; - length[hold] = -1; - } - } + if (hold > -1) { + sort[hold]->f &= ~SELECT; + sort[hold]->f2 |= EDGENEW; + length[hold] = -1; + } + } + } // Beauty Long Edges else { @@ -2624,13 +2626,15 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float rad, int beaut } } } - sort[hold]->f &= ~SELECT; - sort[hold]->f2 |= EDGENEW; - length[hold] = -1; - } - } + if (hold > -1) { + sort[hold]->f &= ~SELECT; + sort[hold]->f2 |= EDGENEW; + length[hold] = -1; + } + } + } } - } + } } gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); @@ -3255,11 +3259,9 @@ void join_triangles(EditMesh *em) if(v1 && v2 && v3 && v4){ /*test if simple island first. This mimics 2.42 behaviour and the tests are less restrictive.*/ if(efaa[0]->tmp.l == 1 && efaa[1]->tmp.l == 1){ - if( convex(v1->co, v2->co, v3->co, v4->co) ){ - eed->f1 |= T2QJOIN; - efaa[0]->f1 = 1; //mark for join - efaa[1]->f1 = 1; //mark for join - } + eed->f1 |= T2QJOIN; + efaa[0]->f1 = 1; //mark for join + efaa[1]->f1 = 1; //mark for join } else{ @@ -3503,10 +3505,6 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed,int dir) if(numshared > 1) return; - /* coplaner faces only please */ - if(Inpf(face[0]->n,face[1]->n) <= 0.000001) - return; - /* we want to construct an array of vertex indicis in both faces, starting at the last vertex of the edge being rotated. - first we find the two vertices that lie on the rotating edge diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 69d580afea9..5a86180a60f 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -45,6 +45,7 @@ #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_mesh.h" #include "BKE_utildefines.h" #include "RNA_access.h" diff --git a/source/blender/editors/object/editconstraint.c b/source/blender/editors/object/editconstraint.c index c8d8ece30dc..d0e487f98c7 100644 --- a/source/blender/editors/object/editconstraint.c +++ b/source/blender/editors/object/editconstraint.c @@ -379,6 +379,8 @@ void add_constraint (Scene *scene, View3D *v3d, short only_IK) nr= pupmenu("Add Constraint to Active Bone%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18"); else if ((obsel) && (obsel->type==OB_CURVE)) nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|%l|Action%x16|Script%x18"); + else if ((obsel) && (obsel->type==OB_MESH)) + nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Shrinkwrap%x22|Stretch To%x7|%l|Action%x16|Script%x18"); else if (obsel) nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18"); else @@ -387,6 +389,8 @@ void add_constraint (Scene *scene, View3D *v3d, short only_IK) else { if ((obsel) && (obsel->type==OB_CURVE)) nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Action%x16|Script%x18"); + else if ((obsel) && (obsel->type==OB_MESH)) + nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Shrinkwrap%x22|%l|Action%x16|Script%x18"); else if (obsel) nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18"); else @@ -489,6 +493,7 @@ void add_constraint (Scene *scene, View3D *v3d, short only_IK) } else if (nr==20) con = add_new_constraint(CONSTRAINT_TYPE_TRANSFORM); else if (nr==21) con = add_new_constraint(CONSTRAINT_TYPE_DISTLIMIT); + else if (nr==22) con = add_new_constraint(CONSTRAINT_TYPE_SHRINKWRAP); if (con==NULL) return; /* paranoia */ diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index a5c811be164..eeba0ad22ae 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -3076,7 +3076,7 @@ static int object_center_set_exec(bContext *C, wmOperator *op) nu= nu1; while(nu) { - if( (nu->type & 7)==1) { + if( (nu->type & 7)==CU_BEZIER) { a= nu->pntsu; while (a--) { VecSubf(nu->bezt[a].vec[0], nu->bezt[a].vec[0], cent); @@ -4338,14 +4338,12 @@ static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob) prop= prop->next; } - if(tot==0) { - error("No properties in the active object to copy"); - return; - } - str= MEM_callocN(50 + 33*tot, "copymenu prop"); - strcpy(str, "Copy Property %t|Replace All|Merge All|%l"); + if (tot) + strcpy(str, "Copy Property %t|Replace All|Merge All|%l"); + else + strcpy(str, "Copy Property %t|Clear All (no properties on active)"); tot= 0; prop= ob->prop.first; @@ -4648,7 +4646,8 @@ void copy_attr(Scene *scene, View3D *v3d, short event) base->object->formfactor = ob->formfactor; base->object->damping= ob->damping; base->object->rdamping= ob->rdamping; - base->object->mass= ob->mass; + base->object->min_vel= ob->min_vel; + base->object->max_vel= ob->max_vel; if (ob->gameflag & OB_BOUNDS) { base->object->boundtype = ob->boundtype; } @@ -5192,7 +5191,7 @@ static void apply_objects_internal(Scene *scene, View3D *v3d, int apply_scale, i nu= cu->nurb.first; while(nu) { - if( (nu->type & 7)==1) { + if( (nu->type & 7)==CU_BEZIER) { a= nu->pntsu; bezt= nu->bezt; while(a--) { diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index 3212494234b..96f3ad2f8df 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -1,5 +1,5 @@ /* - * $Id: editparticle.c $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h index 9ca4f864e48..e03649575cb 100644 --- a/source/blender/editors/physics/physics_intern.h +++ b/source/blender/editors/physics/physics_intern.h @@ -1,7 +1,5 @@ -/* BIF_editparticle.h - * - * - * $Id: BIF_editparticle.h $ +/* + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 7d0c3e3e3ba..bf57e2e7d52 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -47,6 +47,7 @@ #include "BKE_idprop.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_mesh.h" #include "BKE_multires.h" #include "BKE_report.h" #include "BKE_screen.h" diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 1ce5f3a348b..22fb8e61789 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -753,8 +753,7 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float } ibuf = BKE_image_get_ibuf((Image *)tf->tpage, NULL); /* TODO - this may be slow, the only way around it is to have an ibuf index per face */ - - + if (!ibuf) return 0; if (interp) { float x, y; diff --git a/source/blender/editors/space_image/image_header.c b/source/blender/editors/space_image/image_header.c index 1ff71bd2225..288fc76d8e4 100644 --- a/source/blender/editors/space_image/image_header.c +++ b/source/blender/editors/space_image/image_header.c @@ -45,6 +45,7 @@ #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_image.h" +#include "BKE_mesh.h" #include "BKE_screen.h" #include "BKE_utildefines.h" diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 934d58926e2..fcafcd22a3d 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1062,6 +1062,7 @@ void IMAGE_OT_new(wmOperatorType *ot) /* api callbacks */ ot->exec= new_exec; + ot->invoke= WM_operator_redo; ot->poll= ED_operator_image_active; /* flags */ diff --git a/source/blender/editors/space_image/image_panels.c b/source/blender/editors/space_image/image_panels.c index 2fe7f3990ff..971f3a70a8a 100644 --- a/source/blender/editors/space_image/image_panels.c +++ b/source/blender/editors/space_image/image_panels.c @@ -55,6 +55,7 @@ #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_mesh.h" #include "BKE_node.h" #include "BKE_packedFile.h" #include "BKE_screen.h" diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c index 81508066199..0ab43cbf455 100644 --- a/source/blender/editors/space_text/text_header.c +++ b/source/blender/editors/space_text/text_header.c @@ -56,6 +56,7 @@ #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_text.h" @@ -278,6 +279,7 @@ static void text_unlink(Main *bmain, Text *text) // XXX BPY_clear_bad_scriptlinks(text); // XXX BPY_free_pyconstraint_links(text); // XXX free_text_controllers(text); + // XXX free_dome_warp_text(text); /* check if this text was used as script link: * this check function unsets the pointers and returns how many diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 2bb532288ef..5276ca8f0a5 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2832,16 +2832,14 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv ParticleSettings *part; ParticleData *pars, *pa; ParticleKey state, *states=0; - ParticleCacheKey *cache=0; + ParticleBillboardData bb; Material *ma; - Object *bb_ob=0; - float vel[3], vec[3], vec2[3], imat[4][4], onevec[3]={0.0f,0.0f,0.0f}, bb_center[3]; + float vel[3], vec[3], vec2[3], imat[4][4], bb_center[3]; float timestep, pixsize=1.0, pa_size, pa_time, r_tilt; float cfra= bsystem_time(scene, ob,(float)CFRA,0.0); float *vdata=0, *vedata=0, *cdata=0, *ndata=0, *vd=0, *ved=0, *cd=0, *nd=0, xvec[3], yvec[3], zvec[3]; float ma_r=0.0f, ma_g=0.0f, ma_b=0.0f; - int a, k, k_max=0, totpart, totpoint=0, draw_as, path_nbr=0; - int path_possible=0, keys_possible=0, draw_keys=0, totchild=0; + int a, totpart, totpoint=0, draw_as, totchild=0; int select=ob->flag&SELECT, create_cdata=0; GLint polygonmode[2]; char val[32]; @@ -2928,18 +2926,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(part->flag&PART_GLOB_TIME) cfra=bsystem_time(scene, 0, (float)CFRA, 0.0f); - if(psys->pathcache){ - path_possible=1; - keys_possible=1; - } - if(draw_as==PART_DRAW_PATH && path_possible==0) + if(draw_as==PART_DRAW_PATH && psys->pathcache==NULL) draw_as=PART_DRAW_DOT; - if(draw_as!=PART_DRAW_PATH && keys_possible && part->draw&PART_DRAW_KEYS){ - path_nbr=part->keys_step; - draw_keys=1; - } - /* 3. */ switch(draw_as){ case PART_DRAW_DOT: @@ -2988,12 +2977,15 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glPointSize(2.0); /* default dot size */ } else if(part->bb_ob) - bb_ob=part->bb_ob; + bb.ob=part->bb_ob; else - bb_ob=v3d->camera; + bb.ob=v3d->camera; - if(part->bb_align<PART_BB_VIEW) - onevec[part->bb_align]=1.0f; + bb.align = part->bb_align; + bb.anim = part->bb_anim; + bb.lock = part->draw & PART_DRAW_BB_LOCK; + bb.offset[0] = part->bb_offset[0]; + bb.offset[1] = part->bb_offset[1]; break; case PART_DRAW_PATH: break; @@ -3005,35 +2997,37 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv } /* 4. */ - if(draw_as && draw_as!=PART_DRAW_PATH){ - if(draw_as!=PART_DRAW_CIRC){ - switch(draw_as){ + if(draw_as && draw_as!=PART_DRAW_PATH) { + int tot_vec_size = (totpart + totchild) * 3 * sizeof(float); + + if(draw_as!=PART_DRAW_CIRC) { + switch(draw_as) { case PART_DRAW_AXIS: case PART_DRAW_CROSS: - if(draw_as!=PART_DRAW_CROSS || create_cdata) - cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_cdata"); - vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_vdata"); + if(draw_as != PART_DRAW_CROSS || create_cdata) + cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata"); + vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata"); break; case PART_DRAW_LINE: if(create_cdata) - cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_cdata"); - vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_vdata"); + cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata"); + vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata"); break; case PART_DRAW_BB: if(create_cdata) - cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_cdata"); - vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata"); - ndata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata"); + cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata"); + vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); + ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); break; default: if(create_cdata) - cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_cdata"); - vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_vdata"); + cdata=MEM_callocN(tot_vec_size, "particle_cdata"); + vdata=MEM_callocN(tot_vec_size, "particle_vdata"); } } - if(part->draw&PART_DRAW_VEL && draw_as!=PART_DRAW_LINE) - vedata=MEM_callocN((totpart+totchild)*2*3*(path_nbr+1)*sizeof(float), "particle_vedata"); + if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) + vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata"); vd=vdata; ved=vedata; @@ -3046,6 +3040,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(draw_as){ /* 5. */ for(a=0,pa=pars; a<totpart+totchild; a++, pa++){ + /* setup per particle individual stuff */ if(a<totpart){ if(totchild && (part->draw&PART_DRAW_PARENT)==0) continue; if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue; @@ -3085,11 +3080,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv } r_tilt=1.0f+pa->r_ave[0]; - - if(path_nbr){ - cache=psys->pathcache[a]; - k_max=(int)(cache->steps); - } } else{ ChildParticle *cpa= &psys->child[a-totpart]; @@ -3119,47 +3109,23 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv pa_size=psys_get_child_size(psys,cpa,cfra,0); r_tilt=2.0f*cpa->rand[2]; - if(path_nbr){ - cache=psys->childcache[a-totpart]; - k_max=(int)(cache->steps); - } } if(draw_as!=PART_DRAW_PATH){ - int next_pa=0; - for(k=0; k<=path_nbr; k++){ - if(draw_keys){ - state.time=(float)k/(float)path_nbr; - psys_get_particle_on_path(scene, ob, psys, a, &state,1); - } - else if(path_nbr){ - if(k<=k_max){ - VECCOPY(state.co,(cache+k)->co); - VECCOPY(state.vel,(cache+k)->vel); - QUATCOPY(state.rot,(cache+k)->rot); - } - else - continue; - } - else{ - state.time=cfra; - if(psys_get_particle_state(scene, ob, psys, a, &state,0)==0){ - next_pa=1; - break; - } - } - + state.time=cfra; + if(psys_get_particle_state(scene,ob,psys,a,&state,0)){ + /* create actiual particle data */ switch(draw_as){ case PART_DRAW_DOT: + if(vd){ + VECCOPY(vd,state.co) vd+=3; + } if(cd) { cd[0]=ma_r; cd[1]=ma_g; cd[2]=ma_b; cd+=3; } - if(vd){ - VECCOPY(vd,state.co) vd+=3; - } break; case PART_DRAW_CROSS: case PART_DRAW_AXIS: @@ -3242,59 +3208,15 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv cd[2]=cd[5]=cd[8]=cd[11]=ma_b; cd+=12; } - if(part->draw&PART_DRAW_BB_LOCK && part->bb_align==PART_BB_VIEW){ - VECCOPY(xvec,bb_ob->obmat[0]); - Normalize(xvec); - VECCOPY(yvec,bb_ob->obmat[1]); - Normalize(yvec); - VECCOPY(zvec,bb_ob->obmat[2]); - Normalize(zvec); - } - else if(part->bb_align==PART_BB_VEL){ - float temp[3]; - VECCOPY(temp,state.vel); - Normalize(temp); - VECSUB(zvec,bb_ob->obmat[3],state.co); - if(part->draw&PART_DRAW_BB_LOCK){ - float fac=-Inpf(zvec,temp); - VECADDFAC(zvec,zvec,temp,fac); - } - Normalize(zvec); - Crossf(xvec,temp,zvec); - Normalize(xvec); - Crossf(yvec,zvec,xvec); - } - else{ - VECSUB(zvec,bb_ob->obmat[3],state.co); - if(part->draw&PART_DRAW_BB_LOCK) - zvec[part->bb_align]=0.0f; - Normalize(zvec); - - if(part->bb_align<PART_BB_VIEW) - Crossf(xvec,onevec,zvec); - else - Crossf(xvec,bb_ob->obmat[1],zvec); - Normalize(xvec); - Crossf(yvec,zvec,xvec); - } - VECCOPY(vec,xvec); - VECCOPY(vec2,yvec); - - VecMulf(xvec,cos(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI)); - VecMulf(vec2,sin(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI)); - VECADD(xvec,xvec,vec2); - - VecMulf(yvec,cos(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI)); - VecMulf(vec,-sin(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI)); - VECADD(yvec,yvec,vec); - - VecMulf(xvec,pa_size); - VecMulf(yvec,pa_size); - - VECADDFAC(bb_center,state.co,xvec,part->bb_offset[0]); - VECADDFAC(bb_center,bb_center,yvec,part->bb_offset[1]); + bb.size = pa_size; + bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); + bb.time = pa_time; + VECCOPY(bb.vec, state.co); + VECCOPY(bb.vel, state.vel); + psys_make_billboard(&bb, xvec, yvec, zvec, bb_center); + VECADD(vd,bb_center,xvec); VECADD(vd,vd,yvec); vd+=3; @@ -3314,6 +3236,10 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv break; } + totpoint++; + + /* additional things to draw for each particle */ + /* (velocity, size and number) */ if(vedata){ VECCOPY(ved,state.co); ved+=3; @@ -3329,15 +3255,12 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv setlinestyle(0); } - totpoint++; - } - if(next_pa) - continue; - if(part->draw&PART_DRAW_NUM && !(G.f & G_RENDER_SHADOW)){ - /* in path drawing state.co is the end point */ - glRasterPos3f(state.co[0], state.co[1], state.co[2]); - sprintf(val," %i",a); - BMF_DrawString(G.font, val); + if(part->draw&PART_DRAW_NUM && !(G.f & G_RENDER_SHADOW)){ + /* in path drawing state.co is the end point */ + glRasterPos3f(state.co[0], state.co[1], state.co[2]); + sprintf(val," %i",a); + BMF_DrawString(G.font, val); + } } } } @@ -3346,51 +3269,39 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glGetIntegerv(GL_POLYGON_MODE, polygonmode); glDisableClientState(GL_NORMAL_ARRAY); - if(draw_as != PART_DRAW_CIRC){ - if(draw_as==PART_DRAW_PATH){ - ParticleCacheKey **cache, *path; - float *cd2=0,*cdata2=0; - - glEnableClientState(GL_VERTEX_ARRAY); - - if(dt > OB_WIRE) { - glEnableClientState(GL_NORMAL_ARRAY); + if(draw_as==PART_DRAW_PATH){ + ParticleCacheKey **cache, *path; + float *cd2=0,*cdata2=0; - if(part->draw&PART_DRAW_MAT_COL) - glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); - glEnable(GL_LIGHTING); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); - } - else { - glDisableClientState(GL_NORMAL_ARRAY); + /* setup gl flags */ + if(dt > OB_WIRE) { + glEnableClientState(GL_NORMAL_ARRAY); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_LIGHTING); - UI_ThemeColor(TH_WIRE); - } + if(part->draw&PART_DRAW_MAT_COL) + glEnableClientState(GL_COLOR_ARRAY); - if(totchild && (part->draw&PART_DRAW_PARENT)==0) - totpart=0; + glEnable(GL_LIGHTING); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + } + else { + glDisableClientState(GL_NORMAL_ARRAY); - cache=psys->pathcache; - for(a=0, pa=psys->particles; a<totpart; a++, pa++){ - path=cache[a]; - glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + UI_ThemeColor(TH_WIRE); + } - if(dt > OB_WIRE) { - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); - if(part->draw&PART_DRAW_MAT_COL) - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); - } + if(totchild && (part->draw&PART_DRAW_PARENT)==0) + totpart=0; - glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); - } - - cache=psys->childcache; - for(a=0; a<totchild; a++){ - path=cache[a]; + /* draw actual/parent particles */ + cache=psys->pathcache; + for(a=0, pa=psys->particles; a<totpart; a++, pa++){ + path=cache[a]; + if(path->steps > 0) { glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); if(dt > OB_WIRE) { @@ -3401,68 +3312,85 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); } + } + + /* draw child particles */ + cache=psys->childcache; + for(a=0; a<totchild; a++){ + path=cache[a]; + glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); if(dt > OB_WIRE) { + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); if(part->draw&PART_DRAW_MAT_COL) - glDisable(GL_COLOR_ARRAY); - glDisable(GL_COLOR_MATERIAL); + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); } - if(cdata2) - MEM_freeN(cdata2); - cd2=cdata2=0; + glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); + } - glLineWidth(1.0f); - /* draw particle edit mode key points*/ + /* restore & clean up */ + if(dt > OB_WIRE) { + if(part->draw&PART_DRAW_MAT_COL) + glDisable(GL_COLOR_ARRAY); + glDisable(GL_COLOR_MATERIAL); } - if(draw_as!=PART_DRAW_PATH){ - glDisableClientState(GL_COLOR_ARRAY); + if(cdata2) + MEM_freeN(cdata2); + cd2=cdata2=0; - if(vdata){ - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vdata); - } - else - glDisableClientState(GL_VERTEX_ARRAY); + glLineWidth(1.0f); + } + else if(draw_as!=PART_DRAW_CIRC){ + glDisableClientState(GL_COLOR_ARRAY); - if(ndata && dt>OB_WIRE){ - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, ndata); - glEnable(GL_LIGHTING); - } - else{ - glDisableClientState(GL_NORMAL_ARRAY); - glDisable(GL_LIGHTING); - } + /* setup created data arrays */ + if(vdata){ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vdata); + } + else + glDisableClientState(GL_VERTEX_ARRAY); - if(cdata){ - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_FLOAT, 0, cdata); - } + if(ndata && dt>OB_WIRE){ + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, ndata); + glEnable(GL_LIGHTING); + } + else{ + glDisableClientState(GL_NORMAL_ARRAY); + glDisable(GL_LIGHTING); + } - switch(draw_as){ - case PART_DRAW_AXIS: - case PART_DRAW_CROSS: - glDrawArrays(GL_LINES, 0, 6*totpoint); - break; - case PART_DRAW_LINE: - glDrawArrays(GL_LINES, 0, 2*totpoint); - break; - case PART_DRAW_BB: - if(dt<=OB_WIRE) - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - - glDrawArrays(GL_QUADS, 0, 4*totpoint); - break; - default: - glDrawArrays(GL_POINTS, 0, totpoint); - break; - } + if(cdata){ + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(3, GL_FLOAT, 0, cdata); } + + /* draw created data arrays */ + switch(draw_as){ + case PART_DRAW_AXIS: + case PART_DRAW_CROSS: + glDrawArrays(GL_LINES, 0, 6*totpoint); + break; + case PART_DRAW_LINE: + glDrawArrays(GL_LINES, 0, 2*totpoint); + break; + case PART_DRAW_BB: + if(dt<=OB_WIRE) + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + + glDrawArrays(GL_QUADS, 0, 4*totpoint); + break; + default: + glDrawArrays(GL_POINTS, 0, totpoint); + break; + } } + if(vedata){ glDisableClientState(GL_COLOR_ARRAY); cpack(0xC0C0C0); @@ -3705,7 +3633,7 @@ static void tekenhandlesN(Nurb *nu, short sel) glBegin(GL_LINES); - if( (nu->type & 7)==1) { + if( (nu->type & 7)==CU_BEZIER) { if(sel) col= nurbcol+4; else col= nurbcol; @@ -3762,7 +3690,7 @@ static void tekenvertsN(Nurb *nu, short sel) bglBegin(GL_POINTS); - if((nu->type & 7)==1) { + if((nu->type & 7)==CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 94d53a64f32..9a9786cebff 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -63,6 +63,7 @@ #include "BKE_customdata.h" #include "BKE_depsgraph.h" #include "BKE_idprop.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_global.h" #include "BKE_scene.h" @@ -404,7 +405,7 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, nu= cu->editnurb->first; while(nu) { - if((nu->type & 7)==1) { + if((nu->type & 7)==CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 57d227f33bf..36490650415 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -3865,7 +3865,7 @@ static void do_view3d_pose_armature_transformmenu(bContext *C, void *arg, int ev { #if 0 Scene *scene= CTX_data_scene(C); - Object *ob= OBACT; + Object *ob= CTX_data_active_object(C); switch(event) { case 0: /* clear origin */ @@ -3881,9 +3881,7 @@ static void do_view3d_pose_armature_transformmenu(bContext *C, void *arg, int ev clear_object('g'); break; case 4: /* clear user transform */ - rest_pose(ob->pose); - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - ED_undo_push(C, "Pose, Clear User Transform"); + clear_user_transform(scene, ob); break; } #endif @@ -5466,6 +5464,10 @@ void view3d_header_buttons(const bContext *C, ARegion *ar) xco+= XIC; uiDefIconButBitS(block, TOG, SCE_SNAP_ROTATE, B_REDR, ICON_SNAP_NORMAL,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Align rotation with the snapping target"); xco+= XIC; + if (scene->snap_mode == SCE_SNAP_MODE_VOLUME) { + uiDefIconButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_REDR, 0 /* XXX 2.5 ICON_SNAP_PEEL_OBJECT */,xco,0,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Consider objects as whole when finding volume center"); + xco+= XIC; + } uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(scene->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode"); xco+= XIC; uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,yco,70,YIC, &scene->snap_target, 0, 0, 0, 0, "Snap Target Mode"); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index dfbc22b1e14..4ac82fcd73f 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -83,8 +83,8 @@ typedef struct TransSnap { short mode; short align; short status; - float snapPoint[3]; - float snapTarget[3]; + float snapPoint[3]; /* snapping from this point */ + float snapTarget[3]; /* to this point */ float snapNormal[3]; float snapTangent[3]; float dist; // Distance from snapPoint to snapTarget diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index dc32a46a301..72901110388 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -554,13 +554,13 @@ void CalcSnapGeometry(TransInfo *t, float *vec) peelObjectsTransForm(t, &depth_peels, t->mval); -// if (stk->nb_points > 0 && stk->points[stk->nb_points - 1].type == PT_CONTINUOUS) +// if (LAST_SNAP_POINT_VALID) // { -// last_p = stk->points[stk->nb_points - 1].p; +// last_p = LAST_SNAP_POINT; // } -// else if (LAST_SNAP_POINT_VALID) +// else // { -// last_p = LAST_SNAP_POINT; + last_p = t->tsnap.snapPoint; // } @@ -1617,13 +1617,26 @@ int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase Object *ob = dupli_ob->ob; if (ob->type == OB_MESH) { - DerivedMesh *dm; + EditMesh *em; + DerivedMesh *dm = NULL; int val; - - val = peelDerivedMesh(ob, dm, dupli_ob->mat, ray_start, ray_normal, mval, depth_peels); - + + if (ob != obedit) + { + dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); + + val = peelDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels); + } + else + { + em = ((Mesh *)ob->data)->edit_mesh; + dm = editmesh_get_derived_cage(scene, obedit, em, CD_MASK_BAREMESH); + + val = peelDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels); + } + retval = retval || val; - + dm->release(dm); } } diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 7b5a264a440..aded5a4cff9 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -38,6 +38,7 @@ #include "BKE_customdata.h" #include "BKE_DerivedMesh.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_utildefines.h" diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 0fcd0062044..5cc471ebc22 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -4311,8 +4311,8 @@ void param_smooth_area(ParamHandle *handle) } } -void param_pack(ParamHandle *handle) -{ +void param_pack(ParamHandle *handle, float margin) +{ /* box packing variables */ boxPack *boxarray, *box; float tot_width, tot_height, scale; @@ -4320,6 +4320,7 @@ void param_pack(ParamHandle *handle) PChart *chart; int i, unpacked=0; float trans[2]; + double area= 0.0; PHandle *phandle = (PHandle*)handle; @@ -4332,6 +4333,7 @@ void param_pack(ParamHandle *handle) /* we may not use all these boxes */ boxarray = MEM_mallocN( phandle->ncharts*sizeof(boxPack), "boxPack box"); + for (i = 0; i < phandle->ncharts; i++) { chart = phandle->charts[i]; @@ -4352,6 +4354,32 @@ void param_pack(ParamHandle *handle) box->w = chart->u.pack.size[0] + trans[0]; box->h = chart->u.pack.size[1] + trans[1]; box->index = i; /* warning this index skips PCHART_NOPACK boxes */ + + if(margin>0.0f) + area += sqrt(box->w*box->h); + } + + if(margin>0.0f) { + /* multiply the margin by the area to give pradictable results not dependant on UV scale, + * ...Without using the area running pack multiple times also gives a bad feedback loop. + * multiply by 0.1 so the margin value from the UI can be from 0.0 to 1.0 but not give a massive margin */ + margin = (margin*(float)area) * 0.1; + unpacked= 0; + for (i = 0; i < phandle->ncharts; i++) { + chart = phandle->charts[i]; + + if (chart->flag & PCHART_NOPACK) { + unpacked++; + continue; + } + + box = boxarray+(i-unpacked); + trans[0] = margin * area; + trans[1] = margin * area; + p_chart_uv_translate(chart, trans); + box->w += (margin * area) *2; + box->h += (margin * area) *2; + } } boxPack2D(boxarray, phandle->ncharts-unpacked, &tot_width, &tot_height); diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.h b/source/blender/editors/uvedit/uvedit_parametrizer.h index c468b8d62c5..f1454ee3865 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.h +++ b/source/blender/editors/uvedit/uvedit_parametrizer.h @@ -73,7 +73,7 @@ void param_smooth_area(ParamHandle *handle); /* Packing */ -void param_pack(ParamHandle *handle); +void param_pack(ParamHandle *handle, float margin); /* Average area for all charts */ diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index e9dd1969ee2..4d12700d98c 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -409,7 +409,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op) ParamHandle *handle; handle = construct_param_handle(scene, em, 1, 0, 1, 1); - param_pack(handle); + param_pack(handle, scene->toolsettings->uvcalc_margin); param_flush(handle); param_delete(handle); @@ -804,7 +804,7 @@ static int unwrap_exec(bContext *C, wmOperator *op) param_lscm_solve(handle); param_lscm_end(handle); - param_pack(handle); + param_pack(handle, scene->toolsettings->uvcalc_margin); param_flush(handle); diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 7f5f85e23a6..0e123d872fe 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -83,7 +83,18 @@ void GPU_render_text(MTFace *tface, int mode, Image* ima; int characters, index, character; float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance; - + float advance_tab; + + + /* multiline */ + float line_start= 0.0f, line_height; + if (v4) + line_height= MAX4(v1[1], v2[1], v3[1], v4[2]) - MIN4(v1[1], v2[1], v3[1], v4[2]); + else + line_height= MAX3(v1[1], v2[1], v3[1]) - MIN3(v1[1], v2[1], v3[1]); + line_height *= 1.2; /* could be an option? */ + /* end multiline */ + characters = textlen; ima = (Image*)tface->tpage; @@ -97,12 +108,32 @@ void GPU_render_text(MTFace *tface, int mode, glColor3f(1.0f, 1.0f, 1.0f); glPushMatrix(); + + /* get the tab width */ + matrixGlyph((ImBuf *)ima->ibufs.first, ' ', & centerx, ¢ery, + &sizex, &sizey, &transx, &transy, &movex, &movey, &advance); + + advance_tab= advance * 4; /* tab width could also be an option */ + + for (index = 0; index < characters; index++) { float uv[4][2]; // lets calculate offset stuff character = textstr[index]; + if (character=='\n') { + glTranslatef(line_start, -line_height, 0.0); + line_start = 0.0f; + continue; + } + else if (character=='\t') { + glTranslatef(advance_tab, 0.0, 0.0); + line_start -= advance_tab; /* so we can go back to the start of the line */ + continue; + + } + // space starts at offset 1 // character = character - ' ' + 1; matrixGlyph((ImBuf *)ima->ibufs.first, character, & centerx, ¢ery, @@ -143,6 +174,7 @@ void GPU_render_text(MTFace *tface, int mode, glEnd(); glTranslatef(advance, 0.0, 0.0); + line_start -= advance; /* so we can go back to the start of the line */ } glPopMatrix(); } diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h index 745248d3218..7e99df8237a 100644 --- a/source/blender/imbuf/intern/IMB_anim.h +++ b/source/blender/imbuf/intern/IMB_anim.h @@ -76,9 +76,9 @@ #endif /* WITH_QUICKTIME */ #ifdef WITH_FFMPEG -#include <ffmpeg/avformat.h> -#include <ffmpeg/avcodec.h> -#include <ffmpeg/swscale.h> +#include <libavformat/avformat.h> +#include <libavcodec/avcodec.h> +#include <libswscale/swscale.h> #endif #ifdef WITH_REDCODE diff --git a/source/blender/imbuf/intern/IMB_jp2.h b/source/blender/imbuf/intern/IMB_jp2.h index fcdd4589fca..abc6b78357c 100644 --- a/source/blender/imbuf/intern/IMB_jp2.h +++ b/source/blender/imbuf/intern/IMB_jp2.h @@ -1,7 +1,7 @@ /* * IMB_jp2.h * - * $Id: IMB_bmp.h 14444 2008-04-16 22:40:48Z hos $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index 9d70dd3fc60..30f24d9bbf3 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -83,10 +83,10 @@ #include "IMB_anim5.h" #ifdef WITH_FFMPEG -#include <ffmpeg/avformat.h> -#include <ffmpeg/avcodec.h> -#include <ffmpeg/rational.h> -#include <ffmpeg/swscale.h> +#include <libavformat/avformat.h> +#include <libavcodec/avcodec.h> +#include <libavutil/rational.h> +#include <libswscale/swscale.h> #if LIBAVFORMAT_VERSION_INT < (49 << 16) #define FFMPEG_OLD_FRAME_RATE 1 diff --git a/source/blender/imbuf/intern/anim5.c b/source/blender/imbuf/intern/anim5.c index ab203fe80de..b6f29b6a145 100644 --- a/source/blender/imbuf/intern/anim5.c +++ b/source/blender/imbuf/intern/anim5.c @@ -425,7 +425,7 @@ int startanim5(struct anim * anim) { /* de hele file wordt in het geheugen gemapped */ totlen = BLI_filesize(file); - if (totlen && file>=0) { + if (totlen>0 && file>=0) { lseek(file, 0L, SEEK_SET); mem= MEM_mallocN(totlen, "mmap"); diff --git a/source/blender/imbuf/intern/dds/Makefile b/source/blender/imbuf/intern/dds/Makefile index 28f9e24c947..e14f9320d19 100644 --- a/source/blender/imbuf/intern/dds/Makefile +++ b/source/blender/imbuf/intern/dds/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile 7037 2006-03-12 14:11:23Z ton $ +# $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c index 8257eb4643e..807b0c84e90 100644 --- a/source/blender/imbuf/intern/scaling.c +++ b/source/blender/imbuf/intern/scaling.c @@ -299,7 +299,6 @@ struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1) if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (0); do_rect= (ibuf1->rect != NULL); - do_float= (ibuf1->rect_float != NULL); if (ibuf1->x <= 1) return(IMB_half_y(ibuf1)); if (ibuf1->y <= 1) return(IMB_half_x(ibuf1)); @@ -312,6 +311,8 @@ struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1) p1 = (uchar *) ibuf1->rect; dest=(uchar *) ibuf2->rect; + do_float= (ibuf1->rect_float != NULL && ibuf2->rect_float != NULL); + for(y=ibuf2->y;y>0;y--){ if (do_rect) p2 = p1 + (ibuf1->x << 2); if (do_float) p2f = p1f + (ibuf1->x << 2); diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 15d1d031dbd..ffd5d3431af 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -73,10 +73,10 @@ #endif #ifdef WITH_FFMPEG -#include <ffmpeg/avcodec.h> -#include <ffmpeg/avformat.h> -#include <ffmpeg/avdevice.h> -#include <ffmpeg/log.h> +#include <libavcodec/avcodec.h> +#include <libavformat/avformat.h> +#include <libavdevice/avdevice.h> +#include <libavutil/log.h> #if LIBAVFORMAT_VERSION_INT < (49 << 16) #define FFMPEG_OLD_FRAME_RATE 1 diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index 48432b8c6e2..aeabae42adf 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -195,7 +195,8 @@ typedef struct bGameActuator { typedef struct bVisibilityActuator { /** bit 0: Is this object visible? - ** bit 1: Apply recursively */ + ** bit 1: Apply recursively + ** bit 2: Is this object an occluder? */ int flag; } bVisibilityActuator; @@ -357,6 +358,7 @@ typedef struct FreeCamera { #define ACT_PROP_ASSIGN 0 #define ACT_PROP_ADD 1 #define ACT_PROP_COPY 2 +#define ACT_PROP_TOGGLE 3 /* constraint flag */ #define ACT_CONST_LOCX 1 @@ -457,6 +459,7 @@ typedef struct FreeCamera { /* Set means the object will become invisible */ #define ACT_VISIBILITY_INVISIBLE (1 << 0) #define ACT_VISIBILITY_RECURSIVE (1 << 1) +#define ACT_VISIBILITY_OCCLUSION (1 << 2) /* twodfilter->type */ #define ACT_2DFILTER_ENABLED -2 diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index d091ab3d335..33984582d7f 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -1,5 +1,5 @@ /** -* $Id: DNA_cloth_types.h,v 1.1 2007/08/01 02:28:34 daniel Exp $ +* $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index fe19cf60f12..79f032d0d21 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -317,6 +317,15 @@ typedef struct bDistLimitConstraint { int pad; } bDistLimitConstraint; +typedef struct bShrinkwrapConstraint { + Object *target; + float dist; /* distance to kept from target */ + short shrinkType; /* shrink type (look on MOD shrinkwrap for values) */ + char projAxis; /* axis to project over UP_X, UP_Y, UP_Z */ + char pad[9]; +} bShrinkwrapConstraint; + + /* ------------------------------------------ */ /* bConstraint->type @@ -344,10 +353,11 @@ typedef enum B_CONSTAINT_TYPES { CONSTRAINT_TYPE_RIGIDBODYJOINT, /* rigidbody constraint */ CONSTRAINT_TYPE_CLAMPTO, /* clampto constraint */ CONSTRAINT_TYPE_TRANSFORM, /* transformation (loc/rot/size -> loc/rot/size) constraint */ + CONSTRAINT_TYPE_SHRINKWRAP, /* shrinkwrap (loc/rot) constraint */ /* NOTE: everytime a new constraint is added, update this */ - NUM_CONSTRAINT_TYPES= CONSTRAINT_TYPE_TRANSFORM + NUM_CONSTRAINT_TYPES= CONSTRAINT_TYPE_SHRINKWRAP } B_CONSTRAINT_TYPES; /* bConstraint->flag */ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 68d68d79db9..76f6b980aa2 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -40,6 +40,7 @@ typedef enum ModifierType { eModifierType_Mask, eModifierType_SimpleDeform, eModifierType_Multires, + eModifierType_Surface, NUM_MODIFIER_TYPES } ModifierType; @@ -423,6 +424,14 @@ typedef struct CollisionModifierData { struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */ } CollisionModifierData; +typedef struct SurfaceModifierData { + ModifierData modifier; + + struct DerivedMesh *dm; + + struct BVHTreeFromMesh *bvhtree; /* bounding volume hierarchy of the mesh faces */ +} SurfaceModifierData; + typedef enum { eBooleanModifierOp_Intersect, eBooleanModifierOp_Union, diff --git a/source/blender/makesdna/DNA_object_fluidsim.h b/source/blender/makesdna/DNA_object_fluidsim.h index 13984120d90..66c5baab84b 100644 --- a/source/blender/makesdna/DNA_object_fluidsim.h +++ b/source/blender/makesdna/DNA_object_fluidsim.h @@ -1,6 +1,6 @@ /** * - * $Id: + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 21c5242a703..49435000820 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -225,6 +225,7 @@ typedef struct SoftBody { #define PFIELD_USEMAXR 512 #define PFIELD_USEMINR 1024 #define PFIELD_TEX_ROOTCO 2048 +#define PFIELD_SURFACE 4096 /* pd->falloff */ #define PFIELD_FALL_SPHERE 0 diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 64e335fb3ad..60ca659c19c 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -159,7 +159,9 @@ typedef struct Object { float formfactor; float rdamping, sizefac; float margin; - int pad3; + float max_vel; /* clamp the maximum velocity 0.0 is disabled */ + float min_vel; /* clamp the maximum velocity 0.0 is disabled */ + float pad3; /* clamp the maximum velocity 0.0 is disabled */ char dt, dtx; char totcol; /* copy of mesh or curve or meta */ @@ -424,6 +426,7 @@ extern Object workob; #define OB_COLLISION 65536 #define OB_SOFT_BODY 0x20000 +#define OB_OCCLUDER 0x40000 /* ob->gameflag2 */ #define OB_NEVER_DO_ACTIVITY_CULLING 1 @@ -442,6 +445,7 @@ extern Object workob; #define OB_BODY_TYPE_DYNAMIC 2 #define OB_BODY_TYPE_RIGID 3 #define OB_BODY_TYPE_SOFT 4 +#define OB_BODY_TYPE_OCCLUDER 5 /* ob->scavisflag */ #define OB_VIS_SENS 1 diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 2e232c2e1d4..575fcfd8ac7 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -1,7 +1,7 @@ /* DNA_particle_types.h * * - * $Id: DNA_particle_types.h $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -305,7 +305,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PART_DRAW_ANG 2 #define PART_DRAW_SIZE 4 #define PART_DRAW_EMITTER 8 /* render emitter also */ -#define PART_DRAW_KEYS 16 +//#define PART_DRAW_KEYS 16 /* not used anywhere */ #define PART_DRAW_ADAPT 32 #define PART_DRAW_COS 64 #define PART_DRAW_BB_LOCK 128 diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 90b1ec7c9be..6f88a98fee8 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -45,6 +45,7 @@ struct World; struct Scene; struct Image; struct Group; +struct Text; struct bNodeTree; struct AnimData; @@ -316,6 +317,14 @@ typedef struct RenderData { /* jpeg2000 */ short jp2_preset, jp2_depth; int rpad3; + + /* Dome variables */ + short domeres, domemode; + short domeangle, pad9; + float domesize; + float domeresbuf; + struct Text *dometext; + } RenderData; /* control render convert and shading engine */ @@ -453,6 +462,8 @@ typedef struct ToolSettings { short unwrapper; float uvcalc_radius; float uvcalc_cubesize; + float uvcalc_margin; + float pad; short uvcalc_mapdir; short uvcalc_mapalign; short uvcalc_flag; diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h index 2cae2cc8ccb..7a358ad0694 100644 --- a/source/blender/makesdna/DNA_sensor_types.h +++ b/source/blender/makesdna/DNA_sensor_types.h @@ -166,7 +166,8 @@ typedef struct bJoystickSensor { char type; char joyindex; short flag; - int axis; + short axis; + short axis_single; int axisf; int button; int hat; @@ -255,20 +256,22 @@ typedef struct bJoystickSensor { #define SENS_JOY_ANY_EVENT 1 -#define SENS_JOY_BUTTON 0 +#define SENS_JOY_BUTTON 0 /* axis type */ #define SENS_JOY_BUTTON_PRESSED 0 #define SENS_JOY_BUTTON_RELEASED 1 -#define SENS_JOY_AXIS 1 +#define SENS_JOY_AXIS 1 /* axis type */ #define SENS_JOY_X_AXIS 0 #define SENS_JOY_Y_AXIS 1 #define SENS_JOY_NEG_X_AXIS 2 #define SENS_JOY_NEG_Y_AXIS 3 #define SENS_JOY_PRECISION 4 -#define SENS_JOY_HAT 2 +#define SENS_JOY_HAT 2 /* axis type */ #define SENS_JOY_HAT_DIR 0 +#define SENS_JOY_AXIS_SINGLE 3 /* axis type */ + #define SENS_DELAY_REPEAT 1 // should match JOYINDEX_MAX in SCA_JoystickDefines.h */ diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index 3fd6642df8a..8216a0fb800 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -86,9 +86,12 @@ typedef struct World { * bit 1: Do stars * bit 2: (reserved) depth of field * bit 3: (gameengine): Activity culling is enabled. + * bit 4: ambient occlusion + * bit 5: (gameengine) : enable Bullet DBVT tree for view frustrum culling */ short mode; - int physicsEngine; /* here it's aligned */ + short occlusionRes; /* resolution of occlusion Z buffer in pixel */ + short physicsEngine; /* here it's aligned */ float misi, miststa, mistdist, misthi; @@ -139,6 +142,7 @@ typedef struct World { #define WO_DOF 4 #define WO_ACTIVITY_CULLING 8 #define WO_AMB_OCC 16 +#define WO_DBVT_CULLING 32 /* aomix */ #define WO_AOADD 0 diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 7de0b4e3400..2b65f890bd2 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -599,11 +599,6 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_EMITTER); RNA_def_property_ui_text(prop, "Emitter", "Render emitter Object also."); - //could not find this one in the UI - should this be read only? - prop= RNA_def_property(srna, "keys", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_KEYS); - RNA_def_property_ui_text(prop, "Keys", ""); - /* used? prop= RNA_def_property(srna, "adapt", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_ADAPT); diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index 4859bbb550f..a9f303c8dd3 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -17,29 +17,31 @@ incs += ' ../gpu #/extern/glew/include ' incs += ' ' + env['BF_OPENGL_INC'] incs += ' ' + env['BF_ZLIB_INC'] -defs = '' +defs = [] if env['WITH_BF_PYTHON']: - incs += ' ' + env['BF_PYTHON_INC'] - incs += ' ../python' + incs += ' ' + env['BF_PYTHON_INC'] + incs += ' ../python' + if env['BF_DEBUG']: + defs.append('_DEBUG') else: - defs += 'DISABLE_PYTHON' + defs.append('DISABLE_PYTHON') if env['WITH_BF_INTERNATIONAL']: - defs += ' WITH_FREETYPE2' + defs.append('WITH_FREETYPE2') if env['WITH_BF_OPENEXR']: - defs += ' WITH_OPENEXR' + defs.append('WITH_OPENEXR') if env['WITH_BF_FFMPEG']: - defs += ' WITH_FFMPEG' - incs += ' ' + env['BF_FFMPEG_INC'] + defs.append('WITH_FFMPEG') + incs += ' ' + env['BF_FFMPEG_INC'] if env['WITH_BF_QUICKTIME']: - defs += ' WITH_QUICKTIME' - incs += ' ' + env['BF_QUICKTIME_INC'] + defs.append('WITH_QUICKTIME') + incs += ' ' + env['BF_QUICKTIME_INC'] -env.BlenderLib ( libname = 'bf_nodes', sources = sources, includes = Split(incs), defines = Split(defs), libtype=['core'], priority = [190] ) -env.BlenderLib ( libname = 'bf_cmpnodes', sources = cmpsources, includes = Split(incs), defines = Split(defs), libtype=['core'], priority = [175] ) -env.BlenderLib ( libname = 'bf_shdnodes', sources = shdsources, includes = Split(incs), defines = Split(defs), libtype=['core'], priority = [175] ) -env.BlenderLib ( libname = 'bf_texnodes', sources = texsources, includes = Split(incs), defines = Split(defs), libtype=['core'], priority = [175] ) +env.BlenderLib ( libname = 'bf_nodes', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [190] ) +env.BlenderLib ( libname = 'bf_cmpnodes', sources = cmpsources, includes = Split(incs), defines = defs, libtype=['core'], priority = [175] ) +env.BlenderLib ( libname = 'bf_shdnodes', sources = shdsources, includes = Split(incs), defines = defs, libtype=['core'], priority = [175] ) +env.BlenderLib ( libname = 'bf_texnodes', sources = texsources, includes = Split(incs), defines = defs, libtype=['core'], priority = [175] ) diff --git a/source/blender/nodes/TEX_node.h b/source/blender/nodes/TEX_node.h index c52fc757507..d298f062143 100644 --- a/source/blender/nodes/TEX_node.h +++ b/source/blender/nodes/TEX_node.h @@ -1,5 +1,5 @@ /** - * $Id: CMP_node.h 12429 2007-10-29 14:37:19Z bebraw $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c b/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c index a62e4be4015..846aec490c2 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c @@ -1,5 +1,5 @@ /** - * $Id: CMP_normalize.c,v 1.0 2007/03/24 06:57:29 scourage Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c index 4fcfe3a789a..fedca8f9086 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c @@ -345,7 +345,11 @@ static void node_dynamic_pyerror_print(bNode *node) PyGILState_STATE gilstate = PyGILState_Ensure(); fprintf(stderr, "\nError in dynamic node script \"%s\":\n", node->name); - if (PyErr_Occurred()) { PyErr_Print(); } + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + PySys_SetObject("last_traceback", NULL); + } else { fprintf(stderr, "Not a valid dynamic node Python script.\n"); } PyGILState_Release(gilstate); diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_invert.c b/source/blender/nodes/intern/SHD_nodes/SHD_invert.c index 72ee1483ecf..fbab7f64cb3 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_invert.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_invert.c @@ -1,5 +1,5 @@ /** - * $Id: SHD_math.c,v 1.4 2007/04/04 13:58:12 jesterking Exp $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/nodes/intern/TEX_nodes/Makefile b/source/blender/nodes/intern/TEX_nodes/Makefile index 7fad19a772c..ac741280478 100644 --- a/source/blender/nodes/intern/TEX_nodes/Makefile +++ b/source/blender/nodes/intern/TEX_nodes/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile 12796 2007-12-05 16:58:52Z sirdude $ +# $Id$ # # ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** # diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_image.c b/source/blender/nodes/intern/TEX_nodes/TEX_image.c index f9477fef12b..b84088da154 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_image.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_image.c @@ -1,5 +1,5 @@ /** - * $Id: TEX_image.c 10456 2007-04-04 13:58:12Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_texture.c b/source/blender/nodes/intern/TEX_nodes/TEX_texture.c index 884d2cd0eb6..30492b84764 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_texture.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_texture.c @@ -47,7 +47,7 @@ static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, shor Tex *nodetex = (Tex *)node->id; - if(node->custom2) { + if(node->custom2 || node->need_exec==0) { /* this node refers to its own texture tree! */ QUATCOPY( out, diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c b/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c index f63f5682030..0d24652a8f6 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c @@ -45,7 +45,7 @@ static void normalfn(float *out, float *coord, bNode *node, bNodeStack **in, sho float nabla = tex_input_value(in[1], coord, thread); float val; - float nor[2]; + float nor[3]; val = tex_input_value(in[0], coord, thread); diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c b/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c index ec59769fdfd..71d9cb07e18 100644 --- a/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c +++ b/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c @@ -1,5 +1,5 @@ /** - * $Id: SHD_valToRgb.c 10456 2007-04-04 13:58:12Z jesterking $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/nodes/intern/TEX_util.c b/source/blender/nodes/intern/TEX_util.c index 2ff9717afa6..867e754f960 100644 --- a/source/blender/nodes/intern/TEX_util.c +++ b/source/blender/nodes/intern/TEX_util.c @@ -34,6 +34,12 @@ obtain a colour value from this, a node further up the chain reads the TexDelegate* from its input stack, and uses tex_call_delegate to retrieve the colour from the delegate. + + comments: (ton) + + This system needs recode, a node system should rely on the stack, and + callbacks for nodes only should evaluate own node, not recursively go + over other previous ones. */ #include <assert.h> @@ -43,7 +49,8 @@ void tex_call_delegate(TexDelegate *dg, float *out, float *coord, short thread) { - dg->fn(out, coord, dg->node, dg->in, thread); + if(dg->node->need_exec) + dg->fn(out, coord, dg->node, dg->in, thread); } void tex_input(float *out, int sz, bNodeStack *in, float *coord, short thread) diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index 5fcf4a4eb34..9d7fcf6a9cf 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -14,3 +14,4 @@ if env['OURPLATFORM'] in ('win32-mingw', 'win32-vc') and env['BF_DEBUG']: defs.append('Py_TRACE_REFS') env.BlenderLib( libname = 'bf_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype = ['core'], priority = [140]) + diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index a77570ec1a5..ce324239492 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -945,11 +945,17 @@ static Material *give_render_material(Render *re, Object *ob, int nr) /* ------------------------------------------------------------------------- */ /* Particles */ /* ------------------------------------------------------------------------- */ - +typedef struct ParticleStrandData +{ + struct MCol *mcol; + float *orco, *uvco, *surfnor; + float time, adapt_angle, adapt_pix, size; + int totuv, totcol; + int first, line, adapt, override_uv; +} +ParticleStrandData; /* future thread problem... */ -static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, float *orco, float *surfnor, - float *uvco, int totuv, MCol *mcol, int totcol, float *vec, float *vec1, float ctime, - int first, int line, int adapt, float adapt_angle, float adapt_pix, int override_uv) +static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, ParticleStrandData *sd, float *vec, float *vec1) { static VertRen *v1= NULL, *v2= NULL; VlakRen *vlr= NULL; @@ -972,11 +978,11 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo float fac; if(ma->strand_ease!=0.0f) { if(ma->strand_ease<0.0f) - fac= pow(ctime, 1.0+ma->strand_ease); + fac= pow(sd->time, 1.0+ma->strand_ease); else - fac= pow(ctime, 1.0/(1.0f-ma->strand_ease)); + fac= pow(sd->time, 1.0/(1.0f-ma->strand_ease)); } - else fac= ctime; + else fac= sd->time; width= ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end); @@ -1008,7 +1014,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo flag |= R_STRAND; /* single face line */ - if(line) { + if(sd->line) { vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr->flag= flag; vlr->v1= RE_findOrAddVert(obr, obr->totvert++); @@ -1019,25 +1025,25 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo VECCOPY(vlr->v1->co, vec); VecAddf(vlr->v1->co, vlr->v1->co, cross); VECCOPY(vlr->v1->n, nor); - vlr->v1->orco= orco; + vlr->v1->orco= sd->orco; vlr->v1->accum= -1.0f; // accum abuse for strand texco VECCOPY(vlr->v2->co, vec); VecSubf(vlr->v2->co, vlr->v2->co, cross); VECCOPY(vlr->v2->n, nor); - vlr->v2->orco= orco; + vlr->v2->orco= sd->orco; vlr->v2->accum= vlr->v1->accum; VECCOPY(vlr->v4->co, vec1); VecAddf(vlr->v4->co, vlr->v4->co, cross); VECCOPY(vlr->v4->n, nor); - vlr->v4->orco= orco; + vlr->v4->orco= sd->orco; vlr->v4->accum= 1.0f; // accum abuse for strand texco VECCOPY(vlr->v3->co, vec1); VecSubf(vlr->v3->co, vlr->v3->co, cross); VECCOPY(vlr->v3->n, nor); - vlr->v3->orco= orco; + vlr->v3->orco= sd->orco; vlr->v3->accum= vlr->v4->accum; CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); @@ -1045,23 +1051,23 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo vlr->mat= ma; vlr->ec= ME_V2V3; - if(surfnor) { + if(sd->surfnor) { float *snor= RE_vlakren_get_surfnor(obr, vlr, 1); - VECCOPY(snor, surfnor); + VECCOPY(snor, sd->surfnor); } - if(uvco){ - for(i=0; i<totuv; i++){ + if(sd->uvco){ + for(i=0; i<sd->totuv; i++){ MTFace *mtf; mtf=RE_vlakren_get_tface(obr,vlr,i,NULL,1); mtf->uv[0][0]=mtf->uv[1][0]= - mtf->uv[2][0]=mtf->uv[3][0]=(uvco+2*i)[0]; + mtf->uv[2][0]=mtf->uv[3][0]=(sd->uvco+2*i)[0]; mtf->uv[0][1]=mtf->uv[1][1]= - mtf->uv[2][1]=mtf->uv[3][1]=(uvco+2*i)[1]; + mtf->uv[2][1]=mtf->uv[3][1]=(sd->uvco+2*i)[1]; } - if(override_uv>=0){ + if(sd->override_uv>=0){ MTFace *mtf; - mtf=RE_vlakren_get_tface(obr,vlr,override_uv,NULL,0); + mtf=RE_vlakren_get_tface(obr,vlr,sd->override_uv,NULL,0); mtf->uv[0][0]=mtf->uv[3][0]=0.0f; mtf->uv[1][0]=mtf->uv[2][0]=1.0f; @@ -1070,18 +1076,18 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo mtf->uv[2][1]=mtf->uv[3][1]=1.0f; } } - if(mcol){ - for(i=0; i<totcol; i++){ + if(sd->mcol){ + for(i=0; i<sd->totcol; i++){ MCol *mc; mc=RE_vlakren_get_mcol(obr,vlr,i,NULL,1); - mc[0]=mc[1]=mc[2]=mc[3]=mcol[i]; - mc[0]=mc[1]=mc[2]=mc[3]=mcol[i]; + mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i]; + mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i]; } } } /* first two vertices of a strand */ - else if(first) { - if(adapt){ + else if(sd->first) { + if(sd->adapt){ VECCOPY(anor, nor); VECCOPY(avec, vec); second=1; @@ -1093,18 +1099,18 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo VECCOPY(v1->co, vec); VecAddf(v1->co, v1->co, cross); VECCOPY(v1->n, nor); - v1->orco= orco; + v1->orco= sd->orco; v1->accum= -1.0f; // accum abuse for strand texco VECCOPY(v2->co, vec); VecSubf(v2->co, v2->co, cross); VECCOPY(v2->n, nor); - v2->orco= orco; + v2->orco= sd->orco; v2->accum= v1->accum; } /* more vertices & faces to strand */ else { - if(adapt==0 || second){ + if(sd->adapt==0 || second){ vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr->flag= flag; vlr->v1= v1; @@ -1116,14 +1122,14 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo v2= vlr->v3; // cycle - if(adapt){ + if(sd->adapt){ second=0; VECCOPY(anor,nor); VECCOPY(avec,vec); } } - else if(adapt){ + else if(sd->adapt){ float dvec[3],pvec[3]; VecSubf(dvec,avec,vec); Projf(pvec,dvec,vec); @@ -1133,7 +1139,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo dx= re->winx*dvec[0]*re->winmat[0][0]/w; dy= re->winy*dvec[1]*re->winmat[1][1]/w; w= sqrt(dx*dx + dy*dy); - if(Inpf(anor,nor)<adapt_angle && w>adapt_pix){ + if(Inpf(anor,nor)<sd->adapt_angle && w>sd->adapt_pix){ vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr->flag= flag; vlr->v1= v1; @@ -1155,13 +1161,13 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo VECCOPY(vlr->v4->co, vec); VecAddf(vlr->v4->co, vlr->v4->co, cross); VECCOPY(vlr->v4->n, nor); - vlr->v4->orco= orco; - vlr->v4->accum= -1.0f + 2.0f*ctime; // accum abuse for strand texco + vlr->v4->orco= sd->orco; + vlr->v4->accum= -1.0f + 2.0f*sd->time; // accum abuse for strand texco VECCOPY(vlr->v3->co, vec); VecSubf(vlr->v3->co, vlr->v3->co, cross); VECCOPY(vlr->v3->n, nor); - vlr->v3->orco= orco; + vlr->v3->orco= sd->orco; vlr->v3->accum= vlr->v4->accum; CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); @@ -1169,23 +1175,23 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo vlr->mat= ma; vlr->ec= ME_V2V3; - if(surfnor) { + if(sd->surfnor) { float *snor= RE_vlakren_get_surfnor(obr, vlr, 1); - VECCOPY(snor, surfnor); + VECCOPY(snor, sd->surfnor); } - if(uvco){ - for(i=0; i<totuv; i++){ + if(sd->uvco){ + for(i=0; i<sd->totuv; i++){ MTFace *mtf; mtf=RE_vlakren_get_tface(obr,vlr,i,NULL,1); mtf->uv[0][0]=mtf->uv[1][0]= - mtf->uv[2][0]=mtf->uv[3][0]=(uvco+2*i)[0]; + mtf->uv[2][0]=mtf->uv[3][0]=(sd->uvco+2*i)[0]; mtf->uv[0][1]=mtf->uv[1][1]= - mtf->uv[2][1]=mtf->uv[3][1]=(uvco+2*i)[1]; + mtf->uv[2][1]=mtf->uv[3][1]=(sd->uvco+2*i)[1]; } - if(override_uv>=0){ + if(sd->override_uv>=0){ MTFace *mtf; - mtf=RE_vlakren_get_tface(obr,vlr,override_uv,NULL,0); + mtf=RE_vlakren_get_tface(obr,vlr,sd->override_uv,NULL,0); mtf->uv[0][0]=mtf->uv[3][0]=0.0f; mtf->uv[1][0]=mtf->uv[2][0]=1.0f; @@ -1194,12 +1200,12 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo mtf->uv[2][1]=mtf->uv[3][1]=(vlr->v3->accum+1.0f)/2.0f; } } - if(mcol){ - for(i=0; i<totcol; i++){ + if(sd->mcol){ + for(i=0; i<sd->totcol; i++){ MCol *mc; mc=RE_vlakren_get_mcol(obr,vlr,i,NULL,1); - mc[0]=mc[1]=mc[2]=mc[3]=mcol[i]; - mc[0]=mc[1]=mc[2]=mc[3]=mcol[i]; + mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i]; + mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i]; } } } @@ -1252,17 +1258,13 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float } } -static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Object *bb_ob, float *vec, float *vel, float size, float tilt, short align, - int lock, int p, int totpart, short uv_split, short anim, short split_offset, float random, float pa_time, float offset[2], int uv[3]) + +static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, ParticleBillboardData *bb) { VlakRen *vlr; MTFace *mtf; - float xvec[3]={1.0f,0.0f,0.0f}, yvec[3]={0.0f,1.0f,0.0f}, zvec[3]; - float onevec[3]={0.0f,0.0f,0.0f}, tvec[3],tvec2[3], bb_center[3]; - float uvx=0.0f, uvy=0.0f, uvdx=1.0f, uvdy=1.0f, time=0.0f; - - if(align<PART_BB_VIEW) - onevec[align]=1.0f; + float xvec[3], yvec[3], zvec[3], bb_center[3]; + float uvx = 0.0f, uvy = 0.0f, uvdx = 1.0f, uvdy = 1.0f, time = 0.0f; vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr->v1= RE_findOrAddVert(obr, obr->totvert++); @@ -1270,74 +1272,23 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Object vlr->v3= RE_findOrAddVert(obr, obr->totvert++); vlr->v4= RE_findOrAddVert(obr, obr->totvert++); - if(lock && align==PART_BB_VIEW){ - VECCOPY(xvec,bb_ob->obmat[0]); - Normalize(xvec); - VECCOPY(yvec,bb_ob->obmat[1]); - Normalize(yvec); - VECCOPY(zvec,bb_ob->obmat[2]); - Normalize(zvec); - } - else if(align==PART_BB_VEL){ - float temp[3]; - VECCOPY(temp,vel); - Normalize(temp); - VECSUB(zvec,bb_ob->obmat[3],vec); - if(lock){ - float fac=-Inpf(zvec,temp); - VECADDFAC(zvec,zvec,temp,fac); - } - Normalize(zvec); - Crossf(xvec,temp,zvec); - Normalize(xvec); - Crossf(yvec,zvec,xvec); - } - else{ - VECSUB(zvec,bb_ob->obmat[3],vec); - if(lock) - zvec[align]=0.0f; - Normalize(zvec); - - if(align<PART_BB_VIEW) - Crossf(xvec,onevec,zvec); - else - Crossf(xvec,bb_ob->obmat[1],zvec); - Normalize(xvec); - Crossf(yvec,zvec,xvec); - } + psys_make_billboard(bb, xvec, yvec, zvec, bb_center); - VECCOPY(tvec,xvec); - VECCOPY(tvec2,yvec); + VECADD(vlr->v1->co, bb_center, xvec); + VECADD(vlr->v1->co, vlr->v1->co, yvec); + MTC_Mat4MulVecfl(re->viewmat, vlr->v1->co); - VecMulf(xvec,cos(tilt*(float)M_PI)); - VecMulf(tvec2,sin(tilt*(float)M_PI)); - VECADD(xvec,xvec,tvec2); + VECSUB(vlr->v2->co, bb_center, xvec); + VECADD(vlr->v2->co, vlr->v2->co, yvec); + MTC_Mat4MulVecfl(re->viewmat, vlr->v2->co); - VecMulf(yvec,cos(tilt*(float)M_PI)); - VecMulf(tvec,-sin(tilt*(float)M_PI)); - VECADD(yvec,yvec,tvec); + VECSUB(vlr->v3->co, bb_center, xvec); + VECSUB(vlr->v3->co, vlr->v3->co, yvec); + MTC_Mat4MulVecfl(re->viewmat, vlr->v3->co); - VecMulf(xvec,size); - VecMulf(yvec,size); - - VECADDFAC(bb_center,vec,xvec,offset[0]); - VECADDFAC(bb_center,bb_center,yvec,offset[1]); - - VECADD(vlr->v1->co,bb_center,xvec); - VECADD(vlr->v1->co,vlr->v1->co,yvec); - MTC_Mat4MulVecfl(re->viewmat,vlr->v1->co); - - VECSUB(vlr->v2->co,bb_center,xvec); - VECADD(vlr->v2->co,vlr->v2->co,yvec); - MTC_Mat4MulVecfl(re->viewmat,vlr->v2->co); - - VECSUB(vlr->v3->co,bb_center,xvec); - VECSUB(vlr->v3->co,vlr->v3->co,yvec); - MTC_Mat4MulVecfl(re->viewmat,vlr->v3->co); - - VECADD(vlr->v4->co,bb_center,xvec); - VECSUB(vlr->v4->co,vlr->v4->co,yvec); - MTC_Mat4MulVecfl(re->viewmat,vlr->v4->co); + VECADD(vlr->v4->co, bb_center, xvec); + VECSUB(vlr->v4->co, vlr->v4->co, yvec); + MTC_Mat4MulVecfl(re->viewmat, vlr->v4->co); CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); VECCOPY(vlr->v1->n,vlr->n); @@ -1348,115 +1299,142 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Object vlr->mat= ma; vlr->ec= ME_V2V3; - if(uv_split>1){ - uvdx=uvdy=1.0f/(float)uv_split; - if(anim==PART_BB_ANIM_TIME){ - if(split_offset==PART_BB_OFF_NONE) - time=pa_time; - else if(split_offset==PART_BB_OFF_LINEAR) - time=(float)fmod(pa_time+(float)p/(float)(uv_split*uv_split),1.0f); + if(bb->uv_split > 1){ + uvdx = uvdy = 1.0f / (float)bb->uv_split; + if(bb->anim == PART_BB_ANIM_TIME) { + if(bb->split_offset == PART_BB_OFF_NONE) + time = bb->time; + else if(bb->split_offset == PART_BB_OFF_LINEAR) + time = (float)fmod(bb->time + (float)bb->num / (float)(bb->uv_split * bb->uv_split), 1.0f); else /* split_offset==PART_BB_OFF_RANDOM */ - time=(float)fmod(pa_time+random,1.0f); + time = (float)fmod(bb->time + bb->random, 1.0f); } - else if(anim==PART_BB_ANIM_ANGLE){ - if(align==PART_BB_VIEW){ - time=(float)fmod((tilt+1.0f)/2.0f,1.0); + else if(bb->anim == PART_BB_ANIM_ANGLE) { + if(bb->align == PART_BB_VIEW) { + time = (float)fmod((bb->tilt + 1.0f) / 2.0f, 1.0); } else{ - float axis1[3]={0.0f,0.0f,0.0f}; - float axis2[3]={0.0f,0.0f,0.0f}; - axis1[(align+1)%3]=1.0f; - axis2[(align+2)%3]=1.0f; - if(lock==0){ - zvec[align]=0.0f; + float axis1[3] = {0.0f,0.0f,0.0f}; + float axis2[3] = {0.0f,0.0f,0.0f}; + axis1[(bb->align + 1) % 3] = 1.0f; + axis2[(bb->align + 2) % 3] = 1.0f; + if(bb->lock == 0) { + zvec[bb->align] = 0.0f; Normalize(zvec); } - time=saacos(Inpf(zvec,axis1))/(float)M_PI; - if(Inpf(zvec,axis2)<0.0f) - time=1.0f-time/2.0f; + time = saacos(Inpf(zvec, axis1)) / (float)M_PI; + if(Inpf(zvec, axis2) < 0.0f) + time = 1.0f - time / 2.0f; else - time=time/2.0f; + time = time / 2.0f; } - if(split_offset==PART_BB_OFF_LINEAR) - time=(float)fmod(pa_time+(float)p/(float)(uv_split*uv_split),1.0f); - else if(split_offset==PART_BB_OFF_RANDOM) - time=(float)fmod(pa_time+random,1.0f); + if(bb->split_offset == PART_BB_OFF_LINEAR) + time = (float)fmod(bb->time + (float)bb->num / (float)(bb->uv_split * bb->uv_split), 1.0f); + else if(bb->split_offset == PART_BB_OFF_RANDOM) + time = (float)fmod(bb->time + bb->random, 1.0f); } else{ - if(split_offset==PART_BB_OFF_NONE) - time=0.0f; - else if(split_offset==PART_BB_OFF_LINEAR) - time=(float)fmod((float)p/(float)(uv_split*uv_split),1.0f); + if(bb->split_offset == PART_BB_OFF_NONE) + time = 0.0f; + else if(bb->split_offset == PART_BB_OFF_LINEAR) + time = (float)fmod((float)bb->num /(float)(bb->uv_split * bb->uv_split) , 1.0f); else /* split_offset==PART_BB_OFF_RANDOM */ - time=random; + time = bb->random; } - uvx=uvdx*floor((float)(uv_split*uv_split)*(float)fmod((double)time,(double)uvdx)); - uvy=uvdy*floor((1.0f-time)*(float)uv_split); - if(fmod(time,1.0f/uv_split)==0.0f) - uvy-=uvdy; + uvx = uvdx * floor((float)(bb->uv_split * bb->uv_split) * (float)fmod((double)time, (double)uvdx)); + uvy = uvdy * floor((1.0f - time) * (float)bb->uv_split); + if(fmod(time, 1.0f / bb->uv_split) == 0.0f) + uvy -= uvdy; } /* normal UVs */ - if(uv[0]>=0){ - mtf=RE_vlakren_get_tface(obr,vlr,uv[0],NULL,1); - mtf->uv[0][0]=1.0f; - mtf->uv[0][1]=1.0f; - mtf->uv[1][0]=0.0f; - mtf->uv[1][1]=1.0f; - mtf->uv[2][0]=0.0f; - mtf->uv[2][1]=0.0f; - mtf->uv[3][0]=1.0f; - mtf->uv[3][1]=0.0f; + if(bb->uv[0] >= 0){ + mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[0], NULL, 1); + mtf->uv[0][0] = 1.0f; + mtf->uv[0][1] = 1.0f; + mtf->uv[1][0] = 0.0f; + mtf->uv[1][1] = 1.0f; + mtf->uv[2][0] = 0.0f; + mtf->uv[2][1] = 0.0f; + mtf->uv[3][0] = 1.0f; + mtf->uv[3][1] = 0.0f; } /* time-index UVs */ - if(uv[1]>=0){ - mtf=RE_vlakren_get_tface(obr,vlr,uv[1],NULL,1); - mtf->uv[0][0]=mtf->uv[1][0]=mtf->uv[2][0]=mtf->uv[3][0]=pa_time; - mtf->uv[0][1]=mtf->uv[1][1]=mtf->uv[2][1]=mtf->uv[3][1]=(float)p/(float)totpart; + if(bb->uv[1] >= 0){ + mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[1], NULL, 1); + mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = bb->time; + mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = (float)bb->num/(float)bb->totnum; } /* split UVs */ - if(uv_split>1 && uv[2]>=0){ - mtf=RE_vlakren_get_tface(obr,vlr,uv[2],NULL,1); - mtf->uv[0][0]=uvx+uvdx; - mtf->uv[0][1]=uvy+uvdy; - mtf->uv[1][0]=uvx; - mtf->uv[1][1]=uvy+uvdy; - mtf->uv[2][0]=uvx; - mtf->uv[2][1]=uvy; - mtf->uv[3][0]=uvx+uvdx; - mtf->uv[3][1]=uvy; + if(bb->uv_split > 1 && bb->uv[2] >= 0){ + mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[2], NULL, 1); + mtf->uv[0][0] = uvx + uvdx; + mtf->uv[0][1] = uvy + uvdy; + mtf->uv[1][0] = uvx; + mtf->uv[1][1] = uvy + uvdy; + mtf->uv[2][0] = uvx; + mtf->uv[2][1] = uvy; + mtf->uv[3][0] = uvx + uvdx; + mtf->uv[3][1] = uvy; } } -static void render_new_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, int path, int first, int line, - float time, float *loc, float *loc1, float *orco, float *surfnor, int totuv, float *uvco, - int totcol, MCol *mcol, float size, int seed, int override_uv, - int adapt, float adapt_angle, float adapt_pix) +static void render_new_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd, float *loc, float *loc1, int seed) { HaloRen *har=0; - if(path){ - if(ma->mode&MA_WIRE) - static_particle_wire(obr, ma, loc, loc1, first, line); - else if(ma->mode & MA_HALO){ - har= RE_inithalo_particle(re, obr, dm, ma, loc, loc1, orco, uvco, size, 1.0, seed); - if(har) har->lay= obr->ob->lay; + + if(ma->mode&MA_WIRE) + static_particle_wire(obr, ma, loc, loc1, sd->first, sd->line); + else if(ma->mode & MA_HALO){ + har= RE_inithalo_particle(re, obr, dm, ma, loc, loc1, sd->orco, sd->uvco, sd->size, 1.0, seed); + if(har) har->lay= obr->ob->lay; + } + else + static_particle_strand(re, obr, ma, sd, loc, loc1); +} +static void get_particle_uvco_mcol(short from, DerivedMesh *dm, float *fuv, int num, ParticleStrandData *sd) +{ + int i; + + /* get uvco */ + if(sd->uvco && ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) { + for(i=0; i<sd->totuv; i++) { + if(num != DMCACHE_NOTFOUND) { + MFace *mface = dm->getFaceData(dm, num, CD_MFACE); + MTFace *mtface = (MTFace*)CustomData_get_layer_n(&dm->faceData, CD_MTFACE, i); + mtface += num; + + psys_interpolate_uvs(mtface, mface->v4, fuv, sd->uvco + 2 * i); + } + else { + sd->uvco[2*i] = 0.0f; + sd->uvco[2*i + 1] = 0.0f; + } } - else - static_particle_strand(re, obr, ma, orco, surfnor, uvco, totuv, mcol, totcol, loc, loc1, time, first, line, adapt, adapt_angle, adapt_pix, override_uv); } - else{ - har= RE_inithalo_particle(re, obr, dm, ma, loc, NULL, orco, uvco, size, 0.0, seed); - if(har) har->lay= obr->ob->lay; + + /* get mcol */ + if(sd->mcol && ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) { + for(i=0; i<sd->totcol; i++) { + if(num != DMCACHE_NOTFOUND) { + MFace *mface = dm->getFaceData(dm, num, CD_MFACE); + MCol *mc = (MCol*)CustomData_get_layer_n(&dm->faceData, CD_MCOL, i); + mc += num * 4; + + psys_interpolate_mcol(mc, mface->v4, fuv, sd->mcol + i); + } + else + memset(&sd->mcol[i], 0, sizeof(MCol)); + } } } static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *psys, int timeoffset) { Object *ob= obr->ob; - Object *tob=0, *bb_ob=re->scene->camera; + Object *tob=0; Material *ma=0; - MTFace *mtface; ParticleSystemModifierData *psmd; ParticleSystem *tpsys=0; ParticleSettings *part, *tpart=0; @@ -1464,19 +1442,20 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem ParticleKey *states=0; ParticleKey state; ParticleCacheKey *cache=0; + ParticleBillboardData bb; + ParticleStrandData sd; StrandBuffer *strandbuf=0; StrandVert *svert=0; StrandBound *sbound= 0; StrandRen *strand=0; RNG *rng= 0; - MCol *mcol= 0; float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],co[3],nor[3],time; - float *orco=0,*surfnor=0,*uvco=0, strandlen=0.0f, curlen=0.0f; + float strandlen=0.0f, curlen=0.0f; float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(re->scene, ob, (float)re->scene->r.cfra, 0.0); - float adapt_angle=0.0, adapt_pix=0.0, random, simplify[2]; - int i, a, k, max_k=0, totpart, totuv=0, totcol=0, override_uv=-1, dosimplify = 0, dosurfacecache = 0; - int path_possible=0, keys_possible=0, baked_keys=0, totchild=0; - int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0}, num; + float random, simplify[2]; + int i, a, k, max_k=0, totpart, dosimplify = 0, dosurfacecache = 0; + int totchild=0; + int seed, path_nbr=0, orco1=0, num; int totface, *origindex = 0; char **uv_name=0; @@ -1503,6 +1482,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem return 1; } + /* last possibility to bail out! */ psmd= psys_get_modifier(ob,psys); if(!(psmd->modifier.mode & eModifierMode_Render)) return 0; @@ -1511,14 +1491,17 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem totchild = (int)((float)totchild * (float)part->disp / 100.0f); } - psys->flag|=PSYS_DRAWING; + psys->flag |= PSYS_DRAWING; rng= rng_new(psys->seed); - - ma= give_render_material(re, ob, part->omat); - if(part->bb_ob) - bb_ob=part->bb_ob; + totpart=psys->totpart; + + memset(&sd, 0, sizeof(ParticleStrandData)); + sd.override_uv = -1; + +/* 2.1 setup material stff */ + ma= give_render_material(re, ob, part->omat); #if 0 // XXX old animation system if(ma->ipo){ @@ -1527,171 +1510,168 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem } #endif // XXX old animation system + hasize = ma->hasize; + seed = ma->seed1; + + re->flag |= R_HALO; + RE_set_customdata_names(obr, &psmd->dm->faceData); - totuv=CustomData_number_of_layers(&psmd->dm->faceData,CD_MTFACE); - totcol=CustomData_number_of_layers(&psmd->dm->faceData,CD_MCOL); + sd.totuv = CustomData_number_of_layers(&psmd->dm->faceData, CD_MTFACE); + sd.totcol = CustomData_number_of_layers(&psmd->dm->faceData, CD_MCOL); - if(ma->texco & TEXCO_UV && totuv) { - uvco = MEM_callocN(totuv*2*sizeof(float),"particle_uvs"); + if(ma->texco & TEXCO_UV && sd.totuv) { + sd.uvco = MEM_callocN(sd.totuv * 2 * sizeof(float), "particle_uvs"); if(ma->strand_uvname[0]) { - override_uv= CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,ma->strand_uvname); - override_uv-= CustomData_get_layer_index(&psmd->dm->faceData,CD_MTFACE); + sd.override_uv = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, ma->strand_uvname); + sd.override_uv -= CustomData_get_layer_index(&psmd->dm->faceData, CD_MTFACE); } } + else + sd.uvco = NULL; - if(totcol) - mcol = MEM_callocN(totcol*sizeof(MCol),"particle_mcols"); + if(sd.totcol) + sd.mcol = MEM_callocN(sd.totcol * sizeof(MCol), "particle_mcols"); - if(part->draw_as==PART_DRAW_BB){ - int first_uv=CustomData_get_layer_index(&psmd->dm->faceData,CD_MTFACE); +/* 2.2 setup billboards */ + if(part->draw_as == PART_DRAW_BB) { + int first_uv = CustomData_get_layer_index(&psmd->dm->faceData, CD_MTFACE); - uv[0]=CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,psys->bb_uvname[0]); - if(uv[0]<0) - uv[0]=CustomData_get_active_layer_index(&psmd->dm->faceData,CD_MTFACE); + bb.uv[0] = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, psys->bb_uvname[0]); + if(bb.uv[0] < 0) + bb.uv[0] = CustomData_get_active_layer_index(&psmd->dm->faceData, CD_MTFACE); - uv[1]=CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,psys->bb_uvname[1]); - //if(uv[1]<0) - // uv[1]=CustomData_get_active_layer_index(&psmd->dm->faceData,CD_MTFACE); + bb.uv[1] = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, psys->bb_uvname[1]); - uv[2]=CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,psys->bb_uvname[2]); - //if(uv[2]<0) - // uv[2]=CustomData_get_active_layer_index(&psmd->dm->faceData,CD_MTFACE); + bb.uv[2] = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, psys->bb_uvname[2]); - if(first_uv>=0){ - uv[0]-=first_uv; - uv[1]-=first_uv; - uv[2]-=first_uv; + if(first_uv >= 0) { + bb.uv[0] -= first_uv; + bb.uv[1] -= first_uv; + bb.uv[2] -= first_uv; } + + bb.align = part->bb_align; + bb.anim = part->bb_anim; + bb.lock = part->draw & PART_DRAW_BB_LOCK; + bb.ob = (part->bb_ob ? part->bb_ob : re->scene->camera); + bb.offset[0] = part->bb_offset[0]; + bb.offset[1] = part->bb_offset[1]; + bb.split_offset = part->bb_split_offset; + bb.totnum = totpart+totchild; + bb.uv_split = part->bb_uv_split; } #if 0 // XXX old animation system - if(part->flag&PART_ABS_TIME && part->ipo){ +/* 2.3 setup time */ + if(part->flag&PART_ABS_TIME && part->ipo) { calc_ipo(part->ipo, cfra); execute_ipo((ID *)part, part->ipo); } #endif // XXX old animation system - if(part->flag&PART_GLOB_TIME) - cfra=bsystem_time(re->scene, 0, (float)re->scene->r.cfra, 0.0); + if(part->flag & PART_GLOB_TIME) + cfra = bsystem_time(re->scene, 0, (float)re->scene->r.cfra, 0.0); - if(part->type==PART_REACTOR){ +/* 2.4 setup reactors */ + if(part->type == PART_REACTOR){ psys_get_reactor_target(ob, psys, &tob, &tpsys); if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){ - psmd=psys_get_modifier(tob,tpsys); - tpart=tpsys->part; + psmd = psys_get_modifier(tob,tpsys); + tpart = tpsys->part; } } - - hasize = ma->hasize; - seed = ma->seed1; - - re->flag |= R_HALO; +/* 2.5 setup matrices */ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); MTC_Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */ Mat3CpyMat4(nmat, ob->imat); Mat3Transp(nmat); - totpart=psys->totpart; +/* 2.6 setup strand rendering */ + if(part->draw_as == PART_DRAW_PATH && psys->pathcache){ + path_nbr=(int)pow(2.0,(double) part->ren_step); - if(psys->pathcache){ - path_possible=1; - keys_possible=1; - } - if(part->draw_as==PART_DRAW_PATH){ - if(path_possible){ - path_nbr=(int)pow(2.0,(double) part->ren_step); - //if(part->phystype==PART_PHYS_KEYED && (psys->flag&PSYS_BAKED)==0) - // path_nbr*=psys->totkeyed; - - if(path_nbr) { - if((ma->mode & (MA_HALO|MA_WIRE))==0) { - orco= MEM_mallocN(3*sizeof(float)*(totpart+totchild), "particle orcos"); - set_object_orco(re, psys, orco); - } - path=1; + if(path_nbr) { + if((ma->mode & (MA_HALO|MA_WIRE))==0) { + sd.orco = MEM_mallocN(3*sizeof(float)*(totpart+totchild), "particle orcos"); + set_object_orco(re, psys, sd.orco); } + } - if(part->draw&PART_DRAW_REN_ADAPT) { - adapt=1; - adapt_pix=(float)part->adapt_pix; - adapt_angle=cos((float)part->adapt_angle*(float)(M_PI/180.0)); - } + if(part->draw & PART_DRAW_REN_ADAPT) { + sd.adapt = 1; + sd.adapt_pix = (float)part->adapt_pix; + sd.adapt_angle = cos((float)part->adapt_angle * (float)(M_PI / 180.0)); + } - if(re->r.renderer==R_INTERN && part->draw&PART_DRAW_REN_STRAND) { - strandbuf= RE_addStrandBuffer(obr, (totpart+totchild)*(path_nbr+1)); - strandbuf->ma= ma; - strandbuf->lay= ob->lay; - Mat4CpyMat4(strandbuf->winmat, re->winmat); - strandbuf->winx= re->winx; - strandbuf->winy= re->winy; - strandbuf->maxdepth= 2; - strandbuf->adaptcos= cos((float)part->adapt_angle*(float)(M_PI/180.0)); - strandbuf->overrideuv= override_uv; - strandbuf->minwidth= ma->strand_min; - - if(ma->strand_widthfade == 0.0f) - strandbuf->widthfade= 0.0f; - else if(ma->strand_widthfade >= 1.0f) - strandbuf->widthfade= 2.0f - ma->strand_widthfade; - else - strandbuf->widthfade= 1.0f/MAX2(ma->strand_widthfade, 1e-5f); + if(re->r.renderer==R_INTERN && part->draw&PART_DRAW_REN_STRAND) { + strandbuf= RE_addStrandBuffer(obr, (totpart+totchild)*(path_nbr+1)); + strandbuf->ma= ma; + strandbuf->lay= ob->lay; + Mat4CpyMat4(strandbuf->winmat, re->winmat); + strandbuf->winx= re->winx; + strandbuf->winy= re->winy; + strandbuf->maxdepth= 2; + strandbuf->adaptcos= cos((float)part->adapt_angle*(float)(M_PI/180.0)); + strandbuf->overrideuv= sd.override_uv; + strandbuf->minwidth= ma->strand_min; + + if(ma->strand_widthfade == 0.0f) + strandbuf->widthfade= 0.0f; + else if(ma->strand_widthfade >= 1.0f) + strandbuf->widthfade= 2.0f - ma->strand_widthfade; + else + strandbuf->widthfade= 1.0f/MAX2(ma->strand_widthfade, 1e-5f); - if(part->flag & PART_HAIR_BSPLINE) - strandbuf->flag |= R_STRAND_BSPLINE; - if(ma->mode & MA_STR_B_UNITS) - strandbuf->flag |= R_STRAND_B_UNITS; + if(part->flag & PART_HAIR_BSPLINE) + strandbuf->flag |= R_STRAND_BSPLINE; + if(ma->mode & MA_STR_B_UNITS) + strandbuf->flag |= R_STRAND_B_UNITS; - svert= strandbuf->vert; + svert= strandbuf->vert; - if(re->r.mode & R_SPEED) + if(re->r.mode & R_SPEED) + dosurfacecache= 1; + else if((re->wrld.mode & WO_AMB_OCC) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX)) + if(ma->amb != 0.0f) dosurfacecache= 1; - else if((re->wrld.mode & WO_AMB_OCC) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX)) - if(ma->amb != 0.0f) - dosurfacecache= 1; - - totface= psmd->dm->getNumFaces(psmd->dm); - origindex= psmd->dm->getFaceDataArray(psmd->dm, CD_ORIGINDEX); - if(origindex) { - for(a=0; a<totface; a++) - strandbuf->totbound= MAX2(strandbuf->totbound, origindex[a]); - strandbuf->totbound++; - } + + totface= psmd->dm->getNumFaces(psmd->dm); + origindex= psmd->dm->getFaceDataArray(psmd->dm, CD_ORIGINDEX); + if(origindex) { + for(a=0; a<totface; a++) + strandbuf->totbound= MAX2(strandbuf->totbound, origindex[a]); strandbuf->totbound++; - strandbuf->bound= MEM_callocN(sizeof(StrandBound)*strandbuf->totbound, "StrandBound"); - sbound= strandbuf->bound; - sbound->start= sbound->end= 0; } + strandbuf->totbound++; + strandbuf->bound= MEM_callocN(sizeof(StrandBound)*strandbuf->totbound, "StrandBound"); + sbound= strandbuf->bound; + sbound->start= sbound->end= 0; } } - else if(keys_possible && part->draw&PART_DRAW_KEYS){ - path_nbr=part->keys_step; - if(path_nbr==0) - baked_keys=1; - } - if(orco==0){ - orco=MEM_mallocN(3*sizeof(float),"particle orco"); - orco1=1; + if(sd.orco == 0) { + sd.orco = MEM_mallocN(3 * sizeof(float), "particle orco"); + orco1 = 1; } - if(path_nbr==0) - psys->lattice= psys_get_lattice(re->scene, ob, psys); + if(path_nbr == 0) + psys->lattice = psys_get_lattice(re->scene, ob, psys); /* 3. start creating renderable things */ for(a=0,pa=pars; a<totpart+totchild; a++, pa++, seed++) { random = rng_getFloat(rng); - + /* setup per particle individual stuff */ if(a<totpart){ if(pa->flag & PARS_UNEXIST) continue; pa_time=(cfra-pa->time)/pa->lifetime; - if((part->flag&PART_ABS_TIME)==0){ + if((part->flag&PART_ABS_TIME) == 0){ #if 0 // XXX old animation system - if(ma->ipo){ + if(ma->ipo) { /* correction for lifetime */ - calc_ipo(ma->ipo, 100.0f*pa_time); + calc_ipo(ma->ipo, 100.0f * pa_time); execute_ipo((ID *)ma, ma->ipo); } if(part->ipo){ @@ -1707,51 +1687,25 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem /* get orco */ if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){ tpa=tpsys->particles+pa->num; - psys_particle_on_emitter(psmd,tpart->from,tpa->num,pa->num_dmcache,tpa->fuv,tpa->foffset,co,nor,0,0,orco,0); + psys_particle_on_emitter(psmd,tpart->from,tpa->num,pa->num_dmcache,tpa->fuv,tpa->foffset,co,nor,0,0,sd.orco,0); } else - psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,0); + psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,sd.orco,0); + /* get uvco & mcol */ num= pa->num_dmcache; if(num == DMCACHE_NOTFOUND) if(pa->num < psmd->dm->getNumFaces(psmd->dm)) num= pa->num; - if(uvco && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){ - for(i=0; i<totuv; i++){ - if(num != DMCACHE_NOTFOUND) { - MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE); - mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i); - mtface+=num; - - psys_interpolate_uvs(mtface,mface->v4,pa->fuv,uvco+2*i); - } - else { - uvco[2*i]= 0.0f; - uvco[2*i + 1]= 0.0f; - } - } - } - if(mcol && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){ - for(i=0; i<totcol; i++){ - if(num != DMCACHE_NOTFOUND) { - MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE); - MCol *mc=(MCol*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MCOL,i); - mc+=num*4; - - psys_interpolate_mcol(mc,mface->v4,pa->fuv,mcol+i); - } - else - memset(&mcol[i], 0, sizeof(MCol)); - } - } + get_particle_uvco_mcol(part->from, psmd->dm, pa->fuv, num, &sd); - pa_size=pa->size; + pa_size = pa->size; - r_tilt=1.0f+pa->r_ave[0]; + r_tilt = 1.0f + pa->r_ave[0]; - if(path_nbr){ + if(path_nbr) { cache = psys->pathcache[a]; max_k = (int)cache->steps; } @@ -1760,125 +1714,69 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem } else { ChildParticle *cpa= psys->child+a-totpart; + + if(path_nbr) { + cache = psys->childcache[a-totpart]; + + if(cache->steps < 0) + continue; + + max_k = (int)cache->steps; + } - pa_time=psys_get_child_time(psys, cpa, cfra); + pa_time = psys_get_child_time(psys, cpa, cfra); - if((part->flag&PART_ABS_TIME)==0){ + if((part->flag & PART_ABS_TIME) == 0) { #if 0 // XXX old animation system if(ma->ipo){ /* correction for lifetime */ - calc_ipo(ma->ipo, 100.0f*pa_time); + calc_ipo(ma->ipo, 100.0f * pa_time); execute_ipo((ID *)ma, ma->ipo); } - if(part->ipo){ + if(part->ipo) { /* correction for lifetime */ - calc_ipo(part->ipo, 100.0f*pa_time); + calc_ipo(part->ipo, 100.0f * pa_time); execute_ipo((ID *)part, part->ipo); } #endif // XXX old animation system } - pa_size=psys_get_child_size(psys, cpa, cfra, &pa_time); + pa_size = psys_get_child_size(psys, cpa, cfra, &pa_time); - r_tilt=2.0f*cpa->rand[2]; + r_tilt = 2.0f * cpa->rand[2]; - num= cpa->num; + num = cpa->num; /* get orco */ if(part->childtype == PART_CHILD_FACES) { psys_particle_on_emitter(psmd, PART_FROM_FACE, cpa->num,DMCACHE_ISCHILD, - cpa->fuv,cpa->foffset,co,nor,0,0,orco,0); + cpa->fuv,cpa->foffset,co,nor,0,0,sd.orco,0); } else { ParticleData *par = psys->particles + cpa->parent; psys_particle_on_emitter(psmd, part->from, par->num,DMCACHE_ISCHILD,par->fuv, - par->foffset,co,nor,0,0,orco,0); - } - - if(uvco){ - if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ - for(i=0; i<totuv; i++){ - if(part->childtype==PART_CHILD_FACES){ - MFace *mface=psmd->dm->getFaceData(psmd->dm,cpa->num,CD_MFACE); - - mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i); - mtface+=cpa->num; - - psys_interpolate_uvs(mtface,mface->v4,cpa->fuv,uvco+2*i); - } - else{ - uvco[2*i]=uvco[2*i+1]=0.0f; - } - } - } - else if(ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){ - ParticleData *parent = psys->particles + cpa->parent; - num= parent->num_dmcache; - - if(num == DMCACHE_NOTFOUND) - if(parent->num < psmd->dm->getNumFaces(psmd->dm)) - num= parent->num; - - for(i=0; i<totuv; i++) { - if(num != DMCACHE_NOTFOUND) { - MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE); - mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i); - mtface+=num; - psys_interpolate_uvs(mtface,mface->v4,parent->fuv,uvco+2*i); - } - else { - uvco[2*i]= 0.0f; - uvco[2*i + 1]= 0.0f; - } - } - } + par->foffset,co,nor,0,0,sd.orco,0); } - if(mcol){ - if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ - for(i=0; i<totcol; i++){ - if(part->childtype==PART_CHILD_FACES){ - MFace *mface=psmd->dm->getFaceData(psmd->dm,cpa->num,CD_MFACE); - MCol *mc=(MCol*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MCOL,i); - mc+=cpa->num*4; - - psys_interpolate_mcol(mc,mface->v4,cpa->fuv,mcol+i); - } - else - memset(&mcol[i], 0, sizeof(MCol)); - } - } - else if(ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){ - ParticleData *parent = psys->particles + cpa->parent; - num= parent->num_dmcache; - - if(num == DMCACHE_NOTFOUND) - if(parent->num < psmd->dm->getNumFaces(psmd->dm)) - num= parent->num; - - for(i=0; i<totcol; i++){ - if(num != DMCACHE_NOTFOUND) { - MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE); - MCol *mc=(MCol*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MCOL,i); - mc+=num*4; - - psys_interpolate_mcol(mc,mface->v4,parent->fuv,mcol+i); - } - else - memset(&mcol[i], 0, sizeof(MCol)); - } - } + /* get uvco & mcol */ + if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES) { + get_particle_uvco_mcol(PART_FROM_FACE, psmd->dm, cpa->fuv, cpa->num, &sd); } + else { + ParticleData *parent = psys->particles + cpa->parent; + num = parent->num_dmcache; - dosimplify= psys_render_simplify_params(psys, cpa, simplify); + if(num == DMCACHE_NOTFOUND) + if(parent->num < psmd->dm->getNumFaces(psmd->dm)) + num = parent->num; - if(path_nbr && psys->childcache) { - cache = psys->childcache[a-totpart]; - max_k = (int)cache->steps; + get_particle_uvco_mcol(part->from, psmd->dm, pa->fuv, num, &sd); } + dosimplify = psys_render_simplify_params(psys, cpa, simplify); + if(strandbuf) { if(origindex[cpa->num]+1 > sbound - strandbuf->bound) { sbound= strandbuf->bound + origindex[cpa->num]+1; @@ -1890,17 +1788,17 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem /* surface normal shading setup */ if(ma->mode_l & MA_STR_SURFDIFF) { Mat3MulVecfl(nmat, nor); - surfnor= nor; + sd.surfnor= nor; } else - surfnor= NULL; + sd.surfnor= NULL; /* strand render setup */ if(strandbuf) { strand= RE_findOrAddStrand(obr, obr->totstrand++); strand->buffer= strandbuf; strand->vert= svert; - VECCOPY(strand->orco, orco); + VECCOPY(strand->orco, sd.orco); if(dosimplify) { float *ssimplify= RE_strandren_get_simplify(obr, strand, 1); @@ -1908,9 +1806,9 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem ssimplify[1]= simplify[1]; } - if(surfnor) { + if(sd.surfnor) { float *snor= RE_strandren_get_surfnor(obr, strand, 1); - VECCOPY(snor, surfnor); + VECCOPY(snor, sd.surfnor); } if(dosurfacecache && num >= 0) { @@ -1918,20 +1816,20 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *facenum= num; } - if(uvco) { - for(i=0; i<totuv; i++) { - if(i != override_uv) { + if(sd.uvco) { + for(i=0; i<sd.totuv; i++) { + if(i != sd.override_uv) { float *uv= RE_strandren_get_uv(obr, strand, i, NULL, 1); - uv[0]= uvco[2*i]; - uv[1]= uvco[2*i+1]; + uv[0]= sd.uvco[2*i]; + uv[1]= sd.uvco[2*i+1]; } } } - if(mcol) { - for(i=0; i<totcol; i++) { + if(sd.mcol) { + for(i=0; i<sd.totcol; i++) { MCol *mc= RE_strandren_get_mcol(obr, strand, i, NULL, 1); - *mc = mcol[i]; + *mc = sd.mcol[i]; } } @@ -1947,11 +1845,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem strandlen += VecLenf((cache+k-1)->co, (cache+k)->co); } - for(k=0; k<=path_nbr; k++){ - if(path_nbr){ + if(path_nbr) { + /* render strands */ + for(k=0; k<=path_nbr; k++){ if(k<=max_k){ - //bti->convert_bake_key(bsys,cache+k,0,(void*)&state); - //copy_particle_key(&state,cache+k,0); VECCOPY(state.co,(cache+k)->co); VECCOPY(state.vel,(cache+k)->vel); } @@ -1961,65 +1858,95 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(k > 0) curlen += VecLenf((cache+k-1)->co, (cache+k)->co); time= curlen/strandlen; - } - else{ - time=0.0f; - state.time=cfra; - if(psys_get_particle_state(re->scene, ob, psys, a, &state, 0)==0) - continue; + + VECCOPY(loc,state.co); + MTC_Mat4MulVecfl(re->viewmat,loc); + + if(strandbuf) { + VECCOPY(svert->co, loc); + svert->strandco= -1.0f + 2.0f*time; + svert++; + strand->totvert++; + } + else{ + sd.first = 0; + sd.time = time; + sd.size = hasize; + + if(k==1){ + sd.first = 1; + sd.time = 0.0f; + VECSUB(loc0,loc1,loc); + VECADD(loc0,loc1,loc0); + } + + if(k) + render_new_particle(re, obr, psmd->dm, ma, &sd, loc, loc1, seed); + + VECCOPY(loc1,loc); + } } + } + else { + /* render normal particles */ + time=0.0f; + state.time=cfra; + if(psys_get_particle_state(re->scene,ob,psys,a,&state,0)==0) + continue; + VECCOPY(loc,state.co); if(part->draw_as!=PART_DRAW_BB) MTC_Mat4MulVecfl(re->viewmat,loc); - if(part->draw_as==PART_DRAW_LINE) { - VECCOPY(vel,state.vel); - //VECADD(vel,vel,state.co); - MTC_Mat4Mul3Vecfl(re->viewmat,vel); - //VECSUB(vel,vel,loc); - Normalize(vel); - if(part->draw & PART_DRAW_VEL_LENGTH) - VecMulf(vel,VecLength(state.vel)); - VECADDFAC(loc0,loc,vel,-part->draw_line[0]); - VECADDFAC(loc1,loc,vel,part->draw_line[1]); - - render_new_particle(re,obr,psmd->dm,ma,1,0,1,0.0f,loc0,loc1, - orco,surfnor,totuv,uvco,totcol,mcol,hasize,seed,override_uv,0,0,0); - } - else if(part->draw_as==PART_DRAW_BB) { - VECCOPY(vel,state.vel); - //MTC_Mat4Mul3Vecfl(re->viewmat,vel); - particle_billboard(re,obr,ma,bb_ob,loc,vel,pa_size,part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt), - part->bb_align,part->draw&PART_DRAW_BB_LOCK, - a,totpart+totchild,part->bb_uv_split,part->bb_anim,part->bb_split_offset,random,pa_time,part->bb_offset,uv); - } - else if(strandbuf) { - VECCOPY(svert->co, loc); - svert->strandco= -1.0f + 2.0f*time; - svert++; - strand->totvert++; - } - else{ - if(k==1){ - VECSUB(loc0,loc1,loc); - VECADD(loc0,loc1,loc0); - render_new_particle(re,obr,psmd->dm,ma,path,1,0,0.0f,loc1,loc0, - orco,surfnor,totuv,uvco,totcol,mcol,hasize,seed,override_uv, - adapt,adapt_angle,adapt_pix); - } + switch(part->draw_as) { + case PART_DRAW_LINE: + sd.line = 1; + sd.time = 0.0f; + sd.size = hasize; + + VECCOPY(vel,state.vel); + MTC_Mat4Mul3Vecfl(re->viewmat,vel); + Normalize(vel); - if(path_nbr==0 || k) - render_new_particle(re,obr,psmd->dm,ma,path,0,0,time,loc,loc1, - orco,surfnor,totuv,uvco,totcol,mcol,hasize,seed,override_uv, - adapt,adapt_angle,adapt_pix); + if(part->draw & PART_DRAW_VEL_LENGTH) + VecMulf(vel,VecLength(state.vel)); - VECCOPY(loc1,loc); + VECADDFAC(loc0,loc,vel,-part->draw_line[0]); + VECADDFAC(loc1,loc,vel,part->draw_line[1]); + + render_new_particle(re,obr,psmd->dm,ma,&sd,loc0,loc1,seed); + + break; + + case PART_DRAW_BB: + bb.random = random; + bb.size = pa_size; + bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); + bb.time = pa_time; + bb.num = a; + VECCOPY(bb.vec, loc); + VECCOPY(bb.vel, state.vel); + + particle_billboard(re, obr, ma, &bb); + + break; + + default: + { + HaloRen *har=0; + + har = RE_inithalo_particle(re, obr, psmd->dm, ma, loc, NULL, sd.orco, sd.uvco, hasize, 0.0, seed); + + if(har) har->lay= obr->ob->lay; + + break; + } } } if(orco1==0) - orco+=3; + sd.orco+=3; if(re->test_break(re->tbh)) break; @@ -2034,13 +1961,13 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem #endif // XXX old animation system if(orco1) - MEM_freeN(orco); + MEM_freeN(sd.orco); - if(uvco) - MEM_freeN(uvco); + if(sd.uvco) + MEM_freeN(sd.uvco); - if(mcol) - MEM_freeN(mcol); + if(sd.mcol) + MEM_freeN(sd.mcol); if(uv_name) MEM_freeN(uv_name); @@ -2057,7 +1984,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem psys->lattice= NULL; } - if(path && (ma->mode_l & MA_TANGENT_STR)==0) + if(path_nbr && (ma->mode_l & MA_TANGENT_STR)==0) calc_vertexnormals(re, obr, 0, 0); return 1; @@ -4447,24 +4374,8 @@ void RE_Database_Free(Render *re) static int allow_render_object(Object *ob, int nolamps, int onlyselected, Object *actob) { /* override not showing object when duplis are used with particles */ - if(ob->transflag & OB_DUPLIPARTS){ - int allow= 0; - - if(ob->particlesystem.first) { - ParticleSystem *psys; - ParticleSettings *part; - - for(psys=ob->particlesystem.first; psys; psys=psys->next){ - part=psys->part; - - if(part->draw & PART_DRAW_EMITTER) - allow= 1; - } - } - - if(!allow) - return 0; - } + if(ob->transflag & OB_DUPLIPARTS) + ; /* let particle system(s) handle showing vs. not showing */ else if((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) return 0; diff --git a/source/blender/render/intern/source/raytrace.c b/source/blender/render/intern/source/raytrace.c index ec47df74d04..09d3711885a 100644 --- a/source/blender/render/intern/source/raytrace.c +++ b/source/blender/render/intern/source/raytrace.c @@ -1,5 +1,5 @@ /** - * $Id: $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index d44b49cc706..621831fb341 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -1032,9 +1032,11 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, f har->g= (yn*tg+ zn*ma->g); har->b= (yn*tb+ zn*ma->b); } - if(mtex->texco & 16) { + if(mtex->texco & TEXCO_UV) { har->alfa= tin; } + if(mtex->mapto & MAP_ALPHA) + har->alfa= tin; } } |