openframeworks freakday s03e02 diederick huijbers - c++/physics/cloth animation/templates

65
Apollo Hello Diederick Huijbers [email protected] www.apollomedia.nl

Upload: roxlu

Post on 28-Nov-2014

4.872 views

Category:

Technology


1 download

DESCRIPTION

Presentation given at the monthly "freakDays" meetings in Amsterdam on Creative Coding.

TRANSCRIPT

Page 2: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

This presentation is part of the openFrameworks freakDays meetings which are given by a group of

Creative Coders and artists in Amsterdam.

During these monthly meetings we give presentation on innovative techniques and show

projects we’re involved in.

For more information checkout www.roxlu.com or contact us at [email protected]

Page 3: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates
Page 4: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

c++ templates Physics

Cloth

Page 5: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Basic C++structsclassespointers

templates<>

Page 6: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

struct Particle { float x; float y; float mass;}

Particle

xy

mass

... use the keyword “struct”

.. green means “members are accessible”..

Page 7: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

class Particle { float x; float y; float mass;}

Particle

xy

mass

... use the keyword “class”

.. red means “members are NOT accessible”..

Page 8: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Differences:Struct members are

public by default those of a class not.

Page 9: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

class Particle { float x; float y; float mass;}

Particle

xy

mass

Particle

xy

mass

Particle

xy

mass

A struct doesn’t need thispublic keyword. Their members are public by default! That’s nice!

class Particle {public: float x; float y; float mass;}

struct Particle { float x; float y; float mass;}

Check how the keyword public makes the members green ;) and so accessible!

Page 10: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

When to use struct <-> class?It doesn’t really matter; it’s a personal thing....

Page 11: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

...though, typically structsare used for simple datacontainers and classes

for more advanced things.

Page 12: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

class Particle {public: Particle(); void setPosition(float x, float y); void update(); void draw(); void applyRepulsiveForce(); void addForce(float x, float y);

private: float x; float y; float mass;}

Classes for more advanced stuff

Page 13: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

struct User { string name; string password; string homepage; int age; float weight;};

struct Tweet { uint16 userid; string homepage; string avatar_url; int timestamp; bool has_gps;};

Structs for simple data containers

Page 14: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Pointers !!!

Page 15: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Pointers are not that hard!Instead of pointing to a

value hold a a memory address!

Page 16: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Pointers are not that hardValues Address in memory

f #1

r #2

e #3

a #4

k #5

d #6

a #7

y #8

Page 17: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Values Address in memory

f #1

r #2

e #3

a #4

k #5

d #6

a #7

y #8

\0 #9

? #10

? #11

char* name = “freakday”

name + 0

name + 1

name + 2

name + 3

name + 4

name + 5

name + 6

name + 7

name + 8

char *Check the char* the star (*) tells the compiler we want a pointer a char. A normal char is just one character. The \0 is automatically added and tells the compiler it’s the end of the “string”

A pointer points hold an memory address. We can step through the memory addresses using this type of variable.

Page 18: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Values

f #1

r #2

e #3

a #4

k #5

d #6

a #7

y #8

\0 #9

? #10

? #11

name + 9

name + 10

Do not go into unauthorized memory ....or else.....

“EXC_BAD_ACCESS” or“UNDEFINED” behavior

...which is ....

Page 19: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Check XCode project “freakday_S03E02_pointers”

Page 20: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Memory Alignment + packing

class Particle { bool enabled; // 8 bits float x; // 32 bits float y; // 32 bits bool flying; // 8 bits}

enabled

xy

flying

= memory needed

= memory actually used

}32 bit wide

WRONG!You should align your bytes nicely

When the CPU reads from memory it uses a natural alignment which must be respected to permit the CPU to read and write memory effectively. A compiler will leave holes in memory when members/objects aren’t aligned properly.

Page 21: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

}

Memory Alignment + packing

