[Demo]Advanced raycasting on Pokitto

This is an official release of my raycasting demos – they’re pretty old by now, nothing new. I decided not to release this officially until overclocking was announced, since I experimented with that at the time classified piece of technology :slight_smile:

However, the demos got pretty optimized and don’t require overclocking at all – it just adds some nice extra smoothness – you can compare the provided bins below.

sum up

I created a C library for fast and efficient advanced raycasting (a kind of technique used in old 2.5/3D games) – it runs on many platforms, not just Pokitto, but also PC and other consoles. This is good because you can create a game that runs natively on many platforms – your game can run in high resolution on PC, but also be playable on Pokitto.

Using that library I created a few demos to showcase and test it – there are three demos for Pokitto.

This is intended to be reusable, so go ahead and make your own game with it. Everything is documented in the repositories, in READMEs and in the code itself. If anything’s unclear, ask me.

Also thanks goes to the members of community who helped me optimize this for the Pokitto HW, I couldn’t have done that alone.

files:

bins:

demo1.bin (60.8 KB)
demo1_overclock.bin (72.2 KB)
demo2.bin (57.6 KB)
demo2_overclock.bin (69 KB)
demo3.bin (55.2 KB)
demo3_overclock.bin (66.6 KB)
helloRay.bin (46.2 KB)

sources:

Everything is CC0, public domain. Thanks for sharing your own programs and other resources as free and open :slight_smile:

10 Likes

Thanks for this amazing contribution. I hope someone takes up thd challenge of developing a game using these libs

2 Likes

As a next step I’d like to proof-of-concept combine raycastlib and small3dlib in a single program – I’ve been designing both libs so that they can be used together. The idea is to render the big environment with raycasting, which is fast, and then render some small 3D objects over it. Let’s see.

2 Likes

Yep, works like charm:

out

The environment is rendered with raycastlib, the cubes with small3dlib. Nice to see something working right away. (You just have to keep the two cameras in different coordinate systems synced, but that’s it). FPS is great, even without overclocking or optimizations here.

EDIT:

code for the reference
/* by Drummfish, released under CC0 */

#define RCL_PIXEL_FUNCTION pixelFuncRC
#define RCL_COMPUTE_WALL_TEXCOORDS 0
#define RCL_COMPUTE_FLOOR_TEXCOORDS 0
#define RCL_COMPUTE_FLOOR_DEPTH 0
#define RCL_COMPUTE_FLOOR_DEPTH 0
#define RCL_COMPUTE_CEILING_DEPTH 0

#define S3L_PIXEL_FUNCTION pixelFunc3D
#define S3L_RESOLUTION_X 110
#define S3L_RESOLUTION_Y 88
#define S3L_SORT 1

#include "raycastlib.h"
#include "small3dlib.h"
#include "Pokitto.h"

Pokitto::Core pokitto;

RCL_Camera camera;
RCL_RayConstraints constraints;

S3L_Unit cubeVertices[] = { S3L_CUBE_VERTICES(S3L_FRACTIONS_PER_UNIT) };
S3L_Index cubeTriangles[] = { S3L_CUBE_TRIANGLES };

S3L_Model3D models[2];
S3L_Scene scene;

RCL_Unit floorHeightAt(int16_t x, int16_t y)
{
  return x < 0 || x >= 10 || y < 0 || y >= 10 ?
    RCL_UNITS_PER_SQUARE * 2 : 0;
}

void pixelFuncRC(RCL_PixelInfo *pixel)
{
  uint8_t color;

  if (pixel->isWall)
    color = pixel->hit.direction + 2;
  else
    color = pixel->isFloor ? 10 : 11;

  pokitto.display.drawPixel(pixel->position.x,pixel->position.y,color);
}

