internal void SetOffsets() { s_SeOffsets.Auto(); for (int j = 0; j < gravGridDimensions; j++) { int yOffset = (j + mStartWorldY) - rootCoord.y; float s = ((float)yOffset / (float)gravGridDimensions + 1.0f) / 2.0f; for (int i = 0; i < gravGridDimensions; i++) { int x = mod((mStartWorldX + i), gravGridDimensions); int y = mod((mStartWorldY + j), gravGridDimensions); GravNode gn = gravGrid[x, y]; int index = gn.m_Index; int xOffset = (i + mStartWorldX) - rootCoord.x; float t = ((float)xOffset / (float)gravGridDimensions + 1.0f) / 2.0f; offsets[index] = new float2(t, s); } } //var SetOffsetsJob = new GravNode.SetOffsets() //{ // coordinate = coordinates, // sectorOffsets = offsets, // dimensions = new int2(mHorizontalParticles, mVerticalParticles), // worldStart = new int2(mStartWorldX, mStartWorldY), // sectorStart = sector //}; //SetOffsetsJob.Schedule(coordinates.Length, 64).Complete(); }
public int FindLinkIndex(GravNode gn2) { for (int i = 0; i < m_Links.Count; i++) { if (m_Links[i].m_Gn2.m_Index == gn2.m_Index) { return(m_Links[i].m_Index); } } return(-1); }
private void RemoveConnection(GravNode gn1, GravNode gn2) { s_RemoveLinkCreateIP.Begin(); int indexResult = gn1.FindLinkIndex(gn2); if (indexResult == -1) { Debug.LogError("Link not found"); return; } s_RemoveLinkCreateIP.End(); connections[indexResult].BreakLink(m_GravMesh); availableConnectionIndex.Enqueue(indexResult); }
internal void MakeLink(GravNode gn1, GravNode gn2, bool draw, GravMesh gravMesh, float thickness, float spacing) { m_Gn1 = gn1; m_Gn2 = gn2; m_GravNode1PosIndex = gn1.m_Index; m_GravNode2PosIndex = gn2.m_Index; m_RestDistance = spacing; gn1.m_Links.Add(this); gn1.neighborIndiciesList.Add(gn2.m_Index); gn1.restDistancesList.Add(m_RestDistance); gn2.neighborIndiciesList.Add(gn1.m_Index); gn2.restDistancesList.Add(m_RestDistance); m_Draw = draw; m_Thickness = thickness; if (draw) { if (gn1.availibleVertexPositions.Count == 0) { Debug.LogError("No more vertices are available for rendering this connection"); } m_GravNode1VertexStart = gn1.availibleVertexPositions.Dequeue(); if (gn2.availibleVertexPositions.Count == 0) { Debug.LogError("No more vertices are available for rendering this connection"); } m_GravNode2VertexStart = gn2.availibleVertexPositions.Dequeue(); m_TrianglesIndex = gravMesh.AddPair(m_GravNode1VertexStart, m_GravNode2VertexStart); } gn1.m_Connections++; gn2.m_Connections++; }
public void AddAndSetupConnectionAtNextIndex(GravNode gn1, GravNode gn2, bool draw, GravMesh gravMesh) { if (availableConnectionIndex.Count == 0) { Debug.LogError("There are no available connections."); } s_CreateNewLink.Begin(); int index = availableConnectionIndex.Dequeue(); //We're not going to update the thickness data as to preserve the sector location. connections[index].MakeLink(gn1, gn2, draw, gravMesh, 0, spacing); s_CreateNewLink.End(); gn1Index[index] = connections[index].m_GravNode1PosIndex; gn2Index[index] = connections[index].m_GravNode2PosIndex; drawables[index] = connections[index].m_Draw; gn1VertexStartIndices[index] = connections[index].m_GravNode1VertexStart; gn2VertexStartIndices[index] = connections[index].m_GravNode2VertexStart; int gn1I = gn1.m_Index; int gn2I = gn2.m_Index; nodeNumConnections[gn1I] = gn1.m_Connections; nodeNumConnections[gn2I] = gn2.m_Connections; int connectionsStart = startConnectionsIndex[gn1I]; for (int i = 0; i < gn1.m_Connections; i++) { allNodeConnections[i + connectionsStart] = gn1.neighborIndiciesList[i]; allRestsDistances[i + connectionsStart] = gn1.restDistancesList[i]; } connectionsStart = startConnectionsIndex[gn2I]; for (int i = 0; i < gn2.m_Connections; i++) { allNodeConnections[i + connectionsStart] = gn2.neighborIndiciesList[i]; allRestsDistances[i + connectionsStart] = gn2.restDistancesList[i]; } }
public void ConfigureNewStartAndEndNodes( GravNode break1, GravNode break2, GravNode connect1, GravNode connect2, GravNode newStart, GravNode newEnd, GravNode newMid, int row, int start, int max) { s_AddConnections.Begin(); RemoveConnection(break1, break2); AddAndSetupConnectionAtNextIndex(connect1, connect2, true, m_GravMesh); s_AddConnections.End(); s_SetGravNodeConnectionProperties.Begin(); if (row != start && row != start + max - 1) { int midIndex = newMid.m_Index; newMid.SetMoveable(true); moveables[midIndex] = true; } int newStartXIndex = newStart.m_Index; affected[newStartXIndex] = false; moveables[newStartXIndex] = false; newStart.SetMoveable(false); int newEndXINdex = newEnd.m_Index; affected[newEndXINdex] = false; moveables[newEndXINdex] = false; newEnd.SetMoveable(false); s_SetGravNodeConnectionProperties.End(); }
void Start() { gravGridCam = Camera.main; fixedDeltaTimeSeconds = (float)fixedDeltaTime / 1000.0f; gravGrid = new GravNode[gravGridDimensions, gravGridDimensions]; gravNodes = new List <GravNode>(gravGridDimensions * gravGridDimensions); float gridSizeWorld = gravGridDimensions * spacing; m_GravMesh = new GravMesh(new Vector3(gridSizeWorld, gridSizeWorld, 0.5f), gridSizeWorld, GetComponent <MeshFilter>()); m_MeshMatcher = new MeshMatcher(gravGridDimensions / sectorSize, parentLayer, spacing, gravGridDimensions); m_MeshMatcher.SetAdjacentNodes(rootCoord); availableConnectionIndex = new Queue <int>(); offsets = new NativeArray <float2>(gravGridDimensions * gravGridDimensions, Allocator.Persistent); coordinates = new NativeArray <int2>(gravGridDimensions * gravGridDimensions, Allocator.Persistent); rootCoord = new int2(startingRootCoordinate.x, startingRootCoordinate.y); colliderTransformArray = new TransformAccessArray(gravGridDimensions * gravGridDimensions); for (int j = 0, index = 0; j < gravGridDimensions; ++j) { int yOffset = (j + mStartWorldY) - rootCoord.y; float s = ((float)yOffset / (float)gravGridDimensions + 1.0f) / 2.0f; for (int i = 0; i < gravGridDimensions; ++i, index++) { int xOffset = (i + mStartWorldX) - rootCoord.x; float t = ((float)xOffset / (float)gravGridDimensions + 1.0f) / 2.0f; Vector3 position = new Vector3(i * spacing, j * spacing, 0); int vertexStartIndex = m_GravMesh.AddNode(); offsets[index] = new float2(t, s); coordinates[index] = new int2(i, j); var gn = new GravNode(position, spacing, index, transform, vertexStartIndex, gameObject.layer); colliderTransformArray.Add(gn.gravNodeColliderParent.transform); gn.AddForce = ApplyForce; gn.SetTargetLocation = SetTargetLocation; gn.Return = SetTargetToReturnPosition; gn.GetNodePosition = GetNodePosition; gn.GetReturnPosition = GetReturnPosition; gravGrid[i, j] = gn; gravNodes.Add(gn); } } nodeNumConnections = new NativeArray <int>(gravNodes.Count, Allocator.Persistent); startConnectionsIndex = new NativeArray <int>(gravNodes.Count, Allocator.Persistent); allNodeConnections = new NativeArray <int>(gravNodes.Count * MAX_CONNECTIONS, Allocator.Persistent); allRestsDistances = new NativeArray <float>(gravNodes.Count * MAX_CONNECTIONS, Allocator.Persistent); targetPositions = new NativeArray <float3>(gravNodes.Count, Allocator.Persistent); returnPositions = new NativeArray <float3>(gravNodes.Count, Allocator.Persistent); affected = new NativeArray <bool>(gravNodes.Count, Allocator.Persistent); prevPositions = new NativeArray <float3>(gravNodes.Count, Allocator.Persistent); positions = new NativeArray <float3>(gravNodes.Count, Allocator.Persistent); newPositions = new NativeArray <float3>(gravNodes.Count, Allocator.Persistent); accelerations = new NativeArray <float3>(gravNodes.Count, Allocator.Persistent); moveables = new NativeArray <bool>(gravNodes.Count, Allocator.Persistent); forceUpdatePosition = new NativeArray <bool>(gravNodes.Count, Allocator.Persistent); for (int j = 0; j < gravNodes.Count; j++) { accelerations[j] = gravNodes[j].m_Acceleration; prevPositions[j] = gravNodes[j].m_PrevPosition; targetPositions[j] = gravNodes[j].m_TargetPosition; returnPositions[j] = gravNodes[j].m_ReturnPosition; affected[j] = false; moveables[j] = gravNodes[j].m_Moveable; positions[j] = gravNodes[j].m_Position; } ResetConnections(); }
public void ShiftGrid(GridShiftDirection gridShiftDirection) { switch (gridShiftDirection) { case GridShiftDirection.Right: { int newStart = mStartWorldX + 1; int oldEnd = mod(mStartWorldX + gravGridDimensions - 1, gravGridDimensions); int newStartX = mod(newStart, gravGridDimensions); int oldStart = mod(mStartWorldX, gravGridDimensions); int newWorldXPos = mStartWorldX + gravGridDimensions; for (int j = 0; j < gravGridDimensions; j++) { int y = mod((mStartWorldY + j), gravGridDimensions); s_UpdateNodePosesOnShift.Begin(); int yOffset = (mStartWorldY + j) - rootCoord.y; int xOffset = newWorldXPos - rootCoord.x; float t = ((float)xOffset / (float)gravGridDimensions + 1.0f) / 2.0f; float s = ((float)yOffset / (float)gravGridDimensions + 1.0f) / 2.0f; GravNode newStartGN = gravGrid[newStartX, y]; GravNode oldStartNewEndGN = gravGrid[oldStart, y]; GravNode oldEndGN = gravGrid[oldEnd, y]; offsets[oldStartNewEndGN.m_Index] = new float2(t, s); forceUpdatePosition[oldStartNewEndGN.m_Index] = true; ConfigureNewStartAndEndNodes( oldStartNewEndGN, //break newStartGN, //break oldEndGN, // connect oldStartNewEndGN, //connect newStartGN, //start oldStartNewEndGN, //end oldEndGN, //middle y, mStartWorldY, gravGridDimensions); s_UpdateNodePosesOnShift.End(); } mStartWorldX = newStart; if (oldStart == startingRootCoordinate.x) // sector is moving!! { SectorShift(new int2(gravGridDimensions, 0)); } break; } case GridShiftDirection.Up: { int newStart = mStartWorldY + 1; int oldEnd = mod(mStartWorldY + gravGridDimensions - 1, gravGridDimensions); int newStartY = mod(newStart, gravGridDimensions); int oldStart = mod(mStartWorldY, gravGridDimensions); int newWorldYPos = mStartWorldY + gravGridDimensions; for (int j = 0; j < gravGridDimensions; j++) { s_UpdateNodePosesOnShift.Begin(); int x = mod((mStartWorldX + j), gravGridDimensions); int yOffset = newWorldYPos - rootCoord.y; int xOffset = (j + mStartWorldX) - rootCoord.x; float t = ((float)xOffset / (float)gravGridDimensions + 1.0f) / 2.0f; float s = ((float)yOffset / (float)gravGridDimensions + 1.0f) / 2.0f; GravNode newStartGN = gravGrid[x, newStartY]; GravNode oldStartNewEndGN = gravGrid[x, oldStart]; GravNode oldEndGN = gravGrid[x, oldEnd]; offsets[oldStartNewEndGN.m_Index] = new float2(t, s); forceUpdatePosition[oldStartNewEndGN.m_Index] = true; ConfigureNewStartAndEndNodes( oldStartNewEndGN, //break newStartGN, //break oldEndGN, // connect oldStartNewEndGN, //connect newStartGN, //start oldStartNewEndGN, //end oldEndGN, //middle x, mStartWorldX, gravGridDimensions); s_UpdateNodePosesOnShift.End(); } mStartWorldY = newStart; if (oldStart == startingRootCoordinate.y) // sector is moving!! { SectorShift(new int2(0, gravGridDimensions)); } break; } case GridShiftDirection.Left: { int newStart = mStartWorldX - 1; int oldStart = mod(mStartWorldX, gravGridDimensions); int oldEnd = mod(mStartWorldX + gravGridDimensions - 1, gravGridDimensions); int newEnd = mod(mStartWorldX + gravGridDimensions - 2, gravGridDimensions); for (int j = 0; j < gravGridDimensions; j++) { s_UpdateNodePosesOnShift.Begin(); int y = mod((mStartWorldY + j), gravGridDimensions); int yOffset = (j + mStartWorldY) - rootCoord.y; int xOffset = newStart - rootCoord.x; float t = ((float)xOffset / (float)gravGridDimensions + 1.0f) / 2.0f; float s = ((float)yOffset / (float)gravGridDimensions + 1.0f) / 2.0f; GravNode oldStartGN = gravGrid[oldStart, y]; GravNode newEndGN = gravGrid[newEnd, y]; GravNode oldEndNewStartGN = gravGrid[oldEnd, y]; offsets[oldEndNewStartGN.m_Index] = new float2(t, s); forceUpdatePosition[oldEndNewStartGN.m_Index] = true; ConfigureNewStartAndEndNodes( newEndGN, //break oldEndNewStartGN, //break oldEndNewStartGN, // connect oldStartGN, //connect oldEndNewStartGN, //start newEndGN, //end oldStartGN, //middle y, mStartWorldY, gravGridDimensions); s_UpdateNodePosesOnShift.End(); } mStartWorldX = newStart; if (oldEnd == startingRootCoordinate.x) // sector is moving!! { SectorShift(new int2(-gravGridDimensions, 0)); } break; } case GridShiftDirection.Down: { int newStart = mStartWorldY - 1; int oldStart = mod(mStartWorldY, gravGridDimensions); int oldEnd = mod(mStartWorldY + gravGridDimensions - 1, gravGridDimensions); int newEnd = mod(mStartWorldY + gravGridDimensions - 2, gravGridDimensions); for (int j = 0; j < gravGridDimensions; j++) { s_UpdateNodePosesOnShift.Begin(); int x = mod((mStartWorldX + j), gravGridDimensions); int yOffset = newStart - rootCoord.y; int xOffset = (j + mStartWorldX) - rootCoord.x; float t = ((float)xOffset / (float)gravGridDimensions + 1.0f) / 2.0f; float s = ((float)yOffset / (float)gravGridDimensions + 1.0f) / 2.0f; GravNode oldStartGN = gravGrid[x, oldStart]; GravNode newEndGN = gravGrid[x, newEnd]; GravNode oldEndNewStartGN = gravGrid[x, oldEnd]; offsets[oldEndNewStartGN.m_Index] = new float2(t, s); forceUpdatePosition[oldEndNewStartGN.m_Index] = true; ConfigureNewStartAndEndNodes( newEndGN, //break oldEndNewStartGN, //break oldEndNewStartGN, // connect oldStartGN, //connect oldEndNewStartGN, //start newEndGN, //end oldStartGN, //middle x, mStartWorldX, gravGridDimensions); s_UpdateNodePosesOnShift.End(); } mStartWorldY = newStart; if (oldEnd == startingRootCoordinate.y) // sector is moving!! { SectorShift(new int2(0, -gravGridDimensions)); } break; } default: break; } }
public void AddConnection(GravNode gn1, GravNode gn2, bool draw, float thickness, GravMesh gravMesh) { Link l = new Link(gn1, gn2, draw, gravMesh, thickness, connections.Count, spacing); connections.Add(l); }
public void ResetConnections() { s_ResetConnections.Begin(); connections.Clear(); for (int i = 0; i < gravNodes.Count; i++) { gravNodes[i].m_Connections = 0; gravNodes[i].neighborIndiciesList.Clear(); gravNodes[i].restDistancesList.Clear(); gravNodes[i].stiffnessesList.Clear(); } s_AddConnections.Begin(); for (int j = 0; j < gravGridDimensions; j++) { int y = mod((mStartWorldY + j), gravGridDimensions); for (int i = 0; i < gravGridDimensions; i++) { int x = mod((mStartWorldX + i), gravGridDimensions); float thickcessX = lineWidth; float thickcessY = lineWidth; if (y % sectorSize == 0) { thickcessX *= 3; } if (x % sectorSize == 0) { thickcessY *= 3; } if (i < gravGridDimensions - 1) { AddConnection(gravGrid[x, y], gravGrid[mod((x + 1), gravGridDimensions), y], true, thickcessX, m_GravMesh); } if (j < gravGridDimensions - 1) { AddConnection(gravGrid[x, y], gravGrid[x, mod((y + 1), gravGridDimensions)], true, thickcessY, m_GravMesh); } //if (x < mHorizontalParticles - 1 && y < mVerticalParticles - 1) AddConnection(gravGrid[x, y], gravGrid[x + 1, y + 1], drawDiagonals, planeLinkStiffness, m_GravMesh); //if (x < mHorizontalParticles - 1 && y < mVerticalParticles - 1) AddConnection(gravGrid[x + 1, y], gravGrid[x, y + 1], drawDiagonals, planeLinkStiffness, m_GravMesh); //configure extended connections //if (x < mHorizontalParticles - 2) AddConnection(gravGrid[x, y], gravGrid[x + 2, y], drawDiagonals, planeLinkStiffness, m_GravMesh); //if (y < mVerticalParticles - 2) AddConnection(gravGrid[x, y], gravGrid[x, y + 2], drawDiagonals, planeLinkStiffness, m_GravMesh); //if (x < mHorizontalParticles - 2 && y < mVerticalParticles - 2) AddConnection(gravGrid[x, y], gravGrid[x + 2, y + 2], drawDiagonals, planeLinkStiffness, m_GravMesh); //if (x < mHorizontalParticles - 2 && y < mVerticalParticles - 2) AddConnection(gravGrid[x + 2, y], gravGrid[x, y + 2], drawDiagonals, planeLinkStiffness, m_GravMesh); if (x == mStartWorldX || y == mStartWorldY || x == mStartWorldX + gravGridDimensions - 1 || y == mStartWorldY + gravGridDimensions - 1) { gravGrid[x, y].SetMoveable(false); } else { gravGrid[x, y].SetMoveable(true); } } } s_AddConnections.End(); if (!gn1Index.IsCreated) { gn1Index = new NativeArray <int>(connections.Count, Allocator.Persistent); } if (!gn2Index.IsCreated) { gn2Index = new NativeArray <int>(connections.Count, Allocator.Persistent); } if (!gn1VertexStartIndices.IsCreated) { gn1VertexStartIndices = new NativeArray <int>(connections.Count, Allocator.Persistent); } if (!gn2VertexStartIndices.IsCreated) { gn2VertexStartIndices = new NativeArray <int>(connections.Count, Allocator.Persistent); } if (!drawables.IsCreated) { drawables = new NativeArray <bool>(connections.Count, Allocator.Persistent); } if (!lineWidths.IsCreated) { lineWidths = new NativeArray <float>(connections.Count, Allocator.Persistent); } if (!baseLineWidths.IsCreated) { baseLineWidths = new NativeArray <float>(connections.Count, Allocator.Persistent); } s_ConstructuMesh.Begin(); m_GravMesh.ConstructMesh(); s_ConstructuMesh.End(); s_SetConnectionProperties.Begin(); for (int j = 0; j < connections.Count; j++) { gn1Index[j] = connections[j].m_GravNode1PosIndex; gn2Index[j] = connections[j].m_GravNode2PosIndex; drawables[j] = connections[j].m_Draw; gn1VertexStartIndices[j] = connections[j].m_GravNode1VertexStart; gn2VertexStartIndices[j] = connections[j].m_GravNode2VertexStart; lineWidths[j] = connections[j].m_Thickness; baseLineWidths[j] = connections[j].m_Thickness; } s_SetConnectionProperties.End(); s_SetGravNodeConnectionProperties.Begin(); int startIndex = 0; for (int j = 0; j < gravNodes.Count; j++) { GravNode n = gravNodes[j]; nodeNumConnections[j] = n.m_Connections; startConnectionsIndex[j] = startIndex; for (int i = 0; i < n.m_Connections; i++) { allNodeConnections[i + startIndex] = n.neighborIndiciesList[i]; allRestsDistances[i + startIndex] = n.restDistancesList[i]; } startIndex += MAX_CONNECTIONS; moveables[j] = n.m_Moveable; } s_SetGravNodeConnectionProperties.End(); s_ResetConnections.End(); }
public Link(GravNode gn1, GravNode gn2, bool draw, GravMesh gravMesh, float thickness, int index, float spacing) { m_Index = index; MakeLink(gn1, gn2, draw, gravMesh, thickness, spacing); }