Jump to content
desertfish

New demo uploaded: 3d wire frame animated spaceship

Recommended Posts

3d wire frame animated spaceship

View File

3d animated Cobra MK3 ship from Elite!  Uses 16 bits integer math and has hidden-line removal..

This is an almost 1-to-1 conversion of the same program I wrote for the C64, but it runs a lot faster on the CommanderX16 ūüôā

Here is the (prog8) source code https://github.com/irmen/prog8/blob/master/examples/cx16/cobramk3-gfx.p8

 

I haven't figured out how to wait for the Vertical blank yet, to reduce the flickering perhaps...


 

  • Like 5

Share this post


Link to post
Share on other sites

Ok you put me on a mission ūüė¨¬†¬† I now have to at least put all Elite's ship models into that program¬† https://www.c64-wiki.com/wiki/Elite#Spaceship_types

And we also have text mode Elite http://www.elitehomepage.org/text/index.htm

So who knows ūüėÖ

 

edit: Right, that same site hosts various 3d model source files of the Elite shipts. I cobbled up a quick model viewer in Python....  Going to use that to convert the data into binary arrays that I can read into my 6502 program !

image.png.d6460d71e9a0aa0b7251f95f6ec31fdc.png

Edited by desertfish
cobra
  • Thanks 1

Share this post


Link to post
Share on other sites

Yay, the exported ship data works in the Commander X16 version!  Attempt for the next version to implement hidden line removal in this version too.

image.png.e8c53ac95066247fc8d8e593fed75d70.png

  • Like 3

Share this post


Link to post
Share on other sites

Nah, I'm not going to recreate Elite, the game. That would be way too much work. ¬†¬† The 3d code is not a full 3d engine but just capable of showing one spinning object in the center of the screen ūüôā ¬† I'm not going to expand that. I do want to add hidden line removal to it though¬† and the other dozen or so ship models. As a separate project maybe to compile or convert that text-mode Elite trading program.¬†¬†¬† That should be doable and will result in a fun little space trading game program (without fancy graphics though)

  • Like 2

Share this post


Link to post
Share on other sites

I see. You can add spinning 3D ships to the same project as an encyclopedia entries.

  • Like 1

Share this post


Link to post
Share on other sites

Awesome! ūüėĄ

I'm new here, and I don't have time to experiment until the weekend, but something I wanted to try was making a fixed-point math library with some vector-matrix-mult routines. I think you have beaten me to the punch on that! ūüėČ

Share this post


Link to post
Share on other sites

For this program I am not using a fixed point math library perse.  The math library that I use only has primitives for calculations on byte and word values.

The program   (written in prog8) does the actual 3d calculations taking fixed-point scaling into account.  So a hand written math library with 3d routines as well is still useful as it will be quite a bit faster that my generated assembly code I can imagine.

Share this post


Link to post
Share on other sites

Slight update, I'm slowly working towards adding that hidden line removal. The actual math required isn't in there yet but I think I have the ship model data complete for it.

image.png.43d232d5e1232f0ea1137eeca00f2e90.png

Also I've looked at the source code of the text-Elite and it seems a lot more work to convert it to Prog8 than I anticipated. It is still something I would like to complete though, if only to validate the practical applicability of the language.

Share this post


Link to post
Share on other sites

I remember doing this on the Amiga a long time ago. I had great help by the book "Atari ST 3D Graphichs Programming" (https://archive.org/details/Atari_ST-3D_Graphics_Programming/mode/2up). Of course, the programming examples are in 68000 assembler but there are also lengthy explanations of concepts and methods. If you are familiar with linear algebra, it really helps.

When it comes to hidden line removal, a method that is discussed in the book is to calculate the normal vector of each plane (polygon). If the vector points towards the viewer, the plane is visible, if it points away from the viewer, the plane is hidden. The limitation is that this only works on convex bodies. (On concave bodies planes can be partially visible.) If you ever wondered why all ships in Elite are convex bodies I bet it is because this method is used : ).

