2012-04-03 7 views
3

Ich verwende three.js und CSG.js zusammen, um eine neue Form zu erstellen.Hinzufügen von Texturen zu einer three.js-Form, nachdem sie einen CSG.js-Prozess durchlaufen hat

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); 

Nicht die beste Code - Die wichtigsten Linien sind

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); 

Im eine Textur auf einen Schnitt Formen hinzuzufügen versuchen, die CSG umgewandelt wurde, dann auf drei zurück. Jedes Mal, wenn ich es tue, erhalte ich einen zufälligen Fehler von three.js. Ich müde MeshBasicMaterial zu "MeshPhongMaterial" und "MeshLambertMaterial", immer noch den gleichen Fehler.

Also meine Frage ist, mache ich etwas falsch oder ist es nicht möglich?

Antwort

2

Das ist eigentlich ganz einfach, wenn man CSG.js und THREE.CSG.js leicht ändert. UVs müssen in den CSG-Vertex-Prototyp eingeführt werden, und in THREE.CSG müssen die UVs in das CSG-Polygon hinein und aus diesem herausgeführt werden.

Die adaptierten Codes wie folgt aussehen:

Vertex Prototyp in 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) 
    ); 
    } 
}; 

Whole THREE.CSG.js Datei:

/* 
    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; 
    } 
}; 

diese Codes verwenden, die Anwendung CSG-Operationen zu zwei THREE.Geometries, die mit der gleichen Textur-Map texturiert sind, funktionieren gut, während die korrekten Vertex-UVs beibehalten werden.

Hoffe, dass Sie ein wenig helfen können!