Feb 202011
 

I added a ‘VerletHinge’ class that’s a little hacky but it works to give rotation limits on certain joints. Provides slightly more lifelike flailing… also added a little drawing touch and made the ragdoll hang out until clicked.
[processing]

VerletPoint vPointA = new VerletPoint(100, 100);
VerletPoint[] vPointArr = new VerletPoint[9];
VerletStick[] vStickArr = new VerletStick[8];
VerletHinge[] vHingeArr = new VerletHinge[5];

int nVP = 9;
int nVS = 8;
int nVH = 5;

int xDIM = 300;
int yDIM = 120;

float GraV = .15

xSTART = xDIM/2;
ySTART = yDIM/4;
rdSCALE = 12;

boolean initRD = false;

void setup() {
background(255);
fill(255);
stroke(#568984);
size(xDIM, yDIM);
smooth();
frameRate(30);
strokeWeight(3);

vPointArr[0] = new VerletPoint(xSTART, ySTART+rdSCALE/2); //
vPointArr[1] = new VerletPoint(xSTART-rdSCALE*1.5, ySTART+rdSCALE);
vPointArr[2] = new VerletPoint(xSTART, ySTART+rdSCALE);
vPointArr[3] = new VerletPoint(xSTART+rdSCALE*1.5, ySTART+rdSCALE);
vPointArr[4] = new VerletPoint(xSTART, ySTART+rdSCALE*2);
vPointArr[5] = new VerletPoint(xSTART-rdSCALE, ySTART+rdSCALE*3);
vPointArr[6] = new VerletPoint(xSTART-rdSCALE, ySTART+rdSCALE*4);
vPointArr[7] = new VerletPoint(xSTART+rdSCALE, ySTART+rdSCALE*3);
vPointArr[8] = new VerletPoint(xSTART+rdSCALE, ySTART+rdSCALE*4);

vStickArr[0] = new VerletStick(vPointArr[0], vPointArr[2]);
vStickArr[1] = new VerletStick(vPointArr[2], vPointArr[1]);
vStickArr[2] = new VerletStick(vPointArr[2], vPointArr[3]);
vStickArr[3] = new VerletStick(vPointArr[2], vPointArr[4]);
vStickArr[4] = new VerletStick(vPointArr[4], vPointArr[5]);
vStickArr[5] = new VerletStick(vPointArr[5], vPointArr[6]);
vStickArr[6] = new VerletStick(vPointArr[4], vPointArr[7]);
vStickArr[7] = new VerletStick(vPointArr[7], vPointArr[8]);

vHingeArr[0] = new VerletHinge(vPointArr[5], vPointArr[4], vPointArr[7], 45, 160);

vHingeArr[1] = new VerletHinge(vPointArr[1], vPointArr[2], vPointArr[4], 45, 90);
vHingeArr[2] = new VerletHinge(vPointArr[4], vPointArr[2], vPointArr[3], 45, 90);

vHingeArr[3] = new VerletHinge(vPointArr[6], vPointArr[5], vPointArr[4], 10, 160);
vHingeArr[4] = new VerletHinge(vPointArr[8], vPointArr[7], vPointArr[4], 10, 160);

}

void draw() {
background(225);

if(initRD == false){
vPointArr[0].x = xSTART;
vPointArr[0].y = ySTART;
}
if(mousePressed){
initRD = true;
vPointArr[0].x = mouseX;
vPointArr[0].y = mouseY;
}else{

vPointA.y += GraV;
}
vPointA.update();
vPointA.bounds(0, 0, xDIM, yDIM);

for(int p = 0; p < nVP; p++){
if(p==0,1,3,6,8){
vPointArr[p].y += GraV;
}
vPointArr[p].update();
vPointArr[p].bounds(0, 0, xDIM, yDIM);
}

for(int s = 0; s < nVS; s++){
vStickArr[s].update();
}

for(int h = 0; h < nVH; h++){
//ustr = str(vHingeArr[h].pointA.x)+”,”+str(vHingeArr[h].pointB.x)+”,”+str(vHingeArr[h].pointC.x)
// +”-“+str(vHingeArr[h].aMin)+”,”+str(vHingeArr[h].aMax)+”,”+str(vHingeArr[h].aAng)
//println(ustr);
vHingeArr[h].update();
}
oCOL = 0;
iCOL = 255;

stroke(oCOL); strokeWeight(3); //ARMS
line(vPointArr[2].x, vPointArr[2].y, vPointArr[1].x, vPointArr[1].y);
line(vPointArr[2].x, vPointArr[2].y, vPointArr[3].x, vPointArr[3].y);
stroke(iCOL); strokeWeight(2);
line(vPointArr[2].x, vPointArr[2].y, vPointArr[1].x, vPointArr[1].y);
line(vPointArr[2].x, vPointArr[2].y, vPointArr[3].x, vPointArr[3].y);
stroke(oCOL); strokeWeight(4); //SHINS
line(vPointArr[5].x, vPointArr[5].y, vPointArr[6].x, vPointArr[6].y);
line(vPointArr[7].x, vPointArr[7].y, vPointArr[8].x, vPointArr[8].y);
stroke(iCOL); strokeWeight(3);
line(vPointArr[5].x, vPointArr[5].y, vPointArr[6].x, vPointArr[6].y);
line(vPointArr[7].x, vPointArr[7].y, vPointArr[8].x, vPointArr[8].y);
stroke(oCOL); strokeWeight(5); //THIGHS
line(vPointArr[4].x, vPointArr[4].y, vPointArr[5].x, vPointArr[5].y);
line(vPointArr[4].x, vPointArr[4].y, vPointArr[7].x, vPointArr[7].y);
stroke(iCOL); strokeWeight(4);
line(vPointArr[4].x, vPointArr[4].y, vPointArr[5].x, vPointArr[5].y);
line(vPointArr[4].x, vPointArr[4].y, vPointArr[7].x, vPointArr[7].y);
stroke(oCOL); strokeWeight(6); //CHEST
line(vPointArr[2].x, vPointArr[2].y, vPointArr[4].x, vPointArr[4].y);
stroke(iCOL); strokeWeight(5);
line(vPointArr[2].x, vPointArr[2].y, vPointArr[4].x, vPointArr[4].y);
stroke(oCOL); strokeWeight(7); //HEAD
line(vPointArr[0].x, vPointArr[0].y, vPointArr[2].x, vPointArr[2].y);
stroke(iCOL); strokeWeight(5);

line(vPointArr[0].x, vPointArr[0].y, vPointArr[2].x, vPointArr[2].y);
}

class VerletPoint {
float x, y, oldX, oldY;
VerletPoint(float _x, float _y) {
setPosition(_x, _y);
}
void setPosition(float _x, float _y) {
x = oldX = _x;
y = oldY = _y;
}
void update(){
float tempX = x, tempY = y;
x += getVx();
y += getVy();
oldX = tempX;
oldY = tempY;
}
void bounds(float left, float top, float right, float bottom){
x = constrain(x, left, right);
y = constrain(y, top, bottom-5);
}
void setVx(float value){
oldX = x – value;
}
float getVx(){
return x – oldX;
}
void setVy(float value){
oldY = y – value;
}
float getVy(){
return y – oldY;
}
void render(){
ellipse(x, y, 10, 10);
}
}

class VerletStick {
VerletPoint pointA, pointB;
float len;
VerletStick(VerletPoint _pointA, VerletPoint _pointB){
pointA = _pointA;
pointB = _pointB;
len = dist(pointA.x, pointA.y , pointB.x, pointB.y);
}
void update(){
float dst = dist(pointA.x, pointA.y , pointB.x, pointB.y);
float diff = len – dst;
float offsetX = (diff * (pointB.x – pointA.x) / dst) / 2;
float offsetY = (diff * (pointB.y – pointA.y) / dst) / 2;
pointA.x -= offsetX; pointA.y -= offsetY; pointB.x += offsetX; pointB.y += offsetY;
}
void render(){
line(pointA.x, pointA.y , pointB.x, pointB.y);
}
}

void getAngleABC( PVector a, PVector b, PVector c ){
q1 = b.x-a.x;
q2 = dist(a.x,a.y, b.x,b.y);
q3 = q1/q2;
q4 = degrees(asin(q3));
angBA = degrees(asin((b.x-a.x)/(dist(a.x,a.y, b.x,b.y))));
angBC = degrees(asin((b.x-c.x)/(dist(c.x,c.y, b.x,b.y))));
angABC = abs(angBA-angBC);
return angABC;
}

// ptB
// stickA / stickB
// ptA ptC
class VerletHinge {

VerletPoint pointA, pointB, pointC;
int aMin, aMax;
float aAng;

VerletHinge(VerletPoint _pointA, VerletPoint _pointB, VerletPoint _pointC, int _aMin, int _aMax){
aMin = _aMin; aMax = _aMax;
pointA = _pointA;
pointB = _pointB;
pointC = _pointC;

aAng = getAngleABC(pointA, pointB, pointC);
}

void update(){
aAng = getAngleABC(pointA, pointB, pointC);

//HACK – just move the points closer/further away from each other
if(aAng<aMin){
aCS = constrain((pointC.y – pointA.y) / (pointC.x – pointA.x), 0, 1);
aCRate = constrain(abs(radians(aAng-aMin)), 0, 10);
pointA.x -= aCRate; pointA.y -= aCRate*aCS;
pointC.x += aCRate; pointC.y += aCRate*aCS;
}

if(aAng>aMax){
//println(“doing”);
aCS = (pointC.y – pointA.y) / (pointC.x – pointA.x);
aCRate = abs(radians(aAng-aMin));
if(pointC.x>pointA.x){
pointA.x += aCRate; pointA.y += aCRate*aCS;
pointC.x -= aCRate; pointC.y -= aCRate*aCS;
} else if(pointA.x>pointC.x){
pointA.x -= aCRate; pointA.y -= aCRate*aCS;
pointC.x += aCRate; pointC.y += aCRate*aCS;
}
}
}
void render(){
//line(stickA.pointA.x, stickA.pointA.y , stickA.pointB.x, stickA.pointB.y);
//line(stickB.pointA.x, stickB.pointA.y , stickB.pointB.x, stickB.pointB.y);
}
}

 

[/processing]

Feb 202011
 

Collection of the videos I did for various bands.

Destruction of the Western Hemisphere (Blues and the Gunfighters)

The Rich Don’t Die

Comatoaster

Movin’ Weight – South Park Medley

Feb 202011
 

[EDIT] – Just wanted to post this here in case I forget:

A driver can use the current frame in the expression with – bpy.context.scene.frame_current

So you could do something like: sin((bpy.context.scene.frame_current-10)/5)

BUT!!! After 2.68 expressions in drivers only work if you have Auto Run Python Scripts turned on in UserPrefs>File

————————————

B2.56 doesn’t have proper events yet – so this is a hacky way to drive scene animation. I forgot where I found this info – but it worked so I wanted to make it available.
1) create Empty
2) add single keyframe to Zrot (frame 1)
– should have default expanded poly generator on it
3) add single driver to Yloc (frame1)
– in Drivers> choose – Scripted sxpression
– enter this expression

