mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-26 09:45:28 +03:00
Extract 3D model into a separate file
This commit is contained in:
parent
e8456795dd
commit
9bbc5cc000
2 changed files with 146 additions and 121 deletions
107
js/model.js
107
js/model.js
|
@ -27,5 +27,110 @@ var mixerList = [
|
|||
{name: 'Custom', model: 'custom', image: 'custom'},
|
||||
{name: 'Custom Airplane', model: 'custom', image: 'custom'},
|
||||
{name: 'Custom Tricopter', model: 'custom', image: 'custom'}
|
||||
|
||||
];
|
||||
|
||||
|
||||
// 3D model
|
||||
var Model = function (wrapper, canvas) {
|
||||
var useWebGLRenderer = this.canUseWebGLRenderer();
|
||||
|
||||
this.wrapper = wrapper;
|
||||
this.canvas = canvas;
|
||||
|
||||
if (useWebGLRenderer) {
|
||||
this.renderer = new THREE.WebGLRenderer({ canvas: this.canvas[0], alpha: true, antialias: true });
|
||||
} else {
|
||||
this.renderer = new THREE.CanvasRenderer({ canvas: this.canvas[0], alpha: true });
|
||||
}
|
||||
|
||||
// initialize render size for current canvas size
|
||||
this.renderer.setSize(this.wrapper.width() * 2, this.wrapper.height() * 2);
|
||||
|
||||
// load the model including materials
|
||||
var model_file = useWebGLRenderer ? mixerList[CONFIG.multiType - 1].model : 'fallback';
|
||||
|
||||
// Temporary workaround for 'custom' model until akfreak's custom model is merged.
|
||||
if (model_file == 'custom') { model_file = 'fallback'; }
|
||||
|
||||
// setup scene
|
||||
this.scene = new THREE.Scene();
|
||||
|
||||
// modelWrapper adds an extra axis of rotation to avoid gimbal lock with the euler angles
|
||||
this.modelWrapper = new THREE.Object3D();
|
||||
|
||||
// stationary camera
|
||||
this.camera = new THREE.PerspectiveCamera(60, this.wrapper.width() / this.wrapper.height(), 1, 10000);
|
||||
|
||||
// move camera away from the model
|
||||
this.camera.position.z = 125;
|
||||
|
||||
// some light
|
||||
var light = new THREE.AmbientLight(0x404040);
|
||||
var light2 = new THREE.DirectionalLight(new THREE.Color(1, 1, 1), 1.5);
|
||||
light2.position.set(0, 1, 0);
|
||||
|
||||
// add camera, model, light to the foreground scene
|
||||
this.scene.add(light);
|
||||
this.scene.add(light2);
|
||||
this.scene.add(this.camera);
|
||||
this.scene.add(this.modelWrapper);
|
||||
|
||||
// Load model file, add to scene and render it
|
||||
this.loadJSON(model_file, (function (model) {
|
||||
this.model = model;
|
||||
|
||||
this.modelWrapper.add(model);
|
||||
this.scene.add(this.modelWrapper);
|
||||
|
||||
this.render();
|
||||
}).bind(this));
|
||||
};
|
||||
|
||||
Model.prototype.loadJSON = function (model_file, callback) {
|
||||
var loader = new THREE.JSONLoader();
|
||||
|
||||
loader.load('./resources/models/' + model_file + '.json', function (geometry, materials) {
|
||||
var modelMaterial = new THREE.MeshFaceMaterial(materials),
|
||||
model = new THREE.Mesh(geometry, modelMaterial);
|
||||
|
||||
model.scale.set(15, 15, 15);
|
||||
|
||||
callback(model);
|
||||
});
|
||||
};
|
||||
|
||||
Model.prototype.canUseWebGLRenderer = function () {
|
||||
// webgl capability detector
|
||||
// it would seem the webgl "enabling" through advanced settings will be ignored in the future
|
||||
// and webgl will be supported if gpu supports it by default (canary 40.0.2175.0), keep an eye on this one
|
||||
var detector_canvas = document.createElement('canvas');
|
||||
|
||||
return window.WebGLRenderingContext && (detector_canvas.getContext('webgl') || detector_canvas.getContext('experimental-webgl'))
|
||||
};
|
||||
|
||||
Model.prototype.rotateTo = function (x, y, z) {
|
||||
if (!this.model) { return; }
|
||||
|
||||
this.model.rotation.x = x;
|
||||
this.modelWrapper.rotation.y = y;
|
||||
this.model.rotation.z = z;
|
||||
|
||||
this.render();
|
||||
};
|
||||
|
||||
Model.prototype.render = function () {
|
||||
if (!this.model) { return; }
|
||||
|
||||
// draw
|
||||
this.renderer.render(this.scene, this.camera);
|
||||
};
|
||||
|
||||
// handle canvas resize
|
||||
Model.prototype.resize = function () {
|
||||
this.renderer.setSize(this.wrapper.width() * 2, this.wrapper.height() * 2);
|
||||
|
||||
this.camera.aspect = this.wrapper.width() / this.wrapper.height();
|
||||
this.camera.updateProjectionMatrix();
|
||||
|
||||
this.render();
|
||||
};
|
||||
|
|
110
tabs/setup.js
110
tabs/setup.js
|
@ -43,8 +43,9 @@ TABS.setup.initialize = function (callback) {
|
|||
|
||||
GUI.log(chrome.i18n.getMessage('initialSetupBackupAndRestoreApiVersion', [CONFIG.apiVersion, CONFIGURATOR.backupRestoreMinApiVersionAccepted]));
|
||||
}
|
||||
// initialize 3D
|
||||
self.initialize3D();
|
||||
|
||||
// initialize 3D Model
|
||||
self.initModel();
|
||||
|
||||
// set roll in interactive block
|
||||
$('span.roll').text(chrome.i18n.getMessage('initialSetupAttitude', [0]));
|
||||
|
@ -191,7 +192,8 @@ TABS.setup.initialize = function (callback) {
|
|||
roll_e.text(chrome.i18n.getMessage('initialSetupAttitude', [SENSOR_DATA.kinematics[0]]));
|
||||
pitch_e.text(chrome.i18n.getMessage('initialSetupAttitude', [SENSOR_DATA.kinematics[1]]));
|
||||
heading_e.text(chrome.i18n.getMessage('initialSetupAttitude', [SENSOR_DATA.kinematics[2]]));
|
||||
self.render3D();
|
||||
|
||||
self.renderModel();
|
||||
self.updateInstruments();
|
||||
});
|
||||
}
|
||||
|
@ -215,104 +217,22 @@ TABS.setup.initializeInstruments = function() {
|
|||
};
|
||||
};
|
||||
|
||||
TABS.setup.initialize3D = function (compatibility) {
|
||||
var self = this,
|
||||
loader, canvas, wrapper, renderer, camera, scene, light, light2, modelWrapper, model, model_file,
|
||||
useWebGlRenderer = false;
|
||||
TABS.setup.initModel = function () {
|
||||
this.model = new Model($('.model-and-info #canvas_wrapper'), $('.model-and-info #canvas'));
|
||||
|
||||
canvas = $('.model-and-info #canvas');
|
||||
wrapper = $('.model-and-info #canvas_wrapper');
|
||||
$(window).on('resize', $.proxy(this.model.resize, this.model));
|
||||
};
|
||||
|
||||
// webgl capability detector
|
||||
// it would seem the webgl "enabling" through advanced settings will be ignored in the future
|
||||
// and webgl will be supported if gpu supports it by default (canary 40.0.2175.0), keep an eye on this one
|
||||
var detector_canvas = document.createElement('canvas');
|
||||
if (window.WebGLRenderingContext && (detector_canvas.getContext('webgl') || detector_canvas.getContext('experimental-webgl'))) {
|
||||
renderer = new THREE.WebGLRenderer({canvas: canvas.get(0), alpha: true, antialias: true});
|
||||
useWebGlRenderer = true;
|
||||
} else {
|
||||
renderer = new THREE.CanvasRenderer({canvas: canvas.get(0), alpha: true});
|
||||
}
|
||||
// initialize render size for current canvas size
|
||||
renderer.setSize(wrapper.width()*2, wrapper.height()*2);
|
||||
TABS.setup.renderModel = function () {
|
||||
var x = (SENSOR_DATA.kinematics[1] * -1.0) * 0.017453292519943295,
|
||||
y = ((SENSOR_DATA.kinematics[2] * -1.0) - this.yaw_fix) * 0.017453292519943295,
|
||||
z = (SENSOR_DATA.kinematics[0] * -1.0) * 0.017453292519943295;
|
||||
|
||||
|
||||
// // modelWrapper adds an extra axis of rotation to avoid gimbal lock with the euler angles
|
||||
modelWrapper = new THREE.Object3D()
|
||||
//
|
||||
// load the model including materials
|
||||
if (useWebGlRenderer) {
|
||||
model_file = mixerList[CONFIG.multiType - 1].model;
|
||||
} else {
|
||||
model_file = 'fallback'
|
||||
}
|
||||
|
||||
// Temporary workaround for 'custom' model until akfreak's custom model is merged.
|
||||
var useLegacyCustomModel = false;
|
||||
if (model_file == 'custom') {
|
||||
model_file = 'fallback';
|
||||
useLegacyCustomModel = true;
|
||||
}
|
||||
|
||||
// setup scene
|
||||
scene = new THREE.Scene();
|
||||
|
||||
loader = new THREE.JSONLoader();
|
||||
loader.load('./resources/models/' + model_file + '.json', function (geometry, materials) {
|
||||
var modelMaterial = new THREE.MeshFaceMaterial(materials);
|
||||
model = new THREE.Mesh(geometry, modelMaterial);
|
||||
|
||||
model.scale.set(15, 15, 15);
|
||||
|
||||
modelWrapper.add(model);
|
||||
scene.add(modelWrapper);
|
||||
});
|
||||
|
||||
// stationary camera
|
||||
camera = new THREE.PerspectiveCamera(50, wrapper.width() / wrapper.height(), 1, 10000);
|
||||
|
||||
// some light
|
||||
light = new THREE.AmbientLight(0x404040);
|
||||
light2 = new THREE.DirectionalLight(new THREE.Color(1, 1, 1), 1.5);
|
||||
light2.position.set(0, 1, 0);
|
||||
|
||||
// move camera away from the model
|
||||
camera.position.z = 125;
|
||||
|
||||
// add camera, model, light to the foreground scene
|
||||
scene.add(light);
|
||||
scene.add(light2);
|
||||
scene.add(camera);
|
||||
scene.add(modelWrapper);
|
||||
|
||||
this.render3D = function () {
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
|
||||
// compute the changes
|
||||
model.rotation.x = (SENSOR_DATA.kinematics[1] * -1.0) * 0.017453292519943295;
|
||||
modelWrapper.rotation.y = ((SENSOR_DATA.kinematics[2] * -1.0) - self.yaw_fix) * 0.017453292519943295;
|
||||
model.rotation.z = (SENSOR_DATA.kinematics[0] * -1.0) * 0.017453292519943295;
|
||||
|
||||
// draw
|
||||
renderer.render(scene, camera);
|
||||
};
|
||||
|
||||
// handle canvas resize
|
||||
this.resize3D = function () {
|
||||
renderer.setSize(wrapper.width()*2, wrapper.height()*2);
|
||||
camera.aspect = wrapper.width() / wrapper.height();
|
||||
camera.updateProjectionMatrix();
|
||||
|
||||
self.render3D();
|
||||
};
|
||||
|
||||
$(window).on('resize', this.resize3D);
|
||||
this.model.rotateTo(x, y, z);
|
||||
};
|
||||
|
||||
TABS.setup.cleanup = function (callback) {
|
||||
$(window).off('resize', this.resize3D);
|
||||
$(window).off('resize', $.proxy(this.model.resize, this.model));
|
||||
|
||||
if (callback) callback();
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue