Exemplo n.º 1
0
                Buffer(uint blockMetadataSize, uint maxBlockSize, long streamLocation, long opNumber, Guid StreamId)
                {
                    this._AllocationReportedToGC = maxBlockSize + (uint)KLogicalLogInformation.FixedMetadataSize;
                    AddGCMemoryPressure(this._AllocationReportedToGC);

                    this._MetadataSize = blockMetadataSize;
                    NativeLog.CreateSimpleKIoBuffer((uint)KLogicalLogInformation.FixedMetadataSize, out this._MetadataKIoBuffer);

                    //
                    // Allocate the write KIoBuffer to be the full block size requested by the caller despite the fact that some
                    // data will live in the metadata portion. Consider the fact that when the block is completely full, there will be some
                    // amount of data in the metadata and then the data portion will be full as well except for a gap at the end of the block
                    // which is the size of the data in the metadata portion. When rounding up we will need this last block despite it not being
                    // completely full.
                    //
                    NativeLog.CreateSimpleKIoBuffer((uint)(maxBlockSize), out this._PageAlignedKIoBuffer);

                    NativeLog.CreateEmptyKIoBuffer(out this._CombinedKIoBuffer);
                    this._CombinedKIoBuffer.AddIoBufferReference(this._MetadataKIoBuffer, 0, (uint)KLogicalLogInformation.FixedMetadataSize);
                    this._CombinedKIoBuffer.AddIoBufferReference(
                        this._PageAlignedKIoBuffer,
                        0,
                        (uint)(maxBlockSize - KLogicalLogInformation.FixedMetadataSize));

                    this._CombinedBufferStream = new KIoBufferStream(this._CombinedKIoBuffer, (uint)blockMetadataSize);

                    NativeLog.CreateEmptyKIoBuffer(out this._PageAlignedKIoBufferView);

                    unsafe
                    {
                        KLogicalLogInformation.MetadataBlockHeader *mdHdr = null;

                        mdHdr = (KLogicalLogInformation.MetadataBlockHeader *) this._CombinedBufferStream.GetBufferPointer();
                        this._MetadataBlockHeader = mdHdr;
                        ReleaseAssert.AssertIfNot(
                            this._CombinedBufferStream.Skip((uint)sizeof(KLogicalLogInformation.MetadataBlockHeader)),
                            "Unexpected Skip failure");

                        this._StreamBlockHeader     = (KLogicalLogInformation.StreamBlockHeader *) this._CombinedBufferStream.GetBufferPointer();
                        mdHdr->OffsetToStreamHeader = this._CombinedBufferStream.GetPosition();

                        // Position the stream at 1st byte of user record
                        ReleaseAssert.AssertIfNot(
                            this._CombinedBufferStream.Skip((uint)sizeof(KLogicalLogInformation.StreamBlockHeader)),
                            "Unexpected Skip failure");


                        this._StreamBlockHeader->Signature           = KLogicalLogInformation.StreamBlockHeader.Sig;
                        this._StreamBlockHeader->StreamOffsetPlusOne = streamLocation + 1;
                        this._StreamBlockHeader->HighestOperationId  = opNumber;
                        this._StreamBlockHeader->StreamId            = StreamId;

                        this._StreamBlockHeader->HeaderCRC64 = 0;
                        this._StreamBlockHeader->DataCRC64   = 0;
                        this._StreamBlockHeader->DataSize    = 0;
                        this._StreamBlockHeader->Reserved    = 0;

                        this._OffsetToData = mdHdr->OffsetToStreamHeader + (uint)sizeof(KLogicalLogInformation.StreamBlockHeader);
                    }
                }
Exemplo n.º 2
0
        void ExportTarget()
        {
            if (_isExporting)
            {
                return;
            }

            _isExporting = true;

            NativeLog.InstallDebugLogCallback(); // why do we need to do this every time?
            float starttick = Time.realtimeSinceStartup;

            string exportname        = string.IsNullOrEmpty(_exportFileName) ? "export" : Path.GetFileNameWithoutExtension(_exportFileName);
            string finalSaveFileName = Path.Combine(_exportDirectory, exportname) + (_binaryExport ? ".vsgb"
                                                                                     : ".vsga");

            if (_exportTarget != null)
            {
                GraphBuilder.Export(new GameObject[] { _exportTarget }, finalSaveFileName, _settings);
            }
            else
            {
                Scene scene = SceneManager.GetActiveScene();
                GraphBuilder.Export(scene.GetRootGameObjects(), finalSaveFileName, _settings);
            }

            _feedbackText = "Exported in " + (Time.realtimeSinceStartup - starttick) + " seconds";
            EditorUtility.SetDirty(this);

            if (_showPreview)
            {
                GraphBuilder.LaunchViewer(finalSaveFileName, _matchSceneCamera, _previewCameras[_cameraSelectionIndex]);               // this currently blocks
            }
            _isExporting = false;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Create an array of new image data representing the passed texture array
        /// </summary>
        /// <param name="texture"></param>
        /// <returns>ImageData array representing the texture array</returns>

        public static ImageData[] CreateImageDatas(Texture2DArray texture, bool addToCache = true)
        {
            List <ImageData> texdatas = new List <ImageData>();

            TextureSupportIssues issues = GetSupportIssuesForTexture(texture);

            if (issues != TextureSupportIssues.None)
            {
                texdatas.Add(CreateImageData(Texture2D.whiteTexture));
                NativeLog.WriteLine(GetTextureSupportReport(issues, texture));
                return(texdatas.ToArray());
            }

            for (int i = 0; i < texture.depth; i++)
            {
                ImageData texdata = new ImageData();
                PopulateImageData(texture, i, ref texdata);
                texdata.id = texture.GetInstanceID() * (i + 1); // hack some kind of id for the texture
                texdatas.Add(texdata);

                // add to the cache (double check it doesn't exist already)
                if (!_imageDataCache.ContainsKey(texdata.id) && addToCache)
                {
                    _imageDataCache[texdata.id] = texdata;
                }
            }

            return(texdatas.ToArray());
        }
Exemplo n.º 4
0
        /// <summary>
        /// Create a new image data representing the passed texture
        /// </summary>
        /// <param name="texture"></param>
        /// <returns>ImageData representing the texture</returns>

        public static ImageData CreateImageData(Texture texture, bool addToCache = true)
        {
            ImageData texdata = new ImageData();

            TextureSupportIssues issues = GetSupportIssuesForTexture(texture);

            if ((issues & TextureSupportIssues.Format) == TextureSupportIssues.Format && texture.dimension == TextureDimension.Tex2D)
            {
                Texture2D     source = texture as Texture2D;
                RenderTexture rt     = RenderTexture.GetTemporary(source.width, source.height, 0, RenderTextureFormat.ARGB32);
                Graphics.Blit(source, rt);
                Texture2D converted = new Texture2D(rt.width, rt.height, TextureFormat.RGBA32, false);
                Graphics.SetRenderTarget(rt);
                converted.ReadPixels(new Rect(0.0f, 0.0f, rt.width, rt.height), 0, 0, false);
                converted.Apply(false, false);
                RenderTexture.ReleaseTemporary(rt);
                _convertedTextures.Add(converted);

                texdata = TextureConverter.CreateImageData(converted, false);
                TextureConverter.AddImageDataToCache(texdata, source.GetInstanceID());

                return(texdata);
            }
            else if (issues != TextureSupportIssues.None)
            {
                texdata = CreateImageData(Texture2D.whiteTexture);
                NativeLog.WriteLine(GetTextureSupportReport(issues, texture));
                return(texdata);
            }

            switch (texture.dimension)
            {
            case TextureDimension.Tex2D: PopulateImageData(texture as Texture2D, ref texdata); break;

            case TextureDimension.Tex3D: PopulateImageData(texture as Texture3D, ref texdata); break;

            default: break;
            }

            // add to the cache (double check it doesn't exist already)
            if (!_imageDataCache.ContainsKey(texdata.id) && addToCache)
            {
                _imageDataCache[texdata.id] = texdata;
            }

            return(texdata);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WindowsPointerHandler"/> class.
        /// </summary>
        /// <param name="addPointer">A function called when a new pointer is detected.</param>
        /// <param name="updatePointer">A function called when a pointer is moved or its parameter is updated.</param>
        /// <param name="pressPointer">A function called when a pointer touches the surface.</param>
        /// <param name="releasePointer">A function called when a pointer is lifted off.</param>
        /// <param name="removePointer">A function called when a pointer is removed.</param>
        /// <param name="cancelPointer">A function called when a pointer is cancelled.</param>
        public WindowsPointerHandler(PointerDelegate addPointer, PointerDelegate updatePointer, PointerDelegate pressPointer, PointerDelegate releasePointer, PointerDelegate removePointer, PointerDelegate cancelPointer)
        {
            this.addPointer     = addPointer;
            this.updatePointer  = updatePointer;
            this.pressPointer   = pressPointer;
            this.releasePointer = releasePointer;
            this.removePointer  = removePointer;
            this.cancelPointer  = cancelPointer;

            nativeLogDelegate     = nativeLog;
            nativePointerDelegate = nativePointer;

            touchPool = new ObjectPool <TouchPointer>(10, () => new TouchPointer(this), null, resetPointer);

            hMainWindow = WindowsUtils.GetActiveWindow();
            disablePressAndHold();
            setScaling();
        }
Exemplo n.º 6
0
                Buffer(
                    uint blockMetadataSize,
                    long startingStreamPosition,
                    NativeLog.IKIoBuffer metadataBuffer,
                    NativeLog.IKIoBuffer pageAlignedKIoBuffer,
                    string traceType)
                {
                    this._MetadataSize         = blockMetadataSize;
                    this._MetadataKIoBuffer    = metadataBuffer;
                    this._PageAlignedKIoBuffer = pageAlignedKIoBuffer;
                    unsafe
                    {
                        this._StreamBlockHeader = null;
                    }
                    this._PageAlignedKIoBufferView = null;
                    this._OffsetToData             = uint.MaxValue;

                    NativeLog.CreateEmptyKIoBuffer(out this._CombinedKIoBuffer);
                    this.OpenForRead(startingStreamPosition, traceType);
                }
Exemplo n.º 7
0
        CreatePhysicalLogStreamBeginWrapper(
            Guid PhysicalLogStreamId,
            Guid PhysicalLogStreamTypeId,
            string OptionalLogStreamAlias,
            string OptionalPath,
            FileSecurity OptionalSecurityInfo,
            Int64 MaximumSize,
            UInt32 MaximumBlockSize,
            LogManager.LogCreationFlags CreationFlags,
            NativeCommon.IFabricAsyncOperationCallback Callback)
        {
            NativeLog.IKBuffer secInfo = null;

            if (OptionalSecurityInfo != null)
            {
                var secDesc = OptionalSecurityInfo.GetSecurityDescriptorBinaryForm();
                NativeLog.CreateKBuffer((UInt32)secDesc.GetLength(0), out secInfo);
            }

            NativeCommon.IFabricAsyncOperationContext context;

            using (var pin = new PinCollection())
            {
                this._NativeContainer.BeginCreateLogStream(
                    PhysicalLogStreamId,
                    PhysicalLogStreamTypeId,
                    pin.AddBlittable(OptionalLogStreamAlias),
                    // CONSIDER: what about NULL Alias ?
                    pin.AddBlittable(OptionalPath),
                    secInfo,
                    // CONSIDER: does native code need to AddRef() ?
                    MaximumSize,
                    MaximumBlockSize,
                    CreationFlags,
                    Callback,
                    out context);
            }

            return(context);
        }
Exemplo n.º 8
0
        Memcopy(byte *Src, byte *Dest, UInt32 Length)
        {
            // The best observed throughput has been about 2GB/sec or 500ps/byte without calling CopyMemory. Further we
            // see a native call/return overhead of about 70nsecs/call. This is assuming a memory bandwidth of about 27GB/sec
            // our a mem-to-mem copy rate of about 13.5GB/sec. This means that it takes about 140 byte transfer to break even
            // above that and we should call CopyMemory.
            if (Length > 140)
            {
                // At least break even overhead
                NativeLog.CopyMemory(Src, Dest, Length);
                return;
            }

            // BUG: richhas, xxxxxx, it would be great to have access to a memcpy intrinsic - this
            //                       code could just as much damage.

            // The best observed throughput has been about 2GB/sec or 500ps/byte. This means that it takes about
            // 140 byte transfer to break even
            while (Length >= sizeof(UInt64))
            {
                *((UInt64 *)Dest) = *((UInt64 *)Src);
                Src  += sizeof(UInt64);
                Dest += sizeof(UInt64);
                if ((Length -= sizeof(UInt64)) == 0)
                {
                    return;
                }
            }

            while (Length > 0)
            {
                *Dest = *Src;
                Src  += 1;
                Dest += 1;
                Length--;
            }
        }
Exemplo n.º 9
0
        PhysicalLogManager(LogManager.LoggerType LoggerType)
        {
            switch (LoggerType)
            {
            case LogManager.LoggerType.Inproc:
            {
                NativeLog.CreateLogManagerInproc(out this._NativeManager);
                _LoggerType = LogManager.LoggerType.Inproc;
                break;
            }

            case LogManager.LoggerType.Driver:
            {
                NativeLog.CreateLogManager(out this._NativeManager);
                _LoggerType = LogManager.LoggerType.Driver;
                break;
            }

            default:
            {
                throw new InvalidOperationException("Invalid LogManager.LoggerType");
            }
            }
        }
Exemplo n.º 10
0
 private static extern void Init(TOUCH_API api, NativeLog log, NativePointerDelegate pointerDelegate);
Exemplo n.º 11
0
                OpenForRead(long streamPosition, string traceType)
                {
                    // Combine the metadata and page-align IoBuffers
                    uint mdBufferSize;
                    uint paBufferSize;

                    this._MetadataKIoBuffer.QuerySize(out mdBufferSize);
                    this._PageAlignedKIoBuffer.QuerySize(out paBufferSize);

                    this._AllocationReportedToGC = mdBufferSize + paBufferSize;
                    AddGCMemoryPressure(this._AllocationReportedToGC);

                    this._CombinedKIoBuffer.Clear();
                    this._CombinedKIoBuffer.AddIoBufferReference(this._MetadataKIoBuffer, 0, mdBufferSize);
                    this._CombinedKIoBuffer.AddIoBufferReference(this._PageAlignedKIoBuffer, 0, paBufferSize);

                    this._CombinedBufferStream.Reuse(this._CombinedKIoBuffer, this._MetadataSize);

                    // Parse the log stream physical record
                    unsafe
                    {
                        KLogicalLogInformation.MetadataBlockHeader *mdHdr = null;

                        mdHdr = (KLogicalLogInformation.MetadataBlockHeader *) this._CombinedBufferStream.GetBufferPointer();

                        ReleaseAssert.AssertIfNot(
                            this._CombinedBufferStream.PositionTo(mdHdr->OffsetToStreamHeader),
                            "Unexpected PositionTo failure");

                        this._StreamBlockHeader = (KLogicalLogInformation.StreamBlockHeader *) this._CombinedBufferStream.GetBufferPointer();

                        // Position the stream at 1st byte of user record
                        ReleaseAssert.AssertIfNot(
                            this._CombinedBufferStream.Skip((uint)sizeof(KLogicalLogInformation.StreamBlockHeader)),
                            "Unexpected Skip failure");

                        this._OffsetToData = mdHdr->OffsetToStreamHeader + (uint)sizeof(KLogicalLogInformation.StreamBlockHeader);

#if false
                        // TODO: Start: DebugOnly
                        UInt64 savedCrc = _StreamBlockHeader->HeaderCRC64;
                        _StreamBlockHeader->HeaderCRC64 = 0;
                        if (NativeLog.KCrc64(_StreamBlockHeader, (uint)sizeof(KLogicalLogInformation.StreamBlockHeader), 0) != savedCrc)
                        {
                            throw new InvalidDataException();
                        }

                        _StreamBlockHeader->HeaderCRC64 = 0;    // NOTE: Leave HeaderCRC64 0 - this is the unsealed condition

                        if ((_OffsetToData + _StreamBlockHeader->DataSize) > mdBufferSize)
                        {
                            savedCrc = 0;
                            KIoBufferStream.InterationCallback LocalHashFunc = ((
                                                                                    byte *ioBufferFragment,
                                                                                    ref UInt32 fragmentSize) =>
                            {
                                savedCrc = NativeLog.KCrc64(ioBufferFragment, fragmentSize, savedCrc);
                                return(0);
                            });

                            ReleaseAssert.AssertIfNot(
                                _CombinedBufferStream.Iterate(LocalHashFunc, _StreamBlockHeader->DataSize) == 0,
                                "Unexpected Iterate failure");

                            if (_StreamBlockHeader->DataCRC64 != savedCrc)
                            {
                                throw new InvalidDataException();
                            }
                        }
                        // TODO: END: DebugOnly
#endif

                        // Compute position and limits of the KIoBufferStream
                        System.Diagnostics.Debug.Assert(this._StreamBlockHeader->StreamOffsetPlusOne > 0);
                        var recordOffsetToDesiredPosition = streamPosition - (this._StreamBlockHeader->StreamOffsetPlusOne - 1);

                        if ((recordOffsetToDesiredPosition < 0) || (recordOffsetToDesiredPosition >= this._StreamBlockHeader->DataSize))
                        {
                            var s =
                                string.Format(
                                    CultureInfo.InvariantCulture,
                                    "OpenForRead: streamPosition {0}, StreamOffsetPlusOne {1}, DataSize {2}, recordOffsetToDesiredPosition {3}, HeadTruncationPoint {4}, HighestOperationId {5} ",
                                    streamPosition,
                                    this._StreamBlockHeader->StreamOffsetPlusOne,
                                    this._StreamBlockHeader->DataSize,
                                    recordOffsetToDesiredPosition,
                                    this._StreamBlockHeader->HeadTruncationPoint,
                                    this._StreamBlockHeader->HighestOperationId);

                            AppTrace.TraceSource.WriteInfo(
                                traceType,
                                s
                                );
                        }

                        System.Diagnostics.Debug.Assert(recordOffsetToDesiredPosition <= uint.MaxValue);
                        this._CombinedBufferStream.Reuse(
                            this._CombinedKIoBuffer,
                            (uint)recordOffsetToDesiredPosition + this._OffsetToData,
                            this._OffsetToData + this._StreamBlockHeader->DataSize);
                    }
                }
Exemplo n.º 12
0
                SealForWrite(
                    long currentHeadTruncationPoint,
                    bool IsBarrier,
                    out NativeLog.IKIoBuffer metadataBuffer,
                    out uint metadataSize,
                    out NativeLog.IKIoBuffer pageAlignedBuffer,
                    out long userSizeOfStreamData,
                    out long AsnOfRecord,
                    out long OpOfRecord)
                {
                    unsafe
                    {
                        uint   trimSize = 0;
                        uint   dataResidingOutsideMetadata = 0;
                        UInt64 dataCrc = 0;

                        this._MetadataBlockHeader->Flags = IsBarrier ? (uint)KLogicalLogInformation.MetadatBlockHeaderFlags.IsEndOfLogicalRecord : 0;

                        this._StreamBlockHeader->DataSize            = this._CombinedBufferStream.GetPosition() - this._OffsetToData;
                        this._StreamBlockHeader->HeadTruncationPoint = currentHeadTruncationPoint;
                        this._PageAlignedKIoBufferView.Clear();

                        // Compute CRC64 for record data
                        if ((this._OffsetToData < KLogicalLogInformation.FixedMetadataSize) &&
                            ((this._OffsetToData + this._StreamBlockHeader->DataSize) <= KLogicalLogInformation.FixedMetadataSize))
                        {
                            // no data outside the metadata buffer
                            metadataSize = this._OffsetToData + this._StreamBlockHeader->DataSize;
                        }
                        else
                        {
                            //
                            // Compute how much of the metadata is being used. It should be the entire 4K block minus the
                            // space reserved by the physical logger
                            //
                            metadataSize = (uint)KLogicalLogInformation.FixedMetadataSize - this._MetadataSize;
                            ReleaseAssert.AssertIfNot(this._CombinedBufferStream.PositionTo(this._OffsetToData), "Unexpected PositionTo failure");

                            KIoBufferStream.InterationCallback LocalHashFunc = ((
                                                                                    byte *ioBufferFragment,
                                                                                    ref UInt32 fragmentSize) =>
                            {
                                dataCrc = NativeLog.KCrc64(ioBufferFragment, fragmentSize, dataCrc);
                                return(0);
                            });

                            ReleaseAssert.AssertIfNot(
                                this._CombinedBufferStream.Iterate(LocalHashFunc, this._StreamBlockHeader->DataSize) == 0,
                                "Unexpected Iterate failure");

                            //
                            // Compute the number of data blocks that are needed to hold the data that is within the payload
                            // data buffer. This excludes the payload data in the metadata portion
                            //
                            ReleaseAssert.AssertIf(this._OffsetToData > MetadataBlockSize, "Unexpected size for _OffsetToData");
                            dataResidingOutsideMetadata = this._StreamBlockHeader->DataSize - (MetadataBlockSize - this._OffsetToData);
                            trimSize = ((((dataResidingOutsideMetadata) + (MetadataBlockSize - 1)) / MetadataBlockSize) * MetadataBlockSize);
                            this._PageAlignedKIoBufferView.AddIoBufferReference(
                                this._PageAlignedKIoBuffer,
                                0,
                                (uint)trimSize);
                        }
                        this._StreamBlockHeader->DataCRC64 = dataCrc;

                        // Now compute block header CRC
                        this._StreamBlockHeader->HeaderCRC64 = NativeLog.KCrc64(
                            this._StreamBlockHeader,
                            (uint)sizeof(KLogicalLogInformation.StreamBlockHeader),
                            0);

                        // Build results
                        metadataBuffer       = this._MetadataKIoBuffer;
                        pageAlignedBuffer    = this._PageAlignedKIoBufferView;
                        userSizeOfStreamData = this._StreamBlockHeader->DataSize;
                        AsnOfRecord          = this._StreamBlockHeader->StreamOffsetPlusOne;
                        OpOfRecord           = this._StreamBlockHeader->HighestOperationId;
                    }
                }
Exemplo n.º 13
0
        public static void Export(GameObject[] gameObjects, string saveFileName, ExportSettings settings)
        {
            MeshConverter.ClearCaches();
            TextureConverter.ClearCaches();
            MaterialConverter.ClearCaches();
            ShaderMappingIO.ClearCaches();

            GraphBuilderInterface.unity2vsg_BeginExport();

            List <PipelineData> storePipelines = new List <PipelineData>();

            bool insideLODGroup = false;
            bool firstNodeAdded = false;

            System.Action <GameObject> processGameObject = null;
            processGameObject = (GameObject go) =>
            {
                // determine the gameObject type
                Transform gotrans = go.transform;

                bool nodeAdded = false;

                // does it have a none identiy local matrix
                if (gotrans.localPosition != Vector3.zero || gotrans.localRotation != Quaternion.identity || gotrans.localScale != Vector3.one)
                {
                    if (firstNodeAdded || !settings.zeroRootTransform)
                    {
                        // add as a transform
                        TransformData transformdata = TransformConverter.CreateTransformData(gotrans);
                        GraphBuilderInterface.unity2vsg_AddTransformNode(transformdata);
                        nodeAdded = true;
                    }
                }

                // do we need to insert a group
                if (!nodeAdded)// && gotrans.childCount > 0)
                {
                    //add as a group
                    GraphBuilderInterface.unity2vsg_AddGroupNode();
                    nodeAdded = true;
                }

                firstNodeAdded = true;
                bool meshexported = false;

                // get the meshrender here so we can check if the LOD exports the the mesh
                MeshFilter   meshFilter   = go.GetComponent <MeshFilter>();
                MeshRenderer meshRenderer = go.GetComponent <MeshRenderer>();

                // does this node have an LOD group
                LODGroup lodgroup = go.GetComponent <LODGroup>();
                if (lodgroup != null && !insideLODGroup)
                {
                    // rather than process the children we figure out which renderers are in which children and add them as LOD children
                    LOD[] lods = lodgroup.GetLODs();
                    if (lods.Length > 0)
                    {
                        // get bounds from first renderer
                        if (lods[0].renderers.Length > 0)
                        {
                            CullData lodCullData = new CullData();
                            Bounds   bounds      = new Bounds(lods[0].renderers[0].bounds.center, lods[0].renderers[0].bounds.size);
                            foreach (Renderer boundsrenderer in lods[0].renderers)
                            {
                                if (boundsrenderer != null)
                                {
                                    bounds.Encapsulate(boundsrenderer.bounds);
                                }
                            }
                            Vector3 center = bounds.center - gotrans.position;
                            CoordSytemConverter.Convert(ref center);
                            lodCullData.center = NativeUtils.ToNative(center);
                            lodCullData.radius = bounds.size.magnitude * 0.5f;
                            GraphBuilderInterface.unity2vsg_AddLODNode(lodCullData);

                            insideLODGroup = true;

                            for (int i = 0; i < lods.Length; i++)
                            {
                                // for now just support one renderer and assume it's under a seperate child gameObject
                                if (lods[i].renderers.Length == 0)
                                {
                                    continue;
                                }

                                LODChildData lodChild = new LODChildData();
                                lodChild.minimumScreenHeightRatio = lods[i].screenRelativeTransitionHeight;
                                GraphBuilderInterface.unity2vsg_AddLODChild(lodChild);

                                foreach (Renderer lodrenderer in lods[i].renderers)
                                {
                                    if (lodrenderer == meshRenderer)
                                    {
                                        meshexported = true;
                                        ExportMesh(meshFilter.sharedMesh, meshRenderer, gotrans, settings, storePipelines);
                                    }
                                    else if (lodrenderer != null)
                                    {
                                        // now process the renderers gameobject, it'll be added to the group we just created by adding an LOD child
                                        processGameObject(lodrenderer.gameObject);
                                    }
                                }

                                GraphBuilderInterface.unity2vsg_EndNode();
                            }

                            insideLODGroup = false;

                            GraphBuilderInterface.unity2vsg_EndNode(); // end the lod node
                        }
                    }
                }
                else
                {
                    // transverse any children
                    for (int i = 0; i < gotrans.childCount; i++)
                    {
                        processGameObject(gotrans.GetChild(i).gameObject);
                    }
                }

                // does it have a mesh
                if (!meshexported && meshFilter && meshFilter.sharedMesh && meshRenderer)
                {
                    Mesh mesh = meshFilter.sharedMesh;
                    ExportMesh(mesh, meshRenderer, gotrans, settings, storePipelines);
                }

                // does this node have a terrain
                Terrain terrain = go.GetComponent <Terrain>();
                if (terrain != null)
                {
                    ExportTerrainMesh(terrain, settings, storePipelines);
                }

                // if we added a group or transform step out
                if (nodeAdded)
                {
                    GraphBuilderInterface.unity2vsg_EndNode();
                }
            };

            foreach (GameObject go in gameObjects)
            {
                processGameObject(go);
            }

            //GraphBuilderInterface.unity2vsg_EndNode(); // step out of convert coord system node

            GraphBuilderInterface.unity2vsg_EndExport(saveFileName);
            NativeLog.PrintReport();
        }
Exemplo n.º 14
0
        private static void ExportMesh(Mesh mesh, MeshRenderer meshRenderer, Transform gotrans, ExportSettings settings, List <PipelineData> storePipelines = null)
        {
            bool addedCullGroup = false;

            if (settings.autoAddCullNodes)
            {
                CullData culldata = new CullData();
                Vector3  center   = meshRenderer.bounds.center - gotrans.position;
                CoordSytemConverter.Convert(ref center);
                culldata.center = NativeUtils.ToNative(center);
                culldata.radius = meshRenderer.bounds.size.magnitude * 0.5f;
                GraphBuilderInterface.unity2vsg_AddCullGroupNode(culldata);
                addedCullGroup = true;
            }

            //
            Material[] materials = meshRenderer.sharedMaterials;

            if (mesh != null && mesh.isReadable && mesh.vertexCount > 0 && mesh.GetIndexCount(0) > 0)
            {
                int meshid = mesh.GetInstanceID();

                MeshInfo meshInfo = MeshConverter.GetOrCreateMeshInfo(mesh);

                int subMeshCount = mesh.subMeshCount;

                // shader instance id, Material Data, sub mesh indicies
                Dictionary <int, Dictionary <MaterialInfo, List <int> > > meshMaterials = new Dictionary <int, Dictionary <MaterialInfo, List <int> > >();
                for (int matindex = 0; matindex < materials.Length && matindex < subMeshCount; matindex++)
                {
                    Material mat = materials[matindex];
                    if (mat == null)
                    {
                        continue;
                    }

                    MaterialInfo matdata     = MaterialConverter.GetOrCreateMaterialData(mat);
                    int          matshaderid = matdata.shaderStages.id;

                    if (!meshMaterials.ContainsKey(matshaderid))
                    {
                        meshMaterials.Add(matshaderid, new Dictionary <MaterialInfo, List <int> >());
                    }
                    if (!meshMaterials[matshaderid].ContainsKey(matdata))
                    {
                        meshMaterials[matshaderid].Add(matdata, new List <int>());
                    }

                    meshMaterials[matshaderid][matdata].Add(matindex);
                }

                if (subMeshCount > 1)
                {
                    // create mesh data, if the mesh has already been created we only need to pass the ID to the addGeometry function
                    foreach (int shaderkey in meshMaterials.Keys)
                    {
                        List <MaterialInfo> mds = new List <MaterialInfo>(meshMaterials[shaderkey].Keys);

                        if (mds.Count == 0)
                        {
                            continue;
                        }

                        // add stategroup and pipeline for shader
                        GraphBuilderInterface.unity2vsg_AddStateGroupNode();

                        PipelineData pipelineData = NativeUtils.CreatePipelineData(meshInfo); //WE NEED INFO ABOUT THE SHADER SO WE CAN BUILD A PIPLE LINE
                        pipelineData.descriptorBindings = NativeUtils.WrapArray(mds[0].descriptorBindings.ToArray());
                        pipelineData.shaderStages       = mds[0].shaderStages.ToNative();
                        pipelineData.useAlpha           = mds[0].useAlpha;
                        pipelineData.id = NativeUtils.ToNative(NativeUtils.GetIDForPipeline(pipelineData));
                        storePipelines.Add(pipelineData);

                        if (GraphBuilderInterface.unity2vsg_AddBindGraphicsPipelineCommand(pipelineData, 1) == 1)
                        {
                            GraphBuilderInterface.unity2vsg_AddCommandsNode();

                            VertexBuffersData vertexBuffersData = MeshConverter.GetOrCreateVertexBuffersData(meshInfo);
                            GraphBuilderInterface.unity2vsg_AddBindVertexBuffersCommand(vertexBuffersData);

                            IndexBufferData indexBufferData = MeshConverter.GetOrCreateIndexBufferData(meshInfo);
                            GraphBuilderInterface.unity2vsg_AddBindIndexBufferCommand(indexBufferData);


                            foreach (MaterialInfo md in mds)
                            {
                                BindDescriptors(md, false);

                                foreach (int submeshIndex in meshMaterials[shaderkey][md])
                                {
                                    DrawIndexedData drawIndexedData = MeshConverter.GetOrCreateDrawIndexedData(meshInfo, submeshIndex);
                                    GraphBuilderInterface.unity2vsg_AddDrawIndexedCommand(drawIndexedData);
                                }
                            }

                            GraphBuilderInterface.unity2vsg_EndNode(); // step out of commands node for descriptors and draw indexed commands
                        }
                        GraphBuilderInterface.unity2vsg_EndNode();     // step out of stategroup node for shader
                    }
                }
                else
                {
                    List <int> sids = new List <int>(meshMaterials.Keys);
                    if (sids.Count > 0)
                    {
                        List <MaterialInfo> mds = new List <MaterialInfo>(meshMaterials[sids[0]].Keys);

                        if (mds.Count > 0)
                        {
                            // add stategroup and pipeline for shader
                            GraphBuilderInterface.unity2vsg_AddStateGroupNode();

                            PipelineData pipelineData = NativeUtils.CreatePipelineData(meshInfo); //WE NEED INFO ABOUT THE SHADER SO WE CAN BUILD A PIPLE LINE
                            pipelineData.descriptorBindings = NativeUtils.WrapArray(mds[0].descriptorBindings.ToArray());
                            pipelineData.shaderStages       = mds[0].shaderStages.ToNative();
                            pipelineData.useAlpha           = mds[0].useAlpha;
                            pipelineData.id = NativeUtils.ToNative(NativeUtils.GetIDForPipeline(pipelineData));
                            storePipelines.Add(pipelineData);

                            if (GraphBuilderInterface.unity2vsg_AddBindGraphicsPipelineCommand(pipelineData, 1) == 1)
                            {
                                BindDescriptors(mds[0], true);

                                VertexIndexDrawData vertexIndexDrawData = MeshConverter.GetOrCreateVertexIndexDrawData(meshInfo);
                                GraphBuilderInterface.unity2vsg_AddVertexIndexDrawNode(vertexIndexDrawData);

                                GraphBuilderInterface.unity2vsg_EndNode(); // step out of vertex index draw node
                            }
                            GraphBuilderInterface.unity2vsg_EndNode();     // step out of stategroup node
                        }
                    }
                }
            }
            else
            {
                string reason = mesh == null ? "mesh is null." : (!mesh.isReadable ? "mesh '" + mesh.name + "' is not readable. Please enabled read/write in the models import settings." : "mesh '" + mesh.name + "' has an unknown error.");
                NativeLog.WriteLine("ExportMesh: Unable to export mesh for gameobject " + gotrans.gameObject.name + ", " + reason);
            }

            if (addedCullGroup)
            {
                GraphBuilderInterface.unity2vsg_EndNode();
            }
        }
Exemplo n.º 15
0
        public static TerrainInfo CreateTerrainInfo(Terrain terrain, GraphBuilder.ExportSettings settings)
        {
            TerrainInfo terrainInfo         = new TerrainInfo();
            bool        usingCustomMaterial = false;

            if (terrain.materialType == Terrain.MaterialType.Custom)
            {
                // try and load a shader mapping file to match the custom terrain material
                terrainInfo.shaderMapping = ShaderMappingIO.ReadFromJsonFile(terrain.materialTemplate.shader);
                if (terrainInfo.shaderMapping != null)
                {
                    usingCustomMaterial = true;
                }
            }
            else
            {
                // load the default terrain shader mapping file
                terrainInfo.shaderMapping = ShaderMappingIO.ReadFromJsonFile(ShaderMappingIO.GetPathForShaderMappingFile("DefaultTerrain"));
            }

            if (terrainInfo.shaderMapping == null)
            {
                // no mapping loaded, use a default shader so we can at least export and render the terrain mesh
                NativeLog.WriteLine("GraphBuilder: Failed to load Terrain Shader Mapping file for terrain '" + terrain.name + "'.");
                terrainInfo.shaderMapping = ShaderMappingIO.ReadFromJsonFile(ShaderMappingIO.GetPathForShaderMappingFile("Default"));
                usingCustomMaterial       = true;
                return(null);
            }

            terrainInfo.shaderDefines.Add("VSG_LIGHTING");

            // build mesh
            int samplew = terrain.terrainData.heightmapWidth;
            int sampleh = terrain.terrainData.heightmapHeight;

            int cellw = terrain.terrainData.heightmapWidth - 1;
            int cellh = terrain.terrainData.heightmapHeight - 1;

            Vector3 size = terrain.terrainData.size;

            Vector2 cellsize   = new Vector3(size.x / cellw, size.z / cellh);
            Vector2 uvcellsize = new Vector2(1.0f / cellw, 1.0f / cellh);

            float[,] terrainHeights = terrain.terrainData.GetHeights(0, 0, samplew, sampleh);

            int vertcount = samplew * sampleh;

            Vector3[] verts   = new Vector3[vertcount];
            Vector3[] normals = new Vector3[vertcount];
            Vector2[] uvs     = new Vector2[vertcount];

            int[] indicies = new int[(cellw * cellh) * 6];

            // vertices and UVs
            for (int y = 0; y < samplew; y++)
            {
                for (int x = 0; x < sampleh; x++)
                {
                    verts[y * samplew + x].Set(x * cellsize.x, terrainHeights[y, x] * size.y, y * cellsize.y);
                    normals[y * samplew + x] = terrain.terrainData.GetInterpolatedNormal((float)x / (float)samplew, (float)y / (float)sampleh);
                    uvs[y * samplew + x].Set(x * uvcellsize.x, y * uvcellsize.y);
                }
            }

            CoordSytemConverter.Convert(verts);
            CoordSytemConverter.Convert(normals);

            // triangles
            int index = 0;

            for (int y = 0; y < cellw; y++)
            {
                for (int x = 0; x < cellh; x++)
                {
                    indicies[index++] = (y * samplew) + x;
                    indicies[index++] = ((y + 1) * samplew) + x;
                    indicies[index++] = (y * samplew) + x + 1;

                    indicies[index++] = ((y + 1) * samplew) + x;
                    indicies[index++] = ((y + 1) * samplew) + x + 1;
                    indicies[index++] = (y * samplew) + x + 1;
                }
            }

            CoordSytemConverter.FlipTriangleFaces(indicies);

            // convert to meshinfo
            MeshInfo mesh = null;

            if (!MeshConverter.GetMeshInfoFromCache(terrain.GetInstanceID(), out mesh))
            {
                mesh = new MeshInfo
                {
                    id               = terrain.GetInstanceID(),
                    verticies        = NativeUtils.WrapArray(verts),
                    normals          = NativeUtils.WrapArray(normals),
                    uv0              = NativeUtils.WrapArray(uvs),
                    triangles        = NativeUtils.WrapArray(indicies),
                    use32BitIndicies = 1
                };

                MeshConverter.AddMeshInfoToCache(mesh, terrain.GetInstanceID());
            }
            terrainInfo.terrainMesh = mesh;
            terrainInfo.terrainSize = size;

            // gather material info

            if (!usingCustomMaterial)
            {
                // use standard terrain layers
                TerrainLayer[] layers = terrain.terrainData.terrainLayers;
                for (int i = 0; i < layers.Length; i++)
                {
                    ImageData layerData = TextureConverter.GetOrCreateImageData(layers[i].diffuseTexture);
                    terrainInfo.diffuseTextureDatas.Add(layerData);

                    terrainInfo.diffuseScales.Add(new Vector4(1.0f / layers[i].tileSize.x, 1.0f / layers[i].tileSize.y));
                }

                for (int i = 0; i < terrain.terrainData.alphamapTextureCount; i++)
                {
                    Texture2D srcmask   = terrain.terrainData.GetAlphamapTexture(i);
                    ImageData splatData = TextureConverter.GetOrCreateImageData(srcmask);

                    terrainInfo.maskTextureDatas.Add(splatData);
                }

                if (terrainInfo.diffuseTextureDatas.Count > 0)
                {
                    terrainInfo.descriptorBindings.Add(new VkDescriptorSetLayoutBinding()
                    {
                        binding = 0, descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, stageFlags = VkShaderStageFlagBits.VK_SHADER_STAGE_FRAGMENT_BIT, descriptorCount = (uint)terrainInfo.diffuseTextureDatas.Count
                    });
                    terrainInfo.descriptorBindings.Add(new VkDescriptorSetLayoutBinding()
                    {
                        binding = 2, descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, stageFlags = VkShaderStageFlagBits.VK_SHADER_STAGE_FRAGMENT_BIT, descriptorCount = (uint)terrainInfo.diffuseScales.Count
                    });

                    terrainInfo.shaderConsts.Add(terrainInfo.diffuseTextureDatas.Count);
                    terrainInfo.shaderDefines.Add("VSG_TERRAIN_LAYERS");
                }

                terrainInfo.descriptorBindings.Add(new VkDescriptorSetLayoutBinding()
                {
                    binding = 3, descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, stageFlags = VkShaderStageFlagBits.VK_SHADER_STAGE_FRAGMENT_BIT, descriptorCount = 1
                });

                if (terrainInfo.maskTextureDatas.Count > 0)
                {
                    terrainInfo.descriptorBindings.Add(new VkDescriptorSetLayoutBinding()
                    {
                        binding = 1, descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, stageFlags = VkShaderStageFlagBits.VK_SHADER_STAGE_FRAGMENT_BIT, descriptorCount = (uint)terrainInfo.maskTextureDatas.Count
                    });
                    terrainInfo.shaderConsts.Add(terrainInfo.maskTextureDatas.Count);
                }
            }
            else
            {
                Material customMaterial = terrain.materialTemplate;
                terrainInfo.customMaterial = MaterialConverter.CreateMaterialData(customMaterial, terrainInfo.shaderMapping);
                terrainInfo.customMaterial.customDefines = terrainInfo.shaderDefines;
            }

            return(terrainInfo);
        }