︎︎︎ Shilo Homes



Tags :
︎ AEC, AR Mobile App, ML App, Azure Playfab

Status :
Publishing

Role :
Developer



︎ Shilo inc.
︎ 2020 08  


︎ Project Breakdown


. shilo is a start up that creates energy-efficient and personalized accessory-dwelling-unity, commonly knew as ADU. 

. shilo required a mobile application for showcasing their products and provide to clients a wide range of customization in their hands. 

shilo apps includes

. high quality render geometries 
. rich layering of architectural information
. login/authentication
. amodern and readable UI
. AR mode switch
. 360 visualization  
. boards for saving favorites - analytics 

. Magic Leap demo for internal showcase. 
︎︎︎ Image courtesy of Shilo 

︎ Phase 01


. the very first prototype was more of an investigation about the scale of representation for the ADUs showcased in the app


.  it included a simple menu where you could click on the ADU and entering it in two different ways : using a gyroscope 360 view or using an AR mode where you could freely scale the building according a min and max value

. the max value is the real scale of the building
︎ Phase 01 - magic leap





︎ Phase 02 - auth and new navigation


. the homes are visualized from an external point of view 

. the pinch to zoom camera allows close up and a switch between an axonometric view and top view, where the user can get into a more controlled first person view of the main environment in the house 



︎ Mobile App Experience 



. the development was also for shilo a way to further analyze the structure of the ADU and come up with a layer management strategy for the next units that will be fabricated


︎ Moving Imported Geometry

. a common problem faced in game engines when imported not native geometry is the discrepancy in the imported object world axis and the game engine world axis reference

. the cubes represents temporarily the registered initial position of the objects

. in order to achieve the “explode” effect in AR , the position of the parts is relative to a center transform 

︎ Shared Code Sample :
Get the world position of the vertex

. LocalToWorldMatrix transforms a point from local space into world space as TransformPoint, but with matrix

. in this case we get the reference for the vertices[0] of every part as new transform 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    public Vector3 GetVertexWorldPosition(Vector3 vertex, Transform owner)
    {
        return owner.localToWorldMatrix.MultiplyPoint3x4(vertex);
    }
    IEnumerator WaitAndAdd()
    {
        explodingParts = GameObject.FindGameObjectsWithTag("Wall");
        //
        explodingPartsInitialPos = new Vector3[explodingParts.Length];
        //
        for (int i = 0; i < explodingParts.Length; i++)
        {
            Mesh mesh = explodingParts[i].GetComponent<MeshFilter>().mesh;
            Vector3[] vertices = mesh.vertices;
            Vector3 positionVertex = explodingParts[i].transform.TransformPoint(vertices[0]);
            //
            GameObject pivot = new GameObject("pivot");
            pivot.tag = "parent";
            pivot.transform.position = positionVertex;
            explodingParts[i].transform.SetParent(pivot.transform);
            explodingPartsInitialPos[i] = pivot.transform.position;
        }
    }
︎ App Demo [Final]

between the features 

. login
. add and remove favorites
. visualize the homes in isometric view 
. visualize the homes in FPS view
. ar mode
. ar drag and drop 
. lighting modification 
. ar plane detection toggle 
. explode slider 
. reset ar plan 
. lock ar model position 
. toggle interior and garden 
 




︎ Shared Code Sample :
AR drag and drop paint

. in the app the color of certain walls can be changed dragging a color palette from the UI to the 3D object in the scene

. this feature might going further

 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 void Update()
    {
        for (int i = 0; i < rawImage.Length; i++)
        {
            if (colorOn)
            {
                RaycastHit hit;
                //
                Ray ray = camera.ScreenPointToRay(rawImage[i].position);
                //
                if ((Physics.Raycast(ray, out hit)) && hit.transform.gameObject.layer == 10)
                {
                    Transform objectHit = hit.transform;
                    //
                    var cubeRenderer = objectHit.GetComponent<Renderer>();
                    //
                    cubeRenderer.material.SetColor("_Color", rawImage[i].gameObject.GetComponent<RawImage>().color);
                    //
                    rawImage[i].transform.position = rawImageInitialPos[i];

                }
            }
        }
    }