Rotation around an axis three.js - three.js

I'm using three.js Revision 69 and i've got a problem rotating objects around global axis.
I've found on many website the function rotateAroundWorldAxis defined as follow:
function rotateAroundWorldAxis( object, axis, radians ) {
var rotationMatrix = new THREE.Matrix4();
rotationMatrix.makeRotationAxis( axis.normalize(), radians );
rotationMatrix.multiply( object.matrix ); // pre-multiply
object.matrix = rotationMatrix;
object.rotation.setFromRotationMatrix(object.matrix);
}
I've called rotateAroundWorldAxis in my render function like that:
function render() {
var yAxis = new THREE.Vector3(0,1,0);
rotateAroundWorldAxis(albero,yAxis,Math.PI / 180);
requestAnimationFrame( render );
renderer.render( scene, camera );
}
But the result is always the same, the object is rotating around his own axis, I've obtained the same result using another function found on the web: rotateAroundObjectAxis
var rotObjectMatrix;
function rotateAroundObjectAxis(object, axis, radians) {
rotObjectMatrix = new THREE.Matrix4();
rotObjectMatrix.makeRotationAxis(axis.normalize(), radians);
object.matrix.multiply(rotObjectMatrix);
object.rotation.setFromRotationMatrix(object.matrix);
}
Could someone please help me finding out what is wrong with my code? Why those two function are achieving the same result even if they were made for different purposes?
The full javascript is:
function drawStuff() {
var albero = new THREE.Object3D();
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var cone = createCone(0, 0, 0); //create cone of the tree
var cylinder = createCylinder(0, -1.1, 0); //create cylinder of the tree
albero = createAlbero(-4, 2, 3);
scene.add(albero);
var axisHelper = new THREE.AxisHelper( 5 );
scene.add( axisHelper );
camera.position.z = 20;
function createCone(x, y, z){
var coneGeometry = new THREE.CylinderGeometry(0.0, 0.7, 2, 32, 32);
var coneMaterial = new THREE.MeshBasicMaterial( {color: 0xFF0000} );
var cone = new THREE.Mesh( coneGeometry, coneMaterial );
cone.position.set(x, y, z);
return cone;
}
function createCylinder(x, y, z){
var cylGeometry = new THREE.CylinderGeometry(0.1, 0.1, 0.4, 32, 32);
var cylinderMaterial = new THREE.MeshBasicMaterial( {color: 0xffff00} );
var cylinder = new THREE.Mesh( cylGeometry, cylinderMaterial );
cylinder.position.set(x, y, z);
return cylinder;
}
function createAlbero(x ,y, z){
albero.add(cone);
albero.add(cylinder);
albero.position.set(x ,y, z);
return albero;
}
var rotObjectMatrix;
function rotateAroundObjectAxis(object, axis, radians) {
rotObjectMatrix = new THREE.Matrix4();
rotObjectMatrix.makeRotationAxis(axis.normalize(), radians);
//moltiplico la matrice dell'oggetto per la matrice di rotazione
object.matrix.multiply(rotObjectMatrix);
object.rotation.setFromRotationMatrix(object.matrix);
}
function rotateAroundWorldAxis( object, axis, radians ) {
var rotationMatrix = new THREE.Matrix4();
rotationMatrix.makeRotationAxis( axis.normalize(), radians );
rotationMatrix.multiply( object.matrix ); // pre-multiply
object.matrix = rotationMatrix;
object.rotation.setFromRotationMatrix(object.matrix);
}
function render() {
var yAxis = new THREE.Vector3(30,50,1);
rotateAroundWorldAxis(cone2,yAxis,Math.PI / 180);
requestAnimationFrame( render );
renderer.render( scene, camera );
}
render();
}

If I am correct in understanding your intent, you are interested in rotating your objects about a specified axis, which essentially would set them moving around in a circle.
This is actually more about the positioning of the objects as opposed to the orientation (read: rotation) of the object. Therefore, it might be better to write a function that would manually set the position of the object based on the rotation that you are interested in.
function rotateAboutWorldAxis(object, axis, angle) {
var rotationMatrix = new THREE.Matrix4();
rotationMatrix.makeRotationAxis( axis.normalize(), angle );
var currentPos = new THREE.Vector4(object.position.x, object.position.y, object.position.z, 1);
var newPos = currentPos.applyMatrix4(rotationMatrix);
object.position.x = newPos.x;
object.position.y = newPos.y;
object.position.z = newPos.z;
}
Try that, and let me know if that works for you.

I've found another way to rotate around world axis, using a function called "rotateEuler"
function rotateEuler(object, eul) {
object.position.applyEuler(eul);
}
Here is the call to the function:
var alberoRot= new THREE.Euler(0,0.02,0, "XYZ");
rotateEuler(albero,earthRot);

Related

Create Rope in Three.js using Physics from Ammo.js or Cannon.js

I have been trying to create in three.js a rope hanging from a point using any of the 3D physics libraries (ammo.js, cannon.js), but the only one I have successfully done is with (2D)verlet.js.
I really need and want to create it in 3D because I need two ropes attached to a midpoint so that I can show the instability of the midpoint as a load is applied. Something similar as the attached image.
enter image description here
To be honest, I have not idea how to start, I have some experience with Three.js, but non with ammo.js or cannon.js. So far I have been trying to understand the codes for the examples in these links with not success.
http://schteppe.github.io/cannon.js/demos/constraints.html
https://threejs.org/examples/#webgl_physics_rope
I even tried to make a rope using spring function from cannon.js, but you can see that my example is not success.
Can somebody please help me or guide me into the correct way to begin my task?
This is the Code I began to write using Cannon.js:
function initCannon()
{
world = new CANNON.World();
world.gravity.set(.2,-10,.2);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 10;
var mass = 1;
var damping = 1;
// STATIC SPHERE
var sphereShape = new CANNON.Sphere(new CANNON.Vec3(1,1,1));
mass = 0;
sphereBody = new CANNON.Body({ mass: 0 });
sphereBody.addShape(sphereShape);
sphereBody.position.set(.5,8,.5);
world.addBody(sphereBody);
// DINAMIC SPHERE 1
var shape = new CANNON.Sphere(new CANNON.Vec3(1,1,1));
body = new CANNON.Body({ mass: 1 });
body.addShape(shape);
body.angularDamping = damping;
body.position.set(0,8,0);
world.addBody(body);
// DINAMIC SPHERE 2
var shape2 = new CANNON.Sphere(new CANNON.Vec3(1,1,1));
body2 = new CANNON.Body({ mass: 1 });
body2.addShape(shape2);
body2.angularDamping = damping;
body2.position.set(0,8,0);
world.addBody(body2);
// DINAMIC SPHERE 3
var shape3 = new CANNON.Sphere(new CANNON.Vec3(1,1,1));
body3 = new CANNON.Body({ mass: 1 });
body3.addShape(shape3);
body3.angularDamping = damping;
body3.position.set(0,8,0);
world.addBody(body3);
var size = 1;
var rebote = 1;
var spring = new CANNON.Spring(body,sphereBody,{
localAnchorA: new CANNON.Vec3(0,size,0),localAnchorB: new CANNON.Vec3(0,0,0),
restLength : 0, stiffness : 50, damping : rebote, });
var spring2 = new CANNON.Spring(body2, body,{
localAnchorA: new CANNON.Vec3(0,size,0),localAnchorB: new CANNON.Vec3(0,0,0),
restLength : 0, stiffness : 50, damping : rebote, });
var spring3 = new CANNON.Spring(body3, body2,{
localAnchorA: new CANNON.Vec3(0,size,0),localAnchorB: new CANNON.Vec3(0,0,0),
restLength : 0, stiffness : 50, damping : rebote, });
world.addEventListener("postStep",function(event){ spring.applyForce(); });
world.addEventListener("postStep",function(event){ spring2.applyForce(); });
world.addEventListener("postStep",function(event){ spring3.applyForce(); });
}
function initThree()
{
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 100 );
camera.position.y = 3;camera.position.z = 15;
scene.add( camera );
controls = new THREE.TrackballControls( camera );
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
var material_wire = new THREE.MeshBasicMaterial( { color: 0xFFFFFF, wireframe: true } );
var sphere_size = .8;
var segmentos = 5;
geometry_sphere = new THREE.SphereGeometry( sphere_size, segmentos, segmentos );
sphere = new THREE.Mesh( geometry_sphere, material_wire );
scene.add( sphere );
geometry = new THREE.SphereGeometry( sphere_size, segmentos,segmentos ); // RRT DEFINE TAMANO DE CUBE
mesh = new THREE.Mesh( geometry, material_wire );
scene.add( mesh );
mesh2 = new THREE.Mesh( geometry, material_wire );
scene.add( mesh2 );
mesh3 = new THREE.Mesh( geometry, material_wire );
scene.add( mesh3 );
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
updatePhysics();
render();
}
function updatePhysics() {
// Step the physics world
world.step(timeStep);
sphere.position.copy(sphereBody.position);
mesh.position.copy(body.position); // HACE QUE SE VEA
mesh2.position.copy(body2.position);
mesh3.position.copy(body3.position);
}
function render() {
renderer.render( scene, camera );
}

