o3d - fix group matrix composition

This commit is contained in:
dntzhang 2019-07-03 17:41:15 +08:00
parent 56c5916157
commit 93af6590ac
9 changed files with 254 additions and 156 deletions

View File

@ -2503,6 +2503,22 @@
this.scaleY = 1;
this.scaleZ = 1;
this.visible = true;
this.skewX = 0;
this.skewY = 0;
this.skewZ = 0;
this.originX = 0;
this.originY = 0;
this.originZ = 0;
this.rotateX = 0;
this.rotateY = 0;
this.rotateZ = 0;
this.x = 0;
this.y = 0;
this.z = 0;
this._matrix = new Matrix4();
this._groupMatrix = new Matrix4();
}
Object3d.prototype.isVisible = function isVisible() {
@ -2536,7 +2552,7 @@
this.children.push(child);
};
Group.prototype.update = function update(ctx, camera, scale) {
Group.prototype.update = function update(ctx, camera, scale, groupMatrix) {
var list = this.children.slice();
for (var i = 0, l = list.length; i < l; i++) {
var child = list[i];
@ -2544,10 +2560,18 @@
continue;
}
this._matrix.identity().appendTransform(this.x, this.y, this.z, this.scaleX, this.scaleY, this.scaleZ, this.rotateX, this.rotateY, this.rotateZ, this.skewX, this.skewY, this.skewZ, this.originX, this.originY, this.originZ);
if (groupMatrix) {
this._groupMatrix.multiplyMatrices(this._matrix, groupMatrix);
} else {
this._groupMatrix = this._matrix;
}
// draw the child:
ctx.save();
child.updateContext(ctx);
child.update(ctx, camera, scale);
child.update(ctx, camera, scale, this._groupMatrix);
ctx.restore();
}
return true;
@ -2615,23 +2639,11 @@
var _this = _possibleConstructorReturn$2(this, _Object3d.call(this));
options = options || {};
_this.center = options.center || new Vector3(0, 0, 0);
_this.center = options.center || new Vector3(_this.x, _this.y, _this.z);
_this.length = length;
_this.width = width;
_this.height = height;
_this.skewX = 0;
_this.skewY = 0;
_this.skewZ = 0;
_this.originX = 0;
_this.originY = 0;
_this.originZ = 0;
_this.rotate = Object.assign({
x: 0,
y: 0,
z: 0
}, options.rotate);
_this.pv = new Matrix4();
var hl = _this.length / 2;
@ -2659,12 +2671,10 @@
_this.colors = options.colors || ['red', 'green', 'blue', 'yellow', '#ccc', '#467fdd'];
_this.faces = [[ps[0], ps[1], ps[2], ps[3], _this.colors[0]], [ps[4], ps[5], ps[6], ps[7], _this.colors[1]], [ps[4], ps[5], ps[1], ps[0], _this.colors[2]], [ps[3], ps[2], ps[6], ps[7], _this.colors[3]], [ps[3], ps[0], ps[4], ps[7], _this.colors[4]], [ps[2], ps[1], ps[5], ps[6], _this.colors[5]]];
_this._matrix = new Matrix4();
return _this;
}
Cube.prototype.transform = function transform(camera) {
Cube.prototype.transform = function transform(camera, groupMatrix) {
// const yTopOrigin = {
// x: this.center.x,
// y: this.center.y - this.hh,
@ -2691,10 +2701,16 @@
// this.basePoints[7].rotateY(yBottomOrigin, this.rotate.y, this.p7)
this._matrix.identity().appendTransform(this.center.x, this.center.y, this.center.z, this.scaleX, this.scaleY, this.scaleZ, this.rotate.x, this.rotate.y, this.rotate.z, this.skewX, this.skewY, this.skewZ, this.originX, this.originY, this.originZ);
this._matrix.identity().appendTransform(this.x, this.y, this.z, this.scaleX, this.scaleY, this.scaleZ, this.rotateX, this.rotateY, this.rotateZ, this.skewX, this.skewY, this.skewZ, this.originX, this.originY, this.originZ);
if (groupMatrix) {
this._groupMatrix.multiplyMatrices(this._matrix, groupMatrix);
} else {
this._groupMatrix = this._matrix;
}
for (var i = 0; i < 8; i++) {
this.basePoints[i].applyMatrix4Out(this._matrix, this['p' + i]);
this.basePoints[i].applyMatrix4Out(this._groupMatrix, this['p' + i]);
}
this.pv.multiplyMatrices(camera.p_matrix, camera.v_matrix);
@ -2707,8 +2723,8 @@
}
};
Cube.prototype.update = function update(ctx, camera, scale) {
this.transform(camera);
Cube.prototype.update = function update(ctx, camera, scale, groupMatrix) {
this.transform(camera, groupMatrix);
this.fill(ctx, scale);
};
@ -2861,14 +2877,19 @@
});
var group = new Group();
var cube = new Cube(100, 100, 100, {
center: new Vector3(0, 0, 0),
rotate: {
y: 30
}
center: new Vector3(0, 0, 0)
});
//cube.rotateY =30
group.add(cube);
var cubeB = new Cube(100, 100, 100, {
center: new Vector3(200, 0, 0)
});
//cube.rotateY =30
group.add(cubeB);
stage.add(group);
stage.update();
@ -2877,9 +2898,9 @@
function animate() {
requestAnimationFrame(animate);
cube.rotate.y += 1;
cube.rotate.x += 1;
cube.rotate.z += 1;
group.rotateX += 1;
group.rotateY += 1;
group.rotateZ += 1;
//camera.y += 1
stage.update();
}

