-
-
Save allanberger/f20da6bbc4a544eaaf1e1fa4916fb352 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
// 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