Cannonjs and THREE.js one unit off

Hey guys I am trying to make a simple 3js and cannon js demo, it is done except for the fact that it appears that there is a one unit off.
https://www.dropbox.com/s/qqaal0hgq9a506e/Screenshot%202014-10-01%2022.17.47.png?dl=0
function initCannonWorld() {
world = new CANNON.World();
world.gravity.set(0,-9.8,0);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 10;
}
function addBodyToCannonWorld() {
shape = new CANNON.Box(new CANNON.Vec3(1,1,1));
body = new CANNON.Body({
mass: 5
});
body.position.set(0,10,0);
body.addShape(shape);
//body.angularVelocity.set(0,10,0);
//body.angularDamping = 0.5;
world.addBody(body);
}
function initCannon() {
initCannonWorld();
addBodyToCannonWorld();
addPlaneBodyToWorld();
}
function initThreeScene() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 100 );
camera.position.z = 25;
camera.lookAt(new THREE.Vector3(0,0,0));
scene.add( camera );
// add orbit around where camera is targeting is pointing
oribitalControl = new THREE.OrbitControls(camera);
// Listen to the change event.
oribitalControl.addEventListener("change",render);
// Change to canvas for triangles lines.
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function addPlaneToWorld() {
planeGeo = new THREE.BoxGeometry(20,1,20,2,1,2);
planeMat = new THREE.MeshBasicMaterial({ color: 0x3498db, wireframe:true});
plane = new THREE.Mesh(planeGeo, planeMat);
scene.add( plane );
}
function addPlaneBodyToWorld() {
var planeShape = new CANNON.Box(new CANNON.Vec3(20,1,20));
// Mass 0 makes a body static.
planeBody = new CANNON.Body({mass:0});
planeBody.addShape(planeShape);
world.addBody(planeBody);
}
function addMeshToWorld() {
geometry = new THREE.BoxGeometry( 1, 1, 1 );
material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe:true} );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
}
function initThree() {
initThreeScene();
addMeshToWorld();
addPlaneToWorld();
}
function run() {
requestAnimationFrame(run);
oribitalControl.update();
updatePhysics();
render();
}
function updatePhysics() {
// Step the physics world
world.step(timeStep);
mesh.position.copy(body.position);
mesh.quaternion.copy(body.quaternion);
plane.position.copy(planeBody.position);
plane.quaternion.copy(planeBody.quaternion);
}
function render() {
renderer.render( scene, camera );
}
CANNON.Box takes half extents as argument, while THREE.BoxGeometry takes full extents. Double the dimensions of your Three.js boxes or halve the dimensions of the Cannon.js boxes, and they will visually match.
...
var planeShape = new CANNON.Box(new CANNON.Vec3(20,1,20));
...
planeGeo = new THREE.BoxGeometry(2*20, 2*1, 2*20, 2, 1, 2);
...

