Scripting Helpers is winding down operations and is now read-only. More info→
← Blog Home

Exploring the CFrame API

Exploring the CFrame API

If you have read our latest blog post on CFrames you might also have noticed that the roblox wiki says that there are some API functions which we can also explore. These will help you to make hard equations simple - but that will only work if you know what actually is happening. The equations themselves may look pretty advanced and confusing, but if you know what the functions return you can picture what happens and use them in the right places.

This is the list of API functions we are going to discuss:

  • CFrame:inverse()
  • CFrame:toWorldSpace(cf)
  • CFrame:toObjectSpace(cf)
  • CFrame:pointToWorldSpace(v3)
  • CFrame:pointToObjectSpace(v3)
  • CFrame:vectorToWorldSpace(v3)
  • CFrame:vectorToObjectSpace(v3)
  • CFrame:components()

What you probably have noticed is the term WorldSpace and ObjectSpace. Let’s take a look what they mean. To make it more simple we first look at how we could represent World and Object Space in Vectors. A vector is used in a CFrame (you can get it via CFrame.p which represents the position of that CFrame).

You can define a vector as something which has started in (0,0,0) but is currently in another point - the vector itself is the line between those points. We define this World Space. In some cases it is necessary to only find local offsets to other points (vectors). For example, if you have a model placed somewhere with some bricks in it, you will probably use the local offsets to eachother. This is called ObjectSpace. If you have a Model located on (20,22,24) and a part located on (21,22,24) then the offset of this part to the model is (1,0,0) - in other words, Part position - Model position. If you want to convert this Object Space vector to World space, you will need the center of the world object - in this case, the Model. The position is then part position + offset position.

This is something you also can do with CFrames. CFrame:toObjectSpace(cf) basically returns the offset from CFrame to cf, thus CFrame - cf. This returns an offset (Object Space) CFrame in which goes that:

x * x:toObjectSpace(y)= y

As normal equation we would write this as following:

x + offset = y

offset = -x + y

But how do you write a negative CFrame? As you know, adding two CFrames has to go via multiplication because it has a rotation matrix. If you want to create an unary, or actually: the inverse CFrame! Therefore, you use the :inverse() method of CFrames to create the inverse of that CFrame. In other words, x:toObjectSpace(y) can be written as:

x:inverse() * y

Therefore, x * x:inverse() == CFrame.new()(basically the "zero" CFrame)

CFrame:toWorldSpace(cf) basically returns a CFrame from the offset CFrame to cf, thus offset + cf. This can be written as CFrame * cf - something you normally use. Note that cf is your offset CFrame. We explained this in our last post too, to think in offsets when working with CFrames.

Note, that with CFrames, rotation is also a property of them! Converting CFrames to object space therefore also takes rotation into account. If you can’t picture this very well, then you could also think of it like this. You start at a brick with a random rotation and you want to go to another brick. You then have to move x studs forward/backward, y studs to the left/right and z studs down/up. You also need to rotate a little bit. These actions which you do can all be written as an Object Space CFrame: this holds both the change of position and the change of rotation.

Now that you understand what Object Space and World Space is, we can look at the other methods which we havent discussed yet.

Offset

Let’s take a look at the methods which use a point. Their associated methods use the rotation matrix, though. If you use CFrame:pointToWorldSpace(v3) then a Vector3 is returned. If you create a CFrame which uses this Vector3 as position and the Rotation Matrix from the original CFrame, the offset between those CFrames is the Vector3. Looking from the CFrame, it will appear as -Vector3 though, because the viewpoint of the CFrame is the lookVector, which is actually the negative z axis. This is explained in the previous blog post.

CFrame:pointToObjectSpace(v3) returns the offset vector between those two points. Look at the picture below here:

Offsets

The offset vector is showed as the red line.

The remaining method we need to inspect is the vector. In the case of a point, the vector returned had a certain offset from the CFrame. In the case of the vector, the returned vector basically is the same, but now uses (0,0,0) as start offset. The ObjectSpace method returns the offset between the CFrame and (0,0,0) which again uses the rotation matrix.

This picture shows the difference between using the point or the vector method:

Difference

Posted in Scripting Tips

Commentary

Leave a Comment

adark says: April 24, 2014
CFrame.new() is an empty CFrame, yes, but it is not a "zero" CFrame. A more accurate term is to call it a "one" CFrame. 1/x * x = 1, not 0.