Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 09:50 29 Apr 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : CMM2: V5.06.00b7 - 3D engine

     Page 2 of 6    
Author Message
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1082
Posted: 04:11am 30 Nov 2020
Copy link to clipboard 
Print this post

  matherp said  
  Quote  Perhaps I am viewing things from the wrong perspective


You are

Excellent! Your vision is sinking into my noggin. Thank you for the description.

Will the camera always be at elevation = 0 and aimed at the origin?

When a new object is SHOWn (or WRITEn), will all previously SHOWn objects be (selectively?) redrawn to account for objects being in front of or behind other objects?
Visit Vegipete's *Mite Library for cool programs.
 
LeoNicolas

Guru

Joined: 07/10/2020
Location: Canada
Posts: 445
Posted: 05:15am 30 Nov 2020
Copy link to clipboard 
Print this post

Hey VegiPete

Did you see my video about the issues I'm having when running the examples shared by Peter?
Are you having the same result? If not, could you share a video with the expected behaviour for the two examples?

https://youtu.be/lR_S-7ncXVk
Thank you
Edited 2020-11-30 15:15 by LeoNicolas
 
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1082
Posted: 06:35am 30 Nov 2020
Copy link to clipboard 
Print this post

I just watched the video again. It looks like the problem is that MATH Q-CREATE won't accept values returned by functions?

I haven't tried any of this myself yet. I've been crashing together a 3D object viewer - see my new thread.
Visit Vegipete's *Mite Library for cool programs.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8583
Posted: 08:04am 30 Nov 2020
Copy link to clipboard 
Print this post

  Quote  It looks like the problem is that MATH Q-CREATE won't accept values returned by functions?

Q_CREATE uses Geoff's standard code so will definitely accept any expression including function returns. However, there is definitely a problem of some sort. I'll have a play later today.
The bigger problem is in the perspective calculations of off axis objects so that is the main task to understand and fix.
I don't understand the 4x4 matrix in Leo's post which may be part of the solution. How would I use it when vertices only have three coordinates?
Edited 2020-11-30 18:09 by matherp
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 3845
Posted: 12:02pm 30 Nov 2020
Copy link to clipboard 
Print this post

Sorry Peter, even with beta 8 there is still some fraying in SORT's behaviour at the boundary conditions:

Colour Maximite 2
MMBasic Version 5.06.00b8
Copyright 2011-2020 Geoff Graham
Copyright 2016-2020 Peter Mather

> list "sort_bug_3.bas"
Option Explicit On
Option Default None

Dim base% = 0
If InStr(Mm.CmdLine$, "base=1") Then base% = 1
Option Base base%

Dim i%, j%
Dim data$(base% + 4) = ("one", "two", "three", "four", "five")

Print "Option Base =" base%
For i% = base% To base% + 4
 Print "Sort element" i% ": ";

 ' I know sorting a single element is "nonsense" but you can be "sure as eggs
 ' is eggs" that at some point some program is going to work on some piece of
 ' user supplied input that involves this edge case.
 Sort data$(), , , i%, 1

 For j% = base% To base% + 4 : Print data$(j%) " "; : Next j% : Print
Next

> *sort_bug_3
Option Base = 0
Sort element 0: one two three four five
Sort element 1: one two three four five
Sort element 2: one two three four five
Sort element 3: one two three four five
Sort element 4:

Error in line 14: 4 is invalid (valid is 0 to 3)

> *sort_bug_3 base=1
Option Base = 1
Sort element 1: one two three four five
Sort element 2: one two three four five
Sort element 3: one two three four five
Sort element 4:

Error in line 14: 4 is invalid (valid is 1 to 3)


Best wishes,

Tom
Edited 2020-11-30 22:04 by thwill
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8583
Posted: 02:59pm 30 Nov 2020
Copy link to clipboard 
Print this post

V5.06.00b9

http://geoffg.net/Downloads/Maximite/CMM2_Beta.zip

This has a major re-write of the 3D projection logic and is looking much better. One big gotcha was that the world has the y-axis pointing up and the screen has coordinates 0,0 at top left. This is now hopefully corrected.

This site was very useful in getting the projection correct.

Here is another demo that was very useful in getting to the projection issues and fixing them. The white dot represents the camera position (albeit a Z=0). Play with the camera position in this demo if you really want to confuse yourself - I think what gets displayed is correct but it is very hard to visualise and understand why the image looks like it does in some cases.

Some of the other demos need tweaking now the projection is correct but I'll leave this to you to play with.





