Dark Bit Factory & Gravity

PROGRAMMING => General coding questions => Topic started by: Clyde on September 10, 2008

Title: 3D Twister - Sinus Methods
Post by: Clyde on September 10, 2008
Hiya,

Im posting this here, as this I imagine would apply to many different languages and librarys, like C/C+/C++ Ogl and DX, etc, etc.

Ive dug out B3D and been inspired by a few productions that feature twisting effects in. I notice that these are done in 2D. And I would really love to know and very much appreciate is, people ideas and approaches to making a 3D model twist by using Sin And Cos ( or any other math commands like atan, sqr etc ) on the vertecies of the object. The object that I have choosen to try this with, is a segmented cube as it has lots of verticies to play around with rather that just a scaled cube to be a rectangle.

All that I have managed thus far, is to make the object as a standard wave; with nothing to make it change its appearance / motion. Also maybe, I should rotate the verticies independantly in a routine.

Here is some pseudo code, that I'd like people to use to show me how to go about twisting it. It doesnt matter how elaborate it is, zany, its all good. I'd like it to actually twist about, and not a bog standard wave like in a 2D sinus scroller.

Anyhows here's the Psuedo code for use to update the vertex positons.


For a=0 To TotalVerts-1
   
   VertX= OriginalVertX( a )
   VertY= OriginalVertY( a )
   VertZ= OriginalVertZ( a )

   VertX+= Some_Kind_Of_Sin_Cos
   VertY+= Some_Sin_Cos
   VertZ+= More_Sin_Cos_Or_Even_Atan_Sqr
   
   Update_Model()
   Update_Normals()

Next


Also, B3D uses Degrees and not Radians, but it doesnt really matter too much.
And maybe I need stuff that goes outside of the loop too.

Many many thanks for your efforts and answering my post, the more methods the better. As I can learn alot from them.

Really very much appreciated and cheers,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 10, 2008
Hehe, when I read "twister" I thought you're talking about such a thing  :D


let's say your segmented cube is alligned along the y-axis, you just take a rotation-matrix (around the y-axis) and use "y" (plus some offset for animation) as rotation-angle:

   c = cos(angle);
   s = sin(angle);

   x'= c*x +  s*z
   y'= y
   z'= -s*x +  c*z

Now just make some interessting variations on "angle".
But there's no need to limit on the "twisting"-part; you can also alter the scaling or the center for each "slice".
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 11, 2008
Thanks Hellfire dude,

I thought that my psuedo code would have been able to twist, obviously not the case.

Im a little fuzzy wuzzy on wether or not the object is alligned on its Y-Axis. Is there something that can be done to do this, after the model is created?

Also a bit confused, to what is meant by "taking a rotation-matrix (around the y-axis)"
In Blitz3D, I wouldnt know how to do this. Could you please explain further please dude?

Cheers and huge thanks,
Cyde.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 11, 2008
Well, the main duty of a "rotation matrix around the y-axis" is to rotate a vector around the y-axis ;)
Basically it leaves the y-coordinate where it is and moves x,z a certain amount on a circle (which centered at the origin).
Such a matrix looks like this ("a" being an angle defining how far you want to rotate):
cos(a)  0  sin(a)
   0     1    0
-sin(a)  0  cos(a)

If you now use your y-coordinate as "a", your objects twists along it's height.
My little example-code above just multiplies a vertex with such a matrix.

Quotewether or not the object is alligned on its Y-Axis.
Is there something that can be done to do this, after the model is created?
What software did you use to create the object?
First of all you have to check whether the "length" of your mesh goes along the y-axis.
You can use any other axis, but you also have to use the corresponding rotation-matrix.
to get your vertices centered around the y-axis, you just look for the minimum/maximum x,z and move your vertices so that minimum+maximum=0.

Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 11, 2008
I guess my psuedo code isnt of much use, and is wrong. And im a bit stuck on what the loop for twisting should look like.

This is something, I really want to get to work. As im really inspired by other peoples efforts at doing this. And I wonder if other people have any ideas too.

I created the object in a language called Blitz3D, and i've checked that it's central; which it is.

