@react-ecs/boids
Version:
<h1 align="center"> <br> <a href="https://react-ecs.ldlework.com"><img src="https://i.imgur.com/Rn6yLZs.gif" alt="React ECS" width="300"></a> <br> React ECS <br> <a href="https://react-ecs.ldlework.com">react-ecs.ldlework.com</a> </h1>
1,488 lines (1,273 loc) • 45.6 kB
JavaScript
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
import { Box, Torus } from '@react-three/drei';
import { useControls } from 'leva';
import { useRef, useMemo, Suspense, forwardRef } from 'react';
import { Facet, useQuery, useSystem, Entity } from '@react-ecs/core';
import { Vector3, LineBasicMaterial, Color, BufferGeometry, Line } from 'three';
import { ThreeView } from '@react-ecs/three';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __spreadArrays() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
}
var Acceleration =
/** @class */
function (_super) {
__extends(Acceleration, _super);
function Acceleration() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.amount = new Vector3(0, 0, 0);
return _this;
}
return Acceleration;
}(Facet);
var Neighbor =
/** @class */
function (_super) {
__extends(Neighbor, _super);
function Neighbor() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.meta = {
neighbors: []
};
return _this;
}
return Neighbor;
}(Facet);
var TeleportSystem = function TeleportSystem(props) {
var query = useQuery(function (e) {
return e.hasAll(ThreeView, Velocity);
});
return useSystem(function (dt) {
query.loop([ThreeView], function (e, _a) {
var view = _a[0];
var pos = view.object3d.position;
if (pos.x < -props.size) {
pos.setX(props.size);
} else if (pos.x > props.size) {
pos.setX(-props.size);
}
if (pos.y < -props.size) {
pos.setY(props.size);
} else if (pos.y > props.size) {
pos.setY(-props.size);
}
if (pos.z < -props.size) {
pos.setZ(props.size);
} else if (pos.z > props.size) {
pos.setZ(-props.size);
}
});
});
};
var Teleporter = function Teleporter(props) {
return jsxs(Fragment, {
children: [jsx(TeleportSystem, {
size: props.size
}, void 0), props.showBounds && jsxs(Fragment, {
children: [jsx(Box, {
scale: 3
}, void 0), jsx(Box, {
position: [props.size, props.size, props.size]
}, void 0), jsx(Box, {
position: [-props.size, -props.size, -props.size]
}, void 0), jsx(Box, {
position: [props.size, -props.size, props.size]
}, void 0), jsx(Box, {
position: [-props.size, props.size, -props.size]
}, void 0), jsx(Box, {
position: [props.size, props.size, -props.size]
}, void 0), jsx(Box, {
position: [-props.size, -props.size, props.size]
}, void 0), jsx(Box, {
position: [props.size, -props.size, -props.size]
}, void 0), jsx(Box, {
position: [-props.size, props.size, props.size]
}, void 0)]
}, void 0)]
}, void 0);
};
var Tracker =
/** @class */
function (_super) {
__extends(Tracker, _super);
function Tracker() {
return _super !== null && _super.apply(this, arguments) || this;
}
return Tracker;
}(Facet);
Tracker.__componentClassId__ = 99;
var Velocity =
/** @class */
function (_super) {
__extends(Velocity, _super);
function Velocity() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.amount = new Vector3(Math.random() - .5, Math.random() - .5, Math.random() - .5);
return _this;
}
return Velocity;
}(Facet);
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var check = function (it) {
return it && it.Math == Math && it;
};
// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
var global_1 =
// eslint-disable-next-line es/no-global-this -- safe
check(typeof globalThis == 'object' && globalThis) ||
check(typeof window == 'object' && window) ||
// eslint-disable-next-line no-restricted-globals -- safe
check(typeof self == 'object' && self) ||
check(typeof commonjsGlobal == 'object' && commonjsGlobal) ||
// eslint-disable-next-line no-new-func -- fallback
(function () { return this; })() || Function('return this')();
var fails = function (exec) {
try {
return !!exec();
} catch (error) {
return true;
}
};
// Detect IE8's incomplete defineProperty implementation
var descriptors = !fails(function () {
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7;
});
var $propertyIsEnumerable = {}.propertyIsEnumerable;
// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
// Nashorn ~ JDK8 bug
var NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1);
// `Object.prototype.propertyIsEnumerable` method implementation
// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
var f = NASHORN_BUG ? function propertyIsEnumerable(V) {
var descriptor = getOwnPropertyDescriptor(this, V);
return !!descriptor && descriptor.enumerable;
} : $propertyIsEnumerable;
var objectPropertyIsEnumerable = {
f: f
};
var createPropertyDescriptor = function (bitmap, value) {
return {
enumerable: !(bitmap & 1),
configurable: !(bitmap & 2),
writable: !(bitmap & 4),
value: value
};
};
var toString = {}.toString;
var classofRaw = function (it) {
return toString.call(it).slice(8, -1);
};
var split = ''.split;
// fallback for non-array-like ES3 and non-enumerable old V8 strings
var indexedObject = fails(function () {
// throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
// eslint-disable-next-line no-prototype-builtins -- safe
return !Object('z').propertyIsEnumerable(0);
}) ? function (it) {
return classofRaw(it) == 'String' ? split.call(it, '') : Object(it);
} : Object;
// `RequireObjectCoercible` abstract operation
// https://tc39.es/ecma262/#sec-requireobjectcoercible
var requireObjectCoercible = function (it) {
if (it == undefined) throw TypeError("Can't call method on " + it);
return it;
};
// toObject with fallback for non-array-like ES3 strings
var toIndexedObject = function (it) {
return indexedObject(requireObjectCoercible(it));
};
var isObject = function (it) {
return typeof it === 'object' ? it !== null : typeof it === 'function';
};
// `ToPrimitive` abstract operation
// https://tc39.es/ecma262/#sec-toprimitive
// instead of the ES6 spec version, we didn't implement @@toPrimitive case
// and the second argument - flag - preferred type is a string
var toPrimitive = function (input, PREFERRED_STRING) {
if (!isObject(input)) return input;
var fn, val;
if (PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
if (typeof (fn = input.valueOf) == 'function' && !isObject(val = fn.call(input))) return val;
if (!PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
throw TypeError("Can't convert object to primitive value");
};
var hasOwnProperty = {}.hasOwnProperty;
var has = function (it, key) {
return hasOwnProperty.call(it, key);
};
var document = global_1.document;
// typeof document.createElement is 'object' in old IE
var EXISTS = isObject(document) && isObject(document.createElement);
var documentCreateElement = function (it) {
return EXISTS ? document.createElement(it) : {};
};
// Thank's IE8 for his funny defineProperty
var ie8DomDefine = !descriptors && !fails(function () {
// eslint-disable-next-line es/no-object-defineproperty -- requied for testing
return Object.defineProperty(documentCreateElement('div'), 'a', {
get: function () { return 7; }
}).a != 7;
});
// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
// `Object.getOwnPropertyDescriptor` method
// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
var f$1 = descriptors ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
O = toIndexedObject(O);
P = toPrimitive(P, true);
if (ie8DomDefine) try {
return $getOwnPropertyDescriptor(O, P);
} catch (error) { /* empty */ }
if (has(O, P)) return createPropertyDescriptor(!objectPropertyIsEnumerable.f.call(O, P), O[P]);
};
var objectGetOwnPropertyDescriptor = {
f: f$1
};
var anObject = function (it) {
if (!isObject(it)) {
throw TypeError(String(it) + ' is not an object');
} return it;
};
// eslint-disable-next-line es/no-object-defineproperty -- safe
var $defineProperty = Object.defineProperty;
// `Object.defineProperty` method
// https://tc39.es/ecma262/#sec-object.defineproperty
var f$2 = descriptors ? $defineProperty : function defineProperty(O, P, Attributes) {
anObject(O);
P = toPrimitive(P, true);
anObject(Attributes);
if (ie8DomDefine) try {
return $defineProperty(O, P, Attributes);
} catch (error) { /* empty */ }
if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
if ('value' in Attributes) O[P] = Attributes.value;
return O;
};
var objectDefineProperty = {
f: f$2
};
var createNonEnumerableProperty = descriptors ? function (object, key, value) {
return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value));
} : function (object, key, value) {
object[key] = value;
return object;
};
var setGlobal = function (key, value) {
try {
createNonEnumerableProperty(global_1, key, value);
} catch (error) {
global_1[key] = value;
} return value;
};
var SHARED = '__core-js_shared__';
var store = global_1[SHARED] || setGlobal(SHARED, {});
var sharedStore = store;
var functionToString = Function.toString;
// this helper broken in `3.4.1-3.4.4`, so we can't use `shared` helper
if (typeof sharedStore.inspectSource != 'function') {
sharedStore.inspectSource = function (it) {
return functionToString.call(it);
};
}
var inspectSource = sharedStore.inspectSource;
var WeakMap = global_1.WeakMap;
var nativeWeakMap = typeof WeakMap === 'function' && /native code/.test(inspectSource(WeakMap));
var shared = createCommonjsModule(function (module) {
(module.exports = function (key, value) {
return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
})('versions', []).push({
version: '3.10.2',
mode: 'global',
copyright: '© 2021 Denis Pushkarev (zloirock.ru)'
});
});
var id = 0;
var postfix = Math.random();
var uid = function (key) {
return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id + postfix).toString(36);
};
var keys = shared('keys');
var sharedKey = function (key) {
return keys[key] || (keys[key] = uid(key));
};
var hiddenKeys = {};
var OBJECT_ALREADY_INITIALIZED = 'Object already initialized';
var WeakMap$1 = global_1.WeakMap;
var set, get, has$1;
var enforce = function (it) {
return has$1(it) ? get(it) : set(it, {});
};
var getterFor = function (TYPE) {
return function (it) {
var state;
if (!isObject(it) || (state = get(it)).type !== TYPE) {
throw TypeError('Incompatible receiver, ' + TYPE + ' required');
} return state;
};
};
if (nativeWeakMap) {
var store$1 = sharedStore.state || (sharedStore.state = new WeakMap$1());
var wmget = store$1.get;
var wmhas = store$1.has;
var wmset = store$1.set;
set = function (it, metadata) {
if (wmhas.call(store$1, it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);
metadata.facade = it;
wmset.call(store$1, it, metadata);
return metadata;
};
get = function (it) {
return wmget.call(store$1, it) || {};
};
has$1 = function (it) {
return wmhas.call(store$1, it);
};
} else {
var STATE = sharedKey('state');
hiddenKeys[STATE] = true;
set = function (it, metadata) {
if (has(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);
metadata.facade = it;
createNonEnumerableProperty(it, STATE, metadata);
return metadata;
};
get = function (it) {
return has(it, STATE) ? it[STATE] : {};
};
has$1 = function (it) {
return has(it, STATE);
};
}
var internalState = {
set: set,
get: get,
has: has$1,
enforce: enforce,
getterFor: getterFor
};
var redefine = createCommonjsModule(function (module) {
var getInternalState = internalState.get;
var enforceInternalState = internalState.enforce;
var TEMPLATE = String(String).split('String');
(module.exports = function (O, key, value, options) {
var unsafe = options ? !!options.unsafe : false;
var simple = options ? !!options.enumerable : false;
var noTargetGet = options ? !!options.noTargetGet : false;
var state;
if (typeof value == 'function') {
if (typeof key == 'string' && !has(value, 'name')) {
createNonEnumerableProperty(value, 'name', key);
}
state = enforceInternalState(value);
if (!state.source) {
state.source = TEMPLATE.join(typeof key == 'string' ? key : '');
}
}
if (O === global_1) {
if (simple) O[key] = value;
else setGlobal(key, value);
return;
} else if (!unsafe) {
delete O[key];
} else if (!noTargetGet && O[key]) {
simple = true;
}
if (simple) O[key] = value;
else createNonEnumerableProperty(O, key, value);
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, 'toString', function toString() {
return typeof this == 'function' && getInternalState(this).source || inspectSource(this);
});
});
var path = global_1;
var aFunction = function (variable) {
return typeof variable == 'function' ? variable : undefined;
};
var getBuiltIn = function (namespace, method) {
return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global_1[namespace])
: path[namespace] && path[namespace][method] || global_1[namespace] && global_1[namespace][method];
};
var ceil = Math.ceil;
var floor = Math.floor;
// `ToInteger` abstract operation
// https://tc39.es/ecma262/#sec-tointeger
var toInteger = function (argument) {
return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);
};
var min = Math.min;
// `ToLength` abstract operation
// https://tc39.es/ecma262/#sec-tolength
var toLength = function (argument) {
return argument > 0 ? min(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
};
var max = Math.max;
var min$1 = Math.min;
// Helper for a popular repeating case of the spec:
// Let integer be ? ToInteger(index).
// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
var toAbsoluteIndex = function (index, length) {
var integer = toInteger(index);
return integer < 0 ? max(integer + length, 0) : min$1(integer, length);
};
// `Array.prototype.{ indexOf, includes }` methods implementation
var createMethod = function (IS_INCLUDES) {
return function ($this, el, fromIndex) {
var O = toIndexedObject($this);
var length = toLength(O.length);
var index = toAbsoluteIndex(fromIndex, length);
var value;
// Array#includes uses SameValueZero equality algorithm
// eslint-disable-next-line no-self-compare -- NaN check
if (IS_INCLUDES && el != el) while (length > index) {
value = O[index++];
// eslint-disable-next-line no-self-compare -- NaN check
if (value != value) return true;
// Array#indexOf ignores holes, Array#includes - not
} else for (;length > index; index++) {
if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
} return !IS_INCLUDES && -1;
};
};
var arrayIncludes = {
// `Array.prototype.includes` method
// https://tc39.es/ecma262/#sec-array.prototype.includes
includes: createMethod(true),
// `Array.prototype.indexOf` method
// https://tc39.es/ecma262/#sec-array.prototype.indexof
indexOf: createMethod(false)
};
var indexOf = arrayIncludes.indexOf;
var objectKeysInternal = function (object, names) {
var O = toIndexedObject(object);
var i = 0;
var result = [];
var key;
for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
// Don't enum bug & hidden keys
while (names.length > i) if (has(O, key = names[i++])) {
~indexOf(result, key) || result.push(key);
}
return result;
};
// IE8- don't enum bug keys
var enumBugKeys = [
'constructor',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'toLocaleString',
'toString',
'valueOf'
];
var hiddenKeys$1 = enumBugKeys.concat('length', 'prototype');
// `Object.getOwnPropertyNames` method
// https://tc39.es/ecma262/#sec-object.getownpropertynames
// eslint-disable-next-line es/no-object-getownpropertynames -- safe
var f$3 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
return objectKeysInternal(O, hiddenKeys$1);
};
var objectGetOwnPropertyNames = {
f: f$3
};
// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe
var f$4 = Object.getOwnPropertySymbols;
var objectGetOwnPropertySymbols = {
f: f$4
};
// all object keys, includes non-enumerable and symbols
var ownKeys = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
var keys = objectGetOwnPropertyNames.f(anObject(it));
var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
};
var copyConstructorProperties = function (target, source) {
var keys = ownKeys(source);
var defineProperty = objectDefineProperty.f;
var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (!has(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
}
};
var replacement = /#|\.prototype\./;
var isForced = function (feature, detection) {
var value = data[normalize(feature)];
return value == POLYFILL ? true
: value == NATIVE ? false
: typeof detection == 'function' ? fails(detection)
: !!detection;
};
var normalize = isForced.normalize = function (string) {
return String(string).replace(replacement, '.').toLowerCase();
};
var data = isForced.data = {};
var NATIVE = isForced.NATIVE = 'N';
var POLYFILL = isForced.POLYFILL = 'P';
var isForced_1 = isForced;
var getOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f;
/*
options.target - name of the target object
options.global - target is the global object
options.stat - export as static methods of target
options.proto - export as prototype methods of target
options.real - real prototype method for the `pure` version
options.forced - export even if the native feature is available
options.bind - bind methods to the target, required for the `pure` version
options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
options.unsafe - use the simple assignment of property instead of delete + defineProperty
options.sham - add a flag to not completely full polyfills
options.enumerable - export as enumerable property
options.noTargetGet - prevent calling a getter on target
*/
var _export = function (options, source) {
var TARGET = options.target;
var GLOBAL = options.global;
var STATIC = options.stat;
var FORCED, target, key, targetProperty, sourceProperty, descriptor;
if (GLOBAL) {
target = global_1;
} else if (STATIC) {
target = global_1[TARGET] || setGlobal(TARGET, {});
} else {
target = (global_1[TARGET] || {}).prototype;
}
if (target) for (key in source) {
sourceProperty = source[key];
if (options.noTargetGet) {
descriptor = getOwnPropertyDescriptor$1(target, key);
targetProperty = descriptor && descriptor.value;
} else targetProperty = target[key];
FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
// contained in target
if (!FORCED && targetProperty !== undefined) {
if (typeof sourceProperty === typeof targetProperty) continue;
copyConstructorProperties(sourceProperty, targetProperty);
}
// add a flag to not completely full polyfills
if (options.sham || (targetProperty && targetProperty.sham)) {
createNonEnumerableProperty(sourceProperty, 'sham', true);
}
// extend global
redefine(target, key, sourceProperty, options);
}
};
var quot = /"/g;
// B.2.3.2.1 CreateHTML(string, tag, attribute, value)
// https://tc39.es/ecma262/#sec-createhtml
var createHtml = function (string, tag, attribute, value) {
var S = String(requireObjectCoercible(string));
var p1 = '<' + tag;
if (attribute !== '') p1 += ' ' + attribute + '="' + String(value).replace(quot, '"') + '"';
return p1 + '>' + S + '</' + tag + '>';
};
// check the existence of a method, lowercase
// of a tag and escaping quotes in arguments
var stringHtmlForced = function (METHOD_NAME) {
return fails(function () {
var test = ''[METHOD_NAME]('"');
return test !== test.toLowerCase() || test.split('"').length > 3;
});
};
// `String.prototype.sub` method
// https://tc39.es/ecma262/#sec-string.prototype.sub
_export({ target: 'String', proto: true, forced: stringHtmlForced('sub') }, {
sub: function sub() {
return createHtml(this, 'sub', '', '');
}
});
var AlignSystem = function AlignSystem(props) {
var query = useQuery(function (e) {
return e.hasAll(Neighbor, Velocity, Acceleration);
});
return useSystem(function (dt) {
query.loop([Neighbor, Velocity, Acceleration], function (e, _a) {
var neighbor = _a[0],
velocity = _a[1],
acceleration = _a[2];
var steering = new Vector3(0, 0, 0);
var neighbors = neighbor.meta.neighbors;
for (var _i = 0, _b = neighbor.meta.neighbors; _i < _b.length; _i++) {
var other = _b[_i];
var otherVelocity = other.get(Velocity).amount;
steering.add(otherVelocity);
}
if (neighbors.length) {
steering.divideScalar(neighbors.length);
steering.sub(velocity.amount);
steering.clampLength(props.min || 0, props.max || 1);
}
acceleration.amount = steering.normalize().clone().multiplyScalar(props.amount);
});
});
};
var CohesionSystem = function CohesionSystem(props) {
var query = useQuery(function (e) {
return e.hasAll(ThreeView, Velocity, Neighbor);
});
return useSystem(function (dt) {
query.loop([ThreeView, Neighbor, Velocity, Acceleration], function (e, _a) {
var view = _a[0],
neighbor = _a[1],
velocity = _a[2],
acceleration = _a[3]; // current boid
var o3d = view.object3d;
var steering = new Vector3();
var neighbors = neighbor.meta.neighbors;
for (var _i = 0, neighbors_1 = neighbors; _i < neighbors_1.length; _i++) {
var other = neighbors_1[_i];
steering.add(other.get(ThreeView).object3d.position);
}
if (neighbors.length) {
steering.divideScalar(neighbors.length);
steering.sub(o3d.position);
steering.setLength(1);
steering.sub(velocity.amount);
steering.clampLength(props.min, props.max);
steering.multiplyScalar(props.amount);
}
acceleration.amount.add(steering);
});
});
};
var MoveSystem = function MoveSystem(props) {
var query = useQuery(function (e) {
return e.hasAll(ThreeView, Velocity, Acceleration);
});
return useSystem(function (dt) {
query === null || query === void 0 ? void 0 : query.loop([ThreeView, Velocity, Acceleration], function (e, _a) {
var view = _a[0],
velocity = _a[1],
acceleration = _a[2];
var transform = view.object3d;
if (velocity.amount.length() > 0) {
var lookPos = transform.position.clone().add(velocity.amount);
transform.lookAt(lookPos);
}
var newPosition = transform.position.clone().add(velocity.amount.clone().multiplyScalar(dt));
velocity.amount.add(acceleration.amount);
velocity.amount.clampLength(props.min, props.max);
transform.position.copy(newPosition);
});
});
};
var aFunction$1 = function (it) {
if (typeof it != 'function') {
throw TypeError(String(it) + ' is not a function');
} return it;
};
// optional / simple context binding
var functionBindContext = function (fn, that, length) {
aFunction$1(fn);
if (that === undefined) return fn;
switch (length) {
case 0: return function () {
return fn.call(that);
};
case 1: return function (a) {
return fn.call(that, a);
};
case 2: return function (a, b) {
return fn.call(that, a, b);
};
case 3: return function (a, b, c) {
return fn.call(that, a, b, c);
};
}
return function (/* ...args */) {
return fn.apply(that, arguments);
};
};
// `ToObject` abstract operation
// https://tc39.es/ecma262/#sec-toobject
var toObject = function (argument) {
return Object(requireObjectCoercible(argument));
};
// `IsArray` abstract operation
// https://tc39.es/ecma262/#sec-isarray
// eslint-disable-next-line es/no-array-isarray -- safe
var isArray = Array.isArray || function isArray(arg) {
return classofRaw(arg) == 'Array';
};
var engineIsNode = classofRaw(global_1.process) == 'process';
var engineUserAgent = getBuiltIn('navigator', 'userAgent') || '';
var process = global_1.process;
var versions = process && process.versions;
var v8 = versions && versions.v8;
var match, version;
if (v8) {
match = v8.split('.');
version = match[0] + match[1];
} else if (engineUserAgent) {
match = engineUserAgent.match(/Edge\/(\d+)/);
if (!match || match[1] >= 74) {
match = engineUserAgent.match(/Chrome\/(\d+)/);
if (match) version = match[1];
}
}
var engineV8Version = version && +version;
// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing
var nativeSymbol = !!Object.getOwnPropertySymbols && !fails(function () {
// eslint-disable-next-line es/no-symbol -- required for testing
return !Symbol.sham &&
// Chrome 38 Symbol has incorrect toString conversion
// Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
(engineIsNode ? engineV8Version === 38 : engineV8Version > 37 && engineV8Version < 41);
});
/* eslint-disable es/no-symbol -- required for testing */
var useSymbolAsUid = nativeSymbol
&& !Symbol.sham
&& typeof Symbol.iterator == 'symbol';
var WellKnownSymbolsStore = shared('wks');
var Symbol$1 = global_1.Symbol;
var createWellKnownSymbol = useSymbolAsUid ? Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid;
var wellKnownSymbol = function (name) {
if (!has(WellKnownSymbolsStore, name) || !(nativeSymbol || typeof WellKnownSymbolsStore[name] == 'string')) {
if (nativeSymbol && has(Symbol$1, name)) {
WellKnownSymbolsStore[name] = Symbol$1[name];
} else {
WellKnownSymbolsStore[name] = createWellKnownSymbol('Symbol.' + name);
}
} return WellKnownSymbolsStore[name];
};
var SPECIES = wellKnownSymbol('species');
// `ArraySpeciesCreate` abstract operation
// https://tc39.es/ecma262/#sec-arrayspeciescreate
var arraySpeciesCreate = function (originalArray, length) {
var C;
if (isArray(originalArray)) {
C = originalArray.constructor;
// cross-realm fallback
if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
else if (isObject(C)) {
C = C[SPECIES];
if (C === null) C = undefined;
}
} return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
};
var push = [].push;
// `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterOut }` methods implementation
var createMethod$1 = function (TYPE) {
var IS_MAP = TYPE == 1;
var IS_FILTER = TYPE == 2;
var IS_SOME = TYPE == 3;
var IS_EVERY = TYPE == 4;
var IS_FIND_INDEX = TYPE == 6;
var IS_FILTER_OUT = TYPE == 7;
var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
return function ($this, callbackfn, that, specificCreate) {
var O = toObject($this);
var self = indexedObject(O);
var boundFunction = functionBindContext(callbackfn, that, 3);
var length = toLength(self.length);
var index = 0;
var create = specificCreate || arraySpeciesCreate;
var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_OUT ? create($this, 0) : undefined;
var value, result;
for (;length > index; index++) if (NO_HOLES || index in self) {
value = self[index];
result = boundFunction(value, index, O);
if (TYPE) {
if (IS_MAP) target[index] = result; // map
else if (result) switch (TYPE) {
case 3: return true; // some
case 5: return value; // find
case 6: return index; // findIndex
case 2: push.call(target, value); // filter
} else switch (TYPE) {
case 4: return false; // every
case 7: push.call(target, value); // filterOut
}
}
}
return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
};
};
var arrayIteration = {
// `Array.prototype.forEach` method
// https://tc39.es/ecma262/#sec-array.prototype.foreach
forEach: createMethod$1(0),
// `Array.prototype.map` method
// https://tc39.es/ecma262/#sec-array.prototype.map
map: createMethod$1(1),
// `Array.prototype.filter` method
// https://tc39.es/ecma262/#sec-array.prototype.filter
filter: createMethod$1(2),
// `Array.prototype.some` method
// https://tc39.es/ecma262/#sec-array.prototype.some
some: createMethod$1(3),
// `Array.prototype.every` method
// https://tc39.es/ecma262/#sec-array.prototype.every
every: createMethod$1(4),
// `Array.prototype.find` method
// https://tc39.es/ecma262/#sec-array.prototype.find
find: createMethod$1(5),
// `Array.prototype.findIndex` method
// https://tc39.es/ecma262/#sec-array.prototype.findIndex
findIndex: createMethod$1(6),
// `Array.prototype.filterOut` method
// https://github.com/tc39/proposal-array-filtering
filterOut: createMethod$1(7)
};
var arrayMethodIsStrict = function (METHOD_NAME, argument) {
var method = [][METHOD_NAME];
return !!method && fails(function () {
// eslint-disable-next-line no-useless-call,no-throw-literal -- required for testing
method.call(null, argument || function () { throw 1; }, 1);
});
};
var $forEach = arrayIteration.forEach;
var STRICT_METHOD = arrayMethodIsStrict('forEach');
// `Array.prototype.forEach` method implementation
// https://tc39.es/ecma262/#sec-array.prototype.foreach
var arrayForEach = !STRICT_METHOD ? function forEach(callbackfn /* , thisArg */) {
return $forEach(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
// eslint-disable-next-line es/no-array-prototype-foreach -- safe
} : [].forEach;
// `Array.prototype.forEach` method
// https://tc39.es/ecma262/#sec-array.prototype.foreach
// eslint-disable-next-line es/no-array-prototype-foreach -- safe
_export({ target: 'Array', proto: true, forced: [].forEach != arrayForEach }, {
forEach: arrayForEach
});
var SPECIES$1 = wellKnownSymbol('species');
var arrayMethodHasSpeciesSupport = function (METHOD_NAME) {
// We can't use this feature detection in V8 since it causes
// deoptimization and serious performance degradation
// https://github.com/zloirock/core-js/issues/677
return engineV8Version >= 51 || !fails(function () {
var array = [];
var constructor = array.constructor = {};
constructor[SPECIES$1] = function () {
return { foo: 1 };
};
return array[METHOD_NAME](Boolean).foo !== 1;
});
};
var $map = arrayIteration.map;
var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('map');
// `Array.prototype.map` method
// https://tc39.es/ecma262/#sec-array.prototype.map
// with adding support of @@species
_export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, {
map: function map(callbackfn /* , thisArg */) {
return $map(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
}
});
// iterable DOM collections
// flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods
var domIterables = {
CSSRuleList: 0,
CSSStyleDeclaration: 0,
CSSValueList: 0,
ClientRectList: 0,
DOMRectList: 0,
DOMStringList: 0,
DOMTokenList: 1,
DataTransferItemList: 0,
FileList: 0,
HTMLAllCollection: 0,
HTMLCollection: 0,
HTMLFormElement: 0,
HTMLSelectElement: 0,
MediaList: 0,
MimeTypeArray: 0,
NamedNodeMap: 0,
NodeList: 1,
PaintRequestList: 0,
Plugin: 0,
PluginArray: 0,
SVGLengthList: 0,
SVGNumberList: 0,
SVGPathSegList: 0,
SVGPointList: 0,
SVGStringList: 0,
SVGTransformList: 0,
SourceBufferList: 0,
StyleSheetList: 0,
TextTrackCueList: 0,
TextTrackList: 0,
TouchList: 0
};
for (var COLLECTION_NAME in domIterables) {
var Collection = global_1[COLLECTION_NAME];
var CollectionPrototype = Collection && Collection.prototype;
// some Chrome versions have non-configurable methods on DOMTokenList
if (CollectionPrototype && CollectionPrototype.forEach !== arrayForEach) try {
createNonEnumerableProperty(CollectionPrototype, 'forEach', arrayForEach);
} catch (error) {
CollectionPrototype.forEach = arrayForEach;
}
}
var NeighborDebugger =
/** @class */
function (_super) {
__extends(NeighborDebugger, _super);
function NeighborDebugger() {
return _super !== null && _super.apply(this, arguments) || this;
}
return NeighborDebugger;
}(Facet);
var material = new LineBasicMaterial({
color: new Color(Math.random(), Math.random(), Math.random())
});
var zeroPoint = new Vector3();
var zeroLine = [zeroPoint, zeroPoint];
var LinePool =
/** @class */
function () {
function LinePool() {
this.pool = [];
}
LinePool.prototype.fetch = function (parent, v1, v2) {
if (this.pool.length) {
var line = this.pool.pop();
line.geometry.setFromPoints([v1, v2]);
parent.attach(line);
return line;
} else {
var points = [v1, v2];
var geometry = new BufferGeometry();
var line = new Line(geometry, material);
line.geometry.setFromPoints(points);
parent.attach(line);
return line;
}
};
LinePool.prototype.reset = function (line) {
var vec = new Vector3();
line.parent.remove(line);
line.position.set(0, 0, 0);
line.geometry.setFromPoints(zeroLine);
this.pool.push(line);
};
return LinePool;
}();
var NeighborDebugSystem = function NeighborDebugSystem(props) {
var _a;
var id = 0;
var pool = useRef(new LinePool());
var targetQuery = useQuery(function (e) {
return e.hasAll(ThreeView, Neighbor);
});
var debugQuery = useQuery(function (e) {
return e.hasAll(ThreeView, NeighborDebugger);
});
var create = function create(target) {
var key = id++;
var targetView = target.get(ThreeView);
var targetNeighorhood = target.get(Neighbor);
if (!targetView) return null;
return jsxs(Entity, {
children: [jsx(NeighborDebugger, {
targetView: targetView,
targetNeighorhood: targetNeighorhood
}, void 0), jsx(ThreeView, {
children: jsx("group", {
position: targetView.object3d.position
}, void 0)
}, void 0)]
}, key);
};
useSystem(function (dt) {
debugQuery.loop([ThreeView, NeighborDebugger], function (e, _a) {
var view = _a[0],
debug = _a[1];
var debugObj = view.object3d;
var targetObj = debug.targetView.object3d;
var children = __spreadArrays(debugObj.children);
for (var _i = 0, _b = debug.targetNeighorhood.meta.neighbors; _i < _b.length; _i++) {
var neighbor = _b[_i];
var neighborPosition = neighbor.get(ThreeView).object3d.position;
var oldLine = children.pop();
if (oldLine) {
oldLine.geometry.setFromPoints([targetObj.position, neighborPosition]);
} else {
pool.current.fetch(debugObj, targetObj.position, neighborPosition);
}
}
children.forEach(function (c) {
return pool.current.reset(c);
});
});
});
return ((_a = targetQuery.entities) === null || _a === void 0 ? void 0 : _a.map(create)) || null;
};
var $filter = arrayIteration.filter;
var HAS_SPECIES_SUPPORT$1 = arrayMethodHasSpeciesSupport('filter');
// `Array.prototype.filter` method
// https://tc39.es/ecma262/#sec-array.prototype.filter
// with adding support of @@species
_export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$1 }, {
filter: function filter(callbackfn /* , thisArg */) {
return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
}
});
var test = [];
var nativeSort = test.sort;
// IE8-
var FAILS_ON_UNDEFINED = fails(function () {
test.sort(undefined);
});
// V8 bug
var FAILS_ON_NULL = fails(function () {
test.sort(null);
});
// Old WebKit
var STRICT_METHOD$1 = arrayMethodIsStrict('sort');
var FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD$1;
// `Array.prototype.sort` method
// https://tc39.es/ecma262/#sec-array.prototype.sort
_export({ target: 'Array', proto: true, forced: FORCED }, {
sort: function sort(comparefn) {
return comparefn === undefined
? nativeSort.call(toObject(this))
: nativeSort.call(toObject(this), aFunction$1(comparefn));
}
});
var NeighborSystem = function NeighborSystem(props) {
var query = useQuery(function (e) {
return e.hasAll(ThreeView, Neighbor);
});
return useSystem(function (dt) {
query.loop([ThreeView, Neighbor], function (e, _a) {
var view = _a[0],
neighbor = _a[1]; // current boid
var o3d = view.object3d; // helpers
var objFor = function objFor(entity) {
return entity.get(ThreeView).object3d;
};
var distTo = function distTo(entity) {
return o3d.position.distanceTo(objFor(entity).position);
}; // store current neighbors on Neighbor facet
// will be used by aligntment, cohesion and avoidance systems
neighbor.meta.neighbors = query.entities.filter(function (_e) {
return _e.id !== e.id;
}).filter(function (_e) {
return props.filter ? props.filter(e, _e) : true;
}).filter(function (_e) {
return distTo(_e) < props.radius;
}).sort(function (a, b) {
return distTo(a) - distTo(b);
});
});
});
};
var SeparationSystem = function SeparationSystem(props) {
var query = useQuery(function (e) {
return e.hasAll(ThreeView, Velocity, Neighbor);
});
return useSystem(function (dt) {
query.loop([ThreeView, Neighbor, Velocity, Acceleration], function (e, _a) {
var view = _a[0],
neighbor = _a[1],
velocity = _a[2],
acceleration = _a[3]; // current boid
var o3d = view.object3d;
var steering = new Vector3();
var neighbors = neighbor.meta.neighbors;
for (var _i = 0, neighbors_1 = neighbors; _i < neighbors_1.length; _i++) {
var other = neighbors_1[_i];
var otherPosition = other.get(ThreeView).object3d.position;
var dist = o3d.position.distanceTo(otherPosition);
var diff = o3d.position.clone().sub(otherPosition);
diff.divideScalar(dist * dist);
steering.add(diff);
}
if (neighbors.length) {
steering.divideScalar(neighbors.length);
steering.sub(velocity.amount);
steering.clampLength(props.min, props.max);
steering.multiplyScalar(props.amount);
}
acceleration.amount.add(steering);
});
});
};
var BoidSim = function BoidSim(props) {
var _a = useControls('sim', {
size: {
value: 100,
min: 20,
max: 200
},
count: {
value: 250,
min: 1,
max: 250
},
spawnHeight: {
value: 1,
min: 0,
max: 1
},
neighborRadius: {
value: 10,
min: 1,
max: 50
},
showBounds: false
}, {}),
size = _a.size,
count = _a.count,
spawnHeight = _a.spawnHeight,
neighborRadius = _a.neighborRadius,
showBounds = _a.showBounds;
var alignment = useControls('alignment', {
enabled: true,
multiplier: {
value: .1,
min: 0,
max: 1
},
turningRange: {
value: [0, .1],
min: 0,
max: 1
}
});
var cohesion = useControls('cohesion', {
enabled: true,
multiplier: {
value: 1,
min: 0,
max: 1
},
speedRange: {
value: [0, 1],
min: 0,
max: 10
}
});
var separation = useControls('separation', {
enabled: true,
multiplier: {
value: 2,
min: 0,
max: 2
},
speedRange: {
value: [0, 3],
min: 0,
max: 10
}
});
var speed = useControls('speed', {
range: {
value: [15, 50],
min: 0,
max: 50
}
});
var comp = function comp() {
return Math.random() * size * 2 - size;
};
var pos = function pos() {
return [comp(), comp() * spawnHeight, comp()];
};
var data = useMemo(function () {
var items = [];
for (var i = 0; i < count; i++) {
items.push(jsx(Suspense, __assign({
fallback: jsx(Torus, {}, void 0)
}, {
children: jsx(Plane, {
render: props.render,
position: pos()
}, void 0)
}), void 0));
}
return items; // eslint-disable-next-line react-hooks/exhaustive-deps
}, [size, spawnHeight, count]);
return jsxs(Fragment, {
children: [jsx(Teleporter, {
showBounds: showBounds,
size: size
}, void 0), jsx(NeighborSystem, {
radius: neighborRadius
}, void 0), jsx(AlignSystem, {
amount: alignment.enabled ? alignment.multiplier : 0,
min: alignment.turningRange[0],
max: alignment.turningRange[1]
}, void 0), jsx(CohesionSystem, {
amount: cohesion.enabled ? cohesion.multiplier : 0,
min: cohesion.speedRange[0],
max: cohesion.speedRange[1]
}, void 0), jsx(SeparationSystem, {
amount: separation.enabled ? separation.multiplier : 0,
min: separation.speedRange[0],
max: separation.speedRange[1]
}, void 0), jsx(MoveSystem, {
min: speed.range[0],
max: speed.range[1]
}, void 0), data]
}, void 0);
};
var Plane = /*#__PURE__*/forwardRef(function (props, ref) {
var render = props.render,
groupProps = __rest(props, ["render"]);
return jsxs(Entity, {
children: [jsx(Neighbor, {}, void 0), jsx(Velocity, {}, void 0), jsx(Acceleration, {}, void 0), jsx(ThreeView, {
children: jsx("group", __assign({
ref: ref
}, groupProps, {
dispose: null
}, {
children: render()
}), void 0)
}, void 0)]
}, void 0);
});
export { Acceleration, AlignSystem, BoidSim, CohesionSystem, MoveSystem, Neighbor, NeighborDebugSystem, NeighborSystem, Plane, SeparationSystem, TeleportSystem, Teleporter, Tracker, Velocity };