首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在经过CSG.js过程后向three.js形状添加纹理

在经过CSG.js过程后向three.js形状添加纹理
EN

Stack Overflow用户
提问于 2012-04-04 02:52:13
回答 1查看 1.9K关注 0票数 3

我同时使用three.js和CSG.js来创建一个新的形状。

代码语言:javascript
复制
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);

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

代码语言:javascript
复制
    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",仍然是相同的错误。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-04 06:41:07

这实际上非常简单,只需稍微更改CSG.js和THREE.CSG.js即可。需要将UV引入CSG顶点原型,并且在THREE.CSG中,需要将UV传入和传出CSG多边形。

修改后的代码如下所示:

CSG.js中的顶点原型:

代码语言:javascript
复制
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文件:

代码语言:javascript
复制
/*
    THREE.CSG
    @author Chandler Prall <chandler.prall@gmail.com> 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操作应用于两个these。使用相同纹理贴图的textured纹理效果很好,同时保持正确的顶点UV。

希望这能对你有所帮助!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9999531

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档