# Object3D.localToLocal

**URL:** <https://discourse.threejs.org/t/object3d-localtolocal/51564>\
**Category:** Questions\
**Tags:** object3d, matrices, math, basis\
**Created:** [May 14, 2023, 8:09am UTC](https://discourse.threejs.org/t/object3d-localtolocal/51564 "2023-05-14T08:09:23Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![abernier](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/abernier/32/23939_2.png) [@abernier](https://discourse.threejs.org/u/abernier)\
**Post date:** [May 14, 2023, 8:09am UTC](https://discourse.threejs.org/t/object3d-localtolocal/51564/1 "2023-05-14T08:09:23Z")

</div>

`Object3D`’s `localToWorld` and `worldToLocal` methods are really handy shortcuts, when like me you’re too lazy/focus/stupid to deal with `.applyMatrix4` and `.matrixWorld`/`.matrixWorldInverse`\[1\].

And I was this morning: I wanted to express a vector vA of a meshA, in another meshB to obtain vB.

I didn’t want to think at all, so my brain ran to my best friend `.world/localToSomething`… Until I realize I didn’t care about the `"world"` part in the method name 😭

What I wanted was literally `.localToLocal`! But sadly there was no such method…

* * *

Or maybe not yet!

What about a such utility method:

```js
const _m1 = new THREE.Matrix4()

Object3D.prototype.localToLocal = function (v, obj) {
  this.updateWorldMatrix( true, false );
  obj.updateWorldMatrix( true, false );

  const objMatrixWorldInverse = _m1.copy(obj.matrixWorld).invert()
  return v.clone()
    .applyMatrix4(this.matrixWorld)
    .applyMatrix4(objMatrixWorldInverse);
};

```

or 2nd impl alternative (simpler thx to our best friends):

```js
Object3D.prototype.localToLocal = function (v, obj) {
  const v_world = this.localToWorld(v);
  return obj.worldToLocal(v_world);
};

```

in my case, I could then turn off the brain and just consume it with:

```js
const v_B = meshA.localToLocal(v_A, meshB)

```

* * *

> **TS version**
>
> ```plaintext
> declare module "three" {
> export interface Object3D {
> localToLocal: (v: THREE.Vector3, obj: THREE.Object3D) => THREE.Vector3;
> }
> }
> THREE.Object3D.prototype.localToLocal = function (v: THREE.Vector3, obj: THREE.Object3D) {
> const v_world = this.localToWorld(v);
> return obj.worldToLocal(v_world);
> };
> 
> ```

* * *

1. I even wrote a full [memo](https://github.com/abernier/abernier/blob/main/articles/three-spaces.md#b-any-world-descendant-object) on this, but was too lazy to read it again 😅

---

<div class="post-metadata">

**Author:** ![makc3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/makc3d/32/10452_2.png) [@makc3d](https://discourse.threejs.org/u/makc3d)\
**Post date:** [May 14, 2023, 12:07pm UTC](https://discourse.threejs.org/t/object3d-localtolocal/51564/2 "2023-05-14T12:07:16Z")

</div>

inb4 Object3D.prototype.rotateYBy90Degrees and .translateXBy10

Ig what Im saying is that not every function you can imagine needs to be a class method. Having something like

```js
function fromTo(obj1, obj2, vector) {
  return obj2.worldToLocal( obj1.localToWorld(vector) );
}

```

in your own code is not a crime 😅

---

<div class="post-metadata">

**Author:** ![abernier](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/abernier/32/23939_2.png) [@abernier](https://discourse.threejs.org/u/abernier)\
**Post date:** [May 14, 2023, 12:55pm UTC](https://discourse.threejs.org/t/object3d-localtolocal/51564/3 "2023-05-14T12:55:03Z")

</div>

Thank you, I get your point and it is true that last implementation is kinda trivial thx to `.localToWorld` and `worldToLocal`

But those 2 methods impls themselves are at least as simple/trivial [three.js/Object3D.js at 70cc4e192fe2ebd0bf8542a81c8c513d61984c58 · mrdoob/three.js · GitHub](https://github.com/mrdoob/three.js/blob/70cc4e192fe2ebd0bf8542a81c8c513d61984c58/src/core/Object3D.js#L248) and they are still there in the API though.

I’m saying that including some user-friendly methods is not a crime either 😅

Perhaps for someone experienced, `.localToLocal` or even `.localToWorld`/`.worldToLocal` shortcuts are totally useless, but maybe not for someone less experienced, like me

It’s probably also a matter of preference 🙂
