alchemist/js/main.js
lhark a3979b9300 Ajout de transformations, css bootstrap
Les fichiers de resources ont été bougés dans leur dossiers
propres (css, js, fonts).
La position de la souris dans le canvas est maintenant correcte quelle
que soit la position du canvas dans la page.
2017-12-09 23:53:20 -05:00

360 lines
12 KiB
JavaScript

// Prénoms, noms et matricule des membres de l'équipe:
// - Prénom1 NOM1 (matricule1)
// - Prénom2 NOM2 (matricule2)
// déclaration d'une structure pour contenir toutes les variables globales
var glob = { };
addTransformation(null, "rotation");
addTransformation(null, "translation");
addTransformation(null, "scale");
function addTrans(event)
{
var div = document.createElement("div");
var text = document.createTextNode("Plopiloup");
var transdiv = document.getElementById("transformations");
div.appendChild(text);
transdiv.appendChild(div);
}
function addTransformation(event, type)
{
var table = document.getElementById("trans-list");
var glyphClass;
switch (type) {
case "rotation":
glyphClass = "glyphicon-repeat";
break;
case "translation":
glyphClass = "glyphicon-move";
break;
case "scale":
glyphClass = "glyphicon-resize-small";
break;
default:
glyphClass = "glyphicon-alert";
console.log("Unknown transformation type " + type);
break;
}
var tr = table.insertRow(-1);
tr.classList.add(type);
var span = document.createElement("span");
span.classList.add("glyphicon", glyphClass);
var td = tr.insertCell(-1);
td.appendChild(span);
var param = ["x", "y", "z", "𝜃"];
for (var i in param) {
td = tr.insertCell(-1);
if (param[i] === "𝜃" && type !== "rotation")
break;
var input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("value", type === "scale" ? "1" : "0");
input.setAttribute("name", param[i]);
input.setAttribute("class", "form-control");
input.addEventListener("change", updateTransformations, false);
input.addEventListener("keyup", updateTransformations, false);
td.appendChild(input);
}
var button = document.createElement('button');
button.classList.add("btn", "btn-danger", "btn-sm");
button.setAttribute("type", "button");
button.addEventListener("click", removeTransformation, false);
span = document.createElement("span");
span.classList.add("glyphicon", "glyphicon-trash");
button.appendChild(span);
tr.insertCell(-1).appendChild(button);
}
function removeTransformation(event)
{
var tr = event.target.parentNode.parentNode;
tr.parentNode.removeChild(tr);
updateTransformations(event);
}
function updateTransformations(event)
{
glob.transformations = [];
var table = document.getElementById("trans-list");
var x,y,z,𝜃,row,type;
for (var i = 1; i < table.rows.length; i++) {
row = table.rows[i];
x = row.querySelector('input[name="x"]').value;
y = row.querySelector('input[name="y"]').value;
z = row.querySelector('input[name="z"]').value;
𝜃 = row.querySelector('input[name="𝜃"]');
if (𝜃 !== null)
𝜃 = 𝜃.value;
type = row.className;
glob.transformations.push({type: type, x: x, y: y, z: z, 𝜃: 𝜃});
}
}
function handleMouseDown(event)
{
glob.mouseDown = true;
var rect = glob.canevas.getBoundingClientRect();
glob.positionSourisX = event.clientX - rect.left;
glob.positionSourisY = event.clientY - rect.top;
}
function handleMouseUp(event)
{
glob.mouseDown = false;
glob.positionSourisX = null;
glob.positionSourisY = null;
}
function handleMouseMove(event)
{
if (!glob.mouseDown) return;
var rect = glob.canevas.getBoundingClientRect();
glob.positionSourisX = event.clientX - rect.left;
glob.positionSourisY = event.clientY - rect.top;
}
//
// makeRepere
//
// Create a repere with vertices, normals and texCoords. Create VBOs for each as well as the index array.
// Return an object with the following properties:
//
// normalObject WebGLBuffer object for normals
// texCoordObject WebGLBuffer object for texCoords
// vertexObject WebGLBuffer object for vertices
// indexObject WebGLBuffer object for indices
// numIndices The number of indices in the indexObject
//
function makeRepere(ctx)
{
// box
// v2
// |
// |
// |
// v0 o------v1
// /
// v3
//
// vertex coords array
var vertices = new Float32Array(
[ 0, 0, 0, 1, 0, 0, // v0 -> v1 vec X
0, 0, 0, 0, 1, 0, // v0 -> v2 vec Y
0, 0, 0, 0, 0, 1 ]// v0 -> v3 vec Z
);
// colors array
var colors = new Float32Array(
[ 1, 0, 0, 1, 0, 0, // v0 -> v1 vec X
0, 1, 0, 0, 1, 0, // v0 -> v2 vec Y
0, 0, 1, 0, 0, 1 ]// v0 -> v3 vec Z
);
// index array
var indices = new Uint8Array(
[ 0, 1,
2, 3,
4, 5 ]
);
var retval = { };
retval.vertexObject = ctx.createBuffer();
ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.vertexObject);
ctx.bufferData(ctx.ARRAY_BUFFER, vertices, ctx.STATIC_DRAW);
retval.colorObject = ctx.createBuffer();
ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.colorObject);
ctx.bufferData(ctx.ARRAY_BUFFER, colors, ctx.STATIC_DRAW);
ctx.bindBuffer(ctx.ARRAY_BUFFER, null);
retval.indexObject = ctx.createBuffer();
ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, retval.indexObject);
ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, indices, ctx.STATIC_DRAW);
ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, null);
retval.numIndices = indices.length;
return retval;
}
function TPchargerTextures()
{
// Charger une image utilisée comme texture. (Retourne un objet WebGLTexture)
//glob.texture1 = loadImageTexture( gl, "images/Brouillard.jpg" );
//glob.texture2 = loadImageTexture( gl, "images/Exploration.jpg" );
//glob.texture3 = loadImageTexture( gl, "images/Modelisation.jpg" );
}
function TPcreerModele()
{
// Créer une boîte. Au retour, 'glob.box' contient une structure avec
// les VBOs pour les sommets, normales, coordonnées de texture et connectivité.
glob.box = makeRepere( gl );
// Initialiser les attributs pour les sommets, les normales et les coordonnées de texture
// (dans le même ordre qu'à l'appel à simpleSetup() dans la fonction TPinitialiser())
gl.enableVertexAttribArray( 0 );
gl.bindBuffer( gl.ARRAY_BUFFER, glob.box.vertexObject );
gl.vertexAttribPointer( 0, 3, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( 1 );
gl.bindBuffer( gl.ARRAY_BUFFER, glob.box.colorObject );
gl.vertexAttribPointer( 1, 3, gl.FLOAT, false, 0, 0 );
// Lier le tableau de connectivité
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, glob.box.indexObject );
}
function TPinitialiser()
{
// Initialiser webgl
var gl = initWebGL( "tp-canevas" ); // L'identificateur du canevas
if (!gl) return;
glob.program = simpleSetup( gl,
// Les identificateurs des deux nuanceurs
"nuanceurSommets", "nuanceurFragments",
// Les attributs utilisés par les nuanceurs (donnés dans le même ordre que leur indice)
[ "vPosition", "vColor" ],
// La couleur de fond et la profondeur
[ 0x00/255, 0x2b/255, 0x36/255, 1 ], 100);
// Les angles courants de rotation
glob.angleRotX = 0, glob.angleRotY = 0, glob.angleRotZ = 0;
// Les incréments à chaque affichage
glob.incrRotX = 0.2; glob.incrRotY = 0.3; glob.incrRotZ = 0.4;
// Créer les matrices nécessaires et assigner les assigner dans le programme
glob.modelMatrix = mat4.create();
glob.viewMatrix = mat4.create();
glob.modelMatLoc = gl.getUniformLocation( glob.program, "mmodel" );
glob.viewMatLoc = gl.getUniformLocation( glob.program, "mview" );
glob.projMatLoc = gl.getUniformLocation( glob.program, "mproj" );
// terminer l'initialisation
TPchargerTextures();
TPcreerModele();
glob.mouseDown = false;
glob.positionSourisX = null;
glob.positionSourisY = null;
glob.canevas.onmousedown = handleMouseDown;
glob.canevas.onmouseup = handleMouseUp;
glob.canevas.onmousemove = handleMouseMove;
glob.transformations = [];
// Initialiser les variables uniformes pour les nuanceurs
gl.uniform3f( gl.getUniformLocation( glob.program, "lightDir" ), 0, 0, 1 );
gl.uniform1i( gl.getUniformLocation( glob.program, "laTexture" ), 0 );
gl.uniform2f( gl.getUniformLocation( glob.program, "positionSouris" ), glob.positionSourisX, glob.positionSourisY );
return gl;
}
function TPafficherModele( gl )
{
gl.uniform2f( gl.getUniformLocation( glob.program, "positionSouris" ), glob.positionSourisX, glob.canevas.height-glob.positionSourisY );
// Tracer le cube
gl.drawElements( gl.LINES, glob.box.numIndices, gl.UNSIGNED_BYTE, 0 );
}
function TPafficherScene(gl)
{
glob.perspectiveMatrix = mat4.create();
glob.perspectiveMatrix = mat4.perspective(glob.perspectiveMatrix, 70. * 3.14159 / 180., glob.canevas.width / glob.canevas.height, 0.01, 10 );
gl.uniformMatrix4fv(glob.projMatLoc, false, glob.perspectiveMatrix);
// Effacer le canevas
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
// Définir la clôture 1
gl.viewport( 0, 0, glob.canevas.width, glob.canevas.height );
// Incrémenter les angles de rotation
glob.angleRotX += glob.incrRotX; if ( glob.angleRotX >= 360.0 ) glob.angleRotX -= 360.0;
glob.angleRotY += glob.incrRotY; if ( glob.angleRotY >= 360.0 ) glob.angleRotY -= 360.0;
glob.angleRotZ += glob.incrRotZ; if ( glob.angleRotZ >= 360.0 ) glob.angleRotZ -= 360.0;
// Construire la matrice de modélisation
mat4.lookAt( glob.viewMatrix, [5, 5, 5], [0, 0, 0], [0, 1, 0] );
gl.uniformMatrix4fv(glob.viewMatLoc, false, glob.viewMatrix);
mat4.identity(glob.modelMatrix);
gl.uniformMatrix4fv(glob.modelMatLoc, false, glob.modelMatrix);
TPafficherModele( gl );
for (var i = 0; glob.transformations.length > i; i++) {
var t = glob.transformations[i];
var v = vec3.fromValues(t.x, t.y, t.z);
switch(t.type) {
case "rotation":
mat4.rotate(glob.modelMatrix, glob.modelMatrix, glMatrix.toRadian(t.𝜃), v);
break;
case "translation":
mat4.translate(glob.modelMatrix, glob.modelMatrix, v);
break;
case "scale":
mat4.scale(glob.modelMatrix, glob.modelMatrix, v);
break;
default:
console.log("Unknown transformation type : " + t.type);
break;
}
gl.uniformMatrix4fv(glob.modelMatLoc, false, glob.modelMatrix);
TPafficherModele( gl );
}
//glob.modelMatrix.rotate( glob.angleRotX, 1.0, 0.0, 0.0 );
//glob.modelMatrix.setUniform(gl, glob.modelMatLoc, false);
//TPafficherModele(gl);
//glob.modelMatrix.rotate( glob.angleRotY, 0.0, 1.0, 0.0 );
//glob.modelMatrix.setUniform(gl, glob.modelMatLoc, false);
//TPafficherModele(gl);
//glob.modelMatrix.rotate( glob.angleRotZ, 0.0, 0.0, 1.0 );
//glob.modelMatrix.setUniform(gl, glob.modelMatLoc, false);
//TPafficherModele( gl );
}
var requestId;
function TPdebut()
{
glob.canevas = document.getElementById('tp-canevas');
//glob.canevas = WebGLDebugUtils.makeLostContextSimulatingCanvas(c);
// indiquer de perdre le contexte afin de tester
//glob.canevas.loseContextInNCalls(15);
glob.canevas.addEventListener('webglcontextlost', handleContextLost, false);
glob.canevas.addEventListener('webglcontextrestored', handleContextRestored, false);
var gl = TPinitialiser();
if ( !gl ) return;
var displayFunc = function()
{
TPafficherScene(gl);
requestId = window.requestAnimFrame( displayFunc, glob.canevas );
};
displayFunc();
function handleContextLost(e)
{
e.preventDefault();
clearLoadingImages();
if ( requestId !== undefined )
{
window.cancelAnimFrame(requestId);
requestId = undefined;
}
}
function handleContextRestored()
{
TPinitialiser();
displayFunc();
}
}