![]() |
Forum Index : Microcontroller and PC projects : CMM2: V5.06.00b7 - 3D engine
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1122 |
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: CanadaPosts: 500 |
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: CanadaPosts: 1122 |
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 KingdomPosts: 10075 |
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 KingdomPosts: 4251 |
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 MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10075 |
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 KingdomPosts: 56 |
I can imagine this being so useful in computing education. |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
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 MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1122 |
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 StatesPosts: 30 |
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: CanadaPosts: 1122 |
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: CanadaPosts: 500 |
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: CanadaPosts: 500 |
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 KingdomPosts: 10075 |
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 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 RepublicPosts: 533 |
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 KingdomPosts: 4251 |
Yay: ![]() Thank you for your perseverence Peter. And also thank you for adding flood fill. Best wishes, Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
mkopack73 Senior Member ![]() Joined: 03/07/2020 Location: United StatesPosts: 261 |
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 StatesPosts: 261 |
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 KingdomPosts: 4251 |
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 MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10075 |
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 |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |