/** * @methodOf camera */ function set_view(cam, camobj) { var trans = camobj._render.trans; var quat = camobj._render.quat; var wm = _mat4_tmp; m_mat4.rotateX(camobj._render.world_matrix, -Math.PI/2, wm); m_mat4.invert(wm, cam.view_matrix); if (cam.reflection_plane) { reflect_view_matrix(cam); reflect_proj_matrix(cam); } var x = cam.view_matrix[12]; var y = cam.view_matrix[13]; var z = cam.view_matrix[14]; if (cam.type == exports.TYPE_STEREO_LEFT) cam.view_matrix[12] += cam.stereo_eye_dist/2; else if (cam.type == exports.TYPE_STEREO_RIGHT) cam.view_matrix[12] -= cam.stereo_eye_dist/2; // update view projection matrix m_mat4.multiply(cam.proj_matrix, cam.view_matrix, cam.view_proj_matrix); calc_sky_vp_inverse(cam); m_vec3.copy(cam.eye, cam.eye_last); m_vec3.copy(trans, cam.eye); m_quat.copy(quat, cam.quat); }
/** * Fix camera rotation on target. * uses _mat3_tmp, _mat3_tmp2 */ function cam_rotate_to(quat, dir, dest) { // convenient to use 3x3 matrix var mat_dst = _mat3_tmp; var x_cam_world = mat_dst.subarray(0, 3); var y_cam_world = mat_dst.subarray(3, 6); var z_cam_world = mat_dst.subarray(6, 9); m_vec3.copy(dir, y_cam_world); m_vec3.negate(y_cam_world, y_cam_world); m_vec3.normalize(y_cam_world, y_cam_world); var up_down = Boolean(Math.abs(m_vec3.dot(dir, m_util.AXIS_Y)) > 0.999999); if (up_down) { var mat_src = m_mat3.fromQuat(m_quat.normalize(quat, dest), _mat3_tmp2); m_vec3.copy(mat_src.subarray(0, 3), x_cam_world); } else m_vec3.cross(m_util.AXIS_Y, y_cam_world, x_cam_world); m_vec3.normalize(x_cam_world, x_cam_world); m_vec3.cross(x_cam_world, y_cam_world, z_cam_world); m_vec3.normalize(z_cam_world, z_cam_world); m_quat.fromMat3(mat_dst, dest); m_quat.normalize(dest, dest); }
exports.get_translation = function(obj, dest) { if (m_cons.get_type(obj) == m_cons.CONS_TYPE_CHILD_OF) { var offset = m_cons.get_child_of_offset(obj); m_vec3.copy(m_tsr.get_trans_view(offset), dest); } else { m_vec3.copy(obj._render.trans, dest); } }
/** * Set translation and pivot point for the TARGET camera. * @method module:camera.set_trans_pivot * @param {Object} camobj Camera Object ID * @param {Float32Array} trans Translation vector * @param {Float32Array} pivot Pivot vector */ function set_trans_pivot(camobj, trans, pivot) { if (!camera.is_target_camera(camobj)) { m_print.error("set_trans_pivot(): Wrong object or camera move style"); return; } m_vec3.copy(trans, camobj._render.trans); m_vec3.copy(pivot, camobj._render.pivot); transform.update_transform(camobj); m_phy.sync_transform(camobj); }
exports.get_object_center = function(obj, calc_bs_center, dest) { if (!dest) var dest = new Float32Array(3); if (calc_bs_center) { var render = obj._render; m_vec3.copy(render.bs_world.center, dest); } else { if (obj._render.type == "STATIC") var render = obj._dyn_render; else var render = obj._render; var bpy_bb = obj["data"]["b4w_bounding_box"]; dest[0] = (bpy_bb["max_x"] + bpy_bb["min_x"])/2; dest[1] = (bpy_bb["max_y"] + bpy_bb["min_y"])/2; dest[2] = (bpy_bb["max_z"] + bpy_bb["min_z"])/2; m_vec3.transformMat4(dest, render.world_matrix, dest); } return dest; }
function animate_sun(timeline) { var duration = timeline - _sun.start_time; if (duration <= ANIMATION_DURATION) { var sun_offset_dir = m_vec3.copy(m_util.AXIS_X, _vec3_tmp); var new_trans; if (_focusing) { var new_trans_length = m_math.ease_out_expo(duration, _sun.start_trans_length, 50, ANIMATION_DURATION); new_trans = m_vec3.scale(sun_offset_dir, new_trans_length, _vec3_tmp); } else { var new_trans_length = m_math.ease_out_expo(duration, _sun.start_trans_length, -_sun.start_trans_length, ANIMATION_DURATION); new_trans = m_vec3.scale(sun_offset_dir, new_trans_length, _vec3_tmp); } new_trans = m_vec3.add(new_trans, _sun.origin_trans, new_trans); m_trans.set_translation_rel_v(_sun.geom, new_trans); m_trans.set_translation_rel_v(_sun.crown_geom, new_trans); m_trans.set_translation_rel_v(_sun.lamp, new_trans); } }
var start_animation_cb = function(obj, id, pulse) { var mclick_value = m_ctl.get_sensor_value(obj, id, 0); var tclick_value = m_ctl.get_sensor_value(obj, id, 1); var timeline = m_ctl.get_sensor_value(obj, id, 2); if (mclick_value || tclick_value) { var payload = mclick_value ? m_ctl.get_sensor_payload(obj, id, 0): m_ctl.get_sensor_payload(obj, id, 1); var canv_coords = m_cont.client_to_canvas_coords( payload.coords[0], payload.coords[1], _vec2_tmp); var obj = m_scs.pick_object(canv_coords[0], canv_coords[1]); if (obj) { var clicked_planet = get_planet_by_geom(obj); if (clicked_planet) { // check second click on planet if (clicked_planet.focused) { _focusing = false; } else { _focusing = true; } // init sun data _sun.start_time = timeline; var sun_trans = m_trans.get_translation_rel(_sun.geom, _vec3_tmp); _sun.start_trans_length = m_vec3.length(sun_trans); // init orbit _orbits.start_time = timeline; _orbits.start_scale = m_trans.get_scale(_orbits.front); // init data of planet animations for (var i = 0; i < _planets.length; i++) { var planet = _planets[i]; var trans = m_trans.get_translation_rel(planet.armature, _vec3_tmp); if (_focusing) { m_vec3.copy(trans, planet.original_trans); if (planet.geom == obj) { planet.focused = true; } else { planet.focused = false; } } else { planet.focused = false; } planet.start_scale = m_trans.get_scale(planet.armature); planet.start_time = timeline; planet.start_trans_length = m_vec3.length(trans); } } } } }
function start_camera_animation(camobj, pos_view, pos_target) { // retrieve camera current position m_cam.target_get_pivot(camobj, _cam_anim.current_target); m_trans.get_translation(camobj, _cam_anim.current_eye); // set camera starting position m_vec3.copy(_cam_anim.current_target, _cam_anim.starting_target); m_vec3.copy(_cam_anim.current_eye, _cam_anim.starting_eye); // set camera final position m_vec3.copy(pos_view, _cam_anim.final_eye); m_vec3.copy(pos_target, _cam_anim.final_target); // start animation _delta_target = ANIM_TIME; _cam_anim.timeline = m_time.get_timeline(); }
var hmd_cb = function(obj, id, pulse) { if (pulse > 0) { var hmd_pos = m_ctl.get_sensor_payload(obj, id, 1); var device = m_input.get_device_by_type_element(m_input.DEVICE_HMD); if (!updated_eye_data) { m_vec3.copy(hmd_pos, last_hmd_pos); updated_eye_data = true; } else { var diff_hmd_pos = m_vec3.subtract(hmd_pos, last_hmd_pos, _vec3_tmp2); m_vec3.scale(diff_hmd_pos, 15, diff_hmd_pos); _dest_x_trans += diff_hmd_pos[0]; _dest_y_trans += diff_hmd_pos[1]; m_vec3.copy(hmd_pos, last_hmd_pos); } } }
/** * Set pivot point for TARGET camera. * @method module:camera.set_pivot * @param {Object} camobj Camera Object ID * @param {Float32Array} coords Pivot vector */ function set_pivot(camobj, coords) { if (!camera.is_target_camera(camobj)) { m_print.error("set_pivot(): Wrong object or camera move style"); return; } m_vec3.copy(coords, camobj._render.pivot); }
// using _quat_tmp, _vec3_tmp, _vec3_tmp2 function spawn_asteroid_random_pos(asteroid, cam_coord) { asteroid.active = true; // set target point var target_coord = m_vec3.copy(cam_coord, _vec3_tmp2); target_coord[0] += ASTEROID_DEFAULT_TARGET_OFFSET * (2 * Math.random() - 1); target_coord[1] += ASTEROID_DEFAULT_TARGET_OFFSET * (2 * Math.random() - 1); target_coord[2] = 0; // set spawn point var spawn_coord = m_vec3.copy(cam_coord, _vec3_tmp); spawn_coord[0] += ASTEROID_DEFAULT_SPAWN_OFFSET * (2 * Math.random() - 1); spawn_coord[1] += ASTEROID_DEFAULT_SPAWN_OFFSET * Math.random() / 2; spawn_coord[2] = -100; var ast_obj = asteroid.ast_obj; m_trans.set_translation_v(ast_obj, spawn_coord); var ast_copy_obj = asteroid.ast_copy_obj; if (ast_copy_obj) m_trans.set_translation_v(ast_copy_obj, spawn_coord); // set velosity var dir = m_vec3.subtract(target_coord, spawn_coord, _vec3_tmp2); m_vec3.normalize(dir, dir); var velocity = m_vec3.scale(dir, _asteroid_speed, dir); _asteroid_speed = _asteroid_speed < ASTEROID_MAX_SPEED? _asteroid_speed + 1: _asteroid_speed; var cockpit_mesh_obj = _cockpit.cockpit_mesh_obj; if (cockpit_mesh_obj) m_obj.set_nodemat_value(cockpit_mesh_obj, ["screen", "speed"], 1 - 0.1 * ((_asteroid_speed - ASTEROID_DEFAULT_SPEED) / (ASTEROID_MAX_SPEED - ASTEROID_DEFAULT_SPEED) * 8 % 8)); m_vec3.copy(velocity, asteroid.velosity); // apply torque var axis = m_vec3.set(2 * Math.random() - 1, 2 * Math.random() - 1, 2 * Math.random() - 1, _vec3_tmp); asteroid.angular_velosity = m_quat.setAxisAngle(axis, Math.PI * (2 * Math.random() - 1) * 10, asteroid.angular_velosity); // var element = document.getElementById("score"); // element.innerHTML = _asteroid_speed - 20; }
exports.set_point_constraint = function(camobj, pivot) { var render = camobj._render; m_vec3.copy(pivot, render.pivot); if (render.use_distance_limits) m_cons.append_follow_point(camobj, render.pivot, render.distance_min, render.distance_max); else m_cons.append_track_point(camobj, render.pivot); }
exports.get_eye = function(camobj, dest) { if (!camera.is_camera(camobj)) { m_print.error("get_eye(): Wrong object"); return; } if (!dest) var dest = new Float32Array(3); m_vec3.copy(camobj._render.trans, dest); return dest; }
exports.get_hover_cam_pivot = function(camobj, dest) { if (!camera.is_hover_camera(camobj)) { m_print.error("get_hover_cam_pivot(): wrong object"); return null; } if (!dest) dest = new Float32Array(3); m_vec3.copy(camobj._render.hover_pivot, dest); return dest; }
function process_config(data, id, type, url) { setup_buttons(data); setup_music(data); setup_language(data); var camobj = m_scs.get_active_camera(); _cam_rot_fac = data["camera_rotation_fac"]; m_vec3.copy(data["camera_pivot"], _cam_pivot); m_trans.get_translation(camobj, _vec3_tmp); _cam_dist = m_vec3.distance(_cam_pivot, _vec3_tmp); }
exports.get_pivot = function(camobj, dest) { if (!camera.is_target_camera(camobj)) { m_print.error("get_pivot(): Wrong object or camera move style"); return; } if (!dest) var dest = new Float32Array(3); var render = camobj._render; m_vec3.copy(render.pivot, dest); return dest; }
/** * Set camera view matrix * @param cam CAM object * @param {vec3} eye Camera eye point * @param {vec3} target Camera target point * @param {vec3} up Camera up direction * @methodOf camera * @deprecated Deprecated */ function set_view_eye_target_up(cam, eye, target, up) { m_mat4.lookAt(eye, target, up, cam.view_matrix); if (cam.type == exports.TYPE_STEREO_LEFT) cam.view_matrix[12] += cam.stereo_eye_dist/2; else if (cam.type == exports.TYPE_STEREO_RIGHT) cam.view_matrix[12] -= cam.stereo_eye_dist/2; // update view projection matrix m_mat4.multiply(cam.proj_matrix, cam.view_matrix, cam.view_proj_matrix); calc_sky_vp_inverse(cam); m_vec3.copy(eye, cam.eye); // NOTE: some eye_last,trans,quat manipulations }
var trans_interp_cb = function(obj, id, pulse) { if (Math.abs(_dest_x_trans) > EPSILON_DISTANCE || Math.abs(_dest_y_trans) > EPSILON_DISTANCE) { var value = m_ctl.get_sensor_value(obj, id, 0); var delta_x = m_util.smooth(_dest_x_trans, 0, value, 1); var delta_y = m_util.smooth(_dest_y_trans, 0, value, 1); _dest_x_trans -= delta_x; _dest_y_trans -= delta_y; var trans = m_trans.get_translation(obj, _vec3_tmp); trans[0] += delta_x; trans[1] += delta_y; m_trans.set_translation_v(obj, trans); var cam_obj = m_scs.get_active_camera(); m_trans.set_translation_v(cam_obj, trans); m_trans.set_translation_v(camera_asteroids_obj, trans); trans[0] -= _dest_x_trans / 2; trans[1] -= _dest_y_trans / 2; m_trans.set_translation_v(environment_empty, trans); var roll_angle = m_util.clamp(_dest_x_trans * COCKPIT_ROT_FACTOR, -Math.PI * COCKPIT_ROT_FACTOR, Math.PI * COCKPIT_ROT_FACTOR); var roll_quat = m_quat.setAxisAngle(m_util.AXIS_MZ, roll_angle, _quat_tmp); var pitch_angle = - m_util.clamp(_dest_y_trans * COCKPIT_ROT_FACTOR, -Math.PI * COCKPIT_ROT_FACTOR, Math.PI * COCKPIT_ROT_FACTOR) / 4; var pitch_quat = m_quat.setAxisAngle(m_util.AXIS_MX, pitch_angle, _quat_tmp2); var cockpit_quat = m_quat.multiply(roll_quat, pitch_quat, _quat_tmp); m_trans.set_rotation_v(obj, cockpit_quat); var environment_sphere_obj = _cockpit.environment_sphere_obj; if (environment_sphere_obj) { var cur_sphere_quat = m_trans.get_rotation(environment_sphere_obj, _quat_tmp); var pitch_angle = m_util.clamp(_dest_y_trans * COCKPIT_ROT_FACTOR, -Math.PI * COCKPIT_ROT_FACTOR, Math.PI * COCKPIT_ROT_FACTOR) * ENV_SPHERE_ROT_FACTOR; var pitch_quat = m_quat.setAxisAngle(m_util.AXIS_MX, pitch_angle, _quat_tmp2); var new_sphere_quat = m_quat.multiply(cur_sphere_quat, pitch_quat, _quat_tmp); var yaw_angle = - roll_angle * ENV_SPHERE_ROT_FACTOR; var yaw_quat = m_quat.setAxisAngle(m_util.AXIS_MY, yaw_angle, _quat_tmp2); new_sphere_quat = m_quat.multiply(cur_sphere_quat, yaw_quat, _quat_tmp); m_trans.set_rotation_v(environment_sphere_obj, new_sphere_quat); } // bend environment var init_bending_pos = m_tsr.get_trans_view(init_bending_tsr); var new_bending_pos = m_vec3.copy(init_bending_pos, _vec3_tmp); new_bending_pos[0] += _dest_x_trans; new_bending_pos[1] += _dest_y_trans; var new_bending_tsr = m_tsr.copy(init_bending_tsr, _tsr_tmp); new_bending_tsr = m_tsr.set_trans(new_bending_pos, new_bending_tsr); m_armat.set_bone_tsr(environment_arm, "move", new_bending_tsr); } }
/** * Set the sun parameters. * @method module:lights.set_sun_params * @param {Object} sun_params sun parameters */ function set_sun_params (sun_params) { var scene = scenes.get_active(); var lamps = scenes.get_scene_objs(scene, "LAMP", scenes.DATA_ID_ALL); // Index of lamp(sun) on the scene for (var i = 0; i < lamps.length; i++) { var lamp = lamps[i]; var light = lamp._light; if (light.type == "SUN") { var sun = lamp; break; } } if (!sun) { m_print.error("There is no sun on the scene"); return null; } if (typeof sun_params.hor_position == "number" && typeof sun_params.vert_position == "number") { // convert to radians var angle_hor = ((180 - sun_params.hor_position)) / 180 * Math.PI; var angle_vert = ((90 - sun_params.vert_position)) / 180 * Math.PI; var sun_render = sun._render; // rotate sun transform.set_rotation_euler(sun, [angle_vert, angle_hor, 0]); var dir = new Float32Array(3); util.quat_to_dir(sun_render.quat, util.AXIS_Y, dir); var dist_to_center = m_vec3.length(sun_render.trans); m_vec3.copy(dir, _sun_pos); m_vec3.scale(_sun_pos, dist_to_center, _sun_pos); // translate sun transform.set_translation(sun, _sun_pos); transform.update_transform(sun); var sun_light = sun._light; if (sun_light.dynamic_intensity) { // set amplitude lighting params var def_sun_energy = sun["data"]["energy"]; var def_env_color = scene["world"]["light_settings"]["environment_energy"]; // change sun intensity dependent to its position var energy = Math.cos(Math.abs(angle_vert)); var sun_energy = Math.max( Math.min(3.0 * energy, 1.0), 0.0) * def_sun_energy; var env_energy = Math.max(energy, 0.1) * def_env_color; lights.set_light_energy(sun_light, sun_energy); scenes.set_environment_colors(scene, env_energy, null, null); } scenes.update_lamp_scene(sun, scene); } }
function update_sensor(sensor, timeline, elapsed) { if (!elapsed) return; switch (sensor.type) { case ST_MOTION: var obj = sensor.source_object; var trans = obj._render.trans; var quat = obj._render.quat; var dist = m_vec3.dist(sensor.trans_last, trans); var quat_temp = sensor.quat_temp; m_quat.invert(sensor.quat_last, quat_temp); m_quat.multiply(quat, quat_temp, quat_temp); m_quat.normalize(quat_temp, quat_temp); var angle = Math.abs(2 * Math.acos(quat_temp[3])); var linear_vel = dist / elapsed; sensor.avg_linear_vel = m_util.smooth(linear_vel, sensor.avg_linear_vel, elapsed, SENSOR_SMOOTH_PERIOD); sensor.payload[0] = linear_vel; var angular_vel = angle / elapsed; sensor.avg_angular_vel = m_util.smooth(angular_vel, sensor.avg_angular_vel, elapsed, SENSOR_SMOOTH_PERIOD); sensor.payload[1] = angular_vel; if (sensor.avg_linear_vel >= sensor.threshold || sensor.avg_angular_vel >= sensor.rotation_threshold) sensor_set_value(sensor, 1); else sensor_set_value(sensor, 0); m_vec3.copy(trans, sensor.trans_last); m_quat.copy(quat, sensor.quat_last); sensor.time_last = timeline; break; case ST_V_VELOCITY: var obj = sensor.source_object; var trans = obj._render.trans; var vel = Math.abs(trans[1] - sensor.trans_last[1]) / elapsed; sensor.avg_vertical_vel = m_util.smooth(vel, sensor.avg_vertical_vel, elapsed, SENSOR_SMOOTH_PERIOD); sensor.payload = vel; if (sensor.avg_vertical_vel >= sensor.threshold) sensor_set_value(sensor, 1); else sensor_set_value(sensor, 0); m_vec3.copy(trans, sensor.trans_last); sensor.time_last = timeline; break; case ST_TIMER: if ((timeline - sensor.time_last) >= sensor.period) { sensor_set_value(sensor, 1); sensor.time_last = timeline; } break; case ST_ELAPSED: if (!sensor.time_last) { sensor.time_last = timeline; } sensor_set_value(sensor, timeline - sensor.time_last); sensor.time_last = timeline; break; case ST_TIMELINE: sensor_set_value(sensor, timeline); break; default: break; } }