Last active
April 25, 2021 17:32
-
-
Save benursu/40e7456e114f669af9d249b845c83dda 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
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
// Chain | |
// @afrosquared | Ben Ursu | |
// Instagram | Spark AR Studio | SDK v111 | |
// 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'); | |
import { AssetsLoader } from './AssetsLoader'; | |
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
//vars | |
var rotation180 = Math.PI; | |
var rotation360 = Math.PI * 2; | |
var vectorForward = R.vector(1, 0, 0); | |
var facePosition = FT.face(0).forehead.top; | |
var facetracker0; | |
var connection0; | |
var connection1; | |
var segmentStreakTotal = 1; | |
var segmentSegmentTotal = 30; | |
var segment0Connect; | |
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
//scene | |
var objects = {}; | |
var materials = {}; | |
var textures = {}; | |
var PROJECT_OBJECTS = [ | |
'facetracker0', | |
'connection0', | |
'connection1', | |
'segment0_connect' | |
]; | |
for(var i = 0; i < segmentStreakTotal; i++){ | |
for(var k = 0; k < segmentSegmentTotal; k++){ | |
var segmentName = '**/segment' + i + '_' + k; | |
var segmentLineName = segmentName + '/line'; | |
var segmentLineCubeName = segmentLineName + '/cube'; | |
var segmentLineCubeNodeName = segmentLineCubeName + '/node-0' | |
PROJECT_OBJECTS.push(segmentName); | |
PROJECT_OBJECTS.push(segmentLineName); | |
PROJECT_OBJECTS.push(segmentLineCubeName); | |
PROJECT_OBJECTS.push(segmentLineCubeNodeName); | |
} | |
for(var k = 0; k <= segmentSegmentTotal; k++){ | |
PROJECT_OBJECTS.push('**/position' + i + '_' + k); | |
} | |
} | |
const PROJECT_MATERIALS = [ | |
]; | |
const PROJECT_TEXTURES = [ | |
]; | |
// Load assets | |
AssetsLoader({ | |
objects: PROJECT_OBJECTS, | |
materials: PROJECT_MATERIALS, | |
textures: PROJECT_TEXTURES | |
}).then(assets => { | |
objects = assets.objects; | |
materials = assets.materials; | |
textures = assets.textures; | |
facetracker0 = objects['facetracker0']; | |
connection0 = objects['connection0']; | |
connection1 = objects['connection1']; | |
segment0Connect = objects['segment0_connect']; | |
segmentsInit(); | |
segmentsLookAt(); | |
segmentsPositions(); | |
}).catch(err => { | |
D.log(err); | |
}); | |
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
//segments | |
var positions = []; | |
var segments = []; | |
var segmentLines = []; | |
var segmentLineCubes = []; | |
var segmentPositionRatios = []; | |
var segmentScaleRatios = []; | |
for(var i = 0; i <= segmentStreakTotal; i++){ | |
positions.push([]); | |
segments.push([]); | |
segmentLines.push([]); | |
segmentLineCubes.push([]); | |
segmentPositionRatios.push([]); | |
segmentScaleRatios.push([]); | |
} | |
function segmentsInit(){ | |
for(var i = 0; i < segmentStreakTotal; i++){ | |
for(var k = 0; k < segmentSegmentTotal; k++){ | |
var segmentName = '**/segment' + i + '_' + k; | |
var segmentLineName = segmentName + '/line'; | |
var segmentLineCubeName = segmentLineName + '/cube'; | |
var segmentLineCubeNodeName = segmentLineCubeName + '/node-0' | |
var segment = objects[segmentName][0]; | |
segment.hidden = false; | |
var segmentLine = objects[segmentLineName][0]; | |
var segmentLineCube = objects[segmentLineCubeName][0]; | |
var segmentLineCubeNode = objects[segmentLineCubeNodeName][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 = objects['**/position' + i + '_' + k][0]; | |
positions[i].push(position); | |
} | |
} | |
} | |
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
//segments lookat | |
function segmentsLookAt(){ | |
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 segmentsPositions(){ | |
var faceZOffset = 53.5; | |
var segmentXDirection = 0.025; | |
var segmentXOffset = 0; | |
var segmentYLength = 0.1; | |
var segmentZLength = 0.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.applyToPoint(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; | |
} | |
} | |
} | |
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
////////////////////////////////////////////////////////////////////////// | |
// 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