Welcome! » Log In » Create A New Profile

metaball based scenes

Posted by carmatic 
metaball based scenes
November 23, 2010 06:39AM
so i want to explore the possibility of using the metaball to create new scenes, like there is a way to make tunnels out of metaballs or something?

anyway, here's my attempt to give a bass-enhanced biology scene... not directly related to using metaballs, because all i tried to do was use its alternate bass-responsive movement, as well as alter the size of the medusa tails to the sound

#include "mathutils.pur3h"
#include "Metaball.pur3h"
//#include "FeedbackBackground.pur3h"
#include "RandomRenderSolid.pur3h"
#include "Medusa.pur3h"
#include "Background.pur3h"
#include "JumpCamera.pur3h"
#include "AnimatedPoint.pur3h"
#include "Particles.pur3h"

CVolume vol;
float pos;
CBackground background;
CRandomRenderSolid solidRender;
CParticles pRender;
CJumpCamera camera;

const int METABALLS = 8;
const int MESH = 24;
const int MESH_HALF = MESH/2;

const int TRAILS = 64;
const int TRAIL_LENGTH = 15;


float[METABALLS] mbSpeed;
float[METABALLS] mbSize;
float[METABALLS] mbSound;
CAnimatedPoint[METABALLS] mbPos;
Vector3[METABALLS] mbVector;

Vector3[TRAILS] trails;
CMedusa medusa;

int particleTex;
int shader;

export void init() {
  background.create();

    particleTex = texLoad(/*"xml://Particle"*/"biotrail.png");//"particle_simple.png");
    shader = shaderLoad("vSimple.glsl", "fTexColor.glsl");


    pos = 0;
    vol.create(MESH,MESH,MESH);

    int i,j;
    for (i=0;i<METABALLS;i++) {
        mbSpeed[i] = rand()+0.5;
        mbSize[i] = (rand()+0.5)*5000;
        mbSound[i] = (rand()+0.3)*2;
        mbPos[i].create();
    }



    solidRender.create();
    pRender.create();
    medusa.create(TRAILS, TRAIL_LENGTH, 0.4/*spacing*/, 0.5);
    for (i=0;i<medusa.tailElements;i++)
        medusa.sizes[i] = 30.0 / (i+40);
     for (i=0;i<medusa.tails;i++) {
        trails[i] = Vector3( 3 + rand()*(MESH-8), 3 + rand()*(MESH-8), 3 + rand()*(MESH-8));
        Vector3 *tailPos = medusa.getTail(i);
        for (j=0;j<medusa.tailElements;j++)
            tailPos[j] = trails[i];
     }



    camera.create(Vector3(-MESH,-MESH,MESH*3/2), Vector3(MESH*2, MESH*2, MESH*2),
                  Vector3(MESH/4,MESH/4,MESH/4), Vector3(MESH*3/4, MESH*3/4, MESH*3/4),
                  Vector3(0,1,0));
}

export void kill() {
    solidRender.destroy();
    vol.destroy();
    background.destroy();
    pRender.destroy();
    int i;
    for (i=0;i<METABALLS;i++)
        mbPos[i].destroy();
    medusa.destroy();

    texDestroy(particleTex);
    shaderDestroy(shader);
    camera.destroy();
}

export void step() {
  float timePass = visGetFloat(VIS_TIME_DIFF);
  float sound = visGetFloat(VIS_SOUND_BASS);

  pos += timePass ;
  vol.clear(-1000);
  int i,j;
  for (i=0;i<METABALLS;i++) {
      mbPos[i].step(timePass * (mbSpeed[i] + sound * mbSound[i]));

      mbVector[i] = vAdd(Vector3(MESH_HALF,MESH_HALF,MESH_HALF),vMul(mbPos[i].pos, 7));
      vol.ball(mbVector[i], mbSize[i], 2);
  }

  // move particles!
  
  for (i=0;i<medusa.tails;i++) {
        
      Vector3 tpos = trails[i];
      float a = vol.getValueAt(tpos);
      Vector3 norm = vNorm(vol.getGradientAt(tpos));
      Vector3 gradient = vMul(norm, -clip(a*0.2, -20, 20));


      Vector3 attrac = Vector3(0,0,0);
      for (j=0;j<medusa.tails;j++)
          if (i!=j) {
              Vector3 diff = vSub(tpos, trails[j]);
              float r = vMag(diff);
              attrac = vAdd(attrac, vMul(vNorm(diff), 16/(r*r) - r*0.004));
          }


      trails[i] = vAdd(tpos, vMul(vAdd(gradient, attrac), timePass));


      Vector3 *mTail = medusa.getTail(i);
      mTail[0] = trails[i];
      mTail[1] = vSub(trails[i], vMul(norm, medusa.tailSpacing));
	  
  }
  medusa.step((Matrix*)NULL, timePass);

  camera.step();
  background.step();
}

