<commit_before>// Component for aframe cameras that emits mouse events on aframe tags, and do it cycle style
import AFRAME from 'aframe';
import { Raycaster, Vector2 } from 'three';
import { fromEvent } from 'most';

const raycaster = new Raycaster();
const mouseVector = new Vector2();

function intent(source) {
  const { el } = source;

  const mouseDown$ = fromEvent('mousedown', el.sceneEl.canvas);
  const mouseMove$ = fromEvent('mousemove', el.sceneEl.canvas);
  const mouseUp$ = fromEvent('mouseup', el.sceneEl.canvas);
  const mouseOut$ = fromEvent('mouseout', el.sceneEl.canvas);

  mouseDown$.forEach(e => console.info('down'));
  mouseMove$.forEach(e => console.info('move'));
  mouseUp$.forEach(e => console.info('up'));
  mouseOut$.forEach(e => console.info('out'));
}

AFRAME.registerComponent('mouse-events',
  {
    schema: {},
    init() {
      this.el.sceneEl.addEventListener(
        'render-target-loaded',
        () => {
          const actions = intent(this);
        }
      );
    },
  }
);<commit_msg>Capture interescts from mouse position<commit_after>// Component for aframe cameras that emits mouse events on aframe tags, and do it cycle style
import AFRAME from 'aframe';
import { Raycaster, Vector2 } from 'three';
import { fromEvent } from 'most';
import { curry, flatten, find, isNil, not, pipe } from 'ramda';

const sharedRaycaster = new Raycaster();
const mouseVector = new Vector2();

function isObjectGroup(object) {
  return object.type === 'Group';
}

function isVisibleIntersect(item) {
  return item.object.parent.visible === true;
}

function getEntityChildren(entity) {
  return entity
    .children // This is ugly
    .map(child => (isObjectGroup(child) ? getEntityChildren(child) : child));
}

function setRaycastFromCamera(raycaster, camera, vector) {
  // This could be better
  raycaster.ray.origin.setFromMatrixPosition(camera.matrixWorld);

  raycaster.ray.direction
  .set(vector.x, vector.y, 0.5)
  .unproject(camera)
  .sub(raycaster.ray.origin)
  .normalize();

  return raycaster;
}

function intersectFunc(element, vector) {
  const sceneObj3D = element.sceneEl.object3D;
  const { scene } = sceneObj3D;
  const camera = element.getObject3D('camera');
  const allChildren = flatten(getEntityChildren(sceneObj3D));
  const intersects = setRaycastFromCamera(sharedRaycaster, camera, vector)
    .intersectObjects(allChildren);

  if (intersects.length > 0) {
    return find(isVisibleIntersect, intersects).object.parent.el;
  }
  return null;
}
const getIntersect = curry(intersectFunc);

function eventFunc(evt, base, target) {
  console.log(target, evt);
  base.emit(evt, { target });
  target.emit(evt);
}
const emitEvent = curry(eventFunc);

// Mouse Position based on window ratio
function getWorldPosition(evt) {
  const { innerWidth, innerHeight } = window;
  const { clientX, clientY } = evt;

  const position = {
    x: ((clientX / innerWidth) * 2) - 1,
    y: (-1 * (clientY / innerHeight) * 2) + 1,
  };
  return position;
}

function setMouseVector(evt) {
  const { x, y } = getWorldPosition(evt);
  mouseVector.set(x, y);
  return mouseVector;
}

function intent(sources) {
  const { el } = sources;
  const mouseDown$ = fromEvent('mousedown', el.sceneEl.canvas);
  const mouseMove$ = fromEvent('mousemove', el.sceneEl.canvas);
  const mouseUp$ = fromEvent('mouseup', el.sceneEl.canvas);
  const mouseOut$ = fromEvent('mouseout', el.sceneEl.canvas);

  const intents = {
    mouseDown$,
    mouseMove$,
    mouseUp$,
    mouseOut$,
  };
  return intents;
}

function model(actions, element) {
  const { mouseDown$ } = actions;
  mouseDown$
  .map(setMouseVector)
  .map(getIntersect(element))
  .filter(pipe(isNil, not))
  .forEach(emitEvent('mousedown', element));
}

AFRAME.registerComponent('mouse-events',
  {
    schema: {},
    init() {
      // Do nothing until the scene is ready for us
      this.el.sceneEl.addEventListener(
        'render-target-loaded',
        () => {
          const actions = intent(this);
          model(actions, this.el);
        }
      );
    },
  }
);
{'fraction_non_alphanumeric': 0.13828740157480315, 'fraction_numerical': 0.004183070866141733, 'mean_word_length': 3.85663082437276, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5980036', 'n_tokens_mistral': 1314, 'n_tokens_neox': 1286, 'n_words': 312}