#### Archived

This topic is now archived and is closed to further replies.

# Metaballs - Normals

This topic is 5274 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

That would probably work.

The problem comes when you introduce anti-metaballs that subtract energy. But my guess is that there would be a whole lot other issues to solve as well if such where to be added.

The extra step I referred to was not that you pre-divided the normal magnitude. It was that you used a higher power than I did, which looks better. I''m now trying to figure out the exact power to use when computing the normals.

- WitchLord

##### Share on other sites
To calc the energy from 1 ball I use: (And add forces for more balls)
rr = (x-tx1)*(x-tx1) + (y-ty1)*(y-ty1) + (z-tz1)*(z-tz1);Force = MB_SIZE*MB_SIZE/rr;

To calc the normal I use: (Add normals for more balls)
n = MB_SIZE*MB_SIZE / (sqrt(rr) * rr);pVertex->nx = (x-ballx)*n;pVertex->ny = (y-bally)*n;pVertex->nz = (z-ballz)*n;

Hope I''ve got it correct, and hope it helps,
Bas.

(ps: Can''t run your demo! Get an error about "DDRAW.DLL: DirectDrawCreateEx". I have no 3D card. Do I need to upgrade my DirectX 6.1 version first?)

##### Share on other sites
I''ve been tweaking my program a little, here''s a new screenshot:

I have changed the normal computation for my program so that it is now done like this:

inline D3DVECTOR CMetaBallApp::Normal(D3DVECTOR &Pos){  D3DVECTOR N = D3DVECTOR(0,0,0);  for( int i = 0; i < m_nNumBalls; i ++ )  {    D3DVECTOR v = Pos - m_Balls;    float m = SquareMagnitude(v);    m = SQRADIUS / (m*m);    N += v*m;  }  return Normalize(N);}

I couldn''t see much difference between using

and

so I decided to use the one that was faster. Though no performance difference was visible.

- WitchLord

##### Share on other sites
You''re almost making the same mistake I made (page 2, post 3), but I must say: Looks great! Can''t see the difference!

But after lozing the sqrt from this part you probably have to normalize, and the sqrt is back.

I think the sqrt() is there to make the vector (CenterBall to CurrentVertex) of unit length 1.
What do you get if you use the sqrt() and drop normalization?

Your metaballs look great, all 5! of them.

##### Share on other sites
If you want Phong mapping:
- Use a phong map (texture)
- Do environment mapping (use the x & y part of the vertex normals as texture coords)

Here's a PhongMap/Texture:

You can also add a picture-texture by:
- Use the PhongMap as a lightmap orso??? I have never done this with OpenGL or Direct3D, is this possible?
- Mixing it with the phong map. (But then you will not be able to rotate around it) (this would increase the speed of my software engine greatly, but the total engine isn't based on this, and after optimizing this will not support other models...but good idea for you!)

The disadvantage you have with phongmapping is: Your light must come out of the camera, in the Z direction.
Well, you don't have to, but then there's also a light spot on the other side (real ugly).

(ps: We're now in the 25 hottest topics of all time)

Edited by - baskuenen on May 26, 2000 12:35:17 AM

##### Share on other sites
You're right, I did some refurnishing in my functions and now everything looks much logical. Here's what they look like:

inline float CMetaBallApp::Energy(D3DVECTOR &Pos){  float e = 0;  for( int i = 0; i < m_nNumBalls; i++ )  {    float SqDistance = SquareMagnitude(Pos - m_Balls[ i ]);    e += SQRADIUS / SqDistance;  }  return e;}inline D3DVECTOR CMetaBallApp::Normal(D3DVECTOR &Pos){  D3DVECTOR N = D3DVECTOR(0,0,0);  for( int i = 0; i < m_nNumBalls; i ++ )  {    D3DVECTOR v = Pos - m_Balls[ i ];    float SqDistance = SquareMagnitude(v);    v /= (float)sqrt(SqDistance); // Normalize the vector    // We should scale this vector so that the contribution from this     // metaball is inversely proportional to the square distance, because    // the energy from it is also inversely proportional to the square     // distance.    N += (SQRADIUS / SqDistance)*v;  }  return Normalize(N);}

Can you see the similarities?

And I tried to drop the normalization of the normal after the summation but that doesn't work, the lighting gets all screwed. It's actually quite easy to see that it must be normalized. Think about what happens when you have two balls and you take a point exactly between them, then the normal will have zero length. If you move just a little bit away from this spot the normal will be small but it can be normalized to give a unitlength direction.

During this testing I also tested to change the energy function so that it has linear falloff. It still produces metaballs, but they have slightly different properties; They grow a lot more when they are close to each other.

nVidia has some cool demos and papers on how to go about to create phong mapping with specular highlights with OGL and D3D. I had initially planned to implement that and cub environmentmapping on my metaballs, but now I think that I should go back to writing my game instead. Maybe I'll dig up my metaballs again later and add some cool effects to them.

It's been fun.

- WitchLord

Edited by - WitchLord on May 27, 2000 1:50:04 AM

##### Share on other sites
n = MB_SIZE*MB_SIZE / (sqrt(rr) * rr);
--
This:
n = MB_SIZE*MB_SIZE / (sqrt(rr) * rr);

Should be:
n = MB_SIZE*MB_SIZE / (rr * rr);

If you're using "force+=radius/distance;" (not square distance), then the "n = MB_SIZE / (sqrt(rr) * rr);" is correct.

I still don't get why you have MB_SIZE*MB_SIZE and not only MB_SIZE...

-Hans

Edited by - Hans on May 27, 2000 3:07:51 AM

##### Share on other sites
Even though I haven''t had the energy to sit down and prove my theory with maths, I believe you are wrong, Hans. Both the normal and force computations should be the same:

P: Point to be computed
C: Center of metaball
v = P - C;
r = Magnitude(v);
force += n;
normal += n*v/r;

or

v = P - C;
rr = SquareMagnitude(v);
force += n;
normal += n*v/sqrt(rr);

---

baskuenen, when I tried your program it desided to use 16 bit mode because my GeForce 256 don''t support 24 bit mode. Perhaps you should implement you engine to support 32 bit also.

- WitchLord

##### Share on other sites
I''ve now tried it without the sqrt(), and it looks a bit sharper. Also it''s faster (not noticeable though).

The phong spot looks a bit better this way, but the sharp edges between the balls are a bit too sharp.

Here''s a new screenshot:

The use of sqrt() or not is getting a bit confusing to me. I can understand the math using sqrt(), but it makes no sense to me if I lose the sqrt().

Hans: why lose the sqrt? It''s used to make the normal in the calculation of unit length 1, before dividing it with the force from that single ball. (But in practice it almost seems right to lose the sqrt!)

Good idea, the 32bit color depth support...will do that.

##### Share on other sites
What would be a good idea for implementing metaballs into a game? Another remake of tetris, but this time with blobby objects, seems a little boring!

It could be a nice way to have an animated man running around. Although texturing this would be quite hard.

Maybe this question is a little of the topic: Imagine a running man; How do I calculate the anim paths for this? (the metaball coords in this case). Can a few simple sin & cos be enough, or is human movement more complex?
I can imagine setting up a tree...

Edited by - baskuenen on May 27, 2000 4:12:37 PM

##### Share on other sites
I''m just beginning to realize the potential for metaball implentation in games! It''s uge!
Just image perfect collision detection, or calculation of the force for bouncing back after a crash! Adding dents in your car after crashing into a wall. Let your enemy explode like the Terminator2 badguy. Shoot lasers through a boss figure and slowly see it''s flesh turn liquid...

Whoaow, just found another dimension to game programming! If you can actually put it to good use in a game - it will atleast look original! -

##### Share on other sites
It sure will.

Unfortunately it still requires a little bit more processing power than we can afford to use in games. But it shouldn''t be any trouble to use metaballs in modelling programs to generate smooth objects for use in games or animations.

I don''t think it will be as easy to animate human movements with just a few sines and cosines, but you should be able to use the same techniques that are used today with skeletal animations. Just attach the metaballs to the bones and then animate the skeleton.

- WitchLord

##### Share on other sites
Yes, attaching the metaballs to the bones should do the trick.
I''ve been looking around, but cannot find any usefull programming stuff on skeletal animations.

A bit off-the-topic questions:
Yes I agree simple sin/cos will probably not be enough, maybe splines are the way to go?
Is it best to use a tree for the skeleton, or are all animation paths precalculated?
Is there a common data format for motion capturing orso?

Do you know any good tutorials or other links on skeletal animations?
Thanks,
Bas.

##### Share on other sites
Not yet, I haven't searched for it.

But I know how it works

- WitchLord

Edited by - WitchLord on May 27, 2000 11:24:43 PM

##### Share on other sites
Hey guys, get back to the topic

Witchlord, I think you'd better get the energy to prove your algo because I believe my eyes more than your assumptions

Here's a picture, using your normal-calculation algo
P: Point to be computed
C: Center of metaball
v = P - C;

(look at normals near the upper-right-ball for example)

And here's a picture, using a slightly different algo

See how the normals are correct in the lower picture and all messed up in the upper picture?

And

should be

After little testing I came up with this formula:

Don't ask me about that ^2 there, I know ^1 would normalize the vector, but it seems that only ^2 works correctly.
And I believe that baskuenen got also better results with the latter algo..

And that goo value tells how much the elements melt together; the lower it is, the more they melt. The goo value can also be negative (!) and the normals are still correct (but negative goo values give very strange and unwanted results anyway). Here's a picture where goo value is -1. As you can see, metaballs are turned inside out now =)

Here's the program I used to create the images. It's now set in the correct algo, but you may freely test it and change the ^(2+goo) lines to ^(1+goo) and see the results.

http://www.kolumbus.fi/hannes.k/METABALL.BAS

And hey baskuenen, that T2 explosion with metaballs is a great idea (it would look unbelieveble!) but you'll have to wait for maybe 10 years to get a 3d-card that accelerates metaballs.

-Hans

Edited by - Hans on May 28, 2000 4:24:40 AM

##### Share on other sites
You are showing some pretty convincing arguments, Hans.

I''m inclined to believe you now, but to get to the bottom of this I think I''ll just sit down and actually prove the formula

I''ll get back to you all with my results later on

- WitchLord

##### Share on other sites
Ok, I have now proven the formula. First, here is the formula:

f += (r/d)g

n += g*rg*v/dg+2

r is the radius of the individual balls
g is the 'goo' factor
v is the point-center vector
d is the length of v

And now I'll try to explain the mathematical proof. If you haven't come this far in school you'll just have to trust me. If you have come this far then please make sure that I haven't made any mistakes.

The force at each point is computed with

f(p) = Sumi=1 to n( rg*di-g )

and the derivation of this is

df(p)/dx = Sumi=1 to n( -g*rg*di-g-2*vi.x )

The same goes for y and z. With this derivation we have computed the tangential plane of the surface in point p. When we take the normal to this plane the minus will disappear.

- WitchLord

Edited by - WitchLord on May 28, 2000 5:27:40 PM

##### Share on other sites
For those of you who downloaded my code before I have now updated it to use the correct formula.

Hmm, I realize that the above explanation for the formula isn't much of an explanation. Basically the only thing I say is that the normal is a derivation of the energy function. If you want a better explanation I could try to give it to you, but you'll have to ask first.

Just realized that this was in fact exactly what goltrpoat was trying to tell us at the first page. Why didn't we listen to him then? It would have saved us a lot of time and work

- WitchLord

Edited by - WitchLord on May 28, 2000 8:35:45 PM

##### Share on other sites
Here''s my latest version (including some less interresting models), with 32bit color supported. Hope it works.

Yes, Looks real convincing Hans! Especially the pictures!

> Just realized that this was in fact exactly what goltrpoat was trying to tell us at the first page. Why didn''t we listen to him then? It would have saved us a lot of time and work.

I must confess, I still don''t exactly understand what goltrpoat is saying - allthough nurbs/bezier is nothing new for me! Maybe I''ve been doing too much programming and too less "paper"-math lately?

If goltrpoat is right - It would have saved some time, but we sure would have missed the fun!

WitchLord: Downloaded your new demo, but still get the "DDRAW.DLL:DirectDrawCreateEx" error? I have no 3D card, Win95 and running DirectX 6.1. Will download latest DirectX in a minute...maybe this''ll help? (and by the way: good luck with your new job!)

Will be back...

##### Share on other sites
quote:

Here''s my latest version (including some less interresting models), with 32bit color supported . Hope it works.

It worked flawlessly And it looks amazing, except for the low resolution. Perhaps you could try adding antialiasing? What is that spiralthing, anyway?

quote:

I must confess, I still don''t exactly understand what goltrpoat is saying - allthough nurbs/bezier is nothing new for me! Maybe I''ve been doing too much programming and too less "paper"-math lately?

What he is talking about is that for any surface that is described by a continuous function (as metaballs, beizers and nurbs) you can find the tangential plane to the surface by deriving the function. From this plane the normal can then easily be found for example with a crossproduct.

quote:

If goltrpoat is right - It would have saved some time, but we sure would have missed the fun!

Yeah we had fun didn''t we

quote:

WitchLord: Downloaded your new demo, but still get the "DDRAW.DLL:DirectDrawCreateEx" error? I have no 3D card, Win95 and running DirectX 6.1. Will download latest DirectX in a minute...maybe this''ll help? (and by the way: good luck with your new job!)

With DX7 you will be able to run my demo, but without a 3D accelerator it will be painfully slow. How did you survive all this time without a 3D card?

- WitchLord

##### Share on other sites
Antialiasing, good point. I''ve been thinking about this, but can only come up with a fast horizontal antialiasing algo. (maybe that''s enough?)

The spiralthing, was a lot work figuring out how to implement. It''s a torus knot. (wrapped around a torus). I have more info, if you''re interrested...

Have installed DX7. It works! Looks great, and runs fast enough, even fullscreen 1024x768x16! But I got an error when running in 24bits color. After setting it manually to 16bits it ran just fine. Maybe it''s not real important, but I also got a "SURFACE lost" error from your demo after running my demo in between. I used:
SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE/DDSCL_FULLSCREEN)

Should I be doing this?

I''m not really missing a 3D card! I didn''t play much games lately (although I probably should - doing gamedev).

Have tried environment/phong mapping yet? It''s much easier than it looks, but hey who am I telling this to!

Bas.

##### Share on other sites
The torus knot doesn''t interest me because I see absolutely no use for it. But it looks cool

I don''t know why you couldn''t run the program in 24 bit mode. Maybe it is a memory problem, but I doubt it since all surfaces should be in system memory anyway. Could you tell me the error code that you get?

The surface lost problem is most likely due to me not bothering to implement any recovery routine. Maybe I should do that?

> SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE/DDSCL_FULLSCREEN)

Is this in your own program? I thought you didn''t use DirectX. Anyway it''s perfectly legal, and is the way to set fullscreen mode in DirectDraw.

Environment mapping in Direct3D is even easier since you don''t even have to compute the texture coordinates yourself. There is a mode that does that for you

- WitchLord

##### Share on other sites
Hi guys!

Just for example, if you wanna look for real good metaballs, get this one:

[url]http://codexorg.webjump.com/metaballs.arj[/url]

That''s not mine, but they absolutely free with no charge or license (as written at the top of main file), and sources are included.

Regards,
FlyFire/CodeX
[url]http://www.codex.nm.ru[/url]

##### Share on other sites
Hey the formula works! I didn''t know before how to take the size and goo value correctly into account, so I had to have the same goo value for every ball (that g*size^g was quite tricky, and I couldn''t have just quessed it . good that someone here knows how to derivate vectors ). But now I tested with balls that were all different sizes and all had different goo values (one of the balls had even negative goo value) and everything worked well. And as expected the balls with high goo values didn''t melt as easily to other balls.

Baskuenen, I downloaded your new 3d-engine show. The metaballs look good but you should improve your metaball engine so that it can have different sized balls and different goo values for each of them (well not maybe fractions or negative values but goo values 1,2,3,4,5 should be fast to calculate).

One more improvement to the metaball system: why not making a 3d-texture that would tell the amount of force at each point. It wouldn''t have to be that huge texture because you can trilinearly interpolate all the accuracy you want. Then you could have every kind of metaobjects: cars, airplanes and even boxes , and they would melt seamlessly together.. But then you''d had to trash the formulas that we''ve been arguing here so long .. And of course then you would have to calculate the vertex normals in some polygon-kind-of-way like described at the first page of this thread. But it would look aawwwwwesome

-

And Witchlord, a bit off topic question, but where can I get a neat www.myname.com address that would forward visitors to my own pages (that are actually located somewhere else, like your pages).

-Hans

##### Share on other sites
WitchLord:
Here''s the error info I get when running the demo in 24bit color:
error: DDERR_INVALIDPIXELFORMAT
file: d3dapp.cpp
line: 508

No bother implementing the recovery routine, if you ask me. It''s probably not worth your time.

quote:
> SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE/DDSCL_FULLSCREEN)

Is this in your own program? I thought you didn''t use DirectX.

I had no choice - it was the only way to use fullscreen 320x200. But I only used 4 functions orso.

Hans:
quote:
Baskuenen, I downloaded your new 3d-engine show. The metaballs look good but you should improve your metaball engine so that it can have different sized balls and different goo values for each of them (well not maybe fractions or negative values but goo values 1,2,3,4,5 should be fast to calculate).

Thanks, and implementing different sized balls would probably look better. Do metaballs with goo value 5 not provide (too) sharp edges? Practice will prove, but at the moment school is demanding much of my free time...but meta-vakation is coming up...

quote:

...3D texture...
...Then you could have every kind of metaobjects: cars, airplanes and even boxes...

Didn''t think of that. Nice idea! The meta-stuff idea''s seem endless...

- Bas.