ship/public/scripts/main.js

1701 lines
56 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const socket = io({path:base_path + "/socket.io"});
const myId = Date.now();
let camera, scene, renderer, clock, controls;
let dirLight, pointLight;
var ships = [];
var fishes = [];
var birds = [];
var moving_objects = [];
var rotor, light_house, palm, man_pers, whale, seagull;
let geometry;
let material;
var island_group = new THREE.Group();
var border_cube_group = new THREE.Group();
var delta = 0;
var colors = ["orange", "blue", "maroon", "olive", "silver", "purple", "lime", "blue", "red", "pink"];
// 60 fps
var interval = 1 / 60;
const raycaster = new THREE.Raycaster();
const pointer = new THREE.Vector2();
var partical_material, pointsShader;
var partical_points = [];
var collision_distance = 4;
var mouse_down = false;
var border_cube = [];
var active_border_cube, last_selected_border_cube;
var test = false;
var tt = 1;
var manual_drive = false;
var active_border;
var border_points = [];
var prom = [];
var ship_init = {
x: -5,
y: 7,
angle: 40
}
var sea_not_clicked = false;
init();
function init() {
initScene();
initMisc();
window.addEventListener('keydown', function(event) {
const key = event.key; // "ArrowRight", "ArrowLeft", "ArrowUp", or "ArrowDown"
// var object = ships[myId];
var object = seagull;
if(key == "ArrowUp"){
if(!object.before_collision_bezier){
var t_step = 0.002;
}
else{
var t_step = 0.005;
}
object.path += t_step;
}
if(key == "ArrowDown"){
if(!object.before_collision_bezier){
var t_step = 0.002;
}
else{
var t_step = 0.005;
}
object.path -= t_step;
}
});
window.addEventListener( 'resize', onWindowResize );
canvas.addEventListener( 'mousedown', function(){mouse_down = true} );
canvas.addEventListener( 'mousemove', function(){if(!ships[myId].moving_stopped || !active_border_cube) mouse_down = false} );
canvas.addEventListener( 'mouseup', function(e){if(mouse_down) onPointerClick(e)} );
var range = document.querySelector("#range");
range.addEventListener("input", function(){
floor.scale.x = 100 / ( 101 - this.value);
floor.scale.y = 100 / ( 101 - this.value);
});
// window.addEventListener("contextmenu", function(){
// active_border.splice(-1, 1);
// border_cube_group.remove( border_cube.splice(-1, 1)[0] );
// });
window.addEventListener( 'pointermove', onPointerMove );
map.checked = false;
collision_edit.checked = false;
map.addEventListener( 'click', function(){
if(canvas2.style.display == "none" || canvas2.style.display == ""){
canvas2.style.display = "block";
canvas3.style.display = "block";
drawMapAndBorders(1);
}
else{
canvas2.style.display = "none";
canvas3.style.display = "none";
}
} );
collision_edit.addEventListener( 'click', function(){
ships[myId].moving_stopped = true;
test = this.checked;
drawMapAndBorders(1);
for(var i = 0; i < border_cube_group.children.length; i++){
border_cube_group.children[i].visible = this.checked;
}
if(!test){
sheet1.classList.remove("hide");
sheet2.classList.add("hide");
lagr_test.disabled = true;
ships[myId].collision = false;
ships[myId].position.z = ship_init.y;
ships[myId].position.x = ship_init.x;
ships[myId].rotation.y = ship_init.angle / 180 * Math.PI;
ships[myId].path = 1.1; // при t больше единицы движение по кривой Безье остановится
ships[myId].path2 = 0;
}
else{
sheet1.classList.add("hide");
sheet2.classList.remove("hide");
lagr_test.disabled = false;
shipLagrInit();
}
} );
}
function shipLagrInit(){
ships[myId].before_collision = false;
ships[myId].before_collision_bezier = false;
ships[myId].collision = true;
ships[myId].border_line_num = 0;
ships[myId].position.x = active_border[0].x;
ships[myId].position.z = active_border[0].y;
ships[myId].path2 = active_border[0].x;
ships[myId].lagr_direction = 1;
}
lagr_test.addEventListener( 'click', function(){
shipLagrInit();
} );
border_left.addEventListener( 'click', function(){
active_border = border_points[1];
} );
border_right.addEventListener( 'click', function(){
active_border = border_points[0];
} );
function drawLagr(){
ctx3.clearRect(0, 0, canvas2.width, canvas2.height);
var angle = getAngle({}, active_border[0].x, active_border[0].y, active_border[0 + 1].x, active_border[0 + 1].y, true).angle;
var step = 1 * Math.cos(angle);
var n = 0;
for(var x = active_border[0].x; x < active_border[active_border.length - 1].x; x+=step){
for(var i = n + 1; i < active_border.length - 1; i++){
if(x > active_border[i].x){
angle = getAngle({}, active_border[i].x, active_border[i].y, active_border[i + 1].x, active_border[i + 1].y, true).angle;
step = 1 * Math.cos(angle);
n++;
}
}
var y = lagr(x, active_border);
ctx3.fillStyle = "red";
ctx3.fillRect(y*10 + 375, -x*10 + 250, 3,3);
}
}
function initScene() {
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 0, 15, 35 );
scene = new THREE.Scene();
pointLight = new THREE.PointLight( 0xDDDDDD, 1, 100 );
pointLight.name = 'Spot Light';
pointLight.intensity = 10;
pointLight.decay = 0.2;
pointLight.position.set(0, 10, 0);
pointLight.castShadow = true;
pointLight.receiveShadow = true;
scene.add( pointLight );
}
function initMisc() {
clock = new THREE.Clock();
window.canvas = document.querySelector('#c');
renderer = new THREE.WebGLRenderer({canvas, antialias: true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
updateAll();
// Mouse control
controls = new THREE.OrbitControls( camera, canvas );
controls.target.set( 0, 2, 0 );
controls.update();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function collision(obj, test){
if(obj && obj.position){
var angle = obj.rotation.y;
var params = getRadiusCoords(obj.position.x, obj.position.z, 25, angle); // Точка на расстоянии 0.5 от центра объекта — нос корабля, к примеру.
var obj2 = {x: params.x, y: params.y};
for(var k = 0; k <= 1; k++){
for(var i = 0; i < border_points[k].length - 1; i++){
if(canvas2.style.display != "none"){
drawMapAndBorders(i);
}
var obj3 = border_points[k][i];
var obj4 = border_points[k][i + 1];
var r = Math.sqrt(Math.pow( obj.position.x - obj3.x , 2) + Math.pow(obj.position.z - obj3.y , 2));
if( r <= collision_distance && !obj.lagrange_stopped || test){
if(!obj.before_collision && !obj.before_collision_bezier && !obj.collision){
var intersection = lineIntersection({x: obj.position.x, y: obj.position.z}, {x: obj2.x, y: obj2.y}, obj3, obj4);
var x = intersection.x;
var y = intersection.y;
if(obj4.y >= obj3.y){
var condition = x >= obj3.x && x <= obj4.x && y >= obj3.y && y <= obj4.y;
}
else{
var condition = x >= obj3.x && x <= obj4.x && y >= obj4.y && y <= obj3.y;
}
if(condition){
obj.border_line_angle = getAngle({}, obj3.x, obj3.y, obj4.x, obj4.y, true).angle;
obj.border_line_num = i;
ctx3.clearRect(0, 0, canvas2.width, canvas2.height);
drawCross(x, y, "white", size = 0.5);
active_border = border_points[k];
if(!test){
if(i < border_points[k].length / 2 - 1){
obj.lagr_direction = -1;
}
else{
obj.lagr_direction = 1;
}
obj.path2 = x;
// obj.lagr_direction = -1;
// obj.path2 = border_points[k][0].x;
}
else{
obj.path2 = 0;
}
return r;
}
// else{
// return false;
// }
}
}
}
}
// return false;
}
// else{
// return false;
// }
return false;
}
function renderScene() {
// var object = scene.getObjectByName("Scene");
if(typeof man_pers != "undefined"){
if(typeof man_pers.mixer != "undefined" && light_house && light_house.children){
var light_house_plate = light_house.children[0].children[0].children[0].children[0].children[2].geometry.boundingSphere;
let x0 = light_house_plate.center.x * light_house.scale.x;
let y0 = -light_house_plate.center.y * light_house.scale.y;
var params = getRadiusCoords(x0, y0, light_house_plate.radius * light_house.scale.x - 1.3, man_pers.angle_for_rotation * Math.PI / 180);
x0 = man_pers.position.x;
y0 = man_pers.position.z;
man_pers.position.x = params.x;
man_pers.position.z = params.y;
getAngle( man_pers, x0, y0, man_pers.position.x, man_pers.position.z);
man_pers.rotation.y = man_pers.angle + Math.PI/2;
man_pers.position.y = 1.9;
}
}
if(typeof man_pers != "undefined" && man_pers){
man_pers.angle_for_rotation += man_pers.step;
if(man_pers.angle_for_rotation > 360){
man_pers.angle_for_rotation = 0;
}
}
floor.material.uniforms[ 'time' ].value += 0.1 / 60.0;
if(pointsShader){
pointsShader.uniforms[ 'time' ].value += 0.1 / 60.0;
}
if(window.palmShader && window.palmShader.length >= 1){
for(var i in palm){
if(window.palmShader[i]){
palm[i].angle_for_rotation++;
window.palmShader[i].uniforms[ 'uTime' ].value = palm[i].angle_for_rotation * Math.PI / 180;
}
}
}
for(var k in moving_objects){
var object = moving_objects[k];
if(object && !object.test_stop){
object.test_stop = 0;
}
// if(object && object.test_stop < tt || manual_drive){
if(object){
if(!object.rotation_step){
object.angle_for_rotation++;
}
else{
object.angle_for_rotation += object.rotation_step;
}
if(object.angle_for_rotation > 360){
object.angle_for_rotation = 0;
}
object.move(object);
}
}
if(typeof man_pers != "undefined"){
glow_sphere.scale.x = Math.cos(man_pers.angle_for_rotation * Math.PI / 180);
glow_sphere.scale.y = Math.cos(man_pers.angle_for_rotation * Math.PI / 180);
glow_sphere.scale.z = Math.cos(man_pers.angle_for_rotation * Math.PI / 180);
glow_sphere.material.uniforms.viewVector.value = new THREE.Vector3().subVectors( camera.position, new THREE.Vector3(island_group.position.x + glow_sphere.position.x, island_group.position.y + glow_sphere.position.y, island_group.position.z + glow_sphere.position.z));
}
updateParticles();
if(border_cube_group.children.length > 0 && test){
intersectBorderCube();
}
renderer.render( scene, camera );
}
function render() {
renderScene();
}
function updateAll() {
requestAnimationFrame(updateAll);
delta += clock.getDelta();
if (delta > interval) {
// The draw or time dependent code are here
render();
delta = delta % interval;
}
}
////////////////////////////// Move functions ////////////////////////////////////
function fishMove(object, minz = -10, maxz = 0.2){
if(object.path == undefined || object.path >= 0.9){
// alert();
object.collision = false;
object.path = 0;
var x0 = object.position.x0 = object.position.x;
var y0 = object.position.y0 = object.position.z;
var z0 = object.position.z0 = object.position.y;
object.step = getRandom(2, 5) / 1000;
if(object == whale){
var random_radius = getRandom(5, 20);
var random_angle = getRandom(0, Math.PI * 2);
var random_target = getRadiusCoords(0, 0, random_radius, random_angle);
object.position.x_end = random_target.x;
object.position.y_end = random_target.y;
object.position.z_end = getRandom(maxz, minz);
}
else{
object.position.x_end = getRandom(-20, 20);
object.position.y_end = getRandom(-20, 20);
object.position.z_end = getRandom(maxz, minz);
}
var params;
params = getAngle(object, x0, y0, object.position.x_end, object.position.y_end);
object.angle_old = object.rotation.y - Math.PI / 2;
var r = object.hipotenuse;
params = getRadiusCoords(x0, y0, object.hipotenuse / 10, object.angle_old);
params2 = getRadiusCoords(x0, y0, r, object.angle_old + 10 / 180 * Math.PI);
object.p = [];
if(params.x){
object.p[0] = {
x: object.position.x0,
y: object.position.y0,
z: object.position.z0,
}
object.p[1] = {
x: params.x,
y: params.y,
z: getRandom(maxz, minz)
}
object.p[2] = {
x: params2.x,
y: params2.y,
z: getRandom(maxz, minz)
}
object.p[3] = {
x: object.position.x_end,
y: object.position.y_end,
z: object.position.z_end,
}
}
}
if(object.p || test){
if(object == whale){
object.rotation.z = object.angle_for_rotation / 180 * Math.PI;
}
if( (!object.collision || object.lagrange_stopped) && !test ){
if(object.path == undefined){
object.path = 0;
}
if(object.path <= 1){
if(!object.before_collision_bezier){
var t_step = object.step;
}
else{
var t_step = 0.005;
}
if(!manual_drive){
object.path += t_step - t_step * object.path;
}
}
else{
object.moving_stopped = true;
}
}
if(!test){
var t = object.path;
var p0 = object.p[0];
var p1 = object.p[1];
var p2 = object.p[2];
}
///////////////////
var x0 = object.position.x;
var y0 = object.position.z;
var z0 = object.position.y;
///////////////////
if(!object.moving_stopped && t <= 1){
p0 = object.p[0];
p1 = object.p[1];
p2 = object.p[2];
var p3 = object.p[3];
var p4 = object.p[4];
object.position.x = Math.pow(1 - t, 3) * p0.x + 3 * t * Math.pow(1 - t, 2) * p1.x
+ 3 * Math.pow(t, 2) * (1 - t) * p2.x + Math.pow(t, 3) * p3.x;
object.position.z = Math.pow(1 - t, 3) * p0.y + 3 * t * Math.pow(1 - t, 2) * p1.y
+ 3 * Math.pow(t, 2) * (1 - t) * p2.y + Math.pow(t, 3) * p3.y;
object.position.y = Math.pow(1 - t, 3) * p0.z + 3 * t * Math.pow(1 - t, 2) * p1.z
+ 3 * Math.pow(t, 2) * (1 - t) * p2.z + Math.pow(t, 3) * p3.z;
}
// ctx3.fillRect(whale.position.z*10 + 375, -whale.position.x*10 + 250, 1, 1);
if(t <= 1){
getAngle(object, x0, y0, object.position.x, object.position.z);
if(object.angle){
object.rotation.y = object.angle + Math.PI / 2;
}
}
if(t >= 1 && object.before_collision_bezier){
// object.before_collision_bezier = false;
// object.collision = true;
}
}
}
function shipMove(object){
object.position.y = -0.3 + Math.cos(object.angle_for_rotation / 180 * Math.PI + Math.PI / 2) / 10;
object.rotation.x = Math.cos(object.angle_for_rotation / 180 * Math.PI) / 5;
if(object.p || test){
var r = collision(object, test) ;
// Детекция коллизии
if( r && !object.before_collision && ! object.before_collision_bezier && !object.collision){
object.before_collision = true;
object.angle_for_rotation = 0;
object.path = 0;
let x0 = object.position.x0 = object.position.x;
let y0 = object.position.y0 = object.position.z;
let params, params2, params3;
params = getAngle(object, x0, y0, object.position.x_end, object.position.y_end);
if(object.rotation.y){
object.angle_old = object.rotation.y;
}
}
if( (!object.collision || object.lagrange_stopped) && !test ){
if(object.path == undefined){
object.path = 0;
}
if(object.path <= 1){
if(!object.before_collision_bezier){
var t_step = 0.002;
}
else{
var t_step = 0.005;
}
if(!manual_drive){
object.path += t_step;
}
rotor.rotation.x = object.angle_for_rotation / 180 * Math.PI * 10;
}
else{
object.moving_stopped = true;
}
}
if(!object.moving_stopped){
rotor.rotation.x = object.angle_for_rotation / 180 * Math.PI * 10;
}
if(!test){
var t = object.path;
var p0 = object.p[0];
var p1 = object.p[1];
var p2 = object.p[2];
}
///////////////////
let x0 = object.position.x;
let y0 = object.position.z;
///////////////////
if(object.before_collision){
object.path = 0;
object.position.x0 = object.position.x;
object.position.y0 = object.position.z;
var params, params2;
params = getAngle(object, x0, y0, object.position.x_end, object.position.y_end);
object.angle_old = object.rotation.y;
var r = 5;
var x_bezier_end = object.path2;
var y_bezier_end = lagr(object.path2, active_border);
// let angle = getAngle({}, x0, y0, x_bezier_end, y_bezier_end, true).angle;
params = getRadiusCoords(x0, y0, object.hipotenuse / 10, object.angle_old);
var line_num = object.border_line_num;
if(object.lagr_direction > 0){
var determ = Math.PI;
}
else{
var determ = Math.PI * 2;
}
params2 = getRadiusCoords(active_border[line_num].x, active_border[line_num].y, r, object.border_line_angle + determ);
object.p[0] = {
x: object.position.x,
y: object.position.z
}
object.p[1] = {
x: params.x,
y: params.y
}
object.p[2] = {
x: params2.x,
y: params2.y
}
object.p[3] = {
x: x_bezier_end,
y: y_bezier_end
}
object.before_collision = false;
object.before_collision_bezier = true;
}
if(object.collision){
if(!test){
var p = object.p;
}
else{
var p = [];
object.p = [];
}
if(object.path2 != undefined){
object.path2 += 0.02 * object.lagr_direction;
}
// Окончание продвижения по кривой Лагранжа окончено
if(object.lagr_direction == 1){
var condition = object.position.x >= active_border[active_border.length - 1].x;
}
else{
var condition = object.position.x <= active_border[0].x;
}
if(condition){
object.collision = false;
object.lagrange_stopped = true;
object.angle_for_rotation = 0;
object.path = 0;
object.position.x0 = object.position.x;
object.position.y0 = object.position.z;
var params;
params = getAngle(object, x0, y0, object.position.x_end, object.position.y_end, true);
object.angle_old = object.rotation.y;
var r = object.hipotenuse;
params = getRadiusCoords(x0, y0, object.hipotenuse / 10, object.angle_old);
params2 = getRadiusCoords(x0, y0, r, object.angle_old + 10 / 180 * Math.PI);
object.p[0] = {
x: object.position.x,
y: object.position.z
}
object.p[1] = {
x: params.x,
y: params.y
}
object.p[2] = {
x: params2.x,
y: params2.y
}
object.p[3] = {
x: object.position.x_end,
y: object.position.y_end
}
}
// Движение по кривой Лагранжа
var x = object.path2;
var y = lagr(x, active_border); // Лагранж
object.position.x = x;
object.position.z = y;
}
else if(!object.moving_stopped && t <= 1){
p0 = object.p[0];
p1 = object.p[1];
p2 = object.p[2];
var p3 = object.p[3];
var p4 = object.p[4];
object.position.x = Math.pow(1 - t, 3) * p0.x + 3 * t * Math.pow(1 - t, 2) * p1.x
+ 3 * Math.pow(t, 2) * (1 - t) * p2.x + Math.pow(t, 3) * p3.x;
object.position.z = Math.pow(1 - t, 3) * p0.y + 3 * t * Math.pow(1 - t, 2) * p1.y
+ 3 * Math.pow(t, 2) * (1 - t) * p2.y + Math.pow(t, 3) * p3.y;
}
// В начале движения по безье бывает какой-то резкий скачок угла по сравнению с предыдущим положением,
// поэтому первый шаг c приращением t прпускаем
if(t <= 1 && t > t_step || object.collision){
getAngle(object, x0, y0, object.position.x, object.position.z);
if(object.angle){
object.rotation.y = object.angle;
if(object.before_collision_bezier){
// console.log(t); ;
object.test_stop++;
}
}
}
if(t >= 1 && object.before_collision_bezier){
object.before_collision_bezier = false;
object.collision = true;
}
}
}
////////////////////////////// Mathematical functions ////////////////////////////////////
function getRadiusCoords(x0, y0, radius, angle){
var x = x0 + radius * Math.cos(angle);
var y = y0 - radius * Math.sin(angle);
return {x: x, y: y, angle: angle}
}
function getAngle(object, x0, y0, x_end, y_end, flag = false){
var a = y0 - y_end;
var b = x0 - x_end;
var hipotenuse_squared = Math.pow(a, 2) + Math.pow(b, 2);
var hipotenuse = object.hipotenuse = Math.sqrt(hipotenuse_squared);
var sina = object.sina = a / hipotenuse;
var cosa = object.cosa = b / hipotenuse;
if(!flag){
if(sina > 0){
object.angle = Math.PI - Math.acos(cosa);
}
else{
object.angle = Math.PI + Math.acos(cosa);
}
}
else{
if(sina > 0){
var angle = Math.PI - Math.acos(cosa);
}
else{
var angle = Math.PI + Math.acos(cosa);
}
}
return {sin: sina, cos: cosa, angle: angle}
}
function getRandom(min, max) {
const minCeiled = Math.ceil(min);
const maxFloored = Math.floor(max);
return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled); // The maximum is exclusive and the minimum is inclusive
}
function lagr(x0, points){
var y0=0;//значение многочлена в точке y0
var step;
for(var i=0;i<points.length;i++)
{
step=points[i].y;
for(var j=0;j<points.length;j++)//считаем множитель при i-ом значении
{ //сеточной функции
if(i!=j)
step=step*(x0-points[j].x)/(points[i].x-points[j].x);
}
y0+=step;
}
return y0;
}
function lineIntersection(p1, p2, p3, p4){
var x1 = p1.x;
var y1 = p1.y;
var x2 = p2.x;
var y2 = p2.y;
var x3 = p3.x;
var y3 = p3.y;
var x4 = p4.x;
var y4 = p4.y;
var alpha = ( (x1 - x3) * (y4 - y3) - (y1 - y3) * (x4 - x3) ) /
( (y2 - y1) * (x4 - x3) - (x2 - x1) * (y4 - y3) );
// var beta = ( (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1) ) /
// ( (y2 - y1) * (x4 - x3) - (x2 - x1) * (y4 - y3) );
var x = x1 + alpha * (x2 - x1);
var y = y1 + alpha * (y2 - y1);
// var x = ( (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4) ) /
// ( (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4) );
// var y = ( (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4) ) /
// ( (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4) );
return {x: x, y: y};
}
/////////////////////////////// Mouse events, 3d objects intersections /////////////////////////////////////////
socket.on("coords", (obj)=>{
if(obj.id != myId){
var obj2 = ships[obj.id];
if(obj.x && ships[obj.id]){
ships[obj.id].rotation.y = obj.angle;
onPointerClick(undefined, ships[obj.id], {x: obj.x, y: obj.y});
}
}
})
socket.on("connect", ()=> {
socket.on("send_objects", (obj_collection)=>{;
for(var i in obj_collection){
var obj = obj_collection[i];
var obj2 = ships[i];
if(!obj2){
obj2 = ships[myId].clone();
obj2.move = function(object){shipMove(object)};
obj2.position.z = obj.y0;
obj2.position.x = obj.x0;
obj2.rotation.y = obj.angle;
obj2.angle_for_rotation = 0;
obj2.rotation.z = 0;
ships[obj.id] = obj2;
moving_objects[obj.id] = obj2;
scene.add(obj2);
ships[obj.id].getObjectByName("Scene").getObjectByName("ship").material
= ships[myId].getObjectByName("Scene").getObjectByName("ship").material.clone();
var color = colors[obj.id.toString().slice(-1)];
ships[obj.id].getObjectByName("Scene").getObjectByName("ship").material.color.set( color );
if(obj.x){
onPointerClick(undefined, ships[obj.id], {x: obj.x, y: obj.y});
}
}
}
})
})
socket.on("remove", (id) => {
scene.remove(ships[id]);
delete ships[id];
delete moving_objects[id];
scene.remove(partical_points[id]);
delete partical_points[id];
})
function onPointerClick(e, object, end_coords) {
ctx3.clearRect(0, 0, canvas2.width, canvas2.height);
controls.enableRotate = true;
if(test){
intersectBorderCube();
}
if(!object){
var canvasBoundingRect = canvas.getBoundingClientRect();
var t = canvasBoundingRect;
pointer.x = (e.clientX - t.left) / t.width * 2 - 1;
pointer.y = -(e.clientY - t.top) / t.height * 2 + 1;
if(scene.getObjectByName("Scene")){
// scene.getObjectByName("Scene").position.x = pointer.y;
// scene.getObjectByName("Scene").position.z = pointer.x;
scene.getObjectByName("Scene").position.y = -0.3;
}
raycaster.setFromCamera( pointer, camera );
var intersects2 = raycaster.intersectObjects( light_house.children[0].children[0].children[0].children[0].children );
if(intersects2[0]){
sea_not_clicked = true;
}
var intersects = raycaster.intersectObjects( [floor] );
var object = ships[myId];
if(intersects[0] && !sea_not_clicked){
socket.emit("mouseclick", {x0: object.position.x, y0: object.position.z, x: intersects[0].point.x, y: intersects[0].point.z, angle: object.rotation.y, id: myId});
}
}
else{
var intersects = [{point: {x: end_coords.x, z: end_coords.y}}];
}
if(object && intersects[0] && !sea_not_clicked){
object.collision = false;
object.lagrange_stopped = false;
object.angle_for_rotation = 0;
object.path = 0;
if(!collision_edit.checked){
object.moving_stopped = false;
}
var x0 = object.position.x0 = object.position.x;
var y0 = object.position.y0 = object.position.z;
object.position.x_end = intersects[0].point.x;
object.position.y_end = intersects[0].point.z;
var params;
params = getAngle(object, x0, y0, object.position.x_end, object.position.y_end);
object.angle_old = object.rotation.y;
var r = object.hipotenuse;
params = getRadiusCoords(x0, y0, object.hipotenuse / 10, object.angle_old);
params2 = getRadiusCoords(x0, y0, r, object.angle_old + 10 / 180 * Math.PI);
object.p = [];
if(params.x){
object.p[0] = {
x: object.position.x0,
y: object.position.y0
}
object.p[1] = {
x: params.x,
y: params.y
}
object.p[2] = {
x: params2.x,
y: params2.y
}
object.p[3] = {
x: object.position.x_end,
y: object.position.y_end
}
}
if(object.moving_stopped && test && !active_border_cube && mouse_down){
var same;
for(var i = 0; i < border_cube.length; i++){
var r = Math.sqrt(Math.pow(border_cube[i].position.x - object.position.x_end , 2) + Math.pow(border_cube[i].position.z - object.position.y_end , 2));
if(r < 1){
same = true;
}
}
if(!same){
// active_border.push({x: object.position.x_end, y: object.position.y_end});
}
}
if(object.moving_stopped){
drawLagr();
}
if(!test){
drawCross(object.position.x_end, object.position.y_end, "yellow");
}
mouse_down = false;
if(test){
active_border_cube = null;
if(last_selected_border_cube){
last_selected_border_cube.material.color.set( 0x00ff00 );
}
}
}
sea_not_clicked = false;
}
function onPointerMove(e){
if(mouse_down && active_border_cube){
controls.enableRotate = false;
var object = active_border_cube;
var canvasBoundingRect = canvas.getBoundingClientRect();
var t = canvasBoundingRect;
pointer.x = (e.clientX - t.left) / t.width * 2 - 1, pointer.y = -(e.clientY - t.top) / t.height * 2 + 1;
raycaster.setFromCamera( pointer, camera );
const intersects = raycaster.intersectObjects( [floor] );
if(intersects[0] && active_border[object.border_index]){
object.position.x = active_border[object.border_index].x = intersects[0].point.x;
object.position.z = active_border[object.border_index].y = intersects[0].point.z;
}
}
}
function intersectBorderCube(){
raycaster.setFromCamera( pointer, camera );
const intersects = raycaster.intersectObjects( border_cube_group.children );
for ( let i = 0; i < intersects.length; i ++ ) {
if(intersects[i].object.material && intersects[i].object.material.color){
if(intersects[i].object.side == "border_right"){
active_border = border_points[0];
border_right.checked = true;
}
else{
active_border = border_points[1];
border_left.checked = true;
}
if(last_selected_border_cube){
if(last_selected_border_cube.side == "border_right"){
last_selected_border_cube.material.color.set( 0x00ff00 );
}
else{
last_selected_border_cube.material.color.set( 0x00ffff );
}
}
intersects[i].object.material.color.set( 0xff0000 );
intersects[i].object.material.opacity = .4;
intersects[i].object.material.shading = THREE.SmoothShading;
active_border_cube = last_selected_border_cube = intersects[i].object;
}
}
}
/////////////////////////////////// Map /////////////////////////////////////
border_points[0] =
[
{
"x": -1.2113842910829153,
"y": -10.20368127403675
},
{
"x": -0.3268580714700465,
"y": -7.666822126687212
},
{
"x": 0.6890313333965716,
"y": -4.403478523373602
},
{
"x": 2.0357299502829433,
"y": -1.4867182714845308
},
{
"x": 4.708221202175898,
"y": 1.003468923747237
},
{
"x": 7.603186470908478,
"y": 2.0330304558189978
},
{
"x": 9.933313576160806,
"y": 1.417204576840065
},
{
"x": 11.784359617591125,
"y": -0.7930962743302238
}
]
active_border = border_points[0];
border_points[1] = [
{
"x": 0.37174050726418856,
"y": -12.049503723260987
},
{
"x": 1.4611625017149312,
"y": -11.225539099864234
},
{
"x": 3.5639160342243534,
"y": -10.928587507175635
},
{
"x": 6.383207738717317,
"y": -10.026572088951687
},
{
"x": 8.288880726504546,
"y": -8.838856345464318
},
{
"x": 9.423301438191896,
"y": -7.014197207129665
},
{
"x": 10.628422053686432,
"y": -5.119482761193863
},
{
"x": 11.764454365474576,
"y": -2.9429357450408746
}
];
var rock_active_border = [];
function drawMapAndBorders(num){
ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
var x, y, angle;
var rock_points = light_house.children[0].children[0].children[0].children[0].children[3].geometry.attributes.position;
if(rock_active_border.length == 0){
for(var i = 0; i < rock_points.count; i+=5){
if(rock_points.getZ(i) < 0){
x = rock_points.getX(i);
y = rock_points.getY(i);
angle = getAngle({}, 0, 0, y, x, true).angle;
var r = Math.sqrt(Math.pow(x , 2) + Math.pow(y , 2));
var params = getRadiusCoords(0, 0, r, angle + island_group.rotation.y + Math.PI / 2);
rock_active_border.push({x: params.x, y: params.y});
}
}
}
for(var i = 0; i < rock_active_border.length; i++){
x = rock_active_border[i].x * light_house.scale.x + island_group.position.x;
y = rock_active_border[i].y * light_house.scale.z + island_group.position.z;
ctx2.fillStyle = "lime";
ctx2.fillRect(y*10 + 375, -x*10 + 250, 4,4);
}
ctx2.beginPath();
x = -25;
y = - x * Math.cos(Math.PI / 2) / Math.sin(Math.PI / 2);
ctx2.strokeStyle = "red";
ctx2.moveTo(y*10 + 375, -x*10 + 250);
x = 25;
y = - x * Math.cos(Math.PI / 2) / Math.sin(Math.PI / 2);
ctx2.lineTo(y*10 + 375, -x*10 + 250);
ctx2.stroke();
ctx2.beginPath();
x = -25;
y = - x * Math.cos(180 * Math.PI / 180) / Math.sin(180 * Math.PI / 180);
ctx2.strokeStyle = "yellow";
ctx2.moveTo(y*10 + 375, -x*10 + 250);
x = 25;
y = - x * Math.cos(180 * Math.PI / 180) / Math.sin(180 * Math.PI / 180);
ctx2.lineTo(y*10 + 375, -x*10 + 250);
ctx2.stroke();
var color = ["yellow", "pink", "white", "lime", "blue", "maroon", "purple"];
for(var i = 0; i < active_border.length; i++){
ctx2.fillStyle = "yellow";
ctx2.fillRect(active_border[i].y*10 + 375, -active_border[i].x*10 + 250, 5,5);
if(!border_cube[i]){
const w = 0.5;
const geometry = new THREE.BoxGeometry( w, w, w );
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
border_cube[i] = new THREE.Mesh( geometry, material );
border_cube[i].position.set(active_border[i].x, w/2, active_border[i].y);
border_cube[i].name = border_cube + "_" + i;
border_cube[i].border_index = i;
border_cube[i].cube_index = i;
border_cube[i].side = border_right.id;
if(ships[myId].moving_stopped){
border_cube[i].visible = true;
}
else{
border_cube[i].visible = false;
}
border_cube_group.add( border_cube[i] );
scene.add( border_cube_group );
}
}
var k = i;
for(var i = 0; i < border_points[1].length; i++){
ctx2.fillStyle = "blue";
ctx2.fillRect(border_points[1][i].y*10 + 375, -border_points[1][i].x*10 + 250, 5,5);
if(!border_cube[i + k]){
const w = 0.5;
const geometry = new THREE.BoxGeometry( w, w, w );
const material = new THREE.MeshBasicMaterial( {color: 0x00ffff} );
border_cube[i + k] = new THREE.Mesh( geometry, material );
border_cube[i + k].position.set(border_points[1][i].x, w/2, border_points[1][i].y);
border_cube[i + k].name = border_cube + "_" + (i + k);
border_cube[i + k].border_index = i;
border_cube[i + k].cube_index = i + k;
border_cube[i + k].side = border_left.id;
if(ships[myId].moving_stopped){
border_cube[i + k].visible = true;
}
else{
border_cube[i + k].visible = false;
}
border_cube_group.add( border_cube[i + k] );
scene.add( border_cube_group );
}
}
ctx2.fillStyle = "red";
var radius = 6;
ctx2.beginPath();
ctx2.arc(island_group.position.z*10 + 375 - radius/2, -island_group.position.x*10 + 250 - radius/2, radius, 0, Math.PI * 2);
ctx2.fill();
for(var num2 = 0; num2 < active_border.length - 1; num2+=1){
var x1, y1, x2, y2;
angle = getAngle({}, active_border[num2].y, active_border[num2].x, active_border[num2 + 1].y, active_border[num2 + 1].x, true).angle;
ctx2.strokeStyle = "yellow";
ctx2.beginPath();
x1 = active_border[num2].x;
y1 = active_border[num2].y;
ctx2.moveTo(y1*10 + 375, -x1*10 + 250);
x2 = active_border[num2 + 1].x;
y2 = - (x2 - active_border[num2].x) * Math.cos(angle) / Math.sin(angle) + active_border[num2].y;
ctx2.lineTo(y2*10 + 375, -x2*10 + 250);
ctx2.stroke();
}
ctx2.fillStyle = "white";
radius = 3;
ctx2.beginPath();
ctx2.arc(ships[myId].position.z*10 + 375, -ships[myId].position.x*10 + 250, radius, 0, Math.PI * 2);
ctx2.fill();
angle = Math.PI / 2 - ships[myId].rotation.y;
ctx2.strokeStyle = "white";
ctx2.beginPath();
x = ships[myId].position.x;
y = - (x - ships[myId].position.x) * Math.cos(angle) / Math.sin(angle) + ships[myId].position.z;
ctx2.moveTo(y*10 + 375, -x*10 + 250);
if(angle < 0 && angle > -Math.PI){
x = -25;
}
else{
x = 25;
}
y = - (x - ships[myId].position.x) * Math.cos(angle) / Math.sin(angle) + ships[myId].position.z;
ctx2.lineTo(y*10 + 375, -x*10 + 250);
ctx2.stroke();
if(ships[myId].before_collision_bezier){
ctx3.fillStyle = "yellow";
}
else if(ships[myId].collision){
ctx3.fillStyle = "lightblue";
}
else{
ctx3.fillStyle = "red";
}
ctx3.fillRect(ships[myId].position.z*10 + 375, -ships[myId].position.x*10 + 250, 2,2);
}
function drawCross(x0, y0, color, size = 1){
ctx3.lineWidth = 3;
var x1, y1, x2, y2;
var angle = Math.PI / 4;
ctx3.strokeStyle = color;
ctx3.beginPath();
x1 = x0 - size;
y1 = y0 - size;
ctx3.moveTo(y1*10 + 375, -x1*10 + 250);
x2 = x0 + size;
y2 = y0 + size;
ctx3.lineTo(y2*10 + 375, -x2*10 + 250);
ctx3.stroke();
var x1, y1, x2, y2;
var angle = -Math.PI / 4;
ctx3.strokeStyle = color;
ctx3.beginPath();
x1 = x0 - size;
y1 = y0 + size;
ctx3.moveTo(y1*10 + 375, -x1*10 + 250);
x2 = x0 + size;
y2 = y0 - size;
ctx3.lineTo(y2*10 + 375, -x2*10 + 250);
ctx3.stroke();
}
//////////////////////////////// Water /////////////////////////////////////////////
prom[0] = new Promise((resolve, reject) =>{
const planeSize = 40; // размер плоскости, которую будем использовать для пола
var planeGeo = new THREE.PlaneGeometry(planeSize, planeSize, 16, 16); // создаем геометрию для пола — попросту размеры
{
window.floor = new THREE.Water( planeGeo, {
waterNormals: new THREE.TextureLoader().load(floor_texture, function ( texture ) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
loading_text.innerHTML += "sea is loaded";
resolve();
}),
alpha: 0.9,
waterColor: 0x1974d2,
distortionScale: 0,
sunDirection: new THREE.Vector3( 0.0, 0.1, -1.0 ).normalize(),
sunColor: 0xffffff,
});
floor.position.set(0, 0, 0);
floor.rotation.x = Math.PI * -.5; // поворачиваем пол на 90 градусов по X
floor.rotation.z = Math.PI * -.5;
floor.receiveShadow = true;
floor.position.set(0, 0, 0);
floor.material.transparent = true;
scene.add(floor); // добавляем пол в сцену
}
})
/////////////////////////////// Particles /////////////////////////////////////////
{
partical_material = new THREE.PointsMaterial({
color: "white",
map: new THREE.TextureLoader().load(smoke_texture),
onBeforeCompile: patch => {
patch.uniforms.time = { value: 0 };
patch.vertexShader = particle_vertecies;
patch.fragmentShader = particle_fragments;
pointsShader = patch;
}
})
}
function updateParticles(){
for(var i in ships){
var object = ships[i];
var id = i;
if(object.angle_for_rotation % 10 == 0){
if(object.path && object.path > 0 && object.path < 1 || object.collision){
let sizes = [];
let rots = [];
let pts = new Array(1000).fill(0).map(p => {
sizes.push((Math.random() * 0.5 + 0.1) / 3);
rots.push(Math.random() * Math.PI / 10);
return new THREE.Vector3().random().subScalar(0.5).multiplyScalar(10)
});
if(partical_points[id]){
scene.remove(partical_points[id]);
}
geometry = new THREE.BufferGeometry().setFromPoints(pts);
geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));
geometry.setAttribute("rots", new THREE.Float32BufferAttribute(rots, 1));
partical_points[id] = new THREE.Points(geometry, partical_material);
partical_points[id].scale.set(0.25, 0.02, 0.1);
if(object){
partical_points[id].position.x = object.position.x;
partical_points[id].position.z = object.position.z;
partical_points[id].rotation.x = object.rotation.x;
partical_points[id].rotation.y = object.rotation.y;
partical_points[id].rotation.z = object.rotation.z;
}
scene.add(partical_points[id]);
}
else{
scene.remove(partical_points[id]);
}
}
}
}
//////////////////////////////// Models /////////////////////////////////////////////
const gltfLoader = new GLTFLoader();
const fbxLoader = new FBXLoader();
prom[1] = new Promise((resolve, reject) => {
gltfLoader.load( ship_model, (gltf) => {
resolve();
ships[myId] = gltf.scene;
rotor = ships[myId].getObjectByName("Scene").getObjectByName("rotor");
scene.add(ships[myId]);
// ships[myId].children[0].receiveShadow = true
// ships[myId].children[0].castShadow = true
ships[myId].scale.set(0.5, 0.5, 0.5);
ships[myId].angle_for_rotation = 0;
ships[myId].position.z = ship_init.y;
ships[myId].position.x = ship_init.x;
ships[myId].rotation.y = ship_init.angle / 180 * Math.PI;
ships[myId].move = function(object){shipMove(object)};
var color = colors[myId.toString().slice(-1)];
ships[myId].getObjectByName("Scene").getObjectByName("ship").material.color.set( color );
moving_objects[myId] = ships[myId];
}, (bytes) => { loading_text.innerHTML += " " + "ship model " + Math.floor(bytes.loaded / bytes.total * 100) + "% " + "is loaded"})
});
////////////////////////////////////////////////////////////////////////
prom[2] = new Promise((resolve, reject) => {
gltfLoader.load( light_house_model, (gltf) => {
resolve();
window.light_house = gltf.scene;
light_house.name = "Lighthouse";
light_house.scale.set(0.15, 0.15, 0.15);
light_house.position.y -= 0.025;
const vertexShader = island_vertecies;
const fragmentShader = island_fragments;
var rock = light_house.children[0].children[0].children[0].children[0].children[3];
rock.material.onBeforeCompile = patch => {
patch.uniforms.texture1 = {value: 0};
patch.uniforms.texture2 = {value: 0};
patch.uniforms.texture3 = {value: 0};
patch.uniforms.intensity = {value: 0};
patch.uniforms.pointShadowMap = {value: 0};
patch.vertexShader= vertexShader;
patch.fragmentShader= fragmentShader;
window.rockShader = patch;
var texture1 = new THREE.TextureLoader().load(rock_texture, function ( texture ) {
var texture2 = new THREE.TextureLoader().load(base_path + "/Rock_color2.png", function ( texture ) {
var texture3 = new THREE.TextureLoader().load(base_path + "/Rock_color.png", function ( texture ) {
window.rockShader.uniforms.texture1.value = texture1;
window.rockShader.uniforms.texture2.value = texture2;
window.rockShader.uniforms.texture3.value = texture3;
window.rockShader.uniforms.intensity.value = 25;
map.click();
socket.emit("mouseclick", {x0: ships[myId].position.x, y0: ships[myId].position.z, x: undefined, y: undefined, angle: ships[myId].rotation.y, id: myId});
socket.emit("loaded");
})
})
});
// var img = new Image();
// img.src = rock_texture;
// img.onload = function(){createImageBitmap(img).then(function (bitmap) {
// // light_house.children[0].children[0].children[0].children[0].children[3].material.map.source.data = bitmap;
// setTimeout(function(){
// window.rockShader.uniforms[ 'texture2' ].value = { type: 't', value: 0, texture: new THREE.TextureLoader().loaa( rock_texture ) };
// }, 1000);
// })};
};
palmsSet();
island_group.add(light_house);
loading_text.innerHTML += " island texture is loading ";
}, (bytes) => { loading_text.innerHTML += " " + "light house model " + Math.floor(bytes.loaded / bytes.total * 100) + "% " + "is loaded"})
});
////////////////////////////////////////////////////////////////////////
function palmsSet(){
prom[3] = new Promise((resolve, reject) =>{
gltfLoader.load( palm_model, (gltf) => {
resolve();
window.palm = [];
palm[0] = gltf.scene;
palm[0].name = "Palm";
palm[0].scale.set(0.5, 0.5, 0.5);
palm[0].position.x += 5;
palm[0].position.z -= 5;
palm[0].position.y = 0.4;
palm[0].angle_for_rotation = 0;
island_group.add(palm[0]);
var rock_points = light_house.children[0].children[0].children[0].children[0].children[3].geometry.attributes.position;
// light_house.children[0].children[0].children[0].children[0].children[3].receiveShadow = true;
// light_house.children[0].children[0].children[0].children[0].children[3].castShadow = true;
var rock_points_geometry = light_house.children[0].children[0].children[0].children[0].children[3].geometry;
var max = rock_points.count;
var index = 0;
palm[0].position.x = rock_points.getX(index) * light_house.scale.x;
palm[0].position.y = rock_points.getZ(index) * light_house.scale.y;
palm[0].position.z = -rock_points.getY(index) * light_house.scale.z;
for(var i = 1; i < 50; i++){
palm[i] = palm[0].clone();
// scene.add(palm[i]);
island_group.add(palm[i]);
index = getRandom(1, max);
palm[i].position.x = rock_points.getX(index) * light_house.scale.x;
palm[i].position.y = rock_points.getZ(index) * light_house.scale.y;
palm[i].position.z = -rock_points.getY(index) * light_house.scale.z;
// light_house.children[0].children[0].children[0].children[0].children[2].receiveShadow = true;
light_house_borders = light_house.children[0].children[0].children[0].children[0].children[2].geometry.boundingBox;
if(palm[i].position.x < (light_house_borders.max.x + 2) * light_house.scale.x && palm[i].position.x > (light_house_borders.min.x - 2) * light_house.scale.x
&& palm[i].position.z > -(light_house_borders.max.y + 2) * light_house.scale.z && palm[i].position.z < -(light_house_borders.min.y - 2) * light_house.scale.z){
var scale_size = 0.2;
}
else{
var scale_size = getRandom(30, 50) / 100;
}
palm[i].scale.set(scale_size, scale_size, scale_size);
palm[i].rotation.y = getRandom(0, 314) / 100;
palm[i].angle_for_rotation = getRandom(0, 360);
// palm[i].children[0].children[0].children[0].children[0].children[1].children[1].children[0].material
// = palm[0].children[0].children[0].children[0].children[0].children[1].children[1].children[0].material.clone();
}
scene.add(island_group);
island_group.position.x += 6;
island_group.position.z -= 3;
var glass = light_house.getObjectByName("Lighthouse_Glass_0");
glow_sphere.position.y = glass.geometry.boundingSphere.center.z * light_house.scale.y;
island_group.add(glow_sphere);
let x0 = glass.geometry.boundingSphere.center.x * light_house.scale.x;
let y0 = glass.geometry.boundingSphere.center.y * light_house.scale.y;
glow_sphere.position.x = x0;
glow_sphere.position.z = -y0;
island_group.rotation.y = -Math.PI / 3;
loading_text.style.display= "none";
window.palmShader = [];
for(let i = 0; i < palm.length; i++){ // let потому что дальше промисс и значение придет, когда цикл отработает
palm[i].children[0].children[0].children[0].children[0].children[1].children[1].children[0].material.onBeforeCompile = patch => {
patch.uniforms.uTime = { value: 0 };
// console.log(patch.vertexShader);
patch.vertexShader = palm_vertecies;
// console.log(patch.fragmentShader);
patch.fragmentShader = palm_fragments;
window.palmShader[i] = patch;
};
}
}, (bytes) => { loading_text.innerHTML += " " + "palm models " + Math.floor(bytes.loaded / bytes.total * 100) + "% " + "is loaded"})
});
}
////////////////////////////////////////////////////////////////////////
prom[4] = new Promise((resolve, reject) =>{
fbxLoader.load( base_path + "/Walking.fbx", (fbx) => {
resolve();
const root = fbx;
root.scale.set(0.0025, 0.0025, 0.0025);
island_group.add(root);
man_pers = fbx;
man_pers.angle_for_rotation = 0;
const animations = man_pers.animations;
man_pers.mixer = new THREE.AnimationMixer( man_pers );
man_pers.step = 0.6;
man_pers.mixer.timeScale = 1;
man_pers.clock = new THREE.Clock();
const walkAction = man_pers.mixer.clipAction( animations[ 0 ] );
walkAction.play();
}, (bytes) => { loading_text.innerHTML += " " + "character model " + Math.floor(bytes.loaded / bytes.total * 100) + "% " + "is loaded"})
})
////////////////////////////////////////////////////////////////////////
prom[5] = new Promise((resolve, reject) => {
fbxLoader.load( base_path + "/blue_whale.fbx", (fbx) => {
resolve();
var id = Date.now();
whale = moving_objects[id] = fishes[id] = fbx;
scene.add(whale);
whale.scale.set(0.001, 0.001, 0.001);
whale.angle_for_rotation = 0;
whale.rotation_step = 0.1;
whale.move = function(object){fishMove(object)};
const animations = fbx.animations;
whale.mixer = new THREE.AnimationMixer( whale );
whale.step = 0.002;
whale.mixer.timeScale = 5;
whale.clock = new THREE.Clock();
const walkAction = whale.mixer.clipAction( animations[ 0 ] );
walkAction.play();
}, (bytes) => { loading_text.innerHTML += " " + "whale model " + Math.floor(bytes.loaded / bytes.total * 100) + "% " + "is loaded"})
});
////////////////////////////////////////////////////////////////////////
prom[6] = new Promise((resolve, reject) => {
gltfLoader.load( base_path + "/seagull.glb", (gltf) => {
resolve();
var id = Date.now();
seagull = birds[id] = moving_objects[id] = gltf.scene;
scene.add(seagull);
var size = 0.05;
seagull.scale.set(size, size, size);
seagull.angle_for_rotation = 0;
seagull.move = function(object){fishMove(object, 5, 10)};
const animations = gltf.animations;
seagull.mixer = new THREE.AnimationMixer( seagull );
seagull.step = 0.002;
seagull.mixer.timeScale = 5;
seagull.clock = new THREE.Clock();
var walkAction = seagull.mixer.clipAction( animations[ 0 ] );
walkAction.play();
for(var i = 0; i <= 2; i++){
id = Date.now() + "_" + i;
var bird = birds[id] = moving_objects[id] = SkeletonUtils.clone(seagull);
scene.add(bird);
bird.scale.set(size, size, size);
bird.angle_for_rotation = 0;
bird.move = function(object){fishMove(object, 5, 10)};
bird.position.set(getRandom(-20, 20), getRandom(-20, 20), getRandom(-20, 20));
bird.mixer = new THREE.AnimationMixer( bird );
bird.step = 0.002;
bird.mixer.timeScale = 5;
bird.clock = new THREE.Clock();
walkAction = bird.mixer.clipAction( animations[ 0 ] );
walkAction.play();
}
}, (bytes) => { loading_text.innerHTML += " " + "seagull model " + Math.floor(bytes.loaded / bytes.total * 100) + "% " + "is loaded"})
});
////////////////////////////////////////////////////////////////////////
Promise.all(prom).then((values) => {
loading_text.style.display= "none";
renderer.setAnimationLoop( animateAll );
scene.add( glow_sphere );
});
function animateAll() {
animatePers();
animateFish();
animateBird();
}
function animatePers() {
let mixerUpdateDelta = man_pers.clock.getDelta();
man_pers.mixer.update( mixerUpdateDelta );
}
function animateFish() {
let mixerUpdateDelta = whale.clock.getDelta();
whale.mixer.update( mixerUpdateDelta );
}
function animateBird() {
for(var i in birds){
bird = birds[i];
let mixerUpdateDelta = bird.clock.getDelta();
bird.mixer.update( mixerUpdateDelta );
}
}
const geometry2 = new THREE.SphereGeometry( 1, 32, 16 );
const glow_sphere = new THREE.Mesh( geometry2, new THREE.MeshStandardMaterial() );
let glowMaterial = new THREE.ShaderMaterial({
uniforms: {
viewVector: {
type: "v3",
value: camera.position
}
},
vertexShader: `
uniform vec3 viewVector;
varying float intensity;
void main() {
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 );
vec3 actual_normal = vec3(modelMatrix * vec4(normal, 0.0));
intensity = pow( dot(normalize(viewVector), actual_normal), 6.0 );
}
`,
fragmentShader: `
varying float intensity;
void main() {
vec3 glow = vec3(1, 0.8, 0.1) * intensity;
gl_FragColor = vec4( glow, 1.0 );
}
`,
side: THREE.FrontSide,
blending: THREE.AdditiveBlending,
transparent: true
});
glow_sphere.material = glowMaterial;