• Welcome to Dark Bit Factory & Gravity.
 

Use your imagination here..

Started by Shockwave, August 17, 2006

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Shockwave

Here is a technique which is quite cool. Here's how it works.
Let's say that you have four corners of a square..

;D :) :) :) ;D
:) :) :) :) :)
:) :) :) :) :)
:) :) :) :) :)
;D :) :) :) ;D

And you wanted to make it more detailed I figured that you could just divide the opposite corners like;

centrex = (x1+x2) / 2
centrey = (y1+y2) / 2

And easily get this;

;D :) ;D :) ;D
:) :) :) :) :)
;D :) :) :) ;D
:) :) :) :) :)
;D :) ;D :) ;D

From the four original points. I figured that this technique would be quite useful for making low overhead dot cubes, it would be possible to make a cube out of the 8 corner points and recursively subdivide the points to make the cube as detailed as you wanted but only ever having to rotate the original 8 corner points.

Then I thought that wasn't even the best way of doing it so I decided to interpolate, almost as if I was writing a texture mapping routine and I've got the listing below so far.. I am going to apply it to some 3D models in my next intro and do some transformations and other stuff to them.

First and unoptimised test;


'
' This technique is going to form the basis for a demo effect.
' Basically it uses an interpolation technique to subdivide the 4 corners
' Of a cube,this will make it possible to do relly complex dot cubes and make transformations
' a simple matter and also save the overheads of rotating all those points as only the corners
' will ever need to be rotated.
'
' Coded by Shockwave / DBF
' Do not rip without credit :-)
'
' See you in the finished intro..
'
'---------------------------------------------------------------------------


        OPTION STATIC
        OPTION EXPLICIT

'-------------------------------------------------------------------------
' Includes.
'-------------------------------------------------------------------------

        '#define PTC_WIN
        #Include Once "tinyptc.bi"

   
    Const XRES=640 'Screen Width
    Const YRES=480 'Screen Height
   
    const SUBDIVISIONS = 20 '            How many dots per line?

   
DECLARE SUB DRAW_DOT_FACE(BYVAL X1 AS DOUBLE , BYVAL Y1 AS DOUBLE,BYVAL X2 AS DOUBLE , BYVAL Y2 AS DOUBLE , BYVAL X3 AS DOUBLE , BYVAL Y3 AS DOUBLE , BYVAL X4 AS DOUBLE , BYVAL Y4 AS DOUBLE)
DIM SHARED AS INTEGER BUFFER ( XRES * YRES )     

        If( ptc_open( "DBF SCREEN", XRES, YRES ) = 0 ) Then
        End -1
        End If
   
DIM XA,XB,XC,XD,YA,YB,YC,YD
DIM SHARED GADD,GADD2 AS DOUBLE
DO
    GADD=GADD+.004
    GADD2=GADD2+.005

XA = 320+(200*SIN(GADD ))
XB = 320+(200*SIN(GADD + 90))
XC = 320+(200*SIN(GADD2 + 180))
XD = 320+(200*SIN(GADD2 + 270))

YA = 240+(200*COS(GADD2))
YB = 240+(200*COS(GADD2 + 90))
YC = 240+(200*COS(GADD + 70))
YD = 240+(200*COS(GADD + 40))


    DRAW_DOT_FACE(XA,YA, XB,YB,  XC,YC, XD,YD )
    PTC_UPDATE@BUFFER(0)
    ERASE BUFFER
    SLEEP 1
LOOP UNTIL INKEY$=CHR$(27)

SUB DRAW_DOT_FACE(BYVAL X1 AS DOUBLE , BYVAL Y1 AS DOUBLE,BYVAL X2 AS DOUBLE , BYVAL Y2 AS DOUBLE , BYVAL X3 AS DOUBLE , BYVAL Y3 AS DOUBLE , BYVAL X4 AS DOUBLE , BYVAL Y4 AS DOUBLE)
   
    DIM AS INTEGER SA,SB
    DIM AS DOUBLE INTERX,INTERY , XXP , YYP
   
    DIM  AS DOUBLE TOPX (SUBDIVISIONS)
    DIM  AS DOUBLE TOPY (SUBDIVISIONS)
    DIM  AS DOUBLE BOTX (SUBDIVISIONS)
    DIM  AS DOUBLE BOTY (SUBDIVISIONS)

'
'   CALCULATE TOP LINE.
'

INTERX = (X1-X2) / SUBDIVISIONS
INTERY = (Y1-Y2) / SUBDIVISIONS