Could you give me some code please dude, including how to check wether the length of the mesh goes along the y-axis, and using it's rotation matrix ( btw it's not a software 2d routine to do 3D, the language im using takes care of the rotation ), also need help with getting the verticies centered around the y-axis w/ looking for the min/max x & z.

If I use the following in the loop I get a sin wave like effect, and not much of a twist.


;D2R float = pi/180 ;for converting to degrees.

       VertexX+= Cos( (Angle1+VertexY)*D2R)
     
        VertexY+= (Sin( (Angle1+VertexX)*D2R)*24)+_
                  (Sin( (Angle3+VertexX)*D2R)*32)+_
                  (Sin( (Angle2+VertexX)*D2R)*16)

        VertexZ+= Cos( (Angle3+VertexY)*D2R)*32


Cheers and hugest of thanks,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 11, 2008
I made a little example.
Since I don't know how your object is organized, I created it on-the-fly.
It's basically a a cuboid (without top and bottom face) with a base ranging from -1..+1 and an arbitrary number of segments along the height (y-axis).

First of all we set up the view:
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(45.0, 4.0/3.0, 0.1, 100.0);
   gluLookAt(1,15,2, 0,20,0, 0,1,0);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();


Then we turn on a lightsource so we can see something:
   glEnable(GL_LIGHTING);
   GLfloat specular[]= { 1.0f, 1.0f, 1.0f, 1.0f };
   GLfloat ambient[]=  { 0.0f, 0.0f, 0.3f, 1.0f };
   GLfloat diffuse[]=  { 1.0f, 0.9f, 0.9f, 1.0f };
   GLfloat position[]= { 1.5f, 25.0f,30.0f, 1.0f };

   glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
   glLightfv(GL_LIGHT0, GL_POSITION, position);
   glEnable(GL_LIGHT0);

   glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 80.0f);
   glShadeModel(GL_SMOOTH);
   glColor4f(1,1,1,1);


Now we create the vertices of our mesh:

      // number of segments along the height
      const int seg= 512;
      // vertex buffer: 4 vertices per height-segment
      Vector vtx[seg][4]; // vector is just a structure holding x,y,z (float)

      for (int i=0;i<seg;i++)
      {
         // height normalized to 0..1
         float y= (float)i/seg;

         // rotation angle dependant on vertex' height
         // here you can do whatever you find fitting
         // "time" is a float holding the time passed in seconds
         float angle= sin(y*12.0 - time*0.9)*2.5;
         y*=100.0f; // actual height of the vertex

         // coordinates on a unit circle
         float s= sin(angle);
         float c= cos(angle);

         // since it's a cuboid, the other 3 coordinates are rotated by 90degress,
         // so we can generate those by mirroring
         vtx[i][0].x= s;
         vtx[i][0].y= y;
         vtx[i][0].z= c;

         vtx[i][1].x=-c;
         vtx[i][1].y= y;
         vtx[i][1].z= s;

         vtx[i][2].x=-s;
         vtx[i][2].y= y;
         vtx[i][2].z=-c;

         vtx[i][3].x= c;
         vtx[i][3].y= y;
         vtx[i][3].z=-s;

      }


Now we just have to paint it.
We draw a triangle-strip for each side to preserve shading & edges.

      for (int i1=0;i1<4;i1++) // 4 sides
      {
         // vertex on next side
         int i2= (i1+1)&3; // wrap from last (3) to first (0)
         glBegin(GL_TRIANGLE_STRIP);
         for (int j=0;j<seg;j++) // all height-segments
         {
            // the normal is a guesstimate
            glNormal3f( (vtx[j][i1].x+vtx[j][i2].x)*0.7f, 0, (vtx[j][i1].z+vtx[j][i2].z)*0.7f);
            glVertex3f( vtx[j][i1].x, vtx[j][i1].y, vtx[j][i1].z );
            glVertex3f( vtx[j][i2].x, vtx[j][i2].y, vtx[j][i2].z );
         }
         glEnd();
      }


Have fun tweaking it!
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 11, 2008
Cheers dude, looks cool, will take a look.

[ edit ]
That is incredible, and thankyou mate.

Only problem I will have, as the language im using is alot different to OGL, and I dont use C. Is in converting over the object, and im using polys and not quads. And as I dont really want to delete the model, somehow im going to have to store everything into arrays and update them accordingly.

This is how my original model looked like ( taken from the Blitzbasic code archives ):

Function CreateSegCube(segs=1,parent=0)
mesh=CreateMesh( parent )
For scnt=0 To 3
surf=CreateSurface( mesh )
stx#=-.5
sty#=stx
stp#=Float(1)/Float(segs)
y#=sty
For a=0 To segs
x#=stx
v#=a/Float(segs)
For b=0 To segs
u#=b/Float(segs)
AddVertex(surf,x,y,0.5,u,v)
x=x+stp
Next
y=y+stp
Next
For a=0 To segs-1
For b=0 To segs-1
v0=a*(segs+1)+b:v1=v0+1
v2=(a+1)*(segs+1)+b+1:v3=v2-1
AddTriangle( surf,v0,v1,v2 )
AddTriangle( surf,v0,v2,v3 )
Next
Next
RotateMesh mesh,0,90,0
Next
;top and bottom
RotateMesh mesh,90,0,0
For scnt=0 To 1
surf=CreateSurface( mesh )
stx#=-.5
sty#=stx
stp#=Float(1)/Float(segs)
y#=sty
For a=0 To segs
x#=stx
v#=a/Float(segs)
For b=0 To segs
u#=b/Float(segs)
AddVertex(surf,x,y,0.5,u,v)
x=x+stp
Next
y=y+stp
Next
For a=0 To segs-1
For b=0 To segs-1
v0=a*(segs+1)+b:v1=v0+1
v2=(a+1)*(segs+1)+b+1:v3=v2-1
AddTriangle( surf,v0,v1,v2 )
AddTriangle( surf,v0,v2,v3 )
Next
Next
RotateMesh mesh,180,0,0
Next
UpdateNormals mesh
Return mesh
End Function


Thanks for your further help and patience,
Cheers - Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 11, 2008
That function produces a cube with every face being a 2d segs*segs grid.
For the twister you just need segmentation along a single axis.
I rearranged my code a bit to fit into that addvertex/triangle-concept (completely untested):

      for i = 0 to seg-1
         v= i / seg
         y= v*100.0
         angle= sin(v*12.0 - time*0.9)*2.5

         float x= sin(angle)
         float z= cos(angle)

         AddVertex(surf, x,y,z, 0.0, v)
         AddVertex(surf, -z,y,x, 0.25, v)
         AddVertex(surf, -x,y,-z, 0.5, v)
         AddVertex(surf,  z,y,-x, 0.75, v)
         ' note: if you need proper texture-coordinate, it's necesarry to duplicate the first vertex with u=1.0 here
         ' take the fifth' vertex into account when creating the indices below
      Wend

      for i1= 0 to 3
         i2= (i1+1) and 3
         for int j=0 to seg-2
            AddTriangle( surf, j*4+i1, j*4+i2, (j+1)*4+i1 )
            AddTriangle( surf, j*4+i2, (j+1)*4+i1, (j+1)*4+i2 )
         Wend
     Wend

Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 11, 2008
Nice one mate, thanks alot for doing that.
There is however one problem, some of the faces look wrong.


Title: Re: 3D Twister - Sinus Methods
Post by: Rbz on September 11, 2008
Clyde, it's better if you post your blitz3D code, maybe someone can spot what's wrong with it...
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 11, 2008
The orientation of one triangle seems to be wrong (which one depends on whether you cull cw or ccw).
Just try to flip 2nd and 3rd index of one triangle.
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 12, 2008
Righty, I am having all kinds of problems with the following Blitz3D test code, main one being I can't get the object to be in view of visable anymore, as ive pigged about with the code for ages changing allsorts. And ive also had ago and made a Center Entity routine. And I havent used Blitz for sometime now, as i've made the switch to Freebasic.

And I dont think that, the method for the sin & cos is quite right for it; especially the time replacement with blitz's milliseconds ( thats bb's time method ) I've done my best to get it as per the examples above ( which I am truely greatful for )

