| |
Oswald
Registered: Apr 2002 Posts: 5085 |
CL13 spring water- how ?
anyone would care to share how the spring math works in there?
I've tried yesterday to make a simple spring, but it very rarely got close to resting, 8 out of 10 tweaks it "blows" up due to something google said is a problem with the euler equation. :)
so yes I'm trying to be lazy here and asking for the solution right away. Arok is less than 2 weeks away and I need to finish this fast :)
I've found verlet method, but dont understand it in the depth thats enough to turn it into 8 bit code.
for reference:
http://gamedevelopment.tutsplus.com/tutorials/make-a-splash-wit..
thanks, |
|
| |
Axis/Oxyron Account closed
Registered: Apr 2007 Posts: 91 |
Hey Oswald,
the algorithm is relatively simple but alot of fiddling until it looks nice. The basic idea is to track height and velocity of every column. Every column is connected to its 4 neighbours to the left and the four neighbours to the right with dynamic springs (only for the y-axis). The stiffness of the 8 springs (factor on the applied force) is calculated with a gaussian weight table. The last step is mostly what makes it look smooth. I can give you a C-source from my prototype. But I guess it won´t help much. Its optimized to the brim and completely based on 8 and 16 bit values, because I planned to do the effect in realtime. So changing a single value, will blow everything up! ;o) |
| |
Oswald
Registered: Apr 2002 Posts: 5085 |
thanks!
maybe with some tweakage I can get the euler method working, only I didnt expect this to take days, rather only some hours to get right.
this is what I do, the problem is that it almost never gets close to resting. maybe using a damp table where x is not divided with 2^x will help.
springtest
lda #40
sta springhh
sta springhl ;spring height
lda #00
sta springsl
sta springsh ;spring speed
u lda #$40
- cmp $d012
bne -
ldx springhh ;spring height HI byte
lda dampl,x ;0 height is assumed resting
clc ;damp table is 16 bit, x/2^7 signed used to change velocity
adc springsl
sta springsl ;spring speed LO
lda damph,x
adc springsh
sta springsh ;spring speed HI
lda springhl
clc
adc springsl
sta springhl ;spring height + spring speed 16 bit
lda springhh
adc springsh
sta springhh
sta $d000 ;to see how it moves
jmp u
|
| |
Axis/Oxyron Account closed
Registered: Apr 2007 Posts: 91 |
Basically you are on the right way. The damping table is the place for tweaking. But I´m not sure what you want to reach. Only moving a rasterbar or sprite on a wavy motion or building a 2d-waveshape like in CL13? For reaching the latter, you definitely need to take the neighbours into account. |
| |
Oswald
Registered: Apr 2002 Posts: 5085 |
well, first I need to get 1 spring right, only after that can I move on to spread the forces.
I hope the problem is that I only use a x/2^7 damping table, and dividing by some other value or making it non linear will help. |
| |
Copyfault
Registered: Dec 2001 Posts: 470 |
Never did such a routine before, but sounds interesting for sure.
If I understand the article linked in the original posting _and_ your code snipplet correctly it seems that
i) the dampl/h-tables you already have in the code are actually acceleration tables
ii) you need to add real damping depending on the current velocity
something like
u lda #$40
- cmp $d012
bne -
ldy springhh ;spring height HI byte
lda acc_lo,x ;0 height is assumed resting
clc ;damp table is 16 bit, x/2^7 signed used to change velocity
adc springsl
sta springsl ;spring speed LO
lda acc_hi,x
adc springsh
sta springsh ;spring speed HI
lda springhl
clc
adc springsl
sta springhl ;spring height + spring speed 16 bit
lda springhh
adc springsh
sta springhh
sta $d000 ;to see how it moves
jmp u
maybe already does the trick... |
| |
Copyfault
Registered: Dec 2001 Posts: 470 |
sorry, I f**ked up my last posting, at least the "code part".
Another try ;))
u lda #$40
- cmp $d012
bne -
ldy springhh ;spring height HI byte
ldx springsh ;speed value hi byte for damp calculation
lda acc_lo,y ;0 height is assumed resting
sec ;damp table is 16 bit, x/2^7 signed used to change velocity
sbc damp_lo,x ;formula says "acc = k*x - d*speed"
adc springsl
sta springsl ;spring speed LO
lda acc_hi,y
adc springsh
sbc damp_hi,x
sta springsh ;spring speed HI
lda springhl
clc
adc springsl
sta springhl ;spring height + spring speed 16 bit
lda springhh
adc springsh
sta springhh
sta $d000 ;to see how it moves
jmp u
Maybe your damp-table is a combination of both acc_lo/hi and damp_lo/hi, but how can you get the dependencies right with only one table?
Guess Axis knows best, he's gone through it already.
Let's see where this leads to, I'm alread looking forward to this year's Arok party;) |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Bah, just animate it using delta compressed motion on each column. :) |
| |
Oswald
Registered: Apr 2002 Posts: 5085 |
copyfault,
formula says:
float x = Height - TargetHeight;
float acceleration = -k * x;
Position += Velocity;
Velocity += acceleration;
I took targetheight to be 0, so acceleration = damptable(height)
Position += Velocity; this is the last part in my code
Velocity += acceleration; this is the adc damp,x part
aha gotcha ! I mixed things up, I wasnt doing any dampening at all, that was just the normal spring part.
thanks! :) |
| |
Axis/Oxyron Account closed
Registered: Apr 2007 Posts: 91 |
In C my code looks like:
velocity=velocities[x];
for (int dx=-4 ; dx<=4 ; dx++)
{
delta=height[x+dx]-waterplane;
velocity-=delta*weight[dx];
}
velocities[x]=velocity;
height[x]+=velocity*damping;
In my case weight is a gaussian distance table. If you only consider a single value its just a constant that can be used for tweaking. Perhaps it can even be optimized away, because my weight table sums up to 256.
Damping is a constant factor for tweaking motions.
So a simplified version considering only 1 column would look like this:
delta=height[x]-waterplane;
velocities[x]-=delta*weight; ;perhaps weight is 1 and can be removed
height[x]+=velocities[x]*damping;
|
| |
Oswald
Registered: Apr 2002 Posts: 5085 |
thanks that will nail it, basically I should've feed the speed into a table that always reduces it a "bit". |
| |
chatGPZ
Registered: Dec 2001 Posts: 11335 |
Quote:just animate it
that actually seems the correct answer to the original question :=) |
| |
Rudi Account closed
Registered: May 2010 Posts: 125 |
Better do it in C or your language of choice before coding it in assembler. So you have an reference point. If c64 asm-code doesnt work you know its not the algorithm that is wrong. If you dont allready do that.
It takes a few tries to get something up and working. I made a cloth simulation ~10 years ago (in C on PC) and it worked very nicely after many tries. I learned from Hugo Elias also, he still have some of those great articles and pseudocode on subjects like these here:
http://freespace.virgin.net/hugo.elias/models/m_string.htm
and
http://freespace.virgin.net/hugo.elias/models/m_cloth.htm |
| |
Oswald
Registered: Apr 2002 Posts: 5085 |
well, adding up a few 16 bit values and a table lookup looked simple enough to go straight for it, the problem rather was I did not fully understand the math, also the article gives a source code without damping and then later talks about damping.
now I've wrote the code by looking at that incomplete source snippet.
animating it is out of the q, in fact its simpler to make this realtime imho. why animate stuff thats a few dozens of 16 bit adds and table lookups.
remember kids, realtime rules :) |
| |
Digger
Registered: Mar 2005 Posts: 425 |
Oswald, here you can edit the code online and strip it out until you get the idea :) http://paperjs.org/examples/future-splash/ |
| |
Martin Piper
Registered: Nov 2007 Posts: 712 |
Verlet maths can be quite sensitive to numerical accuracy because small numerical errors can get magnified quite quickly without suitable damping.
For example https://github.com/martinpiper/C64Public/blob/master/Verlet/Tes.. |