Skip to content

Latest commit

 

History

History
93 lines (69 loc) · 3.7 KB

adding-a-threejs-mesh.md

File metadata and controls

93 lines (69 loc) · 3.7 KB

Adding a three.js mesh

import { ArxPolygonFlags } from 'arx-convert/types'
import { ArxMap, Material, QUADIFY, Settings, SHADING_SMOOTH, Texture, Vector3 } from 'arx-level-generator'
import { scaleUV, toArxCoordinateSystem } from 'arx-level-generator/tools/mesh'
import { applyTransformations } from 'arx-level-generator/utils'
import { MathUtils, Mesh, MeshBasicMaterial, PlaneGeometry } from 'three'

const map = new ArxMap()
map.config.offset = new Vector3(3000, 0, 3000)

// create a 200x200cm plane that is to be divided into 4x4 quads each with 50x50 size
// at this moment quads are just 2 triangles
let geometry = new PlaneGeometry(200, 200, 4, 4)

// Arx uses an inverted Y axis, this corrects the geometry
geometry = toArxCoordinateSystem(geometry)

// pick a pre-defined texture or load one either from Arx or from a custom file (see docs/examples/textures.md)
let texture = Texture.l2TrollStoneGround04

// [optional step]: you can add extra properties to a texture using the "flags" property, like making it double sided or glowing;
// here you can also make it transparent with the "opacity" and "opacityMode" properties
texture = Material.fromTexture(texture, { flags: ArxPolygonFlags.DoubleSided })

// wrapping the texture into a Material class from three.js (different from the Material of arx-level-generator)
const material = new MeshBasicMaterial({ map: texture })

// grouping the geometry and material together into a three.js mesh object
const mesh = new Mesh(geometry, material)

// [optional step]: adjust the orientation of the geometry
// by default the plane is on its side, need to make it face upwards
geometry.rotateX(MathUtils.degToRad(-90))

// [optional step]: move the mesh on the X/Y/Z axis
geometry.translate(20, 0, 0)

// [optional step]: by default the texture will be scaled in a way that it covers the whole mesh 1x1 times
// this code will tile the texture 4 times in both axis, so every 50x50 tile will have its own full texture
scaleUV(new Vector2(4, 4), geometry)

// boilerplate code that adjusts the center of the geometry to the map's offset (3000/0/3000 in this example)
applyTransformations(mesh)
mesh.translateX(map.config.offset.x)
mesh.translateY(map.config.offset.y)
mesh.translateZ(map.config.offset.z)
applyTransformations(mesh)

// add the mesh to the map; this is where polygons get turned into quads + shading can be smooth or flat
map.polygons.addThreeJsMesh(mesh, { tryToQuadify: QUADIFY, shading: SHADING_SMOOTH })

Simplify the above with createPlaneMesh prefab

import { ArxPolygonFlags } from 'arx-convert/types'
import { ArxMap, Material, QUADIFY, Settings, SHADING_SMOOTH, Texture, Vector3 } from 'arx-level-generator'
import { createPlaneMesh } from 'arx-level-generator/prefabs/mesh'
import { applyTransformations } from 'arx-level-generator/utils'
import { Vector2 } from 'three'

const settings = new Settings()
const map = new ArxMap()

map.config.offset = new Vector3(6000, 0, 6000)

const texture = Material.fromTexture(Texture.l2TrollStoneGround04, { flags: ArxPolygonFlags.DoubleSided })

const mesh = createPlaneMesh({
  size: new Vector2(200, 200),
  tileSize: 50, // every tile will be 50x50 -> the mesh will be subdivided into 4x4 tiles
  texture: texture,
})

applyTransformations(mesh)
mesh.translateX(map.config.offset.x)
mesh.translateY(map.config.offset.y)
mesh.translateZ(map.config.offset.z)
applyTransformations(mesh)

map.polygons.addThreeJsMesh(mesh, {
  tryToQuadify: QUADIFY, // use QUADIFY if the surface is flat, otherwise use DONT_QUADIFY
  shading: SHADING_SMOOTH,
})

how the map generated by the code looks

Resources

https://threejs.org/docs/#api/en/geometries/PlaneGeometry