export void render() {
int counter,counttothree;
  counter = counter + 1 ;
  if (counter == medusa.tails+1){
	counter = 1;
	}
    vol.calculate();

    setPerspective(90, visGetFloat(VIS_ASPECT), 0.1, 75);
    setMatrix(MAT_MODEL, &camera.matrix);

    if (background.maskStart()) {
      vol.render();
      background.maskEnd();
    }

    // background
    background.mainStart();
    solidRender.renderStart(background.getBackgroundTexture());
    // draw a black inner
    glSetInt(GL_COLOR, 0xFF000000);
    vol.buffer.explode(-2);
    vol.render();
    // now draw 2 shells
    glSetInt(GL_DEPTH_MASK, 0); // don't write to depth buffer
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    glSetInt(GL_COLOR, 0x3FFFFFFF);
    vol.buffer.explode(1);
    vol.render();
    vol.buffer.explode(1);
    vol.render();

    glSetInt(GL_DEPTH_MASK, 1);
    solidRender.renderEnd();

    float size = getSizeMultiplier();
    float red [256];
	float green [256];
	float blue [256];
    pRender.start(medusa.tails*medusa.tailElements);
    for (int i=0;i<medusa.tails;i++) {
		
	    
		if (i==counter){
		
	    red[i] = visGetFloat(VIS_SOUND_BASS);
		green[i] = visGetFloat(VIS_SOUND_MID);
		blue[i] = visGetFloat(VIS_SOUND_TREBLE);
		}
        Vector3 *p = medusa.getTail(i);
		
        
		pRender.addTrail(p, medusa.tailElements, 0.2*red[i]);
		
		
    }
    pRender.end();

    glSetInt(GL_COLOR, 0xFFFFFFFF);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    glSetInt(GL_DEPTH_MASK, 0);
    texBind(0, particleTex);
    shaderBind(shader);
    pRender.render();
    glSetInt(GL_DEPTH_MASK, 1);
    background.mainEnd();

}
here is the modified movement, under void.step
for (i=0;i<METABALLS;i++) {
      mbPos[i].step(timePass * (mbSpeed[i] + sound * mbSound[i]));

      mbVector[i] = vAdd(Vector3(MESH_HALF,MESH_HALF,MESH_HALF),vMul(mbPos[i].pos, 7));
      vol.ball(mbVector[i], mbSize[i], 2);
  }
the problem with this scene is the tails...
under void.render
int counter,counttothree;
  counter = counter + 1 ;
  if (counter == medusa.tails+1){
	counter = 1;
	}
this is the 'frame counter'
float red [256];
	float green [256];
	float blue [256];
the reason for the red , green and blue was because i was originally hoping to change the colour of the tails independently, but it seems that is not possible
and this is what i have changed the for loop to
for (int i=0;i<medusa.tails;i++) {
		
	    
		if (i==counter){
		
	    red[i] = visGetFloat(VIS_SOUND_BASS) ;
		green[i] = visGetFloat(VIS_SOUND_MID);
		blue[i] = visGetFloat(VIS_SOUND_TREBLE);
		}
        Vector3 *p = medusa.getTail(i);
		
        
		pRender.addTrail(p, medusa.tailElements, 0.2*red[i]);
		
		
    }
as you can see, i have only used the red colour corresponding to the bass
the result is that the tails have varied sizes, but one of them seems to have an extremely large size, and this appears to be an obvious glitch... i dont seem to get along well with using indexes in Morphyre...
Re: metaball based scenes
December 13, 2010 09:50AM
I think it's probably because you reset 'counter' to 1 and not 0?

