论坛

由用户创建的信息 ranj9119
03 May 2016 22:54

Reply to post of user Kirill Osipov
You can enable distortion (v15.12) for DK2.

m_scenes.set_hmd_params({
enable_hmd_stereo: true,
distortion_scale: 0.666,
distortion_coefs: [0.22, 0.28]
})

But it does not correcting chromatic aberration (webvr-boilerplate does same).

Never mind, gyro_use was missing from init


In case of using engine distortion it is better to disable browser distortion.
requestFullScreen({"vrDistortion": false});


Right correction requires right distortion coefficients.
For example,
OculusRiftDK2 — [0.22, 0.28]
CardboardV1 — [0.441, 0.156]
CardboardV2 — [0.34, 0.55]

Krill I'm trying to get this working on my Android with Cardboard, however both
m_inp.can_use_device(m_inp.DEVICE_GYRO)
& m_inp.can_use_device(m_inp.DEVICE_HMD)
return false! meaning that enable_hmd will have a null sensor. In the past I've been able ti successfully use gyro in the same device using the create_rotation_sensors function that you have posted in the forum. Unfortunately not able to do so right now! any reason as to why?

"use strict"

// register the application module
b4w.register("test", function(exports, require) {

// import modules used by the app
var m_app       = require("app");
var m_data      = require("data");
var m_cfg       = require("config");
var m_scenes    = require("scenes");
var m_hmd    = require("hmd");
var m_inp = require("input");

var m_cam = require("camera");
var m_ctl = require("controls");
var m_quat = require("quat");
var m_trans = require("transform");
var m_util = require("util");
var m_vec3  = require("vec3");

var _last_gyro_quat = m_quat.create();

var _quat_tmp = m_quat.create();
var _quat_tmp2 = m_quat.create();
var _vec3_tmp = m_vec3.create();

/**
 * export the method to initialize the app (called at the bottom of this file)
 */
exports.init = function() {
    // m_cfg.set("stereo", "HMD");
    m_app.init({
        canvas_container_id: "main_canvas_container",
        callback: init_cb,
        show_fps: true,
        console_verbose: true,
        autoresize: true
    });
}

/**
 * callback executed when the app is initizalized
 */
function init_cb(canvas_elem, success) {

    if (!success) {
        console.log("b4w init failure");
        return;
    }
    // m_app.enable_camera_controls();
    load();
}

/**
 * load the scene data
 */
function load() {
    m_data.load("test.json", load_cb);
}

/**
 * callback executed when the scene is loaded
 */
function load_cb(data_id) {
    m_app.enable_controls();
    m_app.enable_camera_controls();
    // m_hmd.enable_hmd(1);
    // console.log(m_inp.can_use_device(m_inp.DEVICE_GYRO));
    // console.log("hi");
    create_rotation_sensors();

    // // place your code here
    // m_scenes.set_hmd_params({
    // 	enable_hmd_stereo: true,
    // 	distortion_scale: 1,
    // 	inter_lens_dist: 0.064,
    //     base_line_dist: 0.035,
    //     screen_to_lens_dist: 0.039,
    //     distortion_coefs: [0.34, 0.55],
    //     chromatic_aberration_coefs : [0.0, 0.0, 0.0, 0.0]
    // })
}

function create_rotation_sensors() {
	console.log("hi from ");
	var obj = m_scenes.get_active_camera();
	var g_sensor = m_ctl.create_gyro_angles_sensor();
	var save_angles = true;

	var rotate_cb = function(obj, id, pulse) {
		if (pulse > 0) {

			var curr_angles = m_ctl.get_sensor_payload(obj, id, 0);
			if (m_cam.is_eye_camera(obj)) {
				var alpha = curr_angles[2];
				var beta  = curr_angles[1];
				var gamma = curr_angles[0];

				var quaternion = _quat_tmp;
				var c1 = Math.cos(alpha / 2);
				var c2 = Math.cos(beta  / 2);
				var c3 = Math.cos(gamma / 2);
				var s1 = Math.sin(alpha / 2);
				var s2 = Math.sin(beta  / 2);
				var s3 = Math.sin(gamma / 2);
				quaternion[0] = c1 * s2 * c3 - s1 * c2 * s3;
				quaternion[1] = c1 * c2 * s3 + s1 * s2 * c3;
				quaternion[2] = s1 * c2 * c3 + c1 * s2 * s3;
				quaternion[3] = c1 * c2 * c3 - s1 * s2 * s3;

				var orientation = Math.PI * window.orientation / 180;
				var screen_quat = m_quat.setAxisAngle(m_util.AXIS_Z,
					-orientation, _quat_tmp2);

				quaternion = m_quat.multiply(quaternion, screen_quat, _quat_tmp);

				var quat = m_quat.setAxisAngle(m_util.AXIS_X, Math.PI / 2,
					_quat_tmp2);
				quaternion = m_quat.multiply(quaternion, quat, _quat_tmp);

				if (save_angles) {
					m_quat.copy(quaternion, _last_gyro_quat);
					save_angles = false;
				} else {
					var last_gyro_inv_quat = m_quat.invert(_last_gyro_quat, _last_gyro_quat);
					var cam_quat = m_trans.get_rotation(obj, _quat_tmp2);
					var clear_cam_quat = m_quat.multiply(cam_quat, last_gyro_inv_quat, _quat_tmp2);
					var new_cam_quat = m_quat.multiply(clear_cam_quat, quaternion, _quat_tmp2);

					var up_axis = m_vec3.transformQuat(m_util.AXIS_MZ,
						new_cam_quat, _vec3_tmp);

					m_cam.set_vertical_axis(obj, up_axis);

					m_trans.set_rotation_v(obj, new_cam_quat);
					m_quat.copy(quaternion, _last_gyro_quat);
				}
			}
		}
	}
	m_ctl.create_sensor_manifold(obj, "ROTATE_GYRO", 
		m_ctl.CT_CONTINUOUS, [g_sensor], null, rotate_cb);
}

});

