Author Topic: jelly vector / dragon ball  (Read 6811 times)

0 Members and 1 Guest are viewing this topic.

Offline marlon

  • C= 64
  • **
  • Posts: 38
  • Karma: 15
    • View Profile
Re: jelly vector / dragon ball
« Reply #20 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?

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1289
  • Karma: 466
    • View Profile
    • my stuff
Re: jelly vector / dragon ball
« Reply #21 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 (the driver will take care of the optimizations) or check out vertex buffer objects.



Challenge Trophies Won:

Offline marlon

  • C= 64
  • **
  • Posts: 38
  • Karma: 15
    • View Profile
Re: jelly vector / dragon ball
« Reply #22 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..
« Last Edit: March 17, 2012 by marlon »

Offline marlon

  • C= 64
  • **
  • Posts: 38
  • Karma: 15
    • View Profile
Re: jelly vector / dragon ball
« Reply #23 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]



Offline copse

  • ZX 81
  • *
  • Posts: 9
  • Karma: 3
    • View Profile
Re: jelly vector / dragon ball
« Reply #24 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

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.

Offline S0lll0s

  • ZX 81
  • *
  • Posts: 6
  • Karma: 0
    • View Profile
Re: jelly vector / dragon ball
« Reply #25 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;
  }
}

Offline nuclear

  • Graphics hacker
  • C= 64
  • **
  • Posts: 28
  • Karma: 39
    • View Profile
    • Personal website
Re: jelly vector / dragon ball
« Reply #26 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.
Nuclear / Mindlapse & The Lab
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1289
  • Karma: 466
    • View Profile
    • my stuff
Re: jelly vector / dragon ball
« Reply #27 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 effect while the original question was about this one.
Challenge Trophies Won:

Offline nuclear

  • Graphics hacker
  • C= 64
  • **
  • Posts: 28
  • Karma: 39
    • View Profile
    • Personal website
Re: jelly vector / dragon ball
« Reply #28 on: April 24, 2013 »
yeap.
Nuclear / Mindlapse & The Lab
Challenge Trophies Won: