r3-legacy/src/r3-d3-scene.js

586 lines
13 KiB
JavaScript
Raw Normal View History

2018-04-09 09:35:04 +02:00
/**
2019-07-24 08:08:02 +02:00
* R3.D3.Scene
2018-04-09 09:35:04 +02:00
* @param graphics
* @param apiScene R3.D3.API.Scene
* @constructor
*/
2019-07-24 08:08:02 +02:00
R3.D3.Scene = function(
2018-04-09 09:35:04 +02:00
graphics,
2019-07-24 08:08:02 +02:00
apiScene
2018-04-09 09:35:04 +02:00
) {
this.graphics = graphics;
this.graphics.isNotThreeThrow();
if (R3.Utils.UndefinedOrNull(apiScene)) {
apiScene = {};
}
R3.D3.API.Scene.call(
this,
apiScene.id,
apiScene.name,
apiScene.meshes,
apiScene.lights,
apiScene.textures,
apiScene.materials,
apiScene.images,
apiScene.fog,
apiScene.showGrid,
apiScene.showAxis,
apiScene.gridSize,
apiScene.gridColor,
2019-07-24 08:08:02 +02:00
apiScene.parent
2018-04-09 09:35:04 +02:00
);
this.textures = this.textures.map(
function(apiTexture) {
if (typeof apiTexture === 'string') {
return apiTexture;
}
return new R3.D3.Texture(
this.graphics,
apiTexture
);
}.bind(this)
);
this.materials = this.materials.map(
function(apiMaterial) {
if (typeof apiMaterial === 'string') {
return apiMaterial;
}
return new R3.D3.Material(
this.graphics,
apiMaterial
);
}.bind(this)
);
this.images = this.images.map(
function(apiImage) {
if (typeof apiImage === 'string') {
return apiImage;
}
return new R3.Image(
this.graphics,
apiImage
);
}.bind(this)
);
if (this.fog instanceof R3.D3.API.Fog) {
this.fog = new R3.D3.Fog(
this.graphics,
this.fog
)
2019-07-24 08:08:02 +02:00
}
2018-04-09 09:35:04 +02:00
this.gridColor = new R3.Color(
this.graphics,
this.gridColor,
this
);
/**
* Runtime scenes have helpers (just used to store which helper belongs to which scene)
* @type {Array}
*/
this.helpers = [];
this.clones = [];
this.grid = [];
this.axis = [];
this.storeClones = false;
2018-05-11 12:51:30 +02:00
this.instance = instance;
2018-04-09 09:35:04 +02:00
R3.Component.call(
this,
{
'meshes' : [R3.D3.Mesh],
'lights' : [R3.D3.Light],
'textures' : [R3.D3.Texture],
'materials' : [R3.D3.Material],
'images' : [R3.Image],
2019-07-24 08:08:02 +02:00
'fog' : R3.D3.Fog
2018-04-09 09:35:04 +02:00
}
);
};
R3.D3.Scene.prototype = Object.create(R3.Component.prototype);
R3.D3.Scene.prototype.constructor = R3.D3.Scene;
2018-05-11 12:51:30 +02:00
R3.D3.Scene.prototype.constructFromInstance = function() {
this.loaded = true;
console.log('todo: - setup scene from instance');
};
2018-04-09 09:35:04 +02:00
/**
* Creates an instance scene
* @returns {THREE.Scene}
*/
R3.D3.Scene.prototype.createInstance = function() {
2018-05-11 12:51:30 +02:00
if (R3.Utils.UndefinedOrNull(this.instance)) {
this.instance = new THREE.Scene();
} else {
this.constructFromInstance();
return;
}
2018-04-09 09:35:04 +02:00
this.instance.name = this.name;
if (this.fog && this.fog.instance) {
this.instance.fog = this.fog.instance;
}
this.meshes.map(
function(mesh) {
if (R3.Utils.UndefinedOrNull(mesh)) {
throw new Error('no mesh');
}
if (R3.Utils.UndefinedOrNull(mesh.instance)) {
throw new Error('no mesh instance');
}
this.instance.add(mesh.instance);
mesh.parentScene = this;
}.bind(this)
);
this.lights.map(
function(light) {
if (R3.Utils.UndefinedOrNull(light)) {
throw new Error('no light');
}
if (R3.Utils.UndefinedOrNull(light.instance)) {
throw new Error('no light instance');
}
this.instance.add(light.instance);
light.parentScene = this;
}.bind(this)
);
if (this.showGrid) {
this.drawGrid();
}
if (this.showAxis) {
this.drawAxis();
}
R3.Component.prototype.createInstance.call(this);
};
R3.D3.Scene.prototype.updateInstance = function(property) {
if (property === 'name') {
this.instance.name = this.name;
return;
}
if (property === 'fog') {
if (this.fog && this.fog.instance !== this.instance.fog) {
this.instance.fog = this.fog.instance;
}
}
if (property === 'meshes') {
/**
* Add missing meshes
*/
this.meshes.map(
2019-07-24 08:08:02 +02:00
function(mesh) {
2018-04-09 09:35:04 +02:00
if (this.instance.children.indexOf(mesh.instance === -1)) {
this.instance.add(mesh.instance);
}
}.bind(this)
);
}
if (property === 'lights') {
/**
* Add missing lights
*/
this.lights.map(
2019-07-24 08:08:02 +02:00
function(light) {
2018-04-09 09:35:04 +02:00
if (this.instance.children.indexOf(light.instance) === -1) {
this.instance.add(light.instance);
}
}.bind(this)
);
}
if (
property === 'meshes' ||
property === 'lights'
) {
/**
* Remove extra meshes and lights
*/
this.instance.children.map(
2019-07-24 08:08:02 +02:00
function(instanceObject) {
2018-04-09 09:35:04 +02:00
var instanceMeshes = this.meshes.map(
2019-07-24 08:08:02 +02:00
function(mesh) {
2018-04-09 09:35:04 +02:00
return mesh.instance;
}
);
var instanceLights = this.lights.map(
2019-07-24 08:08:02 +02:00
function(light) {
2018-04-09 09:35:04 +02:00
return light.instance;
}
);
if (
(
instanceObject instanceof THREE.Mesh ||
instanceObject instanceof THREE.Light
) &&
(
instanceLights.indexOf(instanceObject) === -1 &&
instanceMeshes.indexOf(instanceObject) === -1
)
) {
this.instance.remove(instanceObject);
}
}.bind(this)
);
return;
}
if (
property === 'showGrid' ||
property === 'gridSize' ||
property === 'gridColor'
) {
if (this.showGrid) {
this.drawGrid();
} else {
this.removeGrid();
}
}
if (property === 'showAxis') {
if (this.showAxis) {
this.drawAxis();
} else {
this.removeAxis();
}
}
R3.Component.prototype.updateInstance.call(this, property);
};
/**
* Converts a R3.D3.Scene to a R3.D3.API.Scene
* @returns {R3.D3.API.Scene}
*/
R3.D3.Scene.prototype.toApiObject = function() {
var apiMeshes = [];
if (this.storeClones) {
this.clones.map(
2019-07-24 08:08:02 +02:00
function(clone) {
2018-04-09 09:35:04 +02:00
R3.Utils.PushUnique(
apiMeshes,
R3.Utils.IdOrNull(clone)
);
}
);
}
this.meshes.map(
function(mesh) {
R3.Utils.PushUnique(
apiMeshes,
R3.Utils.IdOrNull(mesh)
);
}
);
return new R3.D3.API.Scene(
this.id,
this.name,
apiMeshes,
this.lights.map(
function(light) {
return R3.Utils.IdOrNull(light);
}
),
this.textures.map(
function(texture) {
return R3.Utils.IdOrNull(texture);
}
),
this.materials.map(
function(material) {
return R3.Utils.IdOrNull(material);
}
),
this.images.map(
function(image) {
return R3.Utils.IdOrNull(image);
}
),
R3.Utils.IdOrNull(this.fog),
this.showGrid,
this.showAxis,
this.gridSize,
this.gridColor.toApiObject(),
2019-07-24 08:08:02 +02:00
R3.Utils.IdOrNull(this.parent)
2018-04-09 09:35:04 +02:00
);
};
/**
* Adds a mesh to the scene
* @param object R3.D3.Mesh
*/
R3.D3.Scene.prototype.addObject = function(object) {
if (object instanceof R3.D3.Mesh) {
if (this.meshes.indexOf(object.id) === -1) {
R3.Utils.PushUnique(this.meshes, object);
}
}
if (object instanceof R3.D3.Light) {
if (this.lights.indexOf(object.id) === -1) {
R3.Utils.PushUnique(this.lights, object);
}
}
object.parentScene = this;
if (
this.instance &&
object.instance
) {
if (this.instance.children.indexOf(object.instance) === -1) {
this.instance.add(object.instance);
}
} else {
// console.warn('either scene or mesh instance not ready');
}
2019-07-24 08:08:02 +02:00
// if (this.parent) {
// this.parent.addComponent(object);
2018-04-09 09:35:04 +02:00
// }
};
R3.D3.Scene.prototype.addClone = function(component) {
if (component instanceof R3.D3.Mesh ||
component instanceof R3.D3.Light
) {
if (this.instance && component.instance) {
if (this.instance.children.indexOf(component.instance) === -1) {
this.instance.add(component.instance);
}
}
component.isClone = true;
R3.Utils.PushUnique(this.clones, component);
var index = this.meshes.indexOf(component);
if (index !== -1) {
this.meshes.splice(index, 1);
}
component.parentScene = this;
}
};
/**
*
* @param object
*/
R3.D3.Scene.prototype.removeObject = function(object) {
var index = -1;
if (object instanceof R3.D3.Mesh) {
index = this.meshes.indexOf(object);
if (index !== -1) {
this.meshes.splice(index, 1);
}
index = this.clones.indexOf(object);
if (index !== -1) {
this.clones.splice(index, 1);
}
} else if (object instanceof R3.D3.Light) {
index = this.lights.indexOf(object);
if (index !== -1) {
this.lights.splice(index, 1);
}
index = this.clones.indexOf(object);
if (index !== -1) {
this.clones.splice(index, 1);
}
} else {
console.warn('Cannot remove this object - what is this ?' + object.toString());
return;
}
if (this.instance.children.indexOf(object.instance) !== -1) {
this.instance.remove(object.instance);
} else {
console.warn('no scene instance');
}
if (object.parentScene === this) {
object.parentScene = null;
}
//
2019-07-24 08:08:02 +02:00
// if (this.parent) {
// this.parent.removeComponent(object);
2018-04-09 09:35:04 +02:00
// }
// this.buildIdToObject();
};
R3.D3.Scene.prototype.drawGrid = function() {
this.removeGrid();
var lineMaterial = new THREE.LineBasicMaterial({
color: this.gridColor.toHex(),
linewidth: 1
});
for (var y = -this.gridSize; y <= this.gridSize; y += 1) {
var Xgeometry = new THREE.Geometry();
Xgeometry.vertices.push(
new THREE.Vector3( y, 0, this.gridSize * -1 ),
new THREE.Vector3( y, 0, this.gridSize )
);
var lineX = new THREE.Line(Xgeometry, lineMaterial);
this.instance.add(lineX);
this.grid.push(lineX);
var Ygeometry = new THREE.Geometry();
Ygeometry.vertices.push(
new THREE.Vector3( this.gridSize * -1 , 0, y ),
new THREE.Vector3( this.gridSize, 0, y )
);
var lineY = new THREE.Line(Ygeometry, lineMaterial);
this.instance.add(lineY);
this.grid.push(lineY);
}
};
R3.D3.Scene.prototype.removeGrid = function() {
this.grid.map(
function(object) {
this.instance.remove(object);
}.bind(this)
);
};
R3.D3.Scene.prototype.drawAxis = function() {
this.removeAxis();
var Xmaterial = new THREE.LineBasicMaterial({
color: 0xff0000,
linewidth: 2
});
var Xgeometry = new THREE.Geometry();
Xgeometry.vertices.push(
new THREE.Vector3( 0, 0, 0 ),
new THREE.Vector3( 100, 0, 0 )
);
var lineX = new THREE.Line(Xgeometry, Xmaterial);
this.instance.add(lineX);
this.axis.push(lineX);
var Ymaterial = new THREE.LineBasicMaterial({
color: 0x00ff00,
linewidth: 2
});
var Ygeometry = new THREE.Geometry();
Ygeometry.vertices.push(
new THREE.Vector3( 0, 0, 0 ),
new THREE.Vector3( 0, 100, 0 )
);
var lineY = new THREE.Line(Ygeometry, Ymaterial);
this.instance.add(lineY);
this.axis.push(lineY);
var Zmaterial = new THREE.LineBasicMaterial({
color: 0x0000ff,
linewidth: 2
});
var Zgeometry = new THREE.Geometry();
Zgeometry.vertices.push(
new THREE.Vector3( 0, 0, 0 ),
new THREE.Vector3( 0, 0, 100 )
);
var lineZ = new THREE.Line(Zgeometry, Zmaterial);
this.instance.add(lineZ);
this.axis.push(lineZ);
};
R3.D3.Scene.prototype.removeAxis = function() {
this.axis.map(
function(object) {
this.instance.remove(object);
}.bind(this)
);
};