float(exec("\n".join([l.body for l in bpy.data.texts["RUN"].lines]))==None)

4) then a script called ‘RUN’ should execute every time the frame changes
– Zrot of Empty drives expression which (i think) grabs the text datablock of the script and runs it

here’s a quick thing I did. set up the empty as above…
then make a cube (named ‘Cube’) subdivide it a lot, then run this-

 import bpy import random ob = bpy.data.objects['Cube'] verts = ob.data.vertices for v in verts: rxnum = round(random.uniform(-0.01 ,0.01), 4) rynum = round(random.uniform(-0.01 ,0.01), 4) rznum = round(random.uniform(-0.01 ,0.01), 4) v.co[0] = v.co[0] + rxnum v.co[1] = v.co[1] + rynum v.co[2] = v.co[2] + rznum scene = bpy.context.scene 

BLENDER ARTIST THREAD

Feb 182011
 

Here are two models I made awhile ago for fun. I decided to make them low poly so I could put them up on the web here. I know the viewer is crappy – I’ll work on it later.
Anyway here they are.

Gumby .blend .png

Pokey .blend .png

…and here’s the animation I made from these awhile back
[videoplayer file=”wp-content/video/Gumby-SoulMachine.flv” /]

Feb 182011
 

I’ll do a proper tutorial on how to export models like this- as soon as I figure it out myself.

for now here’s the basics…
-found this – three.js
-exported a 3d model (balsa plane) from blender using the included export script.  (here’s the .blend file and the .png texture
-jacked the code from this sample viewer, spliced in my model path… and…
VOILA! (if you have a webgl enabled browser)

if you don’t – here’s a render.

Less fun as a 3d model, but still fun.

this is a boids sim I did with the planes.
[videoplayer file=”wp-content/video/BalsaPlaneSpaceSwarm.flv” /]

Feb 182011
 

Here’s my processing.js simulation of Cellular Automation in 3d. Rules 0 and 1 are Conway’s Game of Life. Rule 1 just runs the game on R,G, and B independently. Rule 2 is my own ruleset, which used to create an interesting evolution- but then I randomized the order of cell calcs and it got much less interesting.

Anyway, you can change the domain in 3d in real-time- though anything totaling more than about 500 cells gets slow… … …. … real slow. You can also change the min/max population for the rules in realtime, and all the other vars. It’s slow, it’s a hack, but hey…

3d Cellular Automation Simulator

It wont run unless you have the dev build of Firefox (Minefield), Chrome(ium), or any browser that supports WebGL. Most will in a few months- with the predictable exception of M$Exploder.