Exemple #1
0
        void SetupBackgroundTexture()
        {
            int textureId = SDPlugin.SixDegreesSDK_GetBackgroundTexture();

            if (textureId > 0)
            {
                int width  = 1920;
                int height = 1080;
                unsafe
                {
                    int *widthPtr = &width, heightPtr = &height;
                    SDPlugin.SixDegreesSDK_GetBackgroundTextureSize(widthPtr, heightPtr);
                }

                Debug.Log("Create External Texture:" + textureId + "(" + width + "x" + height + ")");
                mBackgroundTexture = Texture2D.CreateExternalTexture(
                    width,
                    height,
                    TextureFormat.RGBA32,
                    false,
                    false,
                    new System.IntPtr(textureId));
                mBackgroundTexture.filterMode = FilterMode.Point;
                mBackgroundTexture.name       = "camera_texture";
                background.color   = Color.black;
                background.texture = mBackgroundTexture;
                background.material.SetTexture("_MainTex", mBackgroundTexture);
            }
        }
Exemple #2
0
        void Update()
        {
            if (!SDPlugin.IsSDKReady)
            {
                return; // will try later
            }

            int blockBufferSize  = 0;
            int vertexBufferSize = 0;
            int faceBufferSize   = 0;
            int newVersion       = -1;

            unsafe
            {
                newVersion = SDPlugin.SixDegreesSDK_GetMeshBlockInfo(&blockBufferSize, &vertexBufferSize, &faceBufferSize);
            }

            if (newVersion > meshVersion && blockBufferSize > 0 && vertexBufferSize > 0 && faceBufferSize > 0)
            {
                if (meshVersion < 0)
                {
                    blockSize      = SDPlugin.SixDegreesSDK_GetMeshBlockSize();
                    blocksPerChunk = Mathf.Max(1, Mathf.FloorToInt(chunkSize / blockSize));
                    chunkSize      = blocksPerChunk * blockSize;
                }
                UpdateMesh(newVersion, blockBufferSize, vertexBufferSize, faceBufferSize);
            }
            else if (newVersion == 0 && meshVersion > 0 && blockBufferSize == 0)
            {
                // Mesh was reset after loading a new map
                ClearMesh();
            }
        }
        void FixedUpdate()
        {
            if (!SDPlugin.IsSDKReady)
            {
                return; // will try later
            }

            int blockBufferSize  = 0;
            int vertexBufferSize = 0;
            int faceBufferSize   = 0;
            int newVersion       = -1;

            unsafe
            {
                newVersion = SDPlugin.SixDegreesSDK_GetBlockMeshInfo(&blockBufferSize, &vertexBufferSize, &faceBufferSize);
            }
            if (newVersion > meshVersion && blockBufferSize > 0 && vertexBufferSize > 0 && faceBufferSize > 0)
            {
                if (meshVersion < 0)
                {
                    blockSize = SDPlugin.SixDegreesSDK_GetMeshBlockSize();
                }
                UpdateMesh(newVersion, blockBufferSize, vertexBufferSize, faceBufferSize);
            }
            else if (newVersion == 0 && meshVersion > 0 && blockBufferSize == 0)
            {
                // Mesh was reset after loading a new map
                ClearMesh();
            }
        }
        void UpdateCamera()
        {
            // enable the camera, update its rect and replace its default projection matrix
            int width  = 1920;
            int height = 1080;

            unsafe
            {
                int *widthPtr = &width, heightPtr = &height;
                SDPlugin.SixDegreesSDK_GetBackgroundTextureSize(widthPtr, heightPtr);
            }

            mCamera.rect             = SDCameraUtils.GetCameraRect(width, height);
            mCamera.projectionMatrix = SDCameraUtils.GetProjectionMatrix();
            mScreenOrientation       = Screen.orientation;
        }
