<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Augmented Reality - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Augmented Reality - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 23 May 2026 16:27:56 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/augmented-reality/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Augmented Reality Course – Take Your First Steps into the World of AR ]]>
                </title>
                <description>
                    <![CDATA[ Imagine transforming your surroundings with interactive digital overlays, creating new experiences, and changing the way you interact with the world around you. Welcome to the future – the future of Augmented Reality (AR).   The freeCodeCamp.org YouT... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/take-your-first-steps-into-the-world-of-augmented-reality/</link>
                <guid isPermaLink="false">66b2068939b555ffda8bfeba</guid>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Thu, 27 Jul 2023 13:00:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/augmented-reality.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Imagine transforming your surroundings with interactive digital overlays, creating new experiences, and changing the way you interact with the world around you. Welcome to the future – the future of Augmented Reality (AR).  </p>
<p>The freeCodeCamp.org YouTube channel just launched a comprehensive new course that will teach you how to implement Augmented Reality by creating four exciting projects. This course, developed by Priyanshu Bhattacharjee, is aimed at both beginners and more experienced developers who are interested in expanding their knowledge of Augmented Reality (AR).</p>
<h3 id="heading-about-the-course">About the Course</h3>
<p>This course is focused on Markerless Augmented Reality, a type of AR where users can place various digital objects in space without the need for a physical marker. You will be guided through building four distinct AR projects, each with a different theme: Engineering, Education, E-commerce, and Creativity. Each project is built using the Unity Engine and AR Foundation, setting a solid foundation for your future AR endeavors.</p>
<p>To ensure you receive a rounded experience, each project is designed to expose you to different uses of AR. Whether it's learning about our solar system, simulating a jet turbine, creating an AR garden, or visualizing how different furniture could fit into your home, these real-world applications give you a clear view of the potential of AR.</p>
<h3 id="heading-what-will-you-learn">What Will You Learn</h3>
<p>The course is structured into five main sections:</p>
<p><strong>Introduction to the Course &amp; Project Demonstration</strong>: In this initial section, Priyanshu introduces you to the course, sets expectations, and provides a sneak peek into the projects you will be working on.</p>
<p><strong>Building Planets AR with AR Foundation</strong>: The first project is an educational AR application named PlanetsAR. You will learn to develop an AR application that helps users learn about the planets in our solar system in an immersive and interactive way.</p>
<p><strong>Building Jet Turbine Simulation with AR Foundation</strong>: The second project delves into the world of engineering. You'll create an AR simulation of a jet turbine, allowing users to understand its operation and functionality.</p>
<p><strong>Building GardeniAR with AR Foundation</strong>: Here, you'll focus on the creative aspects of AR by building GardeniAR, an application that lets users plant a virtual garden in their own room.</p>
<p><strong>Building Furnish AR with AR Foundation</strong>: The final project centers around e-commerce and product visualization. Inspired by AR solutions used by Amazon and Flipkart, you'll develop FurnishAR, an application that lets users visualize how different furniture fits into their homes, an innovative solution to reduce product returns.</p>
<h3 id="heading-who-is-this-course-for">Who is this Course for?</h3>
<p>This course is designed to cater to anyone who wants to learn about Augmented Reality. Whether you are a beginner taking the first steps into AR, or a seasoned developer interested in expanding your skillset, this course offers valuable learning opportunities.</p>
<h3 id="heading-final-thoughts">Final Thoughts</h3>
<p>freeCodeCamp.org is devoted to democratizing education and providing accessible, quality learning resources to all. This new Augmented Reality course aligns perfectly with this ethos. </p>
<p>Watch the full course <a target="_blank" href="https://youtu.be/FJAO6jDYljs">on the freeCodeCamp.org YouTube channel</a> (2-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/FJAO6jDYljs" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Data-Driven Reality – Exploring the Power of AI, ML, Virtual and Augmented Reality ]]>
                </title>
                <description>
                    <![CDATA[ By now it's no secret that digital data is generated by the truckload and that it can be worth its weight in gold.  But that knowledge isn't half as important as understanding how you can tame the data beast and then wring out every drop of its value... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/data-driven-reality/</link>
                <guid isPermaLink="false">66b995d07bb37b73c3f3c4da</guid>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ big data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Tue, 21 Feb 2023 22:57:20 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/02/pexels-pixabay-164686.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By now it's no secret that digital data is generated by the truckload and that it can be worth its weight in gold. </p>
<p>But that knowledge isn't half as important as understanding <em>how</em> you can tame the data beast and then wring out every drop of its value.</p>
<p>Naturally, creative and resourceful people in one place or another are always finding new processes and applications that'll make better use of their data. So we'll explore some of today's dominant data utilization trends and leave predicting tomorrow's technology for the pundits.</p>
<p>This chapter was taken from my book, <a target="_blank" href="https://amzn.to/3FXXAfb">Keeping Up: Backgrounders to All the Big Technology Trends You Can't Afford to Ignore</a>. If you'd prefer to watch this chapter as a video, feel free to follow along here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/JvoguWXO-lg" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h1 id="heading-what-exactly-is-data">What Exactly Is Data?</h1>
<p>Before priming our understanding of what's available to help us work productively with data, it's a good idea to first define exactly what data is. </p>
<p>Sure, we saw plenty of great individual examples in my <a target="_blank" href="https://www.freecodecamp.org/news/how-to-manage-data-storage/">previous article on Managing Data Storage</a>, including the huge volumes of performance and status information produced by digital components of complex systems like cars. But that's not the same as a definition.</p>
<p>So then let's define it. Data, for our purposes, is any digital information that is generated by, or used for, your compute operations. That will include log messages produced by a compute device, weather information relayed through remote sensors to a server, digital imaging files (like CT, tomography and ultrasound scans), and the numbers you enter into a spreadsheet. And everything in between.</p>
<p>Which brings us to <em>big data</em> – another one of those buzz phrases that get thrown around a lot, often without accompanying context or clarity. </p>
<p>On a first glance, you'd probably figure that <em>big data</em> describes data sets that come in volumes higher than traditional data software and hardware solutions are capable of handling.</p>
<p>Indeed, your way of figuring it would be largely correct. Although we could add one or two secondary characteristics. The <em>complexity</em> of a data set, for instance, is also something that could force you to consider big data solutions. And sets of data that must be consumed and analyzed while in motion (<em>streaming data</em>) are also often better addressed using big data tools.</p>
<p>It's worth mentioning that big data workloads will often seek to solve large scale predictive analytics or behavior analytics problems. Such problems are common within domains like healthcare, Internet of Things (IoC), and information technology.</p>
<p>With that out of the way, we can now get to work understanding how – and why – all that data is being used.</p>
<h1 id="heading-virtual-reality-and-augmented-reality">Virtual Reality and Augmented Reality</h1>
<p>What? Plain old reality suddenly not good enough for you?</p>
<p>Well yes, in some cases, plain old reality really isn't good enough. At least if you have a strong interest in engaging in experiences that are difficult or impossible under normal conditions.</p>
<p>A virtual reality (VR) device lets you immerse yourself in a non-existent environment. </p>
<p>The most common examples of currently available VR technology feature some kind of headset that projects visual images in front of your eyes while tracking your head movements and, in some cases, the way you're moving other parts of your body. The visual images will adapt to your physical movements, giving you the sensation that you're actually within and manipulating the virtual projection.</p>
<p>VR has potential applications in educational, healthcare, research, and military fields. The ability to simulate distant, prohibitively expensive, or theoretical environments can make training more realistic and immediate than would be otherwise possible.</p>
<p>VR technologies have been arriving – and then disappearing – for decades already. For the most part, they've focused on providing immersive gaming and entertainment environments. But they've never really caught on in a big way beyond the niche product level. </p>
<p>This might be partly due to high prices, and because some people experienced forms of motion sickness and disorientation.</p>
<p>But maybe – just maybe – (insert the current year here) will finally be the year VR hits the big time.</p>
<p>But where VR can leverage data in a really meaningful way is when, rather than blocking out your physical surroundings, the virtual environment is overlaid <em>on top</em> of your actual field of vision. </p>
<p>Imagine you're a technician working on electrical switching hardware under a sidewalk. You're wearing goggles that let you see the equipment in front of you, but that also project text and icons clearly identifying labels for each part and that show you where a replacement part should go and how it's connected. This is <em>augmented reality.</em></p>
<p>I'm sure you can easily imagine how powerful this kind of dynamic display could be in the right conditions. </p>
<p>Surgeons are able to access a patient's history or even consult relevant medical literature without having to divert their eyes from the operation. Military pilots can similarly enjoy "heads up" displays that show them timely status reports describing their own aircraft and broader air traffic conditions without distraction.</p>
<h1 id="heading-artificial-intelligence-and-machine-learning">Artificial Intelligence and Machine Learning</h1>
<p>As a rule, computers are even better at performing dull, repetitive tasks over and over again than bored teenagers pretending to do homework. And they make less noise in the process.</p>
<p>The trick with computers is to cleverly string lots of dull, repetitive tasks together so that they can approximate intelligent and useful behavior. </p>
<p>The prize at the end of that road is called <em>automation.</em> Or, in other words, a state where computers can be confidently left alone to perform complex and useful tasks without supervision.</p>
<p>In many ways, we've been living in an age of sophisticated computer automation for decades. Domains as diverse as security monitoring, urban traffic control, book manufacturing, and heavy industry are already being handled with little or no human supervision. </p>
<p>But artificial intelligence (AI) seeks to go beyond relatively simple repetition to train computers to think for themselves – and thereby efficiently solve far more difficult problems.</p>
<p>Great idea. Somewhat harder to achieve in the real world.</p>
<h2 id="heading-what-can-ai-actually-do">What can AI actually do?</h2>
<p>Understanding how effective AI can be will depend on what you expect it to do. Can you design software to search for and flag a handful of suspicious financial transactions from among the millions of credit card transactions a large bank processes? Yes. (Although I'm not quite sure that's truly <em>AI</em> at work and not just automation.)</p>
<p>Can you deploy "intelligent" chatbots on your website to help customers solve their problems without needing actual (and expensive) human interaction? Yes. In fact, I just had a surprisingly effective conversation with my mobile phone carrier's chatbot that did quickly solve my problem.</p>
<p>Can the first stages of a rocket you've just used to launch a payload into space use AI to guide it to a safe landing on a moving platform in the middle of the ocean? If you'd ask me, I'd say it's impossible. But SpaceX went ahead anyway and did it multiple times. Good thing they didn't ask me.</p>
<p>But can AI reliably make strategic decisions that intelligently account for all the many moving parts and complexity that exist in your industry? Can an AI-powered machine pass the Turing test (where a human evaluator is unable to be sure whether the machine is also human)? Perhaps not just yet. And perhaps never.</p>
<p>One tool used in many AI processes is the neural network. The original neural network consists of the many neurons that carry information about the state of a biological environment to the brain. </p>
<p>Artificial and virtual neural networks are systems for assessing, processing, and responding to the large physical or virtual data sets that feed AI-controlled systems. </p>
<p>Such data can come from cameras or other physical sensors, or from multiple data sources. The processed data can sometimes be used for predictive modeling, where the likelihood of future outcomes are compared.</p>
<p>Exciting stuff, to be sure. But the tools used for some of the most significant accomplishments attributed to artificial intelligence aren't actually artificial. Nor did they necessarily require all that much intelligence.</p>
<p>For example, Amazon Mechanical Turk (MTurk) is a service that connects client companies with remote freelancing "human intelligence" workers. The workers will, for what usually amounts to dreadfully low pay, perform "mechanical" tasks like labelling the content of hundreds or thousands of images. The labelling will cover areas like "is the subject a male or female?" or "is the subject a car or a bus?"</p>
<p>It could be that, over time, services like Mechanical Turk will become less important as improving AI methodologies might one day completely replace the human element for this kind of work. But in the meantime, MTurk and its competitors are still steaming along at full speed, churning out millions of units of "artificial" artificial intelligence.</p>
<p>One methodology that can help reduce reliance on human intervention is machine learning (ML).</p>
<h2 id="heading-how-can-machine-learning-help">How can machine learning help?</h2>
<p>ML works by leveraging various kinds of manual assistance to help achieve greater task automation. An ML system can hopefully "learn" how to manage our tasks by being exposed to existing training data. Only once the system has demonstrated sufficient skill at solving the problems you have for it, will it be let loose on "real world" data.</p>
<p>These are some common approaches to training your ML system:</p>
<ul>
<li><strong>Supervised learning</strong> lets the ML software read data sets that include both "problems" (images, for example) and their "solutions" (full labels). By seeing enough of the provided examples, the system should be able to apply its experience to similar problems that arrive without solutions.</li>
<li><strong>Unsupervised learning</strong> simply throws raw data without any associated solutions at the system. The goal is for the software to recognize enough patterns in the data to allow it to solve the problems on its own.</li>
<li><strong>Reinforcement learning</strong> learns from interactions with its environment. Ideally, the software recognizes and understands positive results and evolves its methodology to reliably and consistently produce similar results.</li>
<li><strong>Deep learning</strong> algorithms apply multiple layers of analysis to transform the raw target data. The full, multi-layer process in deep learning is known as the <em>substantial credit assignment path</em> (CAP).</li>
</ul>
<p>AI in general, and ML in particular, are effective at building tools for tasks like autonomous driving, drug discovery, email filtering, and speech recognition, and for deriving sentiment analysis from massive data sets made up of human communications.</p>
<p>What AI and ML share in common with all the other technologies like virtual reality and augmented reality that we've discussed here – and in that <a target="_blank" href="https://www.freecodecamp.org/news/how-to-manage-data-storage/">other "How to Manage Data Storage" article</a> – is the need to control and make better sense of the endless streams of information our digital products keep generating. The better we get at this kind of control, the more value we'll get from our data.</p>
<p><em>YouTube videos of all ten chapters from this book <a target="_blank" href="https://www.youtube.com/playlist?list=PLSiZCpRYoTZ6UWl4xialvwLOKyHYYJUiC">are available here</a>. Lots more tech goodness - in the form of books, courses, and articles - <a target="_blank" href="https://bootstrap-it.com">can be had here</a>. And consider taking my <a target="_blank" href="https://www.udemy.com/user/david-clinton-12/">AWS, security, and container technology courses here</a>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Augmented Reality Full Course ]]>
                </title>
                <description>
                    <![CDATA[ Augmented reality is a technology that lets people superimpose digital content, such as images, sounds & text, over a real-world environment. We just published a 12-hour course on the freeCodeCamp.org YouTube channel that will teach you about augment... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/augmented-reality-full-course/</link>
                <guid isPermaLink="false">66b2009c712508eb160677fc</guid>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Thu, 31 Mar 2022 16:40:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/03/ar.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Augmented reality is a technology that lets people superimpose digital content, such as images, sounds &amp; text, over a real-world environment.</p>
<p>We just published a 12-hour course on the freeCodeCamp.org YouTube channel that will teach you about augmented reality from a theoretical and practical perspective.</p>
<p>Priyanshu Bhattaharjee developed this course. He has many years experience in AR development and has taught classes about AR at multiple colleges.</p>
<p>In this course you will learn to develop AR mobile applications and AR filters for Instagram and Facebook from scratch. You will also learn about concepts such as XR Fundamentals, Unity Engine, C#, Markerbased AR Development, and AR Filter development.</p>
<p>Here is the full syllabus for the course:</p>
<h3 id="heading-module-1-introduction-to-extended-reality">Module 1: Introduction To Extended Reality</h3>
<ul>
<li>Augmented Reality</li>
<li>Marker Based AR</li>
<li>Marker Less AR</li>
<li>Virtual Reality</li>
<li>Mixed Reality</li>
<li>XR Market Size</li>
</ul>
<h3 id="heading-module-2-introduction-to-unity-engine">Module 2: Introduction to Unity Engine</h3>
<ul>
<li>Introduction &amp; Installation</li>
<li>Navigating through interface</li>
<li>Game Objects</li>
<li>Materials</li>
<li>Scenes</li>
<li>Project Structure</li>
<li>Creating our first C# Script</li>
<li>Modifying Components</li>
<li>Prefabs</li>
<li>Physics and Collision</li>
<li>Audio</li>
<li>Designing User Interfaces</li>
</ul>
<h3 id="heading-module-3-introduction-to-c-scripting">Module 3: Introduction to C# Scripting</h3>
<ul>
<li>Introduction</li>
<li>Comments, Variables and Data Types</li>
<li>Operators</li>
<li>Conditionals</li>
<li>If Else, Else If</li>
<li>Inline if</li>
<li>Switch Case</li>
<li>Loops</li>
<li>For Loop</li>
<li>While Loop</li>
<li>Do While Loop</li>
<li>Arrays</li>
<li>Functions</li>
<li>Classes and Objects</li>
</ul>
<h3 id="heading-module-4-marker-based-augmented-reality">Module 4: Marker Based Augmented Reality</h3>
<ul>
<li>Introduction and Architecture</li>
<li>Software Development Kits</li>
<li>Vuforia Engine</li>
<li>Installation and Setting Up Vuforia Engine</li>
<li>Free Resources for developing AR Applications</li>
<li>Image Targets and Image Tracking</li>
<li>Simultanous Image Tracking</li>
<li>Virtual Buttons</li>
<li>Video Playback</li>
</ul>
<h3 id="heading-module-5-projects">Module 5: Projects</h3>
<ul>
<li>AR Car Customizer</li>
<li>AR Business Card</li>
<li>AR Encyclopedia</li>
</ul>
<h3 id="heading-module-6-bonus-ar-filters-with-spark-ar">Module 6: Bonus - AR Filters with Spark AR</h3>
<ul>
<li>Introduction to Spark AR</li>
<li>Interface</li>
<li>Face Tracking</li>
<li>Face Mesh</li>
<li>Head Occluder</li>
</ul>
<h3 id="heading-module-7-bonus-projects">Module 7: Bonus - Projects</h3>
<ul>
<li>3D Face Filter</li>
</ul>
<p>Watch the full course below or on <a target="_blank" href="https://youtu.be/WzfDo2Wpxks">the freeCodeCamp.org YouTube channel</a> (12-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/WzfDo2Wpxks" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How To Build A Super Quick Smile Tracking App ]]>
                </title>
                <description>
                    <![CDATA[ By Jake Shelley ARKit might seem intimidating but it’s not so bad if you already have some basic experience building iOS apps. I’m a learn-by-doing type, so I’ve been playing around with ARKit, building basic apps to get familiar with it. In this pos... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-super-quick-smile-tracking-app-16eee960888d/</link>
                <guid isPermaLink="false">66d45f31d1ffc3d3eb89de00</guid>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 23 Jan 2019 18:02:28 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*6zDrFfE7gE4IIoeiR3IJiw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Jake Shelley</p>
<p>ARKit might seem intimidating but it’s not so bad if you already have some basic experience building iOS apps.</p>
<p>I’m a learn-by-doing type, so I’ve been playing around with ARKit, building basic apps to get familiar with it. In this post, I’ll review what I’ve learned creating a simple face tracking app.</p>
<p>I’ll do this in 3 parts:</p>
<ol>
<li><strong>Initial Setup →</strong> First things first, get Camera permissions and make sure the device can use ARKit.</li>
<li><strong>Smile tracking →</strong> Start tracking smiles with ARKit. This is probably what you’re here for.</li>
<li><strong>User Interface →</strong> Add the UI for our app that will react to smiles.</li>
</ol>
<p>As of this writing, the Xcode simulator does not support the front facing camera <strong>so you will need a real device to run the app. Your device will also need to have a TrueDepth camera (iPhone X or newer should be fine).</strong></p>
<p>Finally, for my fellow members of the Copy Paste Club, <a target="_blank" href="https://github.com/JakeShelley1/SmileTracker">all the code is available on Github</a>.</p>
<h4 id="heading-initial-setup"><strong>Initial Setup</strong></h4>
<p>Start by opening up Xcode and creating a new project named “SmileTracker” (or whatever name you prefer).</p>
<p>Before we can get into face tracking, we’ll need to do two things:</p>
<ol>
<li>Make sure your device supports ARKit</li>
<li>Get permission to access your device’s camera</li>
</ol>
<p>In your new project, open <code>ViewController.swift</code>. Near the top of the file, underneath <code>import UIKit</code>, add the line: <code>import ARKit</code>. This will let us access all the goodies that Apple has provided us to make face tracking super easy.</p>
<p>Now add the following code inside of <code>viewDidLoad</code>:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">guard</span> <span class="hljs-type">ARFaceTrackingConfiguration</span>.isSupported <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">fatalError</span>(<span class="hljs-string">"Device does not support face tracking"</span>)
}
</code></pre>
<p><code>ARFaceTrackingConfiguration.isSupported</code> is a boolean that will be true if the device running the app can support face tracking and false if not. In this case, if the device can’t support face tracking, we’ll crash the app with a fatal error.</p>
<p>Next, let’s get permission to use the camera. Add the following in <code>viewDidLoad</code> below our <code>guard</code> statement:</p>
<pre><code class="lang-swift"><span class="hljs-type">AVCaptureDevice</span>.requestAccess(<span class="hljs-keyword">for</span>: <span class="hljs-type">AVMediaType</span>.video) { granted <span class="hljs-keyword">in</span>
   <span class="hljs-keyword">if</span> (granted) {
      <span class="hljs-type">Dispatch</span>.main.sync {
          <span class="hljs-comment">// We're going to implement this function in a minute</span>
          <span class="hljs-keyword">self</span>.setupSmileTracker()      
      }
   } <span class="hljs-keyword">else</span> {      
      <span class="hljs-built_in">fatalError</span>(<span class="hljs-string">"User did not grant camera permission!"</span>)   
   }
}
</code></pre>
<p>Here we’re asking the device to request camera permissions. If the user grants permissions, we’ll run the function that will setup our smile tracking (don’t worry about the error, we’ll be implementing this function in a moment).</p>
<p>We wrap the function in <code>Dispatch.main.sync</code> because we’ll be adding UI elements in this function, which can only be done on the main thread.</p>
<p>We’ll also need to add a Camera Usage Description to our <code>Info.plist</code>. Open <code>Info.plist</code> and add a new row (you can do this by highlighting the last row and hitting <code>enter</code>).</p>
<p>In the row you just created, add <code>Privacy — Camera Usage Description</code> to the <code>Key</code> column and make sure the <code>Type</code> column is set to string. You can leave the <code>Value</code> column blank or add a message to explain how you will use the camera to the user.</p>
<p>Your <code>Info.plist</code> should now look something like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/37EEOdiE1OAnLvGMi5SF4aU4ZL4KBlW8RSTu" alt="Image" width="800" height="289" loading="lazy"></p>
<p>If you’d like to test your app so far, you can comment out the line where we call <code>setupSmileTracker()</code>. Just remember to uncomment it later.</p>
<p>If you run your app now, you should see a popup asking you to enable camera permissions. <strong>If you say no you’ll have to go to application settings to enable those permissions in order for the app to run.</strong></p>
<p>If the app crashes, check the console for one of our two error messages to see what went wrong.</p>
<h4 id="heading-smile-tracking">Smile tracking</h4>
<p>Open <code>ViewController.swift</code> and add the following variable to the top of <code>ViewController</code>:</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ViewController</span>: <span class="hljs-title">UIViewController</span> </span>{   
   <span class="hljs-keyword">let</span> sceneView = ARSCNView()

   override func viewDidLoad() {...}
}
</code></pre><p><code>ARSCNView</code> comes equipped with an <code>ARSession</code> that your iPhone uses to coordinate AR experiences. We’ll be using <code>sceneView</code>’s <code>ARSession</code> to analyze our user’s face through the front facing camera.</p>
<p>Add this function to your file underneath <code>viewDidLoad</code>:</p>
<pre><code>func setupSmileTracker() {   
   <span class="hljs-keyword">let</span> configuration = ARFaceTrackingConfiguration()   
   sceneView.session.run(configuration)   
   sceneView.delegate = self   
   view.addSubview(sceneView)
}
</code></pre><p>Here we’ve created a configuration to handle face tracking and used it to run our <code>sceneView</code>’s <code>ARSession</code>.</p>
<p>Then we set <code>sceneView</code>'s delegate to self and add it to our view.</p>
<p>Xcode will tell you that there is a problem since <code>ViewController</code> does not conform to <code>ARSCNViewDelegate</code>. Go to where <code>ViewController</code> is declared near the top of the file and change the line to the following:</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ViewController</span>: <span class="hljs-title">ViewController</span>, <span class="hljs-title">ARSCNViewDelegate</span> </span>{   
   ...
}
</code></pre><p>Now add this<code>ARSCNViewDelegate</code> function in your <code>ViewController</code> class <code>setupSmileTracker</code>:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">renderer</span><span class="hljs-params">(_renderer: SCNSceneRenderer, didUpdate node: SCNNode, <span class="hljs-keyword">for</span> anchor: ARAnchor)</span></span> {
   ...
}
</code></pre>
<p><code>renderer</code> will run every time our scene updates and provides us with the <code>ARAnchor</code> that corresponds to the user’s face.</p>
<p>To make it easier to create face tracking experiences, <strong>Apple automatically creates an</strong> <code>ARFaceAnchor</code> <strong>and adds it to our session when we use an</strong> <code>ARFacetrackingConfiguration</code> <strong>to run it.</strong> This ARFaceAnchor is then passed into <code>renderer</code> as an <code>ARAnchor</code>.</p>
<p>Add the following code to renderer:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">renderer</span><span class="hljs-params">(_renderer: SCNSceneRenderer, didUpdate node: SCNNode, <span class="hljs-keyword">for</span> anchor: ARAnchor)</span></span> {   
   <span class="hljs-comment">// 1      </span>
   <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> faceAnchor = anchor <span class="hljs-keyword">as</span>? <span class="hljs-type">ARFaceAnchor</span> <span class="hljs-keyword">else</span> { <span class="hljs-keyword">return</span> }

   <span class="hljs-comment">// 2   </span>
   <span class="hljs-keyword">let</span> leftSmileValue = faceAnchor.blendshapes[.mouthSmileLeft] <span class="hljs-keyword">as</span>! <span class="hljs-type">CGFloat</span>
   <span class="hljs-keyword">let</span> rightSmileValue = faceAnchor.blendShapes[.mouthSmileRight] <span class="hljs-keyword">as</span>! <span class="hljs-type">CGFloat</span>

   <span class="hljs-comment">// 3</span>
   <span class="hljs-built_in">print</span>(leftSmileValue, rightSmileValue)
}
</code></pre>
<p>There’s a lot going on inside this function so I’ve numbered the steps (Ray Wenderlich style).</p>
<p>In <strong>step 1</strong> we convert the <code>ARAnchor</code> into an <code>ARFaceAnchor</code> and assign it to the <code>faceAnchor</code> variable.</p>
<p><code>ARFaceAnchor</code> contains information about the current position and orientation, topology, and <em>facial expression</em> of the face we’re tracking.</p>
<p><code>ARFaceAnchor</code> stores information about facial expressions in its variable <code>blendShapes</code>. <code>blendShapes</code> is a dictionary that stores coefficients corresponding to various facial features. If you’re interested, I suggest you <a target="_blank" href="https://developer.apple.com/documentation/arkit/arfaceanchor/blendshapelocation">check out the full list of facial features in Apple’s documentation</a>. (<em>Hint</em>: if you want to add frown tracking you’ll find a way to do it in here.)</p>
<p>In <strong>step 2</strong>, we use <code>faceAnchor.blendShapes</code> to get the a CGFloat that corresponds to how much the left and right sides of the user’s mouth is smiling by using the keys <code>mouthSmileLeft</code> and <code>mouthSmileRight</code>.</p>
<p>Finally, <strong>step 3</strong> just prints out the two values so you can make sure it’s working properly ?.</p>
<p>At this point you should have an app that:</p>
<ul>
<li>Gets camera and face tracking permissions from the user</li>
<li>Uses ARKit to track the users facial expressions</li>
<li>Prints how much the user is smiling on the left and right sides of their mouth to the console</li>
</ul>
<p>We’ve made a lot of progress, so let’s take a second to make sure everything is running properly.</p>
<p>When you run the app for the first time, you should be asked if you will grant camera permissions. Make sure to say yes.</p>
<p>You’ll then be sent to a blank screen, but you should start seeing CGFloat values being printed to the console (there may be a short delay before you see them).</p>
<p>When you smile at your phone you should notice the values being printed going up. The more you smile the higher the numbers go.</p>
<p>If it’s working properly, <em>congratulations</em> ?! If you’re running into an error, double check to make sure your device supports face tracking and you have camera permissions turned on. If you’ve been following this writeup from the beginning the console will print errors in both those cases.</p>
<h4 id="heading-user-interface">User interface</h4>
<p>So we’re tracking faces, now let’s build the UI to react to smiles.</p>
<p>First add a new <code>UILabel</code> called <code>smileLabel</code> to the top of the file, just below <code>sceneView</code>.</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ViewController</span>: <span class="hljs-title">UIViewController</span> </span>{   
   <span class="hljs-keyword">let</span> sceneView = ARSCNView()      
   <span class="hljs-keyword">let</span> smileLabel = UILabel()

   ...
}
</code></pre><p>This will be the view that reacts to the user’s facial expressions.</p>
<p>Add the following code at the bottom of your <code>setupSmileTracker</code> function:</p>
<pre><code class="lang-swift">smileLabel.text = <span class="hljs-string">"?"</span>smileLabel.font = <span class="hljs-type">UIFont</span>.systemFont(ofSize: <span class="hljs-number">150</span>) 

view.addSubview(smileLabel)

<span class="hljs-comment">// Set constraints</span>
smileLabel.translatesAutoresizingMaskIntoConstraints = <span class="hljs-literal">false</span>
smileLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = <span class="hljs-literal">true</span>
smileLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = <span class="hljs-literal">true</span>
</code></pre>
<p>Here, we’re adding the basic UI properties to our <code>smileLabel</code> and setting its constraints so it is in the middle of the screen. Now when you run the app, you should see a giant ? emoji in the middle.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0t8auH8IkMfU3ZWeKCG28hKVOpsCznKA9Q8N" alt="Image" width="320" height="693" loading="lazy"></p>
<p>Once you see the emoji appear, add the following function to your <code>ViewController</code>:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">handleSmile</span><span class="hljs-params">(leftValue: CGFloat, rightValue: CGFloat)</span></span> {
   <span class="hljs-keyword">let</span> smileValue = (leftValue + rightValue)/<span class="hljs-number">2.0</span>
   <span class="hljs-keyword">switch</span> smileValue {      
         <span class="hljs-keyword">case</span> <span class="hljs-number">_</span> <span class="hljs-keyword">where</span> smileValue &gt; <span class="hljs-number">0.5</span>:         
           smileLabel.text = <span class="hljs-string">"?"</span>      
      <span class="hljs-keyword">case</span> <span class="hljs-number">_</span> <span class="hljs-keyword">where</span> smileValue &gt; <span class="hljs-number">0.2</span>:         
         smileLabel.text = <span class="hljs-string">"?"</span>      
      <span class="hljs-keyword">default</span>:         
         smileLabel.text = <span class="hljs-string">"?"</span>      
   }
}
</code></pre>
<p>This function will change the emoji in our <code>smileLabel</code> depending on how much the user is smiling into the camera. We calculate the <code>smileValue</code> by taking the average of the left and right smile values given to us by our <code>ARFaceAnchor</code> (very scientific, I know).</p>
<p>Plug that value into the switch statement, and the more the user smiles the happier our emoji gets.</p>
<p>Finally, go back to our <code>renderer</code> function and add this to the bottom to plug in our left and right smile values into <code>handleSmile</code>:</p>
<pre><code>DispatchQueue.main.async {   
   self.handleSmile(leftValue: leftSmileValue, <span class="hljs-attr">rightValue</span>: rightSmileValue)
}
</code></pre><p>Again, we use <code>DispatchQueue</code> because we are making changes to the UI, which must be done on the main thread.</p>
<p>When you run the app you should now see the emoji change depending on how much you smile at it.</p>
<p>In the gif below I’ve added my face so that you can see it working with the camera output along with the emoji.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/54NIZPz4oKKzBmkNMjJw654tlemCDBH6ZRQA" alt="Image" width="280" height="660" loading="lazy">
<em>I added the camera output to show how it works</em></p>
<p>Your app won’t have the camera output, but you can add it by adding our <code>ARSCNView</code>, <code>sceneView</code>, to the superview and giving it dimensions.</p>
<h4 id="heading-wrapping-up">Wrapping up</h4>
<p>I hope this post was helpful for you to get started creating apps with ARKit.</p>
<p>If you want to extend this app further, check out the list I mentioned above with all the other facial features you can track. I left a hint for how to extend this to check for frowns as well.</p>
<p>Come back and comment with any cool projects you create on your own, I’m still getting my feet wet with this stuff so it’d be excited to see more complex apps.</p>
<p><a target="_blank" href="https://github.com/JakeShelley1/SmileTracker">I’ve posted all the code for this app up on Github</a> for feedback and questions. Thanks for reading and good luck!</p>
<hr>
<p><em>Thanks so much for reading! If you liked this story, follow me on <a target="_blank" href="https://twitter.com/JakeShelley3">Twitter</a> where I post updates about stories I’m working on and what I’m up to.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Why you should do Augmented Reality if you are a JavaScript developer — and how to start ]]>
                </title>
                <description>
                    <![CDATA[ By Evaristo Caraballo If you are a JavaScript coder who is still late to making up a definitive list of resolutions for 2019, let me give you a hand: Start figuring out how to get into Augmented Reality (AR). The Augmented/Mixed/Virtual Reality (AR/M... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/an-intro-to-augmented-reality-for-the-javascript-developer-with-an-example-71875ab184ee/</link>
                <guid isPermaLink="false">66c343f242d4db64acf4cbc8</guid>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Virtual Reality ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 11 Jan 2019 16:43:29 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*hIfbsKuXmHPb0qEKvotZ4A.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Evaristo Caraballo</p>
<p>If you are a JavaScript coder who is still late to making up a definitive list of resolutions for 2019, let me give you a hand: Start figuring out how to get into Augmented Reality (AR).</p>
<p>The Augmented/Mixed/Virtual Reality (AR/MR/VR) combo has enjoyed frenetic growth since 2016, coming from a <a target="_blank" href="https://www.statista.com/statistics/591181/global-augmented-virtual-reality-market-size/">marginal market value</a> of bit more than $6 Billion to one that might reach the $210 Billion in sales (including hardware) by 2022. Of all, <a target="_blank" href="https://www.telecompetitor.com/ar-vr-forecast-bad-quarter-good-future/">Augmented Reality</a> is the one experiencing steady growth.</p>
<p>At first, a JavaScript (web) developer wanting to get into the AR boat might feel discouraged when finding <a target="_blank" href="https://blog.pusher.com/how-you-can-become-an-ar-vr-developer/">the usual required skills</a>; and then there is who ask <a target="_blank" href="https://medium.freecodecamp.org/8-ways-ai-makes-virtual-augmented-reality-even-more-real-25037707cfa1">Machine Learning</a> or Internet of Things. However if you are mainly a JavaScript developer, consider yourself blessed: the language is <a target="_blank" href="https://www.quora.com/What-programming-language-is-used-to-create-virtual-reality-experiences-and-programs">recurrently mentioned</a> as one you should know to enter this sector. The reason? Right now <strong>a lot of AR development goes on the web</strong>. And this is where JavaScript reigns.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*m3EEXIiH_ZXxVzl-7-grLg.png" alt="Image" width="800" height="567" loading="lazy">
_Mobile and Web were the last getting AR capabilities, and are still developing (extract from a [buildAR presentation](https://www.slideshare.net/robman/web-standards-adoption-in-the-ar-market/6" rel="noopener" target="<em>blank" title="))</em></p>
<h3 id="heading-augmented-jobs-for-the-javascript-fan-really">Augmented Jobs for the JavaScript-fan — Really?</h3>
<p>Maybe not too fast. There are many examples where AR/MR/VR shines on its own, specially in niche markets, but the industry hasn’t completely figured out the full value of the technology for the general consumer. Once that it solved, the industry would be certainly making more AR/MR/VR products, which would translate into more jobs.</p>
<p>For some analysts AR is expected to have the most pervasive impact, in part because it doesn't require <a target="_blank" href="https://www.quora.com/What-are-some-good-VR-AR-hardware-devices-that-not-many-people-know">specific devices and conditions</a> to be implemented as VR does.</p>
<blockquote>
<p>AR has utility for almost everything, overlaying useful and relevant information on the world around you. AR can be pervasive in a way that VR cannot.</p>
<ul>
<li>David McQueen -Strategy Analytics- <a target="_blank" href="https://www.twice.com/product/ces-2018-how-disruptive-can-vr-ar-become-roundtable-discussion">from an interview on Twice</a></li>
</ul>
</blockquote>
<p>It rests on the industry to find how to make AR a more every day life tech. According to some companies, particularly within the mobile phone realm, exploiting better the AR potential reduces to a well-known rule: <em>SIMPLICITY</em>.</p>
<blockquote>
<p>While Unity has become the default path for building AR apps, an increasing number need only a sprinkling of AR.</p>
<ul>
<li>from an <a target="_blank" href="https://medium.com/homestory-ar/building-an-ar-ai-furniture-app-with-react-native-1847bc1fcbaa">article</a> by <a target="_blank" href="https://www.freecodecamp.org/news/an-intro-to-augmented-reality-for-the-javascript-developer-with-an-example-71875ab184ee/undefined">Benjamin Devine</a>, Homestory AR</li>
</ul>
</blockquote>
<p>In many cases, resourcing onto the leading AR tools could be an overkill. Instead, a bunch of good UX-driven features over some 2D/3D assets could be more than enough to make striking products. Something a JavaScript developer regularly does.</p>
<p>It is then possible that any JavaScript developer will be embedding (non)standard AR/VR features as an extension of their traditional duties in the future. And if required, JavaScript is robust enough for more complex tasks. The sky is the limit.</p>
<h3 id="heading-becoming-javascript-augmented">Becoming JavaScript-Augmented</h3>
<p>Before starting, I would suggest to have a look at the several AR platforms and standards. The same technical constraints affecting the industry are also reflected in the AR world.</p>
<p>For example, there are several platforms, one for each Big Tech (Google = <a target="_blank" href="https://developers.google.com/ar/discover/">ARCode</a>, Apple = <a target="_blank" href="https://developer.apple.com/arkit/">ARKit</a>, MS = <a target="_blank" href="https://github.com/microsoft/chakracore">ChakraCore</a>, Facebook = <a target="_blank" href="https://developers.facebook.com/blog/post/2018/05/01/ar-studio-create-distribute/">AR Studio</a>, <a target="_blank" href="https://facebook.github.io/react-360/">React 360</a>, Mozilla = <a target="_blank" href="https://aframe.io/">aframe</a>).</p>
<p>After having a quick look at the options, starting fully JavaScript’ed Augmented Reality projects is relatively easy. You can begin by taking any web/app dev framework like <a target="_blank" href="https://cordova.apache.org/">Cordova</a>, <a target="_blank" href="https://ionicframework.com/">Ionic</a>, <a target="_blank" href="https://facebook.github.io/react-native/">React Native</a> or <a target="_blank" href="https://vue-native.io/">Vue Native</a> to embed the AR framework of your choice — and deploy 3D assets on top of the real world.</p>
<p>If what you want is to deploy on the web using mostly marker-based AR, you could use GitHub repos like <a target="_blank" href="https://github.com/jeromeetienne/AR.js">AR.js</a> (free), <a target="_blank" href="https://www.argonjs.io/">argon.js</a> (free but limited) or <a target="_blank" href="https://awe.media/">awe.js</a> (paid PaaS but with an old GitHub repository still available). There are a few tailored ones that are harder for the novice, many of them focused on things like facial/head recognition (such as <a target="_blank" href="https://trackingjs.com/">tracking.js</a> and <a target="_blank" href="https://github.com/auduno/headtrackr">headtrackr</a>).</p>
<p>Or you can boost your project capabilities if you are able to port available SDKs made by <a target="_blank" href="http://socialcompare.com/en/comparison/augmented-reality-sdks">AR-related companies</a>. There are many APIs that render as AR on browser too. For example, <a target="_blank" href="https://www.mapbox.com/">Mapbox</a> follows that path and it is developed on JavaScript.</p>
<p>I would suggest you to keep it simple but interactive.</p>
<p>However if your ambitions point to also mastering design and animation in JavaScript, you definitively have to learn at least one <a target="_blank" href="https://1stwebdesigner.com/3d-javascript-libraries/">3D Javascript package</a>, and <a target="_blank" href="https://threejs.org/">THREE.js</a> the most popular. Wait, though, until you have gained a good base of JavaScript and <a target="_blank" href="https://www.opengl.org/">OpenGl</a> as well as geometry, trigonometry, linear algebra or physics. And don’t expect more help from the existing 3D JS GUIs; in particular, THREE.js has none. Challenging but exciting!</p>
<h3 id="heading-bonus-example">Bonus Example</h3>
<p>I wanted to prepare a quick demo just to explore the technology, so I took a nice CodePen and modified it to fit a marker-based web-rendered AR animation ported within a clone of <a target="_blank" href="https://github.com/stemkoski/AR-Examples">Stemkoski's</a> <a target="_blank" href="https://stemkoski.github.io/AR-Examples/">great work</a> with AR.js.</p>
<p>For you to see the example you need <em>a mobile device with a camera</em> and internet (phone or tablet), and either a printed copy of <em>the marker</em> or another device to show it on screen.</p>
<p>Ready? Now open this <a target="_blank" href="https://evaristoc.github.io/ARexample/">link</a> using a browser in your mobile device:</p>
<p><a target="_blank" href="https://evaristoc.github.io/ARexample/">https://evaristoc.github.io/ARexample/</a></p>
<p>Give authorization to use your camera, and point the camera <strong>to a marker like below</strong>, either printed or in another screen.</p>
<p><strong>NOTE:</strong> works on Android and Chrome — it might not work for other devices and browsers ?.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*7g9MciK6LR-9VRcH-LePSQ.png" alt="Image" width="512" height="512" loading="lazy">
_The original animation can be found [here](https://codepen.io/rainner/details/LREdXd" rel="noopener" target="<em>blank" title=").</em></p>
<p>Happy New Year!</p>
<p>I hope you will find this technology as fascinating as I do. If so, don't stay alone: contact us at the <a target="_blank" href="https://www.freecodecamp.org/forum/">freeCodeCamp forum</a> and share your questions and ideas.</p>
<p>And if you liked this article, don't forget to give it a ? and to share it on social media.</p>
<p>Thanks for reading, enjoy AR and Happy Coding!!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to use Augmented Reality with JavaScript — a case study ]]>
                </title>
                <description>
                    <![CDATA[ By Apurav Chauhan In this experiment, I talk about how Augmented Reality with JS can be used to make learning more fun and interactive. The case study will discuss the design process, implementation and feedback from children in the age group 2 to 10... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/augmented-reality-with-javascript-a-case-study-c9cffaadcf07/</link>
                <guid isPermaLink="false">66c34510790a62b5fbf7b888</guid>
                
                    <category>
                        <![CDATA[ AR ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Virtual Reality ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 21 Dec 2018 13:28:42 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*evN61t_cenPxPZgDZOB2Mw.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Apurav Chauhan</p>
<p>In this experiment, I talk about how Augmented Reality with JS can be used to make learning more fun and interactive. The case study will discuss the design process, implementation and feedback from children in the age group 2 to 10 years.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*evN61t_cenPxPZgDZOB2Mw.png" alt="Image" width="800" height="276" loading="lazy">
<em>Education and Interactive Alphabets learning using Augmented Reality and Javascript</em></p>
<p>Augmented Reality (AR) has always attracted me, and in this experiment, I try to create a practical AR application. The use-case we will cover is primary education and we will see how we can make the learning fun and interactive. We will make an app to learn alphabets in three languages primarily: Punjabi, Hindi, and English.</p>
<p><em>The Javascript Augmented Reality app currently doesn’t have plane detection. For simplicity’s sake we are only superimposing our objects over the viewport with 3d motion tracking.</em></p>
<h4 id="heading-end-goal">END GOAL</h4>
<p>Below is a demo of our Javascript AR experiment. You can download and play with the app <a target="_blank" href="https://play.google.com/store/apps/details?id=com.webilm.games.arlearning&amp;hl=en">here</a>.</p>
<p>The full code has been open-sourced for learning purposes and is available <a target="_blank" href="https://github.com/apuravchauhan/augmented-reality-javascript">here</a>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*nfxElKKhaa0zlcdODDdtPg.jpeg" alt="Image" width="800" height="1600" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*O6FCNchAd2dNaJwK32GL-A.jpeg" alt="Image" width="800" height="1600" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*UKBmHOO3uW7NIKuoHYDNXA.jpeg" alt="Image" width="800" height="1600" loading="lazy">
<em>Alphabets in augmented reality and javascript to make education more fun and engaging</em></p>
<h3 id="heading-the-design-process">The Design Process</h3>
<p>To make the learning fun and effortless, I am relying on the following points:</p>
<ol>
<li>Active participation of the child</li>
<li>Child’s physical activity instead of sitting in one place</li>
<li>A bit of effort in finding the alphabets.</li>
<li>Intuitive UX/UI.</li>
</ol>
<p>The core theme of the app will be quite similar to the famous Pokemon Go Augmented reality app. Only two main components will be involved: the <strong>Camera Viewport</strong> and <strong>Alphabets</strong>.</p>
<h4 id="heading-alphabet-ux-for-ar-game">Alphabet UX for AR Game</h4>
<p><em>Iteration 1</em></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*_711pNZKifCSaa9bXWbc5g.png" alt="Image" width="640" height="640" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*YdiDXaHGXYKPMD1gdGbZaw.png" alt="Image" width="640" height="640" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*EmkTDWxyVZYcqA9vn2Ixtg.png" alt="Image" width="640" height="640" loading="lazy">
<em>2d Alphabets in English, Hindi and Punjabi for our JS Augmented Reality Game</em></p>
<p>In our first iteration we have 2d alphabets which we will try to merge in our camera viewport. The idea of the Augmented Reality(AR) app is to have children find these alphabet letters in a room or space around them. The prototype after merging the space with 2d alphabets will look something like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*gu70VjYLyFLzzmMvhafZyA.gif" alt="Image" width="984" height="1132" loading="lazy">
<em>AR Motion sensor with 2d object</em></p>
<p>As you can see above, the immersive experience is missing with a 2d model because the human eye sees things in 3d.</p>
<p><em>Iteration 2</em></p>
<p>Lets try to create a 3d model and see if we can improve the experience of our Javascript-based Augmented Reality game:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*lHUszUcxZfFJj0f81Ebixg.gif" alt="Image" width="640" height="553" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*cyXqdHs11SmHwICi-P461g.gif" alt="Image" width="640" height="495" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*GK2PuNQlEEJU8FY9edCR8A.gif" alt="Image" width="640" height="512" loading="lazy">
<em>3D Alphabets in English, Hindi and Punjabi for our AR project</em></p>
<p>And below is the comparison of the experience of a motion sensor with 2d vs 3d alphabet models. As you can see, 3D naturally gives you a much more immersive experience when it comes to Augmented reality.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*gu70VjYLyFLzzmMvhafZyA.gif" alt="Image" width="984" height="1132" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*IPTMBO-kP6EcqhL0tDD_8A.gif" alt="Image" width="1020" height="1092" loading="lazy">
<em>2d vs 3d AR motion experience</em></p>
<h3 id="heading-the-ar-implementation-process">The AR Implementation process</h3>
<p>To implement the above AR concept, I’ll be using the following tools and technologies:</p>
<ol>
<li><a target="_blank" href="https://ionicframework.com">Ionic Framework</a>: For building the hybrid app</li>
<li><a target="_blank" href="https://aframe.io/">Aframe</a>: For bringing the Virtual reality (VR) and Augmented Reality (AR) experience to our app</li>
<li><a target="_blank" href="https://ephtracy.github.io/">MagicaVoxel</a>: For creating our 3D models</li>
</ol>
<p>The basic app building process is very simple. You can follow my earlier post to learn how to go about building and deploying an app using the Ionic framework <a target="_blank" href="https://codeburst.io/part-1-simple-ionic-tutorial-from-scratch-from-0-to-live-app-9a79db510a90">here</a>.</p>
<p>Once you have followed the above tutorial to create a simple app, it’s time to integrate Aframe to bring our 3D alphabets with motion sensors into our app.</p>
<p>Just load the below Aframe core and Aframe loader libraries in ionic’s project index.html file:</p>
<pre><code>&lt;script src=<span class="hljs-string">"https://aframe.io/releases/0.8.2/aframe.min.js"</span>&gt;&lt;/script&gt;
</code></pre><pre><code>&lt;script src=<span class="hljs-string">"https://rawgit.com/donmccurdy/aframe-extras/v2.1.1/dist/aframe-extras.loaders.min.js"</span>&gt;&lt;/script&gt;
</code></pre><p>With this we are ready to do some AR/VR magic in our Javascript code base.</p>
<p>Now in your home component’s home.html, let’s include our 3D models exported from magicavoxel:</p>
<p>And this should make a 3D scene ready for interaction with all motion sensors ready:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*fref3HwlAuN0AJ9VHRaWhQ.gif" alt="Image" width="2708" height="1092" loading="lazy">
<em>Final 3D Virtual Reality scene ready with 3D alphabets</em></p>
<h4 id="heading-adding-augmented-reality-effect">Adding Augmented Reality Effect</h4>
<p>The final part of this experiment is to add the Augmented Reality (AR) feeling in our Javascript-based hybrid app. As already explained, Augmented Reality is when you superimpose 3D models or other objects on top of your camera viewport. So the only thing missing is the camera viewport behind our scene.</p>
<p>To do this, we use the camera preview plugin as explained <a target="_blank" href="https://ionicframework.com/docs/native/camera-preview/">here</a>. And here is the full gist after integration with the camera preview plugin:</p>
<p>We also need to ensure that our backgrounds are transparent so that the camera preview is visible in mobile. This is very <strong>IMPORTANT</strong> otherwise you might feel that the plugin is not working. Here is the home.scss file with transparency css enabled:</p>
<p><strong>And this is what it would finally look like:</strong></p>
<h4 id="heading-user-reaction-to-our-augmented-reality-js-game">User reaction to our Augmented reality JS game</h4>
<p>The final step to measure the success of your concept is real user validation — in our case, kids :) And below is their live feedback recorded.</p>
<p>It was pretty clear that each one of them enjoyed the game and we got full points on fun part. However, initially I had to tell them to move the phone in space to find the letters. Points lost in terms of intuitiveness :(</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Fe97s79RI5BFONl9X5T27w.png" alt="Image" width="800" height="247" loading="lazy">
<em>Points scored out of 10</em></p>
<h4 id="heading-user-feedback-for-augmented-reality-js-game">User feedback for Augmented Reality JS game</h4>
<h3 id="heading-final-thoughts">Final Thoughts</h3>
<p>Well it was an exciting project and I could see a lot of potential for Augmented Reality in learning and education. Children really like it and it surely adds the missing fun factor to education, especially in our monotonous Education system.</p>
<p>Feel free to comment and share your feedback.</p>
<h3 id="heading-downloads">Downloads</h3>
<p>The code for this app is available in <a target="_blank" href="https://github.com/apuravchauhan/augmented-reality-javascript">github</a>. Feel free to play and push new features in it. I’ll be happy to push updates over production.</p>
<p>You can download the app for android <a target="_blank" href="https://play.google.com/store/apps/details?id=com.webilm.games.arlearning&amp;hl=en">here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build an Augmented Images Application with ARCore ]]>
                </title>
                <description>
                    <![CDATA[ By Ayusch Jain This article was originally posted here. In this tutorial, you’ll learn how to place 3D models in the real world by setting the anchor as a specific scene instead of a regular plane. ARCore by Google lets you augment 2D images which ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-an-augmented-images-application-with-arcore-93e417b8579d/</link>
                <guid isPermaLink="false">66c3501d9972b7c5c7624ec8</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 28 Nov 2018 22:56:10 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/0*zDtfBdMWSJNSZgyx.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ayusch Jain</p>
<blockquote>
<p>This article was originally posted <a target="_blank" href="https://ayusch.com/arcore-building-augmented-images-application">here</a>.</p>
</blockquote>
<p>In this tutorial, you’ll learn how to place 3D models in the real world by setting the anchor as a specific scene instead of a regular plane. <strong>ARCore</strong> by Google lets you augment 2D images which can be recognized by ARCore to then place 3D models over them.</p>
<p>You provide some reference images and <strong>ARCore</strong> tracking determines where those images are physically located in the environment. Augmented Images are already widely used such as in books, newspapers, magazines etc.</p>
<p>But before you dive deeper into this <strong>tutorial</strong>, you must check out the following articles as a <strong>prerequisite</strong> to this one:</p>
<ul>
<li><a target="_blank" href="https://ayusch.com/what-is-arcore/"><strong>What is ARCore by Google?</strong></a></li>
<li><a target="_blank" href="https://ayusch.com/building-arcore-app-android-studio/"><strong>Building an augmented reality app using ARCore.</strong></a></li>
</ul>
<p>Once you’re done with these two, you’ll have a basic understanding of some terminology in ARCore and Sceneform such as Scene, Anchor, Node, TransformableNode etc.</p>
<h3 id="heading-what-are-augmented-images">What are Augmented Images?</h3>
<p><a target="_blank" href="https://developers.google.com/ar/develop/c/augmented-images/">According to the developer docs</a>, <strong>Augmented Images</strong> in ARCore let you build AR apps that can respond to 2D images, such as posters or product packaging, in the user’s environment. You provide a set of reference images, and ARCore tracking tells you where those images are physically located in an AR session, once they are detected in the camera view.</p>
<p>Basically, using augmented images, you can turn a simple 2D image into an augmented image which can be recognized by your app and be then used to place a 3D model above it.</p>
<h3 id="heading-when-you-might-want-to-use-augmented-images">When you might want to use Augmented Images</h3>
<p>Here are some restrictions which you might want to consider before using Augmented Images:</p>
<ul>
<li>Your use case must not involve scanning more than 20 images simultaneously (since ARCore can only track up to 20 images at once).</li>
<li>Size of the physical counterpart in the real world must be more than 15cm X 15cm and flat.</li>
<li>You don’t want to track moving objects. ARCore cannot track moving images, although it can start tracking once the image stops.</li>
<li>ARCore uses feature points in the reference image and can store feature point information for up to 1000 images.</li>
</ul>
<h3 id="heading-choosing-a-good-reference-image">Choosing a good reference image</h3>
<p>Here are some tips to choose a good reference image to improve detectability by ARCore:</p>
<ul>
<li>Augmented Images support PNG, JPEG and JPG formats.</li>
<li>Detection is based on points of high contrast and so both color and black/white images are detected, regardless of whether a color or black/white reference image is used.</li>
<li>Image’s resolution must be at least 300 X 300 pixels.</li>
<li>Using high-res images does not mean improved performance.</li>
<li>Images with repetitive features such as patterns and polka dots must be avoided.</li>
<li>Use <strong>arcoreimg</strong> tool to evaluate how good your reference image is. A score of at least 75 is recommended.</li>
</ul>
<h3 id="heading-how-to-use-the-arcoreimg-tool">How to use the arcoreimg tool:</h3>
<ul>
<li>Download the ARCore SDK for Android from this link:</li>
<li>Extract the zip contents of the zip file anywhere you like.</li>
<li>Navigate to the extracted folder and go to tools -&gt; arcoreimg -&gt; windows (linux/macos whatever you use)</li>
<li>Open command prompt at this location.</li>
<li>Now enter this command:</li>
</ul>
<pre><code>arcoreimg.exe <span class="hljs-built_in">eval</span>-img --input_image_path=dog.png
</code></pre><p>Replace <strong>dog.png</strong> with the complete path to your image.</p>
<h3 id="heading-getting-started-with-augmented-images-application">Getting started with Augmented Images Application</h3>
<p>Now that you’ve familiarized yourself with ARCore and Sceneform and have selected a good reference image with a <strong>score of 75+</strong>, it’s time to start coding the application!!</p>
<h4 id="heading-create-a-custom-fragment">Create a custom fragment</h4>
<p>We will be creating a custom fragment to add to our activity. We need a custom fragment as we will be altering some properties of the default fragment.</p>
<p>Create a class named <strong>“CustomArFragment”</strong> and extend it from <strong>ArFragment</strong>. Here is the code for CustomArFragment:</p>
<pre><code>package com.ayusch.augmentedimages;
</code></pre><pre><code><span class="hljs-keyword">import</span> android.util.Log;
</code></pre><pre><code><span class="hljs-keyword">import</span> com.google.ar.core.Config;<span class="hljs-keyword">import</span> com.google.ar.core.Session;<span class="hljs-keyword">import</span> com.google.ar.sceneform.ux.ArFragment;
</code></pre><pre><code>public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CustomArFragment</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ArFragment</span> </span>{
</code></pre><pre><code>    @Override    protected Config getSessionConfiguration(Session session) {        getPlaneDiscoveryController().setInstructionView(<span class="hljs-literal">null</span>);        Config config = <span class="hljs-keyword">new</span> Config(session);        config.setUpdateMode(Config.UpdateMode.LATEST_CAMERA_IMAGE);        session.configure(config);        getArSceneView().setupSession(session);
</code></pre><pre><code>        <span class="hljs-keyword">return</span> config;    }
</code></pre><pre><code>}
</code></pre><p><strong>First of all</strong>, we are setting the plane discovery instruction to <strong>null</strong>. By doing this, we turn off that hand icon which appears just after the fragment is initialized which instructs the user to move their phone around. We don’t need it any more as we are not detecting random planes but a specific image.</p>
<p>Next, we set the update mode for the session to <strong>LATEST_CAMERA_IMAGE.</strong> This ensures that your update listener is called whenever the camera frame updates. It configures the behavior of update method.</p>
<h4 id="heading-setting-up-the-augmented-images-database">Setting up the Augmented Images Database</h4>
<p>Add your chosen reference image (which you want to detect in the physical world) in the <strong>assets</strong> folder. If your assets folder doesn’t exist, create one. Now we will be adding augmented images to our database which will then be detected in the real world.</p>
<p>We’ll set up this <strong>database</strong> as soon as the <strong>fragment (scene)</strong> is created. Then we check for the success and failure of this call and set the log accordingly. Add the following code to your custom fragment:</p>
<pre><code><span class="hljs-keyword">if</span> ((((MainActivity) getActivity()).setupAugmentedImagesDb(config, session))) {    Log.d(<span class="hljs-string">"SetupAugImgDb"</span>, <span class="hljs-string">"Success"</span>);} <span class="hljs-keyword">else</span> {    Log.e(<span class="hljs-string">"SetupAugImgDb"</span>,<span class="hljs-string">"Faliure setting up db"</span>);}
</code></pre><p>This is what the <strong>CustomArFragment</strong> would look like:</p>
<pre><code>package com.ayusch.augmentedimages;
</code></pre><pre><code><span class="hljs-keyword">import</span> android.util.Log;
</code></pre><pre><code><span class="hljs-keyword">import</span> com.google.ar.core.Config;<span class="hljs-keyword">import</span> com.google.ar.core.Session;<span class="hljs-keyword">import</span> com.google.ar.sceneform.ux.ArFragment;
</code></pre><pre><code>public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CustomArFragment</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ArFragment</span> </span>{
</code></pre><pre><code>    @Override    protected Config getSessionConfiguration(Session session) {        getPlaneDiscoveryController().setInstructionView(<span class="hljs-literal">null</span>);        Config config = <span class="hljs-keyword">new</span> Config(session);        config.setUpdateMode(Config.UpdateMode.LATEST_CAMERA_IMAGE);        session.configure(config);        getArSceneView().setupSession(session);
</code></pre><pre><code>        <span class="hljs-keyword">if</span> ((((MainActivity) getActivity()).setupAugmentedImagesDb(config, session))) {            Log.d(<span class="hljs-string">"SetupAugImgDb"</span>, <span class="hljs-string">"Success"</span>);        } <span class="hljs-keyword">else</span> {            Log.e(<span class="hljs-string">"SetupAugImgDb"</span>,<span class="hljs-string">"Faliure setting up db"</span>);        }
</code></pre><pre><code>        <span class="hljs-keyword">return</span> config;    }
</code></pre><pre><code>}
</code></pre><p>We will soon be creating the <strong>setupAugmentedImagesDb</strong> method in the MainActivity. Now with the CustomArFragment created, let’s add it to our activity_main.xml, here’s the code for your activity_main.xml:</p>
<pre><code>&lt;?xml version=<span class="hljs-string">"1.0"</span> encoding=<span class="hljs-string">"utf-8"</span>?&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">android.support.constraint.ConstraintLayout</span> <span class="hljs-attr">xmlns:android</span>=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>    <span class="hljs-attr">xmlns:app</span>=<span class="hljs-string">"http://schemas.android.com/apk/res-auto"</span>    <span class="hljs-attr">xmlns:tools</span>=<span class="hljs-string">"http://schemas.android.com/tools"</span>    <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>    <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"match_parent"</span>    <span class="hljs-attr">tools:context</span>=<span class="hljs-string">".MainActivity"</span>&gt;</span></span>
</code></pre><pre><code>    &lt;fragment        android:id=<span class="hljs-string">"@+id/sceneform_fragment"</span>        android:name=<span class="hljs-string">"com.ayusch.augmentedimages.CustomArFragment"</span>        android:layout_width=<span class="hljs-string">"match_parent"</span>        android:layout_height=<span class="hljs-string">"match_parent"</span> /&gt;
</code></pre><pre><code>&lt;/android.support.constraint.ConstraintLayout&gt;
</code></pre><p><strong>Notice</strong> that we set the name of this fragment to our <strong>CustomArFragment</strong>. This is necessary to ensure that the added fragment is our custom fragment. This will ensure that permission handling and session initializations are taken care of.</p>
<h4 id="heading-adding-an-image-to-the-augmented-images-database">Adding an image to the Augmented Images Database</h4>
<p>Here, we will set up our images database. Find the reference image in the real world and then add a 3D model accordingly.</p>
<p>Let’s start by setting up our database. Create a public function <strong>setupAugmentedImagesDb</strong> in the <strong>MainActivity.java</strong> class:</p>
<pre><code>public boolean setupAugmentedImagesDb(Config config, Session session) {    AugmentedImageDatabase augmentedImageDatabase;    Bitmap bitmap = loadAugmentedImage();    <span class="hljs-keyword">if</span> (bitmap == <span class="hljs-literal">null</span>) {        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;    }
</code></pre><pre><code>    augmentedImageDatabase = <span class="hljs-keyword">new</span> AugmentedImageDatabase(session);    augmentedImageDatabase.addImage(<span class="hljs-string">"tiger"</span>, bitmap);    config.setAugmentedImageDatabase(augmentedImageDatabase);    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;}
</code></pre><pre><code>private Bitmap loadAugmentedImage() {
</code></pre><pre><code><span class="hljs-keyword">try</span> (InputStream is = getAssets().open(<span class="hljs-string">"blanket.jpeg"</span>)) {        <span class="hljs-keyword">return</span> BitmapFactory.decodeStream(is);    } <span class="hljs-keyword">catch</span> (IOException e) {        Log.e(<span class="hljs-string">"ImageLoad"</span>, <span class="hljs-string">"IO Exception"</span>, e);    }
</code></pre><pre><code>    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;}
</code></pre><p>We also have loadAugmentedImage method which loads the image from the assets folder and returns a bitmap.</p>
<p>In <strong>setupAugmentedImagesDb</strong>, we first initialize our database for this session and then add an image to this database. We will name our image “tiger”. Then we set the database for this session configuration and return true, indicating that the image is added successfully.</p>
<h4 id="heading-detecting-the-reference-images-in-the-real-world">Detecting the reference images in the real world</h4>
<p>Now we will start detecting our reference images in the real world. In order to do so, we will add a listener to our scene which will be called every time a frame is created, and that frame will be analyzed to find our reference image.</p>
<p>Add this line in the <strong>onCreate</strong> method of MainActivity.java:</p>
<pre><code>arFragment.getArSceneView().getScene().addOnUpdateListener(<span class="hljs-built_in">this</span>::onUpdateFrame);
</code></pre><p>Now add the <strong>onUpdateFrame</strong> method to MainActivity:</p>
<pre><code>@RequiresApi(api = Build.VERSION_CODES.N)private <span class="hljs-keyword">void</span> onUpdateFrame(FrameTime frameTime) {    Frame frame = arFragment.getArSceneView().getArFrame();
</code></pre><pre><code>    Collection&lt;AugmentedImage&gt; augmentedImages = frame.getUpdatedTrackables(AugmentedImage.class);    <span class="hljs-keyword">for</span> (AugmentedImage augmentedImage : augmentedImages) {        <span class="hljs-keyword">if</span> (augmentedImage.getTrackingState() == TrackingState.TRACKING) {            <span class="hljs-keyword">if</span> (augmentedImage.getName().equals(<span class="hljs-string">"tiger"</span>) &amp;&amp; shouldAddModel) {                placeObject(arFragment, augmentedImage.createAnchor(augmentedImage.getCenterPose()), Uri.parse(<span class="hljs-string">"Mesh_BengalTiger.sfb"</span>));                shouldAddModel = <span class="hljs-literal">false</span>;            }        }    }}
</code></pre><p>In the first line, we get the frame from the scene. A <strong>frame</strong> can be imagined as a snapshot in the middle of a video. If you are familiar with how video works, you might know that they are a series of still pictures flipped one after the another really fast, giving the impression of the motion picture. We are extracting one of those pictures.</p>
<p>Once we have the frame, we analyze for our reference image. We extract a list of all the items ARCore has tracked using <strong>frame.getUpdatedTrackables.</strong> This is a collection of all the detected images. We then loop over the collection and check if our image “tiger” is present in the frame.</p>
<p>If we find a match, then we go ahead and place a 3D model over the detected image.</p>
<blockquote>
<p><em>Note: I have added, <strong>shouldAddModel</strong></em> <em>to ensure that we add the model only once.</em></p>
</blockquote>
<h4 id="heading-placing-a-3d-model-over-reference-image">Placing a 3D model over reference image</h4>
<p>Now that we have detected our image in the real world, we can start adding 3D models over it. We will copy the placeObject and addNodeToScene methods from our <a target="_blank" href="https://ayusch.com/building-arcore-app-android-studio/"><strong>previous project</strong></a><strong>,</strong> and add them here.</p>
<p>Although I have <a target="_blank" href="https://ayusch.com/building-arcore-app-android-studio/">previously</a> explained what these methods do line by line, here is an overview:</p>
<ul>
<li><strong>PlaceObject</strong>: This method is used to build a renderable from the provided Uri. Once the renderable is built, it is passed into addNodeToScene method where the renderable is attached to a node and that node is placed onto the scene.</li>
<li><strong>AddNodeToScene</strong>: This method creates an AnchorNode from the received anchor, creates another node on which the renderable is attached, then adds this node to the AnchorNode and adds the AnchorNode to the scene.</li>
</ul>
<p>Here is our final <strong>MainActivity.java</strong> class:</p>
<pre><code>package com.ayusch.augmentedimages;
</code></pre><pre><code><span class="hljs-keyword">import</span> android.graphics.Bitmap;<span class="hljs-keyword">import</span> android.graphics.BitmapFactory;<span class="hljs-keyword">import</span> android.net.Uri;<span class="hljs-keyword">import</span> android.os.Build;<span class="hljs-keyword">import</span> android.support.annotation.RequiresApi;<span class="hljs-keyword">import</span> android.support.v7.app.AppCompatActivity;<span class="hljs-keyword">import</span> android.os.Bundle;<span class="hljs-keyword">import</span> android.util.Log;<span class="hljs-keyword">import</span> android.widget.Toast;
</code></pre><pre><code><span class="hljs-keyword">import</span> com.google.ar.core.Anchor;<span class="hljs-keyword">import</span> com.google.ar.core.AugmentedImage;<span class="hljs-keyword">import</span> com.google.ar.core.AugmentedImageDatabase;<span class="hljs-keyword">import</span> com.google.ar.core.Config;<span class="hljs-keyword">import</span> com.google.ar.core.Frame;<span class="hljs-keyword">import</span> com.google.ar.core.Session;<span class="hljs-keyword">import</span> com.google.ar.core.TrackingState;<span class="hljs-keyword">import</span> com.google.ar.sceneform.AnchorNode;<span class="hljs-keyword">import</span> com.google.ar.sceneform.FrameTime;<span class="hljs-keyword">import</span> com.google.ar.sceneform.rendering.ModelRenderable;<span class="hljs-keyword">import</span> com.google.ar.sceneform.rendering.Renderable;<span class="hljs-keyword">import</span> com.google.ar.sceneform.ux.ArFragment;<span class="hljs-keyword">import</span> com.google.ar.sceneform.ux.TransformableNode;
</code></pre><pre><code><span class="hljs-keyword">import</span> java.io.IOException;<span class="hljs-keyword">import</span> java.io.InputStream;<span class="hljs-keyword">import</span> java.util.Collection;
</code></pre><pre><code>public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppCompatActivity</span> </span>{    ArFragment arFragment;    boolean shouldAddModel = <span class="hljs-literal">true</span>;
</code></pre><pre><code>    @Override    protected <span class="hljs-keyword">void</span> onCreate(Bundle savedInstanceState) {        <span class="hljs-built_in">super</span>.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        arFragment = (CustomArFragment) getSupportFragmentManager().findFragmentById(R.id.sceneform_fragment);        arFragment.getPlaneDiscoveryController().hide();        arFragment.getArSceneView().getScene().addOnUpdateListener(<span class="hljs-built_in">this</span>::onUpdateFrame);    }
</code></pre><pre><code>    @RequiresApi(api = Build.VERSION_CODES.N)    private <span class="hljs-keyword">void</span> placeObject(ArFragment arFragment, Anchor anchor, Uri uri) {        ModelRenderable.builder()                .setSource(arFragment.getContext(), uri)                .build()                .thenAccept(modelRenderable -&gt; addNodeToScene(arFragment, anchor, modelRenderable))                .exceptionally(throwable -&gt; {                            Toast.makeText(arFragment.getContext(), <span class="hljs-string">"Error:"</span> + throwable.getMessage(), Toast.LENGTH_LONG).show();                            <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;                        }
</code></pre><pre><code>                );    }
</code></pre><pre><code>    @RequiresApi(api = Build.VERSION_CODES.N)    private <span class="hljs-keyword">void</span> onUpdateFrame(FrameTime frameTime) {        Frame frame = arFragment.getArSceneView().getArFrame();
</code></pre><pre><code>        Collection&lt;AugmentedImage&gt; augmentedImages = frame.getUpdatedTrackables(AugmentedImage.class);        <span class="hljs-keyword">for</span> (AugmentedImage augmentedImage : augmentedImages) {            <span class="hljs-keyword">if</span> (augmentedImage.getTrackingState() == TrackingState.TRACKING) {                <span class="hljs-keyword">if</span> (augmentedImage.getName().equals(<span class="hljs-string">"tiger"</span>) &amp;&amp; shouldAddModel) {                    placeObject(arFragment, augmentedImage.createAnchor(augmentedImage.getCenterPose()), Uri.parse(<span class="hljs-string">"Mesh_BengalTiger.sfb"</span>));                    shouldAddModel = <span class="hljs-literal">false</span>;                }            }        }    }
</code></pre><pre><code>    public boolean setupAugmentedImagesDb(Config config, Session session) {        AugmentedImageDatabase augmentedImageDatabase;        Bitmap bitmap = loadAugmentedImage();        <span class="hljs-keyword">if</span> (bitmap == <span class="hljs-literal">null</span>) {            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;        }
</code></pre><pre><code>        augmentedImageDatabase = <span class="hljs-keyword">new</span> AugmentedImageDatabase(session);        augmentedImageDatabase.addImage(<span class="hljs-string">"tiger"</span>, bitmap);        config.setAugmentedImageDatabase(augmentedImageDatabase);        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;    }
</code></pre><pre><code>    private Bitmap loadAugmentedImage() {        <span class="hljs-keyword">try</span> (InputStream is = getAssets().open(<span class="hljs-string">"blanket.jpeg"</span>)) {            <span class="hljs-keyword">return</span> BitmapFactory.decodeStream(is);        } <span class="hljs-keyword">catch</span> (IOException e) {            Log.e(<span class="hljs-string">"ImageLoad"</span>, <span class="hljs-string">"IO Exception"</span>, e);        }
</code></pre><pre><code>        <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;    }
</code></pre><pre><code>    private <span class="hljs-keyword">void</span> addNodeToScene(ArFragment arFragment, Anchor anchor, Renderable renderable) {        AnchorNode anchorNode = <span class="hljs-keyword">new</span> AnchorNode(anchor);        TransformableNode node = <span class="hljs-keyword">new</span> TransformableNode(arFragment.getTransformationSystem());        node.setRenderable(renderable);        node.setParent(anchorNode);        arFragment.getArSceneView().getScene().addChild(anchorNode);        node.select();    }
</code></pre><pre><code>}
</code></pre><p>Now run your app. You should see a screen as shown below. Move around your phone a bit over the reference object. ARCore will detect the feature points and as soon as it detects the reference image in the real world, it will add your 3D model onto it.</p>
<p>[caption id=”attachment_1000" align=”aligncenter” width=”1280"]</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/C8OBR4vV4VsxKSeQ1wcr3U9KHCSnI0l56St1" alt="Image" width="800" height="450" loading="lazy">
<em>I used my blanket as a reference</em></p>
<p>With this, we have created our very first Augmented Images app using ARCore by Google and Sceneform SDK!!</p>
<p><strong>If you want to stay updated with all the latest articles, subscribe to the weekly newsletter by entering your email address in the form on the top right section of this page.</strong></p>
<p><em>Like what you read? Don’t forget to share this post on <a target="_blank" href="https://www.facebook.com/AndroidVille"><strong>Facebook</strong></a>, <strong>Whatsapp</strong> and <strong>LinkedIn</strong>.</em></p>
<p><em>You can follow me on <a target="_blank" href="https://www.linkedin.com/in/ayuschjain">LinkedIn</a>, <a target="_blank" href="https://www.quora.com/profile/Ayusch-Jain">Quora</a>, <a target="_blank" href="https://twitter.com/ayuschjain">Twitter</a> and <a target="_blank" href="https://www.instagram.com/androidville/">Instagram</a> where I <strong>answer</strong> questions related to <strong>Mobile Development, especially Android and Flutter</strong>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Haptics for mobile AR: how to enhance ARKit apps with a sense of “touch” ]]>
                </title>
                <description>
                    <![CDATA[ By Neil Mathew I’m really excited about the future of haptics for AR and VR. It feels like the missing link between my HTC Vive and jumping into the OASIS with Parzival and Art3mis. So it’s not surprising that haptics is perhaps the most hotly antici... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/haptics-for-mobile-ar-how-to-enhance-arkit-apps-with-a-sense-of-touch-151d9e9c9950/</link>
                <guid isPermaLink="false">66c34c1b93db2451bd44146c</guid>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ unity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ user experience ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 23 Nov 2018 17:51:48 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*t8zy_q2Ynm3QowFPo8w6MQ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Neil Mathew</p>
<p>I’m really excited about the future of haptics for AR and VR. It feels like the missing link between my HTC Vive and <a target="_blank" href="https://en.wikipedia.org/wiki/Ready_Player_One_(film)">jumping into the OASIS with Parzival and Art3mis</a>. So it’s not surprising that haptics is perhaps the most hotly anticipated tech in the XR community right now. Several companies like Microsoft and HTC, as well as startups like <a target="_blank" href="https://www.senseglove.com/">SenseGlove</a> and <a target="_blank" href="https://haptx.com/">HaptX</a>, have shown demos of increasingly promising iterations of haptic gloves that I’m itching to try out.</p>
<p>Unfortunately, like most AR developers today, our work at <a target="_blank" href="https://placenote.com"><strong>Placenote</strong></a> is focused almost entirely on mobile AR platforms like <strong>ARKit</strong> and <strong>ARCore</strong>. Naturally, this got us thinking, <strong>“Could haptics do anything for mobile AR?</strong>”</p>
<p>Haptics have been an awesome addition to touch screens, from simulating tactile button clicks to silent notifications. But, after some frantic googling we realized that there’s actually been no real discussion about haptics for <strong>mobile AR apps</strong> so far… CHALLENGE ACCEPTED ??</p>
<h3 id="heading-the-challenge-of-mobile-ar"><strong>The challenge of mobile AR</strong></h3>
<p>We decided to dig into why haptics hasn’t made it’s way into mobile AR and it wasn’t hard to see why. Mobile AR is by far the least immersive AR medium. The consensus in the community is that it’s just a stop gap to the ultimate AR platform — smart glasses.</p>
<p>But mindset isn’t the only barrier here. We found that the mobile form-factor presents some unique challenges to the AR experience designer:</p>
<ul>
<li>unlike headsets, the phone screen is the display as well as the controller</li>
<li>it’s impossible to bring your hands into the experience since you’re holding the phone.</li>
<li>we still rely on touch screen interactions that are ambiguous in dimensionality — 2D or 3D touch?</li>
</ul>
<p>Nevertheless, the reality is that, for the next few years and perhaps more, mobile AR is here to stay. There are a billion mobile devices in consumer pockets right now and only about a handful of AR headsets on their heads. As a developer, distribution for your apps trumps most other factors. In fact, in applications like indoor navigation and gaming, mobile has already proven itself as a viable medium for deploying AR experiences.</p>
<p>This brings us to the topic of haptics for mobile AR. At first, it might seem like there’s no real hope for haptics to enhance mobile AR experiences, but recent studies have actually shown otherwise.</p>
<h3 id="heading-in-haptics-less-is-more"><strong>In haptics, less is more</strong></h3>
<p>There’s been a myriad of methods conceived to achieve haptic feedback. In general they fall under two broad categories — <strong>kinesthetic haptics</strong> (force feedback) and <strong>cutaneous haptics</strong> (skin sensations).</p>
<p>Kinesthetic haptics has widely been considered to be the more realistic haptic technology. It involves physical actuators, either grounded or ungrounded. These push and pull our fingers and other appendages in response to interactions with virtual objects. Intuitively, realistic force-feedback should perform vastly better than plain old vibrations. But a study published in <a target="_blank" href="http://robotics.sciencemag.org/content/3/17/eaar7010">Science Robotics this year titled “The Uncanny Valley of Haptics”</a> has challenged these assumptions.</p>
<p>The researchers found that increasing the realism of haptic sensation doesn’t necessarily increase the quality of the AR experience. It often has a negative impact due to the uncanny valley of realism in simulations. They found that cutaneous haptics, which is essentially a combination of light touches and vibrations, did a lot better in fooling the brain deeper into the illusion. Strange results, but they basically realized that we’ve underestimated how good our brain is at filling the gaps in our sensation of reality.</p>
<blockquote>
<p>The situations where our brain steps in to fill the gaps is what I find most interesting about our perception of the sensation of touch. — Justin Brad, CEO of Osso VR</p>
</blockquote>
<h3 id="heading-bringing-haptics-to-mobile-ar"><strong>Bringing haptics to mobile AR</strong></h3>
<p>Given these findings, why not test what cutaneous haptics can do for mobile AR? After all, haptics on mobile is not just about vibrating ring tones anymore.</p>
<p>Micro-Electro-Mechanical Systems (MEMS) on mobile devices have gotten a lot more sophisticated and capable of some pretty nuanced behaviors. Since the iPhone 7, Apple has upgraded the old basic rumble vibrations to what they now call the <strong>Taptic Engine.</strong> This is a lot more subtle and consists of <strong>seven different types of haptic feedback</strong> with varying patterns and strengths.</p>
<p>The haptic feedback modes available are:</p>
<ul>
<li>Selection Change</li>
<li>Impact Light</li>
<li>Impact Medium</li>
<li>Impact Heavy</li>
<li>Notification Success</li>
<li>Notification Warning</li>
<li>Notification Failure</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/EKykqXsyuWpCeEGMquFljyCCzN6ug26uPhCm" alt="Image" width="800" height="446" loading="lazy">
<em>The new iOS Taptic Engine (iPhone 7 onwards) has 7 different kinds of Haptic Feedback</em></p>
<p>To learn more about the iOS feedback generator, <a target="_blank" href="https://developer.apple.com/documentation/uikit/uifeedbackgenerator">check out this Apple documentation</a>. At the end of this article, I will share some code you can use to quickly add these feedback types to your ARKit apps.</p>
<p>We <strong>decided to experiment</strong> with a number of these haptic feedback modes in our AR apps and I’m really excited to say that the results were a pleasant surprise to our team.The following are some examples of haptic implementations in our mobile AR apps.</p>
<h3 id="heading-usage-examples-of-haptics-in-mobile-ar"><strong>Usage examples of haptics in mobile AR</strong></h3>
<p>In our experiments so far, we’ve found that haptic feedback for mobile AR works well in five distinct scenarios. Here’s a description of each.</p>
<h4 id="heading-1-magnetic-pointers-ie-snap-to-grid">1. Magnetic pointers (i.e. snap to grid)</h4>
<p>A pointer locked along a planar surface is a commonly used feature in many ARKit apps, especially in measurement tools like <a target="_blank" href="http://armeasure.com/">Air Measure</a> and <a target="_blank" href="https://www.magic-plan.com/">Magic Plan</a>. Since your phone behaves as a controller in mobile AR, the standard UX in measurement apps involves dragging a pointer along a surface to draw lines or polygons to measure things in the real world. Of course, when it comes to line drawing, magnetic pointers that snap to the end points and edges of lines are seen everywhere — from PowerPoint to Photoshop.</p>
<p>We found that subtle haptic feedback indicating a “snap” in pointer position is a great enhancement. It almost feels like your phone, (i.e your controller) is physically moving to snap into place.</p>
<p>I was really happy to see that <strong>Apple’s new app “Measure”</strong> actually uses haptic feedback in their UX. It’s an amazingly subtle implementation and you can see a GIF of it in action below. An “Impact Medium” is fired when the pointer snaps to the edge of the plane.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/5h7tXFoybj35qprzl6G1EJIOrljyh-G6o2T-" alt="Image" width="225" height="400" loading="lazy">
<em>Apple’s Measure App</em></p>
<h4 id="heading-2-hit-testing-feeling-real-world-surfaces">2. Hit testing (feeling real world surfaces)</h4>
<p>Another common feature in ARKit apps is the hit-test. This is implemented as a ray-cast from a point on the screen — either a touch point or the center — to a surface in the real word. It is generally used to add a 3D object at the point of contact. A slight haptic sensation can help the user understand that a surface was “hit”. We found two methods that work well here:</p>
<p><strong>Pinning</strong><br>In this example, a marker is added to the scene at the hit point. An “Impact Light” helps users sense the “pinning” of the marker in 3D space. Of course, the downside to this is you can’t quite sense the “depth” of the hit point — in other words, how far the pin is from the user.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/5RQoGLCzDtV5l8bEtaqGmVs7ObuPGxdGGC98" alt="Image" width="225" height="400" loading="lazy"></p>
<p><strong>Grazing</strong><br>An alternative to pinning is the grazing method of hit testing. In this case, a constantly updating marker previews where a marker might be added to a scene. We found that a series of haptic impulses, based on the magnitude of displacement of the preview marker at each frame, gives the sensation of scraping a pointer along a 3D surface and let’s you “feel” a 3D surface.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/l7GMZUOcwkxV8lsIvnS1xRLPwOOQhNGWl08K" alt="Image" width="225" height="400" loading="lazy"></p>
<p>Here’s a code example of grazing in Unity:</p>
<pre><code><span class="hljs-keyword">if</span> (distanceChange &gt;= <span class="hljs-number">0.1</span> &amp;&amp; distanceChange &lt; <span class="hljs-number">0.2</span>) 
{
    iOSHapticFeedback.Instance.Trigger(Impact_Light);
}
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (distanceChange &gt;= <span class="hljs-number">0.2</span> &amp;&amp; distanceChange &lt; <span class="hljs-number">0.4</span>) 
{
    iOSHapticFeedback.Instance.Trigger(Impact_Medium);
}
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (distanceChange &gt;= <span class="hljs-number">0.4</span>)
{
    iOSHapticFeedback.Instance.Trigger(Impact_Heavy);
}
</code></pre><h4 id="heading-3-fps-gun-recoil-or-explosions">3. FPS gun recoil or explosions</h4>
<p>This is by far the most fun example of haptic feedback. When building a first person shooter in AR, your phone is the display as well as the weapon. A great way to simulate a gun shot is a simple “Impact Heavy”, which produces a single bump or a “Notification Failure”, which creates a double bump that feels a lot like a gun recoil. Of course the example below is a laser weapon but, hey, this isn’t meant to be too realistic remember?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/6AOfjrGjmc9pSjmaTVQ-88VW7h92isqHEnfz" alt="Image" width="225" height="400" loading="lazy"></p>
<h4 id="heading-4-collision-with-controller-tip">4. Collision with controller tip</h4>
<p>In VR apps like <a target="_blank" href="https://www.oculus.com/medium/">Oculus Medium</a> or <a target="_blank" href="https://www.tiltbrush.com/">Tilt Brush</a>, one of the handheld controllers serves as a brush tip that the user moves around to draw in 3D space. I’ve spent hours painting in Tilt Brush and so naturally I have tried really hard to mimic this experience with ARKit.</p>
<p>The trouble is that creating an accurate drawing experience on mobile becomes really difficult. You lose the sense of depth when your phone is both the display and the controller. One of the hardest things in 3D drawing apps on mobile is knowing where your brush tip is relative to the other 3D objects in the scene.</p>
<p><strong>And, again, haptics was the answer.</strong> We found that one way to give users a sense of depth is to imagine the brush is actually a cane you can use to hit 3D objects that are already in scene. Providing haptic feedback to let users know whether the brush tip is in contact with any existing objects in the scene lets users accurately pin point their brush in 3D space.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/BN9Hp8CqQrX7jHi0jXsy36SRCjSQJqbC4rU-" alt="Image" width="225" height="400" loading="lazy">
<em>Sensing brush tip collisions</em></p>
<h4 id="heading-5-re-localization-snap-in-persistent-ar-apps">5. Re-localization snap in Persistent AR Apps.</h4>
<p>At <a target="_blank" href="https://placenote.com">Placenote</a> , we primarily build Persistent AR, or AR Cloud, apps. The core functionality of these apps is the ability to save AR content <strong>permanently</strong> in a physical place. Users can load it up in the same location every time.</p>
<p>This behaviour is called the <strong>relocalization of a scene.</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/8z3xdAIYFaaEPXbpVxXGAhov8pHtYZOaEPdN" alt="Image" width="225" height="400" loading="lazy">
<em>Localization snapping into place</em></p>
<p>In order to relocalize an AR scene, a user must first point their phone’s camera to the real world, and then wait until the camera detects its location.</p>
<p>With Placenote, relocalization happens almost instantaneously but it all happens internally. Hence we need to design a way to notify the user of a successful relocalization. The visual cues might be enough, as seen in the GIF above. But a more subtle indication is to provide a haptic “Impact Light” to suggest that you have snapped into place in the real world.</p>
<h3 id="heading-how-to-add-haptics-to-your-arkit-project"><strong>How to add haptics to your ARKit project</strong></h3>
<p>If you’re working with <strong>Swift</strong> for Native iOS ARKit development, <a target="_blank" href="https://www.appcoda.com/haptic-feedback/">check out this tutorial</a> on implementing haptic feedback in Native apps.</p>
<p>If you’re working with <strong>Unity,</strong> my favorite package so far is the <a target="_blank" href="https://assetstore.unity.com/packages/tools/integration/ios-haptic-feedback-73225"><strong>iOS Haptic Feedback Package</strong></a> on the <strong>Unity Asset Store</strong>. It’s $5 but well worth it because Unity’s built in function <a target="_blank" href="https://docs.unity3d.com/ScriptReference/Handheld.Vibrate.html">Handheld.Vibrate()</a> doesn’t actually expose the new iOS Taptic Engine functions!</p>
<p>The iOS Haptic Feedback Package provides a simple Prefab and Scripts to add all 7 types of haptic feedback into your app. You can get it from the Asset Store link here:</p>
<h3 id="heading-things-to-watch-out-for"><strong>Things to watch out for</strong></h3>
<p>As with any design tool, here’s a few things to watch out for when incorporating haptics in your mobile AR app.</p>
<h4 id="heading-using-haptics-too-much-can-mess-up-arkit-tracking"><strong>Using haptics too much can mess up ARKit tracking</strong></h4>
<p>Test the impact of haptics on your AR session. Since ARKit relies on inertial sensing to track the phone’s motion, adding too many vibrations during an ARKit session can throw off tracking slightly.</p>
<h4 id="heading-using-haptics-too-much-can-overheat-the-device"><strong>Using haptics too much can overheat the device</strong></h4>
<p>Haptics is, after all, a physical movement of your mobile device and naturally tends to use more energy. Use this sparingly to ensure your phone doesn’t overheat or run out of battery too fast.</p>
<h4 id="heading-too-much-haptic-feedback-might-confuse-and-desensitize-your-user"><strong>Too much haptic feedback might confuse and desensitize your user</strong></h4>
<p>This is true for any haptic mechanism. Don’t overdo it. Specifically, don’t use it without a clear understanding of why haptic feedback is necessary for the action your user is performing. The danger of overuse is that your user gets confused by it and therefore gets desensitized to your feedback.</p>
<p>And that’s it! I hope this article has given you a helpful dose of design ideas and convinced you to venture into the world of mobile AR haptics. We’ve really enjoyed exploring the different ways we could simulate touch sensations in mobile AR and if you have any more ideas we would love to talk to you about it. If you’re interested in trying out any of our code examples for mobile AR haptics, send me an email at <strong>neil [at] placenote.com</strong>.</p>
<p>If you’re interested in Persistent AR apps or what we do at Placenote, message us on twitter, or check out <a target="_blank" href="https://placenote.com"><strong>Placenote.com</strong></a></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Gn8g8nxE5b5L2zv-C-1aDXCRS1RuigcRudig" alt="Image" width="800" height="160" loading="lazy"></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to build an Augmented Reality Android App with ARCore and Android Studio ]]>
                </title>
                <description>
                    <![CDATA[ By Ayusch Jain This article was originally posted here In the previous post, I explained what ARCore is and how it helps developers build awesome augmented reality apps without the need to understand OpenGL or Matrix maths. If you haven’t checked i... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-an-augmented-reality-android-app-with-arcore-and-android-studio-43e4676cb36f/</link>
                <guid isPermaLink="false">66c3501ff41767c3c96bacfe</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Android Studio ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Apps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 15 Nov 2018 16:57:24 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/0*YjUBhRlE5eEKPbl-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ayusch Jain</p>
<blockquote>
<p>This article was originally posted <a target="_blank" href="http://ayusch.com/building-arcore-app-android-studio/">here</a></p>
</blockquote>
<p><a target="_blank" href="https://ayusch.com/what-is-arcore/">In the previous post</a>, I explained <a target="_blank" href="https://ayusch.com/what-is-arcore/">what ARCore is</a> and how it helps developers build awesome augmented reality apps without the need to understand <strong>OpenGL</strong> or <strong>Matrix</strong> maths.</p>
<p>If you haven’t checked it out yet, I highly recommend doing so before moving ahead with this article and diving into ARCore app development.</p>
<h3 id="heading-overview">Overview</h3>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/ARCore">According to Wikipedia</a>, ARCore is a software development kit developed by Google that allows for augmented reality applications to be built.</p>
<p><strong>ARCore</strong> uses three key technologies to integrate virtual content with the real environment:</p>
<ol>
<li><strong>Motion Tracking:</strong> it allows the phone to understand its position relative to the world.</li>
<li><strong>Environmental understanding:</strong> This allows the phone to detect the size and location of all type of surfaces, vertical, horizontal and angled.</li>
<li><strong>Light Estimation:</strong> it allows the phone to estimate the environment’s current lighting conditions.</li>
</ol>
<h3 id="heading-getting-started">Getting Started</h3>
<p>To get started with <strong>ARCore app</strong> development, you first need to enable ARCore in your project. This is simple as we will be using Android Studio and Sceneform SDK. There are two major operations Sceneform performs automatically:</p>
<ol>
<li><strong>Checking for availability of ARCore</strong></li>
<li><strong>Asking for camera permission</strong></li>
</ol>
<p>You don’t need to bother with these two steps when creating an ARCore app using Sceneform SDK. But you do need to include Sceneform SDK in your project.</p>
<p>Create a new Android Studio project and select an empty activity.</p>
<p><strong>Add the following dependency to your project level build.gradle file:</strong></p>
<pre><code>dependencies {    classpath <span class="hljs-string">'com.google.ar.sceneform:plugin:1.5.0'</span>}
</code></pre><p><strong>Add the following to your app level build.gradle file:</strong></p>
<pre><code>implementation <span class="hljs-string">"com.google.ar.sceneform.ux:sceneform-ux:1.5.0"</span>
</code></pre><p>Now sync project with Gradle files and wait for the build to finish. This will install the Sceneform SDK to the project and Sceneform plugin to <strong>AndroidStudio</strong>. It will help you to view the .<strong>sfb</strong> files. These files are the 3D models which are rendered in your camera. It also helps you in importing, viewing, and building <strong>3D assets</strong>.</p>
<h3 id="heading-building-your-first-arcore-app">Building your first ARCore app</h3>
<p>Now with our <strong>Android Studio</strong> setup complete and Sceneform SDK installed, we can get started with writing our very first <strong>ARCore app.</strong></p>
<p>First, we need to add the Sceneform fragment to our layout file. This will be the Scene where we place all our 3D models. It takes care of the camera initialization and permission handling.</p>
<p>Head over to your main layout file. In my case it is <strong>activity_main.xml</strong> and add the Sceneform fragment:</p>
<pre><code>&lt;?xml version=<span class="hljs-string">"1.0"</span> encoding=<span class="hljs-string">"utf-8"</span>?&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">FrameLayout</span> <span class="hljs-attr">xmlns:android</span>=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>    <span class="hljs-attr">xmlns:tools</span>=<span class="hljs-string">"http://schemas.android.com/tools"</span>    <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>    <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"match_parent"</span>    <span class="hljs-attr">tools:context</span>=<span class="hljs-string">".MainActivity"</span>&gt;</span></span>
</code></pre><pre><code>    &lt;fragment android:name=<span class="hljs-string">"com.google.ar.sceneform.ux.ArFragment"</span>        android:id=<span class="hljs-string">"@+id/ux_fragment"</span>        android:layout_width=<span class="hljs-string">"match_parent"</span>        android:layout_height=<span class="hljs-string">"match_parent"</span> /&gt;
</code></pre><pre><code>&lt;/FrameLayout&gt;
</code></pre><p>I’ve set the width and height to match parent as this will cover my entire activity. You can choose the dimensions according to your requirements.</p>
<h3 id="heading-compatibility-check">Compatibility Check</h3>
<p>This is all that you need to do in the layout file. Now head over to the java file, in my case which is MainActivity.java. Add the method below in your class:</p>
<pre><code>public <span class="hljs-keyword">static</span> boolean checkIsSupportedDeviceOrFinish(final Activity activity) {    <span class="hljs-keyword">if</span> (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.N) {        Log.e(TAG, <span class="hljs-string">"Sceneform requires Android N or later"</span>);        Toast.makeText(activity, <span class="hljs-string">"Sceneform requires Android N or later"</span>, Toast.LENGTH_LONG).show();        activity.finish();        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;    }    <span class="hljs-built_in">String</span> openGlVersionString =            ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE))                    .getDeviceConfigurationInfo()                    .getGlEsVersion();    <span class="hljs-keyword">if</span> (Double.parseDouble(openGlVersionString) &lt; MIN_OPENGL_VERSION) {        Log.e(TAG, <span class="hljs-string">"Sceneform requires OpenGL ES 3.0 later"</span>);        Toast.makeText(activity, <span class="hljs-string">"Sceneform requires OpenGL ES 3.0 or later"</span>, Toast.LENGTH_LONG)                .show();        activity.finish();        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;    }    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;}
</code></pre><p>This method checks whether your device can support Sceneform SDK or not. The SDK requires Android API level 27 or newer and <strong>OpenGL ES</strong> <strong>version 3.0</strong> or newer. If a device does not support these two, the Scene would not be rendered and your application will show a blank screen.</p>
<p>Although, you can still continue to deliver all the other features of your app which don’t require the Sceneform SDK.</p>
<p>Now with the device compatibility check complete, we shall build our 3D model and attach it to the scene.</p>
<h3 id="heading-adding-the-assets">Adding the assets</h3>
<p>You will need to add the 3D models which will be rendered on your screen. Now you can build these models yourself if you are familiar with 3D model creation. Or, you can visit <strong>Poly.</strong></p>
<p>There you’ll find a huge repository of 3D assets to choose from. They are free to download. Just credit the creator and you are good to go.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/n-nw06cs3-ISxbKFW3j1ICdyfLIJM7Jpf0dR" alt="Image" width="800" height="379" loading="lazy"></p>
<p>In the Android Studio, expand your app folder available on the left-hand side project pane. You’ll notice a <strong>“</strong>sampledata<strong>”</strong> folder. This folder will hold all of your 3D model assets. Create a folder for your model inside the sample data folder.</p>
<p>When you download the zip file from poly, you will most probably find 3 files.</p>
<ol>
<li><strong>.mtl file</strong></li>
<li><strong>.obj file</strong></li>
<li><strong>.png file</strong></li>
</ol>
<p>Most important of these 3 is the .obj file. It is your actual model. Place all the 3 files inside <strong>sampledata</strong> <strong>-&gt; “your model’s folde</strong>r”.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/jInoAjquRuqEpoCSH3RSO4VRoWi5tNu9GLL9" alt="Image" width="800" height="429" loading="lazy"></p>
<p><strong>Now right click on the .obj</strong> <strong>file</strong>. The first option would be to Import Sceneform Asset. Click on it, do not change the default settings, just click finish on the next window. Your gradle will sync to include the asset in the assets folder. Once the gradle build finishes, you are good to go.</p>
<p>You’ve finished importing a 3D asset used by Sceneform in your project. <strong>Next</strong>, let’s build the asset from our code and include it in the scene.</p>
<h3 id="heading-building-the-model">Building the Model</h3>
<p>Add the following code to your MainActivity.java file (or whatever it is in your case). Don’t worry, I’ll explain all the code line by line:</p>
<pre><code>private <span class="hljs-keyword">static</span> final <span class="hljs-built_in">String</span> TAG = MainActivity.class.getSimpleName();private <span class="hljs-keyword">static</span> final double MIN_OPENGL_VERSION = <span class="hljs-number">3.0</span>;
</code></pre><pre><code>ArFragment arFragment;ModelRenderable lampPostRenderable;
</code></pre><pre><code>@Override@SuppressWarnings({<span class="hljs-string">"AndroidApiChecker"</span>, <span class="hljs-string">"FutureReturnValueIgnored"</span>})
</code></pre><pre><code>protected <span class="hljs-keyword">void</span> onCreate(Bundle savedInstanceState) {    <span class="hljs-built_in">super</span>.onCreate(savedInstanceState);    <span class="hljs-keyword">if</span> (!checkIsSupportedDeviceOrFinish(<span class="hljs-built_in">this</span>)) {        <span class="hljs-keyword">return</span>;    }    setContentView(R.layout.activity_main);    arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment);
</code></pre><pre><code>    ModelRenderable.builder()            .setSource(<span class="hljs-built_in">this</span>, Uri.parse(<span class="hljs-string">"LampPost.sfb"</span>))            .build()            .thenAccept(renderable -&gt; lampPostRenderable = renderable)            .exceptionally(throwable -&gt; {                Toast toast =                        Toast.makeText(<span class="hljs-built_in">this</span>, <span class="hljs-string">"Unable to load andy renderable"</span>, Toast.LENGTH_LONG);                toast.setGravity(Gravity.CENTER, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>);                toast.show();                <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;            });
</code></pre><pre><code>}
</code></pre><p><strong>First</strong>, we find the <strong>arFragment</strong> that we included in the layout file. This fragment is responsible for hosting the scene. You can think of it as the container of our scene.</p>
<p><strong>Next</strong>, we are using the <strong>ModelRenderable</strong> class to build our model. With the help of setSource method, we load our model from the .<strong>sfb</strong> file. This file was generated when we imported the assets. <strong>thenAccept</strong> method receives the model once it is built. We set the loaded model to our <strong>lampPostRenderable.</strong></p>
<p>For error handling, we have <strong>.exceptionally</strong> method. It is called in case an exception is thrown.</p>
<p>All this happens <strong>asynchronously</strong>, hence you don’t need to worry about multi-threading or deal with handlers XD</p>
<p>With the model loaded and stored in the <strong>lampPostRenderable</strong> variable, we’ll now add it to our scene.</p>
<h3 id="heading-adding-the-model-to-scene">Adding the Model to Scene</h3>
<p>The <strong>arFragment</strong> hosts our scene and will receive the tap events. So we need to set the onTap listener to our fragment to register the tap and place an object accordingly. Add the following code to onCreate method:</p>
<pre><code>arFragment.setOnTapArPlaneListener(        (HitResult hitresult, Plane plane, MotionEvent motionevent) -&gt; {            <span class="hljs-keyword">if</span> (lampPostRenderable == <span class="hljs-literal">null</span>){                <span class="hljs-keyword">return</span>;            }
</code></pre><pre><code>            Anchor anchor = hitresult.createAnchor();            AnchorNode anchorNode = <span class="hljs-keyword">new</span> AnchorNode(anchor);            anchorNode.setParent(arFragment.getArSceneView().getScene());
</code></pre><pre><code>            TransformableNode lamp = <span class="hljs-keyword">new</span> TransformableNode(arFragment.getTransformationSystem());            lamp.setParent(anchorNode);            lamp.setRenderable(lampPostRenderable);            lamp.select();        });
</code></pre><p>We set the <strong>onTapArPlaneListener</strong> to our <strong>AR fragment</strong>. Next what you see is the <strong>Java 8 syntax</strong>, in case you are not familiar with it, I would recommend checking out <a target="_blank" href="https://www.tutorialspoint.com/java8/index.htm"><strong>this guide</strong></a>.</p>
<p><strong>First,</strong> we create our anchor from the HitResult using <strong>hitresult.createAnchor()</strong> and store it in an Anchor object.</p>
<p><strong>Next</strong>, create a node out of this anchor. It will be called <strong>AnchorNode.</strong> It will be attached to the scene by calling the setParent method on it and passing the scene from the fragment.</p>
<p>Now we create a <strong>TransformableNode</strong> which will be our <strong>lamppost</strong> and set it to the anchor spot or our anchor node. The node still doesn’t have any information about the object it has to render. We’ll pass that object using <strong>lamp.setRenderable</strong> method which takes in a renderable as it’s parameter. Finally call lamp.select();</p>
<p><strong>Phew!!</strong> Too much terminology there, but don’t worry, I’ll explain it all.</p>
<ol>
<li><strong>Scene</strong>: This is the place where all your 3D objects will be rendered. This scene is hosted by the AR Fragment which we included in the layout. An anchor node is attached to this screen which acts as the root of the tree and all the other objects are rendered as its objects.</li>
<li><strong>HitResult</strong>: This is an imaginary line (or a ray) coming from infinity which gives the point of intersection of itself with a real-world object.</li>
<li><strong>Anchor</strong>: An anchor is a fixed location and orientation in the real world. It can be understood as the x,y,z coordinate in the 3D space. You can get an anchor’s post information from it. <strong>Pose</strong> is the position and orientation of the object in the scene. This is used to transform the object’s local coordinate space into real-world coordinate space.</li>
<li>AnchorNode: This is the node that automatically positions itself in the world. This is the first node that gets set when the plane is detected.</li>
<li><strong>TransformableNode</strong>: It is a node that can be interacted with. It can be moved around, scaled rotated and much more. In this example, we can scale the <strong>lamp</strong> and rotate it. Hence the name Transformable.</li>
</ol>
<p>There is no rocket science here. It’s really simple. The entire scene can be viewed as a graph with Scene as the parent, <strong>AnchorNode</strong> as its child and then branching out different nodes/objects to be rendered on the screen.</p>
<p>Your final MainActivity.java must look something like this:</p>
<pre><code>package com.ayusch.arcorefirst;
</code></pre><pre><code><span class="hljs-keyword">import</span> android.app.Activity;<span class="hljs-keyword">import</span> android.app.ActivityManager;<span class="hljs-keyword">import</span> android.content.Context;<span class="hljs-keyword">import</span> android.net.Uri;<span class="hljs-keyword">import</span> android.os.Build;<span class="hljs-keyword">import</span> android.support.v7.app.AppCompatActivity;<span class="hljs-keyword">import</span> android.os.Bundle;<span class="hljs-keyword">import</span> android.util.Log;<span class="hljs-keyword">import</span> android.view.Gravity;<span class="hljs-keyword">import</span> android.view.MotionEvent;<span class="hljs-keyword">import</span> android.widget.Toast;
</code></pre><pre><code><span class="hljs-keyword">import</span> com.google.ar.core.Anchor;<span class="hljs-keyword">import</span> com.google.ar.core.HitResult;<span class="hljs-keyword">import</span> com.google.ar.core.Plane;<span class="hljs-keyword">import</span> com.google.ar.sceneform.AnchorNode;<span class="hljs-keyword">import</span> com.google.ar.sceneform.rendering.ModelRenderable;<span class="hljs-keyword">import</span> com.google.ar.sceneform.ux.ArFragment;<span class="hljs-keyword">import</span> com.google.ar.sceneform.ux.TransformableNode;
</code></pre><pre><code>public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppCompatActivity</span> </span>{    private <span class="hljs-keyword">static</span> final <span class="hljs-built_in">String</span> TAG = MainActivity.class.getSimpleName();    private <span class="hljs-keyword">static</span> final double MIN_OPENGL_VERSION = <span class="hljs-number">3.0</span>;
</code></pre><pre><code>    ArFragment arFragment;    ModelRenderable lampPostRenderable;
</code></pre><pre><code>    @Override    @SuppressWarnings({<span class="hljs-string">"AndroidApiChecker"</span>, <span class="hljs-string">"FutureReturnValueIgnored"</span>})    protected <span class="hljs-keyword">void</span> onCreate(Bundle savedInstanceState) {        <span class="hljs-built_in">super</span>.onCreate(savedInstanceState);        <span class="hljs-keyword">if</span> (!checkIsSupportedDeviceOrFinish(<span class="hljs-built_in">this</span>)) {            <span class="hljs-keyword">return</span>;        }        setContentView(R.layout.activity_main);        arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment);
</code></pre><pre><code>        ModelRenderable.builder()                .setSource(<span class="hljs-built_in">this</span>, Uri.parse(<span class="hljs-string">"LampPost.sfb"</span>))                .build()                .thenAccept(renderable -&gt; lampPostRenderable = renderable)                .exceptionally(throwable -&gt; {                    Toast toast =                            Toast.makeText(<span class="hljs-built_in">this</span>, <span class="hljs-string">"Unable to load andy renderable"</span>, Toast.LENGTH_LONG);                    toast.setGravity(Gravity.CENTER, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>);                    toast.show();                    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;                });
</code></pre><pre><code>            arFragment.setOnTapArPlaneListener(                    (HitResult hitresult, Plane plane, MotionEvent motionevent) -&gt; {                        <span class="hljs-keyword">if</span> (lampPostRenderable == <span class="hljs-literal">null</span>){                            <span class="hljs-keyword">return</span>;                        }
</code></pre><pre><code>                        Anchor anchor = hitresult.createAnchor();                        AnchorNode anchorNode = <span class="hljs-keyword">new</span> AnchorNode(anchor);                        anchorNode.setParent(arFragment.getArSceneView().getScene());
</code></pre><pre><code>                        TransformableNode lamp = <span class="hljs-keyword">new</span> TransformableNode(arFragment.getTransformationSystem());                        lamp.setParent(anchorNode);                        lamp.setRenderable(lampPostRenderable);                        lamp.select();                    }            );
</code></pre><pre><code>    }
</code></pre><pre><code>    public <span class="hljs-keyword">static</span> boolean checkIsSupportedDeviceOrFinish(final Activity activity) {        <span class="hljs-keyword">if</span> (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.N) {            Log.e(TAG, <span class="hljs-string">"Sceneform requires Android N or later"</span>);            Toast.makeText(activity, <span class="hljs-string">"Sceneform requires Android N or later"</span>, Toast.LENGTH_LONG).show();            activity.finish();            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;        }        <span class="hljs-built_in">String</span> openGlVersionString =                ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE))                        .getDeviceConfigurationInfo()                        .getGlEsVersion();        <span class="hljs-keyword">if</span> (Double.parseDouble(openGlVersionString) &lt; MIN_OPENGL_VERSION) {            Log.e(TAG, <span class="hljs-string">"Sceneform requires OpenGL ES 3.0 later"</span>);            Toast.makeText(activity, <span class="hljs-string">"Sceneform requires OpenGL ES 3.0 or later"</span>, Toast.LENGTH_LONG)                    .show();            activity.finish();            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;        }        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;    }}
</code></pre><p><strong>Congratulations!!</strong> You’ve just completed your first ARCore app. Start adding objects and see them come alive in the real world!</p>
<p>This was your first look into how to create a simple <strong>ARCore app</strong> from scratch with Android studio. In the next tutorial, I would be going deeper into ARCore and adding more functionality to the app.</p>
<blockquote>
<p><em>If you have any suggestions or any topic you would want a tutorial on, just mention in the comments section and I’ll be happy to oblige.</em></p>
</blockquote>
<p><em>Like what you read? Don’t forget to share this post on <a target="_blank" href="https://www.facebook.com/AndroidVille"><strong>Facebook</strong></a>, <strong>Whatsapp</strong> and <strong>LinkedIn</strong>.</em></p>
<p><em>You can follow me on <a target="_blank" href="https://www.linkedin.com/in/ayuschjain">LinkedIn</a>, <a target="_blank" href="https://www.quora.com/profile/Ayusch-Jain">Quora</a>, <a target="_blank" href="https://twitter.com/ayuschjain">Twitter</a> and <a target="_blank" href="https://www.instagram.com/androidville/">Instagram</a> where I <strong>answer</strong> questions related to <strong>Mobile Development, especially Android and Flutter</strong>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to visualize random distribution algorithms in Swift and ARKit ]]>
                </title>
                <description>
                    <![CDATA[ By Dan Wyszynski A tree in the forest I was recently working on a prototype where I needed to place a large amount of objects in 3D space. This was an AR project, and the thought was that these objects would be placed around you in a random fashion, ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/visualizing-random-distribution-algorithms-in-swift-and-arkit-4e05f502755b/</link>
                <guid isPermaLink="false">66c36497da3c91501890b9e0</guid>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 30 Aug 2018 16:12:18 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*DLjYdq6QI0HUu4SRVC90Mw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dan Wyszynski</p>
<h3 id="heading-a-tree-in-the-forest">A tree in the forest</h3>
<p>I was recently working on a prototype where I needed to place a large amount of objects in 3D space. This was an AR project, and the thought was that these objects would be placed around you in a random fashion, scattering around you as they dropped in from the sky.</p>
<p>This brings up a few problems. First, we don’t know the current surroundings of the user, so we have to limit the radius of the dropped items to something that we can configure based on location or other factors.</p>
<p>Next, we know that built-in random generators are not very random unless specific precautions are taken.</p>
<p>Lastly, generating points with random generators, no matter how random, results in clustering, where many of the generated points can fall in close areas to one another, and leave you with spots that are bald of any points. And nobody wants bald spots: trust me, I know.</p>
<p>There are a number of ways to accomplish random equal distribution. Like any developer worth his salt, I found a couple which have simple implementations that work well for our purpose. Let’s examine each one, and implement them in Swift using ARKit and SceneKit.</p>
<h3 id="heading-roll-them-dice">Roll them dice!</h3>
<p>Before we get to the “good” algorithms, we should look to see what we get by using just random numbers to place our points. In doing this, we’ll get our app put together and use it to test out the other implementations in the same form.</p>
<p>Let’s create our app and get some of the basic stuff in place. Open up Xcode and create a new project using the Augmented Reality App template. Build and run the app to make sure everything is working and you see the default ship appear in front of your phone when running the app.</p>
<p>Next, we’re going set up our project like we did for the <a target="_blank" href="https://medium.com/s23nyc-tech/getting-started-with-arkit-and-scenekit-76814862cc75">first tutorial</a> in my ARKit series. Follow the steps in that tutorial, with the one difference being the name of the scene file. Instead of naming it <strong>HoverScene</strong>, we’ll name it <code>**MainScene**</code> instead. Add the render delegate as described in the tutorial, and follow the <strong>Extra Credits</strong> section where the tap gesture recognizer is created.</p>
<p>At this point the project is almost ready, but we don’t have (nor need) the <code>addSphere</code> method that is referenced in that tutorial. Instead, we will begin creating our algorithm generators.</p>
<p>Create a file called <code>**PointGenerator.swift**</code>. In here we’ll put several iterations of our algorithms. Let’s begin with the random number point generator. We’ll create a protocol that our algorithms will adhere to, making it easy to switch between algorithms in our source later on.</p>
<p>Our protocol is simple. Given a number of points to generate and a width and length to limit the points to, give back an array of points:</p>
<p>Our <code>RandomPointGenerator</code> will adhere to this class and output our first set of results:</p>
<p>The code here is simple. We iterate and create points that lie within the width and length limits, placing points on either side of the midpoint of those limits. We add the created points to an array then simply return the points.</p>
<p>Create a class called <code>Visualizer</code> derived from <code>SCNNode</code>. This class will serve as the container that holds the objects that we’ll place in the world to visualize the point set. For the moment, we’re going to create small spheres at each point generated by our algorithms.</p>
<p>This is what our class should look like:</p>
<p>Alright, now we’re ready to create our points. Let’s go back to our <code>MainScene</code> class and add a method called <code>createPointField</code>, which takes in a <code>SCNVector3</code> position:</p>
<p>We’re going to call this from our <code>ViewController</code> when we tap on the screen. Let’s go to our <code>didTapScreen</code> method and make the part where we previously created a sphere (in that first tutorial) look like the following:</p>
<p>Build and run, and we now have our first algorithm implemented.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Q7WoWRzhOP9iSMBkKDVofA.jpeg" alt="Image" width="750" height="1068" loading="lazy">
<em>Random placement of points. Not great.</em></p>
<p>Notice how the spheres are clustered in certain spots. This is exactly what we want to avoid.</p>
<p>I won’t get into detailed descriptions of each algorithm, but I’ll provide links to the sites that I found informative and gave me the inspiration to implement in Swift and AR.</p>
<h4 id="heading-poisson-sampling-and-mitchells-best-candidate">Poisson Sampling and Mitchell’s best-candidate</h4>
<p>What we need as an alternative to the random number generator way is an algorithm which returns a set of points that are close to each other, but no closer than some specified minimum distance. That’s where <strong>Poisson-disc sampling</strong> comes into the picture. There are several ways of implementing the Poisson-disc algorithm. The one we’re going to be implementing in our code is called <strong>Mitchell’s best-candidate</strong> algorithm. It’s easy to implement and runs fast.</p>
<p>The idea behind the algorithm is to place down points, and as you place them, check whether they meet the requirement of being at least the minimum distance away from the points already placed. To do this, you sample the point as you place it, by looking at the distance that nearby points have. If there are no points within the minimum requirement, place the new point, otherwise, try to find another location. You can read more about the algorithm <a target="_blank" href="https://bost.ocks.org/mike/algorithms/">here</a>.</p>
<p>To implement, we’re going to create another implementation of our <code>**PointGenerator**</code> protocol:</p>
<p>Let’s head back to our <code>MainScene</code> class, comment out the random generator lines, and add these new lines in:</p>
<p>Run the app again, and let’s look at our results.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*7xvbJ3FRTKwiEPdCKmPhWQ.jpeg" alt="Image" width="750" height="1084" loading="lazy">
<em>Poisson-disc using Mitchell’s best candidate method</em></p>
<p>Much better! There are no big clusters or barren areas. This is now something we can use to place items in the world. Other uses for this algorithm include things like dynamically generating textures at runtime or noise generators.</p>
<p>We have what we need with this implementation, and we’re going to make use of it later. But what if we wanted to have something a bit different, where we need uniform distribution within a circular boundary? This is where the Sunflower Seed algorithm comes in.</p>
<h3 id="heading-extra-credit">Extra Credit</h3>
<h4 id="heading-sunflower-seed-algorithm">Sunflower Seed Algorithm</h4>
<p>Throughout history, we have found mathematical patterns in nature. One of the interesting features in many of these patterns that are mimicked in nature is the existence of the Fibonacci sequence in plants. These features manifest themselves in spiral patterns in leaves, seeds and petal arrangements. The study of these patterns is called <strong>Phyllotaxis</strong>. The following algorithm implements the mathematical model of one of these spirals. You can find more info <a target="_blank" href="https://thatsmaths.com/2014/06/05/sunflowers-and-fibonacci-models-of-efficiency/">here</a> and <a target="_blank" href="https://www.popmath.org.uk/rpamaths/rpampages/sunflower.html">here</a>.</p>
<p>Let’s go back to our <code>PointGenerator</code> file and create our new implementation:</p>
<p>You’ll notice here that we are ignoring the <strong>width</strong> and <strong>height</strong> parameters passed in. This is because instead of constraining the points to a region, we will be evenly distributing the points in a spiral fashion until we run out of points.</p>
<p>Changing the <code>alpha</code> in the parameter passed in to the <code>sunflower</code> method controls the granularity of the points at the edge of the boundary. That is, we can make the boundary smoother or rougher by controlling the point distribution. The above code uses an <code>alpha</code> of <code>2</code>, which is on the high side, and results in a more even boundary.</p>
<p>Let’s go to our <code>MainScene</code> again, and comment out the previous algorithm. Let’s add in a call to get our <code>Sunflower</code> pattern generating points:</p>
<p>Let’s run our app again and see what we get.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*jfw0td6NYTbk0m9m637FJQ.jpeg" alt="Image" width="750" height="1099" loading="lazy">
<em>Sunflower Algorithm</em></p>
<p>As you can see, we have a pattern that mimics the way sunflowers hold their seeds. There is also an interesting variation we can apply to the algorithm, as detailed in one of the comments in this Stack Overflow <a target="_blank" href="https://stackoverflow.com/questions/28567166/uniformly-distribute-x-points-inside-a-circle">question</a>.</p>
<p>By changing the <code>theta</code> to a bearing, the commenter turned the algorithm into a geodesic formation.</p>
<p>Change the <code>theta</code> line in our code to the following:</p>
<p>Let’s run our algorithm again and see what it looks like.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*DLjYdq6QI0HUu4SRVC90Mw.jpeg" alt="Image" width="750" height="906" loading="lazy">
<em>Sunflower Algorithm with spiral pattern</em></p>
<p>Cool! Now we have the pattern as spirals.</p>
<p>Speaking of spirals, let’s check out one last algorithm.</p>
<h3 id="heading-the-vogel-spiral">The Vogel Spiral</h3>
<p>Here we have another closely related algorithm which also uses a Fibonacci sequence and the <a target="_blank" href="https://en.wikipedia.org/wiki/Golden_angle">Golden Angle</a>. You can read more about the Vogel Spiral <a target="_blank" href="https://www.codeproject.com/Articles/1221341/The-Vogel-Spiral-Phenomenon">here</a> and <a target="_blank" href="http://www.dcs.gla.ac.uk/~jhw/spirals/">here</a>.</p>
<p>Let’s implement it, and then we’ll tweak it to see how it influences the results.</p>
<p>In our <code>PointGenerator</code> class, add our implementation of this algorithm.</p>
<p>This algorithm, like the Sunflower Seed algorithm, also ignores the <strong>width</strong> and <strong>height</strong> parameters.</p>
<p>Let’s replace the previous algorithm with our new calls.</p>
<p>Let’s give that a run and see what we get.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*E8jaDtxL84_HPeJVAmXu3w.jpeg" alt="Image" width="750" height="901" loading="lazy">
<em>Vogel Spiral</em></p>
<p>Nice! Now, let’s try different variations of this algorithm. By changing the formula, we can get different spiral formations. Change the <code>it</code> declaration to the following line:</p>
<p>Run that and check out what we get.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*QAo1ria723ab_6VSTUTgVg.jpeg" alt="Image" width="750" height="837" loading="lazy">
<em>Vogel spiral, looking like the Sunflower</em></p>
<p>That spiral now looks like a flipped version of our Sunflower spiral with the updated <code>theta</code>. Interesting!</p>
<p>Let’s try it with the following formula:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*uBr1Oa3mrnt3GmdxCiWg5g.jpeg" alt="Image" width="750" height="986" loading="lazy">
<em>Vogel spirals</em></p>
<p>Similar to the first algorithm, but the spirals are separated. Very cool stuff!</p>
<p>We’ve now run through 4 different algorithms, including the not-very-good strictly random number placement. Each one of these has a place in our toolbox, though, and they can be used to fulfill a variety of needs.</p>
<h3 id="heading-extra-credit-part-two">Extra Credit, Part Two</h3>
<p>It wouldn’t be an article of mine if we didn’t do something cool with what we just learned, now would it?</p>
<p>Download some tree models from a 3D model store like Sketchfab or Turbosquid. Convert them to Collada (DAE) format as needed and add them to your project. You may need to resize them to be the proper scale when putting them in your scene, but you’ll know when you go to use them. Be sure to use a low poly model since we are talking about instantiating dozens and even hundreds of object instances.</p>
<p>Let’s make a <code>Tree</code> class that derives from <code>**SceneObject**</code> (we created this class back in our previous tutorial). We’ll make it load a random tree from the ones we have added into our app. We make use of the random convenience function we also added in a previous tutorial.</p>
<p>Here’s what my <code>Tree</code> class looks like:</p>
<p>Let’s use the Mitchell algorithm and bring down the number of models (points) we want to generate to 60. Depending on the amount of polygons in your models, this might be too large. I started with a different set of models and it took a while to place 20 models. Start low and work your way up. For the models I used I could go higher, but 60 was dense enough.</p>
<p>In our <code>Visualizer</code> code, let’s change our <code>Tree</code> creation to animate the scaling up a bit.</p>
<p>In my case, with the models I used, I had to scale them down a bit to get them to a reasonable size which is where that 0.45 comes from. I also lowered the position a bit so that they lay on the ground plane. You can adjust these numbers to whatever fits your situation.</p>
<p>Build and run, and now we have a happy little forest created with almost no effort.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*3xGOTLUtmoisLbHm-CO2ag.gif" alt="Image" width="350" height="542" loading="lazy">
<em>Our happy little forest</em></p>
<p>Hope you enjoyed this little experiment. Feel free to show off your work in the comment section!</p>
<p><a target="_blank" href="https://medium.com/@AbovegroundDan">Daniel Wyszynski</a> is a developer who’s worked on more platforms and languages than he cares to admit to. He believes in building products that create memorable user experiences. To Dan, the users are first, the platforms are second. Follow Dan on <a target="_blank" href="https://medium.com/@AbovegroundDan">Medium</a> or <a target="_blank" href="https://twitter.com/AbovegroundDan">Twitter</a> to hear more from him. Also check out the <a target="_blank" href="https://medium.com/s23nyc-tech">s23NYC: Engineering</a> blog, where a lot of great content by Nike’s Digital Innovation team gets posted.</p>
<p><em>Author’s Note: Views are my own and do not necessarily represent those of my employer</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How you can use AI, AR, and WebGL shaders to assist the visually impaired ]]>
                </title>
                <description>
                    <![CDATA[ By Dan Ruta Today, about 4% of the world’s population is visually impaired. Tasks like simple navigation across a room, or walking down a street pose real dangers they have to face every day. Current technology based solutions are too inaccessible, o... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-you-can-use-ai-ar-and-webgl-shaders-to-assist-the-visually-impaired-3df5bdf3b3e2/</link>
                <guid isPermaLink="false">66c356dc7ef110ecbf367afb</guid>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 27 Aug 2018 21:25:37 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*1Vg0Gku4F-8K6sFtQiOZFQ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Dan Ruta</p>
<p>Today, about 4% of the world’s population is visually impaired. Tasks like simple navigation across a room, or walking down a street pose real dangers they have to face every day. Current technology based solutions are too inaccessible, or difficult to use.</p>
<p>As part of a university assignment, we (<a target="_blank" href="https://twitter.com/Dan_Ruta">myself</a>, <a target="_blank" href="https://twitter.com/LouisJordan">Louis</a>, and <a target="_blank" href="https://www.instagram.com/thomas.j.fox96/">Tom</a>) devised and implemented a new solution. We used configurable WebGL shaders to augment a video feed of a user’s surroundings in real-time. We rendered the output in a AR/VR format, with effects such as edge detection and color adjustments. Later, we also added color blindness simulation, for designers to use. We also added some AI experiments.</p>
<p>We did a more in-depth literature review in our original research paper. ACM published a shorter, two page version <a target="_blank" href="https://dl.acm.org/citation.cfm?id=3196319&amp;dl=ACM&amp;coll=DL&amp;preflayout=flat">here</a>. This article focuses more on the technologies used, as well as some of the further uses, and experiments such as AI integration.</p>
<p>A popular approach we found in our studies of existing solutions was the use of edge detection for detecting obstacles in the environment. Most solutions fell short in terms of usability, or hardware accessibility and portability.</p>
<p>The most intuitive approach we could think of as feedback to the user was through the use of a VR headset. While this meant that the system would not be of help to very severely visually impaired people, it would be a much more intuitive system for those with partial sight, especially for those with blurry vision.</p>
<h4 id="heading-edge-detection">Edge detection</h4>
<p>Feature detection, such as edges, are best done using 2D convolutions, and are even used in deep learning (<a target="_blank" href="http://cs231n.github.io/convolutional-networks/">convolutional neural networks</a>). Simply put, these are dot products of a grid of image data (pixels) against weights in a kernel/filter. In edge detection, the output is higher (more white) when the pixel values line up with the filter values, representing an edge.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/mSstLIsZsNZK2vz-UaV3bLTnpiyQpoKTzNmk" alt="Image" width="364" height="219" loading="lazy">
_This is done for every pixel. - [Image credit](http://jeanvitor.com/convolution-parallel-algorithm-python/" rel="noopener" target="<em>blank" title=")</em></p>
<p>There are a few available options for edge detection filters. The ones we included as configurations are Frei-chen, and the 3x3 and 5x5 variants of <a target="_blank" href="https://en.wikipedia.org/wiki/Sobel_operator">Sobel</a>. They each achieved the same goal, but with slight differences. For example, the 3x3 Sobel filter was sharper than the 5x5 filter, but included more noise, from textures such as fabric:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/St0sndi1cpWo4e9GcpCu9p6yRITP8PVv1pTR" alt="Image" width="800" height="250" loading="lazy">
<em>Left: 3x3, Right: 5x5</em></p>
<h4 id="heading-the-web-platform">The web platform</h4>
<p>The primary reason we chose the web as a platform was its wide availability, and compatibility across almost all mobile devices. It also benefits from easier access, compared to native apps. However, this trade-off came with a few issues, mostly in terms of necessary set-up steps that a user would need to take:</p>
<ol>
<li>Ensure network connectivity</li>
<li>Navigate to the web page</li>
<li>Turn the device to landscape mode</li>
<li>Configure the effect</li>
<li>Enable VR mode</li>
<li>Activate full screen mode (by tapping the screen)</li>
<li>Slot the phone into a VR headset</li>
</ol>
<p>To avoid confusing a non-technical user, we created the website as a PWA (<a target="_blank" href="https://developers.google.com/web/progressive-web-apps/">progressive web app</a>), allowing the user to save it to their Android home screen. This ensures it always starts on the correct page, landscape mode is forced on, the app is always full screen, and not reliant on a network connection.</p>
<h4 id="heading-performance">Performance</h4>
<p>Early JavaScript prototypes ran nowhere near our 60fps target, due to the very expensive convolution operations. We suspected that the bottleneck was JavaScript itself. We attempted a WebAssembly version. The resulting prototype ran even slower. This was most likely due to the overhead in passing the video frame data to the WebAssembly code, and back.</p>
<p>So instead, we turned to WebGL shaders. Shaders are awesome because of their extreme parallelization of a bit of code (the shader) across the texture (video feed) pixels. To maintain high performance, while keeping a high level of customization, the shader code had to be spliced together and re-compiled at run-time, as configurations changed, but with this, we managed to stay within the 16.7ms frame budget needed for 60fps.</p>
<h4 id="heading-feedback">Feedback</h4>
<p>We carried out some user testing. We tested some basic tasks like navigation, and collected some qualitative feedback. This included adjustments to the UI, a suggestion to add an option to configure the colors of the edges and surfaces, and a remark that the field of view (FoV) was too low.</p>
<p>Both software improvement suggestions were applied. The FoV was not something which could have been fixed through software, due to camera hardware limitations. However, we managed to find a solution for this in the form of cheaply available phone-camera fish-eye lenses. The lenses expanded the FoV optically, instead of digitally.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/4jBuDXQcVSRCIW10boRa-Tl5rtdoEYHqerGM" alt="Image" width="349" height="301" loading="lazy">
<em>Fish-eye lens</em></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/SDASEK6w5TFLXm7eXYzjYRQD1Ld7uWWTzofn" alt="Image" width="800" height="278" loading="lazy">
<em>Left: no lens, Right: with lens</em></p>
<p>Other than that, the system surpassed initial expectations, but fell short on reading text. This was due to there being two sets of edges for each character. Low light performance was also usable, despite the introduction of more noise.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/XUnEmgZYZn2cj5iSAEQvnXLHE0JlclqFWhXm" alt="Image" width="800" height="273" loading="lazy">
<em>Some shader effect configuration examples</em></p>
<p>Some other configurations we included was the radius of the effect, its intensity, and color inversion.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/5jvE831AtBsKj7eFSXr0hzCwmJTkfsmdzPsA" alt="Image" width="800" height="292" loading="lazy">
<em>The options menu</em></p>
<h4 id="heading-other-use-cases">Other use cases</h4>
<p>An idea we had was to add shader effects to simulate various types of color blindness, providing an easy way for designers to detect color blindness related accessibility issues in their products, be they software or otherwise.</p>
<p>Using RGB ratio values found <a target="_blank" href="http://web.archive.org/web/20081014161121/http://www.colorjack.com/labs/colormatrix/">here</a>, and turning off edge detection, we were able to add basic simulations of all major types of color blindness through extra, toggle-able components in the shaders.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/YflPhnWBrDuIrMI2w-WeOjQ122D-Vhz9E60J" alt="Image" width="281" height="276" loading="lazy">
_Ishihara test - [Image Credit](http://www.colour-blindness.com/colour-blindness-tests/ishihara-colour-test-plates/" rel="noopener" target="<em>blank" title=")</em></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/BGBmXtHVuvC7WeWoFPubBOMCRZjevjccC3VP" alt="Image" width="800" height="343" loading="lazy">
<em><strong>(Left)</strong> Normal <strong>(Right)</strong> Deuteranopia filter</em></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/b4ZsxdfjfGFJAL2WxJ7EpBIaighVoALhJqOp" alt="Image" width="800" height="343" loading="lazy">
<em><strong>(Left)</strong> Normal <strong>(Right)</strong> Protanopia filter</em></p>
<h4 id="heading-ai-and-future-work">AI and future work</h4>
<p>Although it’s an experiment, still in its very early stages, higher level object detection can be done using <a target="_blank" href="https://js.tensorflow.org/">tensorflowjs</a> and <a target="_blank" href="https://github.com/ModelDepot/tfjs-yolo-tiny">tfjs-yolo-tiny</a>, a tensorflowjs port of <a target="_blank" href="https://pjreddie.com/darknet/yolo/">tiny-yolo</a>, a smaller and faster version of the YOLO object detection model.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/J6bwH0h0HQXONQaDapoimg6aUDcAr5jjJ2c6" alt="Image" width="800" height="328" loading="lazy">
<em>The current categories</em></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/YGBVsqdO0WC9HizjlwNVoWOfh2I-XRHuqeMK" alt="Image" width="800" height="546" loading="lazy">
<em>Example inference, using a laptop. Requires a decent GPU, to work.</em></p>
<p>The next step is to get instance segmentation working in a browser, with something similar to <a target="_blank" href="https://github.com/matterport/Mask_RCNN">mask rcnn</a> (though, it may need to be smaller, like tiny-yolo), and add it to WebSight, to highlight items with a color mask, instead of boxes with labels.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/fs-OeTSPqBXdyLhBL8oU7gqIAQknnb3tDyr5" alt="Image" width="680" height="382" loading="lazy">
_Goals — [Source](https://github.com/matterport/Mask_RCNN#4k-video-demo-by-karol-majek" rel="noopener" target="<em>blank" title=")</em></p>
<p>The GitHub repo is <a target="_blank" href="https://github.com/DanRuta/WebSight">here</a>, and a live demo can be found at <a target="_blank" href="https://websight.danruta.co.uk">https://websight.danruta.co.uk</a>. Do note that until Apple provides support for the camera API in browsers, it might not work on Apple phones.</p>
<p>Of course, I had some extra fun with this as well. Being able to edit what you can see around you in real time opens up a world of opportunities.</p>
<p>For example, using a <a target="_blank" href="https://websight.danruta.co.uk/#matrix">Matrix shader</a>, you can feel like The One.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/PGMyqHkLVWBECPfmIxvEqpAGD7uz8e6pcPWf" alt="Image" width="680" height="318" loading="lazy">
<em>Everything is drawn using green digits, not lines</em></p>
<p>Or maybe you just enjoy watching the world <a target="_blank" href="https://websight.danruta.co.uk/#fire">burn</a>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/3rZoIwLMDtceBYESlehqZWPecrbUdCjN8lLu" alt="Image" width="800" height="359" loading="lazy">
_Playing: [Billy Joel — We Didn’t Start the Fire](https://www.youtube.com/watch?v=eFTLKWw542g" rel="noopener" target="<em>blank" title=")</em></p>
<p>You can tweet more shader ideas at me here: @DanRuta</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to get started with augmented reality in Swift by decorating your home ]]>
                </title>
                <description>
                    <![CDATA[ By Ranadhir Dey If you’ve read my previous post, you already have a beautiful AR floor in your dining room. That was the first thing we built while learning the basics of AR. And now, it’s time to decorate the room with some cool virtual furniture. A... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-get-started-with-augmented-reality-in-swift-by-decorating-your-home-85671482df3c/</link>
                <guid isPermaLink="false">66c35241bbe01f9810478686</guid>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 08 Aug 2018 19:03:08 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*ycF6WrJkcT0SUg45pM-reg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ranadhir Dey</p>
<p>If you’ve read my previous post, you already have a beautiful AR floor in your dining room. That was the first thing we built while learning the <a target="_blank" href="https://medium.freecodecamp.org/how-to-get-started-with-ar-in-swift-the-easy-way-7399fe1c82f5">basics of AR</a>. And now, it’s time to decorate the room with some cool virtual furniture. At the end of this tutorial, you will have a dining room just like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*ANkvfr-d7BmwxS_AxGD6zw.gif" alt="Image" width="404" height="640" loading="lazy"></p>
<h3 id="heading-naming-scnnodes">Naming SCNNodes</h3>
<p>Let’s get our hands dirty. Fire up Xcode, and open the <a target="_blank" href="https://github.com/ranadhirdey/Home-Decor">last project</a> where we decorated our floor. Before viewDidLoad, create a constant floorNodeName.</p>
<pre><code><span class="hljs-keyword">let</span> floorNodeName = <span class="hljs-string">"FloorNode"</span>
</code></pre><p>We are now going to set the name of the floor node to this constant so that we don’t mix up this node with other furniture nodes. Go to the createFloorNode method and name the floor node.</p>
<p>In line 7 we have just named the floor node — everything else remains the same.</p>
<p>The plan is that, once launched, the app would recognise the floor first and then the user would see through the screen to determine where they want to place the furniture. They would tap on the location and a piece of furniture would sit just there. To achieve this, we need a correlation between the points on screen and the real-world locations. Thankfully, Apple has made this process quite simple.</p>
<h3 id="heading-gestures-and-hittests">Gestures and HitTests</h3>
<p>An active AR session keeps on finding nearby objects/planes. Once a new object/plane is found, it places AR anchors on top of it. To find exactly on which anchors user has tapped, we need the help of <a target="_blank" href="https://developer.apple.com/documentation/arkit/arframe/2875718-hittest">HitTest</a>. HitTest works like this:</p>
<ul>
<li>a logical ray is shot from the point of touch to the anchors on the plane</li>
<li>all the anchors the ray passes through are stored in an array in the format of <a target="_blank" href="https://developer.apple.com/documentation/arkit/arhittestresult">HitTestResult</a>.</li>
</ul>
<p>Each HitTestResult contains the information of the real-world surface of an AR anchor. We will use this HitTestResult information to place our furniture.</p>
<p>Let’s create a method that adds the tap gesture to our sceneView to interact with the user. We’ll call this method from viewDidLoad.</p>
<p>Now define the “tapped” method to get the location of the tap and place a furniture there. For now, we print to test if the HitTest is working fine.</p>
<p>In the first line, we are casting tap gesture’s view to ARSCNView. As we know that the tap will come from our sceneView itself, we force-unwrap it. Then we get the location on sceneView where user has tapped. Then a HitTest is performed to get all the HitTestResults from the tapped location to the real-world anchors. “.existingPlaneUsingExtent” gives the estimated size of the detected planes. Now, we check if the user actually has tapped on a detected plane or somewhere else, and we print accordingly.</p>
<p>Now run the app, wait until the world origin loads and the floor is detected. Then tap on the screen to check if we are hitting the planes correctly.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*hPQSMPreK6Nv3bypYaaR_Q.png" alt="Image" width="800" height="407" loading="lazy"></p>
<p>If you tap on the places where the tiles are located, it will print “Touched on the plane.” Touch anywhere else, and it will be “Not a plane.” If there’s no output in the console, you haven’t called the addTapGesture method from viewDidLoad (this happed to me!). Now that we have successfully detected the clicked position, it’s time to bring home some furniture.</p>
<h3 id="heading-importing-3d-models-to-the-project">Importing 3D models to the project</h3>
<p>We need some 3D furniture models. I use <a target="_blank" href="https://www.turbosquid.com/">turbosquid</a>, which is a great repository of 3D models. You need to create a free account there to access their free models. I’ve downloaded a 3D <a target="_blank" href="https://www.turbosquid.com/3d-models/3d-small-dining-table-1161153">table</a> for now (in the GitHub repo — I’ll add some more furniture as well).</p>
<p><a target="_blank" href="https://developer.apple.com/documentation/scenekit/scnscenesource?changes=_4">Apple advises</a> you to use collada-formatted(.dae) models in SceneKit. I have used other kinds of models as well in the past, and I have faced problems in many cases. Mostly, if there is a glass, SceneKit tends to make it solid. So, let’s find 3D models with a .dae extension.</p>
<p>Now add an asset folder under the “Home Decor” group.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*uZdqGuSoLDUxBwrXlOYxUQ.png" alt="Image" width="800" height="585" loading="lazy"></p>
<p>Press next, and in the save dialog, save it as furnitures.<strong>scnassets</strong> and not xcassets.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*xtrw-mhR3k5NKcfRtOUoZw.png" alt="Image" width="800" height="755" loading="lazy"></p>
<h3 id="heading-working-with-xcode-scenekit-editor">Working with Xcode SceneKit Editor</h3>
<p>All scene files or models that will be used by SceneKit should reside in a scnassets folder. Now drag and drop the table we just downloaded to the scnassets folder and rename it as “Table”. Click on the Table.dae file (if not already opened) to open it in SceneKit Editor. On the bottom left corner there is a button (marked with a red ellipse below) to open Scene Graph View. Click on it and the editor should appear like below.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*qffmqaKYDb8vMjRCiqB-8g.png" alt="Image" width="800" height="596" loading="lazy"></p>
<p>In the Scene Graph there are 3 nodes: a Camera, a light source (Lamp) and the table (Small_table). ARKit has its default camera, so we don’t need this camera anymore. As we will be using sceneView’s default lighting, we don’t need the Lamp either. Remove both of them.</p>
<p>Let’s rename “Small_table” to “Table”, same as the file name. Now the scene graph will look like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*FSabN1vH7ZexHcv6Wmscdw.png" alt="Image" width="800" height="483" loading="lazy"></p>
<p>There is something called point of view (marked with a red ellipse above) in the editor which determines how the object will look from a certain point of view. By default, it’s set to Perspective, but we will be seeing the table from the front. So change the point of view to Front.</p>
<p>Oops — it looks like we can see only the top view. Clearly, this isn’t how we would like to see it. We want to see the table as it was shown in the perspective view. Let’s fix this.</p>
<p>Select the Table node, open the Utilities tab (right-top corner button in Xcode) and click on the node inspector(the cube icon). You should see the below window.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*vt6XWmh6fsRBmBIbe1Qgaw.png" alt="Image" width="800" height="626" loading="lazy"></p>
<p>I’ve numbered the steps for your reference. To view the complete table from the front, we need to rotate the table on its X axis. If you can recollect, we did same kind of thing in the <a target="_blank" href="https://medium.freecodecamp.org/how-to-get-started-with-ar-in-swift-the-easy-way-7399fe1c82f5">first post</a> where we rotated the capsule on its Z axis by changing its Euler angle.</p>
<p>If you see the Transforms matrix, the Euler angle for X is already specified to 90 degree radians, which is causing the table to be rotated incorrectly. Make it zero and the rotation will be fixed. But the positioning has a vector of (-0.35,0.348,0). We will make it (0,0,0) to place the table exactly where the user will tap. Now the Transform will look like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*ZnK7C1ACHG-roVzMnNCWsg.png" alt="Image" width="522" height="854" loading="lazy"></p>
<p>Transform matrix editing is kind of a trial and error task. You might need to go through quite a number of iterations before you reach the exact position.</p>
<p>Now, we change the .dae model to a SceneKit scene file (.scn) which will made it much more efficient for SceneKit to handle. Go to Editor&gt;Convert to SceneKit scene file(.scn).</p>
<p>And…we are done with the 3D object editing. Head back to the ViewController file. First, since we have removed the light source of the table, we should turn on the default lighting of the scene view in viewDidLoad.</p>
<p>sceneView.autoenablesDefaultLighting = true</p>
<h3 id="heading-positioning-3d-objects">Positioning 3D objects</h3>
<p>Then we create a method to add the table to the scene. It will accept a HitResult as a parameter and place the table based on the position of the HitResult.</p>
<p>Bear with me — this is the last method which needs some explanation!</p>
<ol>
<li>A constant is declared to know what furniture scene needs to be added. We will change it to a variable and declare it on top of the viewcontroller when we have more furniture.</li>
<li>Then we create a scene from the selected furniture file.</li>
<li>A furniture node is created from the child node of the furniture scene’s root node with the name of the furniture. As we named the first node the same as the furniture name, it doesn’t need to traverse any further. Hence the recursive option is set to false.</li>
<li>HitResult’s <a target="_blank" href="https://developer.apple.com/documentation/arkit/arhittestresult/2867907-worldtransform">worldTransform</a> property holds the co-relation transform matrix between the real-world position and the scene anchor/node position. And the 3rd column of the transform matrix holds the position information.</li>
<li>Now that we have successfully extracted the world coordinate of the tapped location, our job is now just to place the furniture node on that exact same coordinate.</li>
<li>Then we add the node to the root node of the scene. And thats it!</li>
</ol>
<p>Now we just need to call the method whenever the user taps on the screen. Let’s modify the tapped method to accommodate this change.</p>
<p>Here, if we find a plane, we are just calling the method to add the furniture. As HitTest holds all the positions the ray passes through, we are considering the top most result. Let’s run the app, wait until the floor has tiles on it, and then tap on the screen to place a table. And voilà! You have a new table on your floor. Watch your step :)</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*HMeqtcy7IoAzqkiwRoPBkg.png" alt="Image" width="750" height="1334" loading="lazy"></p>
<p>I have downloaded some more furniture and have added it into the repo. I’ve also added pinch and rotate gestures to resize and rotate objects. The complete source code will give you an appearance like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*ycF6WrJkcT0SUg45pM-reg.jpeg" alt="Image" width="746" height="827" loading="lazy"></p>
<p>You can download the full source code from <a target="_blank" href="https://github.com/ranadhirdey/Home-Decor-With-Furniture">GitHub</a>.</p>
<p>Hope you have enjoyed reading the post as much as I did writing it :)</p>
<p>See you at the next post. Happy reading!!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ More “Future” Tech That’s Hiding in Plain Sight: Augmented Reality ]]>
                </title>
                <description>
                    <![CDATA[ By James Hsu As I discussed in the previous article on hot future tech, artificial intelligence (AI), augmented reality (AR/VR), blockchain, and the Internet of Things (IoT) might seem a long way off from mainstream adoption. Movies like Ready Player... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/more-future-tech-thats-hiding-in-plain-sight-augmented-reality-fd9680391e8f/</link>
                <guid isPermaLink="false">66c35b829de50ee9ca7fa70f</guid>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ecommerce ]]>
                    </category>
                
                    <category>
                        <![CDATA[ marketing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Virtual Reality ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 25 Jul 2018 22:51:42 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*F2fcFHKDbNC-iaE2oZ1zqg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By James Hsu</p>
<p>As I discussed in the previous article on hot future tech, artificial intelligence (AI), augmented reality (AR/VR), blockchain, and the Internet of Things (IoT) might seem a long way off from mainstream adoption.</p>
<p>Movies like <strong>Ready Player One</strong> and <strong>Avengers: Infinity Wars</strong> only perpetuate this perception by mixing real technologies with fantasy, making the tech we wield in the real world seem primitive in the process.</p>
<p>The reality, though?</p>
<p>AI, AR/VR, blockchain, and IoT are already playing an important role in our everyday lives, with countless examples hiding in plain sight.</p>
<p>In <a target="_blank" href="https://medium.freecodecamp.org/future-tech-thats-hiding-in-plain-sight-artificial-intelligence-683cce8a7d7a">Part One</a> of our series, we explored how Artificial Intelligence (AI) is already deeply integrated into apps we use every day. In this article, we’ll dive into <strong>Augmented Reality (AR).</strong></p>
<h3 id="heading-what-is-augmented-reality">What is Augmented Reality?</h3>
<p>Not to be confused with virtual reality (VR), which is 100% driven by computer generated images, <strong>augmented reality (AR)</strong> is a technology that combines computer-generated visuals with a user’s live view of the real world, resulting in a composite view.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*fgPEedxdrtadrbl80ClZ4Q.jpeg" alt="Image" width="720" height="405" loading="lazy">
<em>The Pixels movie was a somewhat loose interpretation of augmented reality.</em></p>
<p>For the most part, AR today is meant to be experienced through the lenses of devices like smartphones. (Microsoft’s attempt to evangelize head-worn AR, or what it calls “mixed reality”, is gaining traction in some areas but can still be considered niche.)</p>
<p>Modern smartphones come equipped with everything you need to enjoy an engaging AR experience:</p>
<ul>
<li>A digital camera for providing a video feed of the real world.</li>
<li>A computer to store and run software applications.</li>
<li>A powerful processor capable of <strong>computer vision</strong> (CV), for accurate placement of the computer-generated images “into” the real world.</li>
<li>A high-res display capable of showing the real-time composite view.</li>
<li>Gyroscope sensors for sensing changes in orientation, to make the composite view more engaging/dynamic.</li>
</ul>
<p>There is a massive business opportunity tied to the fact that all the hardware needed to experience meaningful AR applications today can be found inside any modern smartphone.</p>
<h3 id="heading-ar-in-ecommerce">AR in Ecommerce</h3>
<p>It can be challenging to spend your hard-earned cash on furniture you’ve never actually laid eyes on in person. And, even if you have seen a piece of furniture in person, questions remain that might prevent you from pulling the trigger on a purchase.</p>
<p><em>How will it look with my coffee table and side tables? Is it too traditional for my living room? Will that color look tacky against the floral wall paper and shag carpet?</em></p>
<p>Likewise, with fashion ecommerce, how do you know whether that designer jacket will actually look good on you without taking it into a fitting room and seeing whether it jives with the jeans and boots you’re wearing?</p>
<p>This is where AR comes in.</p>
<p>Companies like <a target="_blank" href="https://www.amazon.com/adlp/arview">Amazon</a>, <a target="_blank" href="https://highlights.ikea.com/2017/ikea-place/">IKEA</a>, and <a target="_blank" href="https://techcrunch.com/2017/10/24/target-adds-ar-shopping-to-its-mobile-website/">Target</a> have already added AR functionality to their mobile apps, allowing you to “place” virtual objects into your environment to preview how they might actually look in your home or office. You can place a virtual vase onto your actual coffee table (thanks to plane detection), or “push” a virtual wardrobe against your bedroom wall without breaking a sweat.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*wjvkiudnCBarj29AlvDnBA.jpeg" alt="Image" width="800" height="533" loading="lazy">
<em>Native mobile ecommerce apps can be upgraded to provide AR previews, as Amazon has done on both iOS and Android.</em></p>
<p>In fashion, Michael Kors will be using a Facebook AR-based ad campaign to provide users with a simple way to <a target="_blank" href="https://www.marketingtechnews.net/news/2018/jul/12/facebook-bringing-augmented-reality-ads-news-feed/">“try on” sunglasses</a> and other fashion merchandise before they buy.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*HSvp1FIT1_InIzIPdWOABQ.png" alt="Image" width="800" height="508" loading="lazy">
<em>Soon, any Facebook advertiser will be able to launch AR-based ad campaigns.</em></p>
<p>Ecommerce companies that allow shoppers to try out merchandise with AR believe that doing so will provide a significant lift in conversion rates — and consequently will help grow sales revenues.</p>
<h3 id="heading-ar-in-marketing-amp-advertising">AR in Marketing &amp; Advertising</h3>
<p>Even beyond the conversion-focused world of ecommerce, businesses are finding that augmented reality can be the perfect way to attract and engage potential customers.</p>
<p>Snap, the photography-obsessed creator of Snapchat, <a target="_blank" href="https://forbusiness.snapchat.com/blog/introducing-lens-studio-a-new-way-to-create-branded-ar-experiences/">has already deployed a commercial platform called Lens Studio, which allows businesses to “create branded AR experiences”</a>. Snapchat’s AR experiences are AR-based camera filters, called “lenses”, that Snapchat users are already very familiar with, thanks in part to earlier lenses like the Internet sensation, “Dancing Hotdog.”</p>
<p>See BMW’s Snapchat Lens in action below:</p>
<p>Facebook has also begun testing AR-based advertising with select clients (including Michael Kors, mentioned previously,) and is expected to make AR ad campaigns available to a wider audience of advertisers later in 2018. Early results are promising. ASUS reported that its AR-based test campaign <a target="_blank" href="https://www.mobilemarketer.com/news/michael-kors-is-first-to-test-ar-ads-in-facebook-news-feed/527504/">saw 10x the engagement of its non-AR counterpart</a>.</p>
<p>Beyond these platforms, CPG companies are creating standalone AR experiences to bring life to food or beverage products, for no other reason than to increase customer engagement and create a buzz. Patrón, the Mexican tequila company, launched an AR app last year that lets you plant your own agave field, from which a distillery and bartender emerge to tell you everything you’ve ever wanted to know about creating Patrón tequila.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*pe6Hz7g4L8agf0iPaVpkpA.jpeg" alt="Image" width="800" height="450" loading="lazy">
<em>The Patrón Experience lets you plant your own agave field and distillery on any flat surface.</em></p>
<p>For companies planning a new product launch or corporate event, adding an AR experience can help dial up both audience engagement and the resulting media coverage.</p>
<p>Consider Samsung’s Galaxy S9 product launch, where attendees were able to witness their name badges become virtual and interactive Galaxy S9 phones right in their very hands.</p>
<h3 id="heading-ar-in-industrial-and-medical-procedures">AR in Industrial and Medical Procedures</h3>
<p>Even if you’re not an industrial technician or a medical surgeon, you can probably appreciate the complexities inherent to these professions. One false move, and lives could be at stake.</p>
<p>Thanks to AR, things are becoming a whole lot easier for these professionals.</p>
<p>Energy giant BP has begun <a target="_blank" href="https://www.fieldbit.net/news/fieldbit-expands-collaboration-with-bp-to-deploy-smart-glasses-and-fieldbit-hero/">using AR to help technicians</a> in the field perform equipment maintenance. With the new technology, BP engineers wear AR headsets that transmit a live video feed to a remote expert, who can diagnose issues and then place relevant instructions and diagrams onto the field technician’s visual field (via the AR headset) in real time. This keeps the technician’s hands free to perform the necessary repairs.</p>
<p>Similar use cases are being developed <a target="_blank" href="https://hbr.org/2018/03/how-augmented-reality-will-make-surgery-safer">in the medical field</a>, where AR headsets can provide real time and hands-free information on surgical procedures and vital health information without having to look away from the patient.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*OcLTY2AduIHs6_vyywM_UA.jpeg" alt="Image" width="800" height="450" loading="lazy">
<em>A glimpse of what AR-enabled surgery might look like. Source: The Augmentarium at the University of Maryland (illustration by Brian G. Payne)</em></p>
<h3 id="heading-ar-gaming">AR Gaming</h3>
<p>It’s been two years since Pokemon Go first grabbed the world with its killer combination of geolocation and AR-based exploration, allowing every man, woman, and child to live out their Pokemon trainer fantasies in the real world.</p>
<p>Pokemon Go’s massive popularity (<a target="_blank" href="https://variety.com/2018/gaming/news/pokemon-go-2-years-1-billion-1202867409/">with nearly $2 billion in revenue to date</a>) has piqued plenty of interest and funding in AR gaming.</p>
<p><a target="_blank" href="https://play.google.com/store/apps/details?id=com.ludia.jw2&amp;hl=en_US">Jurassic World: Alive</a> launched earlier this year and doesn’t diverge very far from the location-based and collections-oriented gameplay made popular by Pokemon Go.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*lM_UlkJXbVYr1zHMds7vvg.jpeg" alt="Image" width="800" height="424" loading="lazy">
<em>Pokemon Go, but with dinosaurs?</em></p>
<p>A Walking Dead AR mobile game (<a target="_blank" href="https://www.thewalkingdeadourworld.com/">Walking Dead: Our World</a>) came out just last month, and Pokemon Go creator, Niantic, is expected to launch AR-based Harry Potter: Wizards Unite at <a target="_blank" href="https://www.forbes.com/sites/davidthier/2018/07/02/harry-potter-wizards-unite-release-date-when-will-niantics-next-big-game-come-out/#12a0a9e65cde">some point this year</a>.</p>
<p>Admittedly, one major weakness of today’s AR games is that the AR component is often non-essential to the core gameplay.</p>
<p>Newly-released Walking Dead: Our World is an “AR-optional” game — and one in which the vast majority of users appear to skip the AR mode altogether (partly because it’s not essential to progress in the game, but also because the AR mode seems to struggle with plane detection.)</p>
<p>Even Pokemon Go — which has an excellent AR experience — is AR-optional. You can catch Pokemon without firing up the AR mode, though finding a rare Pokemon sitting on your laundry machine is MUCH more enjoyable.</p>
<p>Some of these limitations are inherent to the software development kits (SDK) the applications are built on. Apple’s ARKit and Google’s ARCore SDKs determine the ceiling for today’s mobile AR experiences on iOS and Android devices, respectively.</p>
<p>Both companies appear to be committed to enhancing support for richer AR experiences, though.</p>
<p>Announced earlier this year, Apple’s ARKit 2 will allow for much better AR-based gameplay experiences.</p>
<p>For example, consider this Apple demo of an AR game built on ARKit 2 , in which multiple players are able to interact with the SAME virtual objects in a “shared experience.” This mechanic opens up a universe of possibilities when it comes to multiplayer AR games.</p>
<h3 id="heading-why-ar-will-gain-mainstream-adoption-faster-than-vr">Why AR will Gain Mainstream Adoption Faster than VR</h3>
<p>Most modern smartphones come standard with every hardware component you need to experience meaningful AR right now.</p>
<p>This low barrier to entry stands in stark contrast to virtual reality (VR).</p>
<p>For VR to work, users must own a virtual reality headset, which enables users to see the virtual world while blocking out all traces of the real world. VR headsets are typically purchased separately from the computers or phones that run the VR applications. While low end VR experiences can be had using a smartphone slapped into an inexpensive, VR headset (like the $15 Google Cardboard), the more immersive and believable VR experiences (on Oculus Rift and HTC Vive, for example) require modern gaming computers and headsets that can cost upwards of $1,500 in total.</p>
<p>The other edge AR has over VR is its versatility.</p>
<p>AR apps are designed for a wide variety of real world use cases. And, because you maintain visibility of your actual surroundings when using AR, safety is not much of an issue — at least no more than when you’re playing Candy Crush or catching up on your Instagram feed.</p>
<p>VR, on the other hand, is best enjoyed in a room without other people, tethered to devices like a desktop computer and motion sensors. This limits VR’s usefulness, relegating VR to use cases around gaming, entertainment, and complex commercial or governmental simulations (for aviation or military training, for example).</p>
<p>Here’s how Apple CEO Tim Cook explained his bullishness on AR relative to VR:</p>
<blockquote>
<p><em>“I’m incredibly excited by AR because I can see uses for it everywhere. I can see uses for it in education, in consumers, in entertainment, in sports. I can see it in every business that I know anything about. I also like the fact that [AR] doesn’t isolate. I don’t like our products being used a lot. I like our products amplifying us. And I think AR can help amplify the human connection. I’ve never been a fan of VR like that because I think it does the opposite. There are clearly some cool niche-y kind of things for VR. But it’s not profound in my view. AR is profound.”</em></p>
</blockquote>
<h3 id="heading-ars-accessibility-is-profound-too">AR’s Accessibility is Profound, Too</h3>
<p>As jaw-dropping and eye-popping as some AR experiences can be, AR experiences are actually not difficult to create or enjoy.</p>
<p>From the consumer perspective (demand side), anyone with a modern smartphone can download AR-enabled applications and begin to enjoy the benefits of augmented reality.</p>
<p>From the business side (supply side), creating an AR experience is as easy as partnering with a <a target="_blank" href="https://citrusbits.com/">reputable software company with AR/VR development capabilities</a>.</p>
<p>The hardest part, as it often is with emerging technologies, is taking the initial plunge.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How we brought our product mascot to life with AR.js ]]>
                </title>
                <description>
                    <![CDATA[ By Mateusz Tarnaski Short answer: using a browser-based Augmented Reality (AR) application. For the long answer, read below. The idea of playing with AR started as a random interesting experiment. In our company, we strive to stay at the edge of the ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-we-brought-our-product-mascot-to-life-87830db12ff4/</link>
                <guid isPermaLink="false">66c35670c7095d76345eaf7d</guid>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Virtual Reality ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 19 Jul 2018 14:36:04 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/0*OWm5DKa9eQRjwPEn.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Mateusz Tarnaski</p>
<p>Short answer: using a browser-based Augmented Reality (AR) application. For the long answer, read below.</p>
<p>The idea of playing with AR started as a random interesting experiment. In our company, we strive to stay at the edge of the curve. We share technical novelties and new technologies with each other on a semi-regular basis. Since we are mostly dealing with web technologies, the concept of AR in the browser really took off.</p>
<p>Since AR is mostly an entertainment technology, a practical application was not obvious to us from the start. Luckily, two unrelated things happened at the same time:</p>
<ul>
<li>we had just created a mascot for our <a target="_blank" href="https://voucherify.io">product</a> — <a target="_blank" href="https://uploads-ssl.webflow.com/58fe5d0657dd045f17ae2345/5ab8c85eff9c8b50cbce8b28_voucherify_index_v2_03%20(2).png">Hubert</a>,</li>
<li>we had to do a marketing booth at <a target="_blank" href="https://devoxx.pl/">devoxxPL 2018</a></li>
</ul>
<p>We decided to bring Hubert to life during the event, in the form of an AR app for people to play with. In our heads, users should be able to:</p>
<ul>
<li>render Hubert on a wall background in their phones</li>
<li>take a picture of the rendered model</li>
<li>tweet the photo (not the subject of this article)</li>
</ul>
<p>The end result is available on <a target="_blank" href="https://meet-hubert.glitch.me/">glitch.com</a>, scaled down and rotated to be suitable for a desktop experience (you can also take a quick look into the <a target="_blank" href="https://glitch.com/edit/#!/meet-hubert?path=contestant_app/index.html:1:0">source code</a>).</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/vvpzSs7qYIixdMDjC8TY4kto2aRREFWKHJ4H" alt="Image" width="800" height="533" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/lTqvZf927WIlmukzwzK7qt-fN1PWfDDSKPYn" alt="Image" width="403" height="638" loading="lazy"></p>
<h3 id="heading-rendering-hubert-in-real-time">Rendering Hubert in real time</h3>
<p>We used <a target="_blank" href="https://github.com/jeromeetienne/AR.js/">AR.js</a> (version from <a target="_blank" href="https://github.com/jeromeetienne/AR.js/commit/bfe82a70eae397e02e457801052ca54a3dbd09e2">this commit</a>) as the main building block of our AR app — it packages webRTC camera access, marker recognition, and 3D scene rendering. We liked it mostly because you can have a basic demo running in around 20 lines of code.</p>
<p>Under the hood, AR.js can use either three.js or A-frame implementations to render your 3D scenes.</p>
<ul>
<li>three.js offers fine-grained control of 3D rendering, and is JavaScript-based. You have probably heard about it in the context of rendering 2D and 3D scenes in the browser.</li>
<li>A-frame is a web framework designed specifically for building VR and AR experiences. It has an HTML-like markup that is more declarative than three.js, but sacrifices some of the control in favor of ease of use.</li>
</ul>
<p>We didn’t have a VR or 3D expert (except <a target="_blank" href="https://twitter.com/mr_oova">Mrówa</a>, who prepared the 3D model). As A-frame’s HTML-like declarative syntax looked more familiar to us, we opted for A-frame to do the rendering.</p>
<p>Here you can see the code for rendering Hubert, 30 lines on the dot. We omitted some options and A-frame tweaking for the sake of simplicity. You can refer to the repo to see it all.</p>
<p>This gives us Hubert nicely rendered <strong>in the web browser in real time.</strong></p>
<h3 id="heading-capturing-a-photo-to-tweet">Capturing a photo to tweet</h3>
<p>Unfortunately, we don’t have a single video feed rendering the whole scene. There is the video from your camera and a rendered 3D scene. We quickly figured out that we would have to capture a frame from both sources and put them together for a nice photo of Hubert.</p>
<p>Taking frames out of a webRTC video stream is pretty straightforward. The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Taking_still_photos">best material on the subject can be found here</a>. If your browser has the appropriate API, you need two elements:</p>
<ul>
<li>a reference to your source  tag</li>
<li>a destination  element in which to put your frame</li>
</ul>
<p>Then it’s just a simple matter of drawing a 2D image from video to canvas. In our case, both of these are a bit tricky.</p>
<p>The video take we are using is generated and embedded by AR.js. We had no idea how to get it gracefully, so we hacked our way around it with a loop and a DOM selector:</p>
<p>We also needed to hack some scaling. AR.js doesn’t present the raw video feed to the user, they scale it to fill the screen without losing aspect ratio. That means we need to apply the same scaling to our frame. If not, our screenshot will have “more” of the video feed than is shown on the screen. We don’t want to confuse the users here.</p>
<p>What the user sees:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/TqNXPoUowQqneSK0YcqTmW0Zs3IXHPXN8Ivv" alt="Image" width="640" height="327" loading="lazy"></p>
<p>If we take a frame <strong>without</strong> scaling and just try to copy from point (0,0) we lose margins imposed by AR.js. This is a totally different picture from what is presented to the user:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/G86uFDWwJ15KiGqWsBEJQdRy-hmnvD9qL8gM" alt="Image" width="640" height="329" loading="lazy"></p>
<p>Suffice it to say we just reverse-engineered the scaling and figured out the bounding box of what the user sees:</p>
<p>To achieve this final result (the same as what is presented live to the user, give or take some camera shake):</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/qanFbFOXGrc4HzplknO4E7PwqGzEw4ZVO1M5" alt="Image" width="640" height="329" loading="lazy"></p>
<p>Now we just need to get Hubert in the picture. Again, <a target="_blank" href="https://github.com/aframevr/aframe/blob/master/docs/components/screenshot.md">the API</a> for that is very straightforward. To capture a screenshot of a rendered A-frame scene, we need to get the scene’s canvas. The relevant part is copied to our destination canvas, on top of the previously taken video frame.</p>
<p>Getting the relevant part is the tricky bit in our case. Thanks to the AR.js scaling, we cannot simply get the “perspective” shot of the scene and use that. It will look too wide or too short, depending on orientation.</p>
<p>For landscape mode (width &gt; height), the scaling method we used for video works perfectly well.</p>
<p>For portrait mode, it works great on a PC… However, once you enter the realm of mobile devices, the scaling breaks and the screenshot doesn’t look nice. You get this skinny Hubert…</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/b6iPvi5VULuttWNr0fhEbL3Sb68rBHK9vXex" alt="Image" width="432" height="639" loading="lazy"></p>
<p>…instead of our lovely, bubbly mascot in all his glory:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/DpNxsKWRiI-WKImCfjd7PZCfg7HAFGk7dB95" alt="Image" width="411" height="640" loading="lazy"></p>
<p>We are still not sure why that is the case. We made the mistake of not testing it out thoroughly on actual mobile devices, thinking it would work the same as it does on the development machine. (Yes, we know how bad that sounds, but that’s the reality of it.) During the conference, we managed to figure out the formula for portrait scaling and introduced a fix:</p>
<p>It’s not pretty. It’s one of those “it’s late, it works, just leave it” fixes. The values presented above produced a satisfactory result and we left it at that.</p>
<p>With that, we have a picture of Hubert in the real world! It can be retrieved from the destination canvas element and displayed on the page or sent to the server to tweet out.</p>
<h3 id="heading-summary">Summary</h3>
<p>AR in the browser is possible. Even more, it is possible on mid-grade mobile hardware (as of June 2018). Getting it to work on every phone and browser is still a long shot, so don’t count on it for wide, diverse userbases.</p>
<p>However, if you have a somewhat controlled environment, augmented reality on a phone can be used to create unique experiences. These don’t require special hardware or workstations and that is a big, big plus. Just make sure to test it on actual devices ahead of time.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to get started with augmented reality in Swift, the easy way ]]>
                </title>
                <description>
                    <![CDATA[ By Ranadhir Dey If you look around, this is the golden era of technology. Every keynote adds something new to the existing stack of technologies. It’s exciting to see how these emerging technologies have enhanced the boundaries of our imagination. As... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-get-started-with-ar-in-swift-the-easy-way-7399fe1c82f5/</link>
                <guid isPermaLink="false">66c3523f39769b84d9fe971b</guid>
                
                    <category>
                        <![CDATA[ Augmented Reality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 16 Jul 2018 22:09:53 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*Gf3uExB7i8IDfN-s3_tcLw.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ranadhir Dey</p>
<p>If you look around, this is the golden era of technology. Every keynote adds something new to the existing stack of technologies. It’s exciting to see how these emerging technologies have enhanced the boundaries of our imagination. As a developer, we must be proud that we are the firsthand users of these technologies.</p>
<p>But every new technology comes with quite a steep learning curve. You just can’t watch a keynote or a video on Youtube and start developing an app. But the good news is that, with AR in Swift, it’s remarkably easy to work with basic AR apps. Apple has done most of the heavy lifting for you. Follow along and you’ll see how easy it can be.</p>
<h3 id="heading-lets-dig-in"><strong>Let’s dig in…</strong></h3>
<p>In this tutorial, we will learn the necessary tools and techniques of AR in Swift that will allow us to create an app that decorates your floor with some cool floor tiles and wooden textures. The finished app will look something like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/vO7XUgbwu9-jNCpzzBts8M-Q4ObnFsVmSCBB" alt="Image" width="600" height="1067" loading="lazy"></p>
<p>Let’s start by creating a <strong>single view</strong> application in Xcode and name it Home Decor.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/vcKpo7OKMJJrjoVC4NUEaj3CK0ZTDVn1B9kc" alt="Image" width="800" height="572" loading="lazy"></p>
<h3 id="heading-adding-camera-permissions"><strong>Adding camera permissions</strong></h3>
<p>Now the very first thing we will do is to navigate to the info.plist file and enable camera usage. Camera capability is the first thing you need for an AR app. Find the Camera Usage Description key, like the below image, and give it a suitable message. This message will show up in the very first launch of the app while asking for the camera permissions from the user.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/nXNhGVVjq4c-CAFVSXuDotT1p4OI44-GWugJ" alt="Image" width="800" height="465" loading="lazy"></p>
<h3 id="heading-adding-arkit-capabilities-to-the-app"><strong>Adding ARKit Capabilities to the app</strong></h3>
<p>Go to Main.storyboard. Drag and drop an ARKit SceneKit View on the ViewController and pin the ARSCNView to the edges of the ViewController.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/mw2nLyGFYWFvXMOtDFrZqCHentFfkfQu2LFu" alt="Image" width="800" height="969" loading="lazy"></p>
<p>Create a IBOutlet to the ViewController class, and name it sceneView. As soon as you do that, an error stating <strong>undeclared ARSCNView</strong><em>,</em> will popup, as our view controller doesn’t recognise anything of type ARSCNView. To resolve this, and to use other ARKit features, we need to import ARKit into the view controller.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/vqFrntUcNDJ0ySI-E9hIWjLttHQ3bv24PPRU" alt="Image" width="800" height="568" loading="lazy"></p>
<p>Now move from storyboard to the view controller.swift file. Declare a property of type ARWorldTrackingConfiguration before the viewDidLoad() method and name it config. And our view controller will look like this (I’ve removed the didReceiveMemoryWarning method):</p>
<pre><code><span class="hljs-keyword">import</span> UIKitimport ARKit
</code></pre><pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ViewController</span>: <span class="hljs-title">UIViewController</span> </span>{
</code></pre><pre><code>@IBOutlet weak <span class="hljs-keyword">var</span> sceneView: ARSCNView!<span class="hljs-keyword">let</span> config = ARWorldTrackingConfiguration()
</code></pre><pre><code>override func viewDidLoad() {<span class="hljs-built_in">super</span>.viewDidLoad()}
</code></pre><h3 id="heading-allow-debugging"><strong>Allow debugging</strong></h3>
<p>This config variable will determine the configurations of the scene session. We will see it’s usage later in the section. Now, in the viewDidLoad method after super.viewDidLoad(), add the following:</p>
<pre><code>sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin]
</code></pre><p>Here we are enabling debug options for our sceneView, which is nothing but the camera view with the capabilities of AR framework. ARSCNDebugOptions.showWorldOrigin will display world origin on the screen. This will help us find the reference point of all other positions. ARSCNDebugOptions.showFeaturePoints will display all the points on the screen which the AR camera has recognised in the surroundings.</p>
<p>Now to start the AR session, we need to run a session in our sceneView with the configurations mentioned in the config variable. Just below sceneView.debugOptions line, write:</p>
<pre><code>sceneView.session.run(config)
</code></pre><p>Now run the app on your device (not on a simulator, as it doesn’t have the camera). The alert asking for camera permissiosn with the message you wrote will show up, and you need allow it. Wait for a bit while it loads the world origin.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/nfQfMj9tFFxVpQ02jfMQpFttyDtiWLo-HAJV" alt="Image" width="800" height="1414" loading="lazy"></p>
<p>If you are here, you have already have an AR app running. Congratulations!</p>
<h3 id="heading-how-ar-axes-work"><strong>How AR Axes work</strong></h3>
<p>The red bar or X axis is used to position objects left or right of the world origin. The green bar or Y axis is used to position objects to the top or bottom of the world origin. And the blue bar or Z axis is used to determine how close or far an object will be placed from the world origin.</p>
<p>A positive value of X will position an object to the right of the world origin, and negative will place it on the left. Positive for Y will place it on top and negative will place it on the bottom of the world origin. Positive for Z will place it nearer, and negative will place it farther from the world origin.</p>
<h3 id="heading-adding-a-virtual-object"><strong>Adding a virtual object</strong></h3>
<p>Let’s add some virtual objects to the scene. 3D capsule would be a good choice. Declare a capsuleNode of type <a target="_blank" href="https://developer.apple.com/documentation/scenekit/scnnode?changes=_8">SCNNode</a> and give it a geometry of <a target="_blank" href="https://developer.apple.com/documentation/scenekit/scncapsule?changes=_5">capsule</a>. Give it a height of 0.1 meter, and radius of 0.03 meters.</p>
<pre><code><span class="hljs-keyword">let</span> capsuleNode = SCNNode(geometry: SCNCapsule(capRadius: <span class="hljs-number">0.03</span>, <span class="hljs-attr">height</span>: <span class="hljs-number">0.1</span>
</code></pre><p>Now position it 0.1 meter left of the world origin, 0.1 meter above the world origin, and 0.1 meter away from the world origin:</p>
<pre><code>capsuleNode.position = SCNVector3(<span class="hljs-number">0.1</span>, <span class="hljs-number">0.1</span>, <span class="hljs-number">-0.1</span>)
</code></pre><p>Now, add the node to scene:</p>
<pre><code>sceneView.scene.rootNode.addChildNode(capsuleNode)
</code></pre><p>The sceneView contains a scene which is responsible for holding all the 3D objects in SCNNode format that will form the 3D scene. We are adding the capsule to the root node of the scene. Root node’s position is exactly aligned to the position of the world origin. That means its position is (0,0,0).</p>
<p>Currently, our viewDidLoad method looks like this:</p>
<pre><code>override func viewDidLoad() {
</code></pre><pre><code><span class="hljs-built_in">super</span>.viewDidLoad()
</code></pre><pre><code>sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin]
</code></pre><pre><code>sceneView.session.run(config)
</code></pre><pre><code><span class="hljs-keyword">let</span> capsuleNode = SCNNode(geometry: SCNCapsule(capRadius: <span class="hljs-number">0.03</span>, <span class="hljs-attr">height</span>: <span class="hljs-number">0.1</span>))
</code></pre><pre><code>capsuleNode.position = SCNVector3(<span class="hljs-number">0.1</span>, <span class="hljs-number">0.1</span>, <span class="hljs-number">-0.1</span>)
</code></pre><pre><code>sceneView.scene.rootNode.addChildNode(capsuleNode)
</code></pre><pre><code>}
</code></pre><p>Now run the app.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/oWdSpOkroOQI7EuYJZ8-HAix6Xdg2tim75NN" alt="Image" width="750" height="1334" loading="lazy"></p>
<p>Cool! We have just positioned a virtual object in the real world. You can play with different positions and different <a target="_blank" href="https://developer.apple.com/documentation/scenekit/scngeometry">geometries</a> to explore more. Now let’s rotate the capsule 90 degree around the Z axis so that it lies flat on the X axis and changes its colour to blue.</p>
<h3 id="heading-euler-angles"><strong>Euler Angles</strong></h3>
<p>Euler Angles are responsible for a SCNNode’s display angle. We will see how to use it to rotate the capsule.</p>
<p>Every SCNGeometry can have materials added to it, which defines the appearance of the geometry. Materials have a diffuse property which, when set, spreads its content all over the geometry.</p>
<p>In viewDidLoad, add the below lines after you set the position of the capsule.</p>
<pre><code>capsuleNode.geometry?.firstMaterial?.diffuse.contents = UIColor.blue <span class="hljs-comment">//1capsuleNode.eulerAngles = SCNVector3(0,0,Double.pi/2)//2</span>
</code></pre><p>Here, in the first line, we are setting the blue colour to the very first material of the node which will spread across the capsule and will make it look blue. In line 2, we are setting the Z Euler angle to 90 degree radians. Finally, our view loads and looks like this:</p>
<pre><code>override func viewDidLoad() {
</code></pre><pre><code><span class="hljs-built_in">super</span>.viewDidLoad()
</code></pre><pre><code>sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin]
</code></pre><pre><code>sceneView.session.run(config)
</code></pre><pre><code><span class="hljs-keyword">let</span> capsuleNode = SCNNode(geometry: SCNCapsule(capRadius: <span class="hljs-number">0.03</span>, <span class="hljs-attr">height</span>: <span class="hljs-number">0.1</span>))
</code></pre><pre><code>capsuleNode.position = SCNVector3(<span class="hljs-number">0.1</span>, <span class="hljs-number">0.1</span>, <span class="hljs-number">-0.1</span>)
</code></pre><pre><code>capsuleNode.geometry?.firstMaterial?.diffuse.contents = UIColor.blue <span class="hljs-comment">//1</span>
</code></pre><pre><code>capsuleNode.eulerAngles = SCNVector3(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,Double.pi/<span class="hljs-number">2</span>)<span class="hljs-comment">//2</span>
</code></pre><pre><code>sceneView.scene.rootNode.addChildNode(capsuleNode)
</code></pre><pre><code>}
</code></pre><p>Now run the app.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/KRIWB1PKTsTUtgcALCZrbEIKFxyFAsOOJr3M" alt="Image" width="750" height="1334" loading="lazy"></p>
<p>Great! A blue coloured sleeping capsule on the wall! You can even add textures as diffuse contents to make an object look more realistic. We will use that in the next section when we place the tiles’ textures on the floor.</p>
<p>Now that we have successfully placed virtual objects on the real world, it’s time to decorate our real floor with virtual floor-tiles. To achieve the floor effect, we will use a <a target="_blank" href="https://developer.apple.com/documentation/scenekit/scnplane">SCNPlane</a> geometry. SCNPlane doesn’t have any depth like other 3D geometries, which makes it a perfect fit for our app.</p>
<h3 id="heading-arsceneview-delegates"><strong>ARSCENEView Delegates</strong></h3>
<p>Before starting the floor detection, we will explore some delegate methods of our sceneView to understand what capabilities we are equipped with to interact with an ongoing AR session.</p>
<pre><code>func renderer(SCNSceneRenderer, <span class="hljs-attr">didAdd</span>: SCNNode, <span class="hljs-attr">for</span>: ARAnchor)
</code></pre><p>Whenever we move or tilt our device with an AR session on in it, the ARKit tries to find different ARAnchors in the surroundings. An <a target="_blank" href="https://developer.apple.com/documentation/arkit/aranchor">ARAnchor</a> contains information about a real world position and orientation that can be used to place an object.</p>
<p>Once a different anchor is found, a new node gets added to the scene with the same information to accommodate this newly found anchor. This delegate method will inform us about that. We will be using it to find all the positions on the floor to place the tiles.</p>
<pre><code>func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, <span class="hljs-keyword">for</span> anchor: ARAnchor)
</code></pre><p>Most of the time, all the nodes that get added from the anchors belong to the same object. Let’s say you are moving around the floor and the device finds a number of anchors at different positions. It tries to add all the nodes for those anchors, as it thinks that all these anchors belong to different objects.</p>
<p>But ARKit eventually recognises that all of them belong to the same floor, so it updates the very first floor node by appending dimensions of other duplicate nodes. This delegate method will inform us about that.</p>
<pre><code>func renderer(SCNSceneRenderer, <span class="hljs-attr">didRemove</span>: SCNNode, <span class="hljs-attr">for</span>: ARAnchor)
</code></pre><p>After updating the first unique node with dimensions of all other duplicate nodes, ARKit removes all the duplicate nodes and the delegate method notifies us. We will be using all of the above delegate methods in our app (and their purpose will become clearer).</p>
<h3 id="heading-plane-detection"><strong>Plane detection</strong></h3>
<p>Presently, our scene is trying to gather all anchors that it comes across, as that is the default behaviour. But since a floor is a horizontal surface, we are only interested in anchors that are on horizontal planes. So, go back to our viewDidLoad method and write the below code <strong>before</strong> running the session (that is before sceneView.session.run(config)) line.</p>
<pre><code>config.planeDetection = .horizontal
</code></pre><p>In the viewDidLoad method, you can remove everything after sceneView.session.run(config) as that was for placing the capsule on screen and we don’t need that anymore. Since we will be using all the above mentioned delegate methods, we need to make our viewController a delegate of the sceneView. Before the closing brace of viewDidLoad() method, add the below line.</p>
<pre><code>sceneView.delegate = self
</code></pre><p>You should get an error now, as our view controller still is not conforming the sceneView delegate. To implement this, let’s create an extension of the view controller at the end of the ViewController.swift file.</p>
<pre><code>extension ViewController:ARSCNViewDelegate{}
</code></pre><p>The didAdd SCNNode delegate method will get fired every time a part of the floor is discovered and a new node gets added to the scene based on the anchor. Within this method, we will create a floor node and will add it as a child of the recently added node in the position of the anchor.</p>
<p><a target="_blank" href="https://developer.apple.com/documentation/arkit/aranchor">ARArchor</a> can be of four different types to solve four different purposes. Here we are only interested in ARPlaneAnchor which detects the horizontal or vertical planes.</p>
<h3 id="heading-creating-ar-floor-nodes"><strong>Creating AR floor nodes</strong></h3>
<p>Let’s create a function that would receive an ARPlaneAnchor as a parameter, create a floor node at the anchor’s position, and return it.</p>
<pre><code>func createFloorNode(anchor:ARPlaneAnchor) -&gt;SCNNode{
</code></pre><pre><code><span class="hljs-keyword">let</span> floorNode = SCNNode(geometry: SCNPlane(width: CGFloat(anchor.extent.x), <span class="hljs-attr">height</span>: CGFloat(anchor.extent.z))) <span class="hljs-comment">//1</span>
</code></pre><pre><code>floorNode.position=SCNVector3(anchor.center.x,<span class="hljs-number">0</span>,anchor.center.z)                                               <span class="hljs-comment">//2</span>
</code></pre><pre><code>floorNode.geometry?.firstMaterial?.diffuse.contents = UIColor.blue                                             <span class="hljs-comment">//3</span>
</code></pre><pre><code>floorNode.geometry?.firstMaterial?.isDoubleSided = <span class="hljs-literal">true</span>                                                        <span class="hljs-comment">//4</span>
</code></pre><pre><code>floorNode.eulerAngles = SCNVector3(Double.pi/<span class="hljs-number">2</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>)                                                    <span class="hljs-comment">//5</span>
</code></pre><pre><code><span class="hljs-keyword">return</span> floorNode                                                                                               <span class="hljs-comment">//6</span>
</code></pre><pre><code>}
</code></pre><p>Let’s go through the function line by line and discuss it in more detail. Please follow each line’s description, as it’s the trickiest part.</p>
<ol>
<li><p>We are creating a node with a geometry of SCNPlane which has the size of the anchor. ARPlaneAnchor’s extent holds the position information. The fact that the extent.z has been used as height and not extent.y, might be a little confusing. If you visualise that a 3D cube is placed on a floor and you want to make it flat along a 2D surface, you would change the y to zero and it would go flat. Now, to get the length of this 2D surface, you would consider the z, wouldn’t you? Our floor is flat, so we need a flat node not a cube.</p>
</li>
<li><p>We are setting the position of the node. As we don’t need any elevation, we make y zero.</p>
</li>
<li><p>Set the floor colour to blue.</p>
</li>
<li><p>The material colour will be displayed only on one side unless we specifically mention it is double-sided.</p>
</li>
<li><p>By default, the plane will be placed vertically. To make it horizontal, we need to rotate it by 90 degrees.</p>
</li>
</ol>
<h3 id="heading-implementing-the-delegate-methods"><strong>Implementing the delegate methods</strong></h3>
<p>Now, let’s implement the didAdd SCNNode delegate method.</p>
<pre><code>func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, <span class="hljs-keyword">for</span> anchor: ARAnchor) {
</code></pre><pre><code>guard <span class="hljs-keyword">let</span> planeAnchor = anchor <span class="hljs-keyword">as</span>? ARPlaneAnchor <span class="hljs-keyword">else</span> {<span class="hljs-keyword">return</span>} <span class="hljs-comment">//1</span>
</code></pre><pre><code><span class="hljs-keyword">let</span> planeNode = createFloorNode(anchor: planeAnchor) <span class="hljs-comment">//2</span>
</code></pre><pre><code>node.addChildNode(planeNode) <span class="hljs-comment">//3</span>
</code></pre><pre><code>}
</code></pre><p>In line 1, we are checking if the anchor is a ARPlaneAnchor, since we would only deal with this type of anchor.</p>
<p>In line 2, a new node is getting created based on the anchor. In line 3, it’s getting added to the node.</p>
<p>Now in the didUpdate SCNNode delegate, we will delete all our floor nodes. We’ll do this because the dimensions of the current node have been changed and the old floor nodes won’t match. Then we will again add a fresh floor node to this updated node.</p>
<pre><code>func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, <span class="hljs-keyword">for</span> anchor: ARAnchor) {
</code></pre><pre><code>guard <span class="hljs-keyword">let</span> planeAnchor = anchor <span class="hljs-keyword">as</span>? ARPlaneAnchor <span class="hljs-keyword">else</span> {<span class="hljs-keyword">return</span>}
</code></pre><pre><code>node.enumerateChildNodes { (node, _) <span class="hljs-keyword">in</span>
</code></pre><pre><code>node.removeFromParentNode()
</code></pre><pre><code>}
</code></pre><pre><code><span class="hljs-keyword">let</span> planeNode = createFloorNode(anchor: planeAnchor)
</code></pre><pre><code>node.addChildNode(planeNode)
</code></pre><pre><code>}
</code></pre><p>In didRemove SCNNode delegate method, we want to clean out all our junk nodes in a civilized manner.</p>
<pre><code>func renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, <span class="hljs-keyword">for</span> anchor: ARAnchor) {
</code></pre><pre><code>guard <span class="hljs-keyword">let</span> _ = anchor <span class="hljs-keyword">as</span>? ARPlaneAnchor <span class="hljs-keyword">else</span> {<span class="hljs-keyword">return</span>}
</code></pre><pre><code>node.enumerateChildNodes { (node, _) <span class="hljs-keyword">in</span>
</code></pre><pre><code>node.removeFromParentNode()
</code></pre><pre><code>}
</code></pre><pre><code>}
</code></pre><p>Phew! Thats it! Run the app.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/3wVNiLmgzrS3Hjqr7lyE4wQJIssiklvQKZOk" alt="Image" width="750" height="1334" loading="lazy"></p>
<h3 id="heading-adding-the-tile-effect"><strong>Adding the tile effect</strong></h3>
<p>Wait, what? A blue floor? No, we are not completely done yet. Just a small change and we will have a stunning floor!</p>
<p>To change the blue floor to tiles, we need a texture. Let’s google for a floor tile texture. I searched for “wooden floor texture” and found some beautiful texture images. Save any of them on your Mac and drag it to the Assets.xcassets.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/k9pct70eqbORC5u5WnCgSPOb5cYSmN9hoKmC" alt="Image" width="800" height="219" loading="lazy"></p>
<p>I named it WoodenFloorTile. You can name it whatever you want. Back to the ViewController.swift file again. In the createFloorNode function, instead of setting UIColor.blue as diffuse content, make it an UIImage with the name you have given to the image in the asset folder.</p>
<pre><code>floorNode.geometry?.firstMaterial?.diffuse.contents = UIImage(named: <span class="hljs-string">"WoodenFloorTile"</span>)
</code></pre><p>Now run the app, and wait until the world origin loads. Once the floor is detected, move around to update the node information.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/aO7-9zVFW65MANwJfIgAmwT0OaX6xXIIYEEx" alt="Image" width="750" height="1334" loading="lazy"></p>
<p>Wow, You really have a gorgeous floor! You can download multiple textures and place them in a listView. This allows you to change the floor based on selected texture, as it was shown in the first part.</p>
<p><a target="_blank" href="https://github.com/ranadhirdey/Home-Decor">Download the complete project from GitHub here.</a></p>
<p>Now that you have a nice floor, you must be missing some nice furnitures to give your room a great look! We will work on that later on.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