option explicit
option default none
option base 0
DIM INTEGER x=0,y,z,layer=0
DIM FLOAT Q(4), yaw=0, pitch=0, roll=0
const camerax=500, cameray=mm.vres-2, viewplane=600
dim integer nv=8, nf=6 ' cube has 8 vertices and 6 faces
const camera1 = 1
dim float vertices(2,7) = (-1,1,-1,  1,1,-1,  1,-1,-1,  -1,-1,-1,  -1,1,1,  1,1,1,  1,-1,1,  -1,-1,1) 'define the vertices of the cube
dim integer fc(5)=(4,4,4,4,4,4) ' define the number of vertices in each face
dim integer faces(23)=(0,1,2,3,  1,5,6,2,  0,4,5,1,  5,4,7,6,  2,6,7,3, 0,3,7,4) 'define the vertices that make up each face
dim integer colours(6)=(rgb(blue), rgb(green), rgb(magenta), rgb(cyan), rgb(red), rgb(brown), rgb(yellow)) 'define our colour palette
dim integer edge(5)=(6,6,6,6,6,6) 'define the colours used for the edges of each face
dim integer fill(5)=(0,1,2,3,4,5) 'define the colours used to fill each face
'
MATH SCALE vertices(), 20, vertices()
'rescale the z dimension by 2
dim float slice(7)
math slice vertices(),2,,slice()
math scale slice(),2,slice()
math insert vertices(),2,,slice()
DRAW3D CREATE 1, nv, nf, camera1, vertices(), fc(), faces(), colours(), edge(), fill()
DRAW3D CAMERA 1, viewplane, camerax, cameray
PAGE WRITE 1
circle camerax,mm.vres-cameray,4,,,rgb(white),rgb(white)
for y=50 to 550 step 45
for z=0 to 960 step 85
DRAW3D write 1,x,y,1600-z+layer
pause 500
page copy 1 to 0
next z
if layer=0 then
 layer=40
else
 layer=0
endif
next y
do:loop
 
chris
Regular Member

Joined: 24/08/2020
Location: United Kingdom
Posts: 54
Posted: 03:56pm 30 Nov 2020
Copy link to clipboard 
Print this post

I can imagine this being so useful in computing education.
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 3845
Posted: 04:12pm 30 Nov 2020
Copy link to clipboard 
Print this post

  matherp said  V5.06.00b9

http://geoffg.net/Downloads/Maximite/CMM2_Beta.zip


You're killing me, or I'm killing you, you've fixed one bug and I think (as far as string arrays and my unit-tests for SORT go) there is only one bug left.

Using the same example as before, run with the base=1 command line argument:

Colour Maximite 2
MMBasic Version 5.06.00b9
Copyright 2011-2020 Geoff Graham
Copyright 2016-2020 Peter Mather

> *sort_bug_3 base=1
Option Base = 1
Sort element 1: one two three four five
Sort element 2: one two three four five
Sort element 3: one two three four five
Sort element 4: one two three four five
Sort element 5:

Error in line 18: 5 is invalid (valid is 1 to 4)


Best wishes,

Tom
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1082
Posted: 06:57pm 30 Nov 2020
Copy link to clipboard 
Print this post

  matherp said  I don't understand the 4x4 matrix in Leo's post which may be part of the solution. How would I use it when vertices only have three coordinates?

The search term is "homogeneous coordinates" Generally, you add a 4th coordinate to each vertex, with a value of 1.
Visit Vegipete's *Mite Library for cool programs.
 
qwerty823
Newbie

Joined: 30/07/2020
Location: United States
Posts: 30
Posted: 09:57pm 30 Nov 2020
Copy link to clipboard 
Print this post

  matherp said  Objects can have a maximum of 64 vertices and 64 faces.


Is there a reason for this limit?

I was looking at some of the "ply" files in the DemoX code, and MANY of these are above those limits, and I can understand the performance constraints with having very high number of vertices/faces, but the 64/64 limit seems quite constraining.
 
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1082
Posted: 02:10am 01 Dec 2020
Copy link to clipboard 
Print this post

This 3D engine is fun stuff!

Peter gave us a brick wall above. But I wanted a curved wall:



There is an obvious problem in that I have to draw the bricks from farthest to nearest. (Ugghh)

A less obvious problem is in the projection. The blue faces of the bricks on the right side in particular look far too square. Something seems wrong with the projection. Have I set the viewing plane or viewing distance too near or too far?

CurvedBrickWall.zip
Visit Vegipete's *Mite Library for cool programs.
 
LeoNicolas

Guru

Joined: 07/10/2020
Location: Canada
Posts: 445
Posted: 05:25am 01 Dec 2020
Copy link to clipboard 
Print this post

Nice curved wall VegiPete. It seems that the Painter's Algorithm is wrong for the right side of the wall.
I also sow a rendering problem in the octahedron example.

The right side of the left octahedron is being cut by the right octahedron.

The beta 9 solved the camera movement problem.


Edited 2020-12-01 15:28 by LeoNicolas
 
LeoNicolas

Guru

Joined: 07/10/2020
Location: Canada
Posts: 445
Posted: 06:13am 01 Dec 2020
Copy link to clipboard 
Print this post

  vegipete said  
  matherp said  I don't understand the 4x4 matrix in Leo's post which may be part of the solution. How would I use it when vertices only have three coordinates?

The search term is "homogeneous coordinates" Generally, you add a 4th coordinate to each vertex, with a value of 1.


This video explains in detail the 4th element in the position vector and the 4th column in the projection matrix. I love this guy's videos, he explains how to create a 3D engine from scratch and the math behind it.

https://www.youtube.com/watch?v=ih20l3pJoeU&ab_channel=javidx9
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8583
Posted: 09:39am 01 Dec 2020
Copy link to clipboard 
Print this post

V5.06.00b10

http://geoffg.net/Downloads/Maximite/CMM2_Beta.zip

This version does a bit of tidying up and performance tuning of the DRAW3D command.

In addition it includes a new flood fill sub command

PIXEL FILL x, y, newcolour


This command reads the pixel at x, y and then replaces it and all contiguous pixels with the same colour with "newcolour"

The code uses the recursive approach but temporarily moves the H/W stack pointer into SDRAM in order to maximise the depth of recursion available. In the event the stack is exhausted the fill will simply terminate safely with some pixels left unfilled. The fill algorithm is capable of completely filling the screen in 640x480 resolution but won't completely fill the screen in 800x600

Also see this thread for details of a minor tweak to the GETSCANLINE function

Finally, b10 includes a new DRAW3D function


DRAW3D(xmin n)'returns the leftmost x coordinate of a box bounding the render of 3d object n on the screen
DRAW3D(xmax n)'returns the rightmost x coordinate of a box bounding the render of 3d object n on the screen
DRAW3D(ymin n)'returns the upper y coordinate of a box bounding the render of 3d object n on the screen
DRAW3D(ymax n)'returns the lower y coordinate of a box bounding the render of 3d
object n on the screen
DRAW3D(x n)'returns the x coordinate in the world current used to display 3D object n
DRAW3D(y n)'returns the y coordinate in the world current used to display 3D object n
DRAW3D(z n)'returns the y coordinate in the world current used to display 3D object n


e.g.

option explicit
option default float
dim integer viewplane = 500
const camera = 1
dim q(4)
dim yaw=rad(1),pitch=rad(2),roll=rad(0.5)
dim integer nv=9, nf=9 ' cube has 9 vertices and 9 faces
'array to hold vertices
dim v(2,nv-1)=(-1,1,-1,  1,1,-1, 1,-1,-1, -1,-1,-1, -1,1,1, 1,1,1, 1,-1,1,  -1,-1,1, 0,0,0)
math scale v(),200,v()
' array to hold number of vertices for each face
dim integer fc(nf-1) =(4,4,4,4,4,3,3,3,3)
dim integer cindex(9)=(rgb(red),rgb(blue),rgb(green),rgb(magenta),rgb(yellow),rgb(cyan),rgb(white),rgb(brown),rgb(gray),0)
dim integer fcol(nf-1)=(9,9,9,9,9,9,9,9,9)
dim integer bcol(nf-1)=(0,1,2,3,4,5,6,7,8)
'array to hold vertices for each face
dim integer fv(math(sum fc())-1)=(1,5,6,2, 1,0,4,5,  0,3,7,4,  5,4,7,6, 2,6,7,3, 0,1,8, 1,2,8, 3,8,2 , 3,0,8)
draw3d create 1, nv, nf, camera, v(), fc(), fv(),cindex(),fcol(),bcol()
dim integer c
page write 1
draw3d camera 1,viewplane, mm.hres\2, mm.vres\2
do
for c=0 to 720
timer=0
 math q_create roll,1,1,1,q()
 draw3d show 1,mm.hres\2,mm.vres\2,1000
'  math q_euler yaw,pitch,roll,q()
 draw3d rotate q(),1
print  @(0,0)draw3d(XMIN 1),@(64)draw3d(xmax 1),@(128)draw3d(ymin 1),@(192)draw3d(ymax 1)
'  inc yaw,rad(1)
'  inc pitch,rad(2)
 inc roll,rad(0.5)
 page copy 1 to 0,b
next
loop
draw3d close all


  Quote  I also sow a rendering problem in the octahedron example.


This is because the example code is incorrect and needs fixings for the corrected rendering
Edited 2020-12-01 20:04 by matherp
 
jirsoft

Guru

Joined: 18/09/2020
Location: Czech Republic
Posts: 532
Posted: 10:11am 01 Dec 2020
Copy link to clipboard 
Print this post

  Quote  PIXEL FILL x, y, newcolour


This command reads the pixel at x, y and then replaces it and all contiguous pixels with the same colour with "newcolour"

