# xeogl / API Docs

API Docs for: 1.0.0

# File: src/math/mathRays.js

```/**
* Ray casting support functions.
*/
(function () {

"use strict";

var math = xeogl.math;

/**
Transforms a Canvas-space position into a World-space ray, in the context of a Camera.
@method canvasPosToWorldRay
@static
@param {Camera} camera The Camera.
@param {Float32Array} canvasPos The Canvas-space position.
@param {Float32Array} worldRayOrigin The World-space ray origin.
@param {Float32Array} worldRayDir The World-space ray direction.
*/
math.canvasPosToWorldRay = (function () {

var tempMat4b = math.mat4();
var tempMat4c = math.mat4();
var tempVec4a = math.vec4();
var tempVec4b = math.vec4();
var tempVec4c = math.vec4();
var tempVec4d = math.vec4();

return function (camera, canvasPos, worldRayOrigin, worldRayDir) {

var canvas = camera.scene.canvas.canvas;

var viewMat = camera.view.matrix;
var projMat = camera.project.matrix;

var pvMat = math.mulMat4(projMat, viewMat, tempMat4b);
var pvMatInverse = math.inverseMat4(pvMat, tempMat4c);

// Calculate clip space coordinates, which will be in range
// of x=[-1..1] and y=[-1..1], with y=(+1) at top

var canvasWidth = canvas.width;
var canvasHeight = canvas.height;

var clipX = (canvasPos[0] - canvasWidth / 2) / (canvasWidth / 2);  // Calculate clip space coordinates
var clipY = -(canvasPos[1] - canvasHeight / 2) / (canvasHeight / 2);

tempVec4a[0] = clipX;
tempVec4a[1] = clipY;
tempVec4a[2] = -1;
tempVec4a[3] = 1;

math.transformVec4(pvMatInverse, tempVec4a, tempVec4b);
math.mulVec4Scalar(tempVec4b, 1 / tempVec4b[3]);

tempVec4c[0] = clipX;
tempVec4c[1] = clipY;
tempVec4c[2] = 1;
tempVec4c[3] = 1;

math.transformVec4(pvMatInverse, tempVec4c, tempVec4d);
math.mulVec4Scalar(tempVec4d, 1 / tempVec4d[3]);

worldRayOrigin[0] = tempVec4d[0];
worldRayOrigin[1] = tempVec4d[1];
worldRayOrigin[2] = tempVec4d[2];

math.subVec3(tempVec4d, tempVec4b, worldRayDir);

math.normalizeVec3(worldRayDir);
};
})();

/**
Transforms a Canvas-space position to an Entity's Local-space coordinate system, in the context of a Camera.
@method canvasPosToLocalRay
@static
@param {Camera} camera The Camera.
@param {Entity} entity The Entity.
@param {Float32Array} canvasPos The Canvas-space position.
@param {Float32Array} localRayOrigin The Local-space ray origin.
@param {Float32Array} localRayDir The Local-space ray direction.
*/
math.canvasPosToLocalRay = (function () {

var worldRayOrigin = math.vec3();
var worldRayDir = math.vec3();

return function (camera, entity, canvasPos, localRayOrigin, localRayDir) {
math.canvasPosToWorldRay(camera, canvasPos, worldRayOrigin, worldRayDir);
math.worldRayToLocalRay(entity, worldRayOrigin, worldRayDir, localRayOrigin, localRayDir);
};
})();

/**
Transforms a ray from World-space to an Entity's Local-space coordinate system.
@method worldRayToLocalRay
@static
@param {Entity} entity The Entity.
@param {Float32Array} worldRayOrigin The World-space ray origin.
@param {Float32Array} worldRayDir The World-space ray direction.
@param {Float32Array} localRayOrigin The Local-space ray origin.
@param {Float32Array} localRayDir The Local-space ray direction.
*/
math.worldRayToLocalRay = (function () {

var tempMat4 = math.mat4();
var tempVec4a = math.vec4();
var tempVec4b = math.vec4();

return function (entity, worldRayOrigin, worldRayDir, localRayOrigin, localRayDir) {

var modelMat = entity.transform.leafMatrix;
var modelMatInverse = math.inverseMat4(modelMat, tempMat4);

tempVec4a[0] = worldRayOrigin[0];
tempVec4a[1] = worldRayOrigin[1];
tempVec4a[2] = worldRayOrigin[2];
tempVec4a[3] = 1;

math.transformVec4(modelMatInverse, tempVec4a, tempVec4b);

localRayOrigin[0] = tempVec4b[0];
localRayOrigin[1] = tempVec4b[1];
localRayOrigin[2] = tempVec4b[2];

math.transformVec3(modelMatInverse, worldRayDir, localRayDir);
};
})();
})();
```