Rob Kwasowski
Rob Kwasowski

Reputation: 2780

Undefined vertexUv in three.js

I'm trying to merge together some meshes, including one that's formed by inputting the vertices co-ordinates. That one causes the error

THREE.DirectGeometry.fromGeometry(): Undefined vertexUv 256

It seems to be fine on it's own, but it doesn't like being merged with something else.

Is there a way to fix this? I tried adding computeVertexNormals but that didn't help.

width = window.innerWidth
height = window.innerHeight

renderer = new THREE.WebGLRenderer({antialias: true})
renderer.setClearColor(0x8e8ed7)
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(width, height)
document.body.appendChild(renderer.domElement)

scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(35, width / height, 0.1, 3000)
camera.position.set(0, -100, 50)

controls = new THREE.OrbitControls(camera, renderer.domElement)
controls.minDistance = 40
controls.maxDistance = 1300

scene.add(camera, new THREE.AmbientLight(0xffffff, 0.48))
light = new THREE.PointLight(0xffffff, 0.55)

light.position.copy( camera.position )
light.position.y -= 80
light.position.x += 100
camera.add(light)

requestAnimationFrame(function animate(){
  requestAnimationFrame(animate)
  renderer.render(scene, camera)
})

function resize() {

    var aspect = window.innerWidth / window.innerHeight
    renderer.setSize(window.innerWidth, window.innerHeight)
    camera.aspect = aspect
    camera.updateProjectionMatrix()
    //controls.handleResize()
  }
window.onresize = resize

material = new THREE.MeshPhongMaterial({color: 0xFF7E14, specular: 0x111111, shininess: 75})

tube_a = new THREE.Mesh(new THREE.CylinderGeometry(6,6,20,32,1,true,0,-6.3))
tube_a.geometry.computeVertexNormals();

tube_b = new THREE.Mesh(new THREE.CylinderGeometry(8,8,20,32,1,true))
ring = new THREE.Mesh(new THREE.RingGeometry(6,8,32))

var geom = new THREE.Geometry()

ta1 = tube_a.clone()
geom.mergeMesh(ta1)
tb1 = tube_b.clone()
geom.mergeMesh(tb1)
r = ring.clone()
r.position.y += 10
r.rotateX((27*Math.PI)/18)
geom.mergeMesh(r)
r = ring.clone()
r.position.y -= 10
r.rotateX((9*Math.PI)/18)
geom.mergeMesh(r)
geom.mergeVertices()

p = [[4, 4],[-4, 4],[4, -4],[-4, -4]]

var sq = new THREE.Geometry()

for (i=0; i<4; i++) {
  c = p[i]
  sq.vertices.push(new THREE.Vector3(c[0],0,c[1]))
}
sq.faces.push( new THREE.Face3( 0, 1, 2 ) )
sq.faces.push( new THREE.Face3( 1, 3, 2 ) )
sq.computeVertexNormals()
sq = new THREE.Mesh(sq)
sq.position.y -= 10
geom.mergeMesh(sq)

scene.add(new THREE.Mesh(geom, material))
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

Upvotes: 4

Views: 1809

Answers (1)

Rabbid76
Rabbid76

Reputation: 210878

The error message

THREE.DirectGeometry.fromGeometry(): Undefined vertexUv

means, that the texture coordinates are missing.

You have to define texture coordinates, as you define the vertex coordinates:

p  = [[4, 4], [-4, 4], [4, -4], [-4, -4]]
uv = [[1, 1], [ 0, 1], [1,  0], [ 0,  0]]

The texture coordinates have to be added per face to Geometry.faceVertexUvs[0]

var sq = new THREE.Geometry()

for (i=0; i<4; i++) {
    c = p[i]
    sq.vertices.push(new THREE.Vector3(c[0],0,c[1]))
}

sq.faces.push( new THREE.Face3( 0, 1, 2 ) )
sq.faces.push( new THREE.Face3( 1, 3, 2 ) )

