在webgl中创建类似铅笔的主体

时间:2018-02-12 19:10:36

标签: javascript webgl

我正在尝试使用WEBGL创建此对象

enter image description here

我是WEBGL的初学者。我想使用我所做的那些代码来完成形状。到目前为止我创建了两个对象:锥形和圆柱形。这是我的圆锥和圆柱的代码。

function Cone(resolution){
        this.name = "cone";
        this.vertices = new Float32Array(3*(resolution+2));

        this.vertices[0] = 0.0;
        this.vertices[1] = 2.0;
        this.vertices[2] = 0.0;

        var radius = 1.0;
        var angle;
        var step = 6.283185307179586476925286766559 / resolution;

        var vertexoffset = 3;

        for(var i=0; i < resolution; i++){
            angle = step*i;
            this.vertices[vertexoffset] = radius * Math.cos(angle);
            this.vertices[vertexoffset+1] = 0.0;
            this.vertices[vertexoffset+2] = radius * Math.sin(angle);
            vertexoffset +=3;
        }

        this.vertices[vertexoffset] = 0.0;
        this.vertices[vertexoffset+1] = 0.0;
        this.vertices[vertexoffset+2] = 0.0;

        this.triangleIndices = new Uint16Array(3*2*resolution);

        var triangleoffset = 0;

        for(var i=0; i < resolution; i++){
            this.triangleIndices[triangleoffset] = 0;
            this.triangleIndices[triangleoffset+1] = 1 + (i % resolution);
            this.triangleIndices[triangleoffset+2] = 1 + ((i+1) % resolution);
            triangleoffset +=3;
        }

        for(var i=0; i < resolution; i++){
            this.triangleIndices[triangleoffset] = resolution + 1;
            this.triangleIndices[triangleoffset+1] = 1 + (i % resolution);
            this.triangleIndices[triangleoffset+2] =((i+1) % resolution); 
            triangleoffset +=3;
        }

        this.numVertices = this.vertices.length/3;
        this.numTriangles = this.triangleIndices.length/3;
}

function Cylinder(resolution){
        this.name = "cylinder";
        this.vertices = new Float32Array(3*(2*resolution+2));

        this.vertices[0] = 0.0;
        this.vertices[1] = 2.0;
        this.vertices[2] = 0.0;

        var radius = 1.0;
        var angle;
        var step = 6.283185307179586476925286766559 / resolution;

        var vertexoffset = 0;

        for(var i=0; i < resolution; i++){

            angle = step*i;

            this.vertices[vertexoffset] = radius * Math.cos(angle);
            this.vertices[vertexoffset+1] = 0.0;
            this.vertices[vertexoffset+2] = radius * Math.sin(angle);

            vertexoffset +=3;
        }

        for(var i=0; i < resolution; i++){

            angle = step*i;

            this.vertices[vertexoffset] = radius * Math.cos(angle);
            this.vertices[vertexoffset+1] = 2.0;
            this.vertices[vertexoffset+2] = radius * Math.sin(angle);

            vertexoffset +=3;
        }

        this.vertices[vertexoffset] = 0.0;
        this.vertices[vertexoffset+1] = 0.0;
        this.vertices[vertexoffset+2] = 0.0;

        vertexoffset +=3;

        this.vertices[vertexoffset] = 0.0;
        this.vertices[vertexoffset+1] = 2.0;
        this.vertices[vertexoffset+2] = 0.0;



        this.triangleIndices = new Uint16Array(3*4*resolution);

        var triangleoffset = 0;

        for(var i=0; i < resolution; i++){
            this.triangleIndices[triangleoffset] = i;
            this.triangleIndices[triangleoffset+1] = (i+1) % resolution;
            this.triangleIndices[triangleoffset+2] = (i % resolution) + resolution;
            triangleoffset +=3;


            this.triangleIndices[triangleoffset] = (i % resolution) + resolution;
            this.triangleIndices[triangleoffset+1] = (i+1) % resolution;
            this.triangleIndices[triangleoffset+2] = ((i+1) % resolution) + resolution;
            triangleoffset +=3;
        }

        for(var i=0; i < resolution; i++){
            this.triangleIndices[triangleoffset] = i;
            this.triangleIndices[triangleoffset+1] = ((i+1) % resolution);
            this.triangleIndices[triangleoffset+2] =2*resolution; 
            triangleoffset +=3;
        }

        for(var i=0; i < resolution; i++){
            this.triangleIndices[triangleoffset] = resolution + i;
            this.triangleIndices[triangleoffset+1] = ((i+1) % resolution) + 
    resolution;
            this.triangleIndices[triangleoffset+2] =2*resolution +1; 
            triangleoffset +=3;
        }

        this.numVertices = this.vertices.length/3;
        this.numTriangles = this.triangleIndices.length/3;
}

