Dark Bit Factory & Gravity

PROGRAMMING => C / C++ /C# => Topic started by: marlon on February 22, 2012

Title: jelly vector / dragon ball
Post by: marlon on February 22, 2012
Hey there!  =)

Back in the good old Melon days I used to LOVE their "Jelly Cube" and "DragonBall" in the Human Target - Amiga demo..

Now that is said.. Can anyone explain to me how they are made?


- Marlon Bodhi
Title: Re: jelly vector / dragon ball
Post by: hellfire on February 22, 2012
Quote
"DragonBall"
The "ball" is just a filled circle which can be scaled along the y axis (by skipping scanlines of the original circle).
The stars are  3d vectors which match the size of the circle and get the same y-scaling in 2d space.
Backfacing polygons are drawn in a different color to make the ball appear transparent.

Quote
"Jelly Cube"
A cube which is subdivided along the y-axis.
The outer edges represent a sine with changing amplitude.
Title: Re: jelly vector / dragon ball
Post by: Raizor on February 23, 2012
It's a shame there's not a demo effects Wiki as things like this are really interesting. It would be great to have info on effects all under one roof somewhere.

K++ for the info Hellfire.
Title: Re: jelly vector / dragon ball
Post by: marlon on February 23, 2012
Thank you very much.

I actually thought it was done using a geosphere and some texture mapped stars..
Title: Re: jelly vector / dragon ball
Post by: hellfire on February 23, 2012
I actually thought it was done using a geosphere and some texture mapped stars..
That's how you'd do it today.
Back in the days a reasonably smooth sphere-mesh would have had way too many polys, though.
Title: Re: jelly vector / dragon ball
Post by: marlon on February 23, 2012
when you say subdividing that cube.. Do you mean that it is split up into a lot of cubes with the same width but a 1-pixel height!?
Title: Re: jelly vector / dragon ball
Post by: hellfire on February 23, 2012
Do you mean that it is split up into a lot of cubes with the same width but a 1-pixel height!?
One pixel isn't necessary, just a few segments along the y-axis are enough:
(http://www.abload.de/img/jellycubewq3s2.png)
Title: Re: jelly vector / dragon ball
Post by: marlon on February 26, 2012
Nice picture..   thanks alot!   =)

How do I actually rotate a (or a few) single vertex in a box consisting of many vertices..?