Exemple #5
0
        public void SetupBackgroundTexture()
        {
            background.gameObject.SetActive(true);
            IntPtr texturePtr = IntPtr.Zero;

#if UNITY_IOS && !UNITY_EDITOR
            if (SystemInfo.graphicsDeviceType == UnityEngine.Rendering.GraphicsDeviceType.OpenGLES3)
            {
                int textureId = SDPlugin.SixDegreesSDK_GetEAGLBackgroundTexture();
                texturePtr = new IntPtr(textureId);
            }
            else
#endif
            {
                texturePtr = SDPlugin.SixDegreesSDK_GetBackgroundTexture();
            }

            if (texturePtr != IntPtr.Zero)
            {
                int width  = 1920;
                int height = 1080;
                unsafe
                {
                    int *widthPtr = &width, heightPtr = &height;
                    SDPlugin.SixDegreesSDK_GetBackgroundTextureSize(widthPtr, heightPtr);
                }

                Debug.Log("Create External Texture:" + texturePtr + "(" + width + "x" + height + ")");
                mBackgroundTexture = Texture2D.CreateExternalTexture(
                    width,
                    height,
                    TextureFormat.RGBA32,
                    false,
                    false,
                    texturePtr);
                mBackgroundTexture.filterMode = FilterMode.Point;
                mBackgroundTexture.name       = "camera_texture";
                background.color   = Color.black;
                background.texture = mBackgroundTexture;
                background.material.SetTexture("_MainTex", mBackgroundTexture);
            }
        }
Exemple #6
0
        unsafe void UpdatePose()
        {
            fixed(float *ptr = &mPoseBuffer[0])
            {
                // R T
                // 0 1
                int bufferSize = 16;

                mTrackingState = SDPlugin.SixDegreesSDK_GetPose(ptr, bufferSize);
            }

            switch (mTrackingState)
            {
            case (int)SDPlugin.SDTrackingQuality.Good:
            case (int)SDPlugin.SDTrackingQuality.Limited:
            {
                Matrix4x4 mat = new Matrix4x4();
                for (int col = 0; col < 4; col++)
                {
                    for (int row = 0; row < 4; row++)
                    {
                        // Column major order
                        mat[row, col] = mPoseBuffer[col * 4 + row];
                    }
                }

                Vector3 position = mat.GetColumn(3);

                Vector3 forward;
                Vector3 upwards;

                switch (Screen.orientation)
                {
                case ScreenOrientation.LandscapeRight:
                    forward = mat.GetColumn(2);
                    upwards = -mat.GetColumn(1);
                    break;

                case ScreenOrientation.Portrait:
                    forward = mat.GetColumn(2);
                    upwards = -mat.GetColumn(0);
                    break;

                case ScreenOrientation.PortraitUpsideDown:
                    forward = mat.GetColumn(2);
                    upwards = mat.GetColumn(0);
                    break;

                default:
                case ScreenOrientation.LandscapeLeft:
                    forward = mat.GetColumn(2);
                    upwards = mat.GetColumn(1);
                    break;
                }
                Quaternion rotation = Quaternion.LookRotation(forward, upwards);
                transform.SetPositionAndRotation(position, rotation);

                break;
            }

            case (int)SDPlugin.SDTrackingQuality.None:
            default:
            {
                break;
            }
            }
        }
Exemple #7
0
 void Start()
 {
     // disable if the device doesn't build meshes on the fly
     enabled = SDPlugin.SixDegreesSDK_HasRealTimeMesh();
 }
