Skip to content

Instantly share code, notes, and snippets.

@allanberger
Forked from benursu/Chained - script.js
Created June 19, 2019 16:16
Show Gist options
  • Save allanberger/f20da6bbc4a544eaaf1e1fa4916fb352 to your computer and use it in GitHub Desktop.
Save allanberger/f20da6bbc4a544eaaf1e1fa4916fb352 to your computer and use it in GitHub Desktop.
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Chained
// @afrosquared | Ben Ursu
// Instagram | Spark AR Studio | SDK v62.0
// https://www.instagram.com/a/r/?effect_id=296042214483846
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//require
const Scene = require('Scene');
const Animation = require('Animation');
const R = require('Reactive');
const D = require('Diagnostics');
const Time = require('Time');
const Materials = require('Materials');
const Textures = require('Textures');
const TouchGestures = require('TouchGestures');
const FT = require('FaceTracking');
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//init
var zero = Scene.root.find('zero');
var rotation180 = Math.PI;
var rotation360 = Math.PI * 2;
var vectorForward = R.vector(1, 0, 0);
var facetracker0 = Scene.root.find('facetracker0');
var facePosition = FT.face(0).forehead.top;
var connection0 = Scene.root.find('connection0');
var connection1 = Scene.root.find('connection1');
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//segments
var segmentStreakTotal = 1;
var segmentSegmentTotal = 30;
var positions = [];
var segments = [];
var segmentLines = [];
var segmentLineCubes = [];
var segmentPositionRatios = [];
var segmentScaleRatios = [];
var segment0Connect = Scene.root.find('segment0_connect');
for(var i = 0; i <= segmentStreakTotal; i++){
positions.push([]);
segments.push([]);
segmentLines.push([]);
segmentLineCubes.push([]);
segmentPositionRatios.push([]);
segmentScaleRatios.push([]);
}
for(var i = 0; i < segmentStreakTotal; i++){
for(var k = 0; k < segmentSegmentTotal; k++){
var segment = Scene.root.find('segment' + i + '_' + k);
segment.hidden = false;
var segmentLine = segment.child('line');
var segmentLineCube = segmentLine.child('cube');
var segmentLineCubeNode = segmentLineCube.child('node-0');
segmentLineCubeNode.transform.scaleX = 0.0014;
segmentLineCubeNode.transform.scaleZ = 0.0014;
var segmentPositionRatio = R.val(1);
var segmentScaleRatio = R.val(1);
segments[i].push(segment);
segmentLines[i].push(segmentLine);
segmentLineCubes[i].push(segmentLineCube);
segmentPositionRatios[i].push(segmentPositionRatio);
segmentScaleRatios[i].push(segmentScaleRatio);
}
for(var k = 0; k <= segmentSegmentTotal; k++){
var position = Scene.root.find('position' + i + '_' + k);
positions[i].push(position);
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//segments lookat
for(var i = 0; i < segmentStreakTotal; i++){
for(var k = 0; k < segmentSegmentTotal; k++){
segments[i][k].transform.position = positions[i][k].transform.position.mul(segmentPositionRatios[i][k]);
segmentLineCubes[i][k].transform.scaleX = positions[i][k].transform.position.distance(positions[i][k+1].transform.position).mul(segmentScaleRatios[i][k]);
var position0_forwardVector = R.normalize(positions[i][k+1].transform.position.sub(positions[i][k].transform.position));
var position0_rotationAxis = position0_forwardVector.cross(vectorForward);
var position0_dot = position0_forwardVector.dot(vectorForward).add(1);
var position0_w0 = position0_dot.mul(-1);
var position0_x0 = position0_rotationAxis.x;
var position0_y0 = position0_rotationAxis.y;
var position0_z0 = position0_rotationAxis.z;
var position0QuatL = R.sqrt((position0_x0.mul(position0_x0)).add(position0_y0.mul(position0_y0)).add(position0_z0.mul(position0_z0)).add(position0_w0.mul(position0_w0)));
var position0QuatLL = R.val(1).div(position0QuatL);
var position0_w = position0_w0.mul(position0QuatLL);
var position0_x = position0_x0.mul(position0QuatLL);
var position0_y = position0_y0.mul(position0QuatLL);
var position0_z = position0_z0.mul(position0QuatLL);
//quaternion to euler using zyx
var position0_r11 = R.val(2).mul((position0_x.mul(position0_y).add(position0_w.mul(position0_z))));
var position0_r12 = (position0_w.mul(position0_w)).add(position0_x.mul(position0_x)).sub(position0_y.mul(position0_y)).sub(position0_z.mul(position0_z));
var position0_r21 = R.val(-2).mul((position0_x.mul(position0_z)).sub(position0_w.mul(position0_y)));
var position0_r31 = R.val(2).mul((position0_y.mul(position0_z)).add(position0_w.mul(position0_x)));
var position0_r32 = (position0_w.mul(position0_w)).sub(position0_x.mul(position0_x)).sub(position0_y.mul(position0_y)).add(position0_z.mul(position0_z));
var position0_heading = R.atan2(position0_r31, position0_r32);
var position0_asin_attitude = R.asin(position0_r21);
var position0_bank = R.atan2(position0_r11, position0_r12);
segments[i][k].transform.rotationX = position0_heading;
segments[i][k].transform.rotationY = position0_asin_attitude;
segments[i][k].transform.rotationZ = position0_bank;
if(i == 0 && k == 0){
segment0Connect.transform.position = segments[i][k].transform.position;
segment0Connect.transform.rotationX = segments[i][k].transform.rotationX;
segment0Connect.transform.rotationY = segments[i][k].transform.rotationY;
segment0Connect.transform.rotationZ = segments[i][k].transform.rotationZ;
}
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//segments start/end positions
function segmentPositions(){
var faceZOffset = 53.5;
var segmentXDirection = 0.025;
var segmentXOffset = 0;
var segmentYLength = 1;
var segmentZLength = 1;
for(var i = 0; i < segmentStreakTotal; i++){
for(var k = 0; k <= segmentSegmentTotal; k++){
var percentage = k/segmentSegmentTotal;
var bridgeToConnection0AttractionPerc = percentage;
var bridgeToConnection1AttractionPerc = R.vector(bridgeToConnection0AttractionPerc * bridgeToConnection0AttractionPerc, 0, bridgeToConnection0AttractionPerc * bridgeToConnection0AttractionPerc);
if(k == segmentSegmentTotal){
bridgeToConnection1AttractionPerc = 0;
}
var bridge = FT.face(0).cameraTransform.applyTo(facePosition.add(R.vector(segmentXOffset + (segmentXDirection * (k*k)), (Math.sin(Math.PI * percentage))*segmentYLength, k*segmentZLength))).add(R.vector(0,0,faceZOffset));
var bridgeToConnection0 = connection0.transform.position.sub(bridge);
var bridgeToConnection0Weight = bridge.add(bridgeToConnection0.mul(bridgeToConnection0AttractionPerc));
var bridgeToConnection1 = connection1.transform.position.sub(bridgeToConnection0Weight);
var bridgeToConnection1Weight = bridgeToConnection0Weight.add(bridgeToConnection1.mul(bridgeToConnection1AttractionPerc));
positions[i][k].transform.position = bridgeToConnection1Weight;
}
}
}
segmentPositions();
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// helplers
function getRandom(min, max) {
return Math.random() * (max - min) + min;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment