3D Morph?

Blitz3D Forums/Blitz3D Programming/3D Morph?

Pongo(Posted 2004) [#1]
I was thinking of a concept, and I'm not quite sure the best way to accomplish this.

What I would like to do is have a character that can change slowly over time as the game plays. Color changes are easy through use of textures and entity color controls, but I would also like to alter the shape,... to make it more complicated, I would like to be able to blend multiple targets together.

For example,... I would have a creature in the following meshes,... all with the exact same vertice/face count and structure:
Base mesh (plain with no features)
Base mesh with horns on back of head
Base mesh with large nose
Base mesh with different shaped eyes

Now,... what I would like to be able to do in-game is mix these together,... a base mesh that has 20% horns, 50% large nose, and 10% different eyes. These would change over time. and could have animations from a base set applied to them.

In MAX, I can do this with a morph modifier obviously, but I would like to have that control in-game, so that game events change the character.

Has anyone written any functions like this, or is there a relatively painless way to do this?


_PJ_(Posted 2004) [#2]
There are commands to alter the vertices of meshes directly. Although I think this doesn't need to be done as animation sequences per se.

You don't even need separate meshes.

Whether you would want to constantly check and update the vertices (whether or not the percentages have changed) I am not sure.

It's certainly possible though - Im not really very good with modelling and stuff though ;)


Pongo(Posted 2004) [#3]
Hmmm,... maybe I didn't explain this well enough. Let me try again.

Imagine you have a goldfish model. It has animation applied to it to allow for different motions of swimming,eating,...etc.

Now you also want to be able to smoothly turn it into a shark, so you modify the mesh so the head is like a shark. You also modify the fins seperately. The reason for doing everything seperate, is so it can be blended smoothly in sections as desired.

For example,... After eating a special food, the goldfish grows a large shark fin, so I blend that mesh in with the original. After doing something else, perhaps the head starts to change into a dolphin head, but retains the shark fins. So I mix in a dolphin head mesh with a shark fin mesh at the appropriate mixture.

In order to do this, all meshes are based off of the original, with only vertices moved around. Although you can move individual points in blitz, I need them to be precisely to what has been modeled. (ie,... load the manipulated mesh, grab all the vertex locations and compare to the original to find out what is changed. Then use that info to move the vertices toward a certain shape)

In Max I can do this by making my seperate shapes and using a morph modifier,... what I would like is to have is that functionality in code.

Hope you're not even more confused now! (I know I am!)


_PJ_(Posted 2004) [#4]
Sorry I thought you meant the mesh would gradually change over longer amounts of time.

I should have picked up on your use of the word 'morphing'!!!

I think you would need separate meshes for the horns, head, nose etc (I know it sounds like a lot)and assign the animation sequences to these??? At least there are commands to control the speed and smoothness of the animations.

This is where it gets way out of my depth though...


Pongo(Posted 2004) [#5]
nope,... still not right. I actually DO want it to change gradually over time. As a matter of fact, so slowly that you do not see it happening while it is changing.

Using the Fish example,.... say for example the fish starts eating a lot and therefore gets fat. I don't want to suddenly just pop a new fat fish in, I want it to happen very slowly, so that you look at it and ask "is that fish fatter than he was a bit ago?" Same with the other changes. Because of this, the function would not need to be called very often, maybe once every 30 seconds or so would probably even be enough.



The method I have in my head is this,... load in each mesh and store all vertex positions,... then call a function that mixes the position of the vertices based on what you want. In the most simple of cases,... 2 meshes,... the output would be a straight mix between the 2, but there is more to it when more variations come in.

Hope this is making more sense now.


Bot Builder(Posted 2004) [#6]
hrm. can't you just loop through all the verts and position them at a point on the line between the target and the finish vert? to do this all you need to do is make a weighted average of the coordinates like this:

cx=(ox*(255-time)+nx*time)shr 8
cy=(oy*(255-time)+ny*time)shr 8
cz=(oz*(255-time)+nz*time)shr 8
this assumes time is between 0 and 255. the shr 8 effectivly divides by 256. c* is the current location, o* is the start vertex location, and n* is the final vertex location. If you want to say, blend between 3 or 4 mehs you could use bezier interopoloation instead of linear interopolation.


Pongo(Posted 2004) [#7]
Maybe I'm overthinking this,... I know I'm in over my head anyways, but what the heck. that's never stopped me in the past.

I guess I'll just have to code something together and see what happens instead of worrying what won't work. My biggest concern was weighting more than 1 point where the point is stationary in multiple meshes. I don't want an average of those points in that case (don't know if this makes sense though, pardon me while I think out loud) I think the way around this is to not store the vertex positions, but the position offset from the original mesh,... then I can apply multiple offsets from different meshes. Hmmm,.. I'm sure no one knows what I'm talking about, but a light bulb is going off over my head right now.


AbbaRue(Posted 2004) [#8]
Just a suggestion, but if you use an x file for your mesh, x files are text files.
If you alter the values in the text file you can make it look however you want.
This is a thought I will be persuing for my project, once I get finished with my outside world.
Or better yet, convert your fish into an x file load it into a text editor
and then cut and paste the vertices into you program. Then you can alter the
verticies using math functions to get any effect you want.


jfk EO-11110(Posted 2004) [#9]
I don't know if it was said before: make models of all required shapes and use the same number of vertices with eachone of them. Now you can morph them easily with cheap math formula, as slow as you want. Simply interpolate the vertices to the new positions.

There is an other problem with textures. If you want to morph them too, this might slow things down. But it's possible.


Ruz(Posted 2004) [#10]
aww i thought you meant morph, the plasticine guy from take hart


PetBom(Posted 2004) [#11]
The maths for doing a morph is really easy if you have the meshes to morph between. This is a function that I created some time ago to do some simple morphing for an idea i had. You simply call the function and send in the mesh to be morphed, the base mesh of the morph, the target mesh of the morph, and a stage between 0 and 1 that sets the bias of morph between base and target (0 = as base, 0.5 = even mix betwen base and target, 1 = as target).

Function DoMorph(morph,base,target,stage#)

	timeMorph = MilliSecs()

	allSurf = CountSurfaces(base)	
	
	For j = 1 To allSurf

		surfBase = GetSurface(base,j)
		surfTarget = GetSurface(target,j)
		surfMorph = GetSurface(morph ,j)
	
		allVerts = CountVertices(surfMorph)
	
		For i = 0 To allVerts-1
			VertexCoords surfMorph,i,VertexX(surfBase,i) + ((VertexX(surfTarget,i)-VertexX(surfBase,i))*stage),VertexY(surfBase,i) + ((VertexY(surfTarget,i)-VertexY(surfBase,i))*stage),VertexZ(surfBase,i) + ((VertexZ(surfTarget,i)-VertexZ(surfBase,i))*stage)
		Next
	
	Next
	
	Return  MilliSecs() - timeMorph
	
End Function


Oh! I just noticed there's a timer in there as well, which actually is the return value from the function. I guess I needed to time the time taken to do the morph. you can just remove it.

If you like I could send you the project where I do the morphing. It's actually really simple. I remember I just whipped it up in a few hours to test if you could do it

Hope this helps!

/PetBom


PetBom(Posted 2004) [#12]
Oops!

Sorry for posting that code with the very long line! I did not realize that it would make this page superwide!

Another thing that I forgot to mention with regards to morphing is that the morph,base and taget meshes must have
EXACTLY the same number of vetices and the same vertex and surface indexes. But this is nothing that is blitz specific, it is true for all morphing algorithms, since mophing in the end just is simple interpolation of vertexes in two vertex sets

/PetBom


Ross C(Posted 2004) [#13]
I thought you couldn't access the vertexs of an animating entity? I mean, they only gave vertex info from the intial un-animated positions..


PetBom(Posted 2004) [#14]
Ross C - You are right.You can not access the vertex positions of a mesh being animated through vertex deformation. So I guess my example only works if you use other forms of animation.