- Marlon Bodhi
Title: Re: jelly vector / dragon ball
Post by: hellfire on February 26, 2012
How do I actually rotate a (or a few) single vertex in a box consisting of many vertices..?
There's no rotation involved here.
Imagine your cube ranges from -0.5..+0.5 in X & Z and from 0.0..+1.0 in Y:
(http://www.abload.de/img/jelly_cube_scalec4joo.png)
The scaling along y describes a sine.

So you just have to scale each vertex' xz according to y:
Code: [Select]
float scale; // something between 0.5 and 1.5
for (int i=0;i<numVertices;i++)
{
  float xz= sin( cubeVertex[i].y * M_PI ) * (1.0-scale) + 1.0;
  squishedVertex[i].x = cubeVertex[i].x * xz;
  squishedVertex[i].y = cubeVertex[i].y * scale;
  squishedVertex[i].z = cubeVertex[i].z * xz;
}
Title: Re: jelly vector / dragon ball
Post by: marlon on February 28, 2012
Thanks again Hellfire!

I have now made that example.. And also used the same cube for twisting..
The jelly cube is fine with a solid color..  But with done with flatshading or smoothshading it really looks..  "Eeeeewww"   =(

Title: Re: jelly vector / dragon ball
Post by: hellfire on February 28, 2012
The jelly cube is fine with a solid color..  But with done with flatshading or smoothshading it really looks..  "Eeeeewww"   =(
Have you set up proper vertex-normals?
The normals change when you modify the vertex positions.
Don't use shared vertex normals across the different sides of the cube (shade each side separately).
Title: Re: jelly vector / dragon ball
Post by: marlon on February 28, 2012
I change the vertices and then i calculate a new normal for each vertex..

I have 4 vertices per segment and 9 segments..  Just like the picture you made..
So that is 36 vertices in all for that cube..

So some of the vertices are being used many times for several triangles..

I have used VertexArrays and NormalsArrays..
Title: Re: jelly vector / dragon ball
Post by: hellfire on February 28, 2012
Can you post an image or exe showing the problem?
Title: Re: jelly vector / dragon ball
Post by: marlon on February 29, 2012
one in wireframe and one in solid and one mixed..
Title: Re: jelly vector / dragon ball
Post by: hellfire on February 29, 2012
Uh, that looks really strange indeed.
According to the diagonal pattern your quads seem to be connected to different rows.
(which is probably not the case since the wireframe seems to be correct)
Where do you get the colors from?
If you don't mind sharing it, I could have a look at the source code.
Title: Re: jelly vector / dragon ball
Post by: marlon on March 02, 2012
all the vertices and vertexlist are done in hand..  Just drawing it on paper and then tried to put it in VC++

i am using an example from nehe to set up the windows and opengl.. because now i rather wanted to learn some opengl than using to much power on struggling with the other things..


http://www.marlonbodhi.com/humm.avi
Title: Re: jelly vector / dragon ball
Post by: Raizor on March 03, 2012
Just out of curiosity Hellfire, what did you use to put those diagrams together? They look pretty neat.
Title: Re: jelly vector / dragon ball
Post by: marlon on March 03, 2012
yes..  those diagrams look very pro!   

http://www.marlonbodhi.com/lol.avi
Title: Re: jelly vector / dragon ball
Post by: hellfire on March 05, 2012
Just out of curiosity Hellfire, what did you use to put those diagrams together? They look pretty neat.
The first (http://www.dbfinteractive.com/forum/index.php?topic=5612.msg74793#msg74793) picture was a quick mock-up with 3dsmax.
The second (http://www.dbfinteractive.com/forum/index.php?topic=5612.msg74857#msg74857) was made with Cool Math's Graph (http://www.coolmath.com/graphit) (don't laugh: it's a math website for kids!) and some photoshop.
Title: Re: jelly vector / dragon ball
Post by: Raizor on March 05, 2012
Hehe, very resourceful - thanks :)
Title: Re: jelly vector / dragon ball
Post by: marlon on March 17, 2012
I am trying to make that jelly ball now using a icosahedron from that Red Book..
But I need more face that the initial 20.. So I subdivide a few times to get a better facecount..
But how do I gather all these new vertices and faces in a Triangle-Strip?
Title: Re: jelly vector / dragon ball
Post by: hellfire on March 17, 2012
I wouldn't put much thought into creating strips.
Just draw the triangles with 3 individual vertices.
If that's too slow create a display list (http://www.songho.ca/opengl/gl_displaylist.html) (the driver will take care of the optimizations) or check out vertex buffer objects (http://www.songho.ca/opengl/gl_vbo.html).



Title: Re: jelly vector / dragon ball
Post by: marlon on March 17, 2012
the red book uses a 2dimensional array..  when i change to a 1dimensional the data is all messed up..
weird.. 


GLuint  * IcoPoly;
GLfloat * IcoVert;
GLfloat * IcoNorm;

GLuint tindices[] = { 0,4,1, 0,9,4, 9,5,4, 4,5,8, 4,8,1,
8,10,1, 8,3,10, 5,3,8, 5,2,3, 2,7,3,
7,10,3, 7,6,10, 7,11,6, 11,0,6, 0,1,6,
6,1,10, 9,0,11, 9,11,2, 9,2,5, 7,2,11 };

..

void InitIcosaHedron() {

   #define X .525731112119133606
   #define Z .850650808352039932

   IcoPoly = new GLuint[20*3];
   IcoVert = new GLfloat[12*3];
   IcoNorm = new GLfloat[12*3];
 

   IcoNorm[ 0] = (GLfloat) -X;      IcoNorm[ 1] = (GLfloat) 0.0;      IcoNorm[ 2] = (GLfloat)  Z;
   IcoNorm[ 3] = (GLfloat)  X;      IcoNorm[ 4] = (GLfloat) 0.0;      IcoNorm[ 5] = (GLfloat)  Z;
   IcoNorm[ 6] = (GLfloat) -X;      IcoNorm[ 7] = (GLfloat) 0.0;      IcoNorm[ 8] = (GLfloat) -Z;
   IcoNorm[ 9] = (GLfloat)  X;      IcoNorm[10] = (GLfloat) 0.0;      IcoNorm[11] = (GLfloat) -Z;

   IcoNorm[12] = (GLfloat) 0.0;      IcoNorm[13] = (GLfloat)  Z;      IcoNorm[14] = (GLfloat)  X;
   IcoNorm[15] = (GLfloat) 0.0;      IcoNorm[16] = (GLfloat)  Z;      IcoNorm[17] = (GLfloat) -X;
   IcoNorm[18] = (GLfloat) 0.0;      IcoNorm[19] = (GLfloat) -Z;      IcoNorm[20] = (GLfloat)  X;
   IcoNorm[21] = (GLfloat) 0.0;      IcoNorm[22] = (GLfloat) -Z;      IcoNorm[23] = (GLfloat) -X;

   IcoNorm[24] = (GLfloat)  Z;      IcoNorm[25] = (GLfloat)  X;      IcoNorm[26] = (GLfloat) 0.0;
   IcoNorm[27] = (GLfloat) -Z;      IcoNorm[28] = (GLfloat)  X;      IcoNorm[29] = (GLfloat) 0.0;
   IcoNorm[30] = (GLfloat)  Z;      IcoNorm[31] = (GLfloat) -X;      IcoNorm[32] = (GLfloat)  0.0;
   IcoNorm[33] = (GLfloat) -Z;      IcoNorm[34] = (GLfloat) -X;      IcoNorm[35] = (GLfloat)  0.0;

       int i;

for (i = 0; i < 12; i++) {

   IcoVert[i*3+0] = IcoNorm[i*3+0];
   IcoVert[i*3+1] = IcoNorm[i*3+1];
   IcoVert[i*3+2] = IcoNorm[i*3+2];

}

float scale = 20.0f;



for (i = 0; i < 12; i++) {
   IcoVert[i*3+0] *= scale;
   IcoVert[i*3+1] *= scale;
   IcoVert[i*3+2] *= scale;

}


}

void DrawIcosaHedron(int smooth) {

int i;

GLfloat v1[3];

glBegin(GL_TRIANGLES);
for (i = 0; i < 20; i++) {

   v1[0] = ( IcoNorm[tindices[i*3+0]+0] + IcoNorm[tindices[i*3+1]+0] + IcoNorm[tindices[i*3+2]+0] ) / 3.0f;
   v1[1] = ( IcoNorm[tindices[i*3+0]+1] + IcoNorm[tindices[i*3+1]+1] + IcoNorm[tindices[i*3+2]+1] ) / 3.0f;
   v1[2] = ( IcoNorm[tindices[i*3+0]+2] + IcoNorm[tindices[i*3+1]+2] + IcoNorm[tindices[i*3+2]+2] ) / 3.0f;
   ReduceToUnit(v1);


glNormal3f(v1[0], v1[1], v1[2]);
if(smooth)
glNormal3f( IcoNorm[tindices[i*3+0]+0], IcoNorm[tindices[i*3+0]+1], IcoNorm[tindices[i*3+0]+2] );
glVertex3f( IcoVert[tindices[i*3+0]+0], IcoVert[tindices[i*3+0]+1], IcoVert[tindices[i*3+0]+2] );
if(smooth)
glNormal3f( IcoNorm[tindices[i*3+1]+0], IcoNorm[tindices[i*3+1]+1], IcoNorm[tindices[i*3+1]+2] );
glVertex3f( IcoVert[tindices[i*3+1]+0], IcoVert[tindices[i*3+1]+1], IcoVert[tindices[i*3+1]+2] );
if(smooth)
glNormal3f( IcoNorm[tindices[i*3+2]+0], IcoNorm[tindices[i*3+2]+1], IcoNorm[tindices[i*3+2]+2] );
glVertex3f( IcoVert[tindices[i*3+2]+0], IcoVert[tindices[i*3+2]+1], IcoVert[tindices[i*3+2]+2] );
}
glEnd();


}



The vertices looks like they are placed right but the rest is garbage..
Title: Re: jelly vector / dragon ball
Post by: marlon on March 18, 2012
i found my error..

the arrays for the vertices and the triangles are setup like Vertices*3 (for x,y,x) and Triangle*3 (for v1, v2,v3)

So i made like this :   IcoVert[tindices[i*3+2]+0]

should have been:    IcoVert[tindices[i*3+2]*3+0]


Title: Re: jelly vector / dragon ball
Post by: copse on May 05, 2012
I was trawling through an old directory full of Amiga source code someone sent me through the post over a decade ago, and found one called jellycube.s.  For some reason I went through and commented it and fixed a few bugs while watching television.  It was resourced from some production, I have no idea what - any code unrelated to this effect was already stripped.

Here's a youtube video of the effect:
http://youtu.be/DDmLIdbQqVw (http://youtu.be/DDmLIdbQqVw)

The commented source code is attached for what its worth.  I didn't bother spending too much time on the Amiga blitter code, but I think that there isn't much to learn from this.  All transformations are done from custom tables.  The "cube" looks to be a sham and is perhaps the three sides that face the camera given it's angle of rotation.  The y stretch is quite straightforward, and the x squish seems to be done in two ways - one a distortion of the 3D vertices, another some distortion of the screen projected 2D line/fill vertices.
Title: Re: jelly vector / dragon ball
Post by: S0lll0s on April 11, 2013
Processing (Java) jellycube:

Code: [Select]
int count = 0;
int speed = 1;
int distance = 0;
boolean strok = true;
boolean freerot = false;

void setup() {
  size( 500, 500, P3D );
}

void draw() {
  background( 120 );
  translate( width / 2, height / 2 + 100, distance );

  count += speed;

  if ( !freerot )
    rotate( sin( count / 341.0 ), 0.2, 1.0, 0 );
  else {
    rotate( ( mouseX - width / 2 ) / float( width ) * 2, 0.0, 1.0, 0.0 );
    rotate( ( mouseY - height / 2 ) / 1000.0, -0.3, 0.0, 0.0 );
  }

  if ( strok )
    strokeWeight( 1 );
  else
    noStroke();
 
  scale( 10, 10, 10 );
  scale( 1, -1 + sin( count / 100.0 * PI ) * 0.2, 1 );
 
  lights();
 
  fill( 80, 80, 80, 130 );
  box( 400, 2, 400 );
 
  fill( 255 );
  for ( int y = 0; y < 9; y++ ) {
    float xz  = sin ( ( y ) * PI / 9.0     ) * sin( count / 100.0 * PI ) * 0.2 + 1.0;
    float xzz = sin ( ( y + 1 ) * PI / 9.0 ) * sin( count / 100.0 * PI ) * 0.2 + 1.0;
    if ( xz == 0 )
      xz = 0.01;
    if ( xzz == 0 )
      xzz = 0.01;
 
    translate( 0, 2, 0 );
 
    //back wall
    beginShape();
    vertex( -10 * xz, -1, -10 * xz );
    vertex( -10 * xzz, 1, -10 * xzz );
    vertex(  10 * xzz, 1, -10 * xzz );
    vertex(  10 * xz, -1, -10 * xz );
    endShape();
 
    //front wall
    beginShape();
    vertex( -10 * xz, -1, 10 * xz );
    vertex( -10 * xzz, 1, 10 * xzz );
    vertex(  10 * xzz, 1, 10 * xzz );
    vertex(  10 * xz, -1, 10 * xz );
    endShape();
 
    //left wall
    beginShape();
    vertex( -10 * xz, -1, -10 * xz );
    vertex( -10 * xzz, 1, -10 * xzz );
    vertex( -10 * xzz, 1, 10 * xzz );
    vertex( -10 * xz, -1, 10 * xz );
    endShape();
 
    //right wall
    beginShape();
    vertex(  10 * xz, -1, -10 * xz );
    vertex(  10 * xzz, 1, -10 * xzz );
    vertex(  10 * xzz, 1, 10 * xzz );
    vertex(  10 * xz, -1, 10 * xz );
    endShape();
  }
 
  //top
  beginShape();
  vertex( -10, 1, -10 );
  vertex( -10, 1, 10 );
  vertex(  10, 1, 10 );
  vertex(  10, 1, -10 );
  endShape();
 
  fill( 80, 80, 80, 130 );
  translate( 0, 2, 0 );
  box( 400, 2, 400 );
 
  count += speed;
}

void keyPressed() {
  if ( key == ' ' )
    freerot = !freerot;
  else if ( key == 's' || key == 'S' )
    strok = !strok;
  else if ( key == CODED ) {
    if ( keyCode == LEFT )
      speed++;
    else if ( keyCode == RIGHT )
      speed--;
    else if ( keyCode == UP )
      distance += 20;
    else if ( keyCode == DOWN )
      distance -= 20;
  }
}
Title: Re: jelly vector / dragon ball
Post by: nuclear on April 22, 2013
The classic jellycube effect absolutely DOES NOT work by subdividing the cube into many polygons. That would be too computationally expensive for the era we're talking about.

What you do, is a simple rotation of a regular six-polygon cube, but you keep a few frames of the area covered by the cube in a crcular buffer. Or even you precalculate the whole rotation animation and keep the frames. Then when it's time to render, instead of blitting all the scanlines from a single frame, you pick a different frame for each scanline, which means that each scanline has a delta-time offset from the previous one.

If you only rotate the cube around the Y axis instead of full 3D rotation, you only need to keep a single scanline from each frame anyway, as they are all the same.

The whole effect it's essentially extremely similar to the traditional swirly column effect if you know the one I mean.
Title: Re: jelly vector / dragon ball
Post by: hellfire on April 24, 2013
you precalculate the whole rotation animation and keep the frames.
Then when it's time to render, instead of blitting all the scanlines from a single frame, you pick a different frame for each scanline
You're probably thinking about this (http://www.youtube.com/watch?v=zWuW3EEjzQk&t=0m10s) effect while the original question was about this (http://www.youtube.com/watch?v=m1iGAjMjg3I&t=0m35s) one.
Title: Re: jelly vector / dragon ball
Post by: nuclear on April 24, 2013
yeap.