Clear() public méthode

public Clear ( ) : void
Résultat void
Exemple #1
0
        public override void Load()
        {
            base.Load();

            if (OfflineCompilation)
                return;

            var renderTargets = new RenderTarget[2];
            DepthStencilBuffer depthStencilBuffer = null;
            Texture2D depthStencilTexture = null;

            Parameters.AddSources(MainPlugin.ViewParameters);

            Parameters.RegisterParameter(EffectPlugin.BlendStateKey);

            var filteredPasses = new FastList<RenderPass>();

            RenderPass.UpdatePasses += updatePassesAction = (RenderPass currentRenderPass, ref FastList<RenderPass> currentPasses) =>
                {
                    var originalPasses = currentPasses;
                    filteredPasses.Clear();
                    currentPasses = filteredPasses;

                    Parameters.Set(PickingFrameIndex, ++currentPickingFrameIndex);
                    Request[] requests;

                    lock (pendingRequests)
                    {
                        // No picking request or no mesh to pick?
                        if (pendingRequests.Count == 0)
                            return;

                        requests = pendingRequests.ToArray();
                        pendingRequests.Clear();
                    }

                    foreach (var request in requests)
                    {
                        requestResults.Add(request);
                    }

                    if (originalPasses == null)
                        return;

                    // Count mesh passes
                    int meshIndex = 0;
                    foreach (var pass in originalPasses)
                    {
                        meshIndex += pass.Passes.Count;
                    }

                    // No mesh to pick?
                    if (meshIndex == 0)
                        return;

                    // Copy mesh passes and assign indices
                    var meshPasses = new EffectMesh[meshIndex];
                    meshIndex = 0;
                    foreach (var pass in RenderPass.Passes)
                    {
                        throw new NotImplementedException();
                        //foreach (var effectMeshPass in pass.Meshes)
                        //{
                        //    meshPasses[meshIndex] = (EffectMesh)effectMeshPass;
                        //    // Prefix increment so that 0 means no rendering.
                        //    effectMeshPass.Parameters.Set(PickingMeshIndex, ++meshIndex);
                        //}
                    }

                    // For now, it generates one rendering per picking.
                    // It would be quite easy to optimize it by make Picking shader works on multiple picking points at a time.
                    foreach (var request in requests)
                    {
                        var pickingRenderPass = new RenderPass("Picking");

                        pickingRenderPass.StartPass.AddFirst = (threadContext) =>
                            {
                                threadContext.GraphicsDevice.Clear(renderTargets[0], Color.Black);
                                threadContext.GraphicsDevice.Clear(renderTargets[1], Color.Black);
                                threadContext.Parameters.Set(PickingScreenPosition, request.Location);
                                threadContext.GraphicsDevice.SetViewport(new Viewport(0, 0, renderTargets[0].Description.Width, renderTargets[0].Description.Height));

                                threadContext.GraphicsDevice.Clear(depthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
                                threadContext.GraphicsDevice.SetRenderTargets(depthStencilBuffer, renderTargets);
                            };
                        pickingRenderPass.EndPass.AddLast = (threadContext) =>
                            {
                                threadContext.Parameters.Reset(PickingScreenPosition);
                                threadContext.GraphicsDevice.Copy(renderTargets[0].Texture, request.ResultTextures[0]);
                                threadContext.GraphicsDevice.Copy(renderTargets[1].Texture, request.ResultTextures[1]);
                            };
                        //pickingRenderPass.PassesInternal = originalPasses;
                        throw new NotImplementedException();

                        request.MeshPasses = meshPasses;

                        currentPasses.Add(pickingRenderPass);

                        request.HasResults = true;

                        // Wait 2 frames before pulling the results.
                        request.FrameCounter = 2;
                    }
                };

            RenderSystem.GlobalPass.EndPass.AddLast = CheckPickingResults;

            var backBuffer = GraphicsDevice.BackBuffer; 

            int pickingArea = 1 + PickingDistance * 2;
            renderTargets[0] = Texture.New2D(GraphicsDevice, pickingArea, pickingArea, PixelFormat.R32_UInt, TextureFlags.ShaderResource | TextureFlags.RenderTarget).ToRenderTarget().KeepAliveBy(ActiveObjects);
            renderTargets[1] = Texture.New2D(GraphicsDevice, pickingArea, pickingArea, PixelFormat.R32G32B32A32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).ToRenderTarget().KeepAliveBy(ActiveObjects);

            depthStencilTexture = Texture.New2D(GraphicsDevice, pickingArea, pickingArea, PixelFormat.D32_Float, TextureFlags.ShaderResource | TextureFlags.DepthStencil).KeepAliveBy(ActiveObjects);
            depthStencilBuffer = depthStencilTexture.ToDepthStencilBuffer(false);

            Parameters.AddDynamic(PickingMatrix, ParameterDynamicValue.New(PickingScreenPosition, (ref Vector2 pickingPosition, ref Matrix picking) =>
                {
                    // Move center to picked position, and zoom (it is supposed to stay per-pixel according to render target size)
                    picking = Matrix.Translation(1.0f - (pickingPosition.X) / backBuffer.Width * 2.0f, -1.0f + (pickingPosition.Y) / backBuffer.Height * 2.0f, 0.0f)
                        * Matrix.Scaling((float)backBuffer.Width / (float)pickingArea, (float)backBuffer.Height / (float)pickingArea, 1.0f);
                }));
        }
        public void Start()
        {
            try
            {
                m_netTool = GameObject.FindObjectOfType <NetTool>();
                if (m_netTool == null)
                {
                    DebugUtils.Log("Net Tool not found");
                    enabled = false;
                    return;
                }

                bendingPrefabs.Clear();

                int count = PrefabCollection <NetInfo> .PrefabCount();

                for (uint i = 0; i < count; i++)
                {
                    NetInfo prefab = PrefabCollection <NetInfo> .GetPrefab(i);

                    if (prefab != null)
                    {
                        if (prefab.m_enableBendingSegments)
                        {
                            bendingPrefabs.Add(prefab);
                        }
                    }
                }

                Redirector <NetInfoDetour> .Deploy();

                collision = (ToolManager.instance.m_properties.m_mode & ItemClass.Availability.AssetEditor) == ItemClass.Availability.None;

                if (chirperAtlasAnarchy == null)
                {
                    LoadChirperAtlas();
                }

                chirperButton = UIView.GetAView().FindUIComponent <UIButton>("Zone");

                if (m_panel == null)
                {
                    m_tries = 0;
                    m_panel = UIView.GetAView().AddUIComponent(typeof(OptionsPanel)) as OptionsPanel;
                }
                else
                {
                    m_panel.m_anarchy.isChecked   = false;
                    m_panel.m_bending.isChecked   = true;
                    m_panel.m_snapping.isChecked  = true;
                    m_panel.m_collision.isChecked = collision;
                }

                DebugUtils.Log("Initialized");
            }
            catch (Exception e)
            {
                DebugUtils.Log("Start failed");
                DebugUtils.LogException(e);
                enabled = false;
            }
        }
Exemple #3
0
        public static void FindEscapePositionsIn(FastList <int> buffer, byte *str, ref int len, int previousComputedMaxSize)
        {
            var originalLen = len;

            buffer.Clear();
            if (previousComputedMaxSize == EscapePositionItemSize)
            {
                // if the value is 5, then we got no escape positions, see: FindEscapePositionsMaxSize
                // and we don't have to do any work
                return;
            }

            var lastEscape = 0;

            for (int i = 0; i < len; i++)
            {
                byte value = str[i];

                // PERF: We use the values directly because it is 5x faster than iterating over a constant array.
                // 8  => '\b' => 0000 1000
                // 9  => '\t' => 0000 1001
                // 13 => '\r' => 0000 1101
                // 10 => '\n' => 0000 1010
                // 12 => '\f' => 0000 1100
                // 34 => '"'  => 0010 0010
                // 92 => '\\' => 0101 1100

                if (value == 92 || value == 34 || (value >= 8 && value <= 13 && value != 11))
                {
                    buffer.Add(i - lastEscape);
                    lastEscape = i + 1;
                    continue;
                }
                //Control character ascii values
                if (value < 32)
                {
                    if (len + ControlCharacterItemSize > originalLen + previousComputedMaxSize)
                    {
                        ThrowInvalidSizeForEscapeControlChars(previousComputedMaxSize);
                    }

                    // move rest of buffer
                    // write \u0000
                    // update size
                    var from       = str + i + 1;
                    var to         = str + i + 1 + ControlCharacterItemSize;
                    var sizeToCopy = len - i - 1;
                    //here we only shifting by 5 bytes since we are going to override the byte at the current position.
                    // source and destination blocks may overlap so we using Buffer.MemoryCopy to handle that scenario.
                    Buffer.MemoryCopy(from, to, (uint)sizeToCopy, (uint)sizeToCopy);
                    str[i]     = (byte)'\\';
                    str[i + 1] = (byte)'u';
                    fixed(byte *controlString = AbstractBlittableJsonTextWriter.ControlCodeEscapes[value])
                    {
                        Memory.Copy(str + i + 2, controlString, 4);
                    }

                    //The original string already had one byte so we only added 5.
                    len += ControlCharacterItemSize;
                    i   += ControlCharacterItemSize;
                }
            }
        }
Exemple #4
0
        public BallPathFinderResult FindPath(City start, City target)
        {
            if (start == target)
            {
                return new BallPathFinderResult(new FastList<City>());
            }

            //int ofsX = Math.Min(sx, tx);
            //int ofsY = Math.Min(sy, ty);

            FastList<AStarNodeBall> enQueueBuffer = new FastList<AStarNodeBall>(10);

            AStarNodeBall startNode = nodeTable[start];
            startNode.parent = null;
            startNode.h = 0;
            startNode.g = 0;
            startNode.f = 0;
            startNode.depth = 0;

            queue.Enqueue(startNode);
            inQueueTable.Add(startNode.GetHashCode(), startNode);

            bool found = false;

            AStarNodeBall finalNode = null;

            // this is just a ordinary BFS with a sorting
            while (queue.Count > 0 && !(found))
            {
                AStarNodeBall curPos = queue.Dequeue();
                int curHash = curPos.GetHashCode();


                inQueueTable.Remove(curHash);
                passedTable.Add(curHash, curPos);

                City cc = curPos.City;

                // BFS展开新节点
                // expand sub nodes in the searching
                for (int i = 0; i < cc.LinkableCityCount; i++) 
                {
                    City nc = cc.GetLinkableCity(i);


                    AStarNodeBall np = nodeTable[nc];

                    if (np.City == target)
                    {
                        // found the way to the destination
                        found = true; //找到路径了
                        finalNode = np;

                        np.depth = curPos.depth + 1;

                        np.parent = curPos;  //当前格坐标为终点的父方格坐标
                        break;
                    }
                    else if (np.City.Owner == start.Owner)
                    {
                        int npHash = np.GetHashCode();
                        float cost = Vector3.Distance(cc.Position, nc.Position) / 1000.0f;

                        bool isNPInQueue = false;
                        AStarNodeBall temp;
                        if (inQueueTable.TryGetValue(npHash, out temp) && temp == np)
                        {
                            if (np.g > curPos.g + cost)
                            {
                                np.g = curPos.g + cost;
                                np.f = np.g + np.h;
                            }
                            isNPInQueue = true;
                        }

                        // check if the expanded node is allowable
                        // Is the grid node is node in passedTable and inQueueTable?
                        if (!isNPInQueue &&
                            (!passedTable.TryGetValue(npHash, out temp) && temp != np))
                        //如果此方格不在即将展开的节点表 和 已遍历过的节点表
                        {
                            np.parent = curPos; //当前格为此格的父方格

                            np.g = curPos.g + cost;
                            np.h = Vector3.Distance(target.Position, nc.Position);
                            np.f = np.g + np.h;
                            np.depth = curPos.depth + 1;

                            enQueueBuffer.Add(np);
                            inQueueTable.Add(npHash, np);
                        }
                    }

                }

                // A*
                //enQueueBuffer.Sort(Comparision);
                if (enQueueBuffer.Count > 0)
                {
                    QuickSort(enQueueBuffer, 0, enQueueBuffer.Count - 1);
                    for (int i = 0; i < enQueueBuffer.Count; i++)
                    {
                        queue.Enqueue(enQueueBuffer[i]);
                    }
                    enQueueBuffer.Clear();
                }
            }


            if (found)
            {
                AStarNodeBall curNode = finalNode;
                for (int i = 0; i < curNode.depth; i++)
                {
                    result.Add((City)null);
                }
                do
                {
                    //result.Add(curNode);
                    result[curNode.depth - 1] = curNode.City;
                    curNode = curNode.parent;
                }
                while (curNode.parent != null);

                return new BallPathFinderResult(result);
            }
            return null;
        }
    /*
     * -----------------------
     * DrawSoundEffects()
     * -----------------------
     */
    void DrawSoundEffects(Event e)
    {
        if ((selectedGroup < 0) || (audioManager.soundGroupings.Length == 0) || (selectedGroup >= audioManager.soundGroupings.Length))
        {
            return;
        }

        if (e.type == EventType.Repaint)
        {
            items.Clear();
        }
        else
        {
            CheckStartDrag(e);
        }

        BeginContents();
        if (DrawHeader("Sound Effects", true))
        {
            GUILayout.Space(3f);
            GUILayout.BeginVertical(GUI.skin.box);

            SerializedProperty soundGroupsArray = serializedObject.FindProperty("soundGroupings");
            SerializedProperty soundGroup       = soundGroupsArray.GetArrayElementAtIndex(selectedGroup);
            SerializedProperty soundList        = soundGroup.FindPropertyRelative("soundList");

            CreateStyles();

            Rect prevRect = new Rect();
            if (soundList.arraySize > 0)
            {
                // show all the sounds
                for (int i = 0; i < soundList.arraySize; i++)
                {
                    EditorGUI.indentLevel = 1;
                    SerializedProperty soundFX   = soundList.GetArrayElementAtIndex(i);
                    SerializedProperty visToggle = soundFX.FindPropertyRelative("visibilityToggle");
                    EditorGUILayout.BeginHorizontal(customDividerStyle);
                    {
                        string soundFXName = soundFX.FindPropertyRelative("name").stringValue;
                        // save the visibility state
                        visToggle.boolValue = EditorGUILayout.Foldout(visToggle.boolValue, soundFXName);

                        // play button
                        if (GUILayout.Button("\u25BA", GUILayout.Width(17f), GUILayout.Height(16f)))
                        {
                            if (AudioManager.IsSoundPlaying(soundFXName))
                            {
                                AudioManager.StopSound(soundFXName);
                            }
                            else
                            {
                                AudioManager.PlaySound(soundFXName);
                            }
                        }
                    }
                    EditorGUILayout.EndHorizontal();
                    if (visToggle.boolValue)
                    {
                        EditorGUILayout.PropertyField(soundFX, true);
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.FlexibleSpace();
                        if (GUILayout.Button("Delete FX", GUILayout.Width(Screen.width / 3.0f)))
                        {
                            if (EditorUtility.DisplayDialog("Delete " + soundFX.displayName, "Are you sure?", "Yes", "No!"))
                            {
                                deleteSoundIdx = i;
                            }
                        }
                        if (GUILayout.Button("Duplicate FX", GUILayout.Width(Screen.width / 3.0f)))
                        {
                            dupeSoundIdx = i;
                        }
                        GUILayout.FlexibleSpace();
                        EditorGUILayout.EndHorizontal();
                        GUILayout.Space(10.0f);
                    }
                    if (e.type == EventType.Repaint)
                    {
                        // GetLastRect() is now returning the last rect drawn in the property drawer,
                        // not the rect used for the entire SoundFX
                        Rect curRect = prevRect;
                        curRect.y = prevRect.y + EditorGUIUtility.singleLineHeight;
                        Rect lastRect = GUILayoutUtility.GetLastRect();
                        curRect.height = (lastRect.y + lastRect.height) - curRect.y;
                        curRect.width  = Screen.width;
                        items.Add(new ItemRect(i, curRect, soundFX));
                    }
                    prevRect = GUILayoutUtility.GetLastRect();
                }
            }
            else
            {
                EditorGUILayout.LabelField(" ");
            }
            GUILayout.EndVertical();
            GUILayout.Space(3f);
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Add FX", GUILayout.Width(70f)))
            {
                //soundList.InsertArrayElementAtIndex( soundList.arraySize );
                //MarkDirty();
                addSound = true;
            }
            if (GUILayout.Button("Sort", GUILayout.Width(70f)))
            {
                sortSounds = true;
            }
            EditorGUILayout.EndHorizontal();
        }
        EndContents();

        UpdateDrag(e);
    }
Exemple #6
0
        public override void Draw(DrawingContext context, IList <IDrawableObject> drawables)
        {
            FindSprites(context);

            var totalSprites = positiveSprites.Count + negativeSprites.Count + zeroOrderSprites.Count;

            if (totalSprites <= 0)
            {
                return;
            }

            if (spriteBatch == null)
            {
                spriteBatch = new SpriteBatch(context.graphics);
                basicEffect = new BasicEffect(context.graphics)
                {
                    VertexColorEnabled = true, TextureEnabled = true, LightingEnabled = false
                };
            }

            if (positiveSprites.Count > 1)
            {
                Array.Sort(positiveSprites.Elements, 0, positiveSprites.Count, sortComparer);
            }
            if (negativeSprites.Count > 1)
            {
                Array.Sort(negativeSprites.Elements, 0, negativeSprites.Count, sortComparer);
            }

            isDrawing                          = false;
            currentBlendState                  = null;
            context.PreviousMaterial           = null;
            context.graphics.DepthStencilState = DepthStencilState.None;
            context.graphics.RasterizerState   = RasterizerState.CullNone;

            // Compensate for half pixel offset
            var viewport = context.graphics.Viewport;
            var invX     = 1f / viewport.Width;
            var invY     = -1f / viewport.Height;

            context.matrices.projection.M41 -= invX;
            context.matrices.projection.M42 -= invY;

            basicEffect.View       = context.matrices.view;
            basicEffect.Projection = context.matrices.projection;

            DrawSprites(context, negativeSprites);
            DrawSprites(context, zeroOrderSprites);
            DrawSprites(context, positiveSprites);

            if (isDrawing)
            {
                spriteBatch.End();
            }

            context.matrices.projection.M41 += invX;
            context.matrices.projection.M42 += invY;

            positiveSprites.Clear();
            negativeSprites.Clear();
            zeroOrderSprites.Clear();

            // Restore rasterizer state to default since we use CullNone for sprites.
            context.graphics.RasterizerState   = RasterizerState.CullCounterClockwise;
            context.graphics.DepthStencilState = DepthStencilState.Default;
        }
Exemple #7
0
 public void Clear()
 {
     ManagedObjects.Clear();
 }
Exemple #8
0
 public void Clear()
 {
     FinalCount = 0;
     Sorting.Clear();
 }
Exemple #9
0
        private TreePage SearchForPage(Slice key, out TreeNodeHeader *node)
        {
            var p = GetReadOnlyTreePage(State.RootPageNumber);

            if (_cursorPathBuffer == null)
            {
                _cursorPathBuffer = new FastList <long>();
            }
            else
            {
                _cursorPathBuffer.Clear();
            }

            _cursorPathBuffer.Add(p.PageNumber);

            bool rightmostPage = true;
            bool leftmostPage  = true;

            while ((p.TreeFlags & TreePageFlags.Branch) == TreePageFlags.Branch)
            {
                int nodePos;

                if (key.Options == SliceOptions.Key)
                {
                    if (p.Search(_llt, key) != null)
                    {
                        nodePos = p.LastSearchPosition;
                        if (p.LastMatch != 0)
                        {
                            nodePos--;
                            p.LastSearchPosition--;
                        }

                        if (nodePos != 0)
                        {
                            leftmostPage = false;
                        }

                        rightmostPage = false;
                    }
                    else
                    {
                        nodePos = (ushort)(p.LastSearchPosition - 1);

                        leftmostPage = false;
                    }
                }
                else if (key.Options == SliceOptions.BeforeAllKeys)
                {
                    p.LastSearchPosition = nodePos = 0;
                    rightmostPage        = false;
                }
                else // if (key.Options == SliceOptions.AfterAllKeys)
                {
                    p.LastSearchPosition = nodePos = (ushort)(p.NumberOfEntries - 1);
                    leftmostPage         = false;
                }

                var pageNode = p.GetNode(nodePos);
                p = GetReadOnlyTreePage(pageNode->PageNumber);
                Debug.Assert(pageNode->PageNumber == p.PageNumber,
                             string.Format("Requested Page: #{0}. Got Page: #{1}", pageNode->PageNumber, p.PageNumber));

                _cursorPathBuffer.Add(p.PageNumber);
            }

            if (p.IsLeaf == false)
            {
                VoronUnrecoverableErrorException.Raise(_llt.Environment, "Index points to a non leaf page " + p.PageNumber);
            }

            if (p.IsCompressed)
            {
                ThrowOnCompressedPage(p);
            }

            node = p.Search(_llt, key); // will set the LastSearchPosition

            AddToRecentlyFoundPages(_cursorPathBuffer, p, leftmostPage, rightmostPage);

            return(p);
        }
Exemple #10
0
        public PathFinderResult FindPath(int sx, int sy, int tx, int ty)
        {
            if (sx == tx && sy == ty)
            {
                return(new PathFinderResult(new FastList <Point>(), false));
            }

            int ofsX = Math.Min(sx, tx);
            int ofsY = Math.Min(sy, ty);

            FastList <AStarNode> enQueueBuffer = new FastList <AStarNode>(10);

            AStarNode startNode = units[sx][sy];

            startNode.parent = null;
            startNode.h      = 0;
            startNode.g      = 0;
            startNode.f      = 0;
            startNode.depth  = 0;

            queue.Enqueue(startNode);
            inQueueTable.Add(startNode.GetHashCode(), startNode);

            bool found = false;
            bool rcpf  = false;

            AStarNode finalNode = null;

            while (queue.Count > 0 && !(found || rcpf))
            {
                AStarNode curPos  = queue.Dequeue(); //将open列表中最前面的元素设为当前格
                int       curHash = curPos.GetHashCode();

                if (curPos.depth > MaxStep)
                {
                    rcpf      = true;
                    finalNode = curPos;
                    break;
                }


                inQueueTable.Remove(curHash);
                passedTable.Add(curHash, curPos);

                int cx = curPos.X;
                int cy = curPos.Y;

                // BFS展开新节点
                for (int i = 0; i < 8; i++)
                {
                    int nx = cx + stateEnum[i][0];
                    int ny = cy + stateEnum[i][1];

                    // 检查范围
                    if (nx >= 0 && nx < width && ny >= 0 && ny < height)
                    {
                        AStarNode np     = units[nx][ny];
                        int       npHash = np.GetHashCode();


                        if (nx == tx && ny == ty) //如此方格为终点
                        {
                            found     = true;     //找到路径了
                            finalNode = np;

                            np.depth  = curPos.depth + 1;
                            np.parent = curPos;  //当前格坐标为终点的父方格坐标
                            break;
                        }
                        else
                        {
                            if (!terrain.GetBit(ny * width + nx))  //地块能通过
                            {
                                bool      isNPInQueue = false;
                                AStarNode temp;
                                if (inQueueTable.TryGetValue(npHash, out temp) && temp == np)
                                {
                                    if (np.g > curPos.g + stateEnumCost[i])
                                    {
                                        np.g = curPos.g + stateEnumCost[i];
                                        np.f = np.g + np.h;
                                    }
                                    isNPInQueue = true;
                                }

                                if (!isNPInQueue &&
                                    (!passedTable.TryGetValue(npHash, out temp) && temp != np))
                                //如果此方格不在即将展开的节点表 和 已遍历过的节点表
                                {
                                    np.parent = curPos; //当前格为此格的父方格

                                    np.g     = curPos.g + stateEnumCost[i];
                                    np.h     = Math.Abs(tx - nx) + Math.Abs(ty - ny);
                                    np.f     = np.g + np.h;
                                    np.depth = curPos.depth + 1;

                                    enQueueBuffer.Add(np);
                                    inQueueTable.Add(npHash, np);
                                }
                            }
                        }
                    }
                }

                // A*
                //enQueueBuffer.Sort(Comparision);
                if (enQueueBuffer.Count > 0)
                {
                    QuickSort(enQueueBuffer, 0, enQueueBuffer.Count - 1);
                    for (int i = 0; i < enQueueBuffer.Count; i++)
                    {
                        queue.Enqueue(enQueueBuffer[i]);
                    }
                    enQueueBuffer.Clear();
                }
            }

            if (rcpf)
            {
                AStarNode curNode    = finalNode;
                int       baseOffset = result.Count;
                for (int i = 0; i < curNode.depth; i++)
                {
                    result.Add(Point.Zero);
                }
                do
                {
                    //result.Add(curNode);
                    result[baseOffset + curNode.depth - 1] = new Point(curNode.X, curNode.Y);
                    curNode = curNode.parent;
                }while (curNode.parent != null);

                return(new PathFinderResult(result, true));
            }
            if (found)
            {
                AStarNode curNode = finalNode;
                for (int i = 0; i < curNode.depth + 1; i++)
                {
                    result.Add(Point.Zero);
                }
                do
                {
                    //result.Add(curNode);
                    result[curNode.depth] = new Point(curNode.X, curNode.Y);
                    curNode = curNode.parent;
                }while (curNode.parent != null);

                result[0] = new Point(sx, sy);
                return(new PathFinderResult(result, false));
            }
            return(null);
        }
Exemple #11
0
        public byte[] DownloadData()
        {
            Stopwatch sw = Stopwatch.StartNew();

            try
            {
                if (_currentStream == null)
                {
                    Trace.WriteLine("Connecting to " + _ip + " for " + _uri);

                    _errored                         = false;
                    _currentTcpClient                = new TcpClient();
                    _currentTcpClient.NoDelay        = true;
                    _currentTcpClient.ReceiveTimeout = 500;
                    _currentTcpClient.SendTimeout    = 500;
                    _currentTcpClient.Connect(_ip, _uri.Port);
                    _currentStream              = _currentTcpClient.GetStream();
                    _currentStream.ReadTimeout  = 500;
                    _currentStream.WriteTimeout = 500;

                    byte[] initialBuffer = Encoding.ASCII.GetBytes(string.Format(_initialRequestFormat, _uri.ToString(), _uri.Host));
                    _currentStream.Write(initialBuffer, 0, initialBuffer.Length);

                    //_readyNextRequest = Encoding.ASCII.GetBytes(string.Format(_nextRequestFormat, uri.ToString(), uri.Host));
                    _readyNextRequest = initialBuffer;
                }
                else
                {
                    _currentStream.Write(_readyNextRequest, 0, _readyNextRequest.Length);
                }

                _responseBuffer.Clear();

                int bytesRead;

                int  bytesAnalyzed;
                bool endOfHeadersReached = false;

                int    contentLength = -1;
                string httpVersion   = null;

                do
                {
                    bytesRead = _currentStream.Read(_buffer, 0, _buffer.Length);

                    _responseBuffer.AddRange(_buffer, 0, bytesRead);
                    IList <string> newHeaders = AnalyzeHeaders(_responseBuffer.GetInternalBuffer(), _responseBuffer.Count, out bytesAnalyzed, out endOfHeadersReached);

                    _responseBuffer.RemoveRange(0, bytesAnalyzed);

                    foreach (string header in newHeaders)
                    {
                        Trace.WriteLine(header);

                        if (header.StartsWith("HTTP/1"))
                        {
                            string[] splitted         = header.Split(_spaceCharArray);
                            string   httpResponseCode = splitted[1];

                            if (httpResponseCode != "200")
                            {
                                throw new InvalidDataException("httpResponseCode is " + httpResponseCode);
                            }

                            httpVersion = splitted[0];
                        }
                        else if (header.StartsWith("Content-Length:"))
                        {
                            contentLength = int.Parse(header.Split(_spaceCharArray)[1]);
                        }
                        else if (header == "Connection: keep-alive")
                        {
                            _keepAlive = true;
                        }
                        else if (header == "Connection: close")
                        {
                            _keepAlive = false;
                        }
                    }
                }while (!endOfHeadersReached);

                if (contentLength < 0 && httpVersion != "HTTP/1.0")
                {
                    throw new InvalidDataException("Content-Length is " + contentLength);
                }

                Trace.WriteLine("HTTP Version is " + httpVersion);

                if (httpVersion != "HTTP/1.0")
                {
                    while (_responseBuffer.Count < contentLength)
                    {
                        bytesRead = _currentStream.Read(_buffer, 0, _buffer.Length);
                        _responseBuffer.AddRange(_buffer, 0, bytesRead);
                    }
                }
                else
                {
                    _keepAlive = false;

                    try
                    {
                        while ((bytesRead = _currentStream.Read(_buffer, 0, _buffer.Length)) > 0)
                        {
                            _responseBuffer.AddRange(_buffer, 0, bytesRead);
                        }
                    }
                    catch (Exception)
                    {
                    }
                }

                byte[] result = _responseBuffer.ToArray();
                return(result);
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Connecting to " + _ip + " for " + _uri);
                Trace.WriteLine("Exception from " + _ip + " for " + _uri + ": " + ex.ToString());

                _errored   = true;
                _keepAlive = false;

                if (_currentStream != null)
                {
                    _currentStream.Close();
                    _currentStream = null;
                }

                if (_currentTcpClient != null)
                {
                    _currentTcpClient.Close();
                    _currentTcpClient = null;
                }

                throw;
            }
            finally
            {
                if (!_keepAlive)
                {
                    if (_currentStream != null)
                    {
                        _currentStream.Close();
                        _currentStream = null;
                    }

                    if (_currentTcpClient != null)
                    {
                        _currentTcpClient.Close();
                        _currentTcpClient = null;
                    }
                }

                Trace.WriteLine("DownloadData " + sw.Elapsed);
            }

            //HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            ////request.KeepAlive = true;
            ////request.IfModifiedSince = _lastModified;

            ////request.Host = "www.oref.org.il";

            //using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            //{
            //    //_lastModified = response.LastModified;

            //    using (Stream responseStream = response.GetResponseStream())
            //    using (StreamReader reader = new StreamReader(responseStream, Encoding.Unicode))
            //    {
            //        return reader.ReadToEnd();
            //    }
            //}
        }
Exemple #12
0
 public override void ClearAll()
 {
     m_record.Clear();
 }
Exemple #13
0
        public PathFinderResult FindPath(int sx, int sy, int tx, int ty)
        {
            if (sx == tx && sy == ty)
            {
                return new PathFinderResult(new FastList<Point>(), false);
            }

            int ofsX = Math.Min(sx, tx);
            int ofsY = Math.Min(sy, ty);

            FastList<AStarNode> enQueueBuffer = new FastList<AStarNode>(10);

            AStarNode startNode = units[sx][sy];
            startNode.parent = null;
            startNode.h = 0;
            startNode.g = 0;
            startNode.f = 0;
            startNode.depth = 0;

            queue.Enqueue(startNode);
            inQueueTable.Add(startNode.GetHashCode(), startNode);

            bool found = false;
            bool rcpf = false;

            AStarNode finalNode = null;

            while (queue.Count > 0 && !(found || rcpf))
            {
                AStarNode curPos = queue.Dequeue(); //将open列表中最前面的元素设为当前格
                int curHash = curPos.GetHashCode();

                if (curPos.depth > MaxStep)
                {
                    rcpf = true;
                    finalNode = curPos;
                    break;
                }


                inQueueTable.Remove(curHash);
                passedTable.Add(curHash, curPos);

                int cx = curPos.X;
                int cy = curPos.Y;

                // BFS展开新节点
                for (int i = 0; i < 8; i++)
                {
                    int nx = cx + stateEnum[i][0];
                    int ny = cy + stateEnum[i][1];

                    // 检查范围
                    if (nx >= 0 && nx < width && ny >= 0 && ny < height)
                    {
                        AStarNode np = units[nx][ny];
                        int npHash = np.GetHashCode();


                        if (nx == tx && ny == ty) //如此方格为终点
                        {
                            found = true; //找到路径了
                            finalNode = np;

                            np.depth = curPos.depth + 1;
                            np.parent = curPos;  //当前格坐标为终点的父方格坐标
                            break;
                        }
                        else
                        {
                            if (!terrain.GetBit(ny * width + nx))  //地块能通过
                            {
                                bool isNPInQueue = false;
                                AStarNode temp;
                                if (inQueueTable.TryGetValue(npHash, out temp) && temp == np)
                                {
                                    if (np.g > curPos.g + stateEnumCost[i])
                                    {
                                        np.g = curPos.g + stateEnumCost[i];
                                        np.f = np.g + np.h;
                                    }
                                    isNPInQueue = true;
                                }

                                if (!isNPInQueue &&
                                    (!passedTable.TryGetValue(npHash, out temp) && temp != np))
                                //如果此方格不在即将展开的节点表 和 已遍历过的节点表
                                {
                                    np.parent = curPos; //当前格为此格的父方格

                                    np.g = curPos.g + stateEnumCost[i];
                                    np.h = Math.Abs(tx - nx) + Math.Abs(ty - ny);
                                    np.f = np.g + np.h;
                                    np.depth = curPos.depth + 1;

                                    enQueueBuffer.Add(np);
                                    inQueueTable.Add(npHash, np);
                                }
                            }
                        }
                    }

                }

                // A*
                //enQueueBuffer.Sort(Comparision);
                if (enQueueBuffer.Count > 0)
                {
                    QuickSort(enQueueBuffer, 0, enQueueBuffer.Count - 1);
                    for (int i = 0; i < enQueueBuffer.Count; i++)
                    {
                        queue.Enqueue(enQueueBuffer[i]);
                    }
                    enQueueBuffer.Clear();
                }
            }

            if (rcpf)
            {
                AStarNode curNode = finalNode;
                int baseOffset = result.Count;
                for (int i = 0; i < curNode.depth; i++)
                {
                    result.Add(Point.Zero);
                }
                do
                {
                    //result.Add(curNode);
                    result[baseOffset + curNode.depth - 1] = new Point(curNode.X, curNode.Y);
                    curNode = curNode.parent;
                }
                while (curNode.parent != null);

                return new PathFinderResult(result, true);
            }
            if (found)
            {
                AStarNode curNode = finalNode;
                for (int i = 0; i < curNode.depth + 1; i++)
                {
                    result.Add(Point.Zero);
                }
                do
                {
                    //result.Add(curNode);
                    result[curNode.depth] = new Point(curNode.X, curNode.Y);
                    curNode = curNode.parent;
                }
                while (curNode.parent != null);

                result[0] = new Point(sx, sy);
                return new PathFinderResult(result, false);
            }
            return null;
        }
        private unsafe object ExportAnimation(ICommandContext commandContext, AssetManager assetManager)
        {
            // Read from model file
            var modelSkeleton = LoadSkeleton(commandContext, assetManager); // we get model skeleton to compare it to real skeleton we need to map to
            var animationClips = LoadAnimation(commandContext, assetManager);
            AnimationClip animationClip = null;

            if (animationClips.Count > 0)
            {
                animationClip = new AnimationClip();

                AnimationClip rootMotionAnimationClip = null;

                // If root motion is explicitely enabled, or if there is no skeleton, try to find root node and apply animation directly on TransformComponent
                if ((AnimationRootMotion || SkeletonUrl == null) && modelSkeleton.Nodes.Length >= 1)
                {
                    // No skeleton, map root node only
                    // TODO: For now, it seems to be located on node 1 in FBX files. Need to check if always the case, and what happens with Assimp
                    var rootNode0 = modelSkeleton.Nodes.Length >= 1 ? modelSkeleton.Nodes[0].Name : null;
                    var rootNode1 = modelSkeleton.Nodes.Length >= 2 ? modelSkeleton.Nodes[1].Name : null;
                    if ((rootNode0 != null && animationClips.TryGetValue(rootNode0, out rootMotionAnimationClip))
                        || (rootNode1 != null && animationClips.TryGetValue(rootNode1, out rootMotionAnimationClip)))
                    {
                        foreach (var channel in rootMotionAnimationClip.Channels)
                        {
                            var curve = rootMotionAnimationClip.Curves[channel.Value.CurveIndex];

                            // Root motion
                            var channelName = channel.Key;
                            if (channelName.StartsWith("Transform."))
                            {
                                animationClip.AddCurve($"[TransformComponent.Key]." + channelName.Replace("Transform.", string.Empty), curve);
                            }

                            // Also apply Camera curves
                            // TODO: Add some other curves?
                            if (channelName.StartsWith("Camera."))
                            {
                                animationClip.AddCurve($"[CameraComponent.Key]." + channelName.Replace("Camera.", string.Empty), curve);
                            }
                        }

                        // Take max of durations
                        if (animationClip.Duration < rootMotionAnimationClip.Duration)
                            animationClip.Duration = rootMotionAnimationClip.Duration;
                    }
                }

                // Load asset reference skeleton
                if (SkeletonUrl != null)
                {
                    var skeleton = assetManager.Load<Skeleton>(SkeletonUrl);
                    var skeletonMapping = new SkeletonMapping(skeleton, modelSkeleton);

                    // Process missing nodes
                    foreach (var nodeAnimationClipEntry in animationClips)
                    {
                        var nodeName = nodeAnimationClipEntry.Key;
                        var nodeAnimationClip = nodeAnimationClipEntry.Value;
                        var nodeIndex = modelSkeleton.Nodes.IndexOf(x => x.Name == nodeName);

                        // Node doesn't exist in skeleton? skip it
                        if (nodeIndex == -1 || skeletonMapping.SourceToSource[nodeIndex] != nodeIndex)
                            continue;

                        // Skip root motion node (if any)
                        if (nodeAnimationClip == rootMotionAnimationClip)
                            continue;

                        // Find parent node
                        var parentNodeIndex = modelSkeleton.Nodes[nodeIndex].ParentIndex;

                        if (parentNodeIndex != -1 && skeletonMapping.SourceToSource[parentNodeIndex] != parentNodeIndex)
                        {
                            // Some nodes were removed, we need to concat the anim curves
                            var currentNodeIndex = nodeIndex;
                            var nodesToMerge = new List<Tuple<ModelNodeDefinition, AnimationBlender, AnimationClipEvaluator>>();
                            while (currentNodeIndex != -1 && currentNodeIndex != skeletonMapping.SourceToSource[parentNodeIndex])
                            {
                                AnimationClip animationClipToMerge;
                                AnimationClipEvaluator animationClipEvaluator = null;
                                AnimationBlender animationBlender = null;
                                if (animationClips.TryGetValue(modelSkeleton.Nodes[currentNodeIndex].Name, out animationClipToMerge))
                                {
                                    animationBlender = new AnimationBlender();
                                    animationClipEvaluator = animationBlender.CreateEvaluator(animationClipToMerge);
                                }
                                nodesToMerge.Add(Tuple.Create(modelSkeleton.Nodes[currentNodeIndex], animationBlender, animationClipEvaluator));
                                currentNodeIndex = modelSkeleton.Nodes[currentNodeIndex].ParentIndex;
                            }

                            // Put them in proper parent to children order
                            nodesToMerge.Reverse();

                            // Find all key times
                            // TODO: We should detect discontinuities and keep them
                            var animationKeysSet = new HashSet<CompressedTimeSpan>();

                            foreach (var node in nodesToMerge)
                            {
                                foreach (var curve in node.Item3.Clip.Curves)
                                {
                                    foreach (CompressedTimeSpan time in curve.Keys)
                                    {
                                        animationKeysSet.Add(time);
                                    }
                                }
                            }

                            // Sort key times
                            var animationKeys = animationKeysSet.ToList();
                            animationKeys.Sort();

                            var animationOperations = new FastList<AnimationOperation>();

                            var combinedAnimationClip = new AnimationClip();

                            var translationCurve = new AnimationCurve<Vector3>();
                            var rotationCurve = new AnimationCurve<Quaternion>();
                            var scaleCurve = new AnimationCurve<Vector3>();

                            // Evaluate at every key frame
                            foreach (var animationKey in animationKeys)
                            {
                                var matrix = Matrix.Identity;

                                // Evaluate node
                                foreach (var node in nodesToMerge)
                                {
                                    // Get default position
                                    var modelNodeDefinition = node.Item1;

                                    // Compute
                                    AnimationClipResult animationClipResult = null;
                                    animationOperations.Clear();
                                    animationOperations.Add(AnimationOperation.NewPush(node.Item3, animationKey));
                                    node.Item2.Compute(animationOperations, ref animationClipResult);

                                    var updateMemberInfos = new List<UpdateMemberInfo>();
                                    foreach (var channel in animationClipResult.Channels)
                                        updateMemberInfos.Add(new UpdateMemberInfo { Name = channel.PropertyName, DataOffset = channel.Offset });

                                    // TODO: Cache this
                                    var compiledUpdate = UpdateEngine.Compile(typeof(ModelNodeDefinition), updateMemberInfos);

                                    unsafe
                                    {
                                        fixed (byte* data = animationClipResult.Data)
                                            UpdateEngine.Run(modelNodeDefinition, compiledUpdate, (IntPtr)data, null);
                                    }

                                    Matrix localMatrix;
                                    TransformComponent.CreateMatrixTRS(ref modelNodeDefinition.Transform.Position, ref modelNodeDefinition.Transform.Rotation, ref modelNodeDefinition.Transform.Scale,
                                        out localMatrix);
                                    matrix = Matrix.Multiply(localMatrix, matrix);
                                }

                                // Done evaluating, let's decompose matrix
                                TransformTRS transform;
                                matrix.Decompose(out transform.Scale, out transform.Rotation, out transform.Position);

                                // Create a key
                                translationCurve.KeyFrames.Add(new KeyFrameData<Vector3>(animationKey, transform.Position));
                                rotationCurve.KeyFrames.Add(new KeyFrameData<Quaternion>(animationKey, transform.Rotation));
                                scaleCurve.KeyFrames.Add(new KeyFrameData<Vector3>(animationKey, transform.Scale));
                            }

                            combinedAnimationClip.AddCurve($"{nameof(ModelNodeTransformation.Transform)}.{nameof(TransformTRS.Position)}", translationCurve);
                            combinedAnimationClip.AddCurve($"{nameof(ModelNodeTransformation.Transform)}.{nameof(TransformTRS.Rotation)}", rotationCurve);
                            combinedAnimationClip.AddCurve($"{nameof(ModelNodeTransformation.Transform)}.{nameof(TransformTRS.Scale)}", scaleCurve);
                            nodeAnimationClip = combinedAnimationClip;
                        }

                        foreach (var channel in nodeAnimationClip.Channels)
                        {
                            var curve = nodeAnimationClip.Curves[channel.Value.CurveIndex];

                            // TODO: Root motion
                            var channelName = channel.Key;
                            if (channelName.StartsWith("Transform."))
                            {
                                animationClip.AddCurve($"[ModelComponent.Key].Skeleton.NodeTransformations[{skeletonMapping.SourceToTarget[nodeIndex]}]." + channelName, curve);
                            }
                        }

                        // Take max of durations
                        if (animationClip.Duration < nodeAnimationClip.Duration)
                            animationClip.Duration = nodeAnimationClip.Duration;
                    }
                }
            }

            if (animationClip == null)
            {
                commandContext.Logger.Info("File {0} has an empty animation.", SourcePath);
            }
            else
            {
                if (animationClip.Duration.Ticks == 0)
                {
                    commandContext.Logger.Warning("File {0} has a 0 tick long animation.", SourcePath);
                }

                // Optimize and set common parameters
                animationClip.RepeatMode = AnimationRepeatMode;
                animationClip.Optimize();
            }
            return animationClip;
        }
Exemple #15
0
        protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
        {
            var viewport = drawContext.CommandList.Viewport;

            using (drawContext.PushRenderTargetsAndRestore())
            {
                // Render Shadow maps
                shadowMapRenderer?.Draw(drawContext);

                if (VRSettings.Enabled && VRSettings.VRDevice != null)
                {
                    var isFullViewport = (int)viewport.X == 0 && (int)viewport.Y == 0 &&
                                         (int)viewport.Width == drawContext.CommandList.RenderTarget.ViewWidth &&
                                         (int)viewport.Height == drawContext.CommandList.RenderTarget.ViewHeight;
                    if (!isFullViewport)
                    {
                        return;
                    }

                    using (drawContext.PushRenderTargetsAndRestore())
                    {
                        //make sure we don't use any default targets!
                        drawContext.CommandList.SetRenderTargets(null, null);

                        PrepareRenderTargets(drawContext, new Size2(VRSettings.VRDevice.ActualRenderFrameSize.Width / 2, VRSettings.VRDevice.ActualRenderFrameSize.Height));

                        //also prepare the final VR target
                        var vrFullSurface = PushScopedResource(drawContext.GraphicsContext.Allocator.GetTemporaryTexture2D(
                                                                   TextureDescription.New2D(VRSettings.VRDevice.ActualRenderFrameSize.Width, VRSettings.VRDevice.ActualRenderFrameSize.Height, 1, PixelFormat.R8G8B8A8_UNorm_SRgb,
                                                                                            TextureFlags.ShaderResource | TextureFlags.RenderTarget)));

                        //draw per eye
                        using (context.SaveViewportAndRestore())
                            using (drawContext.PushRenderTargetsAndRestore())
                            {
                                drawContext.CommandList.SetViewport(new Viewport(0.0f, 0.0f, VRSettings.VRDevice.ActualRenderFrameSize.Width / 2.0f, VRSettings.VRDevice.ActualRenderFrameSize.Height));
                                drawContext.CommandList.SetRenderTargets(currentDepthStencil, currentRenderTargets.Count, currentRenderTargets.Items);

                                ViewCount = 2;

                                for (var i = 0; i < 2; i++)
                                {
                                    using (context.PushRenderViewAndRestore(VRSettings.RenderViews[i]))
                                    {
                                        // Clear render target and depth stencil
                                        Clear?.Draw(drawContext);

                                        ViewIndex = i;

                                        DrawView(context, drawContext);
                                        drawContext.CommandList.CopyRegion(ViewOutputTarget, 0, null, vrFullSurface, 0, VRSettings.VRDevice.ActualRenderFrameSize.Width / 2 * i);
                                    }
                                }

                                if (VRSettings.VRDevice.SupportsOverlays)
                                {
                                    foreach (var overlay in VRSettings.Overlays)
                                    {
                                        if (overlay != null && overlay.Texture != null)
                                        {
                                            overlay.Overlay.UpdateSurface(drawContext.CommandList, overlay.Texture);
                                        }
                                    }
                                }

                                VRSettings.VRDevice.Commit(drawContext.CommandList, vrFullSurface);
                            }
                    }

                    //draw mirror to backbuffer (if size is matching and full viewport)
                    if (VRSettings.CopyMirror)
                    {
                        if (VRSettings.VRDevice.MirrorTexture.Size != drawContext.CommandList.RenderTarget.Size)
                        {
                            VRSettings.MirrorScaler.SetInput(0, VRSettings.VRDevice.MirrorTexture);
                            VRSettings.MirrorScaler.SetOutput(drawContext.CommandList.RenderTarget);
                            VRSettings.MirrorScaler.Draw(drawContext);
                        }
                        else
                        {
                            drawContext.CommandList.Copy(VRSettings.VRDevice.MirrorTexture, drawContext.CommandList.RenderTarget);
                        }
                    }
                }
                else
                {
                    PrepareRenderTargets(drawContext, new Size2((int)viewport.Width, (int)viewport.Height));

                    ViewCount = 1;
                    ViewIndex = 0;

                    using (drawContext.PushRenderTargetsAndRestore())
                    {
                        drawContext.CommandList.SetRenderTargets(currentDepthStencil, currentRenderTargets.Count, currentRenderTargets.Items);

                        // Clear render target and depth stencil
                        Clear?.Draw(drawContext);

                        DrawView(context, drawContext);
                    }
                }
            }

            // Clear intermediate results
            currentRenderTargets.Clear();
            currentRenderTargetsNonMSAA.Clear();
            currentDepthStencil        = null;
            currentDepthStencilNonMSAA = null;
        }
        private Tuple <DynamicVao, DynamicVao> TryBuildVaoForLight(Light light)
        {
            _hullVertices.Clear();
            _shadowVertices.Clear();
            _shadowIndices.Clear();
            _hullIndices.Clear();

            int numSegments       = 0;
            int shadowIndexOffset = 0;
            int hullIndexOffset   = 0;
            int hullCount         = _engine.Hulls.Count;

            for (int i = 0; i < hullCount; i++)
            {
                Hull hull = _engine.Hulls[i];
                if (!hull.Enabled || !hull.Valid || !light.Intersects(hull))
                {
                    continue;
                }

                Polygon points = hull.WorldPoints;

                Vector2 prevPoint = points[points.Count - 1];

                int pointCount = points.Count;
                numSegments += pointCount;
                for (int j = 0; j < pointCount; j++)
                {
                    Vector2 currentPoint = points[j];

                    _shadowVertices.Add(new VertexShadow(prevPoint, currentPoint, new Vector2(0.0f, 0.0f)));
                    _shadowVertices.Add(new VertexShadow(prevPoint, currentPoint, new Vector2(1.0f, 0.0f)));
                    _shadowVertices.Add(new VertexShadow(prevPoint, currentPoint, new Vector2(0.0f, 1.0f)));
                    _shadowVertices.Add(new VertexShadow(prevPoint, currentPoint, new Vector2(1.0f, 1.0f)));

                    _shadowIndices.Add(shadowIndexOffset * 4 + 0);
                    _shadowIndices.Add(shadowIndexOffset * 4 + 1);
                    _shadowIndices.Add(shadowIndexOffset * 4 + 2);

                    _shadowIndices.Add(shadowIndexOffset * 4 + 1);
                    _shadowIndices.Add(shadowIndexOffset * 4 + 3);
                    _shadowIndices.Add(shadowIndexOffset * 4 + 2);

                    prevPoint = currentPoint;
                    shadowIndexOffset++;
                }

                _hullVertices.AddRange(hull.WorldPoints);

                int indexCount = hull.Indices.Count;
                for (int j = 0; j < indexCount; j++)
                {
                    _hullIndices.Add(hull.Indices[j] + hullIndexOffset);
                }
                hullIndexOffset += pointCount;
            }

            if (numSegments == 0)
            {
                return(null);
            }

            Tuple <DynamicVao, DynamicVao> lightVaos;

            if (!_lightsVaos.TryGetValue(light, out lightVaos))
            {
                lightVaos = Tuple.Create(
                    DynamicVao.New(_engine.Device, VertexShadow.Layout, PrimitiveType.TriangleList, _shadowVertices.Count, _shadowIndices.Count, useIndices: true),
                    DynamicVao.New(_engine.Device, VertexPosition2.Layout, PrimitiveType.TriangleList, _hullVertices.Count, _hullIndices.Count, useIndices: true));
                _lightsVaos.Add(light, lightVaos);
            }

            lightVaos.Item1.SetVertices(_shadowVertices);
            lightVaos.Item1.SetIndices(_shadowIndices);
            lightVaos.Item2.SetVertices(_hullVertices);
            lightVaos.Item2.SetIndices(_hullIndices);

            return(lightVaos);
        }
Exemple #17
0
 /// <summary>
 /// removes all Particles and Constraints from the Composite
 /// </summary>
 public void RemoveAll()
 {
     Particles.Clear();
     _constraints.Clear();
 }
    /*
     * -----------------------
     * DrawCategories()
     * -----------------------
     */
    void DrawCategories(Event e)
    {
        // do any housework before we start drawing
        if (moveQueued)
        {
            // make a temp copy
            List <SoundFX> origSoundList   = new List <SoundFX>(audioManager.soundGroupings[origGroup].soundList);
            SoundFX        temp            = origSoundList[origIndex];
            List <SoundFX> moveToSoundList = new List <SoundFX>(audioManager.soundGroupings[moveToGroup].soundList);
            // add it to the move to group
            moveToSoundList.Add(temp);
            audioManager.soundGroupings[moveToGroup].soundList = moveToSoundList.ToArray();
            // and finally, remove it from the original group
            origSoundList.RemoveAt(origIndex);
            audioManager.soundGroupings[origGroup].soundList = origSoundList.ToArray();
            Debug.Log("> Moved '" + temp.name + "' from " + "'" + audioManager.soundGroupings[origGroup].name + "' to '" + audioManager.soundGroupings[moveToGroup].name);
            MarkDirty();
            moveQueued = false;
        }
        // switch to the next group
        if (nextGroup > -1)
        {
            selectedGroup = nextGroup;
            nextGroup     = -1;
        }
        // add a sound
        if (addSound)
        {
            List <SoundFX> soundList = new List <SoundFX>(audioManager.soundGroupings[selectedGroup].soundList);
            SoundFX        soundFX   = new SoundFX();
            soundFX.name = audioManager.soundGroupings[selectedGroup].name.ToLower() + "_new_unnamed_sound_fx";
            soundList.Add(soundFX);
            audioManager.soundGroupings[selectedGroup].soundList = soundList.ToArray();
            MarkDirty();
            addSound = false;
        }
        // sort the sounds
        if (sortSounds)
        {
            List <SoundFX> soundList = new List <SoundFX>(audioManager.soundGroupings[selectedGroup].soundList);
            soundList.Sort(delegate(SoundFX sfx1, SoundFX sfx2) { return(string.Compare(sfx1.name, sfx2.name)); });
            audioManager.soundGroupings[selectedGroup].soundList = soundList.ToArray();
            MarkDirty();
            sortSounds = false;
        }
        // delete a sound
        if (deleteSoundIdx > -1)
        {
            List <SoundFX> soundList = new List <SoundFX>(audioManager.soundGroupings[selectedGroup].soundList);
            soundList.RemoveAt(deleteSoundIdx);
            audioManager.soundGroupings[selectedGroup].soundList = soundList.ToArray();
            MarkDirty();
            deleteSoundIdx = -1;
        }
        // duplicate a sound
        if (dupeSoundIdx > -1)
        {
            List <SoundFX> soundList   = new List <SoundFX>(audioManager.soundGroupings[selectedGroup].soundList);
            SoundFX        origSoundFX = soundList[dupeSoundIdx];
            // clone this soundFX
            string  json    = JsonUtility.ToJson(origSoundFX);
            SoundFX soundFX = JsonUtility.FromJson <SoundFX>(json);
            soundFX.name += "_duplicated";
            soundList.Insert(dupeSoundIdx + 1, soundFX);
            audioManager.soundGroupings[selectedGroup].soundList = soundList.ToArray();
            MarkDirty();
            dupeSoundIdx = -1;
        }

        if (e.type == EventType.Repaint)
        {
            groups.Clear();
        }

        GUILayout.Space(6f);

        Color defaultColor = GUI.contentColor;

        BeginContents();

        if (DrawHeader("Sound FX Groups", true))
        {
            EditorGUILayout.BeginVertical(GUI.skin.box);
            soundGroups.Clear();
            for (int i = 0; i < audioManager.soundGroupings.Length; i++)
            {
                soundGroups.Add(audioManager.soundGroupings[i]);
            }
            for (int i = 0; i < soundGroups.size; i++)
            {
                EditorGUILayout.BeginHorizontal();
                {
                    if (i == selectedGroup)
                    {
                        GUI.contentColor = (i == editGroup) ? Color.white : Color.yellow;
                    }
                    else
                    {
                        GUI.contentColor = defaultColor;
                    }
                    if ((e.type == EventType.KeyDown) && ((e.keyCode == KeyCode.Return) || (e.keyCode == KeyCode.KeypadEnter)))
                    {
                        // toggle editing
                        if (editGroup >= 0)
                        {
                            editGroup = -1;
                        }
                        Event.current.Use();
                    }
                    if (i == editGroup)
                    {
                        soundGroups[i].name = GUILayout.TextField(soundGroups[i].name, GUILayout.MinWidth(Screen.width - 80f));
                    }
                    else
                    {
                        GUILayout.Label(soundGroups[i].name, (i == selectedGroup) ? EditorStyles.whiteLabel : EditorStyles.label, GUILayout.ExpandWidth(true));
                    }
                    GUILayout.FlexibleSpace();
                    if (GUILayout.Button(GUIContent.none, "OL Minus", GUILayout.Width(17f)))                            // minus button
                    {
                        if (EditorUtility.DisplayDialog("Delete '" + soundGroups[i].name + "'", "Are you sure you want to delete the selected sound group?", "Continue", "Cancel"))
                        {
                            soundGroups.RemoveAt(i);
                            MarkDirty();
                        }
                    }
                }
                EditorGUILayout.EndHorizontal();
                // build a list of items
                Rect lastRect = GUILayoutUtility.GetLastRect();
                if (e.type == EventType.Repaint)
                {
                    groups.Add(new ItemRect(i, lastRect, null));
                }
                if ((e.type == EventType.MouseDown) && lastRect.Contains(e.mousePosition))
                {
                    if ((i != selectedGroup) || (e.clickCount == 2))
                    {
                        nextGroup = i;
                        if (e.clickCount == 2)
                        {
                            editGroup = i;
                        }
                        else if (editGroup != nextGroup)
                        {
                            editGroup = -1;
                        }
                        Repaint();
                    }
                }
            }
            // add the final plus button
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (GUILayout.Button(GUIContent.none, "OL Plus", GUILayout.Width(17f)))                     // plus button
            {
                soundGroups.Add(new SoundGroup("unnamed sound group"));
                selectedGroup = editGroup = soundGroups.size - 1;
                MarkDirty();
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();

            // reset the color
            GUI.contentColor = defaultColor;

            // the sort and import buttons
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Sort", GUILayout.Width(70f)))
            {
                soundGroups.Sort(delegate(SoundGroup sg1, SoundGroup sg2) { return(string.Compare(sg1.name, sg2.name)); });
                MarkDirty();
            }
            EditorGUILayout.EndHorizontal();

            // draw a rect around the selected item
            if ((selectedGroup >= 0) && (selectedGroup < groups.size))
            {
                EditorGUI.DrawRect(groups[selectedGroup].rect, new Color(1f, 1f, 1f, 0.06f));
            }

            // finally move the sound groups back into the audio manager
            if (soundGroups.size > 0)
            {
                audioManager.soundGroupings = soundGroups.ToArray();
            }

            // calculate the drop area rect
            if ((e.type == EventType.Repaint) && (groups.size > 0))
            {
                dropArea.x      = groups[0].rect.x;
                dropArea.y      = groups[0].rect.y;
                dropArea.width  = groups[0].rect.width;
                dropArea.height = (groups[groups.size - 1].rect.y - groups[0].rect.y) + groups[groups.size - 1].rect.height;
            }
        }
        // draw the sound group properties now
        DrawSoundGroupProperties();

        EndContents();

        EditorGUILayout.HelpBox("Create and delete sound groups by clicking + and - respectively.  Double click to rename sound groups.  Drag and drop sounds from below to the groups above to move them.", MessageType.Info);
    }
Exemple #19
0
        internal void EndContactTesting()
        {
            newContacts.Clear(true);
            updatedContacts.Clear(true);
            removedContacts.Clear(true);

            foreach (var currentFrameContact in currentFrameContacts)
            {
                if (!previousFrameContacts.Contains(currentFrameContact))
                {
                    newContacts.Add(currentFrameContact);
                }
                else
                {
                    updatedContacts.Add(currentFrameContact);
                }
            }

            foreach (var previousFrameContact in previousFrameContacts)
            {
                if (!currentFrameContacts.Contains(previousFrameContact))
                {
                    removedContacts.Add(previousFrameContact);
                }
            }

            foreach (var contact in newContacts)
            {
                var obj0       = BulletSharp.CollisionObject.GetManaged(contact.ColliderA);
                var obj1       = BulletSharp.CollisionObject.GetManaged(contact.ColliderB);
                var component0 = (PhysicsComponent)obj0.UserObject;
                var component1 = (PhysicsComponent)obj1.UserObject;

                Collision existingPair = null;
                foreach (var x in component0.Collisions)
                {
                    if (x.InternalEquals(component0, component1))
                    {
                        existingPair = x;
                        break;
                    }
                }
                if (existingPair != null)
                {
                    if (existingPair.Contacts.Contains(contact))
                    {
#if DEBUG
                        //should not happen?
                        throw new Exception("Contact already added.");
#else
                        continue;
#endif
                    }

                    existingPair.Contacts.Add(contact);
                }
                else
                {
                    var newPair = new Collision(component0, component1);
                    newPair.Contacts.Add(contact);
                    component0.Collisions.Add(newPair);
                    component1.Collisions.Add(newPair);

                    contactToCollision.Add(contact, newPair);

                    newCollisionsCache.Add(newPair);
                    newContactsFastCache.Add(contact);
                }
            }

            foreach (var contact in updatedContacts)
            {
                var obj0       = BulletSharp.CollisionObject.GetManaged(contact.ColliderA);
                var obj1       = BulletSharp.CollisionObject.GetManaged(contact.ColliderB);
                var component0 = (PhysicsComponent)obj0.UserObject;
                var component1 = (PhysicsComponent)obj1.UserObject;

                Collision existingPair = null;
                foreach (var x in component0.Collisions)
                {
                    if (x.InternalEquals(component0, component1))
                    {
                        existingPair = x;
                        break;
                    }
                }
                if (existingPair != null)
                {
                    if (existingPair.Contacts.Contains(contact))
                    {
                        //update data values (since comparison is only at pointer level internally)
                        existingPair.Contacts.Remove(contact);
                        existingPair.Contacts.Add(contact);
                        updatedContactsCache.Add(contact);
                    }
                    else
                    {
#if DEBUG
                        //should not happen?
                        throw new Exception("Contact not in pair.");
#endif
                    }
                }
                else
                {
#if DEBUG
                    //should not happen?
                    throw new Exception("Pair not present.");
#endif
                }
            }

            foreach (var contact in removedContacts)
            {
                var obj0       = BulletSharp.CollisionObject.GetManaged(contact.ColliderA);
                var obj1       = BulletSharp.CollisionObject.GetManaged(contact.ColliderB);
                var component0 = (PhysicsComponent)obj0.UserObject;
                var component1 = (PhysicsComponent)obj1.UserObject;

                ContactRemoval(contact, component0, component1);
            }
        }
Exemple #20
0
        /// <summary>
        /// Draw this effect mesh.
        /// </summary>
        public void Draw(RenderContext context)
        {
            // Retrieve effect parameters
            var mesh = Mesh;
            var currentRenderData = mesh.Draw;
            var material          = Material;
            var vao       = vertexArrayObject;
            var drawCount = currentRenderData.DrawCount;

            parameters.Set(TransformationKeys.World, WorldMatrix);

            // TODO: We should clarify exactly how to override rasterizer states. Currently setup here on Context.Parameters to allow Material/ModelComponent overrides, but this is ugly
            context.Parameters.Set(Effect.RasterizerStateKey, RasterizerState);

            if (context.IsPicking()) // TODO move this code corresponding to picking outside of the runtime code!
            {
                parameters.Set(ModelComponentPickingShaderKeys.ModelComponentId, new Color4(RenderModel.ModelComponent.Id));
                parameters.Set(ModelComponentPickingShaderKeys.MeshId, new Color4(Mesh.NodeIndex));
                parameters.Set(ModelComponentPickingShaderKeys.MaterialId, new Color4(Mesh.MaterialIndex));

                // Don't use the materials blend state on picking targets
                parameters.Set(Effect.BlendStateKey, null);
            }

            if (material != null && material.TessellationMethod != ParadoxTessellationMethod.None)
            {
                var tessellationMethod = material.TessellationMethod;

                // adapt the primitive type and index buffer to the tessellation used
                if (tessellationMethod.PerformsAdjacentEdgeAverage())
                {
                    vao       = GetOrCreateVertexArrayObjectAEN(context);
                    drawCount = 12 / 3 * drawCount;
                }
                currentRenderData.PrimitiveType = tessellationMethod.GetPrimitiveType();
            }

            //using (Profiler.Begin(ProfilingKeys.PrepareMesh))
            {
                // Order of application of parameters:
                // - RenderPass.Parameters
                // - ModelComponent.Parameters
                // - RenderMesh.Parameters (originally copied from mesh parameters)
                // The order is based on the granularity level of each element and how shared it can be. Material is heavily shared, a model contains many meshes. An renderMesh is unique.
                // TODO: really copy mesh parameters into renderMesh instead of just referencing the meshDraw parameters.

                //var modelComponent = RenderModel.ModelComponent;
                //var hasModelComponentParams = modelComponent != null && modelComponent.Parameters != null;

                //var materialParameters = material != null && material.Parameters != null ? material.Parameters : null;

                parameterCollections.Clear();

                parameterCollections.Add(context.Parameters);
                FillParameterCollections(parameterCollections);

                // Check if we need to recreate the EffectParameterCollectionGroup
                // TODO: We can improve performance by redesigning FillParameterCollections to avoid ArrayExtensions.ArraysReferenceEqual (or directly check the appropriate parameter collections)
                // This also happens in another place: DynamicEffectCompiler (we probably want to factorize it when doing additional optimizations)
                if (parameterCollectionGroup == null || parameterCollectionGroup.Effect != Effect || !ArrayExtensions.ArraysReferenceEqual(previousParameterCollections, parameterCollections))
                {
                    parameterCollectionGroup     = new EffectParameterCollectionGroup(context.GraphicsDevice, Effect, parameterCollections);
                    previousParameterCollections = parameterCollections.ToArray();
                }

                Effect.Apply(context.GraphicsDevice, parameterCollectionGroup, true);
            }

            //using (Profiler.Begin(ProfilingKeys.RenderMesh))
            {
                if (currentRenderData != null)
                {
                    var graphicsDevice = context.GraphicsDevice;

                    graphicsDevice.SetVertexArrayObject(vao);

                    if (currentRenderData.IndexBuffer == null)
                    {
                        graphicsDevice.Draw(currentRenderData.PrimitiveType, drawCount, currentRenderData.StartLocation);
                    }
                    else
                    {
                        graphicsDevice.DrawIndexed(currentRenderData.PrimitiveType, drawCount, currentRenderData.StartLocation);
                    }
                }
            }
        }
Exemple #21
0
        public static void CreateSplineMesh(SplineMeshComponent component, FastList <VertexPositionNormalTangentColorTexture> vertices, FastList <int> indices)
        {
            var children = component.Entity.Transform.Children;

            if (children.Count < 2 || component.Width <= 0.0f)
            {
                return;
            }

            var points = SplineEvaluator.GetPoints(component, children);

            var indexCount  = 0;
            var vertexCount = 0;

            vertices.Clear();
            indices.Clear();

            // Align points to terrain if needed
            var terrain = component.Terrain;

            if (terrain != null)
            {
                for (var i = 0; i < points.Count; i++)
                {
                    SetHeight(terrain, component.HeightOffset, ref points.Items[i]);
                }
            }

            // Generate spline mesh
            float totalDistance = 0.0f;
            var   halfWidth     = component.Width * 0.5f;

            for (var i = 0; i < points.Count; i++)
            {
                // Calculate forward direction
                var forward = Vector3.Zero;
                if (i < points.Count - 1)
                {
                    forward += points[i + 1] - points[i];
                }
                if (i > 0)
                {
                    forward += points[i] - points[i - 1];
                }
                forward.Normalize();

                var right = Vector3.Cross(forward, Vector3.UnitY);
                var left  = -right;

                var p0 = points[i] + left * halfWidth;
                var p1 = points[i];
                var p2 = points[i] + right * halfWidth;

                // Align to terrain if needed
                if (terrain != null)
                {
                    SetHeight(terrain, component.HeightOffset, ref p0);
                    SetHeight(terrain, component.HeightOffset, ref p1);
                    SetHeight(terrain, component.HeightOffset, ref p2);
                }

                // Calculate UV coordinates
                float uvY = 0.0f;
                if (i > 0)
                {
                    var distance = (points[i] - points[i - 1]).Length();
                    totalDistance += distance;

                    uvY = totalDistance / component.SegmentUVLength;
                }

                // Calculate color
                var color = Color.White;

                // Alpha fades out at edges
                if (i == 0 || i == points.Count - 1)
                {
                    color.A = 0;
                }

                // Store forward direction in RGB
                var forwardBiasedAndScaled = ((forward + 1.0f) / 2.0f) * 255.0f;
                color.R = (byte)forwardBiasedAndScaled.X;
                color.G = (byte)forwardBiasedAndScaled.Y;
                color.B = (byte)forwardBiasedAndScaled.Z;

                vertices.Add(new VertexPositionNormalTangentColorTexture(p0, Vector3.UnitY, Vector3.UnitZ, color, new Vector2(0.0f, uvY)));
                vertices.Add(new VertexPositionNormalTangentColorTexture(p1, Vector3.UnitY, Vector3.UnitZ, color, new Vector2(0.5f, uvY)));
                vertices.Add(new VertexPositionNormalTangentColorTexture(p2, Vector3.UnitY, Vector3.UnitZ, color, new Vector2(1.0f, uvY)));

                if (i < points.Count - 1)
                {
                    indices.Add(vertexCount + 0);
                    indices.Add(vertexCount + 3);
                    indices.Add(vertexCount + 1);

                    indices.Add(vertexCount + 1);
                    indices.Add(vertexCount + 3);
                    indices.Add(vertexCount + 4);

                    indices.Add(vertexCount + 1);
                    indices.Add(vertexCount + 4);
                    indices.Add(vertexCount + 2);

                    indices.Add(vertexCount + 2);
                    indices.Add(vertexCount + 4);
                    indices.Add(vertexCount + 5);
                }

                vertexCount += 3;
                indexCount  += 12;
            }
        }
        private unsafe object ExportAnimation(ICommandContext commandContext, ContentManager contentManager)
        {
            // Read from model file
            var modelSkeleton = LoadSkeleton(commandContext, contentManager); // we get model skeleton to compare it to real skeleton we need to map to

            AdjustSkeleton(modelSkeleton);

            TimeSpan duration;
            var      animationClips = LoadAnimation(commandContext, contentManager, out duration);

            // Fix the animation frames
            double startFrameSeconds = StartFrame.TotalSeconds;
            double endFrameSeconds   = EndFrame.TotalSeconds;
            var    startTime         = CompressedTimeSpan.FromSeconds(-startFrameSeconds);

            foreach (var clip in animationClips)
            {
                foreach (var animationCurve in clip.Value.Curves)
                {
                    animationCurve.ShiftKeys(startTime);
                }
            }

            var durationTimeSpan = TimeSpan.FromSeconds((endFrameSeconds - startFrameSeconds));

            if (duration > durationTimeSpan)
            {
                duration = durationTimeSpan;
            }

            AnimationClip animationClip = null;

            if (animationClips.Count > 0)
            {
                animationClip          = new AnimationClip();
                animationClip.Duration = duration;

                AnimationClip rootMotionAnimationClip = null;

                // If root motion is explicitely enabled, or if there is no skeleton, try to find root node and apply animation directly on TransformComponent
                if ((AnimationRootMotion || SkeletonUrl == null) && modelSkeleton.Nodes.Length >= 1)
                {
                    // No skeleton, map root node only
                    // TODO: For now, it seems to be located on node 1 in FBX files. Need to check if always the case, and what happens with Assimp
                    var rootNode0 = modelSkeleton.Nodes.Length >= 1 ? modelSkeleton.Nodes[0].Name : null;
                    var rootNode1 = modelSkeleton.Nodes.Length >= 2 ? modelSkeleton.Nodes[1].Name : null;
                    if ((rootNode0 != null && animationClips.TryGetValue(rootNode0, out rootMotionAnimationClip)) ||
                        (rootNode1 != null && animationClips.TryGetValue(rootNode1, out rootMotionAnimationClip)))
                    {
                        foreach (var channel in rootMotionAnimationClip.Channels)
                        {
                            var curve = rootMotionAnimationClip.Curves[channel.Value.CurveIndex];

                            // Root motion
                            var channelName = channel.Key;
                            if (channelName.StartsWith("Transform."))
                            {
                                animationClip.AddCurve($"[TransformComponent.Key]." + channelName.Replace("Transform.", string.Empty), curve);
                            }

                            // Also apply Camera curves
                            // TODO: Add some other curves?
                            if (channelName.StartsWith("Camera."))
                            {
                                animationClip.AddCurve($"[CameraComponent.Key]." + channelName.Replace("Camera.", string.Empty), curve);
                            }
                        }
                    }
                }

                // Load asset reference skeleton
                if (SkeletonUrl != null)
                {
                    var skeleton        = contentManager.Load <Skeleton>(SkeletonUrl);
                    var skeletonMapping = new SkeletonMapping(skeleton, modelSkeleton);

                    // Process missing nodes
                    foreach (var nodeAnimationClipEntry in animationClips)
                    {
                        var nodeName          = nodeAnimationClipEntry.Key;
                        var nodeAnimationClip = nodeAnimationClipEntry.Value;
                        var nodeIndex         = modelSkeleton.Nodes.IndexOf(x => x.Name == nodeName);

                        // Node doesn't exist in skeleton? skip it
                        if (nodeIndex == -1 || skeletonMapping.SourceToSource[nodeIndex] != nodeIndex)
                        {
                            continue;
                        }

                        // Skip root motion node (if any)
                        if (nodeAnimationClip == rootMotionAnimationClip)
                        {
                            continue;
                        }

                        // Find parent node
                        var parentNodeIndex = modelSkeleton.Nodes[nodeIndex].ParentIndex;

                        if (parentNodeIndex != -1 && skeletonMapping.SourceToSource[parentNodeIndex] != parentNodeIndex)
                        {
                            // Some nodes were removed, we need to concat the anim curves
                            var currentNodeIndex = nodeIndex;
                            var nodesToMerge     = new List <Tuple <ModelNodeDefinition, AnimationBlender, AnimationClipEvaluator> >();
                            while (currentNodeIndex != -1 && currentNodeIndex != skeletonMapping.SourceToSource[parentNodeIndex])
                            {
                                AnimationClip          animationClipToMerge;
                                AnimationClipEvaluator animationClipEvaluator = null;
                                AnimationBlender       animationBlender       = null;
                                if (animationClips.TryGetValue(modelSkeleton.Nodes[currentNodeIndex].Name, out animationClipToMerge))
                                {
                                    animationBlender       = new AnimationBlender();
                                    animationClipEvaluator = animationBlender.CreateEvaluator(animationClipToMerge);
                                }
                                nodesToMerge.Add(Tuple.Create(modelSkeleton.Nodes[currentNodeIndex], animationBlender, animationClipEvaluator));
                                currentNodeIndex = modelSkeleton.Nodes[currentNodeIndex].ParentIndex;
                            }

                            // Put them in proper parent to children order
                            nodesToMerge.Reverse();

                            // Find all key times
                            // TODO: We should detect discontinuities and keep them
                            var animationKeysSet = new HashSet <CompressedTimeSpan>();

                            foreach (var node in nodesToMerge)
                            {
                                if (node.Item3 != null)
                                {
                                    foreach (var curve in node.Item3.Clip.Curves)
                                    {
                                        foreach (CompressedTimeSpan time in curve.Keys)
                                        {
                                            animationKeysSet.Add(time);
                                        }
                                    }
                                }
                            }

                            // Sort key times
                            var animationKeys = animationKeysSet.ToList();
                            animationKeys.Sort();

                            var animationOperations = new FastList <AnimationOperation>();

                            var combinedAnimationClip = new AnimationClip();

                            var translationCurve = new AnimationCurve <Vector3>();
                            var rotationCurve    = new AnimationCurve <Quaternion>();
                            var scaleCurve       = new AnimationCurve <Vector3>();

                            // Evaluate at every key frame
                            foreach (var animationKey in animationKeys)
                            {
                                var matrix = Matrix.Identity;

                                // Evaluate node
                                foreach (var node in nodesToMerge)
                                {
                                    // Needs to be an array in order for it to be modified by the UpdateEngine, otherwise it would get passed by value
                                    var modelNodeDefinitions = new ModelNodeDefinition[1] {
                                        node.Item1
                                    };

                                    if (node.Item2 != null && node.Item3 != null)
                                    {
                                        // Compute
                                        AnimationClipResult animationClipResult = null;
                                        animationOperations.Clear();
                                        animationOperations.Add(AnimationOperation.NewPush(node.Item3, animationKey));
                                        node.Item2.Compute(animationOperations, ref animationClipResult);

                                        var updateMemberInfos = new List <UpdateMemberInfo>();
                                        foreach (var channel in animationClipResult.Channels)
                                        {
                                            updateMemberInfos.Add(new UpdateMemberInfo {
                                                Name = "[0]." + channel.PropertyName, DataOffset = channel.Offset
                                            });
                                        }

                                        // TODO: Cache this
                                        var compiledUpdate = UpdateEngine.Compile(typeof(ModelNodeDefinition[]), updateMemberInfos);

                                        fixed(byte *data = animationClipResult.Data)
                                        {
                                            UpdateEngine.Run(modelNodeDefinitions, compiledUpdate, (IntPtr)data, null);
                                        }
                                    }

                                    Matrix localMatrix;
                                    var    transformTRS = modelNodeDefinitions[0].Transform;
                                    Matrix.Transformation(ref transformTRS.Scale, ref transformTRS.Rotation, ref transformTRS.Position,
                                                          out localMatrix);
                                    matrix = Matrix.Multiply(localMatrix, matrix);
                                }

                                // Done evaluating, let's decompose matrix
                                TransformTRS transform;
                                matrix.Decompose(out transform.Scale, out transform.Rotation, out transform.Position);

                                // Create a key
                                translationCurve.KeyFrames.Add(new KeyFrameData <Vector3>(animationKey, transform.Position));
                                rotationCurve.KeyFrames.Add(new KeyFrameData <Quaternion>(animationKey, transform.Rotation));
                                scaleCurve.KeyFrames.Add(new KeyFrameData <Vector3>(animationKey, transform.Scale));
                            }

                            combinedAnimationClip.AddCurve($"{nameof(ModelNodeTransformation.Transform)}.{nameof(TransformTRS.Position)}", translationCurve);
                            combinedAnimationClip.AddCurve($"{nameof(ModelNodeTransformation.Transform)}.{nameof(TransformTRS.Rotation)}", rotationCurve);
                            combinedAnimationClip.AddCurve($"{nameof(ModelNodeTransformation.Transform)}.{nameof(TransformTRS.Scale)}", scaleCurve);
                            nodeAnimationClip = combinedAnimationClip;
                        }

                        var transformStart    = $"{nameof(ModelNodeTransformation.Transform)}.";
                        var transformPosition = $"{nameof(ModelNodeTransformation.Transform)}.{nameof(TransformTRS.Position)}";

                        foreach (var channel in nodeAnimationClip.Channels)
                        {
                            var curve = nodeAnimationClip.Curves[channel.Value.CurveIndex];

                            // TODO: Root motion
                            var channelName = channel.Key;
                            if (channelName.StartsWith(transformStart))
                            {
                                if (channelName == transformPosition)
                                {
                                    // Translate node with parent 0 using PivotPosition
                                    var keyFrames = ((AnimationCurve <Vector3>)curve).KeyFrames;
                                    for (int i = 0; i < keyFrames.Count; ++i)
                                    {
                                        if (parentNodeIndex == 0)
                                        {
                                            keyFrames.Items[i].Value -= PivotPosition;
                                        }
                                        keyFrames.Items[i].Value *= ScaleImport;
                                    }
                                }
                                animationClip.AddCurve($"[ModelComponent.Key].Skeleton.NodeTransformations[{skeletonMapping.SourceToTarget[nodeIndex]}]." + channelName, curve);
                            }
                        }
                    }
                }
            }

            if (animationClip == null)
            {
                commandContext.Logger.Info($"File {SourcePath} has an empty animation.");
            }
            else
            {
                if (animationClip.Duration.Ticks == 0)
                {
                    commandContext.Logger.Verbose($"File {SourcePath} has a 0 tick long animation.");
                }

                // Optimize and set common parameters
                animationClip.RepeatMode = AnimationRepeatMode;
                animationClip.Optimize();
            }
            return(animationClip);
        }
Exemple #23
0
        private void BuildVaosForLight(Light light, LightVaos lightVaos)
        {
            _hullVertices.Clear();
            _shadowVertices.Clear();
            _shadowIndices.Clear();
            _hullIndices.Clear();

            int numSegments       = 0;
            int shadowIndexOffset = 0;
            int hullIndexOffset   = 0;
            int hullCount         = _engine.Hulls.Count;

            for (int i = 0; i < hullCount; i++)
            {
                Hull hull = _engine.Hulls[i];
                if (!hull.Enabled ||
                    !hull.Valid ||
                    light.IgnoredHulls.Contains(hull) ||
                    !light.Intersects(hull))
                {
                    continue;
                }

                Polygon points = hull.WorldPoints;

                Vector2 prevPoint = points.Items[points.Count - 1];

                int pointCount = points.Count;
                numSegments += pointCount;
                for (int j = 0; j < pointCount; j++)
                {
                    Vector2 currentPoint = points.Items[j];

                    _shadowVertices.Add(new VertexShadow(prevPoint, currentPoint, new Vector2(0.0f, 0.0f)));
                    _shadowVertices.Add(new VertexShadow(prevPoint, currentPoint, new Vector2(1.0f, 0.0f)));
                    _shadowVertices.Add(new VertexShadow(prevPoint, currentPoint, new Vector2(0.0f, 1.0f)));
                    _shadowVertices.Add(new VertexShadow(prevPoint, currentPoint, new Vector2(1.0f, 1.0f)));

                    _shadowIndices.Add(shadowIndexOffset * 4 + 0);
                    _shadowIndices.Add(shadowIndexOffset * 4 + 1);
                    _shadowIndices.Add(shadowIndexOffset * 4 + 2);

                    _shadowIndices.Add(shadowIndexOffset * 4 + 1);
                    _shadowIndices.Add(shadowIndexOffset * 4 + 3);
                    _shadowIndices.Add(shadowIndexOffset * 4 + 2);

                    prevPoint = currentPoint;
                    shadowIndexOffset++;
                }

                _hullVertices.AddRange(hull.WorldPoints);

                int indexCount = hull.Indices.Count;
                for (int j = 0; j < indexCount; j++)
                {
                    _hullIndices.Add(hull.Indices.Items[j] + hullIndexOffset);
                }
                hullIndexOffset += pointCount;
            }

            lightVaos.Enabled = numSegments > 0;
            if (!lightVaos.Enabled)
            {
                return;
            }

            if (lightVaos.ShadowVao == null)
            {
                lightVaos.ShadowVao = DynamicVao.New(
                    _engine.Device,
                    VertexShadow.Layout,
                    PrimitiveType.TriangleList,
                    _shadowVertices.Count,
                    _shadowIndices.Count,
                    useIndices: true);
                lightVaos.HullVao = DynamicVao.New(
                    _engine.Device,
                    VertexPosition2.Layout,
                    PrimitiveType.TriangleList,
                    _hullVertices.Count,
                    _hullIndices.Count,
                    useIndices: true);
            }

            lightVaos.ShadowVao.SetVertices(_shadowVertices);
            lightVaos.ShadowVao.SetIndices(_shadowIndices);
            lightVaos.HullVao.SetVertices(_hullVertices);
            lightVaos.HullVao.SetIndices(_hullIndices);
        }
        private void CollectVisiblePages(TerrainVegetationRenderData renderData, TerrainVegetationComponent component, CameraComponent camera)
        {
            renderData.TransformData.Clear();

            if (camera == null || renderData.Pages == null)
            {
                return;
            }

            var cameraPosition = camera.GetWorldPosition();

            cameraPosition.Y = 0.0f; // Only cull in xz plane

            var maxPageDistance = component.ViewDistance + PageSize;

            _activesPages.Clear();
            for (var i = 0; i < renderData.Pages.Length; i++)
            {
                var page = renderData.Pages[i];
                if (page.Instances == null) // Skip uninitialized pages
                {
                    continue;
                }

                var distance = (cameraPosition - page.WorldPosition).Length();
                if (distance < maxPageDistance)
                {
                    _activesPages.Add(page);
                }
            }

            // Reset camera position for individual instance culling
            cameraPosition = camera.GetWorldPosition();

            float maxDistance   = component.ViewDistance;
            float minDistance   = maxDistance * 0.8f;
            float distanceRange = maxDistance - minDistance;

            // TODO: concurrency??? That would probably be a good thing here
            var maxInstanceDistanceSquared = component.ViewDistance * component.ViewDistance;

            foreach (var page in _activesPages)
            {
                for (var p = 0; p < page.Instances.Count; p++)
                {
                    var distance = (cameraPosition - page.Instances[p].TranslationVector).LengthSquared();
                    //if (distance < maxInstanceDistanceSquared)
                    {
                        var worldMatrix = page.Instances[p];

                        if (component.UseDistanceScaling)
                        {
                            // Fade out the mesh by scaling it, this could be done in the shader for more speeeed
                            var distanceToCamera = Math.Max(0.0f, (cameraPosition - worldMatrix.TranslationVector).Length() - minDistance);
                            var relativeScale    = Math.Min(1.0f, distanceToCamera / distanceRange);

                            var distanceScale = (float)MathUtil.Lerp(1.0f, 0.0f, Math.Pow(relativeScale, 2.0f));
                            var scale         = Matrix.Scaling(distanceScale);

                            renderData.TransformData.Add(scale * worldMatrix);
                        }
                        else
                        {
                            renderData.TransformData.Add(worldMatrix);
                        }
                    }
                }
            }
        }
Exemple #25
0
 /// <summary>
 /// resets the bezier removing all points
 /// </summary>
 public void Reset()
 {
     _points.Clear();
 }
Exemple #26
0
        public override void Load()
        {
            base.Load();

            if (OfflineCompilation)
            {
                return;
            }

            var renderTargets = new RenderTarget[2];
            DepthStencilBuffer depthStencilBuffer  = null;
            Texture2D          depthStencilTexture = null;

            Parameters.AddSources(MainPlugin.ViewParameters);

            Parameters.RegisterParameter(EffectPlugin.BlendStateKey);

            var filteredPasses = new FastList <RenderPass>();

            RenderPass.UpdatePasses += updatePassesAction = (RenderPass currentRenderPass, ref FastList <RenderPass> currentPasses) =>
            {
                var originalPasses = currentPasses;
                filteredPasses.Clear();
                currentPasses = filteredPasses;

                Parameters.Set(PickingFrameIndex, ++currentPickingFrameIndex);
                Request[] requests;

                lock (pendingRequests)
                {
                    // No picking request or no mesh to pick?
                    if (pendingRequests.Count == 0)
                    {
                        return;
                    }

                    requests = pendingRequests.ToArray();
                    pendingRequests.Clear();
                }

                foreach (var request in requests)
                {
                    requestResults.Add(request);
                }

                if (originalPasses == null)
                {
                    return;
                }

                // Count mesh passes
                int meshIndex = 0;
                foreach (var pass in originalPasses)
                {
                    meshIndex += pass.Passes.Count;
                }

                // No mesh to pick?
                if (meshIndex == 0)
                {
                    return;
                }

                // Copy mesh passes and assign indices
                var meshPasses = new EffectMesh[meshIndex];
                meshIndex = 0;
                foreach (var pass in RenderPass.Passes)
                {
                    throw new NotImplementedException();
                    //foreach (var effectMeshPass in pass.Meshes)
                    //{
                    //    meshPasses[meshIndex] = (EffectMesh)effectMeshPass;
                    //    // Prefix increment so that 0 means no rendering.
                    //    effectMeshPass.Parameters.Set(PickingMeshIndex, ++meshIndex);
                    //}
                }

                // For now, it generates one rendering per picking.
                // It would be quite easy to optimize it by make Picking shader works on multiple picking points at a time.
                foreach (var request in requests)
                {
                    var pickingRenderPass = new RenderPass("Picking");

                    pickingRenderPass.StartPass.AddFirst = (threadContext) =>
                    {
                        threadContext.GraphicsDevice.Clear(renderTargets[0], Color.Black);
                        threadContext.GraphicsDevice.Clear(renderTargets[1], Color.Black);
                        threadContext.Parameters.Set(PickingScreenPosition, request.Location);
                        threadContext.GraphicsDevice.SetViewport(new Viewport(0, 0, renderTargets[0].Description.Width, renderTargets[0].Description.Height));

                        threadContext.GraphicsDevice.Clear(depthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
                        threadContext.GraphicsDevice.SetRenderTargets(depthStencilBuffer, renderTargets);
                    };
                    pickingRenderPass.EndPass.AddLast = (threadContext) =>
                    {
                        threadContext.Parameters.Reset(PickingScreenPosition);
                        threadContext.GraphicsDevice.Copy(renderTargets[0].Texture, request.ResultTextures[0]);
                        threadContext.GraphicsDevice.Copy(renderTargets[1].Texture, request.ResultTextures[1]);
                    };
                    //pickingRenderPass.PassesInternal = originalPasses;
                    throw new NotImplementedException();

                    request.MeshPasses = meshPasses;

                    currentPasses.Add(pickingRenderPass);

                    request.HasResults = true;

                    // Wait 2 frames before pulling the results.
                    request.FrameCounter = 2;
                }
            };

            RenderSystem.GlobalPass.EndPass.AddLast = CheckPickingResults;

            var backBuffer = GraphicsDevice.BackBuffer;

            int pickingArea = 1 + PickingDistance * 2;

            renderTargets[0] = Texture.New2D(GraphicsDevice, pickingArea, pickingArea, PixelFormat.R32_UInt, TextureFlags.ShaderResource | TextureFlags.RenderTarget).ToRenderTarget().KeepAliveBy(ActiveObjects);
            renderTargets[1] = Texture.New2D(GraphicsDevice, pickingArea, pickingArea, PixelFormat.R32G32B32A32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).ToRenderTarget().KeepAliveBy(ActiveObjects);

            depthStencilTexture = Texture.New2D(GraphicsDevice, pickingArea, pickingArea, PixelFormat.D32_Float, TextureFlags.ShaderResource | TextureFlags.DepthStencil).KeepAliveBy(ActiveObjects);
            depthStencilBuffer  = depthStencilTexture.ToDepthStencilBuffer(false);

            Parameters.AddDynamic(PickingMatrix, ParameterDynamicValue.New(PickingScreenPosition, (ref Vector2 pickingPosition, ref Matrix picking) =>
            {
                // Move center to picked position, and zoom (it is supposed to stay per-pixel according to render target size)
                picking = Matrix.Translation(1.0f - (pickingPosition.X) / backBuffer.Width * 2.0f, -1.0f + (pickingPosition.Y) / backBuffer.Height * 2.0f, 0.0f)
                          * Matrix.Scaling((float)backBuffer.Width / (float)pickingArea, (float)backBuffer.Height / (float)pickingArea, 1.0f);
            }));
        }
Exemple #27
0
 public void Clear()
 {
     instancedVoxels.Clear();
 }
Exemple #28
0
            private AnimationClip SubtractAnimations(AnimationClip baseAnimation, AnimationClip sourceAnimation)
            {
                if (baseAnimation == null)
                {
                    throw new ArgumentNullException("baseAnimation");
                }
                if (sourceAnimation == null)
                {
                    throw new ArgumentNullException("sourceAnimation");
                }

                var animationBlender = new AnimationBlender();

                var baseEvaluator   = animationBlender.CreateEvaluator(baseAnimation);
                var sourceEvaluator = animationBlender.CreateEvaluator(sourceAnimation);

                // Create a result animation with same channels
                var resultAnimation = new AnimationClip();

                foreach (var channel in sourceAnimation.Channels)
                {
                    // Create new instance of curve
                    var newCurve = (AnimationCurve)Activator.CreateInstance(typeof(AnimationCurve <>).MakeGenericType(channel.Value.ElementType));

                    // Quaternion curve are linear, others are cubic
                    if (newCurve.ElementType != typeof(Quaternion))
                    {
                        newCurve.InterpolationType = AnimationCurveInterpolationType.Cubic;
                    }

                    resultAnimation.AddCurve(channel.Key, newCurve);
                }

                var resultEvaluator = animationBlender.CreateEvaluator(resultAnimation);

                var animationOperations = new FastList <AnimationOperation>();

                // Perform animation blending for each frame and upload results in a new animation
                // Note that it does a simple per-frame sampling, so animation discontinuities will be lost.
                // TODO: Framerate is hardcoded at 30 FPS.
                var frameTime = TimeSpan.FromSeconds(1.0f / 30.0f);

                for (var time = TimeSpan.Zero; time < sourceAnimation.Duration + frameTime; time += frameTime)
                {
                    // Last frame, round it to end of animation
                    if (time > sourceAnimation.Duration)
                    {
                        time = sourceAnimation.Duration;
                    }

                    TimeSpan baseTime;
                    switch (AssetParameters.Mode)
                    {
                    case AdditiveAnimationBaseMode.FirstFrame:
                        baseTime = TimeSpan.Zero;
                        break;

                    case AdditiveAnimationBaseMode.Animation:
                        baseTime = TimeSpan.FromTicks(time.Ticks % baseAnimation.Duration.Ticks);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    // Generates result = source - base
                    animationOperations.Clear();
                    animationOperations.Add(AnimationOperation.NewPush(sourceEvaluator, time));
                    animationOperations.Add(AnimationOperation.NewPush(baseEvaluator, baseTime));
                    animationOperations.Add(AnimationOperation.NewBlend(AnimationBlendOperation.Subtract, 1.0f));
                    animationOperations.Add(AnimationOperation.NewPop(resultEvaluator, time));

                    // Compute
                    AnimationClipResult animationClipResult = null;
                    animationBlender.Compute(animationOperations, ref animationClipResult);
                }

                resultAnimation.Duration   = sourceAnimation.Duration;
                resultAnimation.RepeatMode = sourceAnimation.RepeatMode;

                return(resultAnimation);
            }
Exemple #29
0
        /// <summary>
        /// Copies from original list to a new list based on treeindex values, based upon the flag sent.
        /// ie copies entries with 0 to 262144 only or that have 262144 to 'limit', or just all.
        /// </summary>
        /// <param name="orgBurningList">The orginal source list</param>
        /// <param name="bCopyFlag">0= CopyAllEntries; 1= 0 to 262144; 2= 262144 to 'limit'</param>
        /// <returns>a new FastList of treemanager.burningtrees, returns an empty list on none or error.</returns>
        public static FastList <TreeManager.BurningTree> CopyBurningTreesList(ref FastList <TreeManager.BurningTree> orgBurningList, byte bCopyFlag)
        {
            FastList <TreeManager.BurningTree> newlist = new FastList <TreeManager.BurningTree>();

            newlist.Clear();
            try
            {
                if (orgBurningList != null)
                {
                    int orgcount = orgBurningList.m_size;
                    newlist.EnsureCapacity(orgcount);
                    TreeManager.BurningTree tmpTree = new TreeManager.BurningTree();

                    int tmpcounter = 0;
                    int MinValue   = 0;
                    int MaxValue   = 0;
                    if (OptionsWrapper <Configuration> .Options.IsLoggingEnabled() && OptionsWrapper <Configuration> .Options.DebugLoggingLevel > 1)
                    {
                        Logger.dbgLog("CopyFlag = " + bCopyFlag.ToString());
                    }
                    switch (bCopyFlag)
                    {
                    //0-262144 mainserialze()
                    case 1:
                        MinValue = 0;
                        MaxValue = Mod.DEFAULT_TREE_COUNT;
                        break;

                    //262144 to activelimit  customserialze( not packed)
                    case 2:
                        MinValue = Mod.DEFAULT_TREE_COUNT;
                        MaxValue = LimitTreeManager.Helper.TreeLimit;
                        break;

                    //262144 to lastsavecount.count customseralize(packed)???
                    case 3:
                        MinValue = Mod.DEFAULT_TREE_COUNT;
                        MaxValue = LoadingExtension.LastSaveList.Count;
                        break;

                    //just copy all of them.
                    default:
                        MinValue = 0;
                        MaxValue = LimitTreeManager.Helper.TreeLimit;
                        break;
                    }
                    if (OptionsWrapper <Configuration> .Options.IsLoggingEnabled() && OptionsWrapper <Configuration> .Options.DebugLoggingLevel > 1)
                    {
                        Logger.dbgLog(string.Concat("copying from: ", MinValue.ToString(), " to ", MaxValue.ToString()));
                    }

                    if (OptionsWrapper <Configuration> .Options.IsLoggingEnabled() && OptionsWrapper <Configuration> .Options.DebugLoggingLevel > 1)
                    {
                        m_PerfMonitor.Reset(); m_PerfMonitor.Start();
                    }

                    foreach (TreeManager.BurningTree orgTree in orgBurningList)
                    {
                        if (orgTree.m_treeIndex > 0 && (orgTree.m_treeIndex >= MinValue & orgTree.m_treeIndex < MaxValue))
                        {
                            //copy tree
                            tmpTree.m_treeIndex     = orgTree.m_treeIndex;
                            tmpTree.m_fireDamage    = orgTree.m_fireDamage;
                            tmpTree.m_fireIntensity = orgTree.m_fireIntensity;
                            newlist.Add(tmpTree);
                            tmpcounter++;
                        }
                    }
                    newlist.Trim();
                    if (OptionsWrapper <Configuration> .Options.IsLoggingEnabled() && OptionsWrapper <Configuration> .Options.DebugLoggingLevel > 1)
                    {
                        m_PerfMonitor.Stop(); Logger.dbgLog(string.Concat("Copy time took (ticks):", m_PerfMonitor.ElapsedTicks.ToString()));
                    }
                    if (OptionsWrapper <Configuration> .Options.IsLoggingEnabled() && OptionsWrapper <Configuration> .Options.DebugLoggingLevel > 1)
                    {
                        Logger.dbgLog(string.Concat("orgCount(m_size):", orgcount.ToString(), " copycount:", tmpcounter.ToString()) + " new_msize:" + newlist.m_size.ToString());
                    }
                }
                else
                {
                    Logger.dbgLog("orgBurningList is Null!");
                    return(newlist);
                }
            }
            catch (Exception ex)
            { Logger.dbgLog(ex.ToString()); }

            return(newlist);
        }
Exemple #30
0
        protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
        {
            var viewport = drawContext.CommandList.Viewport;

            using (drawContext.PushRenderTargetsAndRestore())
            {
                // Render Shadow maps
                shadowMapRenderer?.Draw(drawContext);

                if (VRSettings.Enabled && VRSettings.VRDevice != null)
                {
                    var isFullViewport = (int)viewport.X == 0 && (int)viewport.Y == 0 &&
                                         (int)viewport.Width == drawContext.CommandList.RenderTarget.ViewWidth &&
                                         (int)viewport.Height == drawContext.CommandList.RenderTarget.ViewHeight;
                    if (!isFullViewport)
                    {
                        return;
                    }

                    var hasPostEffects = PostEffects != null; // When we have post effect we need to bind a different framebuffer for each view to be sure effects impinge on the other view.

                    Texture vrFullSurface;
                    using (drawContext.PushRenderTargetsAndRestore())
                    {
                        var currentRenderTarget     = drawContext.CommandList.RenderTarget;
                        var vrFullFrameSize         = VRSettings.VRDevice.ActualRenderFrameSize;
                        var desiredRenderTargetSize = !hasPostEffects ? vrFullFrameSize : new Size2(vrFullFrameSize.Width / 2, vrFullFrameSize.Height);
                        if (hasPostEffects || desiredRenderTargetSize.Width != currentRenderTarget.Width || desiredRenderTargetSize.Height != currentRenderTarget.Height)
                        {
                            drawContext.CommandList.SetRenderTargets(null, null); // force to create and bind a new render target
                        }
                        PrepareRenderTargets(drawContext, desiredRenderTargetSize);

                        //prepare the final VR target
                        vrFullSurface = ViewOutputTarget;
                        if (hasPostEffects)
                        {
                            var frameSize = VRSettings.VRDevice.ActualRenderFrameSize;
                            var renderTargetDescription = TextureDescription.New2D(frameSize.Width, frameSize.Height, 1, PixelFormat.R8G8B8A8_UNorm_SRgb, TextureFlags.ShaderResource | TextureFlags.RenderTarget);
                            vrFullSurface = PushScopedResource(drawContext.GraphicsContext.Allocator.GetTemporaryTexture2D(renderTargetDescription));
                        }

                        //draw per eye
                        using (context.SaveViewportAndRestore())
                            using (drawContext.PushRenderTargetsAndRestore())
                            {
                                ViewCount = 2;
                                bool isWindowsMixedReality = false;

                                for (var i = 0; i < 2; i++)
                                {
#if XENKO_GRAPHICS_API_DIRECT3D11 && XENKO_PLATFORM_UWP
                                    if (drawContext.GraphicsDevice.Presenter is WindowsMixedRealityGraphicsPresenter graphicsPresenter)
                                    {
                                        isWindowsMixedReality = true;

                                        MSAALevel = MultisampleCount.None;
                                        currentRenderTargets.Clear();

                                        if (i == 0)
                                        {
                                            currentRenderTargets.Add(graphicsPresenter.LeftEyeBuffer);
                                        }
                                        else
                                        {
                                            currentRenderTargets.Add(graphicsPresenter.RightEyeBuffer);
                                        }
                                    }
#endif

                                    drawContext.CommandList.SetRenderTargets(currentDepthStencil, currentRenderTargets.Count, currentRenderTargets.Items);

                                    if (!hasPostEffects && !isWindowsMixedReality) // need to change the viewport between each eye
                                    {
                                        var frameSize = VRSettings.VRDevice.ActualRenderFrameSize;
                                        drawContext.CommandList.SetViewport(new Viewport(i * frameSize.Width / 2, 0, frameSize.Width / 2, frameSize.Height));
                                    }
                                    else if (i == 0) // the viewport is the same for both eyes so we set it only once
                                    {
                                        drawContext.CommandList.SetViewport(new Viewport(0.0f, 0.0f, VRSettings.VRDevice.ActualRenderFrameSize.Width / 2.0f, VRSettings.VRDevice.ActualRenderFrameSize.Height));
                                    }

                                    using (context.PushRenderViewAndRestore(VRSettings.RenderViews[i]))
                                    {
                                        // Clear render target and depth stencil
                                        if (hasPostEffects || i == 0) // need to clear for each eye in the case we have two different render targets
                                        {
                                            Clear?.Draw(drawContext);
                                        }

                                        ViewIndex = i;

                                        DrawView(context, drawContext, i, 2);

                                        if (hasPostEffects) // copy the rendered view into the vr full view framebuffer
                                        {
                                            drawContext.CommandList.CopyRegion(ViewOutputTarget, 0, null, vrFullSurface, 0, VRSettings.VRDevice.ActualRenderFrameSize.Width / 2 * i);
                                        }
                                    }
                                }

                                if (VRSettings.VRDevice.SupportsOverlays)
                                {
                                    foreach (var overlay in VRSettings.Overlays)
                                    {
                                        if (overlay != null && overlay.Texture != null)
                                        {
                                            overlay.Overlay.UpdateSurface(drawContext.CommandList, overlay.Texture);
                                        }
                                    }
                                }

                                VRSettings.VRDevice.Commit(drawContext.CommandList, vrFullSurface);
                            }
                    }

                    //draw mirror to backbuffer (if size is matching and full viewport)
                    if (VRSettings.CopyMirror)
                    {
                        CopyOrScaleTexture(drawContext, VRSettings.VRDevice.MirrorTexture, drawContext.CommandList.RenderTarget);
                    }
                    else if (hasPostEffects)
                    {
                        CopyOrScaleTexture(drawContext, vrFullSurface, drawContext.CommandList.RenderTarget);
                    }
                }
                else
                {
                    PrepareRenderTargets(drawContext, new Size2((int)viewport.Width, (int)viewport.Height));

                    ViewCount = 1;
                    ViewIndex = 0;

                    //var sssMaterialIndexRenderTarget = GenerateSSSMaterialIndexRenderTarget(context, viewport);

                    using (drawContext.PushRenderTargetsAndRestore())
                    {
                        drawContext.CommandList.SetRenderTargets(currentDepthStencil, currentRenderTargets.Count, currentRenderTargets.Items);

                        // Clear render target and depth stencil
                        Clear?.Draw(drawContext);

                        DrawView(context, drawContext, 0, 1);
                    }
                }
            }

            // Clear intermediate results
            currentRenderTargets.Clear();
            currentRenderTargetsNonMSAA.Clear();
            currentDepthStencil        = null;
            currentDepthStencilNonMSAA = null;
        }
Exemple #31
0
        protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
        {
            var viewport = drawContext.CommandList.Viewport;

            using (drawContext.PushRenderTargetsAndRestore())
            {
                // Render Shadow maps
                shadowMapRenderer?.Draw(drawContext);

                if (VRSettings.Enabled && VRSettings.VRDevice != null)
                {
                    var isFullViewport = (int)viewport.X == 0 && (int)viewport.Y == 0 &&
                                         (int)viewport.Width == drawContext.CommandList.RenderTarget.ViewWidth &&
                                         (int)viewport.Height == drawContext.CommandList.RenderTarget.ViewHeight;
                    if (!isFullViewport)
                    {
                        return;
                    }

                    bool hasPostEffects = PostEffects != null, presentingVR = this == VRRenderers[VRRenderers.Count - 1];

                    Texture vrFullSurface;
                    using (drawContext.PushRenderTargetsAndRestore())
                    {
                        var currentRenderTarget     = drawContext.CommandList.RenderTarget;
                        var desiredRenderTargetSize = VRSettings.VRDevice.ActualRenderFrameSize;

                        if (desiredRenderTargetSize.Width != currentRenderTarget.Width || desiredRenderTargetSize.Height != currentRenderTarget.Height)
                        {
                            drawContext.CommandList.SetRenderTargets(null, null); // force to create and bind a new render target
                        }
                        PrepareRenderTargets(drawContext, desiredRenderTargetSize);

                        vrFullSurface = viewOutputTarget;

                        //draw per eye
                        using (context.SaveViewportAndRestore())
                            using (drawContext.PushRenderTargetsAndRestore())
                            {
                                ViewCount = 2;

                                for (var i = 0; i < 2; i++)
                                {
                                    drawContext.CommandList.SetRenderTargets(currentDepthStencil, currentRenderTargets.Count, currentRenderTargets.Items);

                                    var frameSize = VRSettings.VRDevice.ActualRenderFrameSize;
                                    drawContext.CommandList.SetViewport(new Viewport(i * frameSize.Width / 2, 0, frameSize.Width / 2, frameSize.Height));

                                    using (context.PushRenderViewAndRestore(VRSettings.RenderViews[i]))
                                    {
                                        // Clear render target and depth stencil
                                        if (i == 0)
                                        {
                                            Clear?.Draw(drawContext);
                                        }

                                        ViewIndex = i;

                                        // draw view, but skip post processing (it will not do it, since eye count > 1)
                                        DrawView(context, drawContext, i, 2);

                                        // last eye, draw post effects over both eyes if we have some
                                        if (hasPostEffects && i == 1)
                                        {
                                            if (presentingVR)
                                            {
                                                var renderTargetDescription = TextureDescription.New2D(frameSize.Width, frameSize.Height, 1, PixelFormat.R8G8B8A8_UNorm_SRgb, TextureFlags.ShaderResource | TextureFlags.RenderTarget);
                                                vrFullSurface = PushScopedResource(drawContext.GraphicsContext.Allocator.GetTemporaryTexture2D(renderTargetDescription));
                                            }

                                            PostEffects.Draw(drawContext, OpaqueRenderStage.OutputValidator, currentRenderTargets.Items, currentDepthStencil, vrFullSurface);
                                        }
                                    }
                                }

                                if (VRSettings.VRDevice.SupportsOverlays)
                                {
                                    foreach (var overlay in VRSettings.Overlays)
                                    {
                                        if (overlay != null && overlay.Texture != null)
                                        {
                                            overlay.Overlay.UpdateSurface(drawContext.CommandList, overlay.Texture);
                                        }
                                    }
                                }

                                // if we are on our last forward renderer and our scene is ready for submission
                                if (presentingVR)
                                {
                                    VRSettings.VRDevice.Commit(drawContext.CommandList, vrFullSurface);
                                }
                            }
                    }

                    //draw mirror if desired
                    if (VRSettings.CopyMirror)
                    {
                        CopyOrScaleTexture(drawContext, vrFullSurface, drawContext.CommandList.RenderTarget);
                    }
                }
                else
                {
                    PrepareRenderTargets(drawContext, new Size2((int)viewport.Width, (int)viewport.Height));

                    ViewCount = 1;
                    ViewIndex = 0;

                    //var sssMaterialIndexRenderTarget = GenerateSSSMaterialIndexRenderTarget(context, viewport);

                    using (drawContext.PushRenderTargetsAndRestore())
                    {
                        drawContext.CommandList.SetRenderTargets(currentDepthStencil, currentRenderTargets.Count, currentRenderTargets.Items);

                        // Clear render target and depth stencil
                        Clear?.Draw(drawContext);

                        DrawView(context, drawContext, 0, 1);
                    }
                }
            }

            // Clear intermediate results
            currentRenderTargets.Clear();
            currentRenderTargetsNonMSAA.Clear();
            currentDepthStencil        = null;
            currentDepthStencilNonMSAA = null;
        }
Exemple #32
0
 public static void CleanPropertyArrayOffset()
 {
     _propertyArrayOffset = null;
     _intBuffer?.Clear();
     _intBuffer = null;
 }
Exemple #33
0
        void GenerateChunkMesh(Int3 pos, ref Chunk c, ref ChunkData data)
        {
            if (verts == null)
            {
                verts = new FastList <VertexPositionNormalColor>();
            }
            if (indices == null)
            {
                indices = new FastList <ushort>();
            }

            void CheckChunkMeshData()
            {
            }

            void GenerateBox(ref Chunk chunk, int x, int z, int y)
            {
                if ((Block.Type)chunk[x, y, z] == Block.Type.Air)
                {
                    return;
                }

                {
                    // bottom face
                    if ((Block.Type)chunk[x, y - 1, z] == Block.Type.Air)
                    {
                        // bottom left
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(0.0f + x, -1.0f + y, 0.0f + z),
                            Normal   = new Vector3(0.0f, -1.0f, 0.0f),
                            Color    = Color.Red
                        });

                        // top left
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(0.0f + x, -1.0f + y, 1.0f + z),
                            Normal   = new Vector3(0.0f, -1.0f, 0.0f),
                            Color    = Color.Red
                        });

                        // top right
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(1.0f + x, -1.0f + y, 1.0f + z),
                            Normal   = new Vector3(0.0f, -1.0f, 0.0f),
                            Color    = Color.Red
                        });

                        // bottom right
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(1.0f + x, -1.0f + y, 0.0f + z),
                            Normal   = new Vector3(0.0f, -1.0f, 0.0f),
                            Color    = Color.Red
                        });

                        // first tri
                        indices.Add((ushort)(verts.Count - 4)); // bottom left
                        indices.Add((ushort)(verts.Count - 3)); // top left
                        indices.Add((ushort)(verts.Count - 2)); // top right

                        // second tri
                        indices.Add((ushort)(verts.Count - 4)); // bottom left
                        indices.Add((ushort)(verts.Count - 2)); // top right
                        indices.Add((ushort)(verts.Count - 1)); // bottom right
                    }
                }

                {
                    // top face
                    if ((Block.Type)chunk[x, y + 1, z] == Block.Type.Air)
                    {
                        // bottom left
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(0.0f + x, 0.0f + y, 0.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.Green
                        });

                        // top left
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(0.0f + x, 0.0f + y, 1.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.Green
                        });

                        // top right
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(1.0f + x, 0.0f + y, 1.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.Green
                        });

                        // bottom right
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(1.0f + x, 0.0f + y, 0.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.Green
                        });

                        // first tri
                        indices.Add((ushort)(verts.Count - 2)); // bottom left
                        indices.Add((ushort)(verts.Count - 3)); // top left
                        indices.Add((ushort)(verts.Count - 4)); // top right

                        // second tri
                        indices.Add((ushort)(verts.Count - 1)); // bottom left
                        indices.Add((ushort)(verts.Count - 2)); // top right
                        indices.Add((ushort)(verts.Count - 4)); // bottom right
                    }
                }

                {
                    // left face
                    if ((Block.Type)chunk[x - 1, y, z] == Block.Type.Air)
                    {
                        // bottom left
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(0.0f + x, 0.0f + y, 0.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.Blue
                        });

                        // top left
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(0.0f + x, -1.0f + y, 0.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.Blue
                        });

                        // top right
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(0.0f + x, -1.0f + y, 1.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.Blue
                        });

                        // bottom right
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(0.0f + x, 0.0f + y, 1.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.Blue
                        });

                        // first tri
                        indices.Add((ushort)(verts.Count - 2)); // bottom left
                        indices.Add((ushort)(verts.Count - 3)); // top left
                        indices.Add((ushort)(verts.Count - 4)); // top right

                        // second tri
                        indices.Add((ushort)(verts.Count - 1)); // bottom left
                        indices.Add((ushort)(verts.Count - 2)); // top right
                        indices.Add((ushort)(verts.Count - 4)); // bottom right
                    }
                }

                {
                    // right face
                    if ((Block.Type)chunk[x + 1, y, z] == Block.Type.Air)
                    {
                        // bottom left
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(1.0f + x, 0.0f + y, 0.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.HotPink
                        });

                        // top left
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(1.0f + x, -1.0f + y, 0.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.HotPink
                        });

                        // top right
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(1.0f + x, -1.0f + y, 1.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.HotPink
                        });

                        // bottom right
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(1.0f + x, 0.0f + y, 1.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.HotPink
                        });

                        // first tri
                        indices.Add((ushort)(verts.Count - 4)); // bottom left
                        indices.Add((ushort)(verts.Count - 3)); // top left
                        indices.Add((ushort)(verts.Count - 2)); // top right

                        // second tri
                        indices.Add((ushort)(verts.Count - 4)); // bottom left
                        indices.Add((ushort)(verts.Count - 2)); // top right
                        indices.Add((ushort)(verts.Count - 1)); // bottom right
                    }
                }

                {
                    // front face
                    if ((Block.Type)chunk[x, y, z + 1] == Block.Type.Air)
                    {
                        // bottom left
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(0.0f + x, 0.0f + y, 1.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.White
                        });

                        // top left
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(0.0f + x, -1.0f + y, 1.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.White
                        });

                        // top right
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(1.0f + x, -1.0f + y, 1.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.White
                        });

                        // bottom right
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(1.0f + x, 0.0f + y, 1.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.White
                        });

                        // first tri
                        indices.Add((ushort)(verts.Count - 2)); // bottom left
                        indices.Add((ushort)(verts.Count - 3)); // top left
                        indices.Add((ushort)(verts.Count - 4)); // top right

                        // second tri
                        indices.Add((ushort)(verts.Count - 1)); // bottom left
                        indices.Add((ushort)(verts.Count - 2)); // top right
                        indices.Add((ushort)(verts.Count - 4)); // bottom right
                    }
                }

                {
                    // back face

                    if ((Block.Type)chunk[x, y, z - 1] == Block.Type.Air)
                    {
                        // bottom left
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(0.0f + x, 0.0f + y, 0.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.Orange
                        });

                        // top left
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(0.0f + x, -1.0f + y, 0.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.Orange
                        });

                        // top right
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(1.0f + x, -1.0f + y, 0.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.Orange
                        });

                        // bottom right
                        verts.Add(new VertexPositionNormalColor()
                        {
                            Position = new Vector3(1.0f + x, 0.0f + y, 0.0f + z),
                            Normal   = new Vector3(0.0f, 1.0f, 0.0f),
                            Color    = Color.Orange
                        });

                        // first tri
                        indices.Add((ushort)(verts.Count - 4)); // bottom left
                        indices.Add((ushort)(verts.Count - 3)); // top left
                        indices.Add((ushort)(verts.Count - 2)); // top right

                        // second tri
                        indices.Add((ushort)(verts.Count - 4)); // bottom left
                        indices.Add((ushort)(verts.Count - 2)); // top right
                        indices.Add((ushort)(verts.Count - 1)); // bottom right
                    }
                }
            }

            for (int x = 0; x < Chunk.SIZE; ++x)
            {
                for (int y = 0; y < Chunk.SIZE; ++y)
                {
                    for (int z = 0; z < Chunk.SIZE; ++z)
                    {
                        // GenerateBox(ref c, (pos.X * Chunk.SIZE) + x, (pos.Y * Chunk.SIZE) + y, (pos.Z * Chunk.SIZE) + z);
                        GenerateBox(ref c, x, y, z);
                    }
                }
            }

            // recreate with proper size now, if necessary
            var neededVtxSize = verts.Count * VertexPositionNormalColor.Layout.CalculateSize();
            var neededIdxSize = indices.Count * sizeof(ushort);

            if (neededVtxSize > data.Mesh.Draw.VertexBuffers[0].Buffer.SizeInBytes)
            {
                var vertexBuffer = Xenko.Graphics.Buffer.New <VertexPositionNormalColor>(device, verts.Count, BufferFlags.VertexBuffer, GraphicsResourceUsage.Dynamic);
                data.Mesh.Draw.VertexBuffers[0] = new VertexBufferBinding(vertexBuffer, VertexPositionNormalColor.Layout, verts.Count);
            }

            if (neededIdxSize > data.Mesh.Draw.IndexBuffer.Buffer.SizeInBytes)
            {
                var indexBuffer = Xenko.Graphics.Buffer.New <ushort>(device, indices.Count, BufferFlags.IndexBuffer, GraphicsResourceUsage.Dynamic);
                data.Mesh.Draw.IndexBuffer = new IndexBufferBinding(indexBuffer, false, indices.Count);
            }

            data.Mesh.Draw.DrawCount = indices.Count;

            unsafe
            {
                fixed(VertexPositionNormalColor *vertsPtr = verts.Items)
                {
                    fixed(ushort *indicesPtr = indices.Items)
                    {
                        data.Mesh.Draw.VertexBuffers[0].Buffer.SetData(commandList, new DataPointer(vertsPtr, neededVtxSize));
                        data.Mesh.Draw.IndexBuffer.Buffer.SetData(commandList, new DataPointer(indicesPtr, neededIdxSize));

                        var newChunk   = new Entity(position: new Vector3(pos.X * Chunk.SIZE, pos.Z * Chunk.SIZE, pos.Y * Chunk.SIZE));
                        var chunkModel = new Model {
                            data.Mesh
                        };

                        newChunk.GetOrCreate <ModelComponent>().Model = chunkModel;
                        // chunkModel.Materials.Add(material);
                        Entity.AddChild(newChunk);
                    }
                }
            }

            verts.Clear();
            indices.Clear();
            // TODO: check sanity
        }