forked from bartvdbraak/blender
Some User UI changes: a) Don't ask the user anymore if he wants to overwrite the file when he's doing a simple ctrl-s/ctrl-w; b) Ask for saving on exit when a file has changed, ontheless quit.blend is saved anyway. --> All branch changes, not likely to go into trunk
This commit is contained in:
parent
cf59579d44
commit
3bf1536f5e
@ -70,6 +70,7 @@ extern void BKE_reset_undo(void);
|
|||||||
extern char *BKE_undo_menu_string(void);
|
extern char *BKE_undo_menu_string(void);
|
||||||
extern void BKE_undo_number(int nr);
|
extern void BKE_undo_number(int nr);
|
||||||
extern void BKE_undo_save_quit(void);
|
extern void BKE_undo_save_quit(void);
|
||||||
|
extern int BKE_undo_there(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,18 @@ struct ClothModifierData;
|
|||||||
|
|
||||||
#define CLOTH_MAX_THREAD 2
|
#define CLOTH_MAX_THREAD 2
|
||||||
|
|
||||||
|
typedef struct fc
|
||||||
|
{
|
||||||
|
float *d, *d0; // density
|
||||||
|
float *T, *T0; // temperature
|
||||||
|
float *u, *u0; // velocity in x direction
|
||||||
|
float *v, *v0; // velocity in y direction
|
||||||
|
float *w, *w0; // velocity in z direction
|
||||||
|
} fc;
|
||||||
|
fc *f_init(void);
|
||||||
|
void f_free(fc *m_fc);
|
||||||
|
void step(fc *m_fc, float dt);
|
||||||
|
|
||||||
|
|
||||||
typedef struct ClothVertex {
|
typedef struct ClothVertex {
|
||||||
int flags; /* General flags per vertex. */
|
int flags; /* General flags per vertex. */
|
||||||
@ -69,6 +81,7 @@ typedef struct ClothVertex {
|
|||||||
unsigned int impulse_count; /* same as above */
|
unsigned int impulse_count; /* same as above */
|
||||||
float collball;
|
float collball;
|
||||||
char octantflag;
|
char octantflag;
|
||||||
|
float weight;
|
||||||
} ClothVertex;
|
} ClothVertex;
|
||||||
|
|
||||||
typedef struct ClothSpring {
|
typedef struct ClothSpring {
|
||||||
@ -104,6 +117,7 @@ typedef struct Cloth {
|
|||||||
float (*v)[4]; /* the current velocity of all vertices */
|
float (*v)[4]; /* the current velocity of all vertices */
|
||||||
float (*current_v)[3];
|
float (*current_v)[3];
|
||||||
float (*xconst)[3];
|
float (*xconst)[3];
|
||||||
|
struct fc *m_fc;
|
||||||
} Cloth;
|
} Cloth;
|
||||||
|
|
||||||
/* goal defines */
|
/* goal defines */
|
||||||
|
@ -85,6 +85,7 @@
|
|||||||
#include "BKE_bad_level_calls.h" // for freeAllRad editNurb free_editMesh free_editText free_editArmature
|
#include "BKE_bad_level_calls.h" // for freeAllRad editNurb free_editMesh free_editText free_editArmature
|
||||||
#include "BKE_utildefines.h" // O_BINARY FALSE
|
#include "BKE_utildefines.h" // O_BINARY FALSE
|
||||||
#include "BIF_mainqueue.h" // mainqenter for onload script
|
#include "BIF_mainqueue.h" // mainqenter for onload script
|
||||||
|
#include "BIF_toolbox.h"
|
||||||
#include "mydevice.h"
|
#include "mydevice.h"
|
||||||
#include "nla.h"
|
#include "nla.h"
|
||||||
#include "blendef.h"
|
#include "blendef.h"
|
||||||
@ -617,6 +618,10 @@ void BKE_write_undo(char *name)
|
|||||||
success= BLO_write_file_mem(prevfile, &curundo->memfile, G.fileflags, &err);
|
success= BLO_write_file_mem(prevfile, &curundo->memfile, G.fileflags, &err);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* signals "file needs save" on exit */
|
||||||
|
if(curundo!=NULL && curundo->prev!=NULL)
|
||||||
|
U.uiflag |= USER_UNDOSAVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */
|
/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */
|
||||||
@ -694,7 +699,7 @@ char *BKE_undo_menu_string(void)
|
|||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* saves quit.blend */
|
/* saves quit.blend */
|
||||||
void BKE_undo_save_quit(void)
|
void BKE_undo_save_quit(void)
|
||||||
{
|
{
|
||||||
UndoElem *uel;
|
UndoElem *uel;
|
||||||
|
@ -78,6 +78,22 @@
|
|||||||
#include "BIF_space.h"
|
#include "BIF_space.h"
|
||||||
#include "mydevice.h"
|
#include "mydevice.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif // WIN32
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define GL_GLEXT_LEGACY 1
|
||||||
|
#include <OpenGL/gl.h>
|
||||||
|
#include <OpenGL/glu.h>
|
||||||
|
#else
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#if defined(__sun__) && !defined(__sparc__)
|
||||||
|
#include <mesa/glu.h>
|
||||||
|
#else
|
||||||
|
#include <GL/glu.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
void tstart ( void )
|
void tstart ( void )
|
||||||
{}
|
{}
|
||||||
@ -482,6 +498,309 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define AMBIENT 50
|
||||||
|
#define DECAY 0.04f
|
||||||
|
#define ALMOST_EQUAL(a, b) ((fabs(a-b)<0.00001f)?1:0)
|
||||||
|
|
||||||
|
// cube vertices
|
||||||
|
GLfloat cv[][3] = {
|
||||||
|
{1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f},
|
||||||
|
{1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f}
|
||||||
|
};
|
||||||
|
|
||||||
|
// edges have the form edges[n][0][xyz] + t*edges[n][1][xyz]
|
||||||
|
float edges[12][2][3] = {
|
||||||
|
{{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
|
||||||
|
{{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
|
||||||
|
{{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
|
||||||
|
{{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
|
||||||
|
|
||||||
|
{{1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}},
|
||||||
|
{{-1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}},
|
||||||
|
{{-1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
|
||||||
|
{{1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
|
||||||
|
|
||||||
|
{{-1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}},
|
||||||
|
{{-1.0f, -1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}},
|
||||||
|
{{-1.0f, -1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}},
|
||||||
|
{{-1.0f, 1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}}
|
||||||
|
};
|
||||||
|
|
||||||
|
void light_ray(unsigned char* _texture_data, int _ray_templ[4096][3], int x, int y, int z, int n, float decay)
|
||||||
|
{
|
||||||
|
int xx = x, yy = y, zz = z, i = 0;
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
int l = 255;
|
||||||
|
float d;
|
||||||
|
|
||||||
|
do {
|
||||||
|
offset = ((((zz*n) + yy)*n + xx) << 2);
|
||||||
|
if (_texture_data[offset + 2] > 0)
|
||||||
|
_texture_data[offset + 2] = (unsigned char) ((_texture_data[offset + 2] + l)*0.5f);
|
||||||
|
else
|
||||||
|
_texture_data[offset + 2] = (unsigned char) l;
|
||||||
|
d = _texture_data[offset+1];
|
||||||
|
if (l > AMBIENT) {
|
||||||
|
l -= d*decay;
|
||||||
|
if (l < AMBIENT)
|
||||||
|
l = AMBIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
xx = x + _ray_templ[i][0];
|
||||||
|
yy = y + _ray_templ[i][1];
|
||||||
|
zz = z + _ray_templ[i][2];
|
||||||
|
|
||||||
|
} while ((xx>=0)&&(xx<n)&&(yy>=0)&&(yy<n)&&(zz>=0)&&(zz<n));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cast_light(unsigned char* _texture_data, int _ray_templ[4096][3], float *_light_dir, int n /*edgelen*/)
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
int sx = (_light_dir[0]>0) ? 0 : n-1;
|
||||||
|
int sy = (_light_dir[1]>0) ? 0 : n-1;
|
||||||
|
int sz = (_light_dir[2]>0) ? 0 : n-1;
|
||||||
|
|
||||||
|
float decay = 1.0f/(n*DECAY);
|
||||||
|
|
||||||
|
for (i=0; i<n; i++)
|
||||||
|
for (j=0; j<n; j++) {
|
||||||
|
if (!ALMOST_EQUAL(_light_dir[0], 0))
|
||||||
|
light_ray(_texture_data, _ray_templ, sx,i,j,n,decay);
|
||||||
|
if (!ALMOST_EQUAL(_light_dir[1], 0))
|
||||||
|
light_ray(_texture_data, _ray_templ, i,sy,j,n,decay);
|
||||||
|
if (!ALMOST_EQUAL(_light_dir[2], 0))
|
||||||
|
light_ray(_texture_data, _ray_templ, i,j,sz,n,decay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_ray_templ(int _ray_templ[4096][3], float *_light_dir, int edgelen)
|
||||||
|
{
|
||||||
|
float fx = 0.0f, fy = 0.0f, fz = 0.0f;
|
||||||
|
int x = 0, y = 0, z = 0;
|
||||||
|
float lx = _light_dir[0] + 0.000001f, ly = _light_dir[1] + 0.000001f, lz = _light_dir[2] + 0.000001f;
|
||||||
|
int xinc = (lx > 0) ? 1 : -1;
|
||||||
|
int yinc = (ly > 0) ? 1 : -1;
|
||||||
|
int zinc = (lz > 0) ? 1 : -1;
|
||||||
|
float tx, ty, tz;
|
||||||
|
int i = 1;
|
||||||
|
int len = 0;
|
||||||
|
int maxlen = 3*edgelen*edgelen;
|
||||||
|
_ray_templ[0][0] = _ray_templ[0][2] = _ray_templ[0][2] = 0;
|
||||||
|
|
||||||
|
while (len <= maxlen)
|
||||||
|
{
|
||||||
|
// fx + t*lx = (x+1) -> t = (x+1-fx)/lx
|
||||||
|
tx = (x+xinc-fx)/lx;
|
||||||
|
ty = (y+yinc-fy)/ly;
|
||||||
|
tz = (z+zinc-fz)/lz;
|
||||||
|
|
||||||
|
if ((tx<=ty)&&(tx<=tz)) {
|
||||||
|
_ray_templ[i][0] = _ray_templ[i-1][0] + xinc;
|
||||||
|
x =+ xinc;
|
||||||
|
fx = x;
|
||||||
|
|
||||||
|
if (ALMOST_EQUAL(ty,tx)) {
|
||||||
|
_ray_templ[i][1] = _ray_templ[i-1][1] + yinc;
|
||||||
|
y += yinc;
|
||||||
|
fy = y;
|
||||||
|
} else {
|
||||||
|
_ray_templ[i][1] = _ray_templ[i-1][1];
|
||||||
|
fy += tx*ly;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ALMOST_EQUAL(tz,tx)) {
|
||||||
|
_ray_templ[i][2] = _ray_templ[i-1][2] + zinc;
|
||||||
|
z += zinc;
|
||||||
|
fz = z;
|
||||||
|
} else {
|
||||||
|
_ray_templ[i][2] = _ray_templ[i-1][2];
|
||||||
|
fz += tx*lz;
|
||||||
|
}
|
||||||
|
} else if ((ty<tx)&&(ty<=tz)) {
|
||||||
|
_ray_templ[i][0] = _ray_templ[i-1][0];
|
||||||
|
fx += ty*lx;
|
||||||
|
|
||||||
|
_ray_templ[i][1] = _ray_templ[i-1][1] + yinc;
|
||||||
|
y += yinc;
|
||||||
|
fy = y;
|
||||||
|
|
||||||
|
if (ALMOST_EQUAL(tz,ty)) {
|
||||||
|
_ray_templ[i][2] = _ray_templ[i-1][2] + zinc;
|
||||||
|
z += zinc;
|
||||||
|
fz = z;
|
||||||
|
} else {
|
||||||
|
_ray_templ[i][2] = _ray_templ[i-1][2];
|
||||||
|
fz += ty*lz;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// assert((tz<tx)&&(tz<ty));
|
||||||
|
if((tz<tx)&&(tz<ty))
|
||||||
|
break;
|
||||||
|
|
||||||
|
_ray_templ[i][0] = _ray_templ[i-1][0];
|
||||||
|
fx += tz*lx;
|
||||||
|
_ray_templ[i][1] = _ray_templ[i-1][1];
|
||||||
|
fy += tz*ly;
|
||||||
|
_ray_templ[i][2] = _ray_templ[i-1][2] + zinc;
|
||||||
|
z += zinc;
|
||||||
|
fz = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = _ray_templ[i][0]*_ray_templ[i][0]
|
||||||
|
+ _ray_templ[i][1]*_ray_templ[i][1]
|
||||||
|
+ _ray_templ[i][2]*_ray_templ[i][2];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
int intersect_edges(float ret[12][3], float a, float b, float c, float d)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float t;
|
||||||
|
Vec3 p;
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
for (i=0; i<12; i++) {
|
||||||
|
t = -(a*edges[i][0][0] + b*edges[i][0][1] + c*edges[i][0][2] + d)
|
||||||
|
/ (a*edges[i][1][0] + b*edges[i][1][1] + c*edges[i][1][2]);
|
||||||
|
if ((t>0)&&(t<2)) {
|
||||||
|
ret[num][0] = edges[i][0][0] + edges[i][1][0]*t;
|
||||||
|
ret[num][1] = edges[i][0][1] + edges[i][1][1]*t;
|
||||||
|
ret[num][2] = edges[i][0][2] + edges[i][1][2]*t;
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_slices(float m[][4])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
Vec3 viewdir(m[0][2], m[1][2], m[2][2]);
|
||||||
|
viewdir.Normalize();
|
||||||
|
// find cube vertex that is closest to the viewer
|
||||||
|
for (i=0; i<8; i++) {
|
||||||
|
float x = cv[i][0] + viewdir[0];
|
||||||
|
float y = cv[i][1] + viewdir[1];
|
||||||
|
float z = cv[i][2] + viewdir[2];
|
||||||
|
if ((x>=-1.0f)&&(x<=1.0f)
|
||||||
|
&&(y>=-1.0f)&&(y<=1.0f)
|
||||||
|
&&(z>=-1.0f)&&(z<=1.0f))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(i != 8) return;
|
||||||
|
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
// our slices are defined by the plane equation a*x + b*y +c*z + d = 0
|
||||||
|
// (a,b,c), the plane normal, are given by viewdir
|
||||||
|
// d is the parameter along the view direction. the first d is given by
|
||||||
|
// inserting previously found vertex into the plane equation
|
||||||
|
float d0 = -(viewdir[0]*cv[i][0] + viewdir[1]*cv[i][1] + viewdir[2]*cv[i][2]);
|
||||||
|
float dd = 2*d0/64.0f;
|
||||||
|
int n = 0;
|
||||||
|
for (float d = -d0; d < d0; d += dd) {
|
||||||
|
// intersect_edges returns the intersection points of all cube edges with
|
||||||
|
// the given plane that lie within the cube
|
||||||
|
float pt[12][3];
|
||||||
|
int num = intersect_edges(pt, viewdir[0], viewdir[1], viewdir[2], d);
|
||||||
|
|
||||||
|
if (num > 2) {
|
||||||
|
// sort points to get a convex polygon
|
||||||
|
// std::sort(pt.begin()+1, pt.end(), Convexcomp(pt[0], viewdir));
|
||||||
|
int shuffled = 1;
|
||||||
|
|
||||||
|
while(shuffled)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
shuffled = 0;
|
||||||
|
|
||||||
|
for(j = 0; j < num-1; j++)
|
||||||
|
{
|
||||||
|
// Vec3 va = a-p0, vb = b-p0;
|
||||||
|
// return dot(up, cross(va, vb)) >= 0;
|
||||||
|
float va[3], vb[3], vc[3];
|
||||||
|
|
||||||
|
VECSUB(va, pt[j], pt[0]);
|
||||||
|
VECSUB(vb, pt[j+1], pt[0]);
|
||||||
|
Crossf(vc, va, vb);
|
||||||
|
|
||||||
|
if(INPR(viewdir, vc)>= 0)
|
||||||
|
{
|
||||||
|
float temp[3];
|
||||||
|
|
||||||
|
VECCOPY(temp, pt[j]);
|
||||||
|
VECCOPY(pt[j], pt[j+1]);
|
||||||
|
VECCOPY(pt[j+1], temp);
|
||||||
|
|
||||||
|
shuffled = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_3D);
|
||||||
|
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
||||||
|
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _prog[0]);
|
||||||
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
|
glBindTexture(GL_TEXTURE_3D, _txt[0]);
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
for (i=0; i<num; i++){
|
||||||
|
glColor3f(1.0, 1.0, 1.0);
|
||||||
|
glTexCoord3d((pt[i][0]+1.0)/2.0, (-pt[i][1]+1)/2.0, (pt[i][2]+1.0)/2.0);
|
||||||
|
glVertex3f(pt[i][0], pt[i][1], pt[i][2]);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void draw(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
glClearColor(0, 0, 0, 0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
gluLookAt(0, 0, -_dist, 0, 0, 0, 0, 1, 0);
|
||||||
|
|
||||||
|
float m[4][4];
|
||||||
|
build_rotmatrix(m, _quat);
|
||||||
|
|
||||||
|
glMultMatrixf(&m[0][0]);
|
||||||
|
|
||||||
|
if (_draw_cube)
|
||||||
|
draw_cube();
|
||||||
|
draw_slices(m, _draw_slice_outline);
|
||||||
|
|
||||||
|
if (_dispstring != NULL) {
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadMatrixd(_ortho_m);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_3D);
|
||||||
|
glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
||||||
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||||
|
glRasterPos2i(-_sx/2 + 10, _sy/2 - 15);
|
||||||
|
|
||||||
|
print_string(_dispstring);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadMatrixd(_persp_m);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
/************************************************
|
/************************************************
|
||||||
* clothModifier_do - main simulation function
|
* clothModifier_do - main simulation function
|
||||||
************************************************/
|
************************************************/
|
||||||
@ -499,7 +818,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
|
|||||||
unsigned int framenr = (float)G.scene->r.cfra;
|
unsigned int framenr = (float)G.scene->r.cfra;
|
||||||
float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0);
|
float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0);
|
||||||
ListBase *effectors = NULL;
|
ListBase *effectors = NULL;
|
||||||
float deltaTime = current_time - clmd->sim_parms->sim_time;
|
float deltaTime = current_time - clmd->sim_parms->sim_time;
|
||||||
|
unsigned char* _texture_data=NULL;
|
||||||
|
float _light_dir[3];
|
||||||
|
int _ray_templ[4096][3];
|
||||||
|
|
||||||
clmd->sim_parms->dt = 1.0f / (clmd->sim_parms->stepsPerFrame * G.scene->r.frs_sec);
|
clmd->sim_parms->dt = 1.0f / (clmd->sim_parms->stepsPerFrame * G.scene->r.frs_sec);
|
||||||
|
|
||||||
@ -577,7 +899,14 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
|
|||||||
|
|
||||||
cloth = clmd->clothObject;
|
cloth = clmd->clothObject;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
deltaTime = 0;
|
||||||
|
while( deltaTime < 1.0)
|
||||||
|
{
|
||||||
|
step(cloth->m_fc, 0.1);
|
||||||
|
deltaTime+=0.1;
|
||||||
|
}
|
||||||
|
*/
|
||||||
clmd->clothObject->old_solver_type = clmd->sim_parms->solver_type;
|
clmd->clothObject->old_solver_type = clmd->sim_parms->solver_type;
|
||||||
|
|
||||||
// Insure we have a clmd->clothObject, in case allocation failed.
|
// Insure we have a clmd->clothObject, in case allocation failed.
|
||||||
@ -632,6 +961,34 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cloth = clmd->clothObject;
|
||||||
|
/*
|
||||||
|
if(cloth)
|
||||||
|
{
|
||||||
|
if (_texture_data == NULL)
|
||||||
|
_texture_data = (unsigned char*) malloc((30+2)*(30+2)*(30+2)*4);
|
||||||
|
|
||||||
|
for (i=0; i<(30+2)*(30+2)*(30+2); i++) {
|
||||||
|
_texture_data[(i<<2)] = (unsigned char) (cloth->m_fc->T[i] * 255.0f);
|
||||||
|
_texture_data[(i<<2)+1] = (unsigned char) (cloth->m_fc->d[i] * 255.0f);
|
||||||
|
_texture_data[(i<<2)+2] = 0;
|
||||||
|
_texture_data[(i<<2)+3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
// from ligth constructor
|
||||||
|
_light_dir[0] = -1.0f;
|
||||||
|
_light_dir[1] = 0.5f;
|
||||||
|
_light_dir[2] = 0.0f;
|
||||||
|
|
||||||
|
gen_ray_templ(_ray_templ, _light_dir, 30 + 2);
|
||||||
|
|
||||||
|
cast_light(_texture_data, _ray_templ, _light_dir, 30+2);
|
||||||
|
|
||||||
|
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||||
|
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 30+2, 30+2, 30+2, 0, GL_RGBA, GL_UNSIGNED_BYTE, _texture_data);
|
||||||
|
free(_texture_data);
|
||||||
|
}
|
||||||
|
*/
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,6 +1010,8 @@ void cloth_free_modifier (ClothModifierData *clmd)
|
|||||||
|
|
||||||
if (cloth)
|
if (cloth)
|
||||||
{
|
{
|
||||||
|
f_free(cloth->m_fc);
|
||||||
|
|
||||||
// If our solver provides a free function, call it
|
// If our solver provides a free function, call it
|
||||||
if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free)
|
if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free)
|
||||||
{
|
{
|
||||||
@ -834,6 +1193,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
|
|||||||
unsigned int numverts = dm->getNumVerts(dm);
|
unsigned int numverts = dm->getNumVerts(dm);
|
||||||
MVert *mvert = CDDM_get_verts(dm);
|
MVert *mvert = CDDM_get_verts(dm);
|
||||||
float tnull[3] = {0,0,0};
|
float tnull[3] = {0,0,0};
|
||||||
|
Cloth *cloth = NULL;
|
||||||
|
|
||||||
/* If we have a clothObject, free it. */
|
/* If we have a clothObject, free it. */
|
||||||
if (clmd->clothObject != NULL)
|
if (clmd->clothObject != NULL)
|
||||||
@ -851,6 +1211,10 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
|
|||||||
modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject.");
|
modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cloth = clmd->clothObject;
|
||||||
|
|
||||||
|
cloth->m_fc = f_init();
|
||||||
|
|
||||||
switch (ob->type)
|
switch (ob->type)
|
||||||
{
|
{
|
||||||
@ -1228,3 +1592,333 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
|
|||||||
* SPRING NETWORK BUILDING IMPLEMENTATION END
|
* SPRING NETWORK BUILDING IMPLEMENTATION END
|
||||||
***************************************************************************************/
|
***************************************************************************************/
|
||||||
|
|
||||||
|
#define F_ITER 20
|
||||||
|
#define m_diffusion 0.00001f
|
||||||
|
#define m_viscosity 0.000f
|
||||||
|
#define m_buoyancy 1.5f
|
||||||
|
#define m_cooling 1.0f
|
||||||
|
#define m_vc_eps 4.0f
|
||||||
|
|
||||||
|
#define GRID_SIZE 30
|
||||||
|
#define SIZE ((GRID_SIZE+2)*(GRID_SIZE+2)*(GRID_SIZE+2))
|
||||||
|
#define _I(x,y,z) (((z)<<10)+((y)<<5)+x)
|
||||||
|
|
||||||
|
#define SWAPFPTR(x,y) {float *t=x;x=y;y=t;}
|
||||||
|
|
||||||
|
float buffers[10][SIZE];
|
||||||
|
float sd[SIZE], su[SIZE], sv[SIZE], sw[SIZE], sT[SIZE];
|
||||||
|
|
||||||
|
|
||||||
|
// nothing to do in this mode
|
||||||
|
// add code for 2nd mode
|
||||||
|
void set_bnd(int b, float* x, int N)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void lin_solve(int b, float *x, float *x0, float a, float c, int N)
|
||||||
|
{
|
||||||
|
float cRecip = 1.0 / c;
|
||||||
|
int i, j, k, l;
|
||||||
|
for (l=0; l<F_ITER; l++)
|
||||||
|
{
|
||||||
|
for (k=1; k<=N; k++)
|
||||||
|
{
|
||||||
|
for (j=1; j<=N; j++)
|
||||||
|
{
|
||||||
|
for (i=1; i<=N; i++)
|
||||||
|
{
|
||||||
|
x[_I(i,j,k)] = (x0[_I(i,j,k)] + a*(
|
||||||
|
x[_I(i-1,j,k)]+x[_I(i+1,j,k)]+
|
||||||
|
x[_I(i,j-1,k)]+x[_I(i,j+1,k)]+
|
||||||
|
x[_I(i,j,k-1)]+x[_I(i,j,k+1)]))*cRecip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_bnd(b, x, N);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_source(float* src, float *dst, float dt, int N)
|
||||||
|
{
|
||||||
|
int i, size=(N+2)*(N+2)*(N+2);
|
||||||
|
|
||||||
|
for (i=0; i<size; i++)
|
||||||
|
dst[i] += src[i]*dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_buoyancy(float *v, float* T, float dt, float buoyancy, int N)
|
||||||
|
{
|
||||||
|
int i, size=(N+2)*(N+2)*(N+2);
|
||||||
|
|
||||||
|
for (i=0; i<size; i++)
|
||||||
|
v[i] += -T[i]*buoyancy*dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void diffuse(int b, float* x0, float* x, float diff, float dt, int N)
|
||||||
|
{
|
||||||
|
float a=dt*diff*N*N*N;
|
||||||
|
lin_solve(b, x, x0, a, 1 + 6 * a, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void advect(int b, float* x0, float* x, float* uu, float* vv, float* ww, float dt, int N)
|
||||||
|
{
|
||||||
|
int i, j, k, i0, j0, k0, i1, j1, k1;
|
||||||
|
float sx0, sx1, sy0, sy1, sz0, sz1, v0, v1;
|
||||||
|
float xx, yy, zz, dt0;
|
||||||
|
dt0 = dt*N;
|
||||||
|
for (k=1; k<=N; k++)
|
||||||
|
{
|
||||||
|
for (j=1; j<=N; j++)
|
||||||
|
{
|
||||||
|
for (i=1; i<=N; i++)
|
||||||
|
{
|
||||||
|
xx = i-dt0*uu[_I(i,j,k)];
|
||||||
|
yy = j-dt0*vv[_I(i,j,k)];
|
||||||
|
zz = k-dt0*ww[_I(i,j,k)];
|
||||||
|
if (xx<0.5) xx=0.5f; if (xx>N+0.5) xx=N+0.5f; i0=(int)xx; i1=i0+1;
|
||||||
|
if (yy<0.5) yy=0.5f; if (yy>N+0.5) yy=N+0.5f; j0=(int)yy; j1=j0+1;
|
||||||
|
if (zz<0.5) zz=0.5f; if (zz>N+0.5) zz=N+0.5f; k0=(int)zz; k1=k0+1;
|
||||||
|
sx1 = xx-i0; sx0 = 1-sx1;
|
||||||
|
sy1 = yy-j0; sy0 = 1-sy1;
|
||||||
|
sz1 = zz-k0; sz0 = 1-sz1;
|
||||||
|
v0 = sx0*(sy0*x0[_I(i0,j0,k0)]+sy1*x0[_I(i0,j1,k0)])+sx1*(sy0*x0[_I(i1,j0,k0)]+sy1*x0[_I(i1,j1,k0)]);
|
||||||
|
v1 = sx0*(sy0*x0[_I(i0,j0,k1)]+sy1*x0[_I(i0,j1,k1)])+sx1*(sy0*x0[_I(i1,j0,k1)]+sy1*x0[_I(i1,j1,k1)]);
|
||||||
|
x[_I(i,j,k)] = sz0*v0 + sz1*v1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_bnd(b,x, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
void advect_cool(int b, float* x0, float* x, float* y0, float* y, float* uu, float* vv, float* ww, float dt, float cooling, int N)
|
||||||
|
{
|
||||||
|
int i, j, k, i0, j0, k0, i1, j1, k1;
|
||||||
|
float sx0, sx1, sy0, sy1, sz0, sz1, v0, v1;
|
||||||
|
float xx, yy, zz, dt0, c0;
|
||||||
|
dt0 = dt*N;
|
||||||
|
c0 = 1.0f - cooling*dt;
|
||||||
|
for (k=1; k<=N; k++)
|
||||||
|
{
|
||||||
|
for (j=1; j<=N; j++)
|
||||||
|
{
|
||||||
|
for (i=1; i<=N; i++)
|
||||||
|
{
|
||||||
|
xx = i-dt0*uu[_I(i,j,k)];
|
||||||
|
yy = j-dt0*vv[_I(i,j,k)];
|
||||||
|
zz = k-dt0*ww[_I(i,j,k)];
|
||||||
|
if (xx<0.5) xx=0.5f; if (xx>N+0.5) xx=N+0.5f; i0=(int)xx; i1=i0+1;
|
||||||
|
if (yy<0.5) yy=0.5f; if (yy>N+0.5) yy=N+0.5f; j0=(int)yy; j1=j0+1;
|
||||||
|
if (zz<0.5) zz=0.5f; if (zz>N+0.5) zz=N+0.5f; k0=(int)zz; k1=k0+1;
|
||||||
|
sx1 = xx-i0; sx0 = 1-sx1;
|
||||||
|
sy1 = yy-j0; sy0 = 1-sy1;
|
||||||
|
sz1 = zz-k0; sz0 = 1-sz1;
|
||||||
|
v0 = sx0*(sy0*x0[_I(i0,j0,k0)]+sy1*x0[_I(i0,j1,k0)])+sx1*(sy0*x0[_I(i1,j0,k0)]+sy1*x0[_I(i1,j1,k0)]);
|
||||||
|
v1 = sx0*(sy0*x0[_I(i0,j0,k1)]+sy1*x0[_I(i0,j1,k1)])+sx1*(sy0*x0[_I(i1,j0,k1)]+sy1*x0[_I(i1,j1,k1)]);
|
||||||
|
x[_I(i,j,k)] = sz0*v0 + sz1*v1;
|
||||||
|
v0 = sx0*(sy0*y0[_I(i0,j0,k0)]+sy1*y0[_I(i0,j1,k0)])+sx1*(sy0*y0[_I(i1,j0,k0)]+sy1*y0[_I(i1,j1,k0)]);
|
||||||
|
v1 = sx0*(sy0*y0[_I(i0,j0,k1)]+sy1*y0[_I(i0,j1,k1)])+sx1*(sy0*y0[_I(i1,j0,k1)]+sy1*y0[_I(i1,j1,k1)]);
|
||||||
|
y[_I(i,j,k)] = (sz0*v0 + sz1*v1)*c0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_bnd(b,x, N);
|
||||||
|
set_bnd(b,y, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fproject(float* u, float* u0, float* v, float* v0, float* w, float* w0, int N)
|
||||||
|
{
|
||||||
|
float* p = u0; float* div = v0; // temporary buffers, use old velocity buffers
|
||||||
|
int i, j, k;
|
||||||
|
float h;
|
||||||
|
h = 1.0f/N;
|
||||||
|
for (k=1; k<=N; k++) {
|
||||||
|
for (j=1; j<=N; j++) {
|
||||||
|
for (i=1; i<=N; i++) {
|
||||||
|
div[_I(i,j,k)] = -h*(
|
||||||
|
u[_I(i+1,j,k)]-u[_I(i-1,j,k)]+
|
||||||
|
v[_I(i,j+1,k)]-v[_I(i,j-1,k)]+
|
||||||
|
w[_I(i,j,k+1)]-w[_I(i,j,k-1)])*0.5;
|
||||||
|
p[_I(i,j,k)] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_bnd(0, div, N);
|
||||||
|
set_bnd(0, p, N);
|
||||||
|
lin_solve(0, p, div, 1, 6, N);
|
||||||
|
|
||||||
|
for (k=1; k<=N; k++) {
|
||||||
|
for (j=1; j<=N; j++) {
|
||||||
|
for (i=1; i<=N; i++) {
|
||||||
|
u[_I(i,j,k)] -= (p[_I(i+1,j,k)]-p[_I(i-1,j,k)])*0.5*N;
|
||||||
|
v[_I(i,j,k)] -= (p[_I(i,j+1,k)]-p[_I(i,j-1,k)])*0.5*N;
|
||||||
|
w[_I(i,j,k)] -= (p[_I(i,j,k+1)]-p[_I(i,j,k-1)])*0.5*N;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_bnd(1, u, N);
|
||||||
|
set_bnd(2, v, N);
|
||||||
|
set_bnd(3, w, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vorticity_confinement(float *T0, float* u, float* u0, float* v, float* v0, float* w, float* w0, float dt, float vc_eps, int N)
|
||||||
|
{
|
||||||
|
int i,j,k,ijk;
|
||||||
|
float *curlx = u0, *curly = v0, *curlz=w0, *curl=T0; // temp buffers
|
||||||
|
float dt0 = dt * vc_eps;
|
||||||
|
float x,y,z;
|
||||||
|
|
||||||
|
|
||||||
|
for (k=1; k<N; k++) {
|
||||||
|
for (j=1; j<N; j++) {
|
||||||
|
for (i=1; i<N; i++) {
|
||||||
|
ijk = _I(i,j,k);
|
||||||
|
// curlx = dw/dy - dv/dz
|
||||||
|
x = curlx[ijk] = (w[_I(i,j+1,k)] - w[_I(i,j-1,k)]) * 0.5f -
|
||||||
|
(v[_I(i,j,k+1)] - v[_I(i,j,k-1)]) * 0.5f;
|
||||||
|
|
||||||
|
// curly = du/dz - dw/dx
|
||||||
|
y = curly[ijk] = (u[_I(i,j,k+1)] - u[_I(i,j,k-1)]) * 0.5f -
|
||||||
|
(w[_I(i+1,j,k)] - w[_I(i-1,j,k)]) * 0.5f;
|
||||||
|
|
||||||
|
// curlz = dv/dx - du/dy
|
||||||
|
z = curlz[ijk] = (v[_I(i+1,j,k)] - v[_I(i-1,j,k)]) * 0.5f -
|
||||||
|
(u[_I(i,j+1,k)] - u[_I(i,j-1,k)]) * 0.5f;
|
||||||
|
|
||||||
|
// curl = |curl|
|
||||||
|
curl[ijk] = sqrtf(x*x+y*y+z*z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k=1; k<N; k++) {
|
||||||
|
for (j=1; j<N; j++) {
|
||||||
|
for (i=1; i<N; i++) {
|
||||||
|
float Nx = (curl[_I(i+1,j,k)] - curl[_I(i-1,j,k)]) * 0.5f;
|
||||||
|
float Ny = (curl[_I(i,j+1,k)] - curl[_I(i,j-1,k)]) * 0.5f;
|
||||||
|
float Nz = (curl[_I(i,j,k+1)] - curl[_I(i,j,k-1)]) * 0.5f;
|
||||||
|
float len1 = 1.0f/(sqrtf(Nx*Nx+Ny*Ny+Nz*Nz)+0.0000001f);
|
||||||
|
ijk = _I(i,j,k);
|
||||||
|
Nx *= len1;
|
||||||
|
Ny *= len1;
|
||||||
|
Nz *= len1;
|
||||||
|
u[ijk] += (Ny*curlz[ijk] - Nz*curly[ijk]) * dt0;
|
||||||
|
v[ijk] += (Nz*curlx[ijk] - Nx*curlz[ijk]) * dt0;
|
||||||
|
w[ijk] += (Nx*curly[ijk] - Ny*curlx[ijk]) * dt0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define DIFFUSE
|
||||||
|
#define ADVECT
|
||||||
|
|
||||||
|
void vel_step(float *su, float *sv, float *sw, float* u, float* u0, float* v, float* v0, float* w, float* w0, float *T, float *T0, float dt, int N)
|
||||||
|
{
|
||||||
|
add_source(su, u, dt, N);
|
||||||
|
add_source(sv, v, dt, N);
|
||||||
|
add_source(sw, w, dt, N);
|
||||||
|
|
||||||
|
// external force
|
||||||
|
add_buoyancy(v, T, dt, m_buoyancy, N); // better is using gravity normal vector instead of v
|
||||||
|
|
||||||
|
vorticity_confinement(T0, u, u0, v, v0, w, w0, dt, m_vc_eps, N);
|
||||||
|
|
||||||
|
#ifdef DIFFUSE
|
||||||
|
SWAPFPTR(u0, u); SWAPFPTR(v0, v); SWAPFPTR(w0, w);
|
||||||
|
diffuse(1, u0, u, m_viscosity, dt, N);
|
||||||
|
diffuse(2, v0, v, m_viscosity, dt, N);
|
||||||
|
diffuse(3, w0, w, m_viscosity, dt, N);
|
||||||
|
fproject(u, u0, v, v0, w, w0, N);
|
||||||
|
#endif
|
||||||
|
#ifdef ADVECT
|
||||||
|
SWAPFPTR(u0, u); SWAPFPTR(v0, v); SWAPFPTR(w0, w);
|
||||||
|
advect(1, u0, u, u0, v0, w0, dt, N);
|
||||||
|
advect(2, v0, v, u0, v0, w0, dt, N);
|
||||||
|
advect(3, w0, w, u0, v0, w0, dt, N);
|
||||||
|
fproject(u, u0, v, v0, w, w0, N);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void dens_step(float *sd, float *d, float *d0, float *u, float *v, float *w, float dt, int N)
|
||||||
|
{
|
||||||
|
add_source(sd, d, dt, N);
|
||||||
|
#ifdef DIFFUSE
|
||||||
|
SWAPFPTR(d0, d);
|
||||||
|
diffuse(0, d0, d, m_diffusion, dt, N);
|
||||||
|
#endif
|
||||||
|
#ifdef ADVECT
|
||||||
|
SWAPFPTR(d0, d);
|
||||||
|
advect(0, d0, d, u, v, w, dt, N);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void dens_temp_step(float *sd, float *sT, float *T, float *T0, float *d, float *d0, float *u, float *v, float *w, float dt, int N)
|
||||||
|
{
|
||||||
|
add_source(sd, d, dt, N);
|
||||||
|
add_source(sT, T, dt, N);
|
||||||
|
SWAPFPTR(d0, d);
|
||||||
|
diffuse(0, d0, d, m_diffusion, dt, N);
|
||||||
|
SWAPFPTR(d0, d);
|
||||||
|
SWAPFPTR(T0, T);
|
||||||
|
advect_cool(0, d0, d, T0, T, u, v, w, dt, m_cooling, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
void step(fc *m_fc, float dt)
|
||||||
|
{
|
||||||
|
vel_step(su, sv, sw, m_fc->u, m_fc->u0, m_fc->v, m_fc->v0, m_fc->w, m_fc->w0, m_fc->T, m_fc->T0, dt, GRID_SIZE);
|
||||||
|
dens_temp_step(sd, sT, m_fc->T, m_fc->T0, m_fc->d, m_fc->d0, m_fc->u, m_fc->v, m_fc->w, dt, GRID_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void clear_buffer(float* x)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<SIZE; i++) {
|
||||||
|
x[i] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_sources(float *sd, float *su, float *sv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<SIZE; i++) {
|
||||||
|
sd[i] = su[i] = sv[i] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fc *f_init(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
fc *m_fc = MEM_callocN(sizeof(fc),
|
||||||
|
"f_c");
|
||||||
|
for (i=0; i<10; i++)
|
||||||
|
clear_buffer(buffers[i]);
|
||||||
|
|
||||||
|
i=0;
|
||||||
|
m_fc->d=buffers[i++]; m_fc->d0=buffers[i++];
|
||||||
|
m_fc->T=buffers[i++]; m_fc->T0=buffers[i++];
|
||||||
|
m_fc->u=buffers[i++]; m_fc->u0=buffers[i++];
|
||||||
|
m_fc->v=buffers[i++]; m_fc->v0=buffers[i++];
|
||||||
|
m_fc->w=buffers[i++]; m_fc->w0=buffers[i++];
|
||||||
|
|
||||||
|
clear_sources(sd, su, sv);
|
||||||
|
|
||||||
|
size=(GRID_SIZE+2)*(GRID_SIZE+2)*(GRID_SIZE+2);
|
||||||
|
for (i=0; i<size; i++)
|
||||||
|
m_fc->v[i] = -0.5f;
|
||||||
|
|
||||||
|
return m_fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f_free(fc *m_fc)
|
||||||
|
{
|
||||||
|
if(m_fc)
|
||||||
|
MEM_freeN(m_fc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1630,12 +1630,13 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod
|
|||||||
float magrelVel = 0.0;
|
float magrelVel = 0.0;
|
||||||
float epsilon = clmd->coll_parms->epsilon;
|
float epsilon = clmd->coll_parms->epsilon;
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cloth1 = clmd->clothObject;
|
cloth1 = clmd->clothObject;
|
||||||
|
|
||||||
if(!collpair)
|
if(!collpair)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: check distance & calc normal
|
// TODO: check distance & calc normal
|
||||||
// calc distance + normal
|
// calc distance + normal
|
||||||
@ -1650,8 +1651,11 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod
|
|||||||
|
|
||||||
if (collpair->distance > (epsilon + ALMOST_ZERO))
|
if (collpair->distance > (epsilon + ALMOST_ZERO))
|
||||||
{
|
{
|
||||||
|
printf("collpair->distance > (epsilon + ALMOST_ZERO)\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("IN1\n");
|
||||||
|
|
||||||
// compute barycentric coordinates for both collision points
|
// compute barycentric coordinates for both collision points
|
||||||
collisions_compute_barycentric (collpair->pa,
|
collisions_compute_barycentric (collpair->pa,
|
||||||
@ -1683,6 +1687,8 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod
|
|||||||
// If v_n_mag < 0 the edges are approaching each other.
|
// If v_n_mag < 0 the edges are approaching each other.
|
||||||
if ( magrelVel < -ALMOST_ZERO )
|
if ( magrelVel < -ALMOST_ZERO )
|
||||||
{
|
{
|
||||||
|
printf("magrelVel < -ALMOST_ZERO\n");
|
||||||
|
|
||||||
// Calculate Impulse magnitude to stop all motion in normal direction.
|
// Calculate Impulse magnitude to stop all motion in normal direction.
|
||||||
// const double I_mag = v_n_mag / (1/m1 + 1/m2);
|
// const double I_mag = v_n_mag / (1/m1 + 1/m2);
|
||||||
float magnitude_i = magrelVel / 2.0f; // TODO implement masses
|
float magnitude_i = magrelVel / 2.0f; // TODO implement masses
|
||||||
@ -2162,6 +2168,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
|
|||||||
int collisions = 0, count = 0;
|
int collisions = 0, count = 0;
|
||||||
float (*current_x)[3];
|
float (*current_x)[3];
|
||||||
Implicit_Data *id = NULL;
|
Implicit_Data *id = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (!(((Cloth *)clmd->clothObject)->tree))
|
if (!(((Cloth *)clmd->clothObject)->tree))
|
||||||
{
|
{
|
||||||
@ -2206,7 +2213,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
|
|||||||
if ( collision_list )
|
if ( collision_list )
|
||||||
{
|
{
|
||||||
LinkNode *search = collision_list;
|
LinkNode *search = collision_list;
|
||||||
|
|
||||||
while ( search )
|
while ( search )
|
||||||
{
|
{
|
||||||
collisions_collision_response_static(clmd, collmd, (CollisionPair *)search->link);
|
collisions_collision_response_static(clmd, collmd, (CollisionPair *)search->link);
|
||||||
@ -2234,6 +2241,24 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// vertex weight = 2
|
||||||
|
|
||||||
|
for(i = 0; i < cloth->numverts; i++)
|
||||||
|
if ((cloth->verts[i].impulse_count > 0) && !(cloth->verts[i].flags & CVERT_FLAG_PINNED))
|
||||||
|
{
|
||||||
|
printf("applying impulse\n");
|
||||||
|
|
||||||
|
VECADDS(cloth->current_v[i], cloth->current_v[i], cloth->verts[i].impulse, 1.0 / (cloth->verts[i].impulse_count * 2.0));
|
||||||
|
|
||||||
|
// reset
|
||||||
|
cloth->verts[i].impulse_count = 0;
|
||||||
|
cloth->verts[i].impulse[0] = 0.0;
|
||||||
|
cloth->verts[i].impulse[1] = 0.0;
|
||||||
|
cloth->verts[i].impulse[2] = 0.0;
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
// update velocities + positions
|
// update velocities + positions
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
@ -2243,78 +2268,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
|
|||||||
}
|
}
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
/*
|
|
||||||
// fill collision list
|
|
||||||
collisions += bvh_traverse(self_bvh->root, self_bvh->root, &collision_list);
|
|
||||||
|
|
||||||
// call static collision response
|
|
||||||
|
|
||||||
// free collision list
|
|
||||||
if(collision_list)
|
|
||||||
{
|
|
||||||
LinkNode *search = collision_list;
|
|
||||||
|
|
||||||
while(search)
|
|
||||||
{
|
|
||||||
float distance = 0;
|
|
||||||
float mindistance = cloth->selftree->epsilon;
|
|
||||||
CollisionPair *collpair = (CollisionPair *)search->link;
|
|
||||||
|
|
||||||
// get distance of faces
|
|
||||||
distance = plNearestPoints(
|
|
||||||
cloth->current_x[collpair->point_indexA[0]], cloth->current_x[collpair->point_indexA[1]], cloth->current_x[collpair->point_indexA[2]], cloth->current_x[collpair->point_indexB[0]], cloth->current_x[collpair->point_indexB[1]], cloth->current_x[collpair->point_indexB[2]], collpair->pa,collpair->pb,collpair->vector);
|
|
||||||
|
|
||||||
if(distance < mindistance)
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////
|
|
||||||
// TODO: take velocity of the collision points into account!
|
|
||||||
///////////////////////////////////////////
|
|
||||||
|
|
||||||
float correction = mindistance - distance;
|
|
||||||
float temp[3];
|
|
||||||
|
|
||||||
VECCOPY(temp, collpair->vector);
|
|
||||||
Normalize(temp);
|
|
||||||
VecMulf(temp, -correction*0.5);
|
|
||||||
|
|
||||||
if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[0]].goal >= SOFTGOALSNAP)))
|
|
||||||
VECSUB(cloth->current_x[collpair->point_indexA[0]], cloth->current_x[collpair->point_indexA[0]], temp);
|
|
||||||
|
|
||||||
if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[1]].goal >= SOFTGOALSNAP)))
|
|
||||||
VECSUB(cloth->current_x[collpair->point_indexA[1]], cloth->current_x[collpair->point_indexA[1]], temp);
|
|
||||||
|
|
||||||
if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[2]].goal >= SOFTGOALSNAP)))
|
|
||||||
VECSUB(cloth->current_x[collpair->point_indexA[2]], cloth->current_x[collpair->point_indexA[2]], temp);
|
|
||||||
|
|
||||||
|
|
||||||
if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[0]].goal >= SOFTGOALSNAP)))
|
|
||||||
VECSUB(cloth->current_x[collpair->point_indexB[0]], cloth->current_x[collpair->point_indexB[0]], temp);
|
|
||||||
|
|
||||||
if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[1]].goal >= SOFTGOALSNAP)))
|
|
||||||
VECSUB(cloth->current_x[collpair->point_indexB[1]], cloth->current_x[collpair->point_indexB[1]], temp);
|
|
||||||
|
|
||||||
if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[2]].goal >= SOFTGOALSNAP)))
|
|
||||||
VECSUB(cloth->current_x[collpair->point_indexB[2]], cloth->current_x[collpair->point_indexB[2]], temp);
|
|
||||||
|
|
||||||
collisions = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
search = collision_list;
|
|
||||||
while(search)
|
|
||||||
{
|
|
||||||
CollisionPair *coll_pair = search->link;
|
|
||||||
|
|
||||||
MEM_freeN(coll_pair);
|
|
||||||
search = search->next;
|
|
||||||
}
|
|
||||||
BLI_linklist_free(collision_list,NULL);
|
|
||||||
|
|
||||||
collision_list = NULL;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// Test on *simple* selfcollisions
|
// Test on *simple* selfcollisions
|
||||||
collisions = 1;
|
collisions = 1;
|
||||||
count = 0;
|
count = 0;
|
||||||
@ -2409,5 +2363,5 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
|
|||||||
*/
|
*/
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -915,6 +915,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio
|
|||||||
// of list are horrible slow!
|
// of list are horrible slow!
|
||||||
BLI_linklist_prepend(&collision_list[0], collpair);
|
BLI_linklist_prepend(&collision_list[0], collpair);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5187,6 +5187,8 @@ static void collisionModifier_deformVerts(
|
|||||||
|
|
||||||
// recalc static bounding boxes
|
// recalc static bounding boxes
|
||||||
bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0);
|
bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0);
|
||||||
|
|
||||||
|
printf("bvh_update_from_mvert\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
collmd->time = current_time;
|
collmd->time = current_time;
|
||||||
|
@ -259,6 +259,7 @@ extern UserDef U; /* from usiblender.c !!!! */
|
|||||||
#define USER_KEYINSERTNEED (1 << 19)
|
#define USER_KEYINSERTNEED (1 << 19)
|
||||||
#define USER_ZOOM_TO_MOUSEPOS (1 << 20)
|
#define USER_ZOOM_TO_MOUSEPOS (1 << 20)
|
||||||
#define USER_SHOW_FPS (1 << 21)
|
#define USER_SHOW_FPS (1 << 21)
|
||||||
|
#define USER_UNDOSAVE (1 << 22) // flag to signal a write_undo() call after a save (save on exit needed then)
|
||||||
|
|
||||||
/* transopts */
|
/* transopts */
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -78,7 +78,6 @@
|
|||||||
#include "BIF_usiblender.h"
|
#include "BIF_usiblender.h"
|
||||||
#include "BIF_writeimage.h"
|
#include "BIF_writeimage.h"
|
||||||
#include "BIF_drawscene.h"
|
#include "BIF_drawscene.h"
|
||||||
|
|
||||||
#ifdef WITH_VERSE
|
#ifdef WITH_VERSE
|
||||||
#include "BIF_verse.h"
|
#include "BIF_verse.h"
|
||||||
#endif
|
#endif
|
||||||
@ -830,6 +829,8 @@ static void do_info_filemenu(void *arg, int event)
|
|||||||
if (untitled(dir)) {
|
if (untitled(dir)) {
|
||||||
activate_fileselect(FILE_BLENDER, "Save As", dir, BIF_write_file);
|
activate_fileselect(FILE_BLENDER, "Save As", dir, BIF_write_file);
|
||||||
} else {
|
} else {
|
||||||
|
/* do NOT ask everytime for overwriting... */
|
||||||
|
G.save_over = 1;
|
||||||
BIF_write_file(dir);
|
BIF_write_file(dir);
|
||||||
free_filesel_spec(dir);
|
free_filesel_spec(dir);
|
||||||
}
|
}
|
||||||
|
@ -831,6 +831,8 @@ int blenderqread(unsigned short event, short val)
|
|||||||
if (untitled(dir)) {
|
if (untitled(dir)) {
|
||||||
activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
|
activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
|
||||||
} else {
|
} else {
|
||||||
|
/* do NOT ask everytime for overwriting... */
|
||||||
|
G.save_over = 1;
|
||||||
BIF_write_file(dir);
|
BIF_write_file(dir);
|
||||||
free_filesel_spec(dir);
|
free_filesel_spec(dir);
|
||||||
}
|
}
|
||||||
@ -931,6 +933,8 @@ int blenderqread(unsigned short event, short val)
|
|||||||
if (untitled(dir)) {
|
if (untitled(dir)) {
|
||||||
activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
|
activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
|
||||||
} else {
|
} else {
|
||||||
|
/* do NOT ask everytime for overwriting... */
|
||||||
|
G.save_over = 1;
|
||||||
BIF_write_file(dir);
|
BIF_write_file(dir);
|
||||||
free_filesel_spec(dir);
|
free_filesel_spec(dir);
|
||||||
}
|
}
|
||||||
|
@ -169,6 +169,28 @@ void asciitoraw(int ch, unsigned short *event, unsigned short *qual)
|
|||||||
|
|
||||||
/* this va_ stuff allows printf() style codes in these menus */
|
/* this va_ stuff allows printf() style codes in these menus */
|
||||||
|
|
||||||
|
static int vconfirm_choice(char *title, char *itemfmt, va_list ap)
|
||||||
|
{
|
||||||
|
char *s, buf[512];
|
||||||
|
|
||||||
|
s= buf;
|
||||||
|
if (title) s+= sprintf(s, "%s%%t|", title);
|
||||||
|
vsprintf(s, itemfmt, ap);
|
||||||
|
|
||||||
|
return (pupmenu(buf));
|
||||||
|
}
|
||||||
|
int confirm_choice(char *title, char *itemfmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
va_start(ap, itemfmt);
|
||||||
|
ret= vconfirm_choice(title, itemfmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int vconfirm(char *title, char *itemfmt, va_list ap)
|
static int vconfirm(char *title, char *itemfmt, va_list ap)
|
||||||
{
|
{
|
||||||
char *s, buf[512];
|
char *s, buf[512];
|
||||||
|
@ -110,6 +110,7 @@
|
|||||||
#include "BIF_resources.h"
|
#include "BIF_resources.h"
|
||||||
#include "BIF_screen.h"
|
#include "BIF_screen.h"
|
||||||
#include "BIF_space.h"
|
#include "BIF_space.h"
|
||||||
|
#include "BIF_toets.h"
|
||||||
#include "BIF_toolbox.h"
|
#include "BIF_toolbox.h"
|
||||||
#include "BIF_cursors.h"
|
#include "BIF_cursors.h"
|
||||||
|
|
||||||
@ -793,7 +794,7 @@ void BIF_write_file(char *target)
|
|||||||
strcpy(di, target);
|
strcpy(di, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BLI_exists(di)) {
|
if (BLI_exists(di) && !G.save_over) {
|
||||||
if(!saveover(di))
|
if(!saveover(di))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -824,9 +825,13 @@ void BIF_write_file(char *target)
|
|||||||
G.save_over = 1;
|
G.save_over = 1;
|
||||||
|
|
||||||
writeBlog();
|
writeBlog();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
error("%s", err);
|
error("%s", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* CLEARS signal: "file needs save" on exit */
|
||||||
|
U.uiflag &= ~USER_UNDOSAVE;
|
||||||
|
|
||||||
waitcursor(0);
|
waitcursor(0);
|
||||||
}
|
}
|
||||||
@ -927,6 +932,41 @@ void BIF_init(void)
|
|||||||
BLI_strncpy(G.lib, G.sce, FILE_MAX);
|
BLI_strncpy(G.lib, G.sce, FILE_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int exit_save_question(void)
|
||||||
|
{
|
||||||
|
char dir[FILE_MAXDIR];
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
/* just go on if no undo there */
|
||||||
|
/* better check necessary --> some flag */
|
||||||
|
if(!(U.uiflag & USER_UNDOSAVE))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* do sweet question here */
|
||||||
|
ret = confirm_choice("Warning: Unsaved changes", "Do you want to save your changes before exit?");
|
||||||
|
|
||||||
|
if(ret==1)
|
||||||
|
{
|
||||||
|
/* copyied from header_info.c */
|
||||||
|
strcpy(dir, G.sce);
|
||||||
|
if (untitled(dir)) {
|
||||||
|
activate_fileselect(FILE_BLENDER, "Save As", dir, BIF_write_file);
|
||||||
|
} else {
|
||||||
|
/* do NOT ask everytime for overwriting... */
|
||||||
|
G.save_over = 1;
|
||||||
|
BIF_write_file(dir);
|
||||||
|
free_filesel_spec(dir);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* cancel, ok, continue button available */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/***/
|
/***/
|
||||||
|
|
||||||
extern ListBase editNurb;
|
extern ListBase editNurb;
|
||||||
@ -934,7 +974,15 @@ extern ListBase editelems;
|
|||||||
|
|
||||||
void exit_usiblender(void)
|
void exit_usiblender(void)
|
||||||
{
|
{
|
||||||
struct TmpFont *tf;
|
struct TmpFont *tf;
|
||||||
|
|
||||||
|
/* ask for save before exit */
|
||||||
|
if(!exit_save_question())
|
||||||
|
{
|
||||||
|
/* user pressed 'cancel' */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tf= G.ttfdata.first;
|
tf= G.ttfdata.first;
|
||||||
while(tf)
|
while(tf)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user