/Quark

A simple rendering/game engine designed to work seamlessly with react

Primary LanguageTypeScript

Quark

Simple Typescript-based game engine designed to work seamlessly with React.

image

Simple cube component example:

import { useCallback, useEffect, useRef } from 'react';
import { Engine, Camera, Mesh, Light, DirectionalLight, AreaLight, GameObject } from 'quark';
import { vec2, vec3 } from 'gl-matrix';
import { ModelType } from 'grengine/dist/loader/mesh_loader';

const ThreeDScene = () => {
  const canvasRef = useRef<HTMLCanvasElement | null>(null);

  const initScene = useCallback(async (canvas: HTMLCanvasElement | null) => {
    if (!canvas) {
      return;
    }

    const camera = new Camera(90, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position[2] = -10;
    // camera.rotation[0] = Math.PI;
    
    const engine = Engine.init(canvas, camera); 

    // Create a light
    const lightColor = vec3.fromValues(1.0, 1.0, 1.0);
    const lightIntensity = 1.0;
    const light = new DirectionalLight(lightColor, lightIntensity);
    light.position[1] = 10;
    light.position[2] = 10;
    light.rotation[0] = Math.PI / 2;    
    engine.createLight(light);

    const vertices = [
      // Front face
      -1, -1,  1,
       1, -1,  1,
       1,  1,  1,
       1,  1,  1,
      -1,  1,  1,
      -1, -1,  1,
    
      // Back face
      -1, -1, -1,
      -1,  1, -1,
       1,  1, -1,
       1,  1, -1,
       1, -1, -1,
      -1, -1, -1,
    
      // Top face
      -1,  1, -1,
      -1,  1,  1,
       1,  1,  1,
       1,  1,  1,
       1,  1, -1,
      -1,  1, -1,
    
      // Bottom face
      -1, -1, -1,
       1, -1, -1,
       1, -1,  1,
       1, -1,  1,
      -1, -1,  1,
      -1, -1, -1,
    
      // Right face
       1, -1, -1,
       1,  1, -1,
       1,  1,  1,
       1,  1,  1,
       1, -1,  1,
       1, -1, -1,
    
      // Left face
      -1, -1, -1,
      -1, -1,  1,
      -1,  1,  1,
      -1,  1,  1,
      -1,  1, -1,
      -1, -1, -1
    ];

    const normals = [
      // Front face
       0,  0,  1,
       0,  0,  1,
       0,  0,  1,
       0,  0,  1,
       0,  0,  1,
       0,  0,  1,
    
      // Back face
       0,  0, -1,
       0,  0, -1,
       0,  0, -1,
       0,  0, -1,
       0,  0, -1,
       0,  0, -1,
    
      // Top face
       0,  1,  0,
       0,  1,  0,
       0,  1,  0,
       0,  1,  0,
       0,  1,  0,
       0,  1,  0,
    
      // Bottom face
        0, -1,  0,
        0, -1,  0,
        0, -1,  0,
        0, -1,  0,
        0, -1,  0,
        0, -1,  0,
    
      // Right face
        1,  0,  0,
        1,  0,  0,
        1,  0,  0,
        1,  0,  0,
        1,  0,  0,
        1,  0,  0,
    
      // Left face
      -1,  0,  0,
      -1,  0,  0,
      -1,  0,  0,
      -1,  0,  0,
      -1,  0,  0,
      -1,  0,  0
    ];

    const gameObjects: GameObject[] = [];
    
    const gameObject = await engine.createGameObject({
      modelData: { vertices, normals },
      modelType: ModelType.Vertex,
    });

    gameObject.position[2] = 10;

    gameObjects.push(gameObject);

    const gameObject2 = await engine.createGameObject({
      modelData: { vertices, normals },
      modelType: ModelType.Vertex,
    });

    gameObject2.position[2] = -10;
    gameObject2.position[1] = 10;
    gameObject2.position[0] = 10;

    gameObjects.push(gameObject2);

    engine.update();

    const gameLoop = () => {
      for (const gameObject of gameObjects) {
          gameObject.rotation[0] += 0.01;
          gameObject.rotation[1] += 0.01;
      }
      engine.update();
      requestAnimationFrame(gameLoop);
      
    };

    gameLoop();
  }, []);

  useEffect(() => {
    if (canvasRef.current) {
      initScene(canvasRef.current);
    }
  }, [canvasRef, initScene]);
 
  return (
    <canvas
      ref={canvasRef}
      width={window.innerWidth}
      height={window.innerHeight}
      style={{ width: '100%', height: '100%' }}
    />
  );
};

export default ThreeDScene;

What is .qrkmez?

A .qrkmez or Quark mezanine file is a file containing only the verticies and normals of a 3d model. We use this format, which is simply a text file, to simplify loading 3d models.