class Particle { float x; // 32 bits float y; // 32 bits bool flying; // 8 bits bool enabled; // 8 bits}

xy

f

= memory needed

= memory actually used

32 bit wide

CORRECT!The members are aligned nicely

e

Page 22: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Memory Alignment + packing

Check XCode project “freakday_S03E02_packing”

Page 23: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

[TYPE_ADDRESS]: some value[ADDRESS_ENTRY]: some value

[TYPE_PHONE]: some value

Templates

Page 24: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Office address: some valueBilling address: some valueMobile phone: some valueWork phone: some value

Templates

Page 25: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Templates are a way to write more generic code: write one special thing (algorithm) which you can use for many kind of types.

Create one template for a particle for both 2D and 3D. Particle<2D> and Particle<3D>

Templates

Page 26: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

class Particle2D { ofVec2f position; ofVec2f velocity; ofVec2f forces; void draw();}

class 2DParticlesGroup { vector<Particle2D*> particles; void addForce(ofVec2f f) { for(int i = 0; i < particles.size(); ++i) { particles.at(i)->addForce(f); } }}

2D particles....

Particle-Group

Particle

Page 27: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

class Particle3D { ofVec3f position; ofVec3f velocity; ofVec3f forces; void draw();}

class 3DParticlesGroup { vector<Particle3D*> particles; void addForce(ofVec3f f) { for(int i = 0; i < particles.size(); ++i) { particles.at(i)->addForce(f); } }}

3D particles....

Particle-Group

Particle

Page 28: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

class Particle4D { ofVec4f position; ofVec4f velocity; ofVec4f forces; void draw();}

class 4DParticlesGroup { vector<Particle4D*> particles; void addForce(ofVec4f f) { for(int i = 0; i < particles.size(); ++i) { particles.at(i)->addForce(f); } }}

4D particles....

Particle-Group

Particle

Page 29: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

5D, 6D, 7D ... or templateAdd this before your template class: “template<typename T>”.

The “T” is the type parameter: Particle2D, Particle3D, etc..The name “T” can be anything you like, but T is convention.

Also correct:template<typename SomeType>template<class SomeType>template<class T>

“Typename” and “class” can be used both, “typename”is preferred.

Page 30: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

template<typename T>class Particle {public: Particle(T oPosition, float nMass); void addForce(T oForce); void update(); void draw();

private: T position; T forces; T velocity; float mass;};

Templated Particle

Page 31: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

template<typename P, typename V>class ParticleGroup {public: ParticleGroup(); void addParticle(P oParticle); void addForce(V oForce); void update(); void draw();

private: vector<P> particles};

Templated Particle-Group

Page 32: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

template<typename P, typename V>class ParticleGroup {public: ParticleGroup(); void addParticle(P oParticle); void addForce(V oForce); void update(); void draw();

private: vector<P> particles};

Example of templated particles

Check XCode project “freakday_S03E02_templates”

Page 33: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Keyword TypenameConsider the following code:

template<typename T>class SomeClass {public: typename T::SubType* ptr;};

Makes sure that subtype is seen as a type, not a static member.

Page 34: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

template<typename T>class SomeClass {public: typename T::MyType* ptr;};

template<typename T>class SomeClass {public:

T::MyType* ptr;};

WRONG: Here T::MyType * ptr would mean a multiplication

class WithStatic {public: static int MyType;}

Here T::MyType * ptr would refer to the nested type in the WithType class.

class WithType {public: class MyType { }}

Page 35: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

-- pseudo code --template<typename T>class MyContainer { vector<T> items; void draw() { typename vector<T>::iterator it = items.begin(); while(it != items.end()) { (*it)->draw(); ++it; } }};

-- add some particles to containerMyContainer<Particle2D*> particles;particles.items.push_back(new Particle2D()); particles.items.push_back(new Particle2D());particles.draw();

When to use the keyword typename

Here we make sure that iterator is a type, not a static member! Usually you use the keyword typename with STL iterators

Page 36: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Physics

Page 37: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

An object continues with constant velocity unless a

force acts upon it [1]

Newtons first law

Page 38: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Newtons first law

1 2 3 4 5 6 7time and position

Velocity vector(s):ofxVec2f, ofxVec3f

Note that the red arrow stays the same size. The red arrow represents the velocity vector and showing the first law

Check XCode project “freakday_S03E02_5_simple_motion”

Page 39: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

1 2 3 4 5 6 7time and position

When creating particle systems I often simulate drag by degreasing the velocity by a small percentage.

Note how the velocity vector below get’s smaller.

Check XCode project “freakday_S03E02_6_simple_motion_with_drag”

// example faking dragvoid Particle::update() { velocity *= 0.98;}

The amount of drag, the 0.98 in this example, totally depends on what you want. It’s a case of tweaking to get the right behavior.

Page 40: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

A force acting on a object produces acceleration that

is proportional to the object’s mass. [1]

Newtons second law

Page 41: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Newtons second law

this arrow represents the force acting on the object

this is the resulting forcewhen mass is taken intoaccount

160-200 KG (?)

Page 42: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Newtons second law

this arrow represents the force acting on the object

this is the resulting forcewhen mass is taken intoaccount

75-80 KG

Page 43: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Newtons second law

force = mass * acceleration

The math of how force, acceleration and mass is related....

...to get the acceleration we do:

“The law” ( F = ma )

this is what I use in particle systems

acceleration = 1/mass * force

Page 44: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Newtons second law

acceleration = 1/mass * force

This one is important! The bigger the mass, the less the

acceleration

This is what we call inverse mass. We do not need to recalculate this for each update! We store this in a member of the Particle class and can be used to represent “infinite” mass when set to zero:

0 * force = 0

Page 45: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

class Particle { ofxVec2f position; ofxVec2f velocity; ofxVec2f forces; float inverse_mass; Particle(float fMass) { if(mass <= 0) { inverse_mass = 0; } else { inverse_mass = 1/mass; } }

void addForce(ofxVec2f oForce) { forces += oForce; } void update() { forces *= inverse_mass; velocity += forces; velocity *= 0.99; position += velocity; forces.set(0,0); }};

How does this look like in code?

Check XCode project “freakday_S03E02_7_simple_motion_inverse_mass”

D’Alembert’s Principle (simplified):We can accumulate all forces acting on an object.

Page 46: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

“Springs are structural elements that, when

connected between two objects, apply equal and opposite forces to each

object.”

Springs

Page 47: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Springs

Object 2Object 1

The red arrows represent force vectors in opposite directions: so the two objects are pulled towards each other

Page 48: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Springs

-k = spring strength; in code just a “float strength” which often gets a value like 0.1, 0.001

The rule related to springsforces is called “Hooks” law!

f = -k∆L

∆L = difference between springs “compressed/rest length” and current length.

Page 49: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

∆L = (r - d)difference between springs

“compressed/rest length” and current length.

Two springs not stretched/compressed and showing their rest length. }

