Giter Site home page Giter Site logo

sanj's Introduction

sanj

Notes about working with THREE and react-three-fiber

Text

Convert font file to glyph JSON using https://gero3.github.io/facetype.js

TextGeometry:

import { useLoader } from 'react-three-fiber';

const font = useLoader(THREE.FontLoader, '/roboto_regular.json');

const options = {
  font: font
  size: 80,
  height: 5,
  curveSegments: 12,
  bevelEnabled: true,
  bevelThickness: 10,
  bevelSize: 8,
  bevelOffset: 0,
  bevelSegments: 5
};

<mesh>
  <textGeometry attach="geometry" args={[children, options]} />
  <meshNormalMaterial attach="material" />
</mesh>

Converting to shape geometry more efficient than text geometry, as it does not extrude:

import { useLoader } from 'react-three-fiber';

const font = useLoader(THREE.FontLoader, '/roboto_regular.json');

const shapes = font.generateShapes('Hello world', 20);

<mesh>
  <shapeBufferGeometry attach="geometry" args={[shapes]}>
  <meshNormalMaterial attach="material" />
</mesh>

Visualizing vertices

Render a point cloud with disabled size attenuation using the geometry in question:

<points geometry={geometry}>
  <pointsMaterial
    attach="material"
    size={3}
    vertexColors={true}
    sizeAttenuation={false}
  />
</points>

Tessellation

Looping to increase vertex count:

import { TessellateModifier } from 'three/examples/jsm/modifiers/TessellateModifier';

const modifier = new TessellateModifier(8);

for (let i = 0; i < 6; i++) {
  modifier.modify(geometry); // non-buffer geometry
}

Randomly generating points within a bounding box

function generatePointsWithinBoundingBox(
  geometry: THREE.Geometry,
  numberOfPoints: number
): void {
  for (let i = 0; i < numberOfPoints; i++) {
    geometry.vertices.push(generatePointWithinBoundingBox(geometry));
  }
}

function generatePointWithinBoundingBox(
  geometry: THREE.Geometry
): THREE.Vector3 {
  if (!geometry.boundingBox) {
    geometry.computeBoundingBox();
  }

  const point = new THREE.Vector3(
    THREE.MathUtils.randFloat(
      geometry.boundingBox!.min.x,
      geometry.boundingBox!.max.x
    ),
    THREE.MathUtils.randFloat(
      geometry.boundingBox!.min.y,
      geometry.boundingBox!.max.y
    ),
    0.0
  );

  if (isPointInside(point, geometry)) {
    return point;
  } else {
    return generatePointWithinBoundingBox(geometry);
  }
}

function isPointInside(
  point: THREE.Vector3,
  geometry: THREE.Geometry
): boolean {
  if (!geometry.faces.length) {
    throw new Error('Geometry has no faces');
  }

  for (let i = 0; i < geometry.faces.length; i++) {
    const face = geometry.faces[i];

    const vectorA = geometry.vertices[face.a];
    const vectorB = geometry.vertices[face.b];
    const vectorC = geometry.vertices[face.c];

    if (isPointWithinTriangle(point, vectorA, vectorB, vectorC)) {
      return true;
    }
  }

  return false;
}

function isPointWithinTriangle(
  point: THREE.Vector3,
  vectorA: THREE.Vector3,
  vectorB: THREE.Vector3,
  vectorC: THREE.Vector3
): boolean {
  const A =
    0.5 *
    (-vectorB.y * vectorC.x +
      vectorA.y * (-vectorB.x + vectorC.x) +
      vectorA.x * (vectorB.y - vectorC.y) +
      vectorB.x * vectorC.y);

  const sign = A > 0 ? 1 : -1;

  const s =
    (vectorA.y * vectorC.x -
      vectorA.x * vectorC.y +
      (vectorC.y - vectorA.y) * point.x +
      (vectorA.x - vectorC.x) * point.y) *
    sign;

  const t =
    (vectorA.x * vectorB.y -
      vectorA.y * vectorB.x +
      (vectorA.y - vectorB.y) * point.x +
      (vectorB.x - vectorA.x) * point.y) *
    sign;

  return s > 0 && t > 0 && s + t < 2 * A * sign;
}

Getting visible width/height at z depth for perspective camera

function getVisibleHeight(
  camera: THREE.PerspectiveCamera,
  depth: number
) {
  const { z } = camera.position;
  depth += z;

  const verticalFovRadians = (camera.fov * Math.PI) / 180;

  return Math.tan(verticalFovRadians / 2) * depth * 2;
}

function getVisibleWidth(camera: THREE.PerspectiveCamera, depth: number) {
  return getVisbleHeight(camera, depth) * camera.aspect;
}

sanj's People

Contributors

blackwright avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.