sq.faceVertexUvs[0] = [];
for (var i = 0; i < sq.faces.length ; i++) {

    var i0 = sq.faces[i].a,  
        i1 = sq.faces[i].b, 
        i2 = sq.faces[i].c;

    sq.faceVertexUvs[0].push([
        new THREE.Vector2(uv[i0][0], uv[i0][1]),
        new THREE.Vector2(uv[i1][0], uv[i1][1]),
        new THREE.Vector2(uv[i2][0], uv[i2][1])
    ]);
}

width = window.innerWidth
height = window.innerHeight

renderer = new THREE.WebGLRenderer({antialias: true})
renderer.setClearColor(0x8e8ed7)
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(width, height)
document.body.appendChild(renderer.domElement)

scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(35, width / height, 0.1, 3000)
camera.position.set(0, -100, 50)

controls = new THREE.OrbitControls(camera, renderer.domElement)
controls.minDistance = 40
controls.maxDistance = 1300

scene.add(camera, new THREE.AmbientLight(0xffffff, 0.48))
light = new THREE.PointLight(0xffffff, 0.55)

light.position.copy( camera.position )
light.position.y -= 80
light.position.x += 100
camera.add(light)

requestAnimationFrame(function animate(){
  requestAnimationFrame(animate)
  renderer.render(scene, camera)
})

function resize() {

    var aspect = window.innerWidth / window.innerHeight
    renderer.setSize(window.innerWidth, window.innerHeight)
    camera.aspect = aspect
    camera.updateProjectionMatrix()
    //controls.handleResize()
  }
window.onresize = resize

material = new THREE.MeshPhongMaterial({color: 0xFF7E14, specular: 0x111111, shininess: 75})

tube_a = new THREE.Mesh(new THREE.CylinderGeometry(6,6,20,32,1,true,0,-6.3))
tube_a.geometry.computeVertexNormals();

tube_b = new THREE.Mesh(new THREE.CylinderGeometry(8,8,20,32,1,true))
ring = new THREE.Mesh(new THREE.RingGeometry(6,8,32))

var geom = new THREE.Geometry()

ta1 = tube_a.clone()
geom.mergeMesh(ta1)
tb1 = tube_b.clone()
geom.mergeMesh(tb1)
r = ring.clone()
r.position.y += 10
r.rotateX((27*Math.PI)/18)
geom.mergeMesh(r)
r = ring.clone()
r.position.y -= 10
r.rotateX((9*Math.PI)/18)
geom.mergeMesh(r)
geom.mergeVertices()

p  = [[4, 4], [-4, 4], [4, -4], [-4, -4]]
uv = [[1, 1], [ 0, 1], [1,  0], [ 0,  0]]

var sq = new THREE.Geometry()

for (i=0; i<4; i++) {
  c = p[i]
  sq.vertices.push(new THREE.Vector3(c[0],0,c[1]))
}

sq.faces.push( new THREE.Face3( 0, 1, 2 ) )
sq.faces.push( new THREE.Face3( 1, 3, 2 ) )

sq.faceVertexUvs[0] = [];
for (var i = 0; i < sq.faces.length ; i++) {

  var i0 = sq.faces[i].a,  
      i1 = sq.faces[i].b, 
      i2 = sq.faces[i].c;

  sq.faceVertexUvs[0].push([
      new THREE.Vector2(uv[i0][0], uv[i0][1]),
      new THREE.Vector2(uv[i1][0], uv[i1][1]),
      new THREE.Vector2(uv[i2][0], uv[i2][1])
  ]);
}

sq.computeVertexNormals()
//sq.computeFaceNormals()

sq = new THREE.Mesh(sq)
sq.position.y -= 10
geom.mergeMesh(sq)

scene.add(new THREE.Mesh(geom, material))

function resize() {
    
    var aspect = window.innerWidth / window.innerHeight;
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = aspect;
    camera.updateProjectionMatrix();
    //controls.handleResize();
  }

window.onresize = resize;
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

Upvotes: 4

Related Questions