r = rest length

Page 50: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

∆L = (r - d)

(r) rest length

Two particles connected by a spring

(d) distance

Spring force vector Spring force vector

Page 51: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

(d) distance

Spring force vector Spring force vector

template<typename P, typename V>class Spring {public:! Spring(P pParticleA, P pParticleB, float nStrength = 0.01) ! :a(pParticleA)! ,b(pParticleB)! ,k(nStrength)! {! ! rest_length = (b->position - a->position).length();! }

! void update() {! ! V dir = b->position - a->position;! ! float dist = dir.length();! ! if(dist == 0.0) {! ! ! dist = 0.0001; // division by zero! ! } ! !! ! float f = (rest_length - dist) * k; ! ! dir.normalize();! ! a->addForce(dir * -f);! ! b->addForce(dir * f);! }!! P a,b;

Spring template 2d/3d/..

Rest length

Rest length: distance between particles when

creating the spring

Current distance

The force spring

Force spring multiplied by normalized direction vector and in opposite directions

Page 52: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Springs

Check XCode project “freakday_S03E02_8_spring_forces”

Check XCode project “freakday_S03E02_9_spring_forces_with_gui”

Example: click mouse to add particle + spring...

Example: right click mouse to add particle + spring and use sliders to see the result of

different “k” and “drag” values.

Page 53: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Cloth Physics

Page 54: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Cloth PhysicsSimple cloth physics used multiple springs connected

to particles in a grid.

Page 55: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Cloth Physics

Particles are positioned on a grid and then connected by 3 kind of springs:

- structural springs- shear springs- bending springs

Page 56: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Cloth PhysicsStructural springs

Page 57: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Cloth PhysicsShear springs

Page 58: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Cloth Physics

Bending springs

Page 59: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Errors

are

beauti

ful :)

Check XC

ode project “freakday_S03E02_10_cloth”

Page 60: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

// lets create the grid.for(int i = 0; i < nCols; ++i) {! for(int j = 0; j < nRows; ++j) {! ! ofxVec3f position(i * nSize, j * nSize);! ! Particle3D* particle = new Particle3D(position, 1.1);! ! particles[j * cols + i] = particle;! ! if(j == 0) {! ! ! particle->inverse_mass = 0;! ! }! }}

Creating the particle grid

Calculating the index in the vector. We position the particle just like normal image pixels are stored, by column and row. This is handy when we need to lookup (see getAt) a particle based on a column

and row.

Page 61: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

// create springs.Particle3D* a;Particle3D* b;for(int i = 0; i < nCols; ++i) {! for(int j = 0; j < nRows; ++j) {! !! ! // structural spring - right.! ! if(i < nCols-1) {! ! ! a = getAt(i,j);!! ! ! b = getAt(i+1, j);! ! ! springs.createSpring(a,b);! ! }! !! ! // structural spring - down! ! if(j < nRows-1) {! ! ! a = getAt(i,j);! ! ! b = getAt(i, j+1);! ! ! springs.createSpring(a,b);! ! }! }}

For more info on how to create the other springs see the source; it’s quite similar.

Creating the structural springs

Check XCode project “freakday_S03E02_11_with_gui”

Page 62: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Next time C++/...:

Initializer listsVirtual functionsInheritance More templates.....Debugging linker errors (file, nm)Operator overloading (=,[],*,etc.)Const, static

Page 63: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

Integrators (euler, verlet, runge kutta)

Fast particle systems (buckets, sorting)

BillboardingMatrices / 3DShaders

Next time particles/3d

Page 64: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

....

Other suggestions...

Page 65: openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animation/Templates

References1. Ian Millington, Game Physics Engine Development, 2007