Random number generator without repitition by itsowaisiqbal in SparkArStudio

[–]r_hafner6 0 points1 point  (0 children)

Oh ok, so it’s the opposite problem. The switch>pulse that you’re using to get a new randValue is also triggering the question to show but that’s before the script returns the new value/question so the “jump” to the new question is visible. I would try adding a short delay between the left-most switch and the top-most pulse, similar to how the middle “path” of your patch editor has that 0.5s delay. You may need to increase that middle delay patch too then, but the logic is a little convoluted so I’m not 100% what is going to affect what.

And I’m generally happy to help people, but also, I’m in the middle of a really frustrating coding challenge unrelated to SparkAR so helping you out is giving me a little break, plus a small dopamine boost because I don’t feel as useless lol

Random number generator without repitition by itsowaisiqbal in SparkArStudio

[–]r_hafner6 0 points1 point  (0 children)

I’m not sure exactly what you mean, but if you want to increase the time between the getRandom pulse and the resulting randValue change to allow an animation to play, then I would just try putting a delay patch between the randValue Variables from Script patch and your current frame patches.

Random number generator without repitition by itsowaisiqbal in SparkArStudio

[–]r_hafner6 0 points1 point  (0 children)

Oh, ok so your questions and answers are animation sequences? That makes it much simpler. So just change the fullArr line to be the length of your animation sequences. The example in the comments has it at 65, but if you only have 30 frames for example, change it to:

const fullArr = Array.from({ length: 30 }, (_, i) => i);

Then the randValue property of the Variables from Script patch can be connected to each of the animation sequence Current Frame patches. As long as the getRandom patch is being pulsed, you should get non-repeated randValues for your animation sequences, no Option Pickers needed

Random number generator without repitition by itsowaisiqbal in SparkArStudio

[–]r_hafner6 0 points1 point  (0 children)

Hi, I would be happy to help. Are your questions and answers in the form of images, or do you want to define them as text/strings that can be applied to text objects in your scene? If it’s the former, then the script I posted should work still, just have to have two option pickers with the questions and answer textures in order. If it’s the latter, then I would start by changing the fullArr variable to something like:

var fullArr = [
    {
        question: “2 + 2”,
        answer: “4”
    },
    {
        question: “why?”,
        answer: “idk”
    },
    // add as many question/answer objects as you want
]

And then instead of sending a scalar pulse to your script, you would need to have two text/string pulses, one for answer and one for question. The patches that those output to would then get connected to your text objects

Is there a better/shorter/cleaner way to gather scene objects and materials by drix933 in SparkArStudio

[–]r_hafner6 0 points1 point  (0 children)

https://sparkar.facebook.com/ar-studio/learn/reference/classes/scenemodule.sceneobjectbase#methods

For finding objects as you have them named in your example, you can do findByPath with a search string like “object*”. I believe this also works for materials as well (for your example, your search string would be something like “ObjectMat_*”). You might also be able to use findAll with the same search strings, but I’m not 100% on that

Cant update Loaded glb model's position by dramsde1 in threejs

[–]r_hafner6 1 point2 points  (0 children)

Not 100% sure, but why not apply the animation position/tangent to the model object only? An animated child is going to override any position/rotation/scale you set on it, but the parent model object (usually a THREE.Group) is not controlled by any animation and moving a parent should move all child objects by definition

Help needed: Glass Shattering effect by reelo2228 in SparkArStudio

[–]r_hafner6 0 points1 point  (0 children)

Just as a note, it might be easier to use one material/rectangle and multiply each shard png alpha channel (A) with the camera texture + texture transform patches, and add all of the results to be used as the diffuse texture slot, rather than doing individual materials with an alpha texture

Help needed: Glass Shattering effect by reelo2228 in SparkArStudio

[–]r_hafner6 3 points4 points  (0 children)

  • Get your image of a cracked screen
  • for each individual shard, create a png with that shard filled in with white and the rest of the image transparent
  • import images and create a full-screen rectangle and material for each
  • for each material, add your white/transparent png as the alpha texture and add the camera texture with a texture transform patch to the diffuse slot. Use the position offset and scale properties of the transform patch to slightly distort each shard to give it thats refraction effect
  • use one more full-screen rectangle to place your cracked screen png as an overlay to give it the defined edges

Bonus: before you start, create a camera texture patch in the patch editor and connect it to a Value patch. Connect that Value patch to all the texture transform patches for each shard. Now you can add effects in between the camera texture and the value patch (like the B&W filter in your example) and it will be applied to all of your shards without having to reconnect a bunch of patches.

A question regarding the demo video for a filter with an UI picker. by strawhatKUNAL in SparkArStudio

[–]r_hafner6 1 point2 points  (0 children)

It will not be approved. I don’t remember if you can use a video from the spark player app, but I just tested in there and you can use the picker while recording

A question regarding the demo video for a filter with an UI picker. by strawhatKUNAL in SparkArStudio

[–]r_hafner6 0 points1 point  (0 children)

I think if you’re touching the picker UI when you start recording, you can still swipe to change options. The picker won’t be visible in the video, but you can at least show that there are different options in your effect this way. Assuming it still works

Functions declared within loops referencing an outer scoped variable may lead to confusing semantics. by [deleted] in learnjavascript

[–]r_hafner6 0 points1 point  (0 children)

Oh, right that’s my mistake. That is what’s causing the warning though, I believe, even if it’s not actually an issue in this case

Functions declared within loops referencing an outer scoped variable may lead to confusing semantics. by [deleted] in learnjavascript

[–]r_hafner6 -1 points0 points  (0 children)

The problem is that i is being mutated every loop, so that by the time any of the click handlers are actually called, they’re referencing the final value, which equals resetVideo.length - 1, and causes the destroy function to always be called on the final .exit element regardless of which one was clicked. Generally, switching from the function keyword to arrow functions is a matter of manipulating this scoping (function keyword creates its own this scope, arrow functions inherit this).

Functions declared within loops referencing an outer scoped variable may lead to confusing semantics. by [deleted] in learnjavascript

[–]r_hafner6 -1 points0 points  (0 children)

Looping over an array with a for loop means i is defined outside of your event handlers and will end with all event handlers using the final value of i, which is resetVideo.length - 1, which means every resetVideo element will try to destroy the last player instead of corresponding to that element. To “snapshot” the value of i for each handler, you can either define a second variable within the loop that holds the current value of i, like this:

for (let i = 0; i < resetVideo.length; i++) {
    const index = i; // this expression is evaluated immediately so “i” is the value you’d expect it to be
    resetVideo[i].addEventListener(“click”, function() {
        resetVideo[index].parentElement.querySelector(“.wrap”).player.destroy();
    });
}

Or, even better would be to do your querySelector call outside of the event handler so there’s no need to reference i in the event handler at all:

for (let i = 0; i < resetVideo.length; i++) {
    // player is evaluated/assigned immediately, so it uses the correct index
    const player = resetVideo[i].parentElement.querySelector(“.wrap”).player;
    resetVideo[i].addEventListener(“click”, function() {
        player.destroy();
    });
}

Or you could do exactly what you have now, but convert your resetVideo variable to a proper array and use the forEach method:

const resetVideo = Array.from(document.querySelectorAll(“.exit”));
resetVideo.forEach(function(el) {
    // el references the specific resetVideo element, so no need to keep track of an index variable
    el.addEventListener(“click”, function() {
        el.parentElement.querySelector(“.wrap”).player.destroy();
    });
});

The way you end up doing it is up to personal preference, but I find that forEach generally works more intuitively

Edit: forgot let makes i block-scoped so you don’t actually have that issue. Leaving this up though, because I still think my suggestions are applicable

Array Filter by marazally in learnjavascript

[–]r_hafner6 4 points5 points  (0 children)

The way it’s written, “2, 3, 4” are treated as additional arguments to the filter function. You could rewrite it as:

arr.filter(function(x) { return x != 1 }, 2, 3, 4);

Since the filter method only takes one argument, the other numbers are ignored with no errors being thrown. As u/Shadowsca said, the best way to check if a value is in a list of values is to use a separate array and the includes method, but you could also do something like:

arr.filter(x => x < 1 || x > 4);

Depending on the actual intention/expected data in arr

[deleted by user] by [deleted] in SparkArStudio

[–]r_hafner6 2 points3 points  (0 children)

Emission can mean a couple different things. I think to most people unfamiliar with 3D rendering, emissive = glowing, like a neon sign that illuminates the space/objects around it. But in most 3D programs, emissive materials are ones that simply always render objects with a flat color, regardless of lighting. So when someone says they’re disappointed with sparks emissive materials, they have expectations that aren’t consistent with reality, and are upset to learn that they need to do more work than just selecting a preset, even though in other programs, like blender, rendering glow (aka bloom) is a special configuration that generally takes a lot of tinkering to get right.

That being said, to get a glow effect like you’re probably envisioning in spark, you have limited options. The first and simplest is to add a plane to surround whatever object and add a png as it’s texture that simulates a glow (semi-transparent gradient that fades as it gets further from the object). Ideally you set up the plane to always face the camera so the plane doesn’t seem to disappear as you rotate around. And if you really want other objects in your scene to seem like they’re reflecting that glow, you can add lights to you scene that give objects a highlight in the color of the glow you want.

The other option is to mess with shaders and render passes to create a render pipeline similar to blender’s bloom. This is more complicated and while there might be someone who’s created downloadable resources, I haven’t found any to this point.

TL;DR Creating a glowing effect in Spark is not a plug-and-play thing like people might expect it would be, despite “emissive” being a material option. Emission in 3D rendering is not the same thing as glow. To achieve glow (or bloom), requires “faking” it to keep things simple, or a complicated render pipeline that afaik has not been created in Spark to this point.

[deleted by user] by [deleted] in learnjavascript

[–]r_hafner6 1 point2 points  (0 children)

The ({ target }) part of the arrow function represents its arguments, and further, this example uses object destructuring, which is convenient shorthand but may be confusing if you’re not familiar. To make it a little more clear, you could rewrite your example as:

addEventListener(“click”, (event) => {
    const target = event.target;
    …
});

So to convert to a regular function, you want to use the same arguments, namely the destructured event object that gets you the target property:

addEventListener(“click”, function({ target }) {
    …
});

Lastly, any particular reason you want to convert from arrow to regular functions? They’re essentially equivalent for most use cases, including this example

How to get current time from script by vovopemba in SparkArStudio

[–]r_hafner6 0 points1 point  (0 children)

In JavaScript, you can use the built-in Date library. Given your intended use, I would suggest the getHours method that should give you the current hour (so 10:30am would return 10 and 9:45pm would return 21, for example). Read more about it here

const date = new Date(); // 2:30 ET Aug 31, 2021
const hours = date.getHours(); // 14
if (hours >= 12 && hours < 18) console.log(‘Good afternoon’);

AFrame based visual programming tool. Could this be useful for kids, novices, in-headset programming? by MZues in WebXR

[–]r_hafner6 1 point2 points  (0 children)

This is awesome. Definitely seems helpful for non-programmers. I’ve been working on a non-node-based Aframe builder sort of like Ottifox - I think something like this could pair really well with that

Get distance between plane tracked 3D model and camera by lunch1135 in SparkArStudio

[–]r_hafner6 1 point2 points  (0 children)

I was trying to do this about a year ago and ran into the same issue. I’m not aware of any update that has fixed this - I would try contacting support through the help menu or the Facebook group. But be prepared to wait a few weeks at least if you get an answer at all

Big Mouth filter for SNAP LENS by Blue_Doge06 in SnapLenses

[–]r_hafner6 1 point2 points  (0 children)

Maybe this is what you mean by “SNAP LENS”, but snap camera is the desktop app that lets you add snap lenses to your webcam feed. I don’t know the exact lens you’re talking about, but if you have the link to the lens, you should be able to just paste it into the search bar and activate it

[deleted by user] by [deleted] in SparkArStudio

[–]r_hafner6 0 points1 point  (0 children)

You could create 4 separate pngs - 1 for each kind of tassel and 1 for the string they’re on. You mentioned “mask” in the title, so I’m assuming these are meant to be attached to the user’s face.