The code uses the recursive approach but temporarily moves the H/W stack pointer into SDRAM in order to maximise the depth of recursion available. In the event the stack is exhausted the fill will simply terminate safely with some pixels left unfilled. The fill algorithm is capable of completely filling the screen in 640x480 resolution but won't completely fill the screen in 800x600


Maybe the scanline fill could be better, it was used in 8 bit era... And I remember in final step the draw line could be changed to get line from pattern sample, so it can not just colors but also patterns...
Jiri
Napoleon Commander and SimplEd for CMM2 (GitHub),  CMM2.fun
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 3845
Posted: 10:51am 01 Dec 2020
Copy link to clipboard 
Print this post

Yay:



Thank you for your perseverence Peter.

And also thank you for adding flood fill.

Best wishes,

Tom
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
mkopack73
Senior Member

Joined: 03/07/2020
Location: United States
Posts: 261
Posted: 01:34pm 01 Dec 2020
Copy link to clipboard 
Print this post

Tom, LOVE that you set up a unit test framework!!  Probably not as useful for visual things (ie how do you automatically test to see if the result of graphical commands are correct?) but still very useful for running through the various other commands and ensuring that they haven’t broken or changed in behavior.  I know the Java developers use a similar huge set of tests as they develop the language to ensure they didn’t break things as they add new capabilities in, and to test that new features are working as intended.

I really need to pull down your tools and have a go with them.. Just need to find some time to devote to CMM2 stuff...
 
mkopack73
Senior Member

Joined: 03/07/2020
Location: United States
Posts: 261
Posted: 01:37pm 01 Dec 2020
Copy link to clipboard 
Print this post

And should also say that Peter I love where you are going with this! This is very much in line with what I had wanted to develop myself, just didn’t have the time...(too many other projects!!!)

Question about the 64 vertices /64 faces - is that total for the object or is it 64 vertices PER face? (So a total of 64*64 vertices possible?)
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 3845
Posted: 02:20pm 01 Dec 2020
Copy link to clipboard 
Print this post

  mkopack73 said  Tom, LOVE that you set up a unit test framework!!  ...
I really need to pull down your tools and have a go with them ...


Thanks.

My tools are very much under active development at the moment. If you do pull the code then make sure it is from https://github.com/thwill1000/sptools/tree/develop-r1b3 and not the "master" branch which is very out of date. Please also be aware that since it is a single-developer project I am being "naughty" and doing updates with forced pushes to that branch, something I would never do in "master" or shard branches in public projects.

Best wishes,

Tom
Edited 2020-12-02 00:22 by thwill
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8583
Posted: 02:32pm 01 Dec 2020
Copy link to clipboard 
Print this post

Minor update to the PIXEL FILL posted at 14:32 UTC - no version change. Much faster and no obvious size limits

For anyone interested below is the fill algorithm

void floodFillScanline(int x, int y)
{
 if(filloldcolour == fillnewcolour) return;
 if(ReadPixelFast(x,y) != filloldcolour) return;

 int x1;

 //draw current scanline from start position to the right
 x1 = x;
 while(x1 < fillmaxW && ReadPixelFast(x1, y) == filloldcolour)
 {
   DrawPixelFast(x1,y,fillnewcolour);
   x1++;
 }

 //draw current scanline from start position to the left
 x1 = x - 1;
 while(x1 >= 0 && ReadPixelFast(x1, y) == filloldcolour)
 {
   DrawPixelFast(x1, y,fillnewcolour);
   x1--;
 }

 //test for new scanlines above
 x1 = x;
 while(x1 < fillmaxW && ReadPixelFast(x1, y) == fillnewcolour)
 {
   if(y > 0 && ReadPixelFast(x1, (y - 1)) == filloldcolour)
   {
     floodFillScanline(x1, y - 1);
   }
   x1++;
 }
 x1 = x - 1;
 while(x1 >= 0 && ReadPixelFast(x1, y ) == fillnewcolour)
 {
   if(y > 0 && ReadPixelFast(x1, (y - 1)) == filloldcolour)
   {
     floodFillScanline( x1, y - 1);
   }
   x1--;
 }

 //test for new scanlines below
 x1 = x;
 while(x1 < fillmaxW && ReadPixelFast(x1, y) == fillnewcolour)
 {
   if(y < fillmaxH - 1 && ReadPixelFast(x1, (y + 1)) == filloldcolour)
   {
     floodFillScanline( x1, y + 1);
   }
   x1++;
 }
 x1 = x - 1;
 while(x1 >= 0 && ReadPixelFast(x1, y) == fillnewcolour)
 {
   if(y < fillmaxH - 1 && ReadPixelFast(x1, (y + 1)) == filloldcolour)
   {
     floodFillScanline(x1, y + 1);
   }
   x1--;
 }
}

Edited 2020-12-02 00:44 by matherp
 
     Page 2 of 6    
Print this page
© JAQ Software 2024