LoginLogin

SIM.3D

Root / Submissions / [.]

SimeonCreated:
Download:HEAEP3
Version:1.5Size:90.4KB

A lightweight yet powerful 3D game engine

[poll=p320][/poll] [poll=p339][/poll]

Instructions:

What's New

_____________________

Version 1.5 - The physics update

  • Although only bounding box physics are currently supported, it has been implemented in such a way that more complex shapes will soon be supported.
  • Many performance improvements
  • Now supports split-screen gameplay as well as quadruple-screen gameplay. Using two or four screens does not noticably change the overall framerate!
  • Added the ability to merge objects into one, and split them (MERGEOBJ,SPLITOBJ).
  • Added object bounding box variables (OBJMINX,Y,Z,OBJMAXX,Y,Z).
  • An object's center is not longer its center of mass, but rather the center of its bounding box.
  • Added a wireframe cube object (called WCUBE) as well as UPDATEWCUBETOOBJ to set the wireframe position ans size to match another object's bounding box.
  • Added CHECKCOLLISION to check every object in the world to check for collisions.
  • Added ISCOLLIDING to check if two objects are intersecting.
  • Added RAYTHROUGHOBJ to check if an infinite ray is intersecting an object.
  • Added COLOROBJAB function to color a specific range of triangles in an object.
  • Added a FLAG object (the main character of 3D Parkour).
  • Added 3D Parkour 2 Alpha as a demo.
  • Instead of typing GCLS:BUFFER:RENDER you now just type RENDER to do everything.
  • GETRAY2D now only takes in X,Z as opposed to X,Y,Z.
  • Added variables to keep track of an object's scale.
  • Added OBJSTR$ variables, which work the same as the OBJTAG$ variables.
  • Added SETSTATICOBJ function to set if an object is affected by physics or not.
  • Added variables to define the velocity for each object.

Version 1.4

  • Added TEXT as a new object type! Check the documentation for more details! Game worlds can easily display messages as 3D objects.
  • CHESS.3D has been worked on, the AI is more intelligent and uses alpha-beta pruning to simulate ahead in the future to find how to maximize the minimum score. In the first few lines you can set the AI_VS_AI to watch it play against itself.
  • Every demo has been updated to make use of the new features.
  • Fixed the randomly-appearing-flickering-lines-bug for DLC users.
  • Fixed triangles-sometimes-not-rendering-glitch for non-DLC users.
  • Also non-DLC users run at a fairly higher framerate due to less function calls.
  • Perspective calculations and rendering have been worked on a lot, graphics are much smoother.
  • Added a new demo to showcase 3D randomized fractal tree generation.
  • Spheres now render without borders to improve the look of scenes.
  • Changed the way object tags work, instead of saving TAG$ to every triangle it saves it in the objects themselves. Also triangles no longer carry a second color (the sphere border color). Triangles only carry the most necessary data now.
  • FPS is more smooth/stabilized.
  • Added the ability to change the view distance to make programs run faster for o3DS users.
  • Added function APPLYSURFACEEQUATION to automatically set a SURFACE object to mimic a mathematical equation. This makes the code for the GRAPH_3D demo much simpler and gives users much more power to simulate terrain.
  • Added lots of new functions!

Version 1.3

  • Added a fully functional 3D chess game against a real AI that looks a few moves ahead to determine the best way to move.
  • Added an first person shooter game demo.
  • Added support for 3D lines using ADDLINE(X1,Y1,Z1,X2,Y2,Z2,COLOR).
  • Added a surface object, which is a grid plane with multiple sections (used in the 3D grapher).
  • Fixed a few bugs when deleting an object.
  • Added some new functions.
  • BUFFERing only buffers the top screen, use BUFFERBOTTOM to buffer the lower screen.
  • Other small tweaks and optimizations.

Version 1.2

  • Framerate has been doubled and possibly tripled, especially for DLC users. The engine runs incredibly fast for users that have purchased the SmileBASIC DLC!
  • SIM.3D no longer needs any other program slots other than 3. So this update makes it a lot more compact and simple.
  • Hue, saturation, and value are now optional by using HSV(H,S,V) just like RGB(R,G,B). Objects only need a single color value to be initialized. So #RED, #GREEN, #BLUE, etc... can work too.
  • Field of view (FOV), world scale constant (WSC), and the cutoff ratio (CUTOFF_RATIO) are modifiable. Cutoff ratio is the ratio between the camera and the object of focus in which polygons will no longer be drawn. Default is 0.5.
  • Lots of new functions that give more power to the user, such as finding the closest/furthest objects to a point, and making an object rotate to face a given point in the world.
  • Behind the scenes optimizations for maximum performance.

Version 1.1

  • DLC is fully implemented! The engine runs much smoother when the Advanced Sound DLC is purchased, the application now only needs to run a few ARYOP operations each frame.
  • Performance without DLC has also been improved, but DLC gives much higher performance.
  • Circles have been removed, and re-implemented as triangle objects. Now that there is complete consistency with objects, huge performance advancements have been made.
  • The flickering graphics bug has been targeted and removed. Graphics feel cleaner with modified algorithms.
  • Example programs have been modified a little bit. Please feel free to view the code for those, and use them to implement your own games. I do not require any credit. Everything is free for everybody.
  • Triangles are now sorted by the furthest away Z point.
  • CIRCLE functions are now called SPHERE functions.
  • All future updates from this point forward will minimize the modifications required for a game to run on the updated engine. Any modifications required will be listed down here for you.

Version 1.0

  • Application is stable.

Notes:

This application was designed specifically to teach the idea of 3D game design. While this engine was built with simplicity in mind, it was also built to maximize efficiency and minimize the computation required to display good looking graphics. With that said this is an excellent engine to make 3D games, I don't ask for any credit, and anyone can use this program for their own purposes. Use the comment section below for help, or if you have any questions, I'll be glad to help! To see the power of SIM.3D, I added some regular demos that will give a better idea on how to use SIM.3D. The files include:
  • 3D.ENGINE - The engine in all it's glory.
  • BOX_O_GEMS - A demo to show all the different kinds of objects, and how fast they render.
  • CHESS.3D - A rather complex program to show what can be made with SIM.3D.
  • FPS_DEMO - A first-person-shooter-styled simulation, on a Perlin-noise-generated map.
  • GRAPH_3D - A powerful yet simple 3D equation grapher.
  • PARKOUR2_ALPHA - The new development of 3D Parkour 2, in alpha state.
  • SIERPINSKI - Using simple code to generate a Sierpinski pyramid.
  • SIMPLE_CUBES - A short code demo to show how SIM.3D is used.
  • SPIRAL_SPHERE - Generate colorful sphere-spirals of spheres.
  • SPLIT_SCREEN - Example of using splitscreen (with 3D Parkour 2 Alpha)
  • TREE_OF_WISDOM - Showcasing three dimensional fractal tree generation using simple recursion.
To use this engine, simply add this to the first line of your code
PRGEDIT 3 EXEC "PRG3:3D.ENGINE" END
Doing so will load the 3D engine into program slot 3, then insert the code from program slot 0 into program slot 3, then execute itself.
the full documentation of SIM.3DThe most basic application to rotate a cube in the center of the screen is as follows:
PRGEDIT 3 EXEC "PRG3:3D.ENGINE" END 'S1M.3D

VAR C=ADDCUBE(0,0,0,1,1,1,#GRAY)
		'C CONTAINS A REFERENCE TO THE CUBE
@LOOP
 VSYNC		'STABALIZE THE FRAMERATE
 ROTOBJ C,0,1,0	'ROTATE THE CUBE AROUND THE Y AXIS
 RENDER		'RENDER THE WORLD
GOTO @LOOP	'REPEAT
There are a few things to be aware of before diving into the 3D engine
  • One in-world unit is the equivalent of 50 pixels from the default camera position. Adding a scale definition like this makes the game feel more realistic. This can be customized by changing the WSC (world scaling constant) variable.
  • When working with SIM.3D, you must work in the default program slot 0, you will need to save every time you run the code. Any errors can be traced to your code in program slot 3 where the actual engine is.
  • Or you could work directly in the 3D engine and avoid the use of the loader. There's a spot in the beginning of the code dedicated for user programs to go.
  • Every object is composed of triangles. If a triangle is defined clockwise then it will be visible from the outside of the object. There are preset objects to make this easier to work with.
  • So triangles can only be seen from one side (for higher performance), using STRETCHOBJ with negative values to stretch an object inside-out will let you see the object's back faces instead of front
  • Every object is given an index. This index will never change until the object is deleted, in which case the ID will be given to the next future object to be defined.
Engine variables:
VAR CAMX,CAMY,CAMZ 'THE FOCUS POSITION OF THE CAMERA (DEFAULT: 0,0,0)
VAR CAMRX,CAMRY,CAMRZ 'ROTATION OF THE CAMERA (IN DEGREES) AROUND THE CAMERA FOCUS (DEFAULT: 0,20,0)
VAR CAMDIST 'DISTANCE AWAY FROM CAMERA'S FOCUS POINT (DEFAULT: 10)
VAR FOV 'FIELD OF VIEW (DEFAULT: 5)
VAR WSC 'WORLD SCALING CONSTANT IN PIXELS (DEFAULT: 50)
VAR CUTOFF_RATIO 'THE RATIO BETWEEN CAMERA AND FOCUS IN WHICH THINGS STOP RENDERING (DEFAULT: 0.7)
VAR BOUNDCAMANGLES 'TRUE/FALSE, TELL IF THE CAMERA SHOULD BE BOUNDED BETWEEN -180 AND 180 (DEFAULT: 1)
VAR RENDERDIST 'HOW FAR THE PLACER CAN SEE, 0=INFINITE (DEFAULT: 0)
VAR ACCELERATED_RENDERING 'TRUE/FALSE TO USE ADVANCED SOUND DLC (DEFAULT: 1 IF POSSIBLE)
VAR FPS 'FRAMES PER SECOND
VAR GMW0,GMH0 'WHERE THE SCREEN STARTS (DEFAULT: 0,0)
VAR GMW1,GMH1 'WHERE THE SCREEN ENDS (DEFAULT: 400,240)
VAR GMW05,GMH05 'DEFINES THE CENTER OF THE SCREEN TO SAVE COMPUTATIONAL OVERHEAD
Here are the preset object definitions:
ADDCUBE(X,Y,Z,LENGTH,WIDTH,HEIGHT,COLOR)
'CREATE A RECTANGULAR PRISM, RETURN ITS INDEX

ADDWCUBE(X,Y,Z,LENGTH,WIDTH,HEIGHT,COLOR)
'CREATE A WIREFRAME RECTANGULAR PRISM, RETURN ITS INDEX

ADDSPHERE(X,Y,Z,RADIUS,COLOR)
'CREATE A SPHERE, RETURN ITS INDEX

ADDLINE(X1,Y1,Z1,X2,Y2,Z2,COLOR)
'CREATE A LINE, RETURN ITS INDEX

ADDPYRAMID(X,Y,Z,WIDTH,HEIGHT,COLOR)
'CREATE A SQUARE PYRAMID, WHERE THE BASE OF THE BOTTOM IS X,Y,Z
'RETURNS THE OBJECT'S INDEX

ADDDIAMOND(X,Y,Z,WIDTH,HEIGHT,COLOR)
'CREATE A DIAMOND SHAPE (A.K.A OCTAHEDRON)
'RETURNS THE OBJECT'S INDEX

ADDCRYSTAL(X,Y,Z,WIDTH,HEIGHT,COLOR)
'CREATE A DIFFERENT TYPE OF "DIAMOND" SHAPE
'RETURNS THE OBJECT'S INDEX

ADDSKYBOX(X,Y,Z,LENGTH,WIDTH,HEIGHT,COLOR)
'CREATE AN INSIDE-OUT CUBE THAT ACTS AS A SKYBOX WHEN LARGE
'RETURNS THE OBJECT'S INDEX

ADDSURFACE(X,Y,Z,GRIDX,GRIDY,LENGTH,WIDTH,COLOR)
'CREATE A FLAT GRID PLANE THAT CAN HAVE MATH EQUATIONS APPLIED TO IT
'RETURNS ITS INDEX

ADDFLAG(X,Y,Z,COLOR)
'CREATE A FLAG CHARACTER OBJECT (FROM 3D PARKOUR)
'RETURNS ITS INDEX

ADDTEXT X,Y,Z,TEXT$,COLOR
'MAKE A TEXT OBJECT IN THE WORLD
'RETURNS THE OBJECT'S INDEX
You may also consider defining your own object
ADDOBJ(TYPE$,X[],Y[],Z[],COLOR)
'X[],Y[],Z[] DEFINE EACH TRIANGLE. THESE ARRAYS MUST BE IN SETS OF 3, SO LENGTH=3,6,9,12,15,18,...
Every object contains these variables:
OBJX 'CENTER OF MASS X POSITION
OBJY 'CENTER OF MASS Y POSITION
OBJZ 'CENTER OF MASS Z POSITION
OBJTEXT$ 'A STRING (USED IN TEXT OBJECTS)
OBJTAG$ 'A STRING
ONJTYPE$ 'A STRING TELLING WHAT TYPE OF OBJECT IT IS
OBJINDEX 'THE INDEX POINTING TO WHICH TRIANGLES BELONG TO THIS OBJECT
OBJLENGTH 'THE LENGTH OF HOW MANY TRIANGLES BELONG TO THIS OBJECT
OBJRX 'GET (NO SET) THE OBJECT'S X ROTATION
OBJRY 'GET (NO SET) THE OBJECT'S Y ROTATION
OBJRZ 'GET (NO SET) THE OBJECT'S Z ROTATION
OBJSX 'GET (NO SET) THE OBJECT'S X SCALE (WIDTH)
OBJSY 'GET (NO SET) THE OBJECT'S Y SCALE (HEIGHT)
OBJRZ 'GET (NO SET) THE OBJECT'S Z SCALE (LENGTH)
OBJMINX 'GET (NO SET) THE OBJECT'S MINIMUM X VALUE
OBJMINY 'GET (NO SET) THE OBJECT'S MINIMUM Y VALUE
OBJMINZ 'GET (NO SET) THE OBJECT'S MINIMUM Z VALUE
OBJMAXX 'GET (NO SET) THE OBJECT'S MAXIMUM X VALUE
OBJMAXY 'GET (NO SET) THE OBJECT'S MAXIMUM Y VALUE
OBJMAXZ 'GET (NO SET) THE OBJECT'S MAXIMUM Z VALUE
OBJVX 'THE OBJECT'S X VELOCITY
OBJVY 'THE OBJECT'S Y VELOCITY
OBJVZ 'THE OBJECT'S Z VELOCITY
OBJVISSTATIC 'TRUE/FALSE, IF THE OBJECT IS AFFECTED BY PHYSICS

OBJMASK 'WHEN YOU DEFINE AN OBJECT YOU ARE GIVEN A MASK INDEX WHICH WILL NEVER
'CHANGE, SO YOU CAN ONLY ACCESS THE VARIABLES ABOVE BY GOING THROUGH THE OBJECT MASK
'FIRST:
OBX[OBJMASK[MY_OBJECT_INDEX]]=FOO
'BY USING THIS MASK, WE CAN GUARANTEE THAT AN OBJECT INDEX WILL NEVER CHANGE
'EVEN IF OBJECTS BEFORE IT ARE DELETED.
Here is a list of object functions
STRETCHOBJ INDEX,SCALEX,SCALEY,SCALEZ
'SQUISHES OR STRETCHES AN OBJECT'S POINTS BY A GIVEN SCALE

MOVEOBJ INDEX,DX,DY,DZ
'INCREMENT AN OBJECT'S POSITION RELATIVE TO ITS CURRENT POSITION

MOVEOBJTO INDEX,X,Y,Z
'TELEPORT AN OBJECT SOMEWHERE (NOT RELATIVE)

ROTOBJ INDEX,AX,AY,AZ
'INCREMENT THE ROTATION OF AN OBJECT AROUND ITS CENTER OF MASS RELATIVE TO ITS CURRENT ROTATION

ROTOBJTO INDEX,AX,AY,AZ
'SET THE ROTATION OF AN OBJECT AROUND ITS CENTER OF MASS (NOT RELATIVE)
'THIS WILL RESET THE OBJECT'S ROTATION TO ITS DEFAULT, THEN ROTATE IT AX,AY,AZ

ROTOBJAROUND INDEX,X,Y,Z,AX,AY,AZ
'ROTATE AN OBJECT AROUND (X,Y,Z)

ROTOBJAROUNDOBJ INDEX,INDEX2,AX,AY,AZ
'ROTATE AN OBJECT AROUND ANOTHER OBJECT

ROTOBJTOPOINT INDEX,X,Y,Z
'ROTATE AN OBJECT SO THAT IT FACES THE POINT X,Y,Z

MERGEOBJS(INDEX1,INDEX2)
'MERGE TWO OBJECTS INTO ONE, RETURNS THE NEW INDEX

SPLITOBJ INDEX,TRIANGLES OUT INDEX1,INDEX2
'SPLIT AN OBJECT AT A TRIANGLE INDEX, DEFINING THE AMOUNT OF TRIANGLES FOR THE FIRST OBJECT

DELOBJ INDEX : INDEX=-1
'DELETE AN OBJECT FROM THE WORLD
'THEN IT IS RECOMMENDED TO SET THE INDEX TO -1

CHANGEOBJCOLOR INDEX,COLOR
'SET AN OBJECT'S COLOR

CHANGEOBJFACECOLOR INDEX,FACE,COLOR
'SET THE COLOR OF A SINGLE TRIANGLE ON AN OBJECT

CHANGEOBJCOLORAB OBJECT,INDEX1,INDEX2,COLOR
'SET AN OBJECT'S COLOR FROM INDEX1 TO INDEX2 INSIDE THE OBJECT
'OBJECT TRIANGLE INDEXES START AT 0 FOR EACH OBJECT

SETTAG INDEX,TAG$
'GIVE AN OBJECT A STRING, DEFAULT=""
'THIS CAN BE ANYTHING, IT DOESN'T AFFECT THE 3D ENGINE AT ALL
'DESIGNED TO BE USED BY THE DEVELOPER

GETTAG$(INDEX)
'GET THE TAG$ VALUE OF AN OBJECT

FINDIBJBYTAG(TAG$)
'QUICKLY FIND AN OBJECT WITH A SPECIFIC TAG$ VALUE
'RETURNS -1 IF NO OBJECT EXISTS WITH THIS TAG

SETSTR INDEX,S$
'GIVE AN OBJECT A STRING, DEFAULT=""
'THIS IS USED TO STORE THE VALUE IN TEXT OBJECTS
'THERE IS NO USE OUTSIDE OF TEXT OBJECTS, SO THIS IS ANOTHER FREE VARIABLE

GETSTR$(INDEX)
'GET THE STRING VALUE OF AN OBJECT

FINDIBJBYSTR(S$)
'FIND AN OBJECT WITH A SPECIFIC STRING$ VALUE
'RETURNS -1 IF NO OBJECT EXISTS WITH THIS STRING
'OTHERWISE RETURN THE OBJECT INDEX

GETOBJTYPE$(INDEX)
'RETURNS THE STRING DEFINING WHAT TYPE OF OBJECT IT IS
'POSSIBLE RESULTS ARE:
"CUBE","SPHERE","DIAMOND","CRYSTAL","PYRAMID","SKYBOX","LINE","SURFACE","TEXT",etc...

GETOBJSBYDIST(X,Y,Z)
'RETURNS A SORTED ARRAY OF OBJECT INDEXES SUCH THAT THE FIRST ITEM IS CLOSEST
'TO (X,Y,Z) AND THE LAST ITEM IS FURTHEST AWAY FROM (X,Y,Z)
'THIS FUNCTION TAKES ADVANTAGE OF DLC USERS TO GIVE MUCH FASTER PERFORMANCE

UPDATEWCUBEAROUNDOBJ INDEX1,INDEX2
'CHANGE THE WIREFRAME CUBE OBJECT INSIDE INDEX1 TO THE SAME SHAPE AND
'SIZE OF THE OBJECT INSIDE INDEX2 (INDEX1 MUST BE A WCUBE OBJECT)
'IN OTHER WORDS, THIS IS AN ADD-ON TO THE WCUBE OBJECT TO ALLOW IT TO
'PERFECTLY MASK THE BOUNDING BOX OF ANOTHER OBJECT

APPLYSURFACEEQUATION INDEX,EQU$,MINY,MAXY,SCX,SCY,SCZ
'APPLY A MATH EXPRESSION TO A SURFACE OBJECT
'EQU$ IS AN EQUATION WITH X,Y, AND Z IN IT
'EQU$="SIN(X)+COS(Z)" MAKES A WAVY SURFACE
'MINY AND MAXY DEFINE THE OBJECT'S Y BOUNDS
'SCX,SCY,SCZ ARE THE ZOOM FACTORS, 0.1=>10X ZOOM
'IN OTHER WORDS, THIS IS AN ADD-ON TO SURFACES, ALLOWING
'THEM TO TAKE ON THE FORM OF ANY EQUATION

GETUNMASKEDINDEX(MASKEDINDEX)
'SAME AS SAYING OBJMASK[MASKEDINDEX]
'CONVERTS A STABLE OBJECT ID (THAT DOESN'T CHANGE) INTO
'THE ACTUAL INDEX USED IN OBJX,OBJY,OBJZ,OBJROT,etc... 

UPDATEOBJCENTER INDEX
'UPDATES THE CENTER OF MASS OF AN OBJECT (DONE AUTOMATICALLY)

SETSTATICOBJ INDEX,STATE
'SET IF AN OBJECT IS AFFECTED BY GRAVITY AND COLLISIONS
'STATE IS EITHER 1 OR 0 (WHERE 0=AFFECTED BY GRAVITY)

ADDVEL INDEX,VX,VY,VZ
'ADD VELOCITY TO A NON-STATIC OBJECT
'YOU COULD ALSO JUST DO:
'INC OBJVX[OBJMASK[INDEX]],VX
'INC OBJVY[OBJMASK[INDEX]],VY
'INC OBJVZ[OBJMASK[INDEX]],VZ
And a few other functions, slightly unrelated, but implemented nonetheless:
RENDER
'DRAWS THE CURRENT WORLD STATE, REQUIRED TO RUN ONCE EVERY FRAME

BUFFER
'PREVENTS FLICKERING BY SWAPPING GPAGES EACH FRAME, DRAWING TO THE ONE NOT
'BEING SHOWN. THIS SHOULD BE RAN ONCE EVERY FRAME, WITH A GCLS DIRECTLY AFTER IT
'THIS ONLY AFFECTS THE TOP SCREEN
'THIS IS AUTOMATICALLY CALLED INSIDE RENDER

