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; } }
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; } } }
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); }
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; }
public void Clear() { ManagedObjects.Clear(); }
public void Clear() { FinalCount = 0; Sorting.Clear(); }
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); }
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); }
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(); // } //} }
public override void ClearAll() { m_record.Clear(); }
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; }
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); }
/// <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); }
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); } }
/// <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); } } } }
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); }
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); } } } } }
/// <summary> /// resets the bezier removing all points /// </summary> public void Reset() { _points.Clear(); }
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 Clear() { instancedVoxels.Clear(); }
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); }
/// <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); }
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; }
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; }
public static void CleanPropertyArrayOffset() { _propertyArrayOffset = null; _intBuffer?.Clear(); _intBuffer = null; }
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 }