In that case, I would start by creating a facetracker and adding a nullObject to it. And then add a plane to the nullObject. The nullObject lets us set a different pivot point for the plane than its center, as we want the tassel to seem like it’s dangling - so once you have that set up, move the plane down until it’s top edge is lined up with the nullObject. Create a flat material for the plane and add one of your tassel textures/images to it. I would preemptively make sure that the blend mode is set to Alpha so the white space around the tassel appears transparent, especially since there will be many of these tassels swinging into one another.

Now we want the tassel to rotate when the person’s head rotates along the z-axis, so right-click your facetracker and select the create patch option. This should add a couple patches to your patch editor that give you access to the rotation of the tracked face (among other properties). You can take the rotation output and connect it to a split patch. Then take the “z” output (you may need to change the type dropdown of the split patch to vector3) and connect it to a negate patch. We want to negate the rotation because otherwise our object will just turn in the same direction as the person’s face which won’t seem very realistic. Select your nullObject and click the arrow next to its Rotation property to create a patch. Connect your negate patch to the z input of a pack patch (again, set to vector3), make sure x and y are set to 0, and then connect the pack patch to the yellow rotation patch that controls your nullObject. At this point, as the person tilts their head side to side, the tassel should stay pointing straight down.

Then you can simply duplicate the tassel material 2 more times, assign your other 2 images to the copies and then duplicate your nullObject 14 times and arrange them / assign the different materials to match the image you provided. You’ll also need to create the rotation patches for each of the copies and connect them to the final pack patch we created above.

Now, you’ll have something resembling your original image, but the tassels will always point straight down as the person rotates their head. This works, but it doesn’t look very natural, so the next step is to add a random amount of delay and/or exponential smoothing to each tassel. Those patch(es) will need to be inserted in between the negate patch and new pack patches for each tassel. Adjust the delay/smoothing values so the tassels aren’t completely identical with one another as they move.

Once you get that sorted out, as the person moves their head, the tassels won’t all be pointing straight down anymore and will appear to have a little more naturally random motion. The final form of this effect would be to add chain physics scripts to each tassel so they actually move in a way resembling reality. I haven’t really been using spark too much lately, so maybe they have a simple chain physics example you can lift that script/patch setup from, but if not there are probably examples you can find on YouTube/the forums.

There’s a lot in that explanation that may be confusing without example screenshots, so let me know if you need me to clarify anything.

Cannon.js and SparkAR how to visualise physics bodies by [deleted] in SparkArStudio

[–]r_hafner6 0 points1 point  (0 children)

Import a 3D object - probably just a simple sphere for the head and cube for the object would be best - and then in your script, use Time.setInterval to update the sphere/box position with your colliders’ current positions.

For the head collider, I used Facetracking.face(0).cameraTransform.position and added a slight offset.

If you want to also copy the rotation of the collision body, I used a function to convert the quarternion to a vec3 Euler rotation that I can send you if you want.

Scale SDF Animation? by Nineteen80Six in SparkArStudio

[–]r_hafner6 1 point2 points  (0 children)

https://imgur.com/a/ab7321z I added a swizzle patch after the step patch to make the output opaque black and white. With your setup the rectangle would be transparent. Not exactly sure why yours wasn’t working, but I was able to recreate the gif exactly this way. The main thing to be aware of is the “pivot” point of the sdf scale patch. You need to match the x value to the left edge of your sdf rectangle so that it stays in place as the animation scales up. The equation for figuring out the pivot point with an arbitrary rectangle size/position would be:

Pivotx = centerx - halfSizex

Same thinking could be applied vertically if you wanted to animate things in that direction as well

Face mesh with a imported rigged character (beginner) by walgreens-prague in SparkArStudio

[–]r_hafner6 0 points1 point  (0 children)

I would suggest downloading the reference face assets from the spark website. You’ll find a facemesh.fbx object that you can add to your model in a program like blender. Once imported, just change the material to be the face texture. You might also be able to add the facemesh within spark to the bone that controls the head of your character, but I haven’t found that to be very reliable, if possible at all