_RENDER
'RENDERS THE SCENE WITHOUT CALLING BUFFER AND CLEARING THE SCREEN

BUFFERBOTTOM 
'PREVENT FLICKERING ON THE LOWER SCREEN, PUT GCLS DIRECTLY AFTER IT

GETCAMRAY OUT X,Y,Z
'RETURNS THE NORMALIZED DIRECTION THE CAMERA IS FACING

GETCAMRAY2D OUT X,Z
'RETURNS THE NORMALIZED DIRECTION THE CAMERA IS FACING EXCLUDING Y

RAYTHROUGHOBJ(X,Y,Z,RX,RY,RZ,INDEX)
'CHECK IF THE RAY STARTING AT X,Y,Z AT THE ANGLE RX,RY,RZ
'IS COLLIDING WITH THE OBJECT INSIDE INDEX

NORMALIZE X,Y,Z OUT X,Y,Z
'SET THE DISTANCE OF AN X,Y,Z DISPLACEMENT EQUAL TO 1
'WHILE MAINTAINING THE ANGLE

CLEARWORLD
'DELETES EVERYTHING IN THE WORLD

'TRIANGLE OPERATION FUNCTIONS
ADDTRI INDEX,TAG$,X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3,COLOR
SETTRI INDEX,X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3 'SET A TRIANGLES POSITION
DELTRI TRIANGLEINDEX 'DELETE A TRIANGLE

SPLITSCREENDRAW X1,Y1,Z1,RX1,RY1,RZ1,X2,Y2,Z2,RX2,RY2,RZ2
'REPLACES THE RENDER FUNCTION
'DRAWS TWO PERSPECTIVES FROM TWO CAMERA POSITIONS AND ANGLES
'[ UNDER CONSTRUCTION, STILL A BIT BUGGY ]

QUADRUPLEDRAW X1,Y1,Z1,RX1,RY1,RZ1,X2,Y2,Z2,RX2,RY2,RZ2,X3,Y3,Z3,RX3,RY3,RZ3,X4,Y4,Z4,RX4,RY4,RZ4
'REPLACES THE RENDER FUNCTION
'DRAWS FOUR PERSPECTIVES FROM FOUR CAMERA POSITIONS AND ANGLES

'3D POINT ROTATION FUNCTIONS
ROT X,Y,Z,ORIGINX,ORIGINY,ORIGINZ,ANGLEX,ANGLEY,ANGLEZ OUT X,Y,Z
ROTX X,Y,Z,ANGLE OUT X,Y,Z 'ROTATE A POINT JUST AROUND X AXIS
ROTY X,Y,Z,ANGLE OUT X,Y,Z 'ROTATE A POINT JUST AROUND Y AXIS
ROTZ X,Y,Z,ANGLE OUT X,Y,Z 'ROTATE A POINT JUST AROUND Z AXIS

INSERT ARRAY[],INDEX,VALUE 'QUICKLY INSERT AN ELEMENT INTO AN ARRAY
REMOVE ARRAY[],INDEX 'QUICKLY REMOVE AN ELEMENT FROM AN ARRAY

TRIM$(S$) 'REMOVE SPACES AND NEW LINES FROM THE FRONT AND END OF A STRING

'HSV OPERATIONS
HSV2RGB HUE,SATURATION,VALUE OUT RED,GREEN,BLUE
RGB2HSV RED,GREEN,BLUE OUT HUE,SATURATION,VALUE
HSV(HUE,SATURATION,VALUE)
'RETURNS THE COLOR AS A SINGLE NUMBER, JUST LIKE RGB(R,G,B) DOES

FCIRCLE X,Y,RADIUS,FILLCOLOR,BORDERCOLOR
'DRAW A FILLED CIRCLE

TEXT X,Y,TEXT$,COLOR
'DRAW CENTERED TEXT ON THE SCREEN

PERSPECTIVE X,Y,Z OUT X,Y,Z
'CONVERT IN-WORLD COORDINATES TO SCREEN COORDINATES
PERSPECTIVEZ(X,Y,Z)
'QUICKLY JUST CALCULATE THE Z VALUE AFTER PERSPECTIVE
ARYOP_PERSPECTIVE X[],Y[],Z[] OUT X[],Y[],Z[]
'CALCULATE FASTER PERSPECTIVE
some examples of SIM.3D usageFour cubes with one smaller one orbiting around it, supports moving the camera using the circle pad
PRGEDIT 3 EXEC "PRG3:3D.ENGINE" END 'SIM.3D

