2012-04-03 54 views
3

我将three.js和CSG.js一起使用以创建新形状。通过CSG.js过程将纹理添加到three.js形状

var materialText = new THREE.MeshBasicMaterial({ 
     map: THREE.ImageUtils.loadTexture(rel_path_name+"images/wood.jpg") 
}); 
var material = new THREE.MeshLambertMaterial({ 
    color: 0xFFFFFF 
}); 
var cylinder = new THREE.Mesh(new THREE.CylinderGeometry(120, 100, 300, 40, 50, false), material); 
cylinder.position.y = 100; 
var bodyMainCSG = new THREE.CSG.toCSG(cylinder); 

var cutOutShapeMaterial = new THREE.MeshLambertMaterial({ 
    color: 0x000000 
}); 

var bodyMainFront = new THREE.Mesh(new THREE.CylinderGeometry(200, 190, 300, 40, 50, false), material); 
bodyMainFront.position.z = -126; 
bodyMainFront.position.y = 100; 
var bodyMainFrontCSG = new THREE.CSG.toCSG(bodyMainFront); 

var cutOutShapeFront = new THREE.Mesh(new THREE.CubeGeometry(300,300,200), cutOutShapeMaterial); 
cutOutShapeFront.position.z = 140; 
cutOutShapeFront.position.y = 100; 
var cutOutShapeFrontCSG = new THREE.CSG.toCSG(cutOutShapeFront); 

var cutOutShapeBack = new THREE.Mesh(new THREE.CubeGeometry(300,300,200), cutOutShapeMaterial); 
cutOutShapeBack.position.z = -140; 
cutOutShapeBack.position.y = 100; 
var cutOutShapeBackCSG = new THREE.CSG.toCSG(cutOutShapeBack); 

var spareCube = new THREE.Mesh(new THREE.CubeGeometry(400,300,400), cutOutShapeMaterial); 
    spareCube.position.z = -160; 
    spareCube.position.y = 100; 
    var spareCubeCSG = new THREE.CSG.toCSG(spareCube); 


    var bodyMainBack = new THREE.Mesh(new THREE.CylinderGeometry(220, 210, 300, 40, 50, false), material); 
bodyMainBack.position.z = 148; 
bodyMainBack.position.y = 100; 
var bodyMainBackCSG = new THREE.CSG.toCSG(bodyMainBack); 

var spareCube2 = new THREE.Mesh(new THREE.CubeGeometry(440,300,440), cutOutShapeMaterial); 
    spareCube2.position.z = 180; 
    spareCube2.position.y = 100; 
var spareCube2CSG = new THREE.CSG.toCSG(spareCube2); 
//Front creation Shape - Mixture of body main shape/Cube cut out shape 
var extraCircle = bodyMainFrontCSG.subtract(spareCubeCSG); 




//Front creation Shape - Mixture of body main shape/Cube cut out shape 
var extraCircle = bodyMainFrontCSG.subtract(spareCubeCSG); 
var extraCircleBack = bodyMainBackCSG.subtract(spareCube2CSG); 
var frontCreationShape = bodyMainCSG.subtract(cutOutShapeFrontCSG); 
var backCreationShape = frontCreationShape.subtract(cutOutShapeBackCSG); 
var geometry = extraCircle.union(backCreationShape); 
var geometry = geometry.union(extraCircleBack); 
//var bulkRemoval = bodyMainCSG.subtract(cubeBulkCG); 
//var geometry = bulkRemoval.subtract(frontCreationShape); 

var mesh = new THREE.Mesh(THREE.CSG.fromCSG(geometry), materialText); 

不是最好的代码 - 最重要的线是

var materialText = new THREE.MeshBasicMaterial({ 
     map: THREE.ImageUtils.loadTexture(rel_path_name+"images/wood.jpg") 
    }); 

    var mesh = new THREE.Mesh(THREE.CSG.fromCSG(geometry), materialText); 

我试着将纹理添加到已转换为CSG,然后再返回到三个切割形状。每次我这样做,我都会从three.js中得到一个随机错误。我厌倦了将MeshBasicMaterial改为“MeshPhongMaterial”和“MeshLambertMaterial”,仍然是同样的错误。

所以我的问题是,我做错了什么或者是不可能的?

回答

2

这实际上很容易通过稍微改变CSG.js和THREE.CSG.js。需要将UV引入到CSG顶点原型中,并且在THREE.CSG中需要将UV传入和传出CSG多边形。

的适应代码如下所示:

顶点原型CSG.js:

CSG.Vertex = function(pos, normal, uv) { 
    this.pos = new CSG.Vector(pos); 
    this.normal = new CSG.Vector(normal); 
    // modification 
    this.uv = new CSG.Vector(uv); 
}; 

CSG.Vertex.prototype = { 
    clone: function() { 
    return new CSG.Vertex(
     this.pos.clone(), 
     this.normal.clone(), 
     // modification 
     this.uv.clone() 
    ); 
    }, 

    // Invert all orientation-specific data (e.g. vertex normal). Called when the 
    // orientation of a polygon is flipped. 
    flip: function() { 
    this.normal = this.normal.negated(); 
    }, 

    // Create a new vertex between this vertex and `other` by linearly 
    // interpolating all properties using a parameter of `t`. Subclasses should 
    // override this to interpolate additional properties. 
    interpolate: function(other, t) { 
    return new CSG.Vertex(
     this.pos.lerp(other.pos, t), 
     this.normal.lerp(other.normal, t), 
     // modification 
     this.uv.lerp(other.uv, t) 
    ); 
    } 
}; 

全THREE.CSG.js文件:

/* 
    THREE.CSG 
    @author Chandler Prall <[email protected]> http://chandler.prallfamily.com 

    Wrapper for Evan Wallace's CSG library (https://github.com/evanw/csg.js/) 
    Provides CSG capabilities for Three.js models. 

    Provided under the MIT License 
*/ 

