Changing the Model.Mesh at runtime?

Discuss the ZGameEditor Visualizer plugin for FL-Studio.

Moderator: Moderators

Post Reply
Mic
Posts: 47
Joined: Mon May 30, 2011 8:10 pm

Changing the Model.Mesh at runtime?

Post by Mic »

If I have a model using mesh1 running around the screen, can I change the mesh1 to mesh2 while the model is instantiated? (Haven't tried yet)

TIA,

Mic.
User avatar
Kjell
Posts: 1910
Joined: Sat Feb 23, 2008 11:15 pm

Post by Kjell »

:)

Sure! Attached is a example ~

K
Attachments
Mesh.zgeproj
(826 Bytes) Downloaded 1151 times
Mic
Posts: 47
Joined: Mon May 30, 2011 8:10 pm

is there a technique to morph slowly?

Post by Mic »

Thanks for the example - much appreciated. Is there a technique to morph slowly between 2 different meshes or would I send the second mesh data to the Shader and write shader morph code to move vertices etc? TIA,

Mic.
User avatar
Kjell
Posts: 1910
Joined: Sat Feb 23, 2008 11:15 pm

Re: is there a technique to morph slowly?

Post by Kjell »

Hi mic,
Mic wrote:Is there a technique to morph slowly between 2 different meshes?
There's no morph support build-in at the moment. However, there are 3 DIY solutions .. each with their own shortcomings.
  • Simply render the morphed mesh using OpenGL directly. However, because ZGE doesn't support pointers, you can't use a Vertex Array / VBO and thus rendering will be relatively slow.
  • Use the RefreshContent component on a Mesh. Rendering will be faster then the previous option, but because you can't update vertices individually, you need to use a counter & if-statement to isolate individual vertices ( which adds some overhead / performance-loss ).
  • Pass the data to a shader using the new ShaderArray component. Normally you'd "bake" this data into the mesh using vertex attributes though .. which would be allot faster. Obviously this option requires hardware that supports shaders.
What kind of mesh are you dealing with ( polycount / normals / texture-coordinates / vertex-colors etc )?

K
Mic
Posts: 47
Joined: Mon May 30, 2011 8:10 pm

re: morphing ...

Post by Mic »

A good example would be the Ballz preset and the balls slowly changing to cubes.
User avatar
Kjell
Posts: 1910
Joined: Sat Feb 23, 2008 11:15 pm

Post by Kjell »

Hi mic,

If you're going to do something simple like morphing a cube into a sphere, you might as well do it on the fly 8) You can always optimize later in case you run into frame-rate issues. Attached is a example.

K
Attachments
BoxSphere.zgeproj
(2.22 KiB) Downloaded 1189 times
Mic
Posts: 47
Joined: Mon May 30, 2011 8:10 pm

re: BoxSphere example

Post by Mic »

Many thanks for this example - have questions :-)

1. You are creating a SphereMesh and then doing a MeshLoad of BoxMesh within its Producer. It looks like by setting

float X1, Y1, Z1,
X2, Y2, Z2, S, V;

at the top MeshExpression you are able not only to grab " The special read/write property "V" holds the current vertex" but also a vertex from the MeshLoad vertices into X2,Y2,Z2. Then the MeshExpression code interpolates between a vertex from the SphereMesh (current mesh) and a vertex from the loaded mesh (BoxMesh)

How comes when I add several MeshLoads, X2,Y2,Z2 are always the last MeshLoaded e.g.

MeshLoad BoxMesh1
MeshLoad BoxMesh2
MeshLoad BoxMesh3

would morph to BoxMesh3?

2. Following the above, what I was trying to do was not have SphereMesh "hardcoded" but be able to choose that at runtime i.e. within code choose to morph between BoxMesh3 and BoxMesh1.

As always TIA, and as always if this stuff is documented somewhere slap me and make me read it :-)

brrhhhh - went from 80F yesterday here in Denver to sleet and rain and 35F today ... nothing for it but to turn the heat up and spend all day on ZGE!

Mic.
User avatar
Kjell
Posts: 1910
Joined: Sat Feb 23, 2008 11:15 pm

Post by Kjell »

Hi mic,

Seems like you misunderstood the Mesh generation process a little :)

The only reason for using a MeshLoad instead of a MeshBox is because it is faster to copy / load a generated mesh instead of generating the box every frame. Similarly, all of the local variables used in MeshExpression are merely there for performance reasons. Whenever you access a global-variable / component-property more then once in a expression, it usually pays off to store the value locally first.

So, X1/Y1/Z1 hold the vertex positions of the Box, X2/Y2/Z2 hold the generated* vertex positions of the sphere, S is a variable used in the sphere calculation, and V isn't some magic variable that holds the vertex number, but simply a local copy of the global variable Value ( which determines the % of the mesh-morph mix ).

Anyway, please explain exactly what it is you're trying to create. I can't imagine you actually want to morph a box into one of two other boxes ( as you mentioned ).
Mic wrote:.. what I was trying to do was not have SphereMesh "hardcoded" but be able to choose that at runtime i.e. within code choose to morph between BoxMesh3 and BoxMesh1.
*Since the calculation is relatively simple & for convenience purposes I simply calculate the sphere on the fly. It would however be faster to do the calculations once and cache the results.

K
Mic
Posts: 47
Joined: Mon May 30, 2011 8:10 pm

re: please explain exactly what it is you're ...

Post by Mic »

FL and ZGE combination awesome and need to work out how to code it as quickly as possible .... fast track = set a problem and then code it ... e.g. take Ballz example and have daggers instead of balls where the daggers slowly morph into skulls which morph into cups.

I wanna write in App.OnLoaded.ZExpression:

var mshDagger:Mesh = new Mesh;
var mshSkull:Mesh = new Mesh;
var mshCup:Mesh = new Mesh;
mshDagger.meshImport = 'Dagger.3ds';
mshSkull.meshImport = 'Skull.3ds';
mshCup.meshImport = 'Cup.3ds';

var mshBase:Mesh = new Mesh; // base mesh used by model
mshBase.meshLoad(mshDagger); // load morph mesh 1
mshBase.meshLoad(mshSkull); // load morph mesh 2

and in mshBase.MeshExpression (since mshBase = new var, the meshExpression code must be inherited from a Mesh parent class Is this possible?):

// morph from Dagger to Skull
// change example code - replace circle algorithm with Dagger or Skull mesh

// be able to change runtime var that flags morph between Skull and Cup
mshDagger.unload; ?
mshBase.meshLoad(mshCup);

(can I write code like this in ZGE?)

I looked carefully at your good example and misread SphereMesh as MeshSphere and was thinking you were morphing between 2 loaded meshes - a sphere and a box ...... but you have 1 loaded mesh - the box and you are applying a circle algorithm in the MeshExpression, right? How would I morph between e.g. a dagger and a skull?

If this was done in a Shader, it would have to be in the geometry shader I think .... if I am reading correctly the Vertex Shader cannot change the number of existing vertices but can move them around ... the Geometry Shader can create primitives/vertices .... which would mean having to pass the 'morph-to mesh' to the shader and write an algorithm that could cope with different vertices count between to and from meshes, know how far it was between from and to, how to collapse/expand vertices count etc ...... possible with enough geometry primers? :-)

Thanks!

Mic.
User avatar
Kjell
Posts: 1910
Joined: Sat Feb 23, 2008 11:15 pm

Post by Kjell »

Hi mic,

The standard way of morphing between 2 arbitrary meshes is to create a blend-shape* using the mesh with the highest polycount that matches the other. I'm not aware of any algorithms that lets you do that automatically.

*What animation software are you using ( Maya / Softimage / Blender ) ?

Attached is a example showing a wolf morphing into a bear.

K
Attachments
Morph.zgeproj
The meshes contain some errors, please ignore :P
(31.8 KiB) Downloaded 1214 times
User avatar
VilleK
Site Admin
Posts: 2318
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Post by VilleK »

That morph looks smooth, Kjell :). I noticed that in your example the morphing did not always work (standalone exe vs. inside ZGE). It is because meshes are not created until they are rendered, so the Bison MeshExpression won't execute and fill the morph array unless you have a RenderMesh Bison in your code that executes at least once.
User avatar
Kjell
Posts: 1910
Joined: Sat Feb 23, 2008 11:15 pm

Post by Kjell »

Hi Ville,

Yea, normally you'd want to set the Array to persistent ( and delete the Bison Mesh ) .. I just disabled it to not "bloat" the file with duplicate data :wink:

Updated the file ~

K
Post Reply