我想使用这些代码并将它们组合起来以完成身体!

1 个答案:

答案 0 :(得分:1)

如果您有一个圆柱体(顶部和底部圆盘),那么您只需更改其中一个圆盘中心点的高度即可得到您想要的结果。

KA_Com.Parameters("pFixtureList").Value = true;

参见示例:

&#13;
&#13;
this.vertices[0] = 0.0;
this.vertices[1] = 4.0; // Change this from 2.0 to e.g 4.0
this.vertices[2] = 0.0;
&#13;
var renderer, scene, camera, controls;

function CylinderGeometry(radius, holeRadius, height, segments, openEnded) {
    THREE.Geometry.call(this);
    this.type = 'CylinderGeometry';
    this.fromBufferGeometry(new CylinderBufferGeometry(radius, holeRadius, height, segments, openEnded));
    this.mergeVertices();
}

CylinderGeometry.prototype = Object.create(THREE.Geometry.prototype);
CylinderGeometry.prototype.constructor = CylinderGeometry;

function CylinderBufferGeometry(radius, holeRadius, height, segments, openEnded) {

    THREE.BufferGeometry.call(this);
    this.type = 'CylinderBufferGeometry';
    var scope = this;

    // buffers

    var indices = [];
    var vertices = [];
    var normals = [];
    var uvs = [];

    Cylinder(20.0);

    this.setIndex(indices);
    this.addAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
    this.addAttribute('normal', new THREE.Float32BufferAttribute(normals, 3));
    this.addAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));

    function Cylinder(resolution) {

        var radius = 1.0;
        var angle;
        var step = 6.283185307179586476925286766559 / resolution;

        var h0 = -1;
        var h1 = 0.5;
        var h2 = 2.0;

        var vertexoffset = 0;
        var uvOffset = 0;
        for(var i=0; i < resolution; i++){

            angle = step*i;

            vertices[vertexoffset] = radius * Math.cos(angle);
            vertices[vertexoffset+1] = h0;
            vertices[vertexoffset+2] = radius * Math.sin(angle);

            normals[vertexoffset] = Math.cos(angle);
            normals[vertexoffset+1] = h0;
            normals[vertexoffset+2] = Math.sin(angle);

            uvs[uvOffset] = i/resolution
            uvs[uvOffset+1] = 2.0;

            vertexoffset +=3;
            uvOffset += 2;
        }

        for(var i=0; i < resolution; i++){

            angle = step * i;

            vertices[vertexoffset] = radius * Math.cos(angle);
            vertices[vertexoffset+1] = h1;
            vertices[vertexoffset+2] = radius * Math.sin(angle);

            normals[vertexoffset] = Math.cos(angle)
            normals[vertexoffset+1] = h1;
            normals[vertexoffset+2] = Math.sin(angle);

            uvs[uvOffset] = i/resolution
            uvs[uvOffset+1] = 2.0;

            vertexoffset +=3;
            uvOffset += 2;
        }

        vertices[vertexoffset] = 0.0;
        vertices[vertexoffset+1] = h0;
        vertices[vertexoffset+2] = 0.0;
        normals[vertexoffset] = 0.0
        normals[vertexoffset+1] = -1.0;
        normals[vertexoffset+2] = 0.0;
        uvs[uvOffset] = 0.5
        uvs[uvOffset+1] = 0.5;

        vertexoffset +=3;

        vertices[vertexoffset] = 0.0;
        vertices[vertexoffset+1] = h2;
        vertices[vertexoffset+2] = 0.0;
        normals[vertexoffset] = 0.0
        normals[vertexoffset+1] = 1.0;
        normals[vertexoffset+2] = 0.0;
        uvs[uvOffset] = 0.0
        uvs[uvOffset+1] = 1.0;

        var groupOffset = 0;
        var groupCount = 0;
        var triangleoffset = 0;
        var triangleIndices = indices;
        for(var i=0; i < resolution; i++){
            triangleIndices[triangleoffset] = i;
            triangleIndices[triangleoffset+2] = (i+1) % resolution;
            triangleIndices[triangleoffset+1] = (i % resolution) + resolution;
            triangleoffset +=3;
            groupCount += 3;

            triangleIndices[triangleoffset] = (i % resolution) + resolution;
            triangleIndices[triangleoffset+2] = (i+1) % resolution;
            triangleIndices[triangleoffset+1] = ((i+1) % resolution) + resolution;
            triangleoffset +=3;
            groupCount += 3;
        }

        scope.addGroup(groupOffset, groupCount-groupOffset, 0);
        groupOffset = groupCount;

        for(var i=0; i < resolution; i++){
            triangleIndices[triangleoffset] = i;
            triangleIndices[triangleoffset+1] = ((i+1) % resolution);
            triangleIndices[triangleoffset+2] =2*resolution; 
            triangleoffset +=3;
            groupCount += 3;
        }

        for(var i=0; i < resolution; i++){
            triangleIndices[triangleoffset] = resolution + i;
            triangleIndices[triangleoffset+2] = ((i+1) % resolution) + resolution;
            triangleIndices[triangleoffset+1] =2*resolution +1; 
            triangleoffset +=3;
            groupCount += 3;
        }

        scope.addGroup(groupOffset, groupCount-groupOffset, 1);
    }
}

CylinderBufferGeometry.prototype = Object.create(THREE.BufferGeometry.prototype);
CylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;

function init() {

    // renderer
    renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.setClearColor(0x404040, 1);
    document.body.appendChild( renderer.domElement );
    window.onresize = resize;

    // scene
    scene = new THREE.Scene();
    
    // camera
    camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
    camera.position.set( 3, 3, 3 );

    // controls
    controls = new THREE.OrbitControls( camera );

    var loader = new THREE.TextureLoader();
    loader.setCrossOrigin("");
    var texture1 = loader.load("https://threejs.org/examples/textures/hardwood2_diffuse.jpg");
    texture1.wrapS = texture1.wrapT = THREE.RepeatWrapping;
    texture1.repeat.set(2.0*Math.PI, 1.0);
    var texture2 = loader.load("https://threejs.org/examples/textures/crate.gif");
    texture2.wrapS = texture1.wrapT = THREE.RepeatWrapping;
    texture2.repeat.set(1.0, 1.0);
    
    // materials
    material_1 = new THREE.MeshBasicMaterial({
        map: texture1
        });
    material_2 = new THREE.MeshBasicMaterial({
        map: texture2
        });
    
    var geometry = new CylinderGeometry(1.0, 0.3, 0.5, 16, false);
    var mesh = new THREE.Mesh(geometry, [material_1, material_2]);
    mesh.material.side = THREE.DoubleSide;
    
    // mesh
    scene.add( mesh );

    lastTime = Date.now();
}

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

function animate() {

    requestAnimationFrame( animate );
    renderer.render( scene, camera );
}

init();
animate();
&#13;
&#13;
&#13;