Another method is to simply sort the planes and then draw the furthest plane first and the closest last. It works well on for example mathematically rendered 3D landscapes where it makes sense of talking of the planes as positioned in a specific order. If I take a guess, this is the method the game "Virus" used. 

Edited by Johan Kårlin
  • Like 1

Share this post


Link to post
Share on other sites

Yeah the surface normal method is what I experimented with in my Python prototype shown above. It works fairly well and is quite cheap to do however it's not entirely accurate in the simplified version that I came up with.  I only check of the Z component is negative or positive and it works "most of the time" but fails for some polygons that are perspective projected.  I think it's acceptable though at least for a first solution!

As I'm only drawing lines not full surfaces the painter algorithm (back-to-front drawing) can't be used I think.

Share this post


Link to post
Share on other sites

New version available, here we go,  hidden line removal based on that simple surface normal discussed above:

image.png.2f0df4ad3b0d2e3a4585a9b76b42df6b.png

 

Adding more ships to the program and making a slide show of them is currently not possible due to programming language limitations of Prog8, unfortunately (everything has to be statically allocated)

  • Like 2

Share this post


Link to post
Share on other sites

Actually there was some recent and monumental work on documenting the original assembler of the BBC ELITE. The great stuff is, the BBC computer had a 6502 as well and all the MATH code and all the graphics code could be reused simply.

Obviously the draw routines need rework (e.g. the screen setup and output) and the sound as well. But if you ignore sound for now, and adapt the draw routines for the Vera, it should be possible to get the start screen working - e.g. your spinning ship with line removal ūüôā

This is two masterpieces .. the longer I look at the Elite Source code ... wow ... and those guys were still in school or university at that time. And the comments is another masterpiece. I never have seen a better commented source code with actual explanations on how the engine worked. That includes all the math routines, how the backface culling works and alot of that stuff. It also completely explains the main game loop, how it works and so you can learn a lot by reading this.

The commenting has been done by Mark Moxon (of cause with a lot of help by others).

https://raw.githubusercontent.com/markmoxon/elite-beebasm/master/sources/elite-source.asm

This is the original definition of a MK3 btw:
 

Quote

\ ******************************************************************************
\
\       Name: SHIP5
\       Type: Variable
\   Category: Drawing ships
\    Summary: Ship blueprint for a Cobra Mk III
\
\ ******************************************************************************

.SHIP5

 EQUB 3                 \ Max. canisters on demise = 3
 EQUW 95 * 95           \ Targetable area          = 95 * 95
 EQUB &BC               \ Edges data offset (low)  = &00BC
 EQUB &54               \ Faces data offset (low)  = &0154
 EQUB 153               \ Max. edge count          = (153 - 1) / 4 = 38
 EQUB 84                \ Gun vertex               = 84 / 4 = 21
 EQUB 42                \ Explosion count          = 9, as (4 * n) + 6 = 42
 EQUB 168               \ Number of vertices       = 168 / 6 = 28
 EQUB 38                \ Number of edges          = 38
 EQUW 0                 \ Bounty                   = 0
 EQUB 52                \ Number of faces          = 52 / 4 = 13
 EQUB 50                \ Visibility distance      = 50
 EQUB 150               \ Max. energy              = 150
 EQUB 28                \ Max. speed               = 28
 EQUB &00               \ Edges data offset (high) = &00BC
 EQUB &01               \ Faces data offset (high) = &0154
 EQUB 1                 \ Normals are scaled by    = 2^1 = 2
 EQUB %00010011         \ Laser power              = 2
                        \ Missiles                 = 3

\VERTEX    x,    y,    z, face1, face2, face3, face4, visibility
 VERTEX   32,    0,   76,    15,     15,   15,    15,         31    \ Vertex 0
 VERTEX  -32,    0,   76,    15,     15,   15,    15,         31    \ Vertex 1
 VERTEX    0,   26,   24,    15,     15,   15,    15,         31    \ Vertex 2
 VERTEX -120,   -3,   -8,     3,      7,   10,    10,         31    \ Vertex 3
 VERTEX  120,   -3,   -8,     4,      8,   12,    12,         31    \ Vertex 4
 VERTEX  -88,   16,  -40,    15,     15,   15,    15,         31    \ Vertex 5
 VERTEX   88,   16,  -40,    15,     15,   15,    15,         31    \ Vertex 6
 VERTEX  128,   -8,  -40,     8,      9,   12,    12,         31    \ Vertex 7
 VERTEX -128,   -8,  -40,     7,      9,   10,    10,         31    \ Vertex 8
 VERTEX    0,   26,  -40,     5,      6,    9,     9,         31    \ Vertex 9
 VERTEX  -32,  -24,  -40,     9,     10,   11,    11,         31    \ Vertex 10
 VERTEX   32,  -24,  -40,     9,     11,   12,    12,         31    \ Vertex 11
 VERTEX  -36,    8,  -40,     9,      9,    9,     9,         20    \ Vertex 12
 VERTEX   -8,   12,  -40,     9,      9,    9,     9,         20    \ Vertex 13
 VERTEX    8,   12,  -40,     9,      9,    9,     9,         20    \ Vertex 14
 VERTEX   36,    8,  -40,     9,      9,    9,     9,         20    \ Vertex 15
 VERTEX   36,  -12,  -40,     9,      9,    9,     9,         20    \ Vertex 16
 VERTEX    8,  -16,  -40,     9,      9,    9,     9,         20    \ Vertex 17
 VERTEX   -8,  -16,  -40,     9,      9,    9,     9,         20    \ Vertex 18
 VERTEX  -36,  -12,  -40,     9,      9,    9,     9,         20    \ Vertex 19
 VERTEX    0,    0,   76,     0,     11,   11,    11,          6    \ Vertex 20
 VERTEX    0,    0,   90,     0,     11,   11,    11,         31    \ Vertex 21
 VERTEX  -80,   -6,  -40,     9,      9,    9,     9,          8    \ Vertex 22
 VERTEX  -80,    6,  -40,     9,      9,    9,     9,          8    \ Vertex 23
 VERTEX  -88,    0,  -40,     9,      9,    9,     9,          6    \ Vertex 24
 VERTEX   80,    6,  -40,     9,      9,    9,     9,          8    \ Vertex 25
 VERTEX   88,    0,  -40,     9,      9,    9,     9,          6    \ Vertex 26
 VERTEX   80,   -6,  -40,     9,      9,    9,     9,          8    \ Vertex 27

\EDGE vertex1, vertex2, face1, face2, visibility
 EDGE       0,       1,     0,    11,         31    \ Edge 0
 EDGE       0,       4,     4,    12,         31    \ Edge 1
 EDGE       1,       3,     3,    10,         31    \ Edge 2
 EDGE       3,       8,     7,    10,         31    \ Edge 3
 EDGE       4,       7,     8,    12,         31    \ Edge 4
 EDGE       6,       7,     8,     9,         31    \ Edge 5
 EDGE       6,       9,     6,     9,         31    \ Edge 6
 EDGE       5,       9,     5,     9,         31    \ Edge 7
 EDGE       5,       8,     7,     9,         31    \ Edge 8
 EDGE       2,       5,     1,     5,         31    \ Edge 9
 EDGE       2,       6,     2,     6,         31    \ Edge 10
 EDGE       3,       5,     3,     7,         31    \ Edge 11
 EDGE       4,       6,     4,     8,         31    \ Edge 12
 EDGE       1,       2,     0,     1,         31    \ Edge 13
 EDGE       0,       2,     0,     2,         31    \ Edge 14
 EDGE       8,      10,     9,    10,         31    \ Edge 15
 EDGE      10,      11,     9,    11,         31    \ Edge 16
 EDGE       7,      11,     9,    12,         31    \ Edge 17
 EDGE       1,      10,    10,    11,         31    \ Edge 18
 EDGE       0,      11,    11,    12,         31    \ Edge 19
 EDGE       1,       5,     1,     3,         29    \ Edge 20
 EDGE       0,       6,     2,     4,         29    \ Edge 21
 EDGE      20,      21,     0,    11,          6    \ Edge 22
 EDGE      12,      13,     9,     9,         20    \ Edge 23
 EDGE      18,      19,     9,     9,         20    \ Edge 24
 EDGE      14,      15,     9,     9,         20    \ Edge 25
 EDGE      16,      17,     9,     9,         20    \ Edge 26
 EDGE      15,      16,     9,     9,         19    \ Edge 27
 EDGE      14,      17,     9,     9,         17    \ Edge 28
 EDGE      13,      18,     9,     9,         19    \ Edge 29
 EDGE      12,      19,     9,     9,         19    \ Edge 30
 EDGE       2,       9,     5,     6,         30    \ Edge 31
 EDGE      22,      24,     9,     9,          6    \ Edge 32
 EDGE      23,      24,     9,     9,          6    \ Edge 33
 EDGE      22,      23,     9,     9,          8    \ Edge 34
 EDGE      25,      26,     9,     9,          6    \ Edge 35
 EDGE      26,      27,     9,     9,          6    \ Edge 36
 EDGE      25,      27,     9,     9,          8    \ Edge 37

