Вращение прямоугольной призмы на 45 градусов приводит к искажению треугольников - PullRequest
0 голосов
/ 26 октября 2019

Я пытаюсь повернуть и перевести прямоугольную призму. Конечная цель состоит в том, чтобы сделать две прямоугольные призмы, которые выглядят так со стороны:

Rectangular prisms viewed from side

Однако, в настоящее время у меня есть это как сторона исоответственно, вид сверху:

enter image description here enter image description here

Кроме того, изменение угла камеры от вида сбоку к виду сверху искажаетфигуры далее:

enter image description here enter image description here

Мне удалось отобразить один прямоугольник без поворотов просто отлично, поэтому япредполагаю, что я неправильно вращаю свой прямоугольник.

var rectangle = [
    10.0, 10.0, 40.0, -10.0, 10.0, 40.0, -10.0, 10.0, 0.0, 10.0, 10.0, 0.0, // v0-v1-v2-v3 front
    10.0, 10.0, 40.0, 10.0, 10.0, 0.0, 10.0, -10.0, 0.0, 10.0, -10.0, 40.0, // v0-v3-v4-v5 right
    10.0, 10.0, 40.0, 10.0, -10.0, 40.0, -10.0, -10.0, 40.0, -10.0, 10.0, 40.0, // v0-v5-v6-v1 up
    -10.0, 10.0, 40.0, -10.0, -10.0, 40.0, -10.0, -10.0, 0.0, -10.0, 10.0, 0.0, // v1-v6-v7-v2 left
    -10.0, -10.0, 0.0, 10.0, -10.0, 0.0, 10.0, 10.0, 0.0, -10.0, 10.0, 0.0, // v7-v4-v3-v2 down
    10.0, -10.0, 0.0, -10.0, -10.0, 0.0, -10.0, 40.0, 10.0, -10.0, -10.0, 40.0  // v4-v7-v6-v5 back
];

var twoRects = [//includes first rectangle, second rectangle to be added by later plotRect function
    10.0, 10.0, 40.0, -10.0, 10.0, 40.0, -10.0, 10.0, 0.0, 10.0, 10.0, 0.0, // v0-v1-v2-v3 front
    10.0, 10.0, 40.0, 10.0, 10.0, 0.0, 10.0, -10.0, 0.0, 10.0, -10.0, 40.0, // v0-v3-v4-v5 right
    10.0, 10.0, 40.0, 10.0, -10.0, 40.0, -10.0, -10.0, 40.0, -10.0, 10.0, 40.0, // v0-v5-v6-v1 up
    -10.0, 10.0, 40.0, -10.0, -10.0, 40.0, -10.0, -10.0, 0.0, -10.0, 10.0, 0.0, // v1-v6-v7-v2 left
    -10.0, -10.0, 0.0, 10.0, -10.0, 0.0, 10.0, 10.0, 0.0, -10.0, 10.0, 0.0, // v7-v4-v3-v2 down
    10.0, -10.0, 0.0, -10.0, -10.0, 0.0, -10.0, 40.0, 10.0, -10.0, -10.0, 40.0  // v4-v7-v6-v5 back
];

//adds 2nd rectangle
function plotRect() {

    var rotateMatrix1 = new Matrix4();
    var rotateMatrix2 = new Matrix4();
    //rotateMatrix1.setRotate(Math.PI / 2, 1, 0, 0);
    //roate 90degrres about y axis
    rotateMatrix2.setRotate(Math.PI / 2, 0, 1, 0);

    //loops through verticies of rectangle, rotating the vectors.
    for (var i = 0; i < rectangle.length; i += 3) {

        let v = new Vector3([rectangle[i], rectangle[i + 1], rectangle[i + 2]]);
        v = rotateMatrix1.multiplyVector3(v);
        v = rotateMatrix2.multiplyVector3(v);
        twoRects.push(v.elements[0], v.elements[1], v.elements[2] + 40);
    }
}

шейдеров, основной и инициализирующий буферные функции vertbex:

// // Vertex shader program
var VSHADER_SOURCE =
    'attribute vec4 a_Position;\n' +
    'attribute vec4 a_Color;\n' +
    'attribute vec4 a_Normal;\n' +        // Normal
    'uniform mat4 u_ViewMatrix;\n' +
    'uniform mat4 u_ProjMatrix;\n' +
    'uniform vec3 u_LightColor;\n' +     // Light color
    'uniform vec3 u_LightDirection;\n' + // Light direction (in the world coordinate, normalized)
    'varying vec4 v_Color;\n' +
    'void main() {\n' +
    '   gl_Position = u_ProjMatrix * u_ViewMatrix * a_Position;\n' +
    // Make the length of the normal 1.0
    '  vec3 normal = normalize(a_Normal.xyz);\n' +
    // Dot product of the light direction and the orientation of a surface (the normal)
    '  float nDotL = max(dot(u_LightDirection, normal), 0.0);\n' +
    // Calculate the color due to diffuse reflection
    '  vec3 diffuse = u_LightColor * a_Color.rgb * nDotL;\n' +
    '  v_Color = vec4(diffuse, a_Color.a);\n' +
    '}\n';

// Fragment shader program
var FSHADER_SOURCE =
    '#ifdef GL_ES\n' +
    'precision mediump float;\n' +
    '#endif\n' +
    'varying vec4 v_Color;\n' +
    'void main() {\n' +
    '  gl_FragColor = v_Color;\n' +
    '}\n';

function main() {
    // Retrieve <canvas> element
    var canvas = document.getElementById('webgl');

    // Get the rendering context for WebGL
    var gl = getWebGLContext(canvas);
    if (!gl) {
        console.log('Failed to get the rendering context for WebGL');
        return;
    }

    // Initialize shaders
    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
        console.log('Failed to intialize shaders.');
        return;
    }
    // Set the vertex information
    var n = initVertexBuffers(gl);
    if (n < 0) {
        console.log('Failed to set the vertex information');
        return;
    }

    // Set the clear color and enable the depth test
    gl.clearColor(0.0, 0.0, 0.0, 0.0);
    gl.enable(gl.DEPTH_TEST);

    // Get the storage locations of u_ViewMatrix and u_ProjMatrix variables
    var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
    var u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
    if (!u_ViewMatrix || !u_ProjMatrix) {
        console.log('Failed to get u_ViewMatrix or u_ProjMatrix');
        return;
    }
    //Get the storage locations of u_LightColor and u_LightDirection variables
    var u_LightColor = gl.getUniformLocation(gl.program, 'u_LightColor');
    var u_LightDirection = gl.getUniformLocation(gl.program, 'u_LightDirection');
    if (!u_LightColor || !u_LightDirection) {
        console.log('Failed to get the storage location');
        return;
    }

    // Create the matrix to specify the view matrix
    var viewMatrix = new Matrix4();
    // Create the matrix to specify the viewing volume and pass it to u_ProjMatrix
    var projMatrix = new Matrix4();

    // set ortho or perspective view
    if (document.getElementById("2").value == "Orthographic View") {
        projMatrix.setOrtho(-200.0, 200.0, -200.0, 200.0, -1000.0, 1000.0);
    }
    else if (document.getElementById("2").value == "Perspective View") {
        projMatrix.setPerspective(30, canvas.width / canvas.height, 1, 100);
    }
    gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
    // Set the matrix to be used for to set the camera view
    if (document.getElementById("1").value == "Top View") {
        viewMatrix.setLookAt(0, 0, 200, 0, 0, 0, 0, 1, 0);
    }
    else if (document.getElementById("1").value == "Side View") {
        viewMatrix.setLookAt(0, 200, 0, 0, 0, 0, 0, 0, 1);
    }
    // Pass the view projection matrix
    gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements);

    //get the storage locations of u_LightColor and u_LightDirection
    var u_LightColor = gl.getUniformLocation(gl.program, 'u_LightColor');
    var u_LightDirection = gl.getUniformLocation(gl.program, 'u_LightDirection');
    if (!u_LightColor || !u_LightDirection) {
        console.log('Failed to get the storage location');
        return;
    }

    //Set the light color (white)
    gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);
    // Set the light direction (in the world coordinate)
    var lightDirection = new Vector3([1, 1, 1]);
    lightDirection.normalize();     // Normalize
    gl.uniform3fv(u_LightDirection, lightDirection.elements);

    // Clear color and depth buffer
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    // Draw the cylinder
    gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
}

function initVertexBuffers(gl) {
    plotRect();
    var vertices = new Float32Array(twoRects);
    console.log(twoRects);

    var twoRectsIndices = [];
    var newColors = [];
    for (var i = 0; i < twoRects.length; i++) {
        twoRectsIndices.push(i);
        newColors.push(1.0, 0.0, 0.0);
    }
    var colors = new Float32Array([    // Colors
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v0-v1-v2-v3 front
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v0-v3-v4-v5 right
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v0-v5-v6-v1 up
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v1-v6-v7-v2 left
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v7-v4-v3-v2 down
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v4-v7-v6-v5 back
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v0-v1-v2-v3 front
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v0-v3-v4-v5 right
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v0-v5-v6-v1 up
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v1-v6-v7-v2 left
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,     // v7-v4-v3-v2 down
        1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0     // v4-v7-v6-v5 back
    ]);


    var normals = new Float32Array([    // Normal
        0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,  // v0-v1-v2-v3 front
        1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,  // v0-v3-v4-v5 right
        0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,  // v0-v5-v6-v1 up
        -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0,  // v1-v6-v7-v2 left
        0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0,  // v7-v4-v3-v2 down
        0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0,   // v4-v7-v6-v5 back
        0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,  // v0-v1-v2-v3 front
        1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,  // v0-v3-v4-v5 right
        0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,  // v0-v5-v6-v1 up
        -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0,  // v1-v6-v7-v2 left
        0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0,  // v7-v4-v3-v2 down
        0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0   // v4-v7-v6-v5 back
    ]);


    // Indices of the vertices
    var indices = new Uint8Array([
        0, 1, 2, 0, 2, 3,    // front
        4, 5, 6, 4, 6, 7,    // right
        8, 9, 10, 8, 10, 11,    // up
        12, 13, 14, 12, 14, 15,    // left
        16, 17, 18, 16, 18, 19,    // down
        20, 21, 22, 20, 22, 23,     // back
        24, 25, 26, 24, 27, 28,    // front
        28, 29, 30, 28, 30, 31,    // right
        32, 33, 34, 32, 34, 35,    // up
        34, 35, 36, 34, 36, 37,    // left
        38, 39, 40, 38, 40, 41,    // down
        42, 43, 44, 42, 44, 45     // back
    ]);


    //Indices of the vertices
    var indices = new Uint8Array(twoRectsIndices);


    //Write the vertex property to buffers (coordinates, colors and normals)
    if (!initArrayBuffer(gl, 'a_Position', vertices, 3, gl.FLOAT)) return -1;
    if (!initArrayBuffer(gl, 'a_Color', colors, 3, gl.FLOAT)) return -1;
    if (!initArrayBuffer(gl, 'a_Normal', normals, 3, gl.FLOAT)) return -1;

    //Write the indices to the buffer object
    var indexBuffer = gl.createBuffer();
    if (!indexBuffer) {
        console.log('Failed to create the buffer object');
        return false;
    }

    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

    return indices.length;
}

function initArrayBuffer(gl, attribute, data, num, type) {
    // Create a buffer object
    var buffer = gl.createBuffer();
    if (!buffer) {
        console.log('Failed to create the buffer object');
        return false;
    }
    // Write date into the buffer object
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
    // Assign the buffer object to the attribute variable
    var a_attribute = gl.getAttribLocation(gl.program, attribute);
    if (a_attribute < 0) {
        console.log('Failed to get the storage location of ' + attribute);
        return false;
    }
    gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);
    // Enable the assignment of the buffer object to the attribute variable
    gl.enableVertexAttribArray(a_attribute);

    gl.bindBuffer(gl.ARRAY_BUFFER, null);

    return true;
}
...