THREE.CSG = { 
    toCSG: function (three_model, offset, rotation) { 
     var i, geometry, offset, polygons, vertices, rotation_matrix; 

     if (!CSG) { 
      throw 'CSG library not loaded. Please get a copy from https://github.com/evanw/csg.js'; 
     } 

     if (three_model instanceof THREE.Mesh) { 
      geometry = three_model.geometry; 
      offset = offset || three_model.position; 
      rotation = rotation || three_model.rotation; 
     } else if (three_model instanceof THREE.Geometry) { 
      geometry = three_model; 
      offset = offset || new THREE.Vector3(0, 0, 0); 
      rotation = rotation || new THREE.Vector3(0, 0, 0); 
     } else { 
      throw 'Model type not supported.'; 
     } 
     rotation_matrix = new THREE.Matrix4().setRotationFromEuler(rotation); 

     var polygons = []; 
     for (i = 0; i < geometry.faces.length; i++) { 
      if (geometry.faces[i] instanceof THREE.Face3) { 


       vertices = []; 
       vertices.push(new CSG.Vertex(rotation_matrix.multiplyVector3(geometry.vertices[geometry.faces[i].a].clone().addSelf(offset)), [ geometry.faces[i].normal.x, geometry.faces[i].normal.y, geometry.faces[i].normal.z ], [ geometry.faceVertexUvs[0][i][0].u, geometry.faceVertexUvs[0][i][0].v, 0 ])); 
       vertices.push(new CSG.Vertex(rotation_matrix.multiplyVector3(geometry.vertices[geometry.faces[i].b].clone().addSelf(offset)), [ geometry.faces[i].normal.x, geometry.faces[i].normal.y, geometry.faces[i].normal.z ], [ geometry.faceVertexUvs[0][i][1].u, geometry.faceVertexUvs[0][i][1].v, 0 ])); 
       vertices.push(new CSG.Vertex(rotation_matrix.multiplyVector3(geometry.vertices[geometry.faces[i].c].clone().addSelf(offset)), [ geometry.faces[i].normal.x, geometry.faces[i].normal.y, geometry.faces[i].normal.z ], [ geometry.faceVertexUvs[0][i][2].u, geometry.faceVertexUvs[0][i][2].v, 0 ])); 
       polygons.push(new CSG.Polygon(vertices)); 

      } else if (geometry.faces[i] instanceof THREE.Face4) { 

       vertices = []; 
       vertices.push(new CSG.Vertex(rotation_matrix.multiplyVector3(geometry.vertices[geometry.faces[i].a].clone().addSelf(offset)), [ geometry.faces[i].normal.x, geometry.faces[i].normal.y, geometry.faces[i].normal.z ], [ geometry.faceVertexUvs[0][i][0].u, geometry.faceVertexUvs[0][i][0].v, 0 ])); 
       vertices.push(new CSG.Vertex(rotation_matrix.multiplyVector3(geometry.vertices[geometry.faces[i].b].clone().addSelf(offset)), [ geometry.faces[i].normal.x, geometry.faces[i].normal.y, geometry.faces[i].normal.z ], [ geometry.faceVertexUvs[0][i][1].u, geometry.faceVertexUvs[0][i][1].v, 0 ])); 
       vertices.push(new CSG.Vertex(rotation_matrix.multiplyVector3(geometry.vertices[geometry.faces[i].d].clone().addSelf(offset)), [ geometry.faces[i].normal.x, geometry.faces[i].normal.y, geometry.faces[i].normal.z ], [ geometry.faceVertexUvs[0][i][3].u, geometry.faceVertexUvs[0][i][3].v, 0 ])); 
       polygons.push(new CSG.Polygon(vertices)); 

       vertices = []; 
       vertices.push(new CSG.Vertex(rotation_matrix.multiplyVector3(geometry.vertices[geometry.faces[i].b].clone().addSelf(offset)), [ geometry.faces[i].normal.x, geometry.faces[i].normal.y, geometry.faces[i].normal.z ], [ geometry.faceVertexUvs[0][i][1].u, geometry.faceVertexUvs[0][i][1].v, 0 ])); 
       vertices.push(new CSG.Vertex(rotation_matrix.multiplyVector3(geometry.vertices[geometry.faces[i].c].clone().addSelf(offset)), [ geometry.faces[i].normal.x, geometry.faces[i].normal.y, geometry.faces[i].normal.z ], [ geometry.faceVertexUvs[0][i][2].u, geometry.faceVertexUvs[0][i][2].v, 0 ])); 
       vertices.push(new CSG.Vertex(rotation_matrix.multiplyVector3(geometry.vertices[geometry.faces[i].d].clone().addSelf(offset)), [ geometry.faces[i].normal.x, geometry.faces[i].normal.y, geometry.faces[i].normal.z ], [ geometry.faceVertexUvs[0][i][3].u, geometry.faceVertexUvs[0][i][3].v, 0 ])); 
       polygons.push(new CSG.Polygon(vertices)); 

      } else { 
       throw 'Model contains unsupported face.'; 
      } 
     } 

     return CSG.fromPolygons(polygons); 
    }, 

    fromCSG: function(csg_model) { 
     var i, j, vertices, face, 
      three_geometry = new THREE.Geometry(), 
      polygons = csg_model.toPolygons(); 

     if (!CSG) { 
      throw 'CSG library not loaded. Please get a copy from https://github.com/evanw/csg.js'; 
     } 

     for (i = 0; i < polygons.length; i++) { 

      // Vertices 
      vertices = []; 
      for (j = 0; j < polygons[i].vertices.length; j++) { 
       vertices.push(this.getGeometryVertice(three_geometry, polygons[i].vertices[j].pos)); 
      } 
      if (vertices[0] === vertices[vertices.length - 1]) { 
       vertices.pop(); 
      } 

      for (var j = 2; j < vertices.length; j++) { 
       face = new THREE.Face3(vertices[0], vertices[j-1], vertices[j], new THREE.Vector3().copy(polygons[i].plane.normal)); 
       three_geometry.faces.push(face); 
       three_geometry.faceVertexUvs[0].push([ 
        new THREE.UV(polygons[i].vertices[0].uv.x, polygons[i].vertices[0].uv.y), 
        new THREE.UV(polygons[i].vertices[j-1].uv.x, polygons[i].vertices[j-1].uv.y), 
        new THREE.UV(polygons[i].vertices[j].uv.x, polygons[i].vertices[j].uv.y) 
       ]); 
      } 
     } 

     three_geometry.computeBoundingBox(); 

     return three_geometry; 
    }, 

    getGeometryVertice: function (geometry, vertice_position) { 
     var i; 
     for (i = 0; i < geometry.vertices.length; i++) { 
      if (geometry.vertices[i].x === vertice_position.x && geometry.vertices[i].y === vertice_position.y && geometry.vertices[i].z === vertice_position.z) { 
       // Vertice already exists 
       return i; 
      } 
     }; 

     geometry.vertices.push(new THREE.Vector3(vertice_position.x, vertice_position.y, vertice_position.z)); 
     return geometry.vertices.length - 1; 
    } 
}; 

使用这些代码,应用CSG的操作到两个THREE.Geometry的纹理和相同的纹理贴图效果很好,同时保持正确的顶点UV。

希望可以帮助你一点!