diff --git a/README.md b/README.md new file mode 100644 index 0000000..c5be756 --- /dev/null +++ b/README.md @@ -0,0 +1,118 @@ +![Mapello](images/LAIG3_T01_G03_1.png) + +
GUI
\'s constructor:\n\n \n\n localStorage
on exit.\n\n localStorage
will\n override those passed to dat.GUI
\'s constructor. This makes it\n easier to work incrementally, but localStorage
is fragile,\n and your friends may not see the same values you do.\n\n = 0)
+ float linear_attenuation; // Default: 0 (value must be >= 0)
+ float quadratic_attenuation; // Default: 0 (value must be >= 0)
+ bool enabled; // Deafult: false
+};
+
+struct materialProperties {
+ vec4 ambient; // Default: (0, 0, 0, 1)
+ vec4 diffuse; // Default: (0, 0, 0, 1)
+ vec4 specular; // Default: (0, 0, 0, 1)
+ vec4 emission; // Default: (0, 0, 0, 1)
+ float shininess; // Default: 0 (possible values [0, 128])
+};
+
+uniform mat4 uMVMatrix;
+uniform mat4 uPMatrix;
+uniform mat4 uNMatrix;
+
+uniform bool uLightEnabled;
+uniform bool uLightModelTwoSided;
+
+#define NUMBER_OF_LIGHTS 8
+
+uniform vec4 uGlobalAmbient;
+
+uniform lightProperties uLight[NUMBER_OF_LIGHTS];
+
+uniform materialProperties uFrontMaterial;
+uniform materialProperties uBackMaterial;
+
+out vec4 vFinalColor;
+
+vec4 lighting(vec4 vertex, vec3 E, vec3 N) {
+
+ vec4 result = vec4(0.0, 0.0, 0.0, 0.0);
+
+ for (int i = 0; i < NUMBER_OF_LIGHTS; i++) {
+ if (uLight[i].enabled) {
+
+ float att = 1.0;
+ float spot_effect = 1.0;
+ vec3 L = vec3(0.0);
+
+ if (uLight[i].position.w == 1.0) {
+ L = (uLight[i].position - vertex).xyz;
+ float dist = length(L);
+ L = normalize(L);
+
+ if (uLight[i].spot_cutoff != 180.0) {
+ vec3 sd = normalize(vec3(uLight[i].spot_direction));
+ float cos_cur_angle = dot(sd, -L);
+ float cos_inner_cone_angle = cos(radians(clamp(uLight[i].spot_cutoff, 0.0, 89.0)));
+
+ spot_effect = pow(clamp(cos_cur_angle/ cos_inner_cone_angle, 0.0, 1.0), clamp(uLight[i].spot_exponent, 0.0, 128.0));
+ }
+
+ att = 1.0 / (uLight[i].constant_attenuation + uLight[i].linear_attenuation * dist + uLight[i].quadratic_attenuation * dist * dist);
+
+ } else {
+ L = normalize(uLight[i].position.xyz);
+ }
+
+ float lambertTerm = max(dot(N, L), 0.0);
+
+ vec4 Ia = uLight[i].ambient * uFrontMaterial.ambient;
+
+ vec4 Id = uLight[i].diffuse * uFrontMaterial.diffuse * lambertTerm;
+
+ vec4 Is = vec4(0.0, 0.0, 0.0, 0.0);
+
+ if (lambertTerm > 0.0) {
+ vec3 R = reflect(-L, N);
+ float specular = pow( max( dot(R, E), 0.0 ), uFrontMaterial.shininess);
+
+ Is = uLight[i].specular * uFrontMaterial.specular * specular;
+ }
+
+ if (uLight[i].position.w == 1.0)
+ result += att * max(spot_effect * (Id + Is), Ia);
+ else
+ result += att * spot_effect * (Ia + Id + Is);
+ }
+ }
+
+ result += uGlobalAmbient * uFrontMaterial.ambient + uFrontMaterial.emission;
+ result = clamp(result, vec4(0.0), vec4(1.0));
+
+ return result;
+}
+
+void main() {
+
+ // Transformed Vertex position
+ vec4 vertex = uMVMatrix * vec4(aVertexPosition, 1.0);
+
+ // Transformed normal position
+ vec3 N = normalize(vec3(uNMatrix * vec4(aVertexNormal, 1.0)));
+
+ vec3 eyeVec = -vec3(vertex.xyz);
+ vec3 E = normalize(eyeVec);
+
+ vFinalColor = lighting(vertex, E, N);
+
+ gl_Position = uPMatrix * vertex;
+}
+
diff --git a/frontend/lib/CGF/shaders/Gouraud/textured/fragment.glsl b/frontend/lib/CGF/shaders/Gouraud/textured/fragment.glsl
new file mode 100644
index 0000000..dcb84a7
--- /dev/null
+++ b/frontend/lib/CGF/shaders/Gouraud/textured/fragment.glsl
@@ -0,0 +1,24 @@
+#version 300 es
+precision highp float;
+
+in vec4 vFinalColor;
+in vec2 vTextureCoord;
+
+out vec4 fragColor;
+
+uniform sampler2D uSampler;
+
+uniform bool uUseTexture;
+
+void main() {
+ // Branching should be reduced to a minimal.
+ // When based on a non-changing uniform, it is usually optimized.
+ if (uUseTexture)
+ {
+ vec4 textureColor = texture(uSampler, vTextureCoord);
+ fragColor = textureColor * vFinalColor;
+ }
+ else
+ fragColor = vFinalColor;
+
+}
\ No newline at end of file
diff --git a/frontend/lib/CGF/shaders/Gouraud/textured/multiple_light-vertex.glsl b/frontend/lib/CGF/shaders/Gouraud/textured/multiple_light-vertex.glsl
new file mode 100644
index 0000000..f777b29
--- /dev/null
+++ b/frontend/lib/CGF/shaders/Gouraud/textured/multiple_light-vertex.glsl
@@ -0,0 +1,129 @@
+#version 300 es
+precision highp float;
+
+in vec3 aVertexPosition;
+in vec3 aVertexNormal;
+in vec2 aTextureCoord;
+
+uniform bool uUseTexture;
+
+struct lightProperties {
+ vec4 position; // Default: (0, 0, 1, 0)
+ vec4 ambient; // Default: (0, 0, 0, 1)
+ vec4 diffuse; // Default: (0, 0, 0, 1)
+ vec4 specular; // Default: (0, 0, 0, 1)
+ vec4 half_vector;
+ vec3 spot_direction; // Default: (0, 0, -1)
+ float spot_exponent; // Default: 0 (possible values [0, 128]
+ float spot_cutoff; // Default: 180 (possible values [0, 90] or 180)
+ float constant_attenuation; // Default: 1 (value must be >= 0)
+ float linear_attenuation; // Default: 0 (value must be >= 0)
+ float quadratic_attenuation; // Default: 0 (value must be >= 0)
+ bool enabled; // Default: false
+};
+
+struct materialProperties {
+ vec4 ambient; // Default: (0, 0, 0, 1)
+ vec4 diffuse; // Default: (0, 0, 0, 1)
+ vec4 specular; // Default: (0, 0, 0, 1)
+ vec4 emission; // Default: (0, 0, 0, 1)
+ float shininess; // Default: 0 (possible values [0, 128])
+};
+
+uniform mat4 uMVMatrix;
+uniform mat4 uPMatrix;
+uniform mat4 uNMatrix;
+
+uniform bool uLightEnabled; // not being used
+uniform bool uLightModelTwoSided; // not being used
+
+#define NUMBER_OF_LIGHTS 8
+
+uniform vec4 uGlobalAmbient;
+
+uniform lightProperties uLight[NUMBER_OF_LIGHTS];
+
+uniform materialProperties uFrontMaterial;
+uniform materialProperties uBackMaterial;
+
+out vec4 vFinalColor;
+out vec2 vTextureCoord;
+
+vec4 lighting(vec4 vertex, vec3 E, vec3 N) {
+
+ vec4 result = vec4(0.0, 0.0, 0.0, 0.0);
+
+ for (int i = 0; i < NUMBER_OF_LIGHTS; i++) {
+ if (uLight[i].enabled) {
+
+ float att = 1.0;
+ float spot_effect = 1.0;
+ vec3 L = vec3(0.0);
+
+ if (uLight[i].position.w == 1.0) {
+ L = (uLight[i].position - vertex).xyz;
+ float dist = length(L);
+ L = normalize(L);
+
+ if (uLight[i].spot_cutoff != 180.0) {
+ vec3 sd = normalize(vec3(uLight[i].spot_direction));
+ float cos_cur_angle = dot(sd, -L);
+ float cos_inner_cone_angle = cos(radians(clamp(uLight[i].spot_cutoff, 0.0, 89.0)));
+
+ spot_effect = pow(clamp(cos_cur_angle/ cos_inner_cone_angle, 0.0, 1.0), clamp(uLight[i].spot_exponent, 0.0, 128.0));
+ }
+
+ att = 1.0 / (uLight[i].constant_attenuation + uLight[i].linear_attenuation * dist + uLight[i].quadratic_attenuation * dist * dist);
+
+ } else {
+ L = normalize(uLight[i].position.xyz);
+ }
+
+ float lambertTerm = max(dot(N, L), 0.0);
+
+ vec4 Ia = uLight[i].ambient * uFrontMaterial.ambient;
+
+ vec4 Id = uLight[i].diffuse * uFrontMaterial.diffuse * lambertTerm;
+
+ vec4 Is = vec4(0.0, 0.0, 0.0, 0.0);
+
+ if (lambertTerm > 0.0) {
+ vec3 R = reflect(-L, N);
+ float specular = pow( max( dot(R, E), 0.0 ), uFrontMaterial.shininess);
+
+ Is = uLight[i].specular * uFrontMaterial.specular * specular;
+ }
+
+ if (uLight[i].position.w == 1.0)
+ result += att * max(spot_effect * (Id + Is), Ia);
+ else
+ result += att * spot_effect * (Ia + Id + Is);
+ }
+ }
+
+ result += uGlobalAmbient * uFrontMaterial.ambient + uFrontMaterial.emission;
+ result = clamp(result, vec4(0.0), vec4(1.0));
+
+ return result;
+}
+
+void main() {
+
+ // Transformed Vertex position
+ vec4 vertex = uMVMatrix * vec4(aVertexPosition, 1.0);
+
+ // Transformed normal position
+ vec3 N = normalize(vec3(uNMatrix * vec4(aVertexNormal, 1.0)));
+
+ vec3 eyeVec = -vec3(vertex.xyz);
+ vec3 E = normalize(eyeVec);
+
+ vFinalColor = lighting(vertex, E, N);
+
+ gl_Position = uPMatrix * vertex;
+
+ if (uUseTexture)
+ vTextureCoord = aTextureCoord;
+
+}
+
diff --git a/frontend/lib/CGF/shaders/Phong/multiple_light-phong-fragment.glsl b/frontend/lib/CGF/shaders/Phong/multiple_light-phong-fragment.glsl
new file mode 100644
index 0000000..537956a
--- /dev/null
+++ b/frontend/lib/CGF/shaders/Phong/multiple_light-phong-fragment.glsl
@@ -0,0 +1,119 @@
+#version 300 es
+precision highp float;
+
+#define NUMBER_OF_LIGHTS 4
+
+struct lightProperties {
+ vec4 position; // Default: (0, 0, 1, 0)
+ vec4 ambient; // Default: (0, 0, 0, 1)
+ vec4 diffuse; // Default: (0, 0, 0, 1)
+ vec4 specular; // Default: (0, 0, 0, 1)
+ vec4 half_vector;
+ vec3 spot_direction; // Default: (0, 0, -1)
+ float spot_exponent; // Default: 0 (possible values [0, 128]
+ float spot_cutoff; // Default: 180 (possible values [0, 90] or 180)
+ float constant_attenuation; // Default: 1 (value must be >= 0)
+ float linear_attenuation; // Default: 0 (value must be >= 0)
+ float quadratic_attenuation; // Default: 0 (value must be >= 0)
+ bool enabled; // Deafult: false
+};
+
+struct materialProperties {
+ vec4 ambient; // Default: (0, 0, 0, 1)
+ vec4 diffuse; // Default: (0, 0, 0, 1)
+ vec4 specular; // Default: (0, 0, 0, 1)
+ vec4 emission; // Default: (0, 0, 0, 1)
+ float shininess; // Default: 0 (possible values [0, 128])
+};
+
+uniform mat4 uPMatrix;
+
+uniform bool uLightEnabled;
+uniform bool uLightModelTwoSided;
+
+// uniform vec4 uGlobalAmbient;
+
+uniform lightProperties uLight[NUMBER_OF_LIGHTS];
+
+uniform materialProperties uFrontMaterial;
+uniform materialProperties uBackMaterial;
+
+in vec3 vNormal;
+in vec3 vLightDir[NUMBER_OF_LIGHTS];
+in vec3 vEyeVec;
+
+out vec4 fragColor;
+
+vec4 calcDirectionalLight(int i, vec3 E, vec3 L, vec3 N) {
+ float lambertTerm = dot(N, -L);
+
+ vec4 Ia = uLight[i].ambient * uFrontMaterial.ambient;
+
+ vec4 Id = vec4(0.0, 0.0, 0.0, 0.0);
+
+ vec4 Is = vec4(0.0, 0.0, 0.0, 0.0);
+
+ if (lambertTerm > 0.0) {
+ Id = uLight[i].diffuse * uFrontMaterial.diffuse * lambertTerm;
+
+ vec3 R = reflect(L, N);
+ float specular = pow( max( dot(R, E), 0.0 ), uFrontMaterial.shininess);
+
+ Is = uLight[i].specular * uFrontMaterial.specular * specular;
+ }
+ return Ia + Id + Is;
+}
+
+vec4 calcPointLight(int i, vec3 E, vec3 N) {
+ float dist = length(vLightDir[i]);
+ vec3 direction = normalize(vLightDir[i]);
+
+ vec4 color = calcDirectionalLight(i, E, vLightDir[i], N);
+ float att = 1.0 / (uLight[i].constant_attenuation + uLight[i].linear_attenuation * dist + uLight[i].quadratic_attenuation * dist * dist);
+ return color * att;
+}
+
+vec4 calcSpotLight(int i, vec3 E, vec3 N)
+{
+ vec3 direction = normalize(vLightDir[i]);
+ float spot_factor = dot(direction, uLight[i].spot_direction);
+
+ if (spot_factor > uLight[i].spot_cutoff) {
+ vec4 color = calcPointLight(i, E, N);
+ return color * (1.0 - (1.0 - spot_factor) * 1.0/(1.0 - uLight[i].spot_cutoff));
+ }
+ else {
+ return vec4(0,0,0,0);
+ }
+}
+
+vec4 lighting(vec3 E, vec3 N) {
+
+ vec4 result = vec4(0.0, 0.0, 0.0, 0.0);
+
+ for (int i = 0; i < NUMBER_OF_LIGHTS; i++) {
+ if (uLight[i].enabled) {
+ if (uLight[i].position.w == 0.0) {
+ // Directional Light
+ result += calcDirectionalLight(i, E, normalize(uLight[i].position.xyz), N);
+ } else if (uLight[i].spot_cutoff == 180.0) {
+ // Point Light
+ result += calcPointLight(i, E, N);
+ } else {
+ result += calcSpotLight(i, E, N);
+ }
+ }
+ }
+
+ return result;
+}
+
+void main() {
+
+ // Transformed normal position
+ vec3 N = normalize(vNormal);
+
+ vec3 E = normalize(vEyeVec);
+
+ fragColor = lighting(E, N);
+}
\ No newline at end of file
diff --git a/frontend/lib/CGF/shaders/Phong/multiple_light-phong-vertex.glsl b/frontend/lib/CGF/shaders/Phong/multiple_light-phong-vertex.glsl
new file mode 100644
index 0000000..2eb3ba0
--- /dev/null
+++ b/frontend/lib/CGF/shaders/Phong/multiple_light-phong-vertex.glsl
@@ -0,0 +1,50 @@
+#version 300 es
+precision highp float;
+
+#define NUMBER_OF_LIGHTS 4
+
+in vec3 aVertexPosition;
+in vec3 aVertexNormal;
+
+uniform mat4 uMVMatrix;
+uniform mat4 uPMatrix;
+uniform mat4 uNMatrix;
+
+struct lightProperties {
+ vec4 position; // Default: (0, 0, 1, 0)
+ vec4 ambient; // Default: (0, 0, 0, 1)
+ vec4 diffuse; // Default: (0, 0, 0, 1)
+ vec4 specular; // Default: (0, 0, 0, 1)
+ vec4 half_vector;
+ vec3 spot_direction; // Default: (0, 0, -1)
+ float spot_exponent; // Default: 0 (possible values [0, 128]
+ float spot_cutoff; // Default: 180 (possible values [0, 90] or 180)
+ float constant_attenuation; // Default: 1 (value must be >= 0)
+ float linear_attenuation; // Default: 0 (value must be >= 0)
+ float quadratic_attenuation; // Default: 0 (value must be >= 0)
+ bool enabled; // Deafult: false
+};
+
+uniform lightProperties uLight[NUMBER_OF_LIGHTS];
+
+out vec3 vNormal;
+out vec3 vLightDir[NUMBER_OF_LIGHTS];
+out vec3 vEyeVec;
+
+void main() {
+ vec4 vertex = uMVMatrix * vec4(aVertexPosition, 1.0);
+
+ vNormal = vec3(uNMatrix * vec4(aVertexNormal, 1.0));
+
+ vEyeVec = -vec3(vertex.xyz);
+
+ gl_Position = uPMatrix * vertex;
+
+ for (int i = 0; i < NUMBER_OF_LIGHTS; i++) {
+ if (uLight[i].enabled) {
+ if (uLight[i].position.w == 1.0) {
+ vLightDir[i] = (uMVMatrix * vec4(aVertexPosition, 1.0)).xyz - uLight[i].position.xyz;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend/lib/CGF/shaders/Phong/phong-fragment.glsl b/frontend/lib/CGF/shaders/Phong/phong-fragment.glsl
new file mode 100644
index 0000000..75c3522
--- /dev/null
+++ b/frontend/lib/CGF/shaders/Phong/phong-fragment.glsl
@@ -0,0 +1,51 @@
+#version 300 es
+precision highp float;
+
+uniform mat4 uMVMatrix;
+
+uniform float uShininess;
+uniform vec3 uLightDirection;
+
+uniform vec4 uLightAmbient;
+uniform vec4 uLightDiffuse;
+uniform vec4 uLightSpecular;
+
+uniform vec4 uMaterialAmbient;
+uniform vec4 uMaterialDiffuse;
+uniform vec4 uMaterialSpecular;
+
+in vec3 vNormal;
+in vec3 vEyeVec;
+
+out vec4 fragColor;
+
+void main() {
+ // Normalize light to calculate lambertTerm
+ vec3 L = normalize(vec3(uMVMatrix * vec4(uLightDirection, 0.0)));
+
+ // Transformed normal position
+ vec3 N = normalize(vNormal);
+
+ // Lambert's cosine law
+ float lambertTerm = dot(N, -L);
+
+ vec4 Ia = uLightAmbient * uMaterialAmbient;
+
+ vec4 Id = vec4(0.0, 0.0, 0.0, 1.0);
+
+ vec4 Is = vec4(0.0, 0.0, 0.0, 1.0);
+
+ if (lambertTerm > 0.0) {
+ Id = uLightDiffuse * uMaterialDiffuse * lambertTerm;
+
+ vec3 E = normalize(vEyeVec);
+ vec3 R = reflect(L, N);
+ float specular = pow( max( dot(R, E), 0.0 ), uShininess);
+
+ Is = uLightSpecular * uMaterialSpecular * specular;
+ }
+
+ vec4 finalColor = Ia + Id + Is;
+
+ fragColor = finalColor;
+}
\ No newline at end of file
diff --git a/frontend/lib/CGF/shaders/Phong/phong-vertex.glsl b/frontend/lib/CGF/shaders/Phong/phong-vertex.glsl
new file mode 100644
index 0000000..466b60b
--- /dev/null
+++ b/frontend/lib/CGF/shaders/Phong/phong-vertex.glsl
@@ -0,0 +1,22 @@
+#version 300 es
+precision highp float;
+
+in vec3 aVertexPosition;
+in vec3 aVertexNormal;
+
+uniform mat4 uMVMatrix;
+uniform mat4 uPMatrix;
+uniform mat4 uNMatrix;
+
+out vec3 vNormal;
+out vec3 vEyeVec;
+
+void main() {
+ vec4 vertex = uMVMatrix * vec4(aVertexPosition, 1.0);
+
+ vNormal = vec3(uNMatrix * vec4(aVertexNormal, 1.0));
+
+ vEyeVec = -vec3(vertex.xyz);
+
+ gl_Position = uPMatrix * vertex;
+}
\ No newline at end of file
diff --git a/frontend/lib/CGF/shaders/picking/fragment.glsl b/frontend/lib/CGF/shaders/picking/fragment.glsl
new file mode 100644
index 0000000..21d9e88
--- /dev/null
+++ b/frontend/lib/CGF/shaders/picking/fragment.glsl
@@ -0,0 +1,9 @@
+#version 300 es
+precision highp float;
+
+in vec4 vFinalColor;
+out vec4 fragColor;
+
+void main() {
+ fragColor = vFinalColor;
+}
\ No newline at end of file
diff --git a/frontend/lib/CGF/shaders/picking/vertex.glsl b/frontend/lib/CGF/shaders/picking/vertex.glsl
new file mode 100644
index 0000000..e79302c
--- /dev/null
+++ b/frontend/lib/CGF/shaders/picking/vertex.glsl
@@ -0,0 +1,24 @@
+#version 300 es
+precision highp float;
+
+in vec3 aVertexPosition;
+
+uniform bool uUseTexture;
+
+uniform mat4 uMVMatrix;
+uniform mat4 uPMatrix;
+
+out vec4 vFinalColor;
+
+uniform vec4 uPickColor;
+
+void main() {
+
+ vec3 pt = vec3(aVertexPosition);
+
+ // Transformed Vertex position
+ vec4 vertex = uMVMatrix * vec4(pt, 1.0);
+ gl_Position = uPMatrix * vertex;
+
+ vFinalColor = uPickColor;
+}
diff --git a/frontend/lib/CGF/shaders/viz/normals-fragment.glsl b/frontend/lib/CGF/shaders/viz/normals-fragment.glsl
new file mode 100644
index 0000000..9a20046
--- /dev/null
+++ b/frontend/lib/CGF/shaders/viz/normals-fragment.glsl
@@ -0,0 +1,8 @@
+#version 300 es
+precision highp float;
+
+out vec4 fragColor;
+
+void main() {
+ fragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
\ No newline at end of file
diff --git a/frontend/lib/CGF/shaders/viz/normals-vertex.glsl b/frontend/lib/CGF/shaders/viz/normals-vertex.glsl
new file mode 100644
index 0000000..ab5adb3
--- /dev/null
+++ b/frontend/lib/CGF/shaders/viz/normals-vertex.glsl
@@ -0,0 +1,11 @@
+#version 300 es
+precision highp float;
+
+in vec3 aVertexPosition;
+
+uniform mat4 uMVMatrix;
+uniform mat4 uPMatrix;
+
+void main() {
+ gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
+}
diff --git a/frontend/main.js b/frontend/main.js
new file mode 100644
index 0000000..e69e146
--- /dev/null
+++ b/frontend/main.js
@@ -0,0 +1,96 @@
+//From https://github.com/EvanHahn/ScriptInclude
+include = function () { function f() { var a = this.readyState; (!a || /ded|te/.test(a)) && (c--, !c && e && d()) } var a = arguments, b = document, c = a.length, d = a[c - 1], e = d.call; e && c--; for (var g, h = 0; c > h; h++)g = b.createElement("script"), g.src = arguments[h], g.async = !0, g.onload = g.onerror = g.onreadystatechange = f, (b.head || b.getElementsByTagName("head")[0]).appendChild(g) };
+serialInclude = function (a) { var b = console, c = serialInclude.l; if (a.length > 0) c.splice(0, 0, a); else b.log("Done!"); if (c.length > 0) { if (c[0].length > 1) { var d = c[0].splice(0, 1); b.log("Loading " + d + "..."); include(d, function () { serialInclude([]); }); } else { var e = c[0][0]; c.splice(0, 1); e.call(); }; } else b.log("Finished."); }; serialInclude.l = new Array();
+
+let app;
+
+//Include additional files here
+serialInclude(['../lib/CGF.js', 'XMLscene.js', 'MySceneGraph.js', 'MyInterface.js',
+ 'primitives/MyRectangle.js', 'primitives/MyCylinder.js', 'primitives/MyCircle.js',
+ 'primitives/MyTriangle.js', 'primitives/MySphere.js', 'primitives/MyTorus.js', 'primitives/MyCube.js', 'primitives/MyWater.js', 'utils.js', 'MyNode.js',
+ 'animation/Keyframe.js', 'animation/MyAnimation.js', 'animation/KeyframeAnimation.js', 'animation/CameraAnimation.js', 'sprites/MySpriteSheet.js',
+ 'sprites/MySpriteText.js', 'sprites/MySpriteAnimation.js', 'nurbs/MyPlane.js', 'nurbs/MyPatch.js', 'nurbs/MyBarrel.js',
+
+ 'game/MyTheme.js', 'game/GameScene.js', 'game/GameOrchestrator.js', 'game/StateMachine.js',
+ 'game/graphs/ScenarioSceneGraph.js', 'game/graphs/GameSceneGraph.js',
+ 'game/elements/MyGameElement.js', 'game/elements/MyBoard.js', 'game/elements/MyPiece.js', 'game/elements/MyTile.js',
+ 'game/elements/MyAuxiliarBoard.js', 'game/elements/MyPlayerPiece.js', 'game/elements/MyBonus.js', 'game/elements/MyMarker.js',
+ 'game/elements/MyTimer.js',
+
+ 'game/MyAnimator.js', 'game/MyGameMove.js', 'game/PrologController.js', 'game/MyGameState.js',
+
+ main = function () {
+ // Standard application, scene and interface setup
+ app = new CGFapplication(document.body);
+ var myInterface = new MyInterface();
+ var myScene = new GameOrchestrator(myInterface);
+
+ app.init();
+
+ app.setScene(myScene);
+ app.setInterface(myInterface);
+ myInterface.initButtons(myScene);
+ myInterface.setActiveCamera(myScene.camera);
+
+ // Creates and load the themes and associates them to scene.
+ let sthemes = ["river-side", "living-room"]
+ myScene.setThemes(sthemes);
+
+ // Starts the progress bar while loading the scene
+ progress_bar();
+ }
+
+]);
+
+function progress_bar() {
+ var id = setInterval(frame, 20);
+
+ function frame() {
+ let themes = app.scene.themes;
+ let width = 0;
+ let count = 0;
+ for (const theme in themes) {
+ if (themes.hasOwnProperty(theme)) {
+ const t = themes[theme];
+ width += t.loading_percentage()
+ count++;
+ }
+ }
+ width = Math.floor(width / count);
+ var elem = document.getElementById("bar");
+ elem.style.width = width + "%";
+ if (width >= 98) {
+ clearInterval(id);
+ elem.style.display = "none";
+ document.getElementById("container").style.display = "flex";
+ }
+ }
+}
+
+function initGame() {
+ try {
+ let theme = app.scene.themes[app.scene.selectedTheme];
+ if (theme.is_loaded() && app.scene.sceneInited) {
+ let form_elems = document.querySelector("#container").elements;
+ let settings = {}
+ for (const e of form_elems) {
+ settings[e.name] = e.value.toLowerCase();
+ }
+
+ // The game settings and board generated by the prolog
+ app.scene.setGame(settings);
+
+ let interface = document.querySelector("#interface");
+ interface.remove();
+ app.run();
+ }
+ else {
+ console.log("Not Loaded Yet!", theme.loading_percentage());
+ }
+ }
+ catch (err) {
+ console.log("Prolog not active");
+ }
+
+
+}
\ No newline at end of file
diff --git a/frontend/nurbs/MyBarrel.js b/frontend/nurbs/MyBarrel.js
new file mode 100644
index 0000000..56f7400
--- /dev/null
+++ b/frontend/nurbs/MyBarrel.js
@@ -0,0 +1,87 @@
+/**
+ * MyBarrel
+ * @constructor
+ * @param scene - Reference to MyScene object
+ * @param base - the radius in the xy plane
+ * @param middle - the radius in the middle
+ * @param height - the height of the barrel
+ * @param alfa - the alfa angle
+ * @param slices - number of divisions in u for each barrel surface
+ * @param stacks - number of divisions in v
+ */
+class MyBarrel extends CGFobject {
+ constructor(scene, base, middle, height, alfa, slices, stacks) {
+ super(scene);
+ this.r = base;
+ this.R = middle;
+ this.L = height;
+ this.alfa = alfa;
+
+ this.udegree = 3;
+ this.vdegree = 3;
+
+ this.udivs = slices;
+ this.vdivs = stacks;
+
+ this.h = this.r * 4/3;
+ this.H = (this.R - this.r) * 4/3;
+ this.tgAlfa = Math.tan(this.alfa);
+
+ this.controlpointsTop = [
+ // U = 0
+ // V =0..4
+ [
+ [this.r, 0, 0, 1],
+ [this.r + this.H, 0, this.H/this.tgAlfa, 1],
+ [this.r + this.H, 0, this.L - this.H/this.tgAlfa, 1],
+ [this.r, 0, this.L, 1],
+ ],
+
+ // U = 1
+ // V =0..4
+ [
+ [this.r, this.h, 0, 1],
+ [this.r + this.H, (4/3) * (this.r + this.H), this.H/this.tgAlfa, 1],
+ [this.r + this.H, (4/3) * (this.r + this.H), this.L - this.H/this.tgAlfa, 1],
+ [this.r, this.h, this.L, 1],
+ ],
+
+ // U = 2
+ // V = 0..4
+ [
+ [-this.r, this.h, 0, 1],
+ [-this.r - this.H, (4/3) * (this.r + this.H), this.H/this.tgAlfa, 1],
+ [-this.r - this.H, (4/3) * (this.r + this.H), this.L - this.H/this.tgAlfa, 1],
+ [-this.r, this.h, this.L, 1],
+ ],
+
+ // U = 3
+ // V =0..4
+ [
+ [-this.r, 0, 0, 1],
+ [-this.r - this.H, 0, this.H/this.tgAlfa, 1],
+ [-this.r - this.H, 0, this.L - this.H/this.tgAlfa, 1],
+ [-this.r, 0, this.L, 1],
+ ],
+
+ ];
+
+
+ this.barrelSurfaceTop = new CGFnurbsSurface(this.udegree, this.vdegree, this.controlpointsTop);
+ this.barrelObjectTop = new CGFnurbsObject(this.scene, this.udivs, this.vdivs, this.barrelSurfaceTop);
+ }
+
+ display() {
+
+ this.scene.pushMatrix();
+
+ // Display Top Barrel
+ this.barrelObjectTop.display();
+
+ // Display Bottom Barrel
+ this.scene.rotate(Math.PI, 0,0,1);
+ this.barrelObjectTop.display();
+
+ this.scene.popMatrix();
+ }
+}
\ No newline at end of file
diff --git a/frontend/nurbs/MyPatch.js b/frontend/nurbs/MyPatch.js
new file mode 100644
index 0000000..dbba745
--- /dev/null
+++ b/frontend/nurbs/MyPatch.js
@@ -0,0 +1,38 @@
+/**
+ * MyPatch
+ * @constructor
+ * @param scene - Reference to MyScene object
+ * @param udivs - points in u
+ * @param vdivs - points in v
+ * @param udivs - divs in u
+ * @param vdivs - divs in v
+ * @param controlpoints - controlpoints array
+ */
+class MyPatch extends CGFobject {
+ constructor(scene, upoints, vpoints, udivs, vdivs, controlpoints) {
+ super(scene);
+ this.udegree = upoints - 1;
+ this.vdegree = vpoints - 1;
+ this.udivs = udivs;
+ this.vdivs = vdivs;
+
+ this.controlpoints = [];
+ let index = 0;
+
+ for (let i = 0; i < upoints; i++) {
+ let aux = [];
+ for (let j = 0; j < vpoints; j++) {
+ aux.push(controlpoints[index + j]);
+ }
+ index += vpoints;
+ this.controlpoints.push(aux);
+ }
+
+ this.nurbsSurface = new CGFnurbsSurface(this.udegree, this.vdegree, this.controlpoints);
+ this.nurbsObject = new CGFnurbsObject(this.scene, this.udivs, this.vdivs, this.nurbsSurface);
+ }
+
+ display() {
+ this.nurbsObject.display();
+ }
+}
\ No newline at end of file
diff --git a/frontend/nurbs/MyPlane.js b/frontend/nurbs/MyPlane.js
new file mode 100644
index 0000000..d330baa
--- /dev/null
+++ b/frontend/nurbs/MyPlane.js
@@ -0,0 +1,37 @@
+/**
+ * MyPlane
+ * @constructor
+ * @param scene - Reference to MyScene object
+ * @param udivs - divs in u
+ * @param vdivs - divs in v
+ */
+class MyPlane extends CGFobject {
+ constructor(scene, udivs, vdivs) {
+ super(scene);
+ this.udivs = udivs;
+ this.vdivs = vdivs;
+
+ this.nurbsSurface = new CGFnurbsSurface(1, 1,
+ [
+ // U = 0
+ [ // V = 0..1;
+ [-0.5, 0.0, 0.5, 1],
+ [-0.5, 0.0, -0.5, 1],
+ ],
+ // U = 1
+ [ // V = 0..1
+ [0.5, 0.0, 0.5, 1],
+ [0.5, 0.0, -0.5, 1],
+ ]
+ ]
+ );
+
+ this.nurbsObject = new CGFnurbsObject(this.scene, this.udivs, this.vdivs, this.nurbsSurface);
+
+ }
+
+ display() {
+ this.nurbsObject.display();
+ }
+
+}
diff --git a/frontend/primitives/MyCircle.js b/frontend/primitives/MyCircle.js
new file mode 100644
index 0000000..aabb02c
--- /dev/null
+++ b/frontend/primitives/MyCircle.js
@@ -0,0 +1,65 @@
+/**
+ * MyCircle
+ * @constructor
+ * @param scene - Reference to MyScene object
+ * @param radius
+ * @param slices
+ */
+class MyCircle extends CGFobject {
+ constructor(scene, radius, slices) {
+ super(scene);
+ this.slices = slices;
+ this.radius = radius;
+
+ this.initBuffers();
+ }
+
+ initBuffers() {
+ this.vertices = [];
+ this.indices = [];
+ this.normals = [];
+ this.texCoords = [];
+
+ var ang = 0;
+ var alphaAng = 2 * Math.PI / this.slices;
+
+ this.vertices.push(0, 0, 0);
+ this.normals.push(0, 0, 1);
+ this.texCoords.push(0.5, 0.5);
+
+
+ var ca, sa, x, y, u, v;
+
+ // Last vertices need to be repeated for the circle to close
+ for (var i = 0; i <= this.slices; i++) {
+
+ ca = Math.cos(ang);
+ sa = Math.sin(ang);
+
+ x = ca * this.radius;
+ y = sa * this.radius;
+
+ this.vertices.push(x, y, 0);
+ this.normals.push(0, 0, 1);
+
+ u = 0.5 + x / (2 * this.radius);
+ v = 0.5 + y / (2 * this.radius);
+
+ this.texCoords.push(u, v);
+
+ ang += alphaAng;
+ }
+
+ var i = 0;
+ for (var j = 0; j < this.slices; j++) {
+ this.indices.push(i, i + 1, 0);
+ i++;
+ }
+
+ // For the circle to close
+ this.indices.push(i, 1, 0);
+
+ this.primitiveType = this.scene.gl.TRIANGLES;
+ this.initGLBuffers();
+ }
+}
\ No newline at end of file
diff --git a/frontend/primitives/MyCube.js b/frontend/primitives/MyCube.js
new file mode 100644
index 0000000..5968cf3
--- /dev/null
+++ b/frontend/primitives/MyCube.js
@@ -0,0 +1,53 @@
+class MyCube extends CGFobject {
+ constructor(scene) {
+ super(scene);
+ this.initBuffers();
+
+ this.square = new MyRectangle(this.scene, -0.5, -0.5, 0.5, 0.5);
+ }
+
+ display() {
+
+ //front
+ this.scene.pushMatrix();
+ this.scene.translate(0.0, 0.0, 0.5);
+ this.square.display();
+ this.scene.popMatrix();
+
+ //back
+ this.scene.pushMatrix();
+ this.scene.translate(0.0, 0.0, -0.5);
+ this.scene.rotate(-Math.PI,0.0, 1.0,0.0);
+ this.square.display();
+ this.scene.popMatrix();
+
+ //left
+ this.scene.pushMatrix();
+ this.scene.translate(-0.5, 0.0, 0.0);
+ this.scene.rotate(-Math.PI/2,0.0, 1.0,0.0);
+ this.square.display();
+ this.scene.popMatrix();
+
+ //right
+ this.scene.pushMatrix();
+ this.scene.translate(0.5, 0.0, 0.0);
+ this.scene.rotate(Math.PI/2,0.0, 1.0,0.0);
+ this.square.display();
+ this.scene.popMatrix();
+
+ //bottom
+ this.scene.pushMatrix();
+ this.scene.translate(0.0, -0.5, 0.0);
+ this.scene.rotate(Math.PI/2,1.0, 0.0,0.0);
+ this.square.display();
+ this.scene.popMatrix();
+
+ //top
+ this.scene.pushMatrix();
+ this.scene.translate(0.0, 0.5, 0.0);
+ this.scene.rotate(-Math.PI/2,1.0, 0.0,0.0);
+ this.square.display();
+ this.scene.popMatrix();
+ }
+
+}
\ No newline at end of file
diff --git a/frontend/primitives/MyCylinder.js b/frontend/primitives/MyCylinder.js
new file mode 100644
index 0000000..16714f1
--- /dev/null
+++ b/frontend/primitives/MyCylinder.js
@@ -0,0 +1,109 @@
+/**
+ * MyCylinder
+ * @constructor
+ * @param scene - Reference to MyScene object
+ * @param bottomRadius
+ * @param topRadius
+ * @param height
+ * @param slices
+ * @param stacks
+ */
+class MyCylinder extends CGFobject {
+ constructor(scene, bottomRadius, topRadius, height, slices, stacks) {
+ super(scene);
+ this.stacks = stacks;
+ this.slices = slices;
+ this.height = height;
+ this.topRadius = topRadius;
+ this.bottomRadius = bottomRadius;
+
+ this.top = new MyCircle(scene, topRadius, slices);
+ this.bottom = new MyCircle(scene, bottomRadius, slices);
+
+ this.initBuffers();
+ }
+
+ initBuffers() {
+ this.vertices = [];
+ this.indices = [];
+ this.normals = [];
+ this.texCoords = [];
+
+ var ang = 0;
+ var alphaAng = 2 * Math.PI / this.slices;
+ var stackInc = this.height / this.stacks;
+ var radiusInc = (this.topRadius - this.bottomRadius) / this.stacks;
+
+ var ca, sa, x, y;
+ var r = this.bottomRadius, h = 0;
+ // Last vertices need to be repeated for the cylinder to close
+ for (var j = 0; j <= this.stacks; j++) {
+
+ ang = 0;
+
+ for (var i = 0; i <= this.slices; i++) {
+
+ ca = Math.cos(ang);
+ sa = Math.sin(ang);
+
+ x = ca * r;
+ y = sa * r;
+
+ this.vertices.push(x, y, h);
+ this.normals.push(ca, sa, 0);
+
+ ang += alphaAng;
+ }
+ r += radiusInc;
+ h += stackInc;
+ }
+
+ /*
+ (i+inc)_______(i+inc+1)
+ | |
+ | |
+ i___________(i+1)
+ */
+
+ var i = 0, inc = this.slices + 1, s = 0;
+ for (var k = 0; k < this.stacks; k++) {
+ i = s;
+ for (var j = 0; j < this.slices; j++) {
+ this.indices.push(i, i + 1, i + inc);
+ this.indices.push(i + inc, i + 1, i + 1 + inc);
+ i++;
+ }
+ s += inc;
+ }
+
+ var sliceTexInc = 1 / this.slices;
+ var stackTexInc = 1 / this.stacks;
+ for (var k = this.stacks; k >= 0; k--) {
+ for (var j = 0; j <= this.slices; j++)
+ this.texCoords.push(j * sliceTexInc, k * stackTexInc);
+ }
+
+ this.primitiveType = this.scene.gl.TRIANGLES;
+ this.initGLBuffers();
+ }
+
+ display() {
+ super.display();
+
+ this.scene.pushMatrix();
+ this.scene.rotate(Math.PI, 1, 0, 0);
+ this.bottom.display();
+ this.scene.popMatrix();
+
+ this.scene.pushMatrix();
+ this.scene.translate(0, 0, this.height);
+ this.top.display();
+ this.scene.popMatrix();
+ }
+
+ enableNormalViz() {
+ super.enableNormalViz();
+ this.top.enableNormalViz();
+ this.bottom.enableNormalViz();
+ }
+}
\ No newline at end of file
diff --git a/frontend/primitives/MyRectangle.js b/frontend/primitives/MyRectangle.js
new file mode 100644
index 0000000..8fe4717
--- /dev/null
+++ b/frontend/primitives/MyRectangle.js
@@ -0,0 +1,95 @@
+/**
+ * MyRectangle
+ * @constructor
+ * @param scene - Reference to MyScene object
+ * @param x1 - x coordinate corner 1
+ * @param y1 - y coordinate corner 1
+ * @param x2 - x coordinate corner 2
+ * @param y2 - y coordinate corner 2
+ * @param afs - afs texture coordinate
+ * @param aft - aft texture coordinate
+ */
+class MyRectangle extends CGFobject {
+ constructor(scene, x1, y1, x2, y2, afs = 1, aft = 1) {
+ super(scene);
+ this.x1 = x1;
+ this.x2 = x2;
+ this.y1 = y1;
+ this.y2 = y2;
+ this.afs = afs;
+ this.aft = aft;
+ this.xLength = this.x2-this.x1;
+ this.yLength = this.y2-this.y1;
+ this.initBuffers();
+ }
+
+ initBuffers() {
+ this.vertices = [
+ this.x1, this.y1, 0, //0
+ this.x2, this.y1, 0, //1
+ this.x1, this.y2, 0, //2
+ this.x2, this.y2, 0 //3
+ ];
+
+ //Counter-clockwise reference of vertices
+ this.indices = [
+ 0, 1, 2,
+ 1, 3, 2
+ ];
+
+ //Facing Z positive
+ this.normals = [
+ 0, 0, 1,
+ 0, 0, 1,
+ 0, 0, 1,
+ 0, 0, 1
+ ];
+
+ /*
+ Texture coords (s,t)
+ +----------> s
+ |
+ |
+ |
+ v
+ t
+ */
+
+ this.setTexCoords();
+
+ this.primitiveType = this.scene.gl.TRIANGLES;
+ this.initGLBuffers();
+ }
+
+ /**
+ * Calculates the new values for the TexCoords
+ */
+ setTexCoords() {
+ return (this.texCoords = [
+ 0, this.yLength / this.aft,
+ this.xLength / this.afs, this.yLength / this.aft,
+ 0, 0,
+ this.xLength / this.afs, 0
+ ]);
+ }
+
+ /**
+ * Sets the new values for afs and aft properties, updating the TexCoords
+ * @param afs
+ * @param aft
+ */
+ setAmplification(afs, aft) {
+ this.afs = afs;
+ this.aft = aft;
+ this.updateTexCoords(this.setTexCoords());
+ }
+
+ /**
+ * Updates the list of texture coordinates of the rectangle
+ * @param {Array} coords - Array of texture coordinates
+ */
+ updateTexCoords(coords) {
+ this.texCoords = [...coords];
+ this.updateTexCoordsGLBuffers();
+ }
+}
diff --git a/frontend/primitives/MySphere.js b/frontend/primitives/MySphere.js
new file mode 100644
index 0000000..b695bc1
--- /dev/null
+++ b/frontend/primitives/MySphere.js
@@ -0,0 +1,82 @@
+/**
+ * MySphere
+ * @constructor
+ * @param scene - MyScene object
+ * @param slices - number of slices around Y axis
+ * @param stacks - number of stacks along Y axis, from the center to the poles (half of sphere)
+ */
+class MySphere extends CGFobject {
+
+ constructor(scene, radius, slices, stacks) {
+ super(scene);
+ this.radius = radius;
+ this.latDivs = stacks * 2;
+ this.longDivs = slices;
+
+ this.initBuffers();
+ }
+
+ /**
+ * @method initBuffers
+ * Initializes the sphere buffers
+ */
+ initBuffers() {
+ this.vertices = [];
+ this.indices = [];
+ this.normals = [];
+ this.texCoords = [];
+
+ var phi = 0;
+ var theta = 0;
+ var phiInc = Math.PI / this.latDivs;
+ var thetaInc = (2 * Math.PI) / this.longDivs;
+ var latVertices = this.longDivs + 1;
+ var latFac = 1 / this.latDivs;
+ var longFac = 1 / this.longDivs;
+
+ // build an all-around stack at a time, starting on "north pole" and proceeding "south"
+ for (let latitude = 0; latitude <= this.latDivs; latitude++) {
+ var sinPhi = Math.sin(phi);
+ var cosPhi = Math.cos(phi);
+
+ // in each stack, build all the slices around, starting on longitude 0
+ theta = 0;
+ for (let longitude = 0; longitude <= this.longDivs; longitude++) {
+ //--- Vertices coordinates
+ var x = Math.sin(-theta) * sinPhi;
+ var y = Math.cos(theta) * sinPhi;
+ var z = cosPhi;
+ this.vertices.push(this.radius * x, this.radius * y, this.radius * z);
+
+ //--- Indices
+ if (latitude < this.latDivs && longitude < this.longDivs) {
+ var current = latitude * latVertices + longitude;
+ var next = current + latVertices;
+ // pushing two triangles using indices from this round (current, current+1)
+ // and the ones directly south (next, next+1)
+ // (i.e. one full round of slices ahead)
+
+ this.indices.push(current + 1, current, next);
+ this.indices.push(current + 1, next, next + 1);
+ }
+
+ //--- Normals
+ // at each vertex, the direction of the normal is equal to
+ // the vector from the center of the sphere to the vertex.
+ // in a sphere of radius equal to one, the vector length is one.
+ // therefore, the value of the normal is equal to the position vector
+ this.normals.push(x, y, z);
+ theta += thetaInc;
+
+ //--- Texture Coordinates
+ var s = 0.6 + longFac * longitude;
+ var t = latFac * latitude;
+ this.texCoords.push(s, t);
+ }
+ phi += phiInc;
+ }
+
+ this.primitiveType = this.scene.gl.TRIANGLES;
+ this.initGLBuffers();
+ }
+}
diff --git a/frontend/primitives/MyTorus.js b/frontend/primitives/MyTorus.js
new file mode 100644
index 0000000..bdd7bf9
--- /dev/null
+++ b/frontend/primitives/MyTorus.js
@@ -0,0 +1,80 @@
+/**
+ * MyTorus
+ * @constructor
+ * @param scene - MyScene object
+ * @param inner
+ * @param outer
+ * @param slices - number of slices around Y axis
+ * @param loops - number of loops in 1/4 of the torus
+ */
+class MyTorus extends CGFobject {
+
+ constructor(scene, inner, outer, slices, loops) {
+ super(scene);
+ this.inner = inner;
+ this.outer = outer;
+ this.slices = slices;
+ this.loops = 4 * loops;
+
+ this.initBuffers();
+ }
+
+ /**
+ * @method initBuffers
+ * Initializes the torus buffers
+ */
+ initBuffers() {
+ this.vertices = [];
+ this.indices = [];
+ this.normals = [];
+ this.texCoords = [];
+
+ var phi = 0;
+ var theta;
+ var phiInc = (2 * Math.PI) / this.loops;
+ var thetaInc = (2 * Math.PI) / this.slices;
+
+ var x, y, z, nx, ny, nz;
+ for (var i = 0; i <= this.loops; i++) {
+ theta = 0;
+ for (var j = 0; j <= this.slices; j++) {
+ x = (this.outer + this.inner * Math.cos(theta)) * Math.cos(phi);
+ y = (this.outer + this.inner * Math.cos(theta)) * Math.sin(phi);
+ z = this.inner * Math.sin(theta);
+
+ nx = Math.cos(theta) * Math.cos(phi);
+ ny = Math.cos(theta) * Math.sin(phi);
+ nz = Math.sin(theta);
+
+ this.vertices.push(x, y, z);
+ this.normals.push(nx, ny, nz);
+
+ theta += thetaInc;
+ }
+
+ phi += phiInc;
+ }
+
+ var i = 0, inc = this.slices + 1, s = 0;
+ for (var k = 0; k < this.loops; k++) {
+ i = s;
+ for (var j = 0; j < this.slices; j++) {
+ this.indices.push(i + inc, i + 1, i);
+ this.indices.push(i + inc + 1, i + 1, i + inc);
+ i++;
+ }
+ s += inc;
+ }
+
+ var sliceTexInc = 1 / this.slices;
+ var loopTexInc = 1 / this.loops;
+ for (var k = 0; k <= this.loops; k++) {
+ for (var j = 0; j <= this.slices; j++) {
+ this.texCoords.push(k * loopTexInc, j * sliceTexInc);
+ }
+ }
+
+ this.primitiveType = this.scene.gl.TRIANGLES;
+ this.initGLBuffers();
+ }
+}
diff --git a/frontend/primitives/MyTriangle.js b/frontend/primitives/MyTriangle.js
new file mode 100644
index 0000000..88dc977
--- /dev/null
+++ b/frontend/primitives/MyTriangle.js
@@ -0,0 +1,101 @@
+/**
+ * MyTriangle
+ * @constructor
+ * @param scene - Reference to MyScene object
+ * @param x1 - x coordinate vertex 1
+ * @param y1 - y coordinate vertex 1
+ * @param x2 - x coordinate vertex 2
+ * @param y2 - y coordinate vertex 2
+ * @param x3 - x coordinate vertex 3
+ * @param y3 - y coordinate vertex 3
+ * @param afs - afs texture coordinate
+ * @param aft - aft texture coordinate
+ */
+class MyTriangle extends CGFobject {
+ constructor(scene, x1, y1, x2, y2, x3, y3, afs = 1, aft = 1) {
+ super(scene);
+ this.x1 = x1;
+ this.x2 = x2;
+ this.x3 = x3;
+ this.y1 = y1;
+ this.y2 = y2;
+ this.y3 = y3;
+ this.afs = afs;
+ this.aft = aft;
+
+ this.a = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
+ this.b = Math.sqrt(Math.pow(x3 - x2, 2) + Math.pow(y3 - y2, 2));
+ this.c = Math.sqrt(Math.pow(x1 - x3, 2) + Math.pow(y1 - y3, 2));
+
+ this.cosa = (Math.pow(this.a, 2) - Math.pow(this.b, 2) + Math.pow(this.c, 2)) / (2 * this.a * this.c);
+ this.sina = Math.sqrt(1 - Math.pow(this.cosa, 2));
+
+ this.initBuffers();
+ }
+
+ initBuffers() {
+ this.vertices = [
+ this.x1, this.y1, 0, //0
+ this.x2, this.y2, 0, //1
+ this.x3, this.y3, 0 //2
+ ];
+
+ //Counter-clockwise reference of vertices
+ this.indices = [
+ 0, 1, 2
+ ];
+
+ //Facing Z positive
+ this.normals = [
+ 0, 0, 1,
+ 0, 0, 1,
+ 0, 0, 1
+ ];
+
+ /*
+ Texture coords (s,t)
+ +----------> s
+ |
+ |
+ |
+ v
+ t
+ */
+
+ this.setTexCoords();
+
+ this.primitiveType = this.scene.gl.TRIANGLES;
+ this.initGLBuffers();
+ }
+
+ /**
+ * Calculates the new values for the TexCoords
+ */
+ setTexCoords() {
+ return (this.texCoords = [
+ 0,1,
+ this.a / this.afs, 1,
+ this.c*this.cosa / this.afs, 1 - this.c*this.sina / this.aft
+ ]);
+ }
+
+ /**
+ * Sets the new values for afs and aft properties, updating the TexCoords
+ * @param afs
+ * @param aft
+ */
+ setAmplification(afs, aft) {
+ this.afs = afs;
+ this.aft = aft;
+ this.updateTexCoords(this.setTexCoords());
+ }
+
+ /**
+ * Updates the list of texture coordinates of the rectangle
+ * @param {Array} coords - Array of texture coordinates
+ */
+ updateTexCoords(coords) {
+ this.texCoords = [...coords];
+ this.updateTexCoordsGLBuffers();
+ }
+}
diff --git a/frontend/primitives/MyWater.js b/frontend/primitives/MyWater.js
new file mode 100644
index 0000000..783e182
--- /dev/null
+++ b/frontend/primitives/MyWater.js
@@ -0,0 +1,95 @@
+class MyWater extends CGFobject {
+ constructor(scene, x1, y1, x2, y2, afs = 1, aft = 1) {
+ super(scene);
+ this.x1 = x1;
+ this.x2 = x2;
+ this.y1 = y1;
+ this.y2 = y2;
+ this.afs = afs;
+ this.aft = aft;
+ this.xLength = this.x2-this.x1;
+ this.yLength = this.y2-this.y1;
+ this.initBuffers();
+ }
+
+ initBuffers() {
+ this.vertices = [
+ this.x1, this.y1, 0, //0
+ this.x2, this.y1, 0, //1
+ this.x1, this.y2, 0, //2
+ this.x2, this.y2, 0 //3
+ ];
+
+ //Counter-clockwise reference of vertices
+ this.indices = [
+ 0, 1, 2,
+ 1, 3, 2
+ ];
+
+ //Facing Z positive
+ this.normals = [
+ 0, 0, 1,
+ 0, 0, 1,
+ 0, 0, 1,
+ 0, 0, 1
+ ];
+
+ /*
+ Texture coords (s,t)
+ +----------> s
+ |
+ |
+ |
+ v
+ t
+ */
+
+ this.setTexCoords();
+
+ this.primitiveType = this.scene.gl.TRIANGLES;
+ this.initGLBuffers();
+ }
+
+ /**
+ * Calculates the new values for the TexCoords
+ */
+ setTexCoords() {
+ return (this.texCoords = [
+ 0, this.yLength / this.aft,
+ this.xLength / this.afs, this.yLength / this.aft,
+ 0, 0,
+ this.xLength / this.afs, 0
+ ]);
+ }
+
+ /**
+ * Sets the new values for afs and aft properties, updating the TexCoords
+ * @param afs
+ * @param aft
+ */
+ setAmplification(afs, aft) {
+ this.afs = afs;
+ this.aft = aft;
+ this.updateTexCoords(this.setTexCoords());
+ }
+
+ /**
+ * Updates the list of texture coordinates of the rectangle
+ * @param {Array} coords - Array of texture coordinates
+ */
+ updateTexCoords(coords) {
+ this.texCoords = [...coords];
+ this.updateTexCoordsGLBuffers();
+ }
+
+ display(){
+ this.scene.pushMatrix();
+ this.scene.setActiveShader(this.scene.waterShader);
+ this.scene.defaultAppearance.setTexture(this.scene.textures['waterTex']);
+ this.scene.defaultAppearance.setTextureWrap('REPEAT', 'REPEAT');
+ this.scene.textures['waterMap'].bind(1);
+ super.display();
+ this.scene.setActiveShader(this.scene.defaultShader);
+ this.scene.popMatrix();
+ }
+}
\ No newline at end of file
diff --git a/frontend/scenes/images/ball.jpg b/frontend/scenes/images/ball.jpg
new file mode 100644
index 0000000..db6902b
Binary files /dev/null and b/frontend/scenes/images/ball.jpg differ
diff --git a/frontend/scenes/images/benchWood.jpg b/frontend/scenes/images/benchWood.jpg
new file mode 100644
index 0000000..8e77058
Binary files /dev/null and b/frontend/scenes/images/benchWood.jpg differ
diff --git a/frontend/scenes/images/blackDoor.jpg b/frontend/scenes/images/blackDoor.jpg
new file mode 100644
index 0000000..8170543
Binary files /dev/null and b/frontend/scenes/images/blackDoor.jpg differ
diff --git a/frontend/scenes/images/blackWood.jpg b/frontend/scenes/images/blackWood.jpg
new file mode 100644
index 0000000..0c45a8d
Binary files /dev/null and b/frontend/scenes/images/blackWood.jpg differ
diff --git a/frontend/scenes/images/chairPillowTexture.jpg b/frontend/scenes/images/chairPillowTexture.jpg
new file mode 100644
index 0000000..5a3576b
Binary files /dev/null and b/frontend/scenes/images/chairPillowTexture.jpg differ
diff --git a/frontend/scenes/images/darkWood.jpg b/frontend/scenes/images/darkWood.jpg
new file mode 100644
index 0000000..97e87ce
Binary files /dev/null and b/frontend/scenes/images/darkWood.jpg differ
diff --git a/frontend/scenes/images/floor.jpg b/frontend/scenes/images/floor.jpg
new file mode 100644
index 0000000..43f8ad9
Binary files /dev/null and b/frontend/scenes/images/floor.jpg differ
diff --git a/frontend/scenes/images/gardenFloor.jpg b/frontend/scenes/images/gardenFloor.jpg
new file mode 100644
index 0000000..9b1f087
Binary files /dev/null and b/frontend/scenes/images/gardenFloor.jpg differ
diff --git a/frontend/scenes/images/lamp.jpg b/frontend/scenes/images/lamp.jpg
new file mode 100644
index 0000000..fc052fb
Binary files /dev/null and b/frontend/scenes/images/lamp.jpg differ
diff --git a/frontend/scenes/images/leather.jpg b/frontend/scenes/images/leather.jpg
new file mode 100644
index 0000000..3125433
Binary files /dev/null and b/frontend/scenes/images/leather.jpg differ
diff --git a/frontend/scenes/images/lightWood.jpg b/frontend/scenes/images/lightWood.jpg
new file mode 100644
index 0000000..1c65964
Binary files /dev/null and b/frontend/scenes/images/lightWood.jpg differ
diff --git a/frontend/scenes/images/lightWood.webp b/frontend/scenes/images/lightWood.webp
new file mode 100644
index 0000000..f53d2f8
Binary files /dev/null and b/frontend/scenes/images/lightWood.webp differ
diff --git a/frontend/scenes/images/mediumWood.jpg b/frontend/scenes/images/mediumWood.jpg
new file mode 100644
index 0000000..fd2b8ae
Binary files /dev/null and b/frontend/scenes/images/mediumWood.jpg differ
diff --git a/frontend/scenes/images/metalTexture.jpg b/frontend/scenes/images/metalTexture.jpg
new file mode 100644
index 0000000..de31782
Binary files /dev/null and b/frontend/scenes/images/metalTexture.jpg differ
diff --git a/frontend/scenes/images/rugTexture.jpg b/frontend/scenes/images/rugTexture.jpg
new file mode 100644
index 0000000..da89b35
Binary files /dev/null and b/frontend/scenes/images/rugTexture.jpg differ
diff --git a/frontend/scenes/images/scoreBoard.jpg b/frontend/scenes/images/scoreBoard.jpg
new file mode 100644
index 0000000..1dff0fa
Binary files /dev/null and b/frontend/scenes/images/scoreBoard.jpg differ
diff --git a/frontend/scenes/images/sidewalk.jpg b/frontend/scenes/images/sidewalk.jpg
new file mode 100644
index 0000000..b2ac654
Binary files /dev/null and b/frontend/scenes/images/sidewalk.jpg differ
diff --git a/frontend/scenes/images/spriteTextBlack.png b/frontend/scenes/images/spriteTextBlack.png
new file mode 100644
index 0000000..cf40afa
Binary files /dev/null and b/frontend/scenes/images/spriteTextBlack.png differ
diff --git a/frontend/scenes/images/tableTexture.jpg b/frontend/scenes/images/tableTexture.jpg
new file mode 100644
index 0000000..70624f5
Binary files /dev/null and b/frontend/scenes/images/tableTexture.jpg differ
diff --git a/frontend/scenes/images/texture.jpg b/frontend/scenes/images/texture.jpg
new file mode 100644
index 0000000..bcc6ee1
Binary files /dev/null and b/frontend/scenes/images/texture.jpg differ
diff --git a/frontend/scenes/images/tv.jpg b/frontend/scenes/images/tv.jpg
new file mode 100644
index 0000000..a18ff45
Binary files /dev/null and b/frontend/scenes/images/tv.jpg differ
diff --git a/frontend/scenes/images/tv_show.png b/frontend/scenes/images/tv_show.png
new file mode 100644
index 0000000..f79c107
Binary files /dev/null and b/frontend/scenes/images/tv_show.png differ
diff --git a/frontend/scenes/images/wall.jpg b/frontend/scenes/images/wall.jpg
new file mode 100644
index 0000000..0f9996f
Binary files /dev/null and b/frontend/scenes/images/wall.jpg differ
diff --git a/frontend/scenes/images/waterMap.jpg b/frontend/scenes/images/waterMap.jpg
new file mode 100644
index 0000000..26ba3eb
Binary files /dev/null and b/frontend/scenes/images/waterMap.jpg differ
diff --git a/frontend/scenes/images/waterTex.jpg b/frontend/scenes/images/waterTex.jpg
new file mode 100644
index 0000000..619d862
Binary files /dev/null and b/frontend/scenes/images/waterTex.jpg differ
diff --git a/frontend/scenes/images/whiteMarble.jpg b/frontend/scenes/images/whiteMarble.jpg
new file mode 100644
index 0000000..baad375
Binary files /dev/null and b/frontend/scenes/images/whiteMarble.jpg differ
diff --git a/frontend/scenes/images/whiteWood.jpg b/frontend/scenes/images/whiteWood.jpg
new file mode 100644
index 0000000..013d53f
Binary files /dev/null and b/frontend/scenes/images/whiteWood.jpg differ
diff --git a/frontend/scenes/images/woodGardenTable.jpg b/frontend/scenes/images/woodGardenTable.jpg
new file mode 100644
index 0000000..a3a1762
Binary files /dev/null and b/frontend/scenes/images/woodGardenTable.jpg differ
diff --git a/frontend/scenes/living-room/board.xml b/frontend/scenes/living-room/board.xml
new file mode 100644
index 0000000..ad7614b
--- /dev/null
+++ b/frontend/scenes/living-room/board.xml
@@ -0,0 +1,37 @@
+