VAR STX,STY,C
'POSITION (0,0,0) SIZE (1,1,1)
C=ADDCUBE(0,0,0,1,1,1,#GRAY)
C=ADDCUBE(0,1.5,0,1,1,1,#GREEN)
C=ADDCUBE(1.5,0,0,1,1,1,#CYAN)
C=ADDCUBE(0,0,1.5,1,1,1,#WHITE)
C=ADDCUBE(0,0,3,0.5,0.5,0.5,HSV(0,255,255))
'THE VARIABLE C WAS OVERWRITTEN OVER AND OVER, BUT THIS ONE WE'LL KEEP

@LOOP
VSYNC
STICK OUT STX,STY
'CAMRX,CAMRY ARE USED BY SIM.3D
CAMRX=CAMRX-STX*5
CAMRY=CAMRY-STY*5
'ROTATE THE CUBE AROUND THE POINT (0,0,0) ROTATING AROUND THE X AND Y AXIS
ROTOBJAROUND C,0,0,0,1,1,0
RENDER
GOTO @LOOP
You are a cube, you can rotate your camera and move around the world. In the world there is a large 3D Sierpinski tetrahedron fractal generated recursively
PRGEDIT 3 EXEC "PRG3:3D.ENGINE"

VAR I,J
'MAKE AN INSIDE OUT CUBE CENTERED AT POSITION (0,5,50) AND SIZE (120,120,120)
I=ADDSKYBOX(0,5,50,120,120,120,RGB(60,60,60))

VAR PLAYER=ADDCUBE(0,0,0,1,1,1,#WHITE)
VAR BTN,STX,STY,X,Y,Z

'CALL THE FUNCTION THAT GENERATES THE FRACTAL
'POSITION=(0,30,50)
'SIZE=(40,50)
'DEPTH=3
'(HUE,SATURATION,VALUE)=(RND(360),150,255)
SIERPINSKI 0,30,50,40,50,3,RND(360),150,255

@LOOP
VSYNC
CLS
PRINT "FPS ";FPS 'FPS IS CALCULATED INSIDE SIM.3D
'EVERY FRAME, SET THE PLAYER CUBE TO THE SAME POSITION AS THE CAMERA
MOVEOBJTO PLAYER,CAMX,CAMY,CAMZ
CONTROLS 'CALL THE FUNCTION THAT HANDLES CONTROLS
'PREVENT THE CAMERA FROM GOING UPSIDE DOWN
IF CAMRY<-90 THEN CAMRY=-90
IF CAMRY>90 THEN CAMRY=90
RENDER 'CALL THE RENDER FUNCTION IN SIM.3D
GOTO @LOOP

'HANDLE DEVICE CONTROLS
DEF CONTROLS
 STICK OUT STX,STY 'CIRCLE PAD INPUT
 BTN=BUTTON() 'INPUT FOR BUTTONS
 'ROTATE THE CAMERA, USE COSINE TO ENSURE IT IS ALIGNED
 DEC CAMRX,STX*6*COSCAMRZ
 DEC CAMRY,STY*6*COSCAMRZ
 IF BTN AND #UP THEN CAMDIST=CAMDIST/1.05 'ZOOMING IN/OUT
 IF BTN AND #DOWN THEN CAMDIST=CAMDIST*1.05
 IF BTN AND #X THEN 'MOVING FORWARD
  VAR X,Y,Z
  GETCAMRAY OUT X,Y,Z 'THIS WILL GIVE THE X,Y,Z UNIT ROTATION FACING OUT OF THE CAMERA
  INC CAMX,X/2 'INCREMENT THE CAMERA POSITION
  INC CAMY,Y/2
  INC CAMZ,Z/2
 ENDIF
 IF BTN AND #B THEN 'MOVING BACKWARD
  VAR X,Y,Z
  GETCAMRAY OUT X,Y,Z 'THIS WILL GIVE THE X,Y,Z UNIT ROTATION FACING OUT OF THE CAMERA
  DEC CAMX,X/2 'DECREMENT THE CAMERA POSITION
  DEC CAMY,Y/2
  DEC CAMZ,Z/2
 ENDIF
END

'GENERATE A SIERPINSKI TETRAHEDRON FRACTAL
'POSITION=(X,Y,Z)
'SIZE=(WIDTH,HEIGHT) (LENGTH ISN'T INCLUDED SINCE ITS A SQUARE BASE)
'DEPTH IS HOW MANY ITERATIONS TO GO IN (PERFORMANCE TAKES A HUGE HIT, INCREMENTING)
'COLOR=(HUE,SATURATION,VALUE)
DEF SIERPINSKI X,Y,Z,W_,H_,DEPTH,HU,SA,VA
 VAR I,W=W_*0.5,H=H_*0.5
 IF DEPTH==0 THEN 'BASE CASE
  I=ADDPYRAMID(X,Y,Z,W_*2,H_,HSV(HU,SA,VA))
 ELSE
  SIERPINSKI X,Y-H,Z,W,H,DEPTH-1,HU+100,SA,VA
  SIERPINSKI X-W,Y,Z-W,W,H,DEPTH-1,HU,SA,VA
  SIERPINSKI X-W,Y,Z+W,W,H,DEPTH-1,HU,SA,VA
  SIERPINSKI X+W,Y,Z-W,W,H,DEPTH-1,HU,SA,VA
  SIERPINSKI X+W,Y,Z+W,W,H,DEPTH-1,HU,SA,VA
 ENDIF
END

I just played some Fortnite(which uses Unreal Engine 4) and I noticed something: when you are far away from an object, the resolution is really low. Also, the triangle count in an object decreases. Maybe Simeon can (somehow) implement this in SIM.3D... to conserve RAM and increase FPS

the VSYNC is slowing it down.(I know it will flicker without it), but how about you use this custom command:
DEF WAITTIME A
M = MILLISEC
WHILE MILLISEC-M>A:WEND
END
this waits for smaller units of time(which could help with FPS barely) since the refresh rate of almost every modern device is 60FPS, we can assume that VSYNC waits ~16.667 milliseconds(1000/60) As we all know, the human eye(on average)sees at ~24 FPS Using this command, we can make a smaller wait time for refreshing, therefore higher FPS. I would recommend a wait time of...33.33ms. Seems stupid, but that should include rendering AND refresh time.

Replying to:DFrost
the VSYNC is slowing it down.(I know it will flicker without it), but how about you use this custom command:
DEF WAITTIME A
M = MILLISEC
WHILE MILLISEC-M>A:WEND
END
this waits for smaller units of time(which could help with FPS barely) since the refresh rate of almost every modern device is 60FPS, we can assume that VSYNC waits ~16.667 milliseconds(1000/60) As we all know, the human eye(on average)sees at ~24 FPS Using this command, we can make a smaller wait time for refreshing, therefore higher FPS. I would recommend a wait time of...33.33ms. Seems stupid, but that should include rendering AND refresh time.
Did you actually test this before posting?

Replying to:DFrost
the VSYNC is slowing it down.(I know it will flicker without it), but how about you use this custom command:
DEF WAITTIME A
M = MILLISEC
WHILE MILLISEC-M>A:WEND
END
this waits for smaller units of time(which could help with FPS barely) since the refresh rate of almost every modern device is 60FPS, we can assume that VSYNC waits ~16.667 milliseconds(1000/60) As we all know, the human eye(on average)sees at ~24 FPS Using this command, we can make a smaller wait time for refreshing, therefore higher FPS. I would recommend a wait time of...33.33ms. Seems stupid, but that should include rendering AND refresh time.
33.33ms frame time is 30FPS, you know

Replying to:DFrost
the VSYNC is slowing it down.(I know it will flicker without it), but how about you use this custom command:
DEF WAITTIME A
M = MILLISEC
WHILE MILLISEC-M>A:WEND
END
this waits for smaller units of time(which could help with FPS barely) since the refresh rate of almost every modern device is 60FPS, we can assume that VSYNC waits ~16.667 milliseconds(1000/60) As we all know, the human eye(on average)sees at ~24 FPS Using this command, we can make a smaller wait time for refreshing, therefore higher FPS. I would recommend a wait time of...33.33ms. Seems stupid, but that should include rendering AND refresh time.
(its a theory)

Replying to:DFrost
the VSYNC is slowing it down.(I know it will flicker without it), but how about you use this custom command:
DEF WAITTIME A
M = MILLISEC
WHILE MILLISEC-M>A:WEND
END
this waits for smaller units of time(which could help with FPS barely) since the refresh rate of almost every modern device is 60FPS, we can assume that VSYNC waits ~16.667 milliseconds(1000/60) As we all know, the human eye(on average)sees at ~24 FPS Using this command, we can make a smaller wait time for refreshing, therefore higher FPS. I would recommend a wait time of...33.33ms. Seems stupid, but that should include rendering AND refresh time.
As we all know, the human eye(on average)sees at ~24 FPS
This is a myth. The truth is more complicated, but the fastest we can perceive motion generally lies somewhere above 60 FPS. Luckily, with SmileBASIC, we don't have to rely on hearsay -- it's easy to test this for ourselves. (Hold R to switch to 60 FPS.)
ACLS
SPSET 0,2048
SPSCALE 0,2,2
WHILE TRUE
 T=MAINCNT
 X=80*SIN(T/8)+200
 Y=80*COS(T/8)+136
 SPOFS 0,X,Y
 CLS
 ?T
 IF BUTTON() AND #R THEN
  ?"60 FPS"
  VSYNC 1
 ELSE
  ?"30 FPS"
  VSYNC 2
 ENDIF
WEND

Replying to:DFrost
the VSYNC is slowing it down.(I know it will flicker without it), but how about you use this custom command:
DEF WAITTIME A
M = MILLISEC
WHILE MILLISEC-M>A:WEND
END
this waits for smaller units of time(which could help with FPS barely) since the refresh rate of almost every modern device is 60FPS, we can assume that VSYNC waits ~16.667 milliseconds(1000/60) As we all know, the human eye(on average)sees at ~24 FPS Using this command, we can make a smaller wait time for refreshing, therefore higher FPS. I would recommend a wait time of...33.33ms. Seems stupid, but that should include rendering AND refresh time.
I'm trying to say Simeon needs to use this custom command the for *exact* amount of time to stop flickering at a minimum wait time

Replying to:DFrost
the VSYNC is slowing it down.(I know it will flicker without it), but how about you use this custom command:
DEF WAITTIME A
M = MILLISEC
WHILE MILLISEC-M>A:WEND
END
this waits for smaller units of time(which could help with FPS barely) since the refresh rate of almost every modern device is 60FPS, we can assume that VSYNC waits ~16.667 milliseconds(1000/60) As we all know, the human eye(on average)sees at ~24 FPS Using this command, we can make a smaller wait time for refreshing, therefore higher FPS. I would recommend a wait time of...33.33ms. Seems stupid, but that should include rendering AND refresh time.
Well, but VSYNC does that And simple is better If there's any flickering then BUFFER isn't working properly

Replying to:DFrost
the VSYNC is slowing it down.(I know it will flicker without it), but how about you use this custom command:
DEF WAITTIME A
M = MILLISEC
WHILE MILLISEC-M>A:WEND
END
this waits for smaller units of time(which could help with FPS barely) since the refresh rate of almost every modern device is 60FPS, we can assume that VSYNC waits ~16.667 milliseconds(1000/60) As we all know, the human eye(on average)sees at ~24 FPS Using this command, we can make a smaller wait time for refreshing, therefore higher FPS. I would recommend a wait time of...33.33ms. Seems stupid, but that should include rendering AND refresh time.
OK, I'm just making a fool of myself.

Replying to:DFrost
the VSYNC is slowing it down.(I know it will flicker without it), but how about you use this custom command:
DEF WAITTIME A
M = MILLISEC
WHILE MILLISEC-M>A:WEND
END
this waits for smaller units of time(which could help with FPS barely) since the refresh rate of almost every modern device is 60FPS, we can assume that VSYNC waits ~16.667 milliseconds(1000/60) As we all know, the human eye(on average)sees at ~24 FPS Using this command, we can make a smaller wait time for refreshing, therefore higher FPS. I would recommend a wait time of...33.33ms. Seems stupid, but that should include rendering AND refresh time.
Nah don't worry about it man, you gave me lots of great suggestions that I'll be working on, I've just been a little bit too busy with school to put more effort into your requests. In most programming languages, simple is not better especially with 3D engine building. When there are strict computing limitations, in my opinion it seems unnecessary to put extra effort into mipmaps and texture mapping. The issue I see with decreased triangle count as objects get far away, is the issue is of actually detecting when they're far away since the slightest additions of computations dramatically change the performance. In SmileBASIC, its a little bit strange because the more code, the slower it gets since there seems to be a small portion of overhead for each line of code. It's hard to detect, but because of this limitation we're forced to use the minimum number of commands. Granted, I'm sure if 12Me21 was to look over SIM.3D, he'd be able to optimize this much more than any of us could. It seems that the biggest optimization to be made is converting floating point variables to integer variables (using %). I'll look more into all of this when I get the time.

Im not sure if this has to came to anybody's attention but, do notice how Spooky Maze uses Textures on its walls. It uses raycasting to get a slice of a sprite and draws it onto the screen. Its very efficient and could be be used in a situation like a 3D engine. you would need many more rays, but if you were to lower the resolution to half for New3DS's and a quarter for Old3DS's, the performance should be usable, and allow for images to be pasted onto 3D geometry. Locking the FPS to 45 or 30 using this method would yield good results as well. Its all a theory though, but ill attempt a test of this idea later, probably nearing the end of the month or mid-June.

Replying to:MochaProbably
Im not sure if this has to came to anybody's attention but, do notice how Spooky Maze uses Textures on its walls. It uses raycasting to get a slice of a sprite and draws it onto the screen. Its very efficient and could be be used in a situation like a 3D engine. you would need many more rays, but if you were to lower the resolution to half for New3DS's and a quarter for Old3DS's, the performance should be usable, and allow for images to be pasted onto 3D geometry. Locking the FPS to 45 or 30 using this method would yield good results as well. Its all a theory though, but ill attempt a test of this idea later, probably nearing the end of the month or mid-June.
You can only use that type of raycasting on regular grids or scenes where everything is parallel lines, as far as I'm aware. You could try something like the classic DOOM engine, but I think you'll have to do most of it in software and it'll end up too slow.

Replying to:MochaProbably
Im not sure if this has to came to anybody's attention but, do notice how Spooky Maze uses Textures on its walls. It uses raycasting to get a slice of a sprite and draws it onto the screen. Its very efficient and could be be used in a situation like a 3D engine. you would need many more rays, but if you were to lower the resolution to half for New3DS's and a quarter for Old3DS's, the performance should be usable, and allow for images to be pasted onto 3D geometry. Locking the FPS to 45 or 30 using this method would yield good results as well. Its all a theory though, but ill attempt a test of this idea later, probably nearing the end of the month or mid-June.
Well, sprites can be rotated too. Warrior is right I believe. Account for the camera & object rotations, and you should be able to transform the sprite image into the required 3d shape.

Replying to:DFrost
the VSYNC is slowing it down.(I know it will flicker without it), but how about you use this custom command:
DEF WAITTIME A
M = MILLISEC
WHILE MILLISEC-M>A:WEND
END
this waits for smaller units of time(which could help with FPS barely) since the refresh rate of almost every modern device is 60FPS, we can assume that VSYNC waits ~16.667 milliseconds(1000/60) As we all know, the human eye(on average)sees at ~24 FPS Using this command, we can make a smaller wait time for refreshing, therefore higher FPS. I would recommend a wait time of...33.33ms. Seems stupid, but that should include rendering AND refresh time.
I'm just saying there might be a refresh rate that will stop flickering and spend less time WAITING. I'm just visualizing frame time in a spectrum like this: ("*" means that framerate will cause a visible flicker) ("0" means that flicker is invisible) *0 I think there might be a *perfect* wait time that will wait for the least amount of time to stop flickering and not be time-consuming. I want a framerate between the "*" and "0"

Bug:if you move a sprite, the geometry disappears. I found this because I wanted to make a game with 3D geometry, but 2D characters and stuff JUST BECAUSE I WANT 3D GEOMETRY IN A GAME DOESN'T MEAN I WANT 3D CHARACTERS IN SAID GAME

How to outsmart the chess AI (as of 1.4) in 5 easy steps!

Replying to:IAmRalsei
Bug:if you move a sprite, the geometry disappears. I found this because I wanted to make a game with 3D geometry, but 2D characters and stuff JUST BECAUSE I WANT 3D GEOMETRY IN A GAME DOESN'T MEAN I WANT 3D CHARACTERS IN SAID GAME
That'd be a cool feature to add, ill look into it thanks Late response, my bad

Replying to:IAmRalsei
Bug:if you move a sprite, the geometry disappears. I found this because I wanted to make a game with 3D geometry, but 2D characters and stuff JUST BECAUSE I WANT 3D GEOMETRY IN A GAME DOESN'T MEAN I WANT 3D CHARACTERS IN SAID GAME
It’s okay.

Once 3D Parkour 2 gets developed more, I will give it it's own submission key. I'm taking any feedback, so if you have any cool ideas for it let me know! I'm thinking to make the game about orbiting around objects instead of linear gravity

Replying to:Simeon
Once 3D Parkour 2 gets developed more, I will give it it's own submission key. I'm taking any feedback, so if you have any cool ideas for it let me know! I'm thinking to make the game about orbiting around objects instead of linear gravity
Buttons, switches, and moving booby traps would bring it more life.