Skip to content

Commit

Permalink
Add Scene.opticalObjs
Browse files Browse the repository at this point in the history
  • Loading branch information
ricktu288 committed May 21, 2024
1 parent d619012 commit ed6ab00
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 21 deletions.
7 changes: 6 additions & 1 deletion simulator/js/Scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const DATA_VERSION = 5;
/**
* Represents the scene in this simulator.
* @class Scene
* @property {BaseSceneObj[]} objs - The objects (optical elements and/or decorations created by the user with "Tools") in the scene.
* @property {Array<BaseSceneObj>} objs - The objects (optical elements and/or decorations created by the user with "Tools") in the scene.
* @property {string} mode - The mode of the scene. Possible values: 'rays' (Rays), 'extended' (Extended Rays), 'images' (All Images), 'observer' (Seen by Observer).
* @property {number} rayModeDensity - The density of rays in 'rays' and 'extended' modes.
* @property {number} imageModeDensity - The density of rays in 'images' and 'observer' modes.
Expand Down Expand Up @@ -73,6 +73,11 @@ class Scene {
}
}

/** @property {Array<BaseSceneObj>} opticalObjs - The objects in the scene which are optical. If the user edits only the non-optical part of the scene, then the content of this array will not change. */
get opticalObjs() {
return this.objs.filter(obj => obj.constructor.isOptical);
}

/**
* The callback function when the entire scene or a resource (e.g. image) is loaded.
* @callback fromJSONCallback
Expand Down
14 changes: 7 additions & 7 deletions simulator/js/objs/BaseGrinGlass.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,16 +228,16 @@ class BaseGrinGlass extends BaseGlass {
*/
initRefIndex(ray) {
let obj_tmp;
for (let i = 0; i < this.scene.objs.length; i++) {
if ((this.scene.objs[i] instanceof BaseGrinGlass) && (scene.objs[i].isOnBoundary(ray.p1) || scene.objs[i].isInsideGlass(ray.p1))) {
for (let obj of this.scene.opticalObjs) {
if ((obj instanceof BaseGrinGlass) && (obj.isOnBoundary(ray.p1) || obj.isInsideGlass(ray.p1))) {
if (!obj_tmp) {
obj_tmp = {};
obj_tmp.p = scene.objs[i].shiftOrigin(scene.objs[i].p);
obj_tmp.fn_p = scene.objs[i].fn_p;
obj_tmp.fn_p_der_x = scene.objs[i].fn_p_der_x;
obj_tmp.fn_p_der_y = scene.objs[i].fn_p_der_y;
obj_tmp.p = obj.shiftOrigin(obj.p);
obj_tmp.fn_p = obj.fn_p;
obj_tmp.fn_p_der_x = obj.fn_p_der_x;
obj_tmp.fn_p_der_y = obj.fn_p_der_y;
} else {
obj_tmp = scene.objs[i].multRefIndex(obj_tmp);
obj_tmp = obj.multRefIndex(obj_tmp);
}
}
}
Expand Down
32 changes: 19 additions & 13 deletions simulator/js/simulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,13 @@ function draw_(skipLight, skipGrid) {
{
var i = mapped[j].index;
scene.objs[i].draw(ctx0.constructor == C2S ? canvasRenderer : canvasRenderer0, false, scene.objs[i] === mouseObj);
if (!skipLight)
{
const ret = scene.objs[i].onSimulationStart();

}

if (!skipLight) {
// Initialize the simulation (e.g. add the rays and reset the detector readings)
for (let obj of scene.opticalObjs) {
const ret = obj.onSimulationStart();
if (ret) {
if (ret.newRays) {
waitingRays.push(...ret.newRays);
Expand All @@ -153,6 +157,7 @@ function draw_(skipLight, skipGrid) {
}
}
}

}

if (!skipLight) {
Expand Down Expand Up @@ -210,6 +215,7 @@ function shootWaitingRays() {
var rpd;
var surfaceMergingObjs = [];

const opticalObjs = scene.opticalObjs;

if (scene.simulateColors) {
ctxLight.globalCompositeOperation = 'screen';
Expand All @@ -226,7 +232,7 @@ function shootWaitingRays() {
document.getElementById('forceStop').style.display = '';
document.getElementById('simulatorStatus').innerHTML = getMsg("ray_count") + shotRayCount + '<br>' + getMsg("total_truncation") + totalTruncation.toFixed(3) + '<br>' + getMsg("time_elapsed") + (new Date() - drawBeginTime) + '<br>';

draw(true, true); // Redraw the scene.objs to avoid outdated information (e.g. detector readings).
draw(true, true); // Redraw the opticalObjs to avoid outdated information (e.g. detector readings).
return;
}
if (isExporting && shotRayCount > exportRayCountLimit)
Expand Down Expand Up @@ -265,30 +271,30 @@ function shootWaitingRays() {
surfaceMergingObjs = []; // The objects whose surface is to be merged with s_obj
s_lensq = Infinity;
observed = false; // Whether waitingRays[j] is observed by the observer
for (var i = 0; i < scene.objs.length; i++)
for (var i = 0; i < opticalObjs.length; i++)
{
// Test whether scene.objs[i] intersects with the ray
s_point_temp = scene.objs[i].checkRayIntersects(waitingRays[j]);
// Test whether opticalObjs[i] intersects with the ray
s_point_temp = opticalObjs[i].checkRayIntersects(waitingRays[j]);
if (s_point_temp)
{
// Here scene.objs[i] intersects with the ray at s_point_temp
// Here opticalObjs[i] intersects with the ray at s_point_temp
s_lensq_temp = geometry.distanceSquared(waitingRays[j].p1, s_point_temp);
if (s_point && geometry.distanceSquared(s_point_temp, s_point) < minShotLength_squared && (scene.objs[i].constructor.supportsSurfaceMerging || s_obj.constructor.supportsSurfaceMerging))
if (s_point && geometry.distanceSquared(s_point_temp, s_point) < minShotLength_squared && (opticalObjs[i].constructor.supportsSurfaceMerging || s_obj.constructor.supportsSurfaceMerging))
{
// The ray is shot on two objects at the same time, and at least one of them supports surface merging

if (s_obj.constructor.supportsSurfaceMerging)
{
if (scene.objs[i].constructor.supportsSurfaceMerging)
if (opticalObjs[i].constructor.supportsSurfaceMerging)
{
// Both of them supports surface merging (e.g. two glasses with one common edge
surfaceMergingObjs[surfaceMergingObjs.length] = scene.objs[i];
surfaceMergingObjs[surfaceMergingObjs.length] = opticalObjs[i];
}
else
{
// Only the first shot object supports surface merging
// Set the object to be shot to be the one not supporting surface merging (e.g. if one surface of a glass coincides with a blocker, then only block the ray)
s_obj = scene.objs[i];
s_obj = opticalObjs[i];
s_obj_index = i;
s_point = s_point_temp;
s_lensq = s_lensq_temp;
Expand All @@ -299,7 +305,7 @@ function shootWaitingRays() {
}
else if (s_lensq_temp < s_lensq && s_lensq_temp > minShotLength_squared)
{
s_obj = scene.objs[i]; // Update the object to be shot
s_obj = opticalObjs[i]; // Update the object to be shot
s_obj_index = i;
s_point = s_point_temp;
s_lensq = s_lensq_temp;
Expand Down

0 comments on commit ed6ab00

Please sign in to comment.