// import the app module and start the app by calling the init method
b4w.require("test").init();

Above code is to test the gyro with not luck :( I was able to get the stereo and hmd to work on cardboard so I have commented those sections out.

Thank you in advance
23 April 2016 05:09
Thank you so much. This does indeed work when using the API. However I need to duplicate the object many times, and wanted to do this in blender by creating empty objects and assigning duplication to Sphere Group. Is there anyway that this can be done through blender by shape keys are modified through script, yet it is properly displayed on all dupli objects?
22 April 2016 14:09
I've been trying a few things, but I dont think shape keys actually change the vertex arrays :(

        var position = m_geom.extract_vertex_array(sphere, "Material.002", "a_position");
        var normal = m_geom.extract_vertex_array(sphere, "Material.002", "a_normal");
        var index = m_geom.extract_index_array(sphere, "Material.002");
        m_geom.update_vertex_array(sphere, "a_position", position);
        m_geom.update_vertex_array(sphere, "a_normal", normal);
        m_geom.override_geometry(sphere, "Material.002", index, position, false);


No luck! Would really appreciate some help

Edit: tried the following with no luck:
m_geom.override_geometry(sphere, "Material.002", sphere.scenes_data[0].batches[0].bufs_data.ibo_array, sphere.scenes_data[0].batches[0].bufs_data.vbo_array, false);
22 April 2016 13:45
Hi all.

I am manipulating a "Sphere"s shape key values using baked fcruve data from an object called "properties".
This is being done using a timeline sensor with values being updated in sensor's callback. So far so good, everything works!

I have anempty called "Dupli" who is responsible for showing a duplicate of "Sphere" through the duplicate group option in the object panel of "Dupli". How can I update "Dupli" so it reflects the latest state of "Sphere" with correct shape key values? I have looked all over the API but can't seem to find a solution.



Duplication updates properly if I bake the vertex animation for shape keys on "Sphere", but this makes the .bin file grow very large, so it's not a feasible solution for me. Thank you in advance

The code for applying new shape key values:
function get_prop(obj, prop ,frame){
    switch(prop) {
    case 0:
        return obj.actions[0].fcurves['["prop"]'][0]._pierced_points[frame];
        break;
    case 1:
        return obj.actions[0].fcurves['["prop1"]'][0]._pierced_points[frame];
        break;
    case 2:
        return obj.actions[0].fcurves['["prop2"]'][0]._pierced_points[frame];
        break;
    case 3:
        return obj.actions[0].fcurves['["prop3"]'][0]._pierced_points[frame];
        break;
    case 4:
        return obj.actions[0].fcurves['["prop4"]'][0]._pierced_points[frame];
        break;
    case 5:
        return obj.actions[0].fcurves['["prop5"]'][0]._pierced_points[frame];
        break;
    case 6:
        return obj.actions[0].fcurves['["prop6"]'][0]._pierced_points[frame];
        break;
    case 7:
        return obj.actions[0].fcurves['["prop7"]'][0]._pierced_points[frame];
        break;
    }
}

function setup_anim() {
    var elapsed = m_ctl.create_timeline_sensor();
    var sens_array = [elapsed];
    var logic = function(s) {return (s[0])};


    function anim_cb(obj, id, pulse) {

        var time = m_ctl.get_sensor_value(obj, id, 0);
        var timeToFrame = parseInt(m_anim.get_frame(properties, 0), 10);
        var prop    = get_prop(properties, 0 ,timeToFrame);
        var prop1   = get_prop(properties, 1 ,timeToFrame);
        var prop2   = get_prop(properties, 2 ,timeToFrame);
        var prop3   = get_prop(properties, 3 ,timeToFrame);
        var prop4   = get_prop(properties, 4 ,timeToFrame);
        var prop5   = get_prop(properties, 5 ,timeToFrame);
        var prop6   = get_prop(properties, 6 ,timeToFrame);
        var prop7   = get_prop(properties, 7 ,timeToFrame);
        // Below is where I update the shape key values:
        m_geom.set_shape_key_value(sphere, "dispOne", prop);
        m_geom.set_shape_key_value(sphere, "dispFour", prop3);
        m_geom.set_shape_key_value(sphere, "defTwo", prop1);
        m_geom.set_shape_key_value(sphere, "defThree", prop2+prop7);
        m_trans.set_rotation_euler(sphere, prop1, prop2, prop3);
    }

    m_ctl.create_sensor_manifold(properties, "ANIM", m_ctl.CT_CONTINUOUS,
                sens_array, logic, anim_cb);
}


If you want more insight into my previous discussion regarding drivers and shape keys read this.
22 April 2016 13:31
Posting this here in case somone runs in to the same problem. "props" are custom properties baked in cycles.

function get_prop(obj, prop ,frame){
    switch(prop) {
    case 0:
        return obj.actions[0].fcurves['["prop"]'][0]._pierced_points[frame];
        break;
    case 1:
        return obj.actions[0].fcurves['["prop1"]'][0]._pierced_points[frame];
        break;
    case 2:
        return obj.actions[0].fcurves['["prop2"]'][0]._pierced_points[frame];
        break;
    case 3:
        return obj.actions[0].fcurves['["prop3"]'][0]._pierced_points[frame];
        break;
    case 4:
        return obj.actions[0].fcurves['["prop4"]'][0]._pierced_points[frame];
        break;
    case 5:
        return obj.actions[0].fcurves['["prop5"]'][0]._pierced_points[frame];
        break;
    case 6:
        return obj.actions[0].fcurves['["prop6"]'][0]._pierced_points[frame];
        break;
    case 7:
        return obj.actions[0].fcurves['["prop7"]'][0]._pierced_points[frame];
        break;
    }
}

function setup_anim() {
    var elapsed = m_ctl.create_timeline_sensor();
    var sens_array = [elapsed];
    var logic = function(s) {return (s[0])};


    function anim_cb(obj, id, pulse) {

        var time = m_ctl.get_sensor_value(obj, id, 0);
        var timeToFrame = parseInt(m_anim.get_frame(properties, 0), 10);
        var prop    = get_prop(properties, 0 ,timeToFrame);
        var prop1   = get_prop(properties, 1 ,timeToFrame);
        var prop2   = get_prop(properties, 2 ,timeToFrame);
        var prop3   = get_prop(properties, 3 ,timeToFrame);
        var prop4   = get_prop(properties, 4 ,timeToFrame);
        var prop5   = get_prop(properties, 5 ,timeToFrame);
        var prop6   = get_prop(properties, 6 ,timeToFrame);
        var prop7   = get_prop(properties, 7 ,timeToFrame);
        m_geom.set_shape_key_value(sphere, "dispOne", prop);
        m_geom.set_shape_key_value(sphere, "dispFour", prop3);
        m_geom.set_shape_key_value(sphere, "defTwo", prop1);
        m_geom.set_shape_key_value(sphere, "defThree", prop2+prop7);
        m_trans.set_rotation_euler(sphere, prop1, prop2, prop3);
    }

    m_ctl.create_sensor_manifold(properties, "ANIM", m_ctl.CT_CONTINUOUS,
                sens_array, logic, anim_cb);
}


Size of bin file is now 700kbs :)
28 March 2016 04:36
Hi all.
I'm trying to bake a sound to an object, and then use that data for multiple drivers responsible for transforming the object.

