Skip to content

Commit f04fbea

Browse files
committed
Projective viewport
1 parent d1ad05d commit f04fbea

13 files changed

+605
-7
lines changed

README.md

+17
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,23 @@ Regular linear XYZ.
249249
})
250250
```
251251

252+
__Projective__
253+
Applies a 4x4 homogeneous/projective transform.
254+
255+
```javascript
256+
.viewport({
257+
type: 'projective',
258+
range: [[-1, 1], [-1, 1], [-1, 1]], // Range in X, Y, Z
259+
scale: [1, 1, 1], // Scale in X, Y, Z
260+
rotation: [0, 0, 0], // Viewport rotation in Euler angles
261+
position: [0, 0, 0], // Viewport position in XYZ
262+
projective: [[1, 0, 0, 0], // 4x4 projective transform
263+
[0, 1, 0, 0],
264+
[0, 0, 1, 0],
265+
[0, 0, 0, 1]],
266+
})
267+
```
268+
252269
__Polar__
253270
Polar coordinate grid in radians. X is angle, Y is radius, Z is ordinary depth.
254271
Also useful for visualizing complex operations in polar representation.

build.sh

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ src/renderables/Labels.js
4646
src/viewports/Viewport.js
4747
src/viewports/ViewportCartesian.js
4848
src/viewports/ViewportPolar.js
49+
src/viewports/ViewportProjective.js
4950
src/viewports/ViewportSphere.js
5051
"
5152

build/MathBox-bundle.js

+88-1
Original file line numberDiff line numberDiff line change
@@ -46944,13 +46944,100 @@ MathBox.ViewportPolar.prototype = _.extend(new MathBox.ViewportCartesian(null),
4694446944

4694546945
validatePolar: function (polar) {
4694646946
return Math.max(0, Math.min(1, +polar || 0));
46947-
}//,
46947+
},
46948+
46949+
validateFold: function (fold) {
46950+
return +fold || 0;
46951+
},
46952+
46953+
validatePower: function (power) {
46954+
return +power || 0;
46955+
},
46956+
46957+
validateHelix: function (helix) {
46958+
return +helix || 0;
46959+
},
4694846960

4694946961
});
4695046962

4695146963
MathBox.Attributes.mixin(MathBox.Viewport);
4695246964

4695346965
MathBox.Viewport.types.polar = MathBox.ViewportPolar;
46966+
/**
46967+
* Projective viewport, i.e. with a 4x4 projective transform applied
46968+
*/
46969+
MathBox.ViewportProjective = function (options) {
46970+
var _super = MathBox.ViewportCartesian;
46971+
_super.call(this, options);
46972+
this.super = _super.prototype;
46973+
46974+
// Prepare uniforms
46975+
_.extend(this._uniforms, {
46976+
projectiveTransform: new THREE.Matrix4(),//,
46977+
});
46978+
};
46979+
46980+
MathBox.ViewportProjective.prototype = _.extend(new MathBox.ViewportCartesian(null), {
46981+
46982+
defaults: function () {
46983+
return {
46984+
type: 'projective',
46985+
range: [[-1, 1], [-1, 1], [-1, 1]],
46986+
scale: [1, 1, 1],
46987+
rotation: [0, 0, 0],
46988+
position: [0, 0, 0],
46989+
projective: [[1, 0, 0, 0],
46990+
[0, 1, 0, 0],
46991+
[0, 0, 1, 0],
46992+
[0, 0, 0, 1]],
46993+
};
46994+
},
46995+
46996+
to: function (vector) {
46997+
// Apply projective transform
46998+
this._uniforms.projectiveTransform.multiplyVector3(vector);
46999+
47000+
// Apply viewport
47001+
this.transform.multiplyVector3(vector);
47002+
},
47003+
47004+
from: function (vector) {
47005+
// Apply inverse viewport
47006+
this.inverse.multiplyVector3(vector);
47007+
},
47008+
47009+
update: function (stage) {
47010+
var t = this._uniforms.projectiveTransform;
47011+
var m = this.get('projective');
47012+
console.log(m, m[0].concat(m[1], m[2], m[3]));
47013+
// t.set.apply(t, m[0].concat(m[1], m[2], m[3]));
47014+
47015+
MathBox.ViewportCartesian.prototype.update.call(this, stage);
47016+
},
47017+
47018+
shader: function (factory) {
47019+
factory
47020+
.snippet('projectiveTransform')
47021+
.snippet('mathToWorld');
47022+
},
47023+
47024+
// Attribute validators
47025+
47026+
validateProjective: function (m) {
47027+
if (m.constructor == Array) {
47028+
for (var j = 0; j < 3; ++j) {
47029+
m[j] = (m[j] && m.constructor == Array && m[j]) || [];
47030+
m[j] = m[j].concat([0, 0, 0, 0]).slice(0, 4);
47031+
}
47032+
return m;
47033+
}
47034+
},
47035+
47036+
});
47037+
47038+
MathBox.Attributes.mixin(MathBox.Viewport);
47039+
47040+
MathBox.Viewport.types.projective = MathBox.ViewportProjective;
4695447041
/**
4695547042
* Cartesian to spherical viewport transform.
4695647043
*

build/MathBox-bundle.min.js

+4-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/MathBox-core.js

+88-1
Original file line numberDiff line numberDiff line change
@@ -4335,13 +4335,100 @@ MathBox.ViewportPolar.prototype = _.extend(new MathBox.ViewportCartesian(null),
43354335

43364336
validatePolar: function (polar) {
43374337
return Math.max(0, Math.min(1, +polar || 0));
4338-
}//,
4338+
},
4339+
4340+
validateFold: function (fold) {
4341+
return +fold || 0;
4342+
},
4343+
4344+
validatePower: function (power) {
4345+
return +power || 0;
4346+
},
4347+
4348+
validateHelix: function (helix) {
4349+
return +helix || 0;
4350+
},
43394351

43404352
});
43414353

43424354
MathBox.Attributes.mixin(MathBox.Viewport);
43434355

43444356
MathBox.Viewport.types.polar = MathBox.ViewportPolar;
4357+
/**
4358+
* Projective viewport, i.e. with a 4x4 projective transform applied
4359+
*/
4360+
MathBox.ViewportProjective = function (options) {
4361+
var _super = MathBox.ViewportCartesian;
4362+
_super.call(this, options);
4363+
this.super = _super.prototype;
4364+
4365+
// Prepare uniforms
4366+
_.extend(this._uniforms, {
4367+
projectiveTransform: new THREE.Matrix4(),//,
4368+
});
4369+
};
4370+
4371+
MathBox.ViewportProjective.prototype = _.extend(new MathBox.ViewportCartesian(null), {
4372+
4373+
defaults: function () {
4374+
return {
4375+
type: 'projective',
4376+
range: [[-1, 1], [-1, 1], [-1, 1]],
4377+
scale: [1, 1, 1],
4378+
rotation: [0, 0, 0],
4379+
position: [0, 0, 0],
4380+
projective: [[1, 0, 0, 0],
4381+
[0, 1, 0, 0],
4382+
[0, 0, 1, 0],
4383+
[0, 0, 0, 1]],
4384+
};
4385+
},
4386+
4387+
to: function (vector) {
4388+
// Apply projective transform
4389+
this._uniforms.projectiveTransform.multiplyVector3(vector);
4390+
4391+
// Apply viewport
4392+
this.transform.multiplyVector3(vector);
4393+
},
4394+
4395+
from: function (vector) {
4396+
// Apply inverse viewport
4397+
this.inverse.multiplyVector3(vector);
4398+
},
4399+
4400+
update: function (stage) {
4401+
var t = this._uniforms.projectiveTransform;
4402+
var m = this.get('projective');
4403+
console.log(m, m[0].concat(m[1], m[2], m[3]));
4404+
// t.set.apply(t, m[0].concat(m[1], m[2], m[3]));
4405+
4406+
MathBox.ViewportCartesian.prototype.update.call(this, stage);
4407+
},
4408+
4409+
shader: function (factory) {
4410+
factory
4411+
.snippet('projectiveTransform')
4412+
.snippet('mathToWorld');
4413+
},
4414+
4415+
// Attribute validators
4416+
4417+
validateProjective: function (m) {
4418+
if (m.constructor == Array) {
4419+
for (var j = 0; j < 3; ++j) {
4420+
m[j] = (m[j] && m.constructor == Array && m[j]) || [];
4421+
m[j] = m[j].concat([0, 0, 0, 0]).slice(0, 4);
4422+
}
4423+
return m;
4424+
}
4425+
},
4426+
4427+
});
4428+
4429+
MathBox.Attributes.mixin(MathBox.Viewport);
4430+
4431+
MathBox.Viewport.types.projective = MathBox.ViewportProjective;
43454432
/**
43464433
* Cartesian to spherical viewport transform.
43474434
*

build/MathBox-core.min.js

+4-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/MathBox.glsl.html

+10
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,16 @@
169169

170170
</script>
171171

172+
<script type="application/x-glsl" id="projectiveTransform">
173+
// Vertex shader: apply the projective viewport transform
174+
uniform mat4 projectiveTransform;
175+
176+
void projective(in vec3 positionIn, out vec3 positionOut) {
177+
vec4 pos4 = projectiveTransform * vec4(positionIn, 1.0);
178+
positionOut = pos4.xyz / pos4.w;
179+
}
180+
</script>
181+
172182
<script type="application/x-glsl" id="mathTransform">
173183
// Vertex shader: apply an arbitrary transform in math space
174184
uniform mat4 mathTransform;

build/MathBox.js

+88-1
Original file line numberDiff line numberDiff line change
@@ -7321,13 +7321,100 @@ MathBox.ViewportPolar.prototype = _.extend(new MathBox.ViewportCartesian(null),
73217321

73227322
validatePolar: function (polar) {
73237323
return Math.max(0, Math.min(1, +polar || 0));
7324-
}//,
7324+
},
7325+
7326+
validateFold: function (fold) {
7327+
return +fold || 0;
7328+
},
7329+
7330+
validatePower: function (power) {
7331+
return +power || 0;
7332+
},
7333+
7334+
validateHelix: function (helix) {
7335+
return +helix || 0;
7336+
},
73257337

73267338
});
73277339

73287340
MathBox.Attributes.mixin(MathBox.Viewport);
73297341

73307342
MathBox.Viewport.types.polar = MathBox.ViewportPolar;
7343+
/**
7344+
* Projective viewport, i.e. with a 4x4 projective transform applied
7345+
*/
7346+
MathBox.ViewportProjective = function (options) {
7347+
var _super = MathBox.ViewportCartesian;
7348+
_super.call(this, options);
7349+
this.super = _super.prototype;
7350+
7351+
// Prepare uniforms
7352+
_.extend(this._uniforms, {
7353+
projectiveTransform: new THREE.Matrix4(),//,
7354+
});
7355+
};
7356+
7357+
MathBox.ViewportProjective.prototype = _.extend(new MathBox.ViewportCartesian(null), {
7358+
7359+
defaults: function () {
7360+
return {
7361+
type: 'projective',
7362+
range: [[-1, 1], [-1, 1], [-1, 1]],
7363+
scale: [1, 1, 1],
7364+
rotation: [0, 0, 0],
7365+
position: [0, 0, 0],
7366+
projective: [[1, 0, 0, 0],
7367+
[0, 1, 0, 0],
7368+
[0, 0, 1, 0],
7369+
[0, 0, 0, 1]],
7370+
};
7371+
},
7372+
7373+
to: function (vector) {
7374+
// Apply projective transform
7375+
this._uniforms.projectiveTransform.multiplyVector3(vector);
7376+
7377+
// Apply viewport
7378+
this.transform.multiplyVector3(vector);
7379+
},
7380+
7381+
from: function (vector) {
7382+
// Apply inverse viewport
7383+
this.inverse.multiplyVector3(vector);
7384+
},
7385+
7386+
update: function (stage) {
7387+
var t = this._uniforms.projectiveTransform;
7388+
var m = this.get('projective');
7389+
console.log(m, m[0].concat(m[1], m[2], m[3]));
7390+
// t.set.apply(t, m[0].concat(m[1], m[2], m[3]));
7391+
7392+
MathBox.ViewportCartesian.prototype.update.call(this, stage);
7393+
},
7394+
7395+
shader: function (factory) {
7396+
factory
7397+
.snippet('projectiveTransform')
7398+
.snippet('mathToWorld');
7399+
},
7400+
7401+
// Attribute validators
7402+
7403+
validateProjective: function (m) {
7404+
if (m.constructor == Array) {
7405+
for (var j = 0; j < 3; ++j) {
7406+
m[j] = (m[j] && m.constructor == Array && m[j]) || [];
7407+
m[j] = m[j].concat([0, 0, 0, 0]).slice(0, 4);
7408+
}
7409+
return m;
7410+
}
7411+
},
7412+
7413+
});
7414+
7415+
MathBox.Attributes.mixin(MathBox.Viewport);
7416+
7417+
MathBox.Viewport.types.projective = MathBox.ViewportProjective;
73317418
/**
73327419
* Cartesian to spherical viewport transform.
73337420
*

0 commit comments

Comments
 (0)