Added 2 files for softbody plus sconscript!

This commit is contained in:
Ton Roosendaal
2004-10-01 14:10:30 +00:00
parent 04f5baee3a
commit f2b785296e
3 changed files with 430 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
/**
* BKE_softbody.h
*
* $Id: BKE_softbody.h
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifndef BKE_SOFTBODY_H
#define BKE_SOFTBODY_H
typedef struct BodyPoint {
float orig[3], pos[3], vec[3], force[3];
float weight, goal;
} BodyPoint;
typedef struct BodySpring {
int v1, v2;
float len, strength;
} BodySpring;
typedef struct SoftBody {
int totpoint, totspring;
BodyPoint *bpoint;
BodySpring *bspring;
float ctime; // last time calculated
} SoftBody;
/* temporal data, nothing saved in file */
extern void free_softbody(SoftBody *sb);
/* makes totally fresh start situation */
extern void object_to_softbody(Object *ob);
/* copy original (but new) situation in softbody, as result of matrices or deform */
void object_update_softbody(Object *ob);
/* copies softbody result back to object (in displist) */
extern void softbody_to_object(Object *ob);
/* go one step in simulation */
extern void object_softbody_step(Object *ob, float ctime);
#endif

View File

@@ -39,6 +39,7 @@ source_files = ['intern/constraint.c',
'intern/font.c',
'intern/library.c',
'intern/property.c',
'intern/softbody.c',
'intern/texture.c']
blenkernel_env.Append (CPPPATH = ['.',

View File

@@ -0,0 +1,357 @@
/* softbody.c
*
* $Id:
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) Blender Foundation
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include <math.h>
#include <stdlib.h>
#include "MEM_guardedalloc.h"
/* types */
#include "DNA_ika_types.h"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BKE_global.h"
#include "BKE_utildefines.h"
#include "BKE_softbody.h"
#include "BKE_displist.h"
/* ********** soft body engine ******* */
static SoftBody *new_softbody(int totpoint, int totspring)
{
SoftBody *sb= NULL;
if(totpoint) {
sb= MEM_callocN(sizeof(SoftBody), "softbody");
sb->totpoint= totpoint;
sb->totspring= totspring;
sb->bpoint= MEM_mallocN( totpoint*sizeof(BodyPoint), "bodypoint");
if(totspring)
sb->bspring= MEM_mallocN( totspring*sizeof(BodySpring), "bodyspring");
}
return sb;
}
void free_softbody(SoftBody *sb)
{
if(sb) {
if(sb->bpoint) MEM_freeN(sb->bpoint);
if(sb->bspring) MEM_freeN(sb->bspring);
MEM_freeN(sb);
}
}
static void softbody_calc_forces(Object *ob)
{
SoftBody *sb= ob->soft; // is supposed to be there
BodyPoint *bp;
float ks;
int a;
/* clear forces */
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
bp->force[0]= bp->force[1]= bp->force[2]= 0.0;
}
/* spring constant */
ks= ob->springf;
/* accumulate forces, vertex stiffness */
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
bp->force[0]= ks*(bp->orig[0]-bp->pos[0]);
bp->force[1]= ks*(bp->orig[1]-bp->pos[1]);
bp->force[2]= ks*(bp->orig[2]-bp->pos[2]);
}
}
static void softbody_apply_forces(Object *ob, float dtime)
{
SoftBody *sb= ob->soft; // is supposed to be there
BodyPoint *bp;
float kd;
int a;
kd= 1.0-ob->damping;
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
// friction
bp->vec[0]*= kd;
bp->vec[1]*= kd;
bp->vec[2]*= kd;
VECADD(bp->vec, bp->vec, bp->force); // mass here!?
VECADD(bp->pos, bp->pos, bp->vec);
}
}
static void softbody_apply_goal(Object *ob, float dtime)
{
SoftBody *sb= ob->soft; // is supposed to be there
BodyPoint *bp;
float vec[3], ks;
int a;
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
ks= bp->goal;
// this is hackish, screws up physics but stabilizes
vec[0]= ks*(bp->orig[0]-bp->pos[0]);
vec[1]= ks*(bp->orig[1]-bp->pos[1]);
vec[2]= ks*(bp->orig[2]-bp->pos[2]);
VECADD(bp->pos, bp->pos, vec);
ks= 1.0-ks;
bp->vec[0]*= ks;
bp->vec[1]*= ks;
bp->vec[2]*= ks;
}
}
/* ************ convertors ********** */
/* copy original (new) situation in softbody, as result of matrices or deform */
static void mesh_update_softbody(Object *ob)
{
Mesh *me= ob->data;
MVert *mvert= me->mvert;
MEdge *medge= me->medge;
BodyPoint *bp;
BodySpring *bs;
int a;
if(ob->soft) {
bp= ob->soft->bpoint;
for(a=0; a<me->totvert; a++, mvert++, bp++) {
VECCOPY(bp->orig, mvert->co);
Mat4MulVecfl(ob->obmat, bp->orig);
}
if(medge) {
bs= ob->soft->bspring;
bp= ob->soft->bpoint;
for(a=0; a<me->totedge; a++, medge++, bs++) {
bs->len= VecLenf( (bp+bs->v1)->orig, (bp+bs->v2)->orig);
}
}
}
}
/* makes totally fresh start situation */
static void mesh_to_softbody(Object *ob)
{
Mesh *me= ob->data;
MVert *mvert= me->mvert;
MEdge *medge= me->medge;
MFace *mface= me->mface;
BodyPoint *bp;
BodySpring *bs;
int a;
ob->soft= new_softbody(me->totvert, me->totedge);
if(ob->soft) {
bp= ob->soft->bpoint;
for(a=me->totvert; a>0; a--, mvert++, bp++) {
VECCOPY(bp->pos, mvert->co);
Mat4MulVecfl(ob->obmat, bp->pos); // yep, sofbody is global coords
VECCOPY(bp->orig, bp->pos);
bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0;
bp->weight= 1.0;
bp->goal= 0.5;
}
if(medge) {
bs= ob->soft->bspring;
bp= ob->soft->bpoint;
for(a=me->totedge; a>0; a--, medge++, bs++) {
bs->v1= medge->v1;
bs->v2= medge->v2;
bs->strength= 1.0;
bs->len= VecLenf( (bp+bs->v1)->orig, (bp+bs->v2)->orig);
}
}
/* vertex colors are abused as weights here, however they're stored in faces... uhh */
if(mface && me->mcol) {
char *mcol= (char *)me->mcol;
for(a=me->totface; a>0; a--, mface++, mcol+=16) {
bp= ob->soft->bpoint+mface->v1;
if(bp->goal==0.5) {
bp->goal= ( (float)( (mcol + 0)[1] ) )/255.0;
}
bp= ob->soft->bpoint+mface->v2;
if(bp->goal==0.5) {
bp->goal= ( (float)( (mcol + 4)[1] ) )/255.0;
}
bp= ob->soft->bpoint+mface->v3;
if(bp->goal==0.5) {
bp->goal= ( (float)( (mcol + 8)[1]) )/255.0;
}
if(mface->v4) {
bp= ob->soft->bpoint+mface->v4;
if(bp->goal==0.5) {
bp->goal= ( (float)( (mcol + 12)[1]) )/255.0;
}
}
}
}
bp= ob->soft->bpoint;
for(a=me->totvert; a>0; a--, bp++) {
//printf("a %d goal %f\n", a, bp->goal);
}
}
}
/* copies current sofbody position in mesh, so do this within modifier stacks! */
static void softbody_to_mesh(Object *ob)
{
Mesh *me= ob->data;
MVert *mvert;
BodyPoint *bp;
int a;
Mat4Invert(ob->imat, ob->obmat);
bp= ob->soft->bpoint;
mvert= me->mvert;
for(a=me->totvert; a>0; a--, mvert++, bp++) {
VECCOPY(mvert->co, bp->pos);
Mat4MulVecfl(ob->imat, mvert->co); // softbody is in global coords
}
}
/* makes totally fresh start situation */
static void lattice_to_softbody(Object *ob)
{
}
/* copies current sofbody position */
static void softbody_to_lattice(Object *ob)
{
}
/* ************ Object level, exported functions *************** */
/* copy original (new) situation in softbody, as result of matrices or deform */
void object_update_softbody(Object *ob)
{
switch(ob->type) {
case OB_MESH:
mesh_update_softbody(ob);
break;
case OB_LATTICE:
//lattice_update_softbody(ob);
break;
}
}
/* makes totally fresh start situation */
void object_to_softbody(Object *ob)
{
if(ob->soft) free_softbody(ob->soft);
ob->soft= NULL;
switch(ob->type) {
case OB_MESH:
mesh_to_softbody(ob);
break;
case OB_LATTICE:
lattice_to_softbody(ob);
break;
}
}
/* copies softbody result back in object */
void softbody_to_object(Object *ob)
{
if(ob->soft==NULL) return;
switch(ob->type) {
case OB_MESH:
softbody_to_mesh(ob);
break;
case OB_LATTICE:
softbody_to_lattice(ob);
break;
}
}
/* simulates one step. ctime is in frames not seconds */
void object_softbody_step(Object *ob, float ctime)
{
float dtime;
if(ob->soft==NULL) {
object_to_softbody(ob);
if(ob->soft==NULL) return;
ob->soft->ctime= ctime;
}
dtime= ctime - ob->soft->ctime;
dtime= ABS(dtime);
if(dtime > 0.0) {
/* desired vertex locations in oldloc */
object_update_softbody(ob);
/* extra for desired vertex locations */
softbody_apply_goal(ob, dtime);
softbody_calc_forces(ob);
softbody_apply_forces(ob, dtime);
/* and apply to vertices */
softbody_to_object(ob);
ob->soft->ctime= ctime;
}
}