void pixelFunc3D(S3L_PixelInfo *pixel)
{
  uint8_t color;

  if (pixel->triangleIndex == 0 || pixel->triangleIndex == 1 ||
      pixel->triangleIndex == 4 || pixel->triangleIndex == 5)
    color = 7;
  else if (pixel->triangleIndex == 2 || pixel->triangleIndex == 3 ||
      pixel->triangleIndex == 6 || pixel->triangleIndex == 7)
    color = 9;
  else
    color = 3;

  pokitto.display.drawPixel(pixel->x,pixel->y,color);
}

void draw()
{
  RCL_renderComplex(camera,floorHeightAt,0,0,constraints);

  S3L_newFrame();
  S3L_drawScene(scene);
}

int main()
{
  int32_t cam_x, cam_y, cam_z, cam_r;

  pokitto.begin(); 
  pokitto.setFrameRate(60);

  RCL_initCamera(&camera);

  cam_x = 512;
  cam_y = 512;
  cam_z = 512;
  cam_r = 0;

  camera.resolution.x = 110;
  camera.resolution.y = 88;

  RCL_initRayConstraints(&constraints);
  constraints.maxHits = 1;
  constraints.maxSteps = 20;

  S3L_initModel3D(cubeVertices,S3L_CUBE_VERTEX_COUNT,cubeTriangles,S3L_CUBE_TRIANGLE_COUNT,&(models[0])); 
  S3L_initModel3D(cubeVertices,S3L_CUBE_VERTEX_COUNT,cubeTriangles,S3L_CUBE_TRIANGLE_COUNT,&(models[1])); 

  models[0].transform.translation.x = -4000;
  models[0].transform.translation.y = 512;
  models[0].transform.translation.z = 2000;

  models[1].transform.translation.x = -2000;
  models[1].transform.translation.y = 512;
  models[1].transform.translation.z = 4000;

  S3L_initScene(models,2,&scene);

  while (pokitto.isRunning())
  {
    if (pokitto.update())
    {
      draw();

      RCL_Vector2D moveOffset;

      moveOffset.x = 0;
      moveOffset.y = 0;
      moveOffset = RCL_angleToDirection(camera.direction);
      moveOffset.x = (moveOffset.x * 50) / RCL_UNITS_PER_SQUARE;
      moveOffset.y = (moveOffset.y * 50) / RCL_UNITS_PER_SQUARE;

      if (pokitto.rightBtn())
        cam_r += 10;
      if (pokitto.leftBtn())
        cam_r -= 10;

      if (pokitto.upBtn())
      {
        cam_x += moveOffset.x;
        cam_y += moveOffset.y;
      }
      else if (pokitto.downBtn())
      {
        cam_x -= moveOffset.x;
        cam_y -= moveOffset.y;
      }

      if (pokitto.aBtn())
        cam_z += 50;
      else if (pokitto.bBtn())
        cam_z -= 50;

      camera.position.x = cam_x * 2;
      camera.position.y = cam_y * 2;
      camera.height = cam_z * 2;
      camera.direction = cam_r * 2;
 
      scene.camera.transform.translation.x = -1 * cam_y;
      scene.camera.transform.translation.y = cam_z;
      scene.camera.transform.translation.z = cam_x;
      scene.camera.transform.rotation.y = -1 * cam_r;

      models[0].transform.rotation.y += 2;
      models[1].transform.rotation.x += 5;
    }
  }

  return 0;
}
5 Likes

This just gets more and more exciting!! Oh my gosh.

2 Likes

3d game jam when?

1 Like

@drummyfish looks too good!

2 Likes

An amazing combination of speed and 3d objects!

2 Likes

I was able to run this in FemtoIDE. FemtoIDE has this super nice feature of autoconverting images to hex arrays. But when I tried this with one of the textures in the demo1, the texture was screwed up. Is there an endianess or transpose that the raycast demo expects that the auto conversion is not doing?

I used custom image format using this. It stores indexed pixels by columns, I dunno what format FemtoIDE uses.

Ah thanks! Also I love your work on Arduboy and Pokitto! Thanks for doing all the heavy lifting on the raycast engine! Looking forward to playing around with it.

2 Likes