File diff suppressed because one or more lines are too long

View File

@ -22,14 +22,20 @@ const stage = new Stage({
});
const group = new Group()
const cube = new Cube(100, 100, 100, {
center: new Vector3(0, 0, 0),
rotate: {
y: 30
}
center: new Vector3(0, 0, 0)
})
//cube.rotateY =30
group.add(cube)
const cubeB = new Cube(100, 100, 100, {
center: new Vector3(200, 0, 0)
})
//cube.rotateY =30
group.add(cubeB)
stage.add(group)
stage.update()
@ -38,9 +44,9 @@ animate()
function animate() {
requestAnimationFrame(animate)
cube.rotate.y += 1
cube.rotate.x += 1
cube.rotate.z += 1
group.rotateX += 1
group.rotateY += 1
group.rotateZ += 1
//camera.y += 1
stage.update()
}

View File

@ -2494,35 +2494,40 @@
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Group = function () {
function Group() {
_classCallCheck(this, Group);
var Object3d = function () {
function Object3d() {
_classCallCheck(this, Object3d);
this.children = [];
this.alpha = 1;
this.scaleX = 1;
this.scaleY = 1;
this.scaleZ = 1;
this.visible = true;
this.skewX = 0;
this.skewY = 0;
this.skewZ = 0;
this.originX = 0;
this.originY = 0;
this.originZ = 0;
this.rotateX = 0;
this.rotateY = 0;
this.rotateZ = 0;
this.x = 0;
this.y = 0;
this.z = 0;
this._matrix = new Matrix4();
this._groupMatrix = new Matrix4();
}
Group.prototype.add = function add(child) {
this.children.push(child);
Object3d.prototype.isVisible = function isVisible() {
return this.visible && this.alpha > 0 && this.scaleX !== 0 && this.scaleY !== 0 && this.scaleZ !== 0;
};
Group.prototype.render = function render(ctx) {
var list = this.children.slice();
for (var i = 0, l = list.length; i < l; i++) {
var child = list[i];
if (!child.isVisible()) {
continue;
}
Object3d.prototype.updateContext = function updateContext() {};
// draw the child:
ctx.save();
child.updateContext(ctx);
child.render(ctx);
ctx.restore();
}
return true;
};
return Group;
return Object3d;
}();
function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
@ -2531,13 +2536,63 @@
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Group = function (_Object3d) {
_inherits(Group, _Object3d);
function Group() {
_classCallCheck$1(this, Group);
var _this = _possibleConstructorReturn(this, _Object3d.call(this));
_this.children = [];
return _this;
}
Group.prototype.add = function add(child) {
this.children.push(child);
};
Group.prototype.update = function update(ctx, camera, scale, groupMatrix) {
var list = this.children.slice();
for (var i = 0, l = list.length; i < l; i++) {
var child = list[i];
if (!child.isVisible()) {
continue;
}
this._matrix.identity().appendTransform(this.x, this.y, this.z, this.scaleX, this.scaleY, this.scaleZ, this.rotateX, this.rotateY, this.rotateZ, this.skewX, this.skewY, this.skewZ, this.originX, this.originY, this.originZ);
if (groupMatrix) {
this._groupMatrix.multiplyMatrices(this._matrix, groupMatrix);
} else {
this._groupMatrix = this._matrix;
}
// draw the child:
ctx.save();
child.updateContext(ctx);
child.update(ctx, camera, scale, this._groupMatrix);
ctx.restore();
}
return true;
};
return Group;
}(Object3d);
function _classCallCheck$2(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn$1(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits$1(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Stage = function (_Group) {
_inherits(Stage, _Group);
_inherits$1(Stage, _Group);
function Stage(option) {
_classCallCheck$1(this, Stage);
_classCallCheck$2(this, Stage);
var _this = _possibleConstructorReturn(this, _Group.call(this));
var _this = _possibleConstructorReturn$1(this, _Group.call(this));
_this.renderTo = typeof option.renderTo === 'string' ? document.querySelector(option.renderTo) : option.renderTo;
_this.canvas = document.createElement('canvas');
@ -2569,63 +2624,57 @@
return Stage;
}(Group);
function _classCallCheck$2(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _classCallCheck$3(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn$2(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits$2(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Cube = function (_Object3d) {
_inherits$2(Cube, _Object3d);
var Cube = function () {
function Cube(length, width, height, options) {
_classCallCheck$2(this, Cube);
_classCallCheck$3(this, Cube);
var _this = _possibleConstructorReturn$2(this, _Object3d.call(this));
options = options || {};
this.center = options.center || new Vector3(0, 0, 0);
this.length = length;
this.width = width;
this.height = height;
this.scaleX = 1;
this.scaleY = 1;
this.scaleZ = 1;
this.skewX = 0;
this.skewY = 0;
this.skewZ = 0;
this.originX = 0;
this.originY = 0;
this.originZ = 0;
_this.center = options.center || new Vector3(_this.x, _this.y, _this.z);
_this.length = length;
_this.width = width;
_this.height = height;
this.rotate = Object.assign({
x: 0,
y: 0,
z: 0
}, options.rotate);
this.pv = new Matrix4();
_this.pv = new Matrix4();
var hl = this.length / 2;
var hw = this.width / 2;
var hh = this.height / 2;
this.p0 = this.center.clone().sub({ x: hl, y: hh, z: hw });
this.p1 = this.center.clone().sub({ x: hl - this.length, y: hh, z: hw });
this.p2 = this.center.clone().sub({ x: hl - this.length, y: hh - this.height, z: hw });
this.p3 = this.center.clone().sub({ x: hl, y: hh - this.height, z: hw });
var hl = _this.length / 2;
var hw = _this.width / 2;
var hh = _this.height / 2;
_this.p0 = _this.center.clone().sub({ x: hl, y: hh, z: hw });
_this.p1 = _this.center.clone().sub({ x: hl - _this.length, y: hh, z: hw });
_this.p2 = _this.center.clone().sub({ x: hl - _this.length, y: hh - _this.height, z: hw });
_this.p3 = _this.center.clone().sub({ x: hl, y: hh - _this.height, z: hw });
this.p4 = this.center.clone().sub({ x: hl, y: hh, z: hw - this.width });
_this.p4 = _this.center.clone().sub({ x: hl, y: hh, z: hw - _this.width });
this.p5 = this.center.clone().sub({ x: hl - this.length, y: hh, z: hw - this.width });
this.p6 = this.center.clone().sub({ x: hl - this.length, y: hh - this.height, z: hw - this.width });
this.p7 = this.center.clone().sub({ x: hl, y: hh - this.height, z: hw - this.width });
_this.p5 = _this.center.clone().sub({ x: hl - _this.length, y: hh, z: hw - _this.width });
_this.p6 = _this.center.clone().sub({ x: hl - _this.length, y: hh - _this.height, z: hw - _this.width });
_this.p7 = _this.center.clone().sub({ x: hl, y: hh - _this.height, z: hw - _this.width });
this.hh = hh;
this.hl = hl;
this.hw = hw;
this.basePoints = [this.p0.clone(), this.p1.clone(), this.p2.clone(), this.p3.clone(), this.p4.clone(), this.p5.clone(), this.p6.clone(), this.p7.clone()];
_this.hh = hh;
_this.hl = hl;
_this.hw = hw;
_this.basePoints = [_this.p0.clone(), _this.p1.clone(), _this.p2.clone(), _this.p3.clone(), _this.p4.clone(), _this.p5.clone(), _this.p6.clone(), _this.p7.clone()];
this.points = [this.p0, this.p1, this.p2, this.p3, this.p4, this.p5, this.p6, this.p7];
_this.points = [_this.p0, _this.p1, _this.p2, _this.p3, _this.p4, _this.p5, _this.p6, _this.p7];
var ps = this.points;
this.colors = options.colors || ['red', 'green', 'blue', 'yellow', '#ccc', '#467fdd'];
this.faces = [[ps[0], ps[1], ps[2], ps[3], this.colors[0]], [ps[4], ps[5], ps[6], ps[7], this.colors[1]], [ps[4], ps[5], ps[1], ps[0], this.colors[2]], [ps[3], ps[2], ps[6], ps[7], this.colors[3]], [ps[3], ps[0], ps[4], ps[7], this.colors[4]], [ps[2], ps[1], ps[5], ps[6], this.colors[5]]];
var ps = _this.points;
_this.colors = options.colors || ['red', 'green', 'blue', 'yellow', '#ccc', '#467fdd'];
_this.faces = [[ps[0], ps[1], ps[2], ps[3], _this.colors[0]], [ps[4], ps[5], ps[6], ps[7], _this.colors[1]], [ps[4], ps[5], ps[1], ps[0], _this.colors[2]], [ps[3], ps[2], ps[6], ps[7], _this.colors[3]], [ps[3], ps[0], ps[4], ps[7], _this.colors[4]], [ps[2], ps[1], ps[5], ps[6], _this.colors[5]]];
this._matrix = new Matrix4();
return _this;
}
Cube.prototype.transform = function transform(camera) {
Cube.prototype.transform = function transform(camera, groupMatrix) {
// const yTopOrigin = {
// x: this.center.x,
// y: this.center.y - this.hh,
@ -2652,10 +2701,16 @@
// this.basePoints[7].rotateY(yBottomOrigin, this.rotate.y, this.p7)
this._matrix.identity().appendTransform(this.center.x, this.center.y, this.center.z, this.scaleX, this.scaleY, this.scaleZ, this.rotate.x, this.rotate.y, this.rotate.z, this.skewX, this.skewY, this.skewZ, this.originX, this.originY, this.originZ);
this._matrix.identity().appendTransform(this.x, this.y, this.z, this.scaleX, this.scaleY, this.scaleZ, this.rotateX, this.rotateY, this.rotateZ, this.skewX, this.skewY, this.skewZ, this.originX, this.originY, this.originZ);
if (groupMatrix) {
this._groupMatrix.multiplyMatrices(this._matrix, groupMatrix);
} else {
this._groupMatrix = this._matrix;
}
for (var i = 0; i < 8; i++) {
this.basePoints[i].applyMatrix4Out(this._matrix, this['p' + i]);
this.basePoints[i].applyMatrix4Out(this._groupMatrix, this['p' + i]);
}
this.pv.multiplyMatrices(camera.p_matrix, camera.v_matrix);
@ -2668,8 +2723,8 @@
}
};
Cube.prototype.update = function update(ctx, camera, scale) {
this.transform(camera);
Cube.prototype.update = function update(ctx, camera, scale, groupMatrix) {
this.transform(camera, groupMatrix);
this.fill(ctx, scale);
};
@ -2685,16 +2740,16 @@
};
Cube.prototype.fill = function fill(ctx, scale) {
var _this = this;
var _this2 = this;
var ps = this.points;
this.faces.sort(function (a, b) {
return _this._zOrder(a) - _this._zOrder(b);
return _this2._zOrder(a) - _this2._zOrder(b);
});
this.faces.forEach(function (face) {
_this._rect(ctx, face[0], face[1], face[2], face[3], scale, face[4]);
_this2._rect(ctx, face[0], face[1], face[2], face[3], scale, face[4]);
});
};
@ -2729,13 +2784,13 @@
};
return Cube;
}();
}(Object3d);
function _classCallCheck$3(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _classCallCheck$4(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Camera = function () {
function Camera(option) {
_classCallCheck$3(this, Camera);
_classCallCheck$4(this, Camera);
//http://blog.csdn.net/lyx2007825/article/details/8792475
//http://www.cnblogs.com/yiyezhai/archive/2012/09/12/2677902.html
@ -2822,12 +2877,10 @@
});
var cube = new Cube(100, 100, 100, {
center: new Vector3(0, 0, 0),
rotate: {
y: 30
}
center: new Vector3(0, 0, 0)
});
cube.rotateY = 30;
stage.add(cube);
stage.update();
@ -2836,9 +2889,9 @@
function animate() {
requestAnimationFrame(animate);
cube.rotate.y += 1;
cube.rotate.x += 1;
cube.rotate.z += 1;
cube.rotateY += 1;
cube.rotateX += 1;
cube.rotateZ += 1;
//camera.y += 1
stage.update();
}

File diff suppressed because one or more lines are too long

View File

@ -22,12 +22,10 @@ const stage = new Stage({
});
const cube = new Cube(100, 100, 100, {
center: new Vector3(0, 0, 0),
rotate: {
y: 30
}
center: new Vector3(0, 0, 0)
})
cube.rotateY = 30
stage.add(cube)
stage.update()
@ -36,9 +34,9 @@ animate()
function animate() {
requestAnimationFrame(animate)
cube.rotate.y += 1
cube.rotate.x += 1
cube.rotate.z += 1
cube.rotateY += 1
cube.rotateX += 1
cube.rotateZ += 1
//camera.y += 1
stage.update()
}

View File

@ -6,26 +6,14 @@ class Cube extends Object3d{
constructor(length, width, height, options) {
super()
options = options || {}
this.center = options.center || new Vector3(0, 0, 0)
this.center = options.center || new Vector3(this.x, this.y, this.z)
this.length = length
this.width = width
this.height = height
this.skewX = 0
this.skewY = 0
this.skewZ = 0
this.originX = 0
this.originY = 0
this.originZ = 0
this.rotate = Object.assign(
{
x: 0,
y: 0,
z: 0
},
options.rotate
)
this.pv = new Matrix4()
const hl = this.length / 2
@ -86,11 +74,9 @@ class Cube extends Object3d{
[ps[2], ps[1], ps[5], ps[6], this.colors[5]]
]
this._matrix = new Matrix4()
}
transform(camera) {
transform(camera, groupMatrix) {
// const yTopOrigin = {
// x: this.center.x,
// y: this.center.y - this.hh,
@ -117,10 +103,17 @@ class Cube extends Object3d{
// this.basePoints[7].rotateY(yBottomOrigin, this.rotate.y, this.p7)
this._matrix.identity().appendTransform(this.center.x, this.center.y, this.center.z, this.scaleX, this.scaleY, this.scaleZ, this.rotate.x, this.rotate.y, this.rotate.z, this.skewX, this.skewY, this.skewZ, this.originX, this.originY, this.originZ)
this._matrix.identity().appendTransform(this.x, this.y, this.z, this.scaleX, this.scaleY, this.scaleZ, this.rotateX, this.rotateY, this.rotateZ, this.skewX, this.skewY, this.skewZ, this.originX, this.originY, this.originZ)
if(groupMatrix){
this._groupMatrix.multiplyMatrices(this._matrix, groupMatrix)
}else{
this._groupMatrix = this._matrix
}
for (let i = 0; i < 8; i++) {
this.basePoints[i].applyMatrix4Out(this._matrix, this['p' + i])
this.basePoints[i].applyMatrix4Out(this._groupMatrix, this['p' + i])
}
@ -134,8 +127,8 @@ class Cube extends Object3d{
}
}
update(ctx, camera, scale) {
this.transform(camera)
update(ctx, camera, scale, groupMatrix) {
this.transform(camera, groupMatrix)
this.fill(ctx, scale)
}

View File

@ -10,7 +10,7 @@ class Group extends Object3d {
this.children.push(child)
}
update(ctx, camera, scale) {
update(ctx, camera, scale, groupMatrix) {
let list = this.children.slice()
for (let i = 0, l = list.length; i < l; i++) {
let child = list[i]
@ -18,10 +18,19 @@ class Group extends Object3d {
continue
}
this._matrix.identity().appendTransform(this.x, this.y, this.z, this.scaleX, this.scaleY, this.scaleZ, this.rotateX, this.rotateY, this.rotateZ, this.skewX, this.skewY, this.skewZ, this.originX, this.originY, this.originZ)
if(groupMatrix){
this._groupMatrix.multiplyMatrices(this._matrix, groupMatrix)
}else{
this._groupMatrix = this._matrix
}
// draw the child:
ctx.save()
child.updateContext(ctx)
child.update(ctx, camera, scale)
child.update(ctx, camera, scale, this._groupMatrix)
ctx.restore()
}
return true

View File

@ -1,3 +1,5 @@
import { Matrix4 } from './matrix4'
class Object3d {
constructor() {
this.alpha = 1
@ -5,6 +7,22 @@ class Object3d {
this.scaleY = 1
this.scaleZ = 1
this.visible = true
this.skewX = 0
this.skewY = 0
this.skewZ = 0
this.originX = 0
this.originY = 0
this.originZ = 0
this.rotateX = 0
this.rotateY = 0
this.rotateZ = 0
this.x = 0
this.y = 0
this.z = 0
this._matrix = new Matrix4()
this._groupMatrix = new Matrix4()
}
isVisible() {
@ -14,7 +32,7 @@ class Object3d {
}
updateContext(){
}