GGScraps.tioga
Last edited by Bier on July 29, 1985 1:26:59 pm PDT
Pieces of code which will probably never be used again, but you never know.
GGMouseEventImpl
SameJointAsLastTime: PROC [thisTraj: Traj, thisJointNum: NAT, gargoyleData: GargoyleData] RETURNS [BOOL] = CHECKED {
RETURN[
gargoyleData.hitTest.responsibleFor # NIL
AND gargoyleData.hitTest.responsibleFor.traj = thisTraj
AND gargoyleData.hitTest.responsibleFor.start = thisJointNum
AND gargoyleData.hitTest.responsibleFor.end = thisJointNum
];
};
NearestJoint: PROC [scene: Scene, worldPt: Point, tolerance: REAL] RETURNS [result: Traj, index: NAT] = {
Returns traj = NIL if no joints are found within tolerance.
d2, d2guess: REAL;
joint: INT;
trajGen: TrajectoryGenerator;
trajGen ← GGObjects.TrajsInScene[scene];
FOR traj: Traj ← GGObjects.NextTraj[trajGen], GGObjects.NextTraj[trajGen] UNTIL trajs = NIL DO
[joint, d2] ← GGObjects.NearestJoint[traj, worldPt, tolerance];
IF joint # -1 THEN {
result ← traj;
index ← joint;
GOTO NearFound;
};
REPEAT
NearFound => {
FOR traj2: Traj ← GGObjects.NextTraj[trajGen], GGObjects.NextTraj[trajGen] UNTIL traj2 = NIL DO
[joint, d2guess] ← GGObjects.NearestJoint[traj2, worldPt, tolerance];
IF joint # -1 THEN {
IF d2guess < d2 THEN {
result ← traj2;
index ← joint;
d2 ← d2guess;
};
};
ENDLOOP;
};
FINISHED => {result ← NIL};
ENDLOOP;
};
August 2, 1985 2:31:39 pm PDT
GGObjectsImpl.mesa
Hit Testing
NearestJoint: PUBLIC PROC [traj: Traj, testPoint: Point, tolerance: REAL] RETURNS [index: INT, d2: REAL] = CHECKED {
Finds the joint which is closest to testPoint. If there are several, it returns one of them. If none, index = -1.
thisPos: Point;
d2guess: REAL;
hiJoint: NAT ← HiJoint[traj];
FOR i: INT IN [0..hiJoint] DO
thisPos ← FetchJointPos[traj, i];
d2 ← GGVector.DistanceSquared[thisPos, testPoint];
IF d2 < tolerance*tolerance THEN {
index ← i;
GOTO NearFound;
};
REPEAT
NearFound => {
FOR j: INT IN [index+1..hiJoint] DO
thisPos ← FetchJointPos[traj, j];
d2guess ← GGVector.DistanceSquared[thisPos, testPoint];
IF d2guess < tolerance*tolerance THEN {
d2 ← d2guess;
index ← j;
};
ENDLOOP;
};
FINISHED => {index ← -1; d2 ← 0.0};
ENDLOOP;
};
NearJoints: PUBLIC PROC [traj: Traj, testPoint: Point, tolerance: REAL] RETURNS [indexes: LIST OF NAT, distancesSquared: LIST OF REAL] = CHECKED {
Finds all of the joints of traj which are within tolerance (and their distances from testPoint). If none, indexes = NIL.
thisPos: Point;
d2: REAL;
indexes ← NIL;
distancesSquared ← NIL;
FOR i: NAT IN [0..HiJoint[traj]] DO
thisPos ← FetchJointPos[traj, i];
d2 ← GGVector.DistanceSquared[thisPos, testPoint];
IF d2 < tolerance*tolerance THEN {
indexes ← CONS[i, indexes];
distancesSquared ← CONS[d2, distancesSquared];
};
ENDLOOP;
};
IsNearTraj: PUBLIC PROC [traj: Traj, testPoint: Point, tolerance: REAL] RETURNS [near: BOOL, howNear: REAL] = CHECKED {
For now, we just look for near joints.
indexes: LIST OF NAT;
distancesSquared: LIST OF REAL;
[indexes, distancesSquared] ← NearJoints[traj, testPoint, tolerance];
IF indexes = NIL THEN {
near ← FALSE; howNear ← 0.0; RETURN;
}
ELSE {
near ← TRUE;
howNear ← distancesSquared.first;
FOR dList: LIST OF REAL ← distancesSquared.rest, dList.rest UNTIL dList = NIL DO
howNear ← MIN[dList.first, howNear];
ENDLOOP;
};
};
IsNearOutline: PUBLIC PROC [outline: Outline, testPoint: Point, tolerance: REAL] RETURNS [near: BOOL, howNear: REAL] = {
howNearGuess: REAL;
nearGuess: BOOL;
FOR children: LIST OF Traj ← outline.children, children.rest UNTIL children = NIL DO
[near, howNearGuess] ← IsNearTraj[children.first, testPoint, tolerance];
IF near THEN GOTO FoundNear;
REPEAT
FoundNear => {
howNear ← howNearGuess;
FOR children2: LIST OF Traj ← children.rest, children2.rest UNTIL children2 = NIL DO
[nearGuess, howNearGuess] ← IsNearTraj[children2.first, testPoint, tolerance];
IF nearGuess THEN howNear ← MIN[howNearGuess, howNear];
ENDLOOP;
};
FINISHED => {
near ← FALSE; howNear ← 0.0;
};
ENDLOOP;
};
IsNearCluster: PUBLIC PROC [cluster: Cluster, testPoint: Point, tolerance: REAL] RETURNS [near: BOOL, howNear: REAL] = {
howNearGuess: REAL;
nearGuess: BOOL;
FOR children: LIST OF REF ANY ← cluster.children, children.rest UNTIL children = NIL DO
WITH children.first SELECT FROM
outline: Outline => {
[near, howNearGuess] ← IsNearOutline[outline, testPoint, tolerance];
IF near THEN GOTO FoundNear
};
subCluster: Cluster => {
[near, howNearGuess] ← IsNearCluster[subCluster, testPoint, tolerance];
IF near THEN GOTO FoundNear;
};
ENDCASE => ERROR;
REPEAT
FoundNear => {
howNear ← howNearGuess;
FOR children2: LIST OF REF ANY ← children.rest, children2.rest UNTIL children2 = NIL DO
WITH children2.first SELECT FROM
outline: Outline => {
[nearGuess, howNearGuess] ← IsNearOutline[outline, testPoint, tolerance];
IF nearGuess THEN howNear ← MIN[howNearGuess, howNear];
};
subCluster: Cluster => {
[nearGuess, howNearGuess] ← IsNearCluster[subCluster, testPoint, tolerance];
IF nearGuess THEN howNear ← MIN[howNearGuess, howNear];
};
ENDCASE => ERROR;
ENDLOOP;
};
FINISHED => {
near ← FALSE; howNear ← 0.0;
};
ENDLOOP;
};