Also if you want colour, you can change CParticles to CColourParticles (you need to change the #include of Particles to ColourParticles too). Then, addTrail changes from:

addTrail(Vector3 *pos, int count, float size)

to

addTrail(Vector3 *pos, int count, float size, Colour4 col)

so all you need to do is use:

pRender.addTrail(p, medusa.tailElements, 0.2*red[i], Colour4(red[i],green[i],blue[i],1));

hope that helps smiling smiley
Re: metaball based scenes
December 13, 2010 12:55PM
ERROR:No matching function found for (&*Vector3,&I,F,Colour4), only the following:
V CParticles::addTrail(*Vector3,I,F)
(/tmp/PUR3CcSi5ES:192:1) (/tmp/PUR3CcSi5ES:192:1)



Edited 1 time(s). Last edit at 12/13/2010 12:56PM by carmatic.
Re: metaball based scenes
December 16, 2010 12:32PM
Chances are you didn't change

CParticles pRender;

to

CColourParticles pRender;

like I said? It shouldn't be mentioning CParticles if it's not mentioned in the code.
Re: metaball based scenes
December 17, 2010 05:31PM
ok i got it, for real this time
#include "mathutils.pur3h"
#include "Metaball.pur3h"
//#include "FeedbackBackground.pur3h"
#include "RandomRenderSolid.pur3h"
#include "Medusa.pur3h"
#include "Background.pur3h"
#include "JumpCamera.pur3h"
#include "AnimatedPoint.pur3h"
#include "ColourParticles.pur3h"

CVolume vol;
float pos;
CBackground background;
CRandomRenderSolid solidRender;
CColourParticles pRender;
CJumpCamera camera;

const int METABALLS = 8;
const int MESH = 24;
const int MESH_HALF = MESH/2;

const int TRAILS = 64;
const int TRAIL_LENGTH = 15;


float[METABALLS] mbSpeed;
float[METABALLS] mbSize;
float[METABALLS] mbSound;
CAnimatedPoint[METABALLS] mbPos;
Vector3[METABALLS] mbVector;

Vector3[TRAILS] trails;
CMedusa medusa;

int particleTex;
int shader;
int counter;
float red [255];
float green [255];
float blue [255];
float size;

export void init() {
  background.create();

    particleTex = texLoad(/*"xml://Particle"*/"biotrail.png");//"particle_simple.png");
    shader = shaderLoad("vSimple.glsl", "fTexColor.glsl");


    pos = 0;
    vol.create(MESH,MESH,MESH);

    int i,j;
    for (i=0;i<METABALLS;i++) {
        mbSpeed[i] = rand()+0.5;
        mbSize[i] = (rand()+0.5)*5000;
        mbSound[i] = (rand()+0.3)*2;
        mbPos[i].create();
    }



    solidRender.create();
    pRender.create();
    medusa.create(TRAILS, TRAIL_LENGTH, 0.4/*spacing*/, 0.5);
    for (i=0;i<medusa.tailElements;i++)
        medusa.sizes[i] = 30.0 / (i+40);
     for (i=0;i<medusa.tails;i++) {
        trails[i] = Vector3( 3 + rand()*(MESH-8), 3 + rand()*(MESH-8), 3 + rand()*(MESH-8));
        Vector3 *tailPos = medusa.getTail(i);
        for (j=0;j<medusa.tailElements;j++)
            tailPos[j] = trails[i];
     }



    camera.create(Vector3(-MESH,-MESH,MESH*3/2), Vector3(MESH*2, MESH*2, MESH*2),
                  Vector3(MESH/4,MESH/4,MESH/4), Vector3(MESH*3/4, MESH*3/4, MESH*3/4),
                  Vector3(0,1,0));
}

export void kill() {
    solidRender.destroy();
    vol.destroy();
    background.destroy();
    pRender.destroy();
    int i;
    for (i=0;i<METABALLS;i++)
        mbPos[i].destroy();
    medusa.destroy();

    texDestroy(particleTex);
    shaderDestroy(shader);
    camera.destroy();
}

export void step() {
  float timePass = visGetFloat(VIS_TIME_DIFF);
  float sound = visGetFloat(VIS_SOUND_BASS);

  pos += timePass ;
  vol.clear(-1000);
  int i,j;
  for (i=0;i<METABALLS;i++) {
      mbPos[i].step(timePass * (mbSpeed[i] + sound * mbSound[i]));

      mbVector[i] = vAdd(Vector3(MESH_HALF,MESH_HALF,MESH_HALF),vMul(mbPos[i].pos, 7));
      vol.ball(mbVector[i], mbSize[i], 2);
  }

  // move particles!
  
  for (i=0;i<medusa.tails;i++) {
        
      Vector3 tpos = trails[i];
      float a = vol.getValueAt(tpos);
      Vector3 norm = vNorm(vol.getGradientAt(tpos));
      Vector3 gradient = vMul(norm, -clip(a*0.2, -20, 20));


      Vector3 attrac = Vector3(0,0,0);
      for (j=0;j<medusa.tails;j++)
          if (i!=j) {
              Vector3 diff = vSub(tpos, trails[j]);
              float r = vMag(diff);
              attrac = vAdd(attrac, vMul(vNorm(diff), 16/(r*r) - r*0.004));
          }


      trails[i] = vAdd(tpos, vMul(vAdd(gradient, attrac), timePass));


      Vector3 *mTail = medusa.getTail(i);
      mTail[0] = trails[i];
      mTail[1] = vSub(trails[i], vMul(norm, medusa.tailSpacing));
	  
  }
  medusa.step((Matrix*)NULL, timePass);

  camera.step();
  background.step();
}

export void render() {

  counter = counter + 1 ;
  if (counter == medusa.tails){
	counter = 0;
	}
    vol.calculate();

    setPerspective(90, visGetFloat(VIS_ASPECT), 0.1, 75);
    setMatrix(MAT_MODEL, &camera.matrix);

    if (background.maskStart()) {
      vol.render();
      background.maskEnd();
    }

    // background
    background.mainStart();
    solidRender.renderStart(background.getBackgroundTexture());
    // draw a black inner
    glSetInt(GL_COLOR, 0xFF000000);
    vol.buffer.explode(-2);
    vol.render();
    // now draw 2 shells
    glSetInt(GL_DEPTH_MASK, 0); // don't write to depth buffer
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    glSetInt(GL_COLOR, 0x3FFFFFFF);
    vol.buffer.explode(1);
    vol.render();
    vol.buffer.explode(1);
    vol.render();

    glSetInt(GL_DEPTH_MASK, 1);
    solidRender.renderEnd();

    size = getSizeMultiplier();
    
    pRender.start(medusa.tails*medusa.tailElements);
	    for (int i=0;i<medusa.tails;i++) {
		
	    
		if (counter==i){
		
	    red[i] = visGetFloat(VIS_SOUND_BASS);
		green[i] = visGetFloat(VIS_SOUND_MID);
		blue[i] = visGetFloat(VIS_SOUND_TREBLE);
		}
        Vector3 *p = medusa.getTail(i);
		
        
		pRender.addTrail(p, medusa.tailElements, 0.2*size, Colour4(red[i],green[i],blue[i],1));
		
		
    }
    pRender.end();

    glSetInt(GL_COLOR, 0xFFFFFFFF);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    glSetInt(GL_DEPTH_MASK, 0);
    texBind(0, particleTex);
    shaderBind(shader);
    pRender.render();
    glSetInt(GL_DEPTH_MASK, 1);
    background.mainEnd();

}



Edited 2 time(s). Last edit at 12/27/2010 08:23PM by carmatic.
Re: metaball based scenes
December 27, 2010 07:33PM
i think that there is a problem with how morphyre handles arrays ... like, in this example, if the array size is 64, the tails are multicoloured, one of the tails will flash red and transparent , and it looks like some other tails will flash between 2 colours... if the array size is 256, the tails are all red, with one flashing red and transparent as well...
i was expecting it to update the colour of one tail for every frame rendered, but instead the tails stay the same colour from the first frame they were rendered

::edit:: void render is not a good place to declare variables... moving the float declarations for red, green , blue, and size to before init solved the tail colour not changing problem... i've updated the previous post
the sound response is great, especially during the transitions from quiet to loud as the tails all light up at the same time, and with higher frame rates the colours respond faster too



Edited 2 time(s). Last edit at 12/27/2010 08:27PM by carmatic.
Re: metaball based scenes
December 29, 2010 05:30AM
so anyway, i remember you telling me that there's a way to combine metaballs with tunnels

how do i do that again?
Re: metaball based scenes
January 10, 2011 12:04PM
Yep, if you define variables in a function they're only guaranteed to be held around during that function - next time you enter it they'll probably be filled with different values. It's the same behavior as in most programming languages.

Not quite sure what you mean about combining them with tunnels?

If you copy metaball.pur3c and change:
balls[i].vector = Vector3( 12 + sin(balls[i].pos)*6, 12 + cos(balls[i].pos)*7, 12 );
to:
balls[i].vector = Vector3( 12 + sin(balls[i].pos)*6, 12 + cos(balls[i].pos)*7, i*MESH/METABALLS );

and maybe increase the size by changing the 'balls[i].size = ' line you should end up with a long wobbly blob thing (you might want to change *6 and *7 in the line above to smaller values). You can then change the values that go into camera.create to position the camera inside it...
Re: metaball based scenes
January 15, 2011 05:43AM
texture question

so i have added another object to the scene, which i then set to render within renderstart so that it takes on the foreground texture

what if i want the metaballs to reflect both this object and the background?
Re: metaball based scenes
January 16, 2011 12:08PM
Your best bet is to render an environment texture separately (by rendering the background *and* the other object onto that as well as to the screen).

So:
texRenderBegin(-2,-2); // (half screen res)
background.skybox->render(); // I think - this will only work with skybox scenes though
// render first object
tex = texRenderEnd();

...
texBind(0, tex);
Render metaballs
texRenderFinished(tex);

It'll never be perfect though as you don't really get that without raytracing.
Re: metaball based scenes
January 17, 2011 01:57PM
also, i have changed the balls[i].vector equation to what you have said, but it doesnt form a line

it would have been ideal if the rendered object and background was simply put on-screen, and if the metaball simply reflected what was on the screen 'behind' it

here is the scene i am trying to work on

http://carmatic.info/metaballenki.7z

on the skybox-based scenes, the 'enkidushape' object as well as the skybox are completely black... this looks like the problem Morphyre had with the videos back a few months ago



Edited 4 time(s). Last edit at 01/17/2011 07:01PM by carmatic.
Sorry, only registered users may post in this forum.

Click here to login