This question is more about Math, than about threejs but maybe there are usable Alternatives for my issue.
So what I want to do, is to go through every vertice in a Box Geometry and check weither it has to be moved down/up and move it then by a specific value. (it is only about the y-values of each vertice)
var width = 200,
height = 100,
depth = 50;
var roundCornerWidth = var roundCornerHeight = 10;
var helpWidth = width - 2*roundCornerWidth,
helpHeight = height - 2*roundCornerHeight;
var boxGeometry = new THREE.BoxGeometry(width, height, depth, 100, 50, 10);
boxGeometry.vertices.forEach(v => {
if(Math.abs(v.x)>helpWidth/2){
if(Math.abs(v.y)>helpHeight/2){
let helper = Math.abs(v.x)-helperWidth/2;
v.y = Math.sign(v.y)*(helperHeight + Math.cos(helper/roundWidth * Math.PI/2)*roundHeight);
}
}
});
The code above creates corners like you can see on the example image. Those aren't kind of beautiful! :( Another "function" than cos() is needed.
I've used a method without trigonometrical functions, as we can manipulate with vectors:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(50, 50, 150);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var radius = 10;
var width = 200,
height = 100;
var geometry = new THREE.BoxGeometry(width, height, 50, 100, 50, 10);
var v1 = new THREE.Vector3();
var w1 = (width - (radius * 2)) * 0.5,
h1 = (height - (radius * 2)) * 0.5;
var vTemp = new THREE.Vector3(),
vSign = new THREE.Vector3(),
vRad = new THREE.Vector3();
geometry.vertices.forEach(v => {
v1.set(w1, h1, v.z);
vTemp.multiplyVectors(v1, vSign.set(Math.sign(v.x), Math.sign(v.y), 1));
vRad.subVectors(v, vTemp);
if (Math.abs(v.x) > v1.x && Math.abs(v.y) > v1.y && vRad.length() > radius) {
vRad.setLength(radius).add(vTemp);
v.copy(vRad);
}
});
var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
color: "aqua",
wireframe: true
}));
scene.add(mesh);
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/90/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
Disadvantage: you can't control the smoothness of the roundness without increasing the amount of width or height or depth segments.
EDIT: copied surrounding Code Blocks from prisoner849 to make result visbile for everyone.
I wanted to stay with the box Geometry, because I also deform the Geometry on the z-axis, so this is my solution:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(50, 50, 150);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var width = 200,
height = 100,
depth = 50;
var roundCornerWidth = roundCornerHeight = 10;
var helpWidth = width - 2*roundCornerWidth,
helpHeight = height - 2*roundCornerHeight;
var boxGeometry = new THREE.BoxGeometry(width, height, depth, 100, 50, 10);
boxGeometry.vertices.forEach(v => {
if(Math.abs(v.x)>helpWidth/2){
if(Math.abs(v.y)>helpHeight/2){
let helperX = Math.abs(v.x)-helpWidth/2;
let helperY2 = (Math.abs(v.y)-helpHeight/2)/roundCornerHeight;
let helperY = (1-helperX/roundCornerWidth) * roundCornerHeight * helperY2;
v.y = Math.sign(v.y)*((helpHeight/2 + helperY)+(Math.sin(helperX/roundCornerWidth * Math.PI)*(roundCornerHeight/4))*helperY2);
v.x = Math.sign(v.x)*(Math.abs(v.x)+(Math.sin(helperX/roundCornerWidth * Math.PI)*(roundCornerWidth/4))*helperY2);
}
}
});
var mesh = new THREE.Mesh(boxGeometry, new THREE.MeshBasicMaterial({
color: 0xffce00,
wireframe: true
}));
scene.add(mesh);
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/90/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
This worked for me perfectly and seems to be the simplest solution for my issue.
Related
I would like to create circles in two different ways:
With a circle sprite, then draw it with Points and PointsMaterial
With basic circle buffer geometries
However, I cannot make them match together because of PointsMaterial size.
const width = window.innerWidth;
const height = window.innerHeight;
const fov = 40;
const near = 10;
const far = 200;
const camera = new THREE.PerspectiveCamera(fov, width / height, near, far);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
const circle_sprite = new THREE.TextureLoader().load(
'https://fastforwardlabs.github.io/visualization_assets/circle-sprite.png'
);
const factor = 280;
const positions = [
{ x: 100, y: -5 },
{ x: 6, y: 50 }
];
const circleRadius = 20;
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xefefef);
/* First method */
const pointsGeometry = new THREE.Geometry();
const colors = [];
for (const position of positions) {
// Set vector coordinates from data
const vertex = new THREE.Vector3(position.x, position.y, 0);
pointsGeometry.vertices.push(vertex);
const color = new THREE.Color(0xff0000);
colors.push(color);
}
pointsGeometry.colors = colors;
const pointsMaterial = new THREE.PointsMaterial({
size: (factor * circleRadius) / fov,
sizeAttenuation: false,
vertexColors: true,
map: circle_sprite,
transparent: true,
opacity: 0.5
});
const firstPoints = new THREE.Points(pointsGeometry, pointsMaterial);
scene.add(firstPoints);
/* Second method */
const circleGeometry = new THREE.CircleBufferGeometry(circleRadius, 32);
const circleMaterial = new THREE.MeshBasicMaterial({
color: 0xffff00,
transparent: true,
opacity: 0.5
});
positions.forEach((position) => {
const circleMesh = new THREE.Mesh(circleGeometry, circleMaterial);
circleMesh.position.set(position.x, position.y, 0);
scene.add(circleMesh);
});
/* Render loop */
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
camera.position.set(0, 0, far);
I try to find the factor variable value but I also discovered that width or height are involved in this factor.
How can I draw same circles with PointsMaterial?
Having this: https://github.com/mrdoob/three.js/issues/12150#issuecomment-327874431, you can compute the size of points.
body {
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://threejs.org/build/three.module.js";
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(50, innerWidth / innerHeight, 1, 100);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
var grid = new THREE.GridHelper(10, 10);
grid.rotation.x = Math.PI * 0.5;
scene.add(grid);
// geometry
var cGeom = new THREE.CircleBufferGeometry(1, 32);
var cMat = new THREE.MeshBasicMaterial({
color: "magenta"
});
var circle = new THREE.Mesh(cGeom, cMat);
circle.position.set(0, 3, 0);
scene.add(circle);
// points
var g = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3()]);
var c = document.createElement("canvas");
c.width = 128;
c.height = 128;
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, 128, 128);
ctx.fillStyle = "white";
ctx.beginPath();
ctx.arc(64, 64, 64, 0, 2 * Math.PI);
ctx.fill();
var tex = new THREE.CanvasTexture(c);
var desiredSize = 2;
var pSize = desiredSize / Math.tan( THREE.Math.degToRad( camera.fov / 2 ) );
var m = new THREE.PointsMaterial({
size: pSize,
color: "aqua",
map: tex,
alphaMap: tex,
alphaTest: 0.5
});
var p = new THREE.Points(g, m);
scene.add(p);
renderer.setAnimationLoop(() => {
renderer.render(scene, camera)
});
</script>
I am trying to create spheres and assign them a random color at the vertices of the rectangle (It can be other geometrical from like triangles or hexagons and so forth, for simplicity in this example I want to use a rectangle). http://jsfiddle.net/ElmerCC/ja6zL0k1/
let scene, camera, renderer;
let controls;
let widthWindow = window.innerWidth;
let heightWindow = window.innerHeight;
let aspect = widthWindow / heightWindow;
let mouse = new THREE.Vector2();
let raycaster = new THREE.Raycaster();
let intersect;
let elements = [];
let elementsNew = [];
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 10000);
camera.up.set(0, 0, 1);
camera.position.set(-500, -500, 400);
scene.add(camera);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(widthWindow, heightWindow);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
let p = [];
p[0] = new THREE.Vector3(-100, -100, 0);
p[1] = new THREE.Vector3(100, -100, 0);
p[2] = new THREE.Vector3(100, 100, 0);
p[3] = new THREE.Vector3(-100, 100, 0);
//dibujar los nodos
for (let cont = 0; cont < 4; cont++) {
let obj = drawJoint(p[cont], 10, 0x666666, 0, true);
elements.push(obj);
scene.add(obj);
}
var geometry = new THREE.PlaneGeometry(200, 200);
var material = new THREE.MeshBasicMaterial({
color: 0x666666,
side: THREE.DoubleSide
});
var plane = new THREE.Mesh(geometry, material);
scene.add(plane);
//document.addEventListener("mousemove", moveMouse);
document.addEventListener("mousedown", downMouse);
}
function downMouse(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
let intersected = raycaster.intersectObjects(elements);
if (intersected.length > 0) {
intersect = intersected[0].object;
let center = intersect.position;
let n = drawJoint(center, 15, Math.random() * 0xffffff, 1, true);
elementsNew.push(n);
scene.add(n);
}
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
controls.update();
renderer.render(scene, camera);
}
function drawJoint(
JtCenter,
JtRadius,
Jtcolor,
JtOpacity,
JtTransparency
) {
let JtMaterial = new THREE.MeshBasicMaterial({
color: Jtcolor,
opacity: JtOpacity,
transparent: JtTransparency
});
let JtGeom = new THREE.SphereGeometry(JtRadius, 10, 10);
let Joint = new THREE.Mesh(JtGeom, JtMaterial);
JtGeom .computeBoundingSphere();
Joint.position.copy(JtCenter);
return Joint;
}
How can I detect the intersection of two sphere objects to avoid overlapping one another?
Spheres are the easiest objects for which you can test intersection.
Note that a Sphere is a mathematical representation, and is different than a Mesh with sphere geometry. (You can still get the mathematical bounding sphere of a Mesh with the boundingSphere property.)
Here is how you'd check if two spheres touch/intersect (you can send this function two boundingSphere properties to check other non-sphere objects).
function spheresIntersect(sphere1, sphere1position, sphere2, sphere2position){
return sphere1position.distanceTo(sphere2position) <= (sphere1.radius + sphere2.radius)
}
i'm trying to figure out for hours why I can't see the text inside the cube and I don't see why it's not working.
There's two meshes, one of them is inside the other, but is invisible.
When I comment the line adding the cube mesh to my group, the text appears (line 34).
I can see the text if I remove the "transparent: true" from its material, but a background appears (line 52).
The text is added as a canvas texture, that's the easiest way I've found to dynamically add 2d text.
I just want to add some white text inside my cube without having any backgound color.
I saw this question but it looks like it's not related to my problem : THREE.JS: Seeing geometry when inside mesh
var renderer, scene, camera, cubeGroup;
var rotationX = 0;
var rotationY = 0;
var percentX, percentY;
var container = document.getElementById('container');
init();
animate();
function init(){
renderer = new THREE.WebGLRenderer({alpha: true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor( 0x000000, 1);
document.getElementById('container').appendChild(renderer.domElement);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 0, 1000);
scene.add(camera);
// group
cubeGroup = new THREE.Group();
// cube
var geometry = new THREE.BoxGeometry(200, 200, 200);
var material = new THREE.MeshPhongMaterial({
color: 0x11111f,
side: THREE.DoubleSide,
opacity: .5,
transparent: true
});
var mesh = new THREE.Mesh(geometry, material);
cubeGroup.add(mesh); // Comment this and the text appears with transparency
var ambientLight = new THREE.AmbientLight(0x999999, 0.8);
scene.add(ambientLight);
// text
var bitmap = document.createElement('canvas');
var g = bitmap.getContext('2d');
bitmap.width = 256;
bitmap.height = 256;
g.font = '80px Arial';
g.fillStyle = 'white';
g.fillText('text', 20, 80);
var geometry = new THREE.PlaneGeometry(180, 180);
var texture = new THREE.CanvasTexture(bitmap);
var material = new THREE.MeshStandardMaterial({
map: texture,
transparent: true // Comment this and the text appears - but with background
});
var mesh2 = new THREE.Mesh(geometry, material);
cubeGroup.add(mesh2);
// add group to scene
scene.add(cubeGroup);
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate(now){
requestAnimationFrame(animate);
cubeGroup.rotation.y += (rotationX - cubeGroup.rotation.y) * 0.05;
cubeGroup.rotation.x += (rotationY - cubeGroup.rotation.x) * 0.05;
renderer.render(scene, camera);
}
function findViewCoords(mouseEvent)
{
var xpos;
var ypos;
var w = window.innerWidth;
var h = window.innerHeight;
var centerX = w/2;
var centerY = h/2;
if (mouseEvent)
{
xpos = mouseEvent.pageX - document.body.scrollLeft;
ypos = mouseEvent.pageY - document.body.scrollTop;
}
else
{
xpos = window.event.x + 2;
ypos = window.event.y + 2;
}
var diffX = xpos - centerX;
var diffY = ypos - centerY;
percentX = diffX / centerX;
percentY = diffY / centerY;
rotationX = percentX/2;
rotationY = percentY/2;
}
container.addEventListener("mousemove", findViewCoords);
body {
margin: 0;
padding: 0;
overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.js"></script>
<div id="container"></div>
The reason this happens is that rendering in three.js happens in 2 phases.
First solid stuff is rendered.. then transparent things.
The transparent objects are sorted by their distance from the camera.
So by setting your .transparent = true; you're making your text get rendered during the second pass, and thus render on top of the other geometry.
Check out this answer by the indomitable West Langley:
Transparent objects in Threejs
Currently trying to wrap images around a cube on three.js and getting the following error 'THREE.MeshFaceMaterial has been removed. Use an Array instead.', from previous searches it looks like the method I'm trying to use might not be available anymore, is there a new method that anyone knows of? I'll attach the code below. Any help would be greatly appreciated. Thanks in advance, Mike.
<script src="js/three.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/ParallaxBarrierEffect.js"></script>
<script>
(function(){var script=document.createElement('script');script.onload=function(){var stats=new Stats();document.body.appendChild(stats.dom);requestAnimationFrame(function loop(){stats.update();requestAnimationFrame(loop)});};script.src='//rawgit.com/mrdoob/stats.js/master/build/stats.min.js';document.head.appendChild(script);})()
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', function ()
{
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
});
//var effect = new THREE.ParallaxBarrierEffect(renderer);
//effect.setSize(window.innerWidth, window.innerHeight);
controls = new THREE.OrbitControls(camera, renderer.domElement)
/* var loader = new THREE.ObjectLoader();
loader.load
(
'models/skull.json',
function(object)
{
scene.add(object);
}
);
*/
var geometry = new THREE.CubeGeometry(10000,10000,10000);
var cubeMaterials =
[
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/right.png'), side: THREE.DoubleSide}), // RIGHT SIDE
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/left.png'), side: THREE.DoubleSide}), // LEFT SIDE
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/top.png'), side: THREE.DoubleSide}), // TOP SIDE
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/bottom.png'), side: THREE.DoubleSide}), // BOTTOM SIDE
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/front.png'), side: THREE.DoubleSide}), // FRONT SIDE
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/back.png'), side: THREE.DoubleSide}) // BACK SIDE
];
var cubeMaterial = new THREE.MeshFaceMaterial(cubeMaterials);
var cube = new THREE.Mesh(geometry, cubeMaterial);
scene.add(cube);
camera.position.z = 3;
var ambientLight = new THREE.AmbientLight(0xFFFFFF, 0.3);
scene.add(ambientLight);
var light1 = new THREE.PointLight(0xFF0040, 4, 5);
//scene.add(light1);
var light2 = new THREE.PointLight(0x0040FF, 2, 5);
//scene.add(light2);
var light3 = new THREE.PointLight(0x80FF80, 4, 5);
//scene.add(light3);
var directionalLight = new THREE.DirectionalLight(0xFFFFFF, 1);
directionalLight.position.set(0,1,0);
//scene.add(directionalLight);
var spotLight = new THREE.SpotLight(0xFF45F6, 200);
spotLight.position.set(0,3,3);
//scene.add(spotLight);
var update = function()
{
//cube.rotation.x += 0.01;
//cube.rotation.z += 0.005;
var time = Date.now() * 0.0005;
light1.position.x = Math.sin(time + 0.7) * 30;
light1.position.x = Math.cos(time + 0.5) * 40;
light1.position.x = Math.cos(time + 0.3) * 30;
light2.position.x = Math.cos(time + 0.3) * 30;
light2.position.x = Math.sin(time + 0.5) * 40;
light2.position.x = Math.sin(time + 0.7) * 30;
light3.position.x = Math.sin(time + 0.7) * 30;
light3.position.x = Math.cos(time + 0.3) * 40;
light3.position.x = Math.sin(time + 0.5) * 30;
};
var render = function()
{
renderer.render(scene, camera);
};
var GameLoop = function()
{
requestAnimationFrame(GameLoop);
update();
render();
};
GameLoop();
</script>
You can change the THREE.MeshFaceMaterial(cubeMaterials)for THREE.MeshBasicMaterial(cubeMaterials) if you are trying to create a skybox. However be aware that your perspective camera are rendering until 1000 and your box has 10000 units, so you will have to change your camera variable if you want to see the sky box.
I have a working animation, just not the way I would like.
I would like the object to rotate 90 degrees with a delay (works) then continue to rotate 90 degrees, ultimately looping forever. No matter what I do, it always resets. Even if I set up 4 tweens taking me to 360, the last tween that resets back zero makes the whole object spin in the opposite direction.
Thanks
var width = 1000;
var height = 600;
var scene = new THREE.Scene();
var group = new THREE.Object3D(); //create an empty container
var camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, -500, 1000);
camera.position.x = 180;
camera.position.y = 180;
camera.position.z = 200;
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.setClearColor(0xf0f0f0);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry(300, 300, 300);
var material = new THREE.MeshLambertMaterial({
color: 0xffffff,
shading: THREE.SmoothShading,
overdraw: 0.5
});
var cube = new THREE.Mesh(geometry, material);
group.add(cube);
var canvas1 = document.createElement('canvas');
canvas1.width = 1000;
canvas1.height = 1000;
var context1 = canvas1.getContext('2d');
context1.font = "Bold 20px Helvetica";
context1.fillStyle = "rgba(0,0,0,0.95)";
context1.fillText('Text bit', 500, 500);
// canvas contents will be used for a texture
var texture1 = new THREE.Texture(canvas1)
texture1.needsUpdate = true;
var material1 = new THREE.MeshBasicMaterial({
map: texture1,
side: THREE.DoubleSide
});
material1.transparent = true;
var mesh1 = new THREE.Mesh(
new THREE.PlaneBufferGeometry(2000, 2000),
material1
);
mesh1.position.set(-150, 150, 151);
group.add(mesh1);
directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 0, 0)
scene.add(directionalLight);
directionalLight = new THREE.DirectionalLight(0x888888);
directionalLight.position.set(0, 1, 0)
scene.add(directionalLight);
directionalLight = new THREE.DirectionalLight(0xcccccc);
directionalLight.position.set(0, 0, 1)
scene.add(directionalLight);
scene.add(group)
// with help from https://github.com/tweenjs/tween.js/issues/14
var tween = new TWEEN.Tween(group.rotation).to({ y: -(90 * Math.PI / 180)}, 1000).delay(1000);
tween.onComplete(function() {
group.rotation.y = 0;
});
tween.chain(tween);
tween.start();
camera.lookAt(scene.position);
var render = function() {
requestAnimationFrame(render);
TWEEN.update();
renderer.render(scene, camera);
};
render();
=====EDIT=====
I got it working, not sure if this is the most efficient approach but I'm satisfied:
var start = {}
start.y = 0;
var targ = {};
targ.y = 90*Math.PI/180
function rot(s,t) {
start["y"] = s;
targ["y"] = t;
}
var cnt1 = 1;
var cnt2 = 2;
rot(0,90*Math.PI/180);
var tween = new TWEEN.Tween(start).to(targ, 1000).delay(1000);
tween.onUpdate(function() {
group.rotation.y = start.y;
})
tween.onComplete(function() {
_c = cnt1++;
_d = cnt2++;
rot((_c*90)*Math.PI/180,(_d*90)*Math.PI/180)
});
tween.chain(tween);
tween.start();
Simple call setTimeout when tween is end
( http://jsfiddle.net/bhpf4zvy/ ):
function tRotate( obj, angles, delay, pause ) {
new TWEEN.Tween(group.rotation)
.delay(pause)
.to( {
x: obj.rotation._x + angles.x,
y: obj.rotation._y + angles.y,
z: obj.rotation._z + angles.z
}, delay )
.onComplete(function() {
setTimeout( tRotate, pause, obj, angles, delay, pause );
})
.start();
}
tRotate(group, {x:0,y:-Math.PI/2,z:0}, 1000, 500 );
Upd: pfff, what nonsense am I??? Simple use relative animation (http://jsfiddle.net/vv06u6rs/7/):
var tween = new TWEEN.Tween(group.rotation)
.to({ y: "-" + Math.PI/2}, 1000) // relative animation
.delay(1000)
.onComplete(function() {
// Check that the full 360 degrees of rotation,
// and calculate the remainder of the division to avoid overflow.
if (Math.abs(group.rotation.y)>=2*Math.PI) {
group.rotation.y = group.rotation.y % (2*Math.PI);
}
})
.start();
tween.repeat(Infinity)