matrix – Shifting the world origin and scaling all points?

Imagine you have a simulation in very large coordinates, and to render it out you need to scale it down (say, solar system -> fitting inside a few thousand units). This is controlled by a float multiplier that you can increase/decrease at runtime.

Additionally, imagine that you have a point in space that can move around, which acts as a kind of “shifted origin”, such that objects near that point will be rendered as if they’re near the true origin (0,0,0). In this ‘example’, that may be the player/camera position.

The idea is to allow that ‘scaleFactor’ to scale up/down the world around that point, e.g. if this shifted origin point is at (1000, 1000) (it’s 3D but assume z=0 for convenience), and there are four objects equidistant around it each 500 units away along one or both axes (i.e. (1500, 1500), (500, 1500), etc), then they should be rendered around the true origin (0,0,0) 500 units away, and should move towards/away from it as that scale factor changes.

I can get the objects around the origin, but the scale increasing/decreasing shows the objects either moving to the shifted world origin (i.e. scaling around (1000, 1000)), or to the inverse (-1000, -1000).

Note: this shifted origin point itself is not in render scale – i.e. it is in the ‘simulation scale’ so you could decide to do something like “shift and scale the solar system around planet X’s position in the simulation”.

So we need to:

  • Translate all positions by this shiftPos (‘worldOrigin) to get them around the render origin (0,0,0)
  • Scale by renderScale so they fit within our renderable scene
  • Draw and/or profit

I tried, foreach obj:

// basePos is glm::dvec3
// renderScale is a float

const glm::dvec3 shifted = glm::translate(-worldOrigin) * glm::dvec4(basePos, 1.0);
const glm::dvec3 scaled = glm::scale(glm::dvec3(renderScale)) * glm::dvec4(shifted, 1.0);

// draw using 'scaled' as position for obj

Here is the result, where green sphere is (0,0,0), red sphere is this ‘worldOrigin’ / shiftPos, i.e. (1000, 1000, 0) in the above example, and the white spheres are the objects that ‘should’ be scaling around green. (Ignore the blue sphere and the text – was a leftover). Shown is what happened when I pushed the scale down such that the translation of each white sphere was very small – they converged on -worldOrigin (inverse of red), and when I started increasing the scale, they moved towards and past the red. I am unsure of how to get them to scale centered around green (expand/retract out/in to it).


enter image description here