Among my needs for driver animation are these:
LocRotScale
Shape Key
Value Node (Materials)
Logic Editor Variable

So far I have been unsuccessful in using the drivers. I was able to get the desired transformative animation using Bake Action, and was able to animate the shape keys using the Vertex Animation Bake option. However this is not really feasible. Especially due to the fact that it increases the file size if multiple objects are animated.
I have seen in example files, that shape keys have drivers to slider controlled by the user.
Is it possible to use drivers as links to already baked data? and do not require user interaction?

For example:
– Bake sound to the z location of an object
– Use that f-curve as a driver for value node in materials, logic node variable (number input), shape key, etc

Thank you in advance

Edit: I have tried baking everything, vertex animation and regular transformations, with XYZ rot animated, and 4 different shapekeys on a default Sphere. The resulting BIN file is 200 mbs! Is there anyway to dynamically use the sample data and update shapekeys and transformations at runtime? I really think Drivers can be a huge improvement to B4W. Thank you again

Edit 2: Alternatively is it possible to use WebAudioAPI and fft to animate different parameters?


28 March 2016 04:30

Ответ на сообщение пользователя Kirill Osipov
Hello ranj9119. Welcome to our forum!


I think this will help you.

Thanks for the reply. Will give this a try and get back to you.
28 March 2016 04:29
Lovely example.
Thanks for getting back to me and thank you for taking the time to put this together.
20 March 2016 12:01
Hi all.
Is it possible to activate HMD display in developed apps? Possibly in load callback?

Best
20 March 2016 11:53
Hi all.
First post here on the forum. I feel it is necessary to thank the team behind the fascinating project. It has opened unimaginable doors to me. So thank you from the bottom of my heart.

I am using B4W for some "artistic" purposes and was wondering if something similar to this would be possible. In short Framebuffer Feedback Looping. I have realized that increasing motion blur to max (1) in the scene has very similar effects. I tried increasing it through code to something above the value of 1, but it disables the effect entirely.

Is something like possible with B4W? If so how would one go about implementing this?

Thank you all in advance, and happy first day of spring and Nowrouz.