Exemple #8
0
        void UpdateMesh(int newVersion, int blockBufferSize, int vertexBufferSize, int faceBufferSize)
        {
            meshVersion = newVersion;

            int[]   blockArray  = new int[blockBufferSize];
            float[] vertexArray = new float[vertexBufferSize];
            int[]   faceArray   = new int[faceBufferSize];

            unsafe
            {
                fixed(int *blockBufferPtr = &blockArray[0], faceBufferPtr = &faceArray[0])
                {
                    fixed(float *vertexBufferPtr = &vertexArray[0])
                    {
                        fullBlocks = SDPlugin.SixDegreesSDK_GetMeshBlocks(blockBufferPtr, vertexBufferPtr, faceBufferPtr,
                                                                          blockBufferSize, vertexBufferSize, faceBufferSize);
                    }
                }
            }
            bool gotAllBlocks = (fullBlocks == blockBufferSize / 6);

            if (fullBlocks < 0)
            {
                Debug.Log("Error calling SixDegreesSDK_GetMeshBlocks(), will not update the mesh.");
                return;
            }
            else if (fullBlocks == 0)
            {
                Debug.Log("SixDegreesSDK_GetMeshBlocks() gave us an empty mesh, will not update.");
                return;
            }
            else if (!gotAllBlocks)
            {
                Debug.Log("SixDegreesSDK_GetMeshBlocks() returned " + fullBlocks + " full blocks, expected " + (blockBufferSize / 5));
            }

            int firstVertex   = 0;
            int firstTriangle = 0;
            HashSet <Vector3Int> chunksToUpdate = new HashSet <Vector3Int>();
            HashSet <Vector3Int> meshBlocks     = new HashSet <Vector3Int>();

            // Update all the full blocks returned by the API
            int fullBlockSize = fullBlocks * 6;

            for (int b = 0; b + 5 < fullBlockSize; b += 6)
            {
                Vector3Int blockCoords   = new Vector3Int(blockArray[b], blockArray[b + 1], blockArray[b + 2]);
                Vector3Int chunkCoords   = GetChunkCoords(blockCoords);
                int        vertexCount   = blockArray[b + 3];
                int        triangleCount = blockArray[b + 4];
                int        blockVersion  = blockArray[b + 5];
                meshBlocks.Add(blockCoords);

                if (!IsChunkTooFar(chunkCoords))
                {
                    SDMeshChunk chunk = GetOrCreateChunk(chunkCoords);
                    SDMeshBlock block = GetOrCreateBlock(chunk, blockCoords);

                    // Update block if it is outdated
                    if (block.version < blockVersion)
                    {
                        chunksToUpdate.Add(chunkCoords);

                        block.version     = blockVersion;
                        block.meshVersion = meshVersion;
                        block.vertices.Clear();
                        block.normals.Clear();
                        block.triangles.Clear();

                        // copy vertices
                        int fullVertices    = 0;
                        int lastBlockVertex = Mathf.Min(vertexBufferSize, (firstVertex + vertexCount) * 6);
                        for (int va = firstVertex * 6; va + 5 < lastBlockVertex; va += 6)
                        {
                            block.vertices.Add(new Vector3(vertexArray[va], vertexArray[va + 1], vertexArray[va + 2]));
                            block.normals.Add(new Vector3(vertexArray[va + 3], vertexArray[va + 4], vertexArray[va + 5]));
                            fullVertices++;
                        }

                        if (fullVertices != vertexCount)
                        {
                            Debug.Log("Got only " + fullVertices + " vertices out of " + vertexCount);
                        }

                        // copy faces
                        int fullTriangles     = 0;
                        int lastBlockTriangle = Mathf.Min(faceBufferSize, (firstTriangle + triangleCount) * 3);
                        for (int fa = firstTriangle * 3; fa + 2 < lastBlockTriangle; fa += 3)
                        {
                            block.triangles.Add(new Vector3Int(faceArray[fa] - firstVertex, faceArray[fa + 1] - firstVertex, faceArray[fa + 2] - firstVertex));
                            fullTriangles++;
                        }

                        if (fullTriangles != triangleCount)
                        {
                            Debug.Log("Got only " + fullTriangles + " triangles out of " + triangleCount);
                        }
                    }
                }

                firstVertex   += vertexCount;
                firstTriangle += triangleCount;
            }

            // Clean up missing blocks only if we received all the expected full blocks
            if (gotAllBlocks)
            {
                foreach (SDMeshChunk chunk in chunks.Values)
                {
                    HashSet <Vector3Int> blocksToRemove = new HashSet <Vector3Int>(chunk.blocks.Keys);
                    blocksToRemove.ExceptWith(meshBlocks);
                    foreach (Vector3Int block in blocksToRemove)
                    {
                        chunk.blocks.Remove(block);
                    }
                    if (blocksToRemove.Count > 0)
                    {
                        chunksToUpdate.Add(chunk.coordinates);
                    }
                }
            }

            // Update chunks with updated blocks
            UpdateChunks(chunksToUpdate);

            // Clean up far chunks
            if (destroyFarChunks)
            {
                List <Vector3Int> allChunks      = new List <Vector3Int>(chunks.Keys);
                List <Vector3Int> chunksToDelete = allChunks.FindAll((Vector3Int chunkCoords) => IsChunkTooFar(chunkCoords));
                DeleteChunks(chunksToDelete);
            }
        }
        public static Matrix4x4 GetProjectionMatrix()
        {
            const int bufferSize = 16;

            float[] projectionBuffer = new float[bufferSize];

            unsafe
            {
                fixed(float *ptr = &projectionBuffer[0])
                {
                    SDPlugin.SixDegreesSDK_GetProjection(ptr, bufferSize);
                }
            }

            Matrix4x4 projectionMatrix = new Matrix4x4();

            for (int row = 0; row < 4; row++)
            {
                for (int col = 0; col < 4; col++)
                {
                    projectionMatrix[row, col] = projectionBuffer[row + col * 4];
                }
            }

            bool portrait = Screen.orientation == ScreenOrientation.Portrait ||
                            Screen.orientation == ScreenOrientation.PortraitUpsideDown;

            if (Mode == CameraMode.Fill)
            {
                // fix the projection when filling the screen
                int width  = 1920;
                int height = 1080;
                unsafe
                {
                    int *widthPtr = &width, heightPtr = &height;
                    SDPlugin.SixDegreesSDK_GetBackgroundTextureSize(widthPtr, heightPtr);
                }
                float texAspect    = (float)width / height;
                float windowAspect = portrait ? (float)Screen.height / Screen.width
                                              : (float)Screen.width / Screen.height;

                if (texAspect > windowAspect)
                {
                    float scaleFactor = texAspect / windowAspect;
                    projectionMatrix[0, 0] *= scaleFactor;
                    projectionMatrix[0, 2] *= scaleFactor;
                }
                if (windowAspect > texAspect)
                {
                    float scaleFactor = windowAspect / texAspect;
                    projectionMatrix[1, 1] *= scaleFactor;
                    projectionMatrix[1, 2] *= scaleFactor;
                }
            }

            if (portrait)
            {
                // fix the projection in portrait
                float p00 = projectionMatrix[0, 0];
                projectionMatrix[0, 0] = projectionMatrix[1, 1];
                projectionMatrix[1, 1] = p00;
                float p02 = projectionMatrix[0, 2];
                projectionMatrix[0, 2] = projectionMatrix[1, 2];
                projectionMatrix[1, 2] = p02;
            }

            return(projectionMatrix);
        }
        void UpdateMesh(int newVersion, int blockBufferSize, int vertexBufferSize, int faceBufferSize)
        {
            meshVersion = newVersion;

            int[]   blockArray  = new int[blockBufferSize];
            float[] vertexArray = new float[vertexBufferSize];
            int[]   faceArray   = new int[faceBufferSize];

            int fullBlocks = 0;

            unsafe
            {
                fixed(int *blockBufferPtr = &blockArray[0], faceBufferPtr = &faceArray[0])
                {
                    fixed(float *vertexBufferPtr = &vertexArray[0])
                    {
                        fullBlocks = SDPlugin.SixDegreesSDK_GetBlockMesh(blockBufferPtr, vertexBufferPtr, faceBufferPtr,
                                                                         blockBufferSize, vertexBufferSize, faceBufferSize);
                    }
                }
            }
            bool gotAllBlocks = (fullBlocks == blockBufferSize / 6);

            if (fullBlocks < 0)
            {
                Debug.Log("Error calling SixDegreesSDK_GetMeshBlocks(), will not update the mesh.");
                return;
            }
            else if (fullBlocks == 0)
            {
                Debug.Log("SixDegreesSDK_GetMeshBlocks() gave us an empty mesh, will not update.");
                return;
            }
            else if (!gotAllBlocks)
            {
                Debug.Log("SixDegreesSDK_GetMeshBlocks() returned " + fullBlocks + " full blocks, expected " + (blockBufferSize / 6));
                return;
            }

            int firstVertex   = 0;
            int firstTriangle = 0;
            int normalsOffset = vertexBufferSize / 2;

            // Update all the full blocks returned by the API
            for (int b = 0; b < blockBufferSize; b += 6)
            {
                // Transform block coordinates from 6D right-handed coordinates to Unity left-handed coordinates
                // By flipping the sign of Z
                Vector3Int blockCoords   = new Vector3Int(blockArray[b], blockArray[b + 1], -blockArray[b + 2]);
                int        vertexCount   = blockArray[b + 3];
                int        triangleCount = blockArray[b + 4];
                int        blockVersion  = blockArray[b + 5];

                SDMeshBlock currentBlock;

                if (!blocks.TryGetValue(blockCoords, out currentBlock))
                {
                    currentBlock        = new SDMeshBlock();
                    blocks[blockCoords] = currentBlock;
                }

                currentBlock.meshVersion = meshVersion;

                // Update block if it is outdated
                if (currentBlock.version < blockVersion)
                {
                    currentBlock.version = blockVersion;

                    List <Vector3> vertices  = new List <Vector3>();
                    List <Vector3> normals   = new List <Vector3>();
                    List <int>     triangles = new List <int>();
                    // copy vertices
                    for (int va = firstVertex; va < firstVertex + vertexCount; va++)
                    {
                        // Transform vertices from 6D right-handed coordinates to Unity left-handed coordinates
                        // By flipping the sign of Z
                        int pos = va * 3;
                        vertices.Add(new Vector3(vertexArray[pos], vertexArray[pos + 1], -vertexArray[pos + 2]));
                        int norm = normalsOffset + pos;
                        normals.Add(new Vector3(vertexArray[norm], vertexArray[norm + 1], -vertexArray[norm + 2]));
                    }

                    // copy faces
                    for (int fa = firstTriangle; fa < firstTriangle + triangleCount; fa++)
                    {
                        //block.triangles.Add(new Vector3Int(faceArray[fa] - firstVertex, faceArray[fa + 2] - firstVertex, faceArray[fa + 1] - firstVertex));
                        int f = fa * 3;
                        triangles.Add(faceArray[f] - firstVertex);
                        triangles.Add(faceArray[f + 2] - firstVertex);
                        triangles.Add(faceArray[f + 1] - firstVertex);
                    }

                    if (currentBlock.gameObject == null)
                    {
                        currentBlock.gameObject = Instantiate(meshPrefab);
                        currentBlock.gameObject.transform.parent = gameObject.transform;

                        if (!meshVisible && depthMaskMaterial != null)
                        {
                            MeshRenderer meshRenderer = currentBlock.gameObject.GetComponent <MeshRenderer>();
                            if (meshRenderer != null)
                            {
                                meshRenderer.material = depthMaskMaterial;
                            }
                        }
                    }

                    Mesh workMesh = currentBlock.gameObject.GetComponent <MeshFilter>().mesh;
                    workMesh.Clear();
                    workMesh.vertices  = vertices.ToArray();
                    workMesh.normals   = normals.ToArray();
                    workMesh.triangles = triangles.ToArray();
                    MeshCollider meshCollider = currentBlock.gameObject.GetComponent <MeshCollider>();
                    // update the collider less often for optimal performance
                    if (meshCollider && (currentBlock.colliderVersion < 0 || (currentBlock.colliderVersion + 10 < currentBlock.version)))
                    {
                        meshCollider.sharedMesh      = workMesh;
                        currentBlock.colliderVersion = currentBlock.version;
                    }
                }
                firstVertex   += vertexCount;
                firstTriangle += triangleCount;
            }
            List <Vector3Int> keys = new List <Vector3Int>(blocks.Keys);

            // Clean up obsolete blocks
            foreach (Vector3Int blockCoords in keys)
            {
                if (blocks[blockCoords].meshVersion != meshVersion)
                {
                    Destroy(blocks[blockCoords].gameObject.GetComponent <MeshFilter>().mesh);
                    Destroy(blocks[blockCoords].gameObject);
                    blocks.Remove(blockCoords);
                }
            }
        }