XXP = X1
YYP = Y1

FOR SA = 1 TO SUBDIVISIONS   
    TOPX(SA) = INT(XXP)
    TOPY(SA) = INT(YYP)
    XXP=XXP-INTERX       
    YYP=YYP-INTERY
    BUFFER(TOPX(SA)+(TOPY(SA) * XRES)) = &HFFFFFF
    BUFFER(TOPX(SA)+((TOPY(SA)-1) * XRES)) = &HFFFFF
    BUFFER(TOPX(SA)+((TOPY(SA)+1) * XRES)) = &HFFFFFF
    BUFFER((TOPX(SA)-1)+(TOPY(SA) * XRES)) = &HFFFFFF
    BUFFER((TOPX(SA)+1)+(TOPY(SA) * XRES)) = &HFFFFFF
NEXT

'
'   CALCULATE BOTTOM LINE.
'

INTERX = (X3-X4) / SUBDIVISIONS
INTERY = (Y3-Y4) / SUBDIVISIONS

XXP = X3
YYP = Y3
FOR SA = 1 TO SUBDIVISIONS   
   
    BOTX(SA) = INT(XXP)
    BOTY(SA) = INT(YYP)
   
    XXP=XXP-INTERX       
    YYP=YYP-INTERY
    BUFFER(BOTX(SA)+(BOTY(SA) * XRES)) = &HFFFFFF
    BUFFER(BOTX(SA)+((BOTY(SA)+1) * XRES)) = &HFFFFFF
    BUFFER(BOTX(SA)+((BOTY(SA)-1) * XRES)) = &HFFFFFF
    BUFFER((BOTX(SA)-1)+(BOTY(SA) * XRES)) = &HFFFFFF
    BUFFER((BOTX(SA)+1)+(BOTY(SA) * XRES)) = &HFFFFFF
NEXT

'
'   CALCULATE MIDDLES;
'
FOR SB=1 TO SUBDIVISIONS

INTERX = (TOPX(SB)-BOTX(SB)) / SUBDIVISIONS
INTERY = (TOPY(SB)-BOTY(SB)) / SUBDIVISIONS

XXP = TOPX(SB)
YYP = TOPY(SB)

FOR SA = 1 TO SUBDIVISIONS-1
    XXP=XXP-INTERX       
    YYP=YYP-INTERY
    BUFFER(INT(XXP)+(INT(YYP) * XRES)) = &HFFFFFF
    BUFFER(INT(XXP-1)+(INT(YYP) * XRES)) = &HFFFFFF
    BUFFER(INT(XXP+1)+(INT(YYP) * XRES)) = &HFFFFFF
    BUFFER(INT(XXP)+(INT(YYP-1) * XRES)) = &HFFFFFF
    BUFFER(INT(XXP)+(INT(YYP+1) * XRES)) = &HFFFFFF
NEXT

NEXT

END SUB



Shockwave ^ Codigos
Challenge Trophies Won:

Shockwave

To give you an example of how powerful this is, check this 200 * 200 Dot poly square or 40,000 dots in other words! Imaging how slow it would be to rotate 40,000 vertices, this could be drawn at this speed (faster when I've removed the fpu math) from just rotating 4 corners..


'
' This technique is going to form the basis for a demo effect.
' Basically it uses an interpolation technique to subdivide the 4 corners
' Of a cube,this will make it possible to do relly complex dot cubes and make transformations
' a simple matter and also save the overheads of rotating all those points as only the corners
' will ever need to be rotated.
'
' Coded by Shockwave / DBF
' Do not rip without credit :-)
'
' See you in the finished intro..
'
'---------------------------------------------------------------------------


        OPTION STATIC
        OPTION EXPLICIT

'-------------------------------------------------------------------------
' Includes.
'-------------------------------------------------------------------------

        '#define PTC_WIN
        #Include Once "tinyptc.bi"

   
    Const XRES=640 'Screen Width
    Const YRES=480 'Screen Height
   
    const SUBDIVISIONS = 200 '            How many dots per line?

   
DECLARE SUB DRAW_DOT_FACE(BYVAL X1 AS DOUBLE , BYVAL Y1 AS DOUBLE,BYVAL X2 AS DOUBLE , BYVAL Y2 AS DOUBLE , BYVAL X3 AS DOUBLE , BYVAL Y3 AS DOUBLE , BYVAL X4 AS DOUBLE , BYVAL Y4 AS DOUBLE)
DIM SHARED AS INTEGER BUFFER ( XRES * YRES )     

        If( ptc_open( "DBF SCREEN", XRES, YRES ) = 0 ) Then
        End -1
        End If
   
DIM XA,XB,XC,XD,YA,YB,YC,YD
DIM SHARED AS DOUBLE GADD,GADD2, GADD3,GADD4, GADD5
DO
    GADD=GADD+.004
    GADD2=GADD2+.008
    GADD3=GADD3+.007
    GADD4=GADD4+.005
    GADD5=GADD5+.01

XA = 320+(300*SIN(GADD5))
XB = 320+(300*SIN(GADD4))
XC = 320+(300*SIN(GADD3))
XD = 320+(300*SIN(GADD))

YA = 240+(238*COS(GADD2 ))
YB = 240+(238*COS(GADD3 ))
YC = 240+(238*COS(GADD4 ))
YD = 240+(238*COS(GADD5 ))


    DRAW_DOT_FACE(XA,YA, XB,YB,  XC,YC, XD,YD )
    PTC_UPDATE@BUFFER(0)
    ERASE BUFFER   
LOOP UNTIL INKEY$=CHR$(27)

SUB DRAW_DOT_FACE(BYVAL X1 AS DOUBLE , BYVAL Y1 AS DOUBLE,BYVAL X2 AS DOUBLE , BYVAL Y2 AS DOUBLE , BYVAL X3 AS DOUBLE , BYVAL Y3 AS DOUBLE , BYVAL X4 AS DOUBLE , BYVAL Y4 AS DOUBLE)
   
    DIM AS INTEGER SA,SB
    DIM AS DOUBLE INTERX,INTERY , XXP , YYP
   
    DIM  AS DOUBLE TOPX (SUBDIVISIONS)
    DIM  AS DOUBLE TOPY (SUBDIVISIONS)
    DIM  AS DOUBLE BOTX (SUBDIVISIONS)
    DIM  AS DOUBLE BOTY (SUBDIVISIONS)

'
'   CALCULATE TOP LINE.
'

INTERX = (X1-X2) / SUBDIVISIONS
INTERY = (Y1-Y2) / SUBDIVISIONS

XXP = X1
YYP = Y1

FOR SA = 1 TO SUBDIVISIONS   
    TOPX(SA) = INT(XXP)
    TOPY(SA) = INT(YYP)
    XXP=XXP-INTERX       
    YYP=YYP-INTERY
    BUFFER(TOPX(SA)+(TOPY(SA) * XRES)) = &HFFFFFF

NEXT

'
'   CALCULATE BOTTOM LINE.
'

INTERX = (X3-X4) / SUBDIVISIONS
INTERY = (Y3-Y4) / SUBDIVISIONS

XXP = X3
YYP = Y3
FOR SA = 1 TO SUBDIVISIONS   
   
    BOTX(SA) = INT(XXP)
    BOTY(SA) = INT(YYP)
   
    XXP=XXP-INTERX       
    YYP=YYP-INTERY
    BUFFER(BOTX(SA)+(BOTY(SA) * XRES)) = &HFFFFFF
NEXT

'
'   CALCULATE MIDDLES;
'
FOR SB=1 TO SUBDIVISIONS

INTERX = (TOPX(SB)-BOTX(SB)) / SUBDIVISIONS
INTERY = (TOPY(SB)-BOTY(SB)) / SUBDIVISIONS

XXP = TOPX(SB)
YYP = TOPY(SB)

FOR SA = 1 TO SUBDIVISIONS-1
    XXP=XXP-INTERX       
    YYP=YYP-INTERY
    BUFFER(INT(XXP)+(INT(YYP) * XRES)) = &HFFFFFF
NEXT

NEXT

END SUB
Shockwave ^ Codigos
Challenge Trophies Won:

MrP

Sweet little idea. Look forward to seeing the finished version....

Dad1916

Can you post the .exe examples if you get a chance. thanks. O0 O0

Shockwave

Yep, no problem, I'll get a dotcube working with it and post it later :)
Shockwave ^ Codigos
Challenge Trophies Won:

Shockwave

Ok, well it works with a cube no problem, I have attached an exe to this post :)
Shockwave ^ Codigos
Challenge Trophies Won:

Clyde

Welldone and all, that dot cube looks amazing dude. :)

Cheers,
Clyde.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.


Challenge Trophies Won:

Jim

Now, think about ANY point inside your cube.  You can get to it by adding only!  Just rotate 3 points x=(0,0,1), y=(0,1,0), z=(1,0,0) and then multiply x, y and z by the scale factors of the points you're interested in and you can get any point inside the cube (right now you've only used 1/2).  And then see that those x,y and z scale factors are actually just the x,y and z positions of the points inside the object.

I think you've just had an epiphany.

Jim
Challenge Trophies Won:

DrewPee

Wow! Thats stunning - how the hell did you come up with that? My head hurts (although I do understand how its done!).
Looks wicked . . . what about setting fire to that now? lol?

Drew
DrewPee
aka Falcon of The Lost Boyz (Amiga)
Ex-Amiga Coder and Graphic Designer
Administrator of > www.retrocomputermuseum.co.uk

Shockwave

Quote from: Jim on August 18, 2006
Now, think about ANY point inside your cube. You can get to it by adding only! Just rotate 3 points x=(0,0,1), y=(0,1,0), z=(1,0,0) and then multiply x, y and z by the scale factors of the points you're interested in and you can get any point inside the cube (right now you've only used 1/2). And then see that those x,y and z scale factors are actually just the x,y and z positions of the points inside the object.

I think you've just had an epiphany.

Jim

Shit, that's so simple that it's sick :) I am going to have to re-write most of my 3D code to take advantage of this now. Cheers Jim.

Quote from: DrewPee on August 18, 2006
Wow! Thats stunning - how the hell did you come up with that? My head hurts (although I do understand how its done!).
Looks wicked . . . what about setting fire to that now? lol?

Drew

Burning it would be pretty easy, I'll add an example of it after I have finished doing the cracktro I am working on.

As far as working out how to do this I was just thinking about how it must be possible to calculate a cube from the corners if it was possible to calculate a texture from the same data so it just clicked.

I think I've been waiting to have an idea lately to be Honest Drew :)
Shockwave ^ Codigos
Challenge Trophies Won:

Shockwave

Shockwave ^ Codigos
Challenge Trophies Won:

Stonemonkey


ninogenio

holy shit that is good!


i was gonna try one of these but i had it down a totally diffrent way, whats better is i understand it too.
Challenge Trophies Won:

Shockwave

Yeah, I am really happy with the way this worked out and the extra understanding of how this may be applied to a 3D engine (thanks Jim, Thanks Stonemonkey). Glad that you like it guys, I'll surely do something cute with this technique soon.
Shockwave ^ Codigos
Challenge Trophies Won:

Rbz

Very smart  :)

Can you make a jelly cube effect  ?  Would be nice too
Challenge Trophies Won:

Jim

Let's see if I can drive the nail in a little further...

When you multiply (0,0,1)  (0,1,0) and (1,0,0) by your matrix to get the vectors you need to add together in your new technique, all you are really doing is extracting rows from the matrix.
So

(x,y,z) * (a b c)
         (d e f)
         (g h i)
=(xa+yd+zg, xb+ye+ zh, xc+yf+zi)

But if x=0, y=0, z=1 that's just

(0a+0d+1g, 0b+0e+1h, 0c+0f+1i)=(g,h,i)

which is exactly the bottom row of the matrix.  x is the top row (a,b,c) and y is the middle row (d,e,f).

That tells you that the rows of the matrix are just 3 vectors.  vectors which point along the bottom edges of your cube.

All you are doing when you rotate a vector by a matrix is applying an x,y,z scale to the 3 vectors that point along the bottom edges of your cube.

In the immortal words of Paul Daniels "Now that's magic!"

Jim

Challenge Trophies Won:

Clyde

I still need to inspect and see whats occuring.
Goes without saying though, Very cool and impressive transformers Shockwave.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.


Challenge Trophies Won:

Shockwave

Good old small daniels :) And thanks Jim, this has been a revelation to me, I'm glad I shared this code now.

It is also having another completely seperate side effect too. In the Flame intro I used Delta timing for the text writer because I wanted to make sure that it was in synch to the music, I am applying delta timing to this routine and it still looks smooth right down to about 30fps, I'm hoping that I will be able to use this to make something really oldschool without the glitches I've come to accept as part of tinyptc.
Shockwave ^ Codigos
Challenge Trophies Won:

MrP

Yep looks real good...... must study that a bit my maths is pants....

Dad1916

Quote from: Shockwave on August 17, 2006
Ok, well it works with a cube no problem, I have attached an exe to this post :)
Very nice indeed. Now the hard part, I must examine the code and learn! O0 O0