Three.js Raycasting with Camera as Origin

I'm trying to determine whether a point in space is visible to the camera or hidden behind other objects in the scene. I'm doing this by casting a ray from the position of the camera to that point in space and testing if that ray is intersected by an set of intersectable objects.
My problem is no intersections occur until the camera position itself intersects one of the objects in the set of intersectable objects.
I've created a jsfiddle in which, if an intersection is detected, a line is drawn from the camera position to the position in space i'm testing for visibility. Currently I believe, the line is only draw at specific points where the camera position intersects the set of intersectable objects.
How do I get the intersections to be registered as they should be, without having to have the camera position intersect objects in the set of intersectable objects?
the code:
var container;
var camera, controls, scene, renderer;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
controls = new THREE.OrbitControls(camera);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [65, 83, 68];
controls.addEventListener('change', render);
// world
scene = new THREE.Scene();
var testObject_G = new THREE.CubeGeometry(100, 100, 5);
var testObject_M = new THREE.MeshBasicMaterial({
color: 0xBBBBBB
});
var testObject_Mesh = new THREE.Mesh(testObject_G, testObject_M);
testObject_Mesh.position.x = -150;
scene.add(testObject_Mesh);
var testObject_Mesh2 = new THREE.Mesh(testObject_G, testObject_M);
testObject_Mesh2.position.x = 0;
scene.add(testObject_Mesh2);
var testObject_Mesh3 = new THREE.Mesh(testObject_G, testObject_M);
testObject_Mesh3.position.x = 150;
scene.add(testObject_Mesh3);
scene2 = new THREE.Object3D();
// renderer
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff, 1);
container = document.getElementById('container');
container.appendChild(renderer.domElement);
//
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
controls.handleResize();
render();
}
function animate() {
requestAnimationFrame(animate);
controls.update();
}
function render() {
renderer.render(scene, camera);
castRays();
}
function castRays() {
// rays
var direction = new THREE.Vector3(0, 200, -200);
var startPoint = camera.position.clone();
var ray = new THREE.Raycaster(startPoint, direction);
scene.updateMatrixWorld(); // required, since you haven't rendered yet
var rayIntersects = ray.intersectObjects(scene.children, true);
if (rayIntersects[0]) {
console.log(rayIntersects[0]);
var material = new THREE.LineBasicMaterial({
color: 0x0000ff
});
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(ray.ray.origin.x, ray.ray.origin.y, ray.ray.origin.z));
geometry.vertices.push(new THREE.Vector3(ray.ray.direction.x, ray.ray.direction.y, ray.ray.direction.z));
var line = new THREE.Line(geometry, material);
scene2.add( line );
}
scene.add(scene2);
}
Thank you
For anyone currently seeing this thread, THREE.Projector has been replaced.
Three.js THREE.Projector has been moved to
The code below handles a 3D vector. If you go to the link above, the first commenter provided the code for a 2D vector.
var vector = new THREE.Vector3();
var raycaster = new THREE.Raycaster();
var dir = new THREE.Vector3();
...
if ( camera instanceof THREE.OrthographicCamera ) {
vector.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, - 1 ); // z = - 1 important!
vector.unproject( camera );
dir.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
raycaster.set( vector, dir );
} else if ( camera instanceof THREE.PerspectiveCamera ) {
vector.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 ); // z = 0.5 important!
vector.unproject( camera );
raycaster.set( camera.position, vector.sub( camera.position ).normalize());
}
var intersects = raycaster.intersectObjects( objects, recursiveFlag );`
Your idea of casting a ray is good, however raycasting in three.js already does this :
mouse.x = ( ( event.clientX - renderer.domElement.offsetLeft ) / renderer.domElement.width ) * 2 - 1;
mouse.y = - ( ( event.clientY - renderer.domElement.offsetTop ) / renderer.domElement.height ) * 2 + 1;
this formula maps a pixel coordinate from Screen Space to a point in Normalized Device Coordinate ( NDC ) Space.
projector.unprojectVector( vector, camera );
maps a point from NDC Space to a point in World space
Raycaster then creates a ray from the camera position through that world point.
Here is your working Fiddle in which I changed the way of raycasting in your scene and this works, all you have to do now is creating a ray with the right coordinates that I provided you.
r.68

Physijs object goes through concaveMesh

I've a problem that seems to be known: my "bounding" object doesn't collide with "floor" concaveMesh.
I already read that this issue could be caused by an error in scaling concaveMesh together with the model, so I exported my floor model scaled as I need it and after I applied a concaveMesh (as follow) but it doesn't work.
I red this: https://github.com/chandlerprall/Physijs/issues/102 and a lot of other things about this topic (Physijs Load model three.js collisions don't work and a similar) and I made the following code but nothing to do :(
I really don't understand why "bounding" goes through the floor.
Here my code:
Physijs.scripts.worker = './libs/chandlerprall-Physijs-7e3837b/physijs_worker.js';
Physijs.scripts.ammo = './examples/js/ammo.js';
var gravityVector = new THREE.Vector3( 0, -100, 0 );
//renderer
var renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setClearColor(0xffffff, 0);
renderer.setSize( window.innerWidth, window.innerHeight );
//canvas
var canvas = renderer.domElement;
canvas.setAttribute("width", window.innerWidth);
canvas.setAttribute("height", window.innerHeight);
document.body.appendChild( canvas );
var perspectiveCamera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight, 1, 200000);
//scene
var rttScene = new Physijs.Scene();
var bounding = new Physijs.SphereMesh(new THREE.SphereGeometry(100, 100, 100),
Physijs.createMaterial(
new THREE.MeshBasicMaterial({color: '#ff0000'}),
1.0, // friction
0.0 // restitution
),50 //mass
);
bounding.position.set(200,1200,-5000);
loader.load("http://0.0.0.0:8000/Models/Isola/pavimento.js", function( geometry, materials){
var groundMaterial = Physijs.createMaterial(new THREE.MeshFaceMaterial(materials),
0.8, // friction
0.2 // restitution
);
floor = new Physijs.ConcaveMesh(geometry,groundMaterial,0);
floor.name = "pavimento";
rttScene.add(floor);
initScene();
render();
});
function initScene() {
rttScene.setGravity(gravityVector);
rttScene.add(envModel);
rttScene.add(bounding);
bounding.setAngularFactor(new THREE.Vector3(0, 0, 0));
bounding.setCcdMotionThreshold( 0.1 );
bounding.setCcdSweptSphereRadius( 1 );
var ambientLight = new THREE.AmbientLight(0xD9B775 );
rttScene.add(ambientLight);
var directionalLight = new THREE.DirectionalLight(0xc7af81);
directionalLight.target.position.copy( rttScene.position );
directionalLight.position.set(-550,1950,1950).normalize();
directionalLight.intensity = 0.7;
rttScene.add(directionalLight);
perspectiveCamera.position.set(200,1200,-3000);
perspectiveCamera.lookAt(bounding.position);
}
function render() {
requestAnimationFrame(render);
renderer.clear();
rttScene.simulate();
renderer.render(rttScene, perspectiveCamera);
}
I also tried this into render() function:
var originPoint = bounding.position.clone();
var ray = new THREE.Raycaster(originPoint, new THREE.Vector3(0, -1, 0));
var collisionResults = ray.intersectObjects(rttScene.children)
if (collisionResults.length > 0) {
console.log(collisionResults[0].distance);
}
In console i can read the distance between "bounding" and "floor". This should mean that floor exist as a collider but it doesn't stop bounding from falling. Why?

Three.js Rotate Texture

I have a texture applied to a mesh I can change the offset with
mesh.material.map.offset.set
I can change the scaling with
mesh.material.repeat.set
so my question is, how can I rotate texture inside a plane?
Example:
From This:
To this
Thanks.
use 2D canvas as a texture
demo:
https://dl.dropboxusercontent.com/u/1236764/temp/stackoverflow_20130525/index.html
example code
var camera, scene, renderer, mesh;
var width = window.innerWidth;
var height = window.innerHeight;
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 30, width / height, 1, 1000 );
camera.position.z = 100;
renderer = new THREE.WebGLRenderer();
renderer.setSize( width, height );
document.body.appendChild( renderer.domElement );
var img = new Image();
img.onload = createMeshThenRender;
img.src = 'img.jpg';
function createMeshThenRender () {
var imgWidth = imgHeight = 256;
var mapCanvas = document.createElement( 'canvas' );
mapCanvas.width = mapCanvas.height = 256;
// document.body.appendChild( mapCanvas );
var ctx = mapCanvas.getContext( '2d' );
ctx.translate( imgWidth / 2, imgHeight / 2 );
ctx.rotate( Math.PI / 4 );
ctx.translate( -imgWidth / 2, -imgHeight / 2 );
ctx.drawImage( img, 0, 0, imgWidth, imgHeight );
var texture = new THREE.Texture( mapCanvas );
texture.needsUpdate = true;
mesh = new THREE.Mesh(
new THREE.PlaneGeometry( 50, 50, 1, 1 ),
new THREE.MeshBasicMaterial( {
map : texture
} )
);
scene.add( mesh );
renderer.render( scene, camera );
}
three.js does not have a UV editing utility, so you either have to edit the geometry.faceVertexUvs manually, or rotate your image in an image editing program. I'd suggest the latter.
three.js r.58
three.js r85
For those looking to actually "rotate UVs" on a Plane sitting in XY plane (default plane) using a ShapeBufferGeometry or PlaneBufferGeometry.
var planeGeo = new THREE.PlaneBufferGeometry(24,24);
var planeMesh = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({map: yourTexture}));
scene.add(planeMesh);
rotateUVonPlanarBufferGeometry(45, planeMesh);
function rotateUVonPlanarBufferGeometry(rotateInDeg, mesh){
if(rotateInDeg != undefined && mesh){
var degreeInRad = THREE.Math.degToRad(rotateInDeg);
var tempGeo = mesh.geometry.clone();
var geo;
if(tempGeo instanceof THREE.BufferGeometry){
geo = new THREE.Geometry().fromBufferGeometry(tempGeo);
}else{
console.log('regular geometry currently not supported in this method, but can be if code is modified, so use a buffer geometry');
return;
}
// rotate the geo on Z-axis
// which will rotate the vertices accordingly
geo.applyMatrix(new THREE.Matrix4().makeRotationZ(degreeInRad));
// loop through the vertices which should now have been rotated
// change the values of UVs based on the new rotated vertices
var index = 0;
geo.vertices.forEach(function(v){
mesh.geometry.attributes.uv.setXY( index, v.x, v.y );
index++;
});
mesh.geometry.attributes.uv.needsUpdate = true;
}
}
three.js r121
In the newer version of the three.js, you can directly set rotation and rotation center of texture.
var texture = new THREE.Texture( ... );
texture.rotation = Math.PI/4;
texture.center = new Vector2d(0.5, 0.5); // center of texture.
The above solutions were not good to me, a little bit old. That's simple solution worked for me (Three.js 125)
imgData = canvasCtx.getImageData(0, 0, canvasElement.width, canvasElement.height);
texture = new THREE.DataTexture( imgData.data, canvasElement.width, canvasElement.height, THREE.SRGB );
texture.rotation = Math.PI;
texture.center = new THREE.Vector2(0.5, 0.5); // center of texture.
mymaterial = new THREE.MeshBasicMaterial({
map: texture,
alphaTest: 0.5,
transparent: true,
side: THREE.DoubleSide,
});

Resources