If anyone can shed some light onto the solution, that would be immense & awesome.

Here goes:

;
; 3D Twister V1-1
;

Const XRES=640
Const YRES=480

Graphics3D XRES,YRES,32
SetBuffer BackBuffer()

Dim vc( 512*4 )

RunTwist()
End


Function AverageX#( Entity )

Local avgx#

Surface=GetSurface( Entity, 1 )

TotalVerts=CountVertices( Surface )

For a=0 To TotalVerts-1

avgx#=avgx#+VertexX ( Surface, a )

Next

Return ( avgx# / a )

End Function




Function AverageY#( Entity )

Local avgy#

Surface=GetSurface( Entity, 1 )

TotalVerts=CountVertices( Surface )

For a=0 To TotalVerts-1

avgy#=avgy#+VertexY ( Surface, a )

Next

Return ( avgy# / a )

End Function



Function AverageZ#( Entity )

Local avgz#

surface=GetSurface( Entity, 1 )

TotalVerts=CountVertices(Surface)

For a=0 To TotalVerts-1

avgz#=avgz#+VertexZ ( Surface, a )

Next

Return ( avgz# / a )

End Function



Function RunTwist()

MainCam=CreateCamera()

PositionEntity MainCam,0,0,-5

Light=CreateLight()

While Not KeyHit(1)

Twister=CreateCuboidTwister()
PositionEntity Twister,0,0,10
EntityColor Twister,255,000,000
ScaleEntity Twister,50,50,50
CenterMesh( Twister )


RenderWorld()

FreeEntity Twister
Flip

Wend


End Function


Function CenterMesh( Entity )

Local x#=AverageX#( Entity )
Local y#=AverageY#( Entity )
Local z#=AverageZ#( Entity )

surface=GetSurface( Entity,1 )


For a=0 To CountVertices( Surface )-1

vx#=VertexX( surface, a )
vy#=VertexY( surface, a )
vz#=VertexZ( surface, a )

vx#=vx#-x#
vy#=vy#-y#
vz#=vz#-z#

VertexCoords Surface, a, vx#, vy#, vz#

Next

UpdateNormals ( Entity )


End Function




Function CreateCuboidTwister( segs=512, Parent=0 )

Entity = CreateMesh ( Parent )
surface = CreateSurface ( Entity )


For i = 0 To segs-1

v#= i / segs
y#= v*100.0
angle#= Sin(v#*12.0 - MilliSecs()*0.9)*2.5

x#= Sin(angle#)
z#= Cos(angle#)

vc(a)=AddVertex(surface,  x#,y#, z#, 0.0 , v#) : a=a+1
vc(a)=AddVertex(surface, -z#,y#, x#, 0.25, v#) : a=a+1
vc(a)=AddVertex(surface, -x#,y#,-z#, 0.5 , v#) : a=a+1
vc(a)=AddVertex(surface,  z#,y#,-x#, 0.75, v#) : a=a+1

Next

For i1= 0 To 3
i2= (i1+1) And 3
For j=0 To segs-2

v0=j*4+i1
            v1=j*4+i2
            v2=(j+1)*4+i1
            v3=(j+1)*4+i2


AddTriangle( surface, vc(V0), vc(V1), vc(V2) )
AddTriangle( surface, vc(V1), vc(V3), vc(V2) )

Next
Next

UpdateNormals( Entity )

Return ( Entity )

End Function


Cheers,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 14, 2008
I can only comment your source on a theoretical basis since I have no clue what I need to compile it.
The function "CreateCuboidTwister" creates a mesh that is already center in the x- & z-dimensions (x,z are calculated from a unit-circle (http://en.wikipedia.org/wiki/Unit_circle)).
You don't have to center it again with "CenterMesh". If you still want to do that, you should probably initialize the variables "avgx/y/z#" in "AverageX/Y/Z#" to zero.
Translating an object also doesn't change the normals, so "UpdateNormals" shouldn't be required.
Make sure that "v#= i / segs" actually results in a floating-point value.
In the example-code I used a variable "time" which is a floating-point value holding the passed time in seconds.
So you should use something like MilliSecs()/1000.0. It's important to read the time only once so it doesn't change its' value while processing.
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 14, 2008
ok Cheers dude for the tips, ive now made a little update.
I need the updatenormals as the model is being created and then deleted; so a new model is made with the new sin and cos. it's how Blitz 3D works with building models


;
; 3D Twister V1-1
;
Const XRES=640
Const YRES=480

Graphics3D XRES,YRES,32
SetBuffer BackBuffer()

Dim vc( 512*4 )

RunTwist()
End


Function RunTwist()

MainCam=CreateCamera()

PositionEntity MainCam,0,0,-5

Light=CreateLight()

While Not KeyHit(1)

Twister=CreateCuboidTwister()
PositionEntity Twister,0,0,10
EntityColor Twister,255,000,000
;ScaleEntity Twister,50,50,50

RenderWorld()
Flip

FreeEntity Twister


Wend


End Function



Function CreateCuboidTwister( segs=512, Parent=0 )

Entity = CreateMesh ( Parent )
surface = CreateSurface ( Entity )

Time#=MilliSecs()/1000.00

For i = 0 To segs-1

v#= Float ( i / segs )
y#= v#*100.0
angle#= Sin(v#*12.0 - Time#*0.9)*2.5

x#= Sin(angle#)
z#= Cos(angle#)

vc(a)=AddVertex(surface,  x#,y#, z#, 0.0 , v#) : a=a+1
vc(a)=AddVertex(surface, -z#,y#, x#, 0.25, v#) : a=a+1
vc(a)=AddVertex(surface, -x#,y#,-z#, 0.5 , v#) : a=a+1
vc(a)=AddVertex(surface,  z#,y#,-x#, 0.75, v#) : a=a+1

Next

For i1= 0 To 3
i2= (i1+1) And 3
For j=0 To segs-2

v0=j*4+i1
            v1=j*4+i2
            v2=(j+1)*4+i1
            v3=(j+1)*4+i2

AddTriangle( surface, vc(V0), vc(V1), vc(V2) )
AddTriangle( surface, vc(V1), vc(V3), vc(V2) )

Next
Next

UpdateNormals( Entity )

Return ( Entity )

End Function


I dont know wether or not the source i've posted will fit into the blitz 3d demo as theres a limit to the size of code you can do with the demo trial, but here is a link to the demo version: http://www.blitzbasic.com/file/get.php?file=/Products/demos/Blitz3DDemo183.exe

Cheers and many thanks,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 14, 2008
You now cast the result of an intger-division (result: 0) to floating-point. Instead you need to cast the arguments:
v#= Float ( i ) / Float ( segs )

Blitz3D assumes arguments to sin/cos in degree instead of radians:
RAD2DEG= 180.0 / 3.1415926535897932384626433832795
angle#= Sin( (v#*12.0 - Time#*0.9) * RAD2DEG )*2.5
x#= Sin(angle# * RAD2DEG)
z#= Cos(angle# * RAD2DEG)


The mesh extends from 0..100 on the y-axis, so the socket is now in the center of the screen.
Just move it down a bit:
PositionEntity Twister,0,-50,10

The triangles have wrong orientation (you are looking into the object), just flip the the indices:
AddTriangle( surface, vc(V0), vc(V2), vc(V1) )
AddTriangle( surface, vc(V1), vc(V2), vc(V3) )





Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 14, 2008
Cheers for sorting that for me dude. Nice one.
It doesnt quite twist as your ogl example; will have a bit of a play, unless you know how to correct it.

Big thanks,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: Rbz on September 15, 2008
It does Clyde, it's just a matter of point of view :)


;
; 3D Twister V1-1
;
Const XRES=640
Const YRES=480

Graphics3D XRES,YRES,32,2
SetBuffer BackBuffer()

Global pitch#=44.0,yaw#=0,roll#=0

Dim vc( 512*4 )

RunTwist()
End


Function RunTwist()

MainCam=CreateCamera()
CameraClsColor MainCam, 26, 26, 26
CameraClsMode MainCam, True, True
PositionEntity MainCam,0,0,-10

Light=CreateLight(1)
LightColor Light,255.0,255.0,255.0
AmbientLight 50.0,50.0,50.0


While Not KeyHit(1)

Twister=CreateCuboidTwister()
PositionEntity Twister,0,-45,-50
;EntityColor Twister,0,0,76
TurnEntity Twister,pitch#,yaw#,roll#
;ScaleEntity Twister,50,50,50

RenderWorld()

;draw debug info
Text 0,0, "pitch = " + pitch#
Text 0,10, "yaw= " + yaw#
Text 0,20, "roll= " + roll#
;update values
If KeyDown( 208 )=True Then pitch#=pitch#-1.0
If KeyDown( 200 )=True Then pitch#=pitch#+1.0
If KeyDown( 203 )=True Then yaw#=yaw#-1.0
If KeyDown( 205 )=True Then yaw#=yaw#+1.0
If KeyDown( 45 )=True Then roll#=roll#-1.0
If KeyDown( 44 )=True Then roll#=roll#+1.0

Flip

FreeEntity Twister

Wend


End Function



Function CreateCuboidTwister( segs=512, Parent=0 )

Entity = CreateMesh ( Parent )
surface = CreateSurface ( Entity )

Time#=Float(MilliSecs())/1000.00

RAD2DEG= 180.0 / 3.1415926535897932384626433832795

For i = 0 To segs-1

angle#= Sin( (v#*12.0 - Time#*0.9) * RAD2DEG )*2.5
x#= Sin(angle# * RAD2DEG)
z#= Cos(angle# * RAD2DEG)

v#= Float ( i ) / Float ( segs )
y#= v#*100.0

vc(a)=AddVertex(surface,  x#,y#, z#, 0.0 , v#) : a=a+1
vc(a)=AddVertex(surface, -z#,y#, x#, 0.25, v#) : a=a+1
vc(a)=AddVertex(surface, -x#,y#,-z#, 0.5 , v#) : a=a+1
vc(a)=AddVertex(surface,  z#,y#,-x#, 0.75, v#) : a=a+1

Next

For i1= 0 To 3
i2= (i1+1) And 3
For j=0 To segs-2

v0=j*4+i1
            v1=j*4+i2
            v2=(j+1)*4+i1
            v3=(j+1)*4+i2

AddTriangle( surface, vc(V0), vc(V2), vc(V1) )
AddTriangle( surface, vc(V1), vc(V2), vc(V3) )

Next
Next

UpdateNormals( Entity )

Return ( Entity )

End Function
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 15, 2008
Mighty thanks for that.
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 15, 2008
Ok I've got a few more questions to this.

1/ There is a ripple / bumpy like effect on the u and v co-ordinates of the object. How would this be smoothed out. It's very noticeable once a texture is applied.

2/ How would it be possible to add more bendyness to it? If you need an example of what I mean, I can draw up some example images if that helps.

3/ Sometimes, it jumps with the updating of the current twist calc. I think it's to do with the the timer. Any Ideas on curing that please?

4/ Do you have any more methods / examples of different sin and cos to do to the object?

Cheers and many thanks,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 15, 2008
You should really try to figure out what your code does ;)

Quoteangle#= Sin( (v#*12.0 - Time#*0.9) * RAD2DEG )*2.5
Bigger values bend "further"

Quoteangle#= Sin( (v#*12.0 - Time#*0.9) * RAD2DEG )*2.5
..."faster"

Quoteangle#= Sin( (v#*12.0 - Time#*0.9) * RAD2DEG )*2.5
..."tighter"

QuoteThere is a ripple / bumpy like effect on the u and v co-ordinates of the object
Sometimes a picture says more than 1000 words.

Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 15, 2008
Yeah dude I get what the current method of twisting does; and thanks for clarifying. I was wonderning if there was any different calcs to use, etc.

I'll do up an exe and some piccies; i've got to nip out for a bit, and will do it when I get back.

Cheers, and all the very best,
Clyde
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 15, 2008
Here's an exe and bb source of the twister. if you look closely & carefully, when the twist is happening on the sides there is a ripple / bump type effect.

Also still very interested in different sinus methods!

Will post some rough picture examples later ron.

Big thanks,
Clyde
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 15, 2008
Quotewhen the twist is happening on the sides there is a ripple / bump type effect.
that's mathematically plausible:
When rotating the segments against each other, the texture is no longer parallel to the polygon which makes linear interpolation fail.

To make it less obvious you can only use more segments (thus making the interpolation-gaps smaller).
Note that most of your object currently extends out of the bottom screen (currently visible in y is ~60..75), so you don't need more segments but just a better arrangement.
Title: Re: 3D Twister - Sinus Methods
Post by: benny! on September 15, 2008
@Clyde dude:
Looks good now. Good work.

@hellfire:
Awesome help and cool example source !
Title: Re: 3D Twister - Sinus Methods
Post by: Shockwave on September 15, 2008
That looks pretty cool indeed :)

I am a sucker for twisters.. I coded one while I was at Sundown, I'll have to grab it off the laptop and post it (It's not 3D like yous though).. It's not as good as what you have here but it moves in a strangely crazy way.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 16, 2008
I forgot to mention yesterday:
In the way you now assign your texture-coordinates you get wrong texture-scaling (and inverse u-direction) on one side of your object because the last edge connects vertices 0 and 3 (here delta-u is 0.75 while the other faces have 0.25)
To fix this you would need a fifth vertex with the same position as vertex0 and a u-coordinate of 1.0.
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 16, 2008
Ok cheers for that, how would I go about using this 5th Element?
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 16, 2008
you add an additional vertex:
vc(a)=AddVertex(surface,  x#,y#,z#, 1.0, v#) : a=a+1

And connect the last edge to this new vertex instead of wrapping back to vertex 0:

For i1= 0 To 3
i2= i1+1
For j=0 To segs-2
    v0=j*5+i1
            v1=j*5+i2
            v2=(j+1)*5+i1
            v3=(j+1)*5+i2

            AddTriangle( surface, vc(V0), vc(V2), vc(V1) )
    AddTriangle( surface, vc(V1), vc(V2), vc(V3) )

Next
Next


Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 16, 2008
Cheers dude.

Thanks,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 20, 2008
Im now looking for different ways / new approaches of adding sin and cos ( Sinus Methods ), for more variety to the effect. as per the original topic title.

If anyone has suggestions and ways, I'd love to hear about them. :D
And they can be in Blitz Degrees style, or Radians. My brain cell is acting up.

Many Huge Thanks,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: Jim on September 20, 2008
You're gonna have to write some of this demo yourself eventually ;)
Quote
Quote
angle#= Sin( (v#*12.0 - Time#*0.9) * RAD2DEG )*2.5
Bigger values bend "further"

Quote
angle#= Sin( (v#*12.0 - Time#*0.9) * RAD2DEG )*2.5
..."faster"

Quote
angle#= Sin( (v#*12.0 - Time#*0.9) * RAD2DEG )*2.5
..."tighter"

My first port of call would be to make these constants in to variables.  Then animate them using sin.
So, eg.

angle#= Sin( (v#*12.0 - Time#*0.9) * RAD2DEG )*rotation_speed
rotation_speed = sin(frame_counter*some_scale_factor)
or
rotation_speed = y * some_scale_factor
or
...


Jim

Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 20, 2008
Thanks dude much appreciated, im in the process of re-exploring and experimenting with Blitz3D.
However I was after different approaches to the sinus motion.

Cheers,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 23, 2008
You are now animating the rotation angle only.
As pointed out earlier, you can also animate the center-position, radius or center-of-rotation of each segment.
The "sin" function is only used to "make things go forth and back", but you can use any function imaginable.
You're usually getting good (means: still smooth but less predictable) results when adding multiple sine-waves with different amplitudes and frequencies to form the resulting "value".
You can also load a texture (which is basically a table of a 2d-function) and pick your values from there instead of doing a simple "sin"...
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 26, 2008
Ok cool dude and thanks & I will experiment some more.

I have another query / problem with texturing the object, I have designed a texture of 64*256, and it wont properly map to it, meaning each side / face of the cuboid isnt quite right. I think its to do with the U and V, but am not entirely sure how I would solve this problem, and i'd love a hand in working it out please dude?

Cheers and hugest of thanks,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 26, 2008
Quoteeach side / face of the cuboid isnt quite right
Can you post an example?
Are you now using a 5th vertex to compensate the texture-seam?
Do you using any texture-tiling?
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 26, 2008
I am using the 5th vertext to compensate the texture-seam, and Im not using any texture tiling; as I dont wont to use any inbuilt texture scaling commands, id like the model to be able to map it properly.

Below is an example texture image and zip with exe and source:
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 26, 2008
I don't have Blitz installed anymore, so just some theory again.
This is the way you are now assigning your texture coordinates:

vc(a)=AddVertex(surface,  x#,y#, z#, 0.0 , v#) : a=a+1
vc(a)=AddVertex(surface, -z#,y#, x#, 0.25, v#) : a=a+1
vc(a)=AddVertex(surface, -x#,y#,-z#, 0.5 , v#) : a=a+1
vc(a)=AddVertex(surface,  z#,y#,-x#, 0.75, v#) : a=a+1
vc(a)=AddVertex(surface,  x#,y#,z#,  1.0, v#) : a=a+1


So your are wrapping the width of the texture (u= 0..1) once around the whole object.
But you probably want to map the texture once on each side?
Just multiply your texture-coordinate by 4 then.

Basically the same applies to the v-coordinate. Because the cuboid is much higher than the screen, there are only a few segments visible, so you might want to scale it accordingly to avoid texture-stretching.
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 26, 2008
Ok dude, thanks mate.

Not quite sure on the scaling part to avoid texture stretching?

Cheers,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 26, 2008
ok, ive mutiplied the texture co-ords by 4; still have a problem with it on it's v.

Any solutions?

I have tried dividing the v's by the height ( 100 ) but I dont think thats the solution.

Cheers and many thanks,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 26, 2008
Clyde, using smaller (dividing the existing) texture-coordinates means that a smaller area of the texture is stretched across the polygon. What you want is the opposite.
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 26, 2008
Ah ok, so for example:


vc(a)=AddVertex(surface,  x#,y#, z#, 0.0*4 , v#*4*100) : a=a+1
vc(a)=AddVertex(surface, -z#,y#, x#, 0.25*4, v#*4*100) : a=a+1
vc(a)=AddVertex(surface, -x#,y#,-z#, 0.5*4 , v#*4*100) : a=a+1
vc(a)=AddVertex(surface,  z#,y#,-x#, 0.75*4, v#*4*100) : a=a+1
vc(a)=AddVertex(surface,  x#,y#,z#,  1.0*4, v#*4*100) : a=a+1


Edit- tried that, but still having problems with the texture not working properly against the V.
I have tried, v*(4*Height), v*4*Height, v+(4*Height). Height being 100.0 or 256.0

I dont suppose it has anything to do with the v co-ords being worked out like this: v#= Float ( i ) / Float ( segs )


Cheers and many thanks,
Clyde.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 28, 2008
When multiplying your v-coordinate by 400, the texture will tile 400 times along the height of your object, so it's squeezed into only a few pixels height - better try 10 or 20.
You should really try to understand the effect of scaling texture-coordinates as this is an elementary concept.
Title: Re: 3D Twister - Sinus Methods
Post by: Clyde on September 29, 2008
Ok cheers for that Hellfire dude.

I thought that there might be some kind of math for calculating the correct scale for the texture co-ords, as I have done quite a bit of mesh making and experimenting in B3D. I thought there might be a bit of math to use in the u and v's.

Its sorted now in that area, which is nice and thankyou.
Title: Re: 3D Twister - Sinus Methods
Post by: hellfire on September 29, 2008
QuoteI thought that there might be some kind of math for calculating the correct scale for the texture co-ords
You can scale, scroll or rotate your texture-coordinates how you like and all these can have an useful application or desired effect.
Generally you want to keep the aspect-ratio of your texture. In this case you align the width of your texture to fill one side of the cuboid (the edge length is 1). Since the texture is 4x as high as wide and the cuboid has a height of 100 you would scale your v-coordinate into a range of 0..25 (100/4) to keep the texture's aspect ratio.