\FACE normal_x, normal_y, normal_z, visibility
 FACE        0,       62,       31,         31    \ Face 0
 FACE      -18,       55,       16,         31    \ Face 1
 FACE       18,       55,       16,         31    \ Face 2
 FACE      -16,       52,       14,         31    \ Face 3
 FACE       16,       52,       14,         31    \ Face 4
 FACE      -14,       47,        0,         31    \ Face 5
 FACE       14,       47,        0,         31    \ Face 6
 FACE      -61,      102,        0,         31    \ Face 7
 FACE       61,      102,        0,         31    \ Face 8
 FACE        0,        0,      -80,         31    \ Face 9
 FACE       -7,      -42,        9,         31    \ Face 10
 FACE        0,      -30,        6,         31    \ Face 11
 FACE        7,      -42,        9,         31    \ Face 12

 

Edited by SerErris
  • Like 1

Share this post


Link to post
Share on other sites
On 9/18/2020 at 10:29 AM, desertfish said:

Yeah the surface normal method is what I experimented with in my Python prototype shown above. It works fairly well and is quite cheap to do however it's not entirely accurate in the simplified version that I came up with.  I only check of the Z component is negative or positive and it works "most of the time" but fails for some polygons that are perspective projected.  I think it's acceptable though at least for a first solution!

As I'm only drawing lines not full surfaces the painter algorithm (back-to-front drawing) can't be used I think.

This is what Ian Bell and David Braben created (explained by Mark)

Quote

\ ******************************************************************************
\
\       Name: LL9 (Part 5 of 11)
\       Type: Subroutine
\   Category: Drawing ships
\    Summary: Draw ship: Calculate the visibility of each of the ship's faces
\
\ ******************************************************************************
\
\ Deep dive: Back-face culling
\ ============================
\
\ One of the reasons that Elite's 3D wireframe ships look so good is because
\ you can't see through them - they look genuinely solid. This is down to a
\ process called "back-face culling", a mathematical process that works out
\ which faces of the ship are visible to the viewer and which ones aren't. It
\ then discards (or "culls") any faces that aren't visible and only draws those
\ that we can actually see. This prevents the wireframes from being see-through,
\ and this gives the ships a real sense of solidity.
\
\ The main principle behind back-face culling is the dot product. This simple
\ mathematical operation takes two vectors and produces a scalar value that is
\ in essence a kind of mathematical application of one vector to the other, of
\ taking the "essence" of one vector and applying it to another. For the
\ purposes of back-face culling in Elite, we use the dot product in two distinct
\ ways.

This is just the summary, In the source is following long and long discussion on the details of that. 

  • Thanks 1

Share this post


Link to post
Share on other sites

I am really considering now to port it to X16 ... It is still a huge endeavour ... but it is getting possible now.

  • Like 2

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


√ó
√ó
  • Create New...

Important Information

Please review our Terms of Use