public override void _Ready() { //when we open the generator, add our dock to the editor dock = new AsteroidGeneratorPlugin(); AddChild(dock); sphere = GetNode <Icosphere>("IcosphereInstance"); }
public void NewGame() { WorldData = JsonUtility.FromJson <WorldData>(WorldDataAsset.text); WorldData.Init(); _worldGenData = JsonUtility.FromJson <WorldGenData>(WorldGenAsset.text); Icosphere = Instantiate(IcospherePrefab, transform); Icosphere.Init(Subdivisions); StaticState = new StaticState(); StaticState.Init(_worldGenData.Radius, Icosphere, WorldData); _simulation = new SimTick(StaticState); _tempState = new TempState(StaticState); int height = 3; for (int i = 0; i < _simStates.Length; i++) { _simStates[i] = new SimState(); _simStates[i].Init(StaticState); } WorldGen.Generate(StaticState.Count, height, _worldGenData, _simStates[_curSimStateIndex], StaticState); _initialized = true; NewGameEvent?.Invoke(_simStates[_curSimStateIndex]); }
public Planet(Vector3 center, float radius, int divisions, float scale) { // We make sure the radius of the planet will work as intendad. if (radius <= 1) { radius = 1; Debug.LogWarning("The radius can't be smaller than 1.0f."); } // We make sure resizing the planet will work as intendad. if (scale <= 0) { scale = 0.1f; Debug.LogWarning("The scale can't be smaller than 0.1f."); } // Prevent the mesh to overflow. if (divisions > 6) { divisions = 6; Debug.LogWarning("Can't divide a planet more than 6 times."); } // We Generate the Basic Icosphere points and triangles. ico = new Icosphere(center, radius); // We divide the icosphere n times(add smoothness). Thread t = new Thread(() => generated = ico.Subdivide(divisions)); t.Start(); }
public void GenerateIcosphere() { icos = new Icosphere(); icos.Subdivide(mapSubdivisions); map = new TileMap(icos, mapSettings, tileSettings); icos.Subdivide(meshSubdivisions); }
// Use this for initialization void Initialize() { m_vertices = Icosphere.GenerateIcosphere(1f, m_nbSubdivisions); m_segments = new List <IcoSegment>(); for (int i = 0; i < m_vertices.Count / 3; ++i) { Vector3 v0 = m_vertices[3 * i + 0]; Vector3 v1 = m_vertices[3 * i + 1]; Vector3 v2 = m_vertices[3 * i + 2]; GameObject segment = new GameObject(); segment.transform.position = transform.position; segment.name = "segment" + i; segment.transform.parent = transform; segment.AddComponent <MeshRenderer>(); segment.GetComponent <MeshRenderer>().material = m_segmentMaterial; segment.layer = LayerMask.NameToLayer("Planet"); IcoSegment icoSeg = segment.AddComponent <IcoSegment>(); m_segments.Add(icoSeg); icoSeg.heightLevel = m_defaultHeightLevel; icoSeg.icoPlanet = this; icoSeg.SetBaseVertices(v0, v1, v2); m_segmentJoints.Add(segment.AddComponent <MTK_PlanetSegmentJoint>()); MTK_Interactable interactable = segment.AddComponent <MTK_Interactable>(); interactable.isDistanceGrabbable = false; interactable.isGrabbable = false; interactable.isDroppable = false; } }
// Update is called once per frame void Update() { HexSphere hexSphere = sphere.GetSphere(); Icosphere gameSphere = hexSphere.GetHexMap(); if (gameSphere == null) { return; } if (Input.GetButtonDown("Select")) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit, Mathf.Infinity, LayerMask.GetMask("Sphere"))) { if (outlineHighlight != null) { GameObject.Destroy(outlineHighlight); } GameObject obj = hit.collider.gameObject; HexIdentifier hex = obj.GetComponent <HexIdentifier>(); if (hex != null) { selected = hex.location; float rad = gameSphere.Radius; gameSphere.SetRadius(rad + 0.001f); outlineHighlight = new GameObject(); outlineHighlight.transform.position += sphere.transform.position; outlineHighlight.transform.Rotate(sphere.transform.eulerAngles); outlineHighlight.name = "Outline Highlight"; MeshFilter mf = outlineHighlight.AddComponent <MeshFilter>(); MeshRenderer mr = outlineHighlight.AddComponent <MeshRenderer>(); mr.material = new Material(Shader.Find("Transparent/Diffuse")); HexSphere.RenderTile(mf.mesh, selected, gameSphere); if (new List <SCoord>(gameSphere.GetNeighbors(selected)).Count == 5) { mr.material.SetTexture("_MainTex", pentHighlight); } else { mr.material.SetTexture("_MainTex", hexHighlight); } gameSphere.SetRadius(rad); } } } }
public void GeneratePlanet() { icos = null; Initialize(); GenerateMap(); GenerateMesh(); GenerateTileInfo(); }
protected void CreatePlanetVertexes(int recursionLevel) { var icosphere = new Icosphere(); icosphere.Create(recursionLevel); PlanetVertexes = icosphere.Vertexes.Select(v => ComputeModelElevation(v)).ToList(); PlanetTriangles = icosphere.Triangles.ToList(); }
private static void test03() //****************************************************************************80 // // Purpose: // // TEST03 tests SPHERE_ICOS2_POINTS. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 29 August 2010 // // Author: // // John Burkardt // { Console.WriteLine(""); Console.WriteLine("TEST03"); Console.WriteLine(" SPHERE_ICOS_POINT_NUM \"sizes\" a grid generated"); Console.WriteLine(" on an icosahedron and projected to a sphere."); Console.WriteLine(" SPHERE_ICOS2_POINTS creates the grid."); const int factor = 3; Console.WriteLine(""); Console.WriteLine(" Sizing factor FACTOR = " + factor + ""); int node_num = Icosphere.sphere_icos_point_num(factor); Console.WriteLine(""); Console.WriteLine(" Number of nodes = " + node_num + ""); double[] node_xyz = Icosphere.sphere_icos2_points(factor, node_num); typeMethods.r8mat_transpose_print_some(3, node_num, node_xyz, 1, 1, 3, 20, " Initial part of NODE_XYZ array:"); // // Write the nodes to a file. // string filename = "sphere_grid_icos2_points_f" + (factor, "%d") + ".xyz"; typeMethods.r8mat_write(filename, 3, node_num, node_xyz); Console.WriteLine(""); Console.WriteLine(" Wrote data to \"" + filename + "\""); }
public HexSphere(int subdivisions, Vector3 center, float edgeLength) { tileMap = new Dictionary <SCoord, GameObject>(); // Make and subdivide the icosphere hexSphere = new Icosphere(center, 1); for (int sub = 0; sub < subdivisions; sub++) { hexSphere = hexSphere.SubdivideSphere(); } // Scale the spehres float sf = HexSphere.GetScaleFactor(hexSphere, edgeLength); hexSphere.SetRadius(sf); }
private static float GetScaleFactor(Icosphere sphere, float edgeLength) { List <SCoord> coordinates = new List <SCoord>(sphere.Coordinates); // Compute the scaling factor to meet the target edge length // Get the distance from the pole to one of its neighbors Vector3 scaleVec1 = sphere.GetPoint(coordinates[0]); IEnumerator <SCoord> scaleNeighbors = sphere.GetNeighbors(coordinates[0]).GetEnumerator(); scaleNeighbors.MoveNext(); Vector3 scaleVec2 = sphere.GetPoint(scaleNeighbors.Current); float dist = Vector3.Distance(scaleVec1, scaleVec2); // Compute the new scale factor and set this for the sphere float sf = edgeLength / dist; return(sf); }
private bool FieldShapeBlocked() { ModulatorGridComponent modComp; MyGrid.Components.TryGet(out modComp); if (ShieldComp.Modulator == null || ShieldComp.Modulator.ModSet.Settings.ModulateVoxels || Session.Enforced.DisableVoxelSupport == 1) { return(false); } var pruneSphere = new BoundingSphereD(DetectionCenter, BoundingRange); var pruneList = new List <MyVoxelBase>(); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref pruneSphere, pruneList); if (pruneList.Count == 0) { return(false); } MobileUpdate(); Icosphere.ReturnPhysicsVerts(DetectMatrixOutside, ShieldComp.PhysicsOutsideLow); foreach (var voxel in pruneList) { if (voxel.RootVoxel == null || voxel != voxel.RootVoxel) { continue; } if (!CustomCollision.VoxelContact(ShieldComp.PhysicsOutsideLow, voxel)) { continue; } Shield.Enabled = false; DsState.State.FieldBlocked = true; DsState.State.Message = true; if (Session.Enforced.Debug == 3) { Log.Line($"Field blocked: - ShieldId [{Shield.EntityId}]"); } return(true); } DsState.State.FieldBlocked = false; return(false); }
void CreatePlanet(float radius, float variation, float seaLevel, Color planetColor, float atmosphereRadius, Color atmosphereColor, bool habitableAtmosphere, Orbit orbit) { PlanetVars planetVars = new PlanetVars(radius, variation, seaLevel, planetColor, atmosphereRadius, atmosphereColor, habitableAtmosphere, orbit); GameObject planet = new GameObject(); Icosphere.Create(planet, 6, planetVars.radius, Mathf.RoundToInt(Random.value * int.MaxValue), planetVars.variation, planetVars.variation); planet.AddComponent <MeshRenderer>(); planet.AddComponent <MeshCollider>(); planet.AddComponent <Orbiter>(); //Generate Material Material planetMaterial = new Material(triplanar); planetMaterial.SetTexture("_MainTex", ground); planetMaterial.SetTexture("_MainTex1", ground); planetMaterial.SetTexture("_MainTex2", ground); planet.GetComponent <MeshRenderer>().material = planetMaterial; //Generate Orbit planet.GetComponent <Orbiter>().orbit = planetVars.orbit; //Make ocean GameObject ocean = new GameObject(); Icosphere.Create(ocean, 6, planetVars.radius, Mathf.RoundToInt(Random.value * int.MaxValue), 0, 0); ocean.AddComponent <MeshRenderer>(); ocean.transform.parent = planet.transform; //Make ocean material Material oceanMaterial = new Material(triplanar); oceanMaterial.SetTexture("_MainTex", water); oceanMaterial.SetTexture("_MainTex1", water); oceanMaterial.SetTexture("_MainTex2", water); ocean.GetComponent <MeshRenderer>().material = oceanMaterial; //Set starting position planet.transform.localScale = new Vector3(radius, radius, radius); planet.transform.position = Orbiter.GetPointOnEclipse(90, planetVars.orbit); }
public TileMap(Icosphere icos, MapSettings mapSettings, TileSettings tileSettings) { this.mapSettings = mapSettings; this.tileSettings = tileSettings; this.tiles = icos.GenerateTileMap(tileSettings.DEFAULT); }
private static void test01() //****************************************************************************80 // // Purpose: // // TEST01 tests SPHERE_ICOS_POINT_NUM. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 29 August 2010 // // Author: // // John Burkardt // { int edge_num; int factor; int factor_log; int node_num; int triangle_num; Console.WriteLine(""); Console.WriteLine("TEST01"); Console.WriteLine(" SPHERE_ICOS_POINT_NUM determines the size"); Console.WriteLine(" (number of vertices, edges and faces) in a grid"); Console.WriteLine(" on a sphere, made by subdividing an initial"); Console.WriteLine(" projected icosahedron."); Console.WriteLine(""); Console.WriteLine(" N determines the number of subdivisions of each"); Console.WriteLine(" edge of the icosahedral faces."); Console.WriteLine(""); Console.WriteLine(" N V E F"); Console.WriteLine(" -------- -------- -------- --------"); Console.WriteLine(""); for (factor = 1; factor <= 20; factor++) { node_num = Icosphere.sphere_icos_point_num(factor); edge_num = Icosphere.sphere_icos_edge_num(factor); triangle_num = Icosphere.sphere_icos_face_num(factor); Console.WriteLine(" " + factor.ToString().PadLeft(8) + " " + node_num.ToString().PadLeft(8) + " " + edge_num.ToString().PadLeft(8) + " " + triangle_num.ToString().PadLeft(8) + ""); } Console.WriteLine(""); Console.WriteLine(" Repeat, but using N constrained by doubling:"); Console.WriteLine(""); Console.WriteLine(" N V E F"); Console.WriteLine(" -------- -------- -------- --------"); Console.WriteLine(""); factor = 1; for (factor_log = 0; factor_log <= 10; factor_log++) { node_num = Icosphere.sphere_icos_point_num(factor); edge_num = Icosphere.sphere_icos_edge_num(factor); triangle_num = Icosphere.sphere_icos_face_num(factor); Console.WriteLine(" " + factor.ToString().PadLeft(8) + " " + node_num.ToString().PadLeft(8) + " " + edge_num.ToString().PadLeft(8) + " " + triangle_num.ToString().PadLeft(8) + ""); factor *= 2; } }
public void WebEntities() { PruneList.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref WebBox, PruneList); if (Missiles.Count > 0) { var missileBox = WebBox; foreach (var missile in Missiles) { if (missile.InScene && !missile.MarkedForClose && missileBox.Intersects(missile.PositionComp.WorldAABB)) { PruneList.Add(missile); } } } var shieldsStartIndex = PruneList.Count; foreach (var eShield in EnemyShields) { PruneList.Add(eShield); } var disableVoxels = Session.Enforced.DisableVoxelSupport == 1 || ShieldComp.Modulator == null || ShieldComp.Modulator.ModSet.Settings.ModulateVoxels; var voxelFound = false; var shieldFound = false; var entChanged = false; var iMoving = ShieldComp.GridIsMoving; var tick = Session.Instance.Tick; _enablePhysics = false; for (int i = 0; i < PruneList.Count; i++) { var ent = PruneList[i]; var entPhysics = ent.Physics; if (i < shieldsStartIndex) { var voxel = ent as MyVoxelBase; if (ent == null || (voxel == null && (entPhysics == null || entPhysics.IsPhantom || ent.DefinitionId == null)) || (voxel != null && (!iMoving || !GridIsMobile || disableVoxels || voxel != voxel.RootVoxel))) { continue; } bool quickReject; if (_isServer) { quickReject = ent is IMyEngineerToolBase || IgnoreCache.Contains(ent) || EnemyShields.Contains(ent) || FriendlyMissileCache.Contains(ent) || AuthenticatedCache.Contains(ent); } else { quickReject = (!(ent is MyCubeGrid) && voxel == null && !(ent is IMyCharacter)) || IgnoreCache.Contains(ent) || EnemyShields.Contains(ent) || AuthenticatedCache.Contains(ent); } var floater = ent as IMyFloatingObject; if (quickReject || floater != null && (!iMoving && Vector3.IsZero(entPhysics.LinearVelocity, 1e-2f)) || !WebSphere.Intersects(ent.PositionComp.WorldVolume)) { continue; } if (voxel != null) { if (VoxelsToIntersect.ContainsKey(voxel)) { VoxelsToIntersect[voxel]++; } else { VoxelsToIntersect[voxel] = 1; } voxelFound = true; entChanged = true; _enablePhysics = true; continue; } } Ent relation; ProtectCache protectedEnt; EntIntersectInfo entInfo = null; ProtectedEntCache.TryGetValue(ent, out protectedEnt); var refreshInfo = false; if (protectedEnt == null) { WebEnts.TryGetValue(ent, out entInfo); if (entInfo != null) { var last = entInfo.LastTick; var refresh = entInfo.RefreshTick; var refreshTick = tick - last > 180 || (tick - last == 180 && tick - refresh >= 3600) || (tick - last == 1 && tick - refresh >= 60); refreshInfo = refreshTick; if (refreshInfo || entInfo.RefreshNow) { entInfo.RefreshTick = tick; entInfo.Relation = EntType(ent); } relation = entInfo.Relation; entInfo.LastTick = tick; } else { relation = EntType(ent); } } else { var last = protectedEnt.LastTick; var refresh = protectedEnt.RefreshTick; var refreshTick = tick - last > 180 || (tick - last == 180 && tick - refresh >= 3600) || (tick - last == 1 && tick - refresh >= 60); refreshInfo = refreshTick; if (refreshInfo) { protectedEnt.RefreshTick = tick; protectedEnt.PreviousRelation = protectedEnt.Relation; protectedEnt.Relation = EntType(ent); } relation = protectedEnt.Relation; protectedEnt.LastTick = tick; } switch (relation) { case Ent.Authenticated: continue; case Ent.Ignore: case Ent.Friendly: case Ent.Protected: if (relation == Ent.Protected) { if (protectedEnt == null) { ProtectedEntCache[ent] = new ProtectCache(tick, tick, tick, relation, relation); } MyProtectors protectors; Session.Instance.GlobalProtect.TryGetValue(ent, out protectors); if (protectors == null) { protectors = Session.Instance.GlobalProtect[ent] = Session.ProtSets.Get(); protectors.Init(LogicSlot, tick); } if (protectors.Shields.Contains(this)) { continue; } protectors.Shields.Add(this); protectors.Shields.ApplyAdditions(); continue; } IgnoreCache.Add(ent); continue; } if (relation == Ent.Shielded) { shieldFound = true; } try { if (entInfo != null) { var interestingEnts = relation == Ent.Floater || relation == Ent.EnemyGrid || relation == Ent.NobodyGrid || relation == Ent.Shielded; if (entPhysics != null && entPhysics.IsMoving) { entChanged = true; } else if (entInfo.Touched || (refreshInfo && interestingEnts && !ent.PositionComp.LocalAABB.Equals(entInfo.Box))) { entInfo.RefreshTick = tick; entInfo.Box = ent.PositionComp.LocalAABB; entChanged = true; } _enablePhysics = true; if (refreshInfo) { if ((relation == Ent.EnemyGrid || relation == Ent.NobodyGrid) && entInfo.CacheBlockList.Count != (ent as MyCubeGrid).BlocksCount) { entInfo.RefreshNow = true; } } } else { if (relation == Ent.Other) { var entPast = -Vector3D.Normalize(entPhysics.LinearVelocity) * 6; var entTestLoc = ent.PositionComp.WorldVolume.Center + entPast; var centerStep = -Vector3D.Normalize(entTestLoc - DetectionCenter) * 2f; var counterDrift = centerStep + entTestLoc; if (CustomCollision.PointInShield(counterDrift, DetectMatrixOutsideInv)) { FriendlyMissileCache.Add(ent); continue; } } entChanged = true; _enablePhysics = true; ProtectedEntCache.Remove(ent); WebEnts.TryAdd(ent, new EntIntersectInfo(false, ent.PositionComp.LocalAABB, tick, tick, tick, relation)); } } catch (Exception ex) { Log.Line($"Exception in WebEntities entInfo: {ex}"); } } if (!_enablePhysics) { return; } ShieldMatrix = ShieldEnt.PositionComp.WorldMatrix; if ((_needPhysics && shieldFound) || !ShieldMatrix.EqualsFast(ref OldShieldMatrix)) { OldShieldMatrix = ShieldMatrix; if (shieldFound) { _needPhysics = false; Icosphere.ReturnPhysicsVerts(DetectMatrixOutside, ShieldComp.PhysicsOutside); } else { _needPhysics = true; } if (voxelFound) { Icosphere.ReturnPhysicsVerts(DetectMatrixOutside, ShieldComp.PhysicsOutsideLow); } } if (iMoving || entChanged) { Asleep = false; LastWokenTick = tick; Session.Instance.WebWrapper.Enqueue(this); Session.Instance.WebWrapperOn = true; } }
public void Draw(int onCount, bool sphereOnCamera) { _onCount = onCount; var renderId = MyGrid.Render.GetRenderObjectID(); var percent = DsState.State.ShieldPercent; var reInforce = DsState.State.ReInforce; //var hitAnim = !reInforce && DsSet.Settings.HitWaveAnimation; Vector3D impactPos; lock (HandlerImpact) impactPos = HandlerImpact.Active ? ComputeHandlerImpact() : WorldImpactPosition; var intersected = WorldImpactPosition != Vector3D.NegativeInfinity && impactPos != Vector3D.Zero; WorldImpactPosition = impactPos; var activeVisible = DetermineVisualState(reInforce); WorldImpactPosition = Vector3D.NegativeInfinity; var vanillaHit = EnergyHit != HitType.Other; var kineticHit = EnergyHit == HitType.Kinetic; _localImpactPosition = Vector3D.NegativeInfinity; if (impactPos != Vector3D.NegativeInfinity && (kineticHit && KineticCoolDown < 0 || EnergyHit == HitType.Energy && EnergyCoolDown < 0 || EnergyHit == HitType.Other)) { if (_isServer && WebDamage && GridIsMobile) { Vector3 pointVel; var gridCenter = DetectionCenter; MyGrid.Physics.GetVelocityAtPointLocal(ref gridCenter, out pointVel); impactPos += (Vector3D)pointVel * Session.TwoStep; } if (kineticHit) { KineticCoolDown = 0; } else if (EnergyHit == HitType.Energy) { EnergyCoolDown = 0; } if (EnergyHit != HitType.Other) { HitParticleStart(impactPos, intersected); } var cubeBlockLocalMatrix = MyGrid.PositionComp.LocalMatrixRef; var referenceWorldPosition = cubeBlockLocalMatrix.Translation; var worldDirection = impactPos - referenceWorldPosition; var localPosition = Vector3D.TransformNormal(worldDirection, MatrixD.Transpose(cubeBlockLocalMatrix)); _localImpactPosition = localPosition; } EnergyHit = HitType.Kinetic; if (DsState.State.Online) { var prevlod = _prevLod; var lod = CalculateLod(_onCount); if (_shapeChanged || _updateRender || lod != prevlod) { _updateRender = false; _shapeChanged = false; Icosphere.CalculateTransform(ShieldShapeMatrix, lod); if (!GridIsMobile) { Icosphere.ReturnPhysicsVerts(DetectionMatrix, ShieldComp.PhysicsOutside); } } Icosphere.ComputeEffects(this, _localImpactPosition, prevlod, percent, activeVisible); } else if (_shapeChanged) { _updateRender = true; } var startPulse = Session.Instance.Tick20 && _toggle; var updated = Session.Instance.Tick300 || startPulse; var wasPulsing = _sidePulsing; if (updated && ShellActive != null && RedirectVisualUpdate()) { UpdateShieldRedirectVisuals(); } if (ShellActive != null && _sidePulsing) { SidePulseRender(); } if (wasPulsing && !_sidePulsing) { ClearSidePulse(); } if (sphereOnCamera && DsState.State.Online && Session.Instance.Settings.ClientConfig.ShowHitRings || vanillaHit) { Icosphere.Draw(renderId, this); } }
public static void RenderTile(Mesh mesh, SCoord tileCenter, Icosphere hexSphere) { // Make a linked list of the coordinate's neighbors LinkedList <SCoord> neighbors; // hexes are not triangles neighbors = new LinkedList <SCoord>(hexSphere.GetNeighbors(tileCenter)); // Make list of vertices List <Vector3> vertices = new List <Vector3>(neighbors.Count + 1); // Make list of normals for each vertex List <Vector3> normals = new List <Vector3>(neighbors.Count + 1); // Make list of UV coordinates for each vertex List <Vector2> uvLocations = new List <Vector2>(neighbors.Count + 1); // Setup lookup table for vertices Dictionary <SCoord, int> keyLookup = new Dictionary <SCoord, int>(); keyLookup.Add(tileCenter, keyLookup.Count); uvLocations.Add(new Vector2(0.5f, 0.5f)); vertices.Add(hexSphere.GetPoint(tileCenter)); normals.Add(tileCenter.ToEuclidian()); float radPerVertex = Mathf.PI * 2 / neighbors.Count; SCoord startVertex = neighbors.First.Value; SCoord source = startVertex; neighbors.RemoveFirst(); // Get the order of neighbors (forward or backward just wrapping around center) LinkedList <SCoord> orderedNeighbors = new LinkedList <SCoord>(); orderedNeighbors.AddLast(startVertex); // Calculate the teselated edges of the hexagon/pentagon while (neighbors.Count > 1) { // Find the next SCoord in the sequence of neighbors (neighbor to origin that is // adjacent to the previous neighbor) LinkedListNode <SCoord> nextVertex = neighbors.First; while (!new List <SCoord>(hexSphere.GetNeighbors(nextVertex.Value)).Contains(source)) { nextVertex = nextVertex.Next; } orderedNeighbors.AddLast(nextVertex.Value); // Save current vertex as previous vertex source = nextVertex.Value; // Remove current vertex so it is not checked again neighbors.Remove(nextVertex); } // Finish list of ordered neighbors orderedNeighbors.AddLast(neighbors.First.Value); foreach (SCoord n in orderedNeighbors) { keyLookup.Add(n, keyLookup.Count); } List <SCoord> neighborList = new List <SCoord>(orderedNeighbors); List <int> triangleList = new List <int>(); for (int idx = 0; idx < neighborList.Count; idx++) { // Get the centroid of the three adjacent tiles SCoord vert = SCoord.GetCentroid(tileCenter, neighborList[idx], neighborList[(idx + 1) % neighborList.Count]); // Sort the coordinates in the correct order so the face is visible SCoord[] triangleCoords = SCoord.SortClockwiseOrder(tileCenter, neighborList[idx], neighborList[(idx + 1) % neighborList.Count]); // Add the vertex vertices.Add(hexSphere.GetPoint(vert)); // Add the normal vector of the vertex normals.Add(vert.ToEuclidian()); // Add UV coordinate for this vertex Vector2 uv = new Vector2(0.5f + Mathf.Cos(radPerVertex * idx) * 0.5f, 0.5f + Mathf.Sin(radPerVertex * idx) * 0.5f); uvLocations.Add(new Vector2(0.5f + Mathf.Cos(radPerVertex * idx) * 0.5f, 0.5f + Mathf.Sin(radPerVertex * idx) * 0.5f)); // Add the triangles (set of three vertices) triangleList.Add(keyLookup[triangleCoords[2]]); triangleList.Add(keyLookup[triangleCoords[1]]); triangleList.Add(keyLookup[triangleCoords[0]]); } // Flatten out the center of the hex so it doesn't arch out Vector3 flatCenter = Vector3.zero; for (int i = 1; i < vertices.Count; i++) { flatCenter += vertices[i]; } flatCenter /= (vertices.Count - 1); vertices[0] = flatCenter; // assign values to mesh mesh.vertices = vertices.ToArray(); mesh.normals = normals.ToArray(); mesh.triangles = triangleList.ToArray(); mesh.uv = uvLocations.ToArray(); }
public void Draw(int onCount, bool sphereOnCamera) { _onCount = onCount; var renderId = MyGrid.Render.GetRenderObjectID(); var percent = DsState.State.ShieldPercent; var reInforce = DsState.State.ReInforce; var hitAnim = !reInforce && DsSet.Settings.HitWaveAnimation; var refreshAnim = !reInforce && DsSet.Settings.RefreshAnimation; Vector3D impactPos; lock (HandlerImpact) impactPos = HandlerImpact.Active ? ComputeHandlerImpact() : WorldImpactPosition; var intersected = WorldImpactPosition != Vector3D.NegativeInfinity && impactPos != Vector3D.Zero; WorldImpactPosition = impactPos; var activeVisible = DetermineVisualState(reInforce); WorldImpactPosition = Vector3D.NegativeInfinity; var kineticHit = EnergyHit == HitType.Kinetic; _localImpactPosition = Vector3D.NegativeInfinity; if (impactPos != Vector3D.NegativeInfinity && (kineticHit && KineticCoolDown < 0 || EnergyHit == HitType.Energy && EnergyCoolDown < 0)) { if (_isServer && WebDamage && GridIsMobile) { Vector3 pointVel; var gridCenter = MyGrid.PositionComp.WorldAABB.Center; MyGrid.Physics.GetVelocityAtPointLocal(ref gridCenter, out pointVel); impactPos += (Vector3D)pointVel * Session.TwoStep; } if (kineticHit) { KineticCoolDown = 0; } else if (EnergyHit == HitType.Energy) { EnergyCoolDown = 0; } if (EnergyHit != HitType.Other) { HitParticleStart(impactPos, intersected); } var cubeBlockLocalMatrix = MyGrid.PositionComp.LocalMatrix; var referenceWorldPosition = cubeBlockLocalMatrix.Translation; var worldDirection = impactPos - referenceWorldPosition; var localPosition = Vector3D.TransformNormal(worldDirection, MatrixD.Transpose(cubeBlockLocalMatrix)); _localImpactPosition = localPosition; } EnergyHit = HitType.Kinetic; if (DsState.State.Online) { var prevlod = _prevLod; var lod = CalculateLod(_onCount); if (_shapeChanged || _updateRender || lod != prevlod) { _updateRender = false; _shapeChanged = false; Icosphere.CalculateTransform(ShieldShapeMatrix, lod); if (!GridIsMobile) { Icosphere.ReturnPhysicsVerts(DetectionMatrix, ShieldComp.PhysicsOutside); } } Icosphere.ComputeEffects(ShieldShapeMatrix, _localImpactPosition, _shellPassive, _shellActive, prevlod, percent, activeVisible, refreshAnim); } else if (_shapeChanged) { _updateRender = true; } if (hitAnim && sphereOnCamera && DsState.State.Online) { Icosphere.Draw(renderId); } }
// Init is called on startup. public override void Init() { var fontLato = AssetStorage.Get <Font>("Lato-Black.ttf"); var fontLatoMap = new FontMap(fontLato, 32); var vsTex = AssetStorage.Get <string>("texture.vert"); var psTex = AssetStorage.Get <string>("texture.frag"); var icosphereWithTangents = new Icosphere(5); icosphereWithTangents.Tangents = icosphereWithTangents.CalculateTangents(); icosphereWithTangents.BiTangents = icosphereWithTangents.CalculateBiTangents(); icosphereWithTangents.BoundingBox = new AABBf(icosphereWithTangents.Vertices); var canvasWidth = Width / 100f; var canvasHeight = Height / 100f; var guiDescriptionScene = new SceneContainer { Children = new List <SceneNode> { new CanvasNode("Canvas", CanvasRenderMode.World, new MinMaxRect { Min = new float2(-canvasWidth / 2, -canvasHeight / 2f), Max = new float2(canvasWidth / 2, canvasHeight / 2f) }) { Children = new ChildList { new TextNode( "How-To:\n############################\n- Move with WASD\n- Left mouse button rotates spheres\n- Mouse wheel zooms", "howTo", vsTex, psTex, UIElementPosition.GetAnchors(AnchorPos.DownDownLeft), UIElementPosition.CalcOffsets(AnchorPos.DownDownLeft, new float2(-11, -5), canvasHeight, canvasWidth, new float2(12, 1)), fontLatoMap, new float4(1, 1, 0, 1), HorizontalTextAlignment.Left, VerticalTextAlignment.Center) } }, new CanvasNode("Complete", CanvasRenderMode.World, MinMaxRect.FromCenterSize(float2.Zero, float2.One)) { Components = new List <SceneComponent> { new Transform { Name = "TextTransform", Translation = new float3(-15, 2.5f, 0) } }, Children = new ChildList { new TextNode( "Complete", "desc", vsTex, psTex, MinMaxRect.FromCenterSize(float2.Zero, float2.One), new MinMaxRect(), fontLatoMap, new float4(0, 0, 0, 1), HorizontalTextAlignment.Left, VerticalTextAlignment.Center), new TextNode( "NOT YET IMPLEMENTED", "desc", vsTex, psTex, MinMaxRect.FromCenterSize(float2.Zero, float2.One), new MinMaxRect { Max = new float2(0, 0), Min = new float2(0, -1.25f) }, fontLatoMap, new float4(1, 0, 0, 0.5f), HorizontalTextAlignment.Left, VerticalTextAlignment.Center) } }, new CanvasNode("Albedo and specular", CanvasRenderMode.World, MinMaxRect.FromCenterSize(float2.Zero, float2.One)) { Components = new List <SceneComponent> { new Transform { Name = "TextTransform", Translation = new float3(-10, 2.5f, 0) } }, Children = new ChildList { new TextNode( "Albedo and Specular", "desc", vsTex, psTex, MinMaxRect.FromCenterSize(float2.Zero, float2.One), new MinMaxRect(), fontLatoMap, new float4(0, 0, 0, 1), HorizontalTextAlignment.Left, VerticalTextAlignment.Center) } }, new CanvasNode("Albedo, specular and albedo texture", CanvasRenderMode.World, MinMaxRect.FromCenterSize(float2.Zero, float2.One)) { Components = new List <SceneComponent> { new Transform { Name = "TextTransform", Translation = new float3(-5, 2.5f, 0) } }, Children = new ChildList { new TextNode( "Albedo, specular and\nalbedo texture", "desc", vsTex, psTex, MinMaxRect.FromCenterSize(float2.Zero, float2.One), new MinMaxRect(), fontLatoMap, new float4(0, 0, 0, 1), HorizontalTextAlignment.Left, VerticalTextAlignment.Center) } }, new CanvasNode("Specular texture", CanvasRenderMode.World, MinMaxRect.FromCenterSize(float2.Zero, float2.One)) { Components = new List <SceneComponent> { new Transform { Name = "TextTransform", Translation = new float3(0, 2.5f, 0) } }, Children = new ChildList { new TextNode( "Specular texture", "desc", vsTex, psTex, MinMaxRect.FromCenterSize(float2.Zero, float2.One), new MinMaxRect(), fontLatoMap, new float4(0, 0, 0, 1), HorizontalTextAlignment.Left, VerticalTextAlignment.Center), new TextNode( "NOT YET IMPLEMENTED", "desc", vsTex, psTex, MinMaxRect.FromCenterSize(float2.Zero, float2.One), new MinMaxRect { Max = new float2(0, 0), Min = new float2(0, -1.25f) }, fontLatoMap, new float4(1, 0, 0, 0.75f), HorizontalTextAlignment.Left, VerticalTextAlignment.Center) } }, new CanvasNode("Normal map", CanvasRenderMode.World, MinMaxRect.FromCenterSize(float2.Zero, float2.One)) { Components = new List <SceneComponent> { new Transform { Name = "TextTransform", Translation = new float3(5, 2.5f, 0) } }, Children = new ChildList { new TextNode( "Normal map", "desc", vsTex, psTex, MinMaxRect.FromCenterSize(float2.Zero, float2.One), new MinMaxRect(), fontLatoMap, new float4(0, 0, 0, 1), HorizontalTextAlignment.Left, VerticalTextAlignment.Center) } }, new CanvasNode("Albedo and emissive", CanvasRenderMode.World, MinMaxRect.FromCenterSize(float2.Zero, float2.One)) { Components = new List <SceneComponent> { new Transform { Name = "TextTransform", Translation = new float3(10, 2.5f, 0) } }, Children = new ChildList { new TextNode( "Albedo and emissive", "desc", vsTex, psTex, MinMaxRect.FromCenterSize(float2.Zero, float2.One), new MinMaxRect(), fontLatoMap, new float4(0, 0, 0, 1), HorizontalTextAlignment.Left, VerticalTextAlignment.Center), new TextNode( "NOT YET IMPLEMENTED", "desc", vsTex, psTex, MinMaxRect.FromCenterSize(float2.Zero, float2.One), new MinMaxRect { Max = new float2(0, 0), Min = new float2(0, -1.25f) }, fontLatoMap, new float4(1, 0, 0, 0.75f), HorizontalTextAlignment.Left, VerticalTextAlignment.Center) } }, new CanvasNode("Albedo and emissive with texture", CanvasRenderMode.World, MinMaxRect.FromCenterSize(float2.Zero, float2.One)) { Components = new List <SceneComponent> { new Transform { Name = "TextTransform", Translation = new float3(15, 3, 0) } }, Children = new ChildList { new TextNode( "Albedo, emissive and\nemissive texture", "desc", vsTex, psTex, MinMaxRect.FromCenterSize(float2.Zero, float2.One), new MinMaxRect(), fontLatoMap, new float4(0, 0, 0, 1), HorizontalTextAlignment.Left, VerticalTextAlignment.Center), new TextNode( "NOT YET IMPLEMENTED", "desc", vsTex, psTex, MinMaxRect.FromCenterSize(float2.Zero, float2.One), new MinMaxRect { Max = new float2(0, 0), Min = new float2(0, -1.75f) }, fontLatoMap, new float4(1, 0, 0, 0.75f), HorizontalTextAlignment.Left, VerticalTextAlignment.Center) } } } }; _scene = new SceneContainer { Header = new SceneHeader { CreatedBy = "MR", CreationDate = DateTime.Now.ToString(), Generator = "by hand" }, Children = new List <SceneNode> { new SceneNode { Children = new ChildList { new SceneNode { Components = new List <SceneComponent> { new Transform { Name = "complete", Translation = new float3(-15, 0, 0) }, ShaderCodeBuilder.MakeShaderEffectFromShaderEffectPropsProto(new ShaderEffectProps { MatProbs = { HasAlbedo = true, HasAlbedoTexture = true, HasSpecular = true, //HasSpecularTexture = true, HasEmissive = true, HasEmissiveTexture = true, HasNormalMap = true }, MatType = MaterialType.Standard, MatValues = { AlbedoColor = float4.One * 0.25f, AlbedoMix = 1f, AlbedoTexture = "albedoTex.jpg", SpecularColor = float4.One, SpecularIntensity = 2f, SpecularShininess = 25f, SpecularMix = 1f, //SpecularTexture = "specularTex.jpg", NormalMap = "normalTex.jpg", NormalMapIntensity = 1f, EmissiveColor = new float4(0, 1, 1, 1), EmissiveMix = 0.5f, EmissiveTexture = "emissiveTex.jpg" } }), icosphereWithTangents, } }, new SceneNode { Components = new List <SceneComponent> { new Transform { Name = "albedo and specular", Translation = new float3(-10, 0, 0) }, ShaderCodeBuilder.MakeShaderEffectProto(albedoColor: new float4(0.39f, 0.19f, 0, 1), specularColor: new float4(.5f, .5f, .5f, 1), shininess: 25.0f, specularIntensity: 2.5f), icosphereWithTangents } }, new SceneNode { Components = new List <SceneComponent> { new Transform { Name = "albedo, specular, albedo texture", Translation = new float3(-5, 0, 0) }, ShaderCodeBuilder.MakeShaderEffectProto(albedoColor: new float4(0.39f, 0.19f, 0, 1), specularColor: new float4(.5f, .5f, .5f, 1), albedoTexture: "albedoTex.jpg", albedoTextureMix: 1f, shininess: 256.0f, specularIntensity: 20.0f), icosphereWithTangents } }, // ---- Specular Textures are not implemented yet. There is no fitting shader! ---- // //new SceneNode //{ // Components = new List<SceneComponent> // { // new Transform // { // Name = "specular texture", // Translation = new float3(0, 0, 0) // }, // ShaderCodeBuilder.MakeShaderEffectFromShaderEffectPropsProto(new ShaderEffectProps // { // MatProbs = // { // HasAlbedo = true, // HasAlbedoTexture = true, // HasSpecular = true, // HasSpecularTexture = true // }, // MatType = MaterialType.Standard, // MatValues = // { // AlbedoColor = new float4(0.39f, 0.19f, 0, 1), // SpecularColor = float4.One, // SpecularIntensity = 2f, // SpecularShininess = 25f, // SpecularMix = 1f, // TODO: Implement in ShaderShards // SpecularTexture = "specularTex.jpg" // TODO: Implement in ShaderShards // } // }), // icosphereWithTangents // } //}, new SceneNode { Components = new List <SceneComponent> { new Transform { Name = "normal map", Translation = new float3(5, 0, 0) }, ShaderCodeBuilder.MakeShaderEffectFromShaderEffectPropsProto(new ShaderEffectProps { MatProbs = { HasAlbedo = true, HasAlbedoTexture = true, HasNormalMap = true, HasSpecular = true }, MatType = MaterialType.Standard, MatValues = { AlbedoColor = float4.One * 0.25f, AlbedoMix = 1f, AlbedoTexture = "albedoTex.jpg", SpecularColor = float4.One, SpecularIntensity = 5f, SpecularShininess = 200f, NormalMap = "normalTex.jpg", NormalMapIntensity = 1f } }), icosphereWithTangents } }, new SceneNode { Components = new List <SceneComponent> { new Transform { Name = "albedo, emissive", Translation = new float3(10, 0, 0) }, ShaderCodeBuilder.MakeShaderEffectFromShaderEffectPropsProto(new ShaderEffectProps { MatProbs = { HasAlbedo = true, HasAlbedoTexture = true, HasEmissive = true }, MatType = MaterialType.Standard, MatValues = { AlbedoColor = float4.One * 0.25f, AlbedoMix = 1f, AlbedoTexture = "albedoTex.jpg", EmissiveColor = new float4(1, 0, 0, 1) // TODO: Implement in ShaderShards } }), icosphereWithTangents } }, new SceneNode { Components = new List <SceneComponent> { new Transform { Name = "albedo, emissive, emissive texture", Translation = new float3(15, 0, 0) }, ShaderCodeBuilder.MakeShaderEffectFromShaderEffectPropsProto(new ShaderEffectProps { MatProbs = { HasAlbedo = true, HasAlbedoTexture = true, HasEmissive = true, HasEmissiveTexture = true }, MatType = MaterialType.Standard, MatValues = { AlbedoColor = float4.One * 0.25f, AlbedoMix = 1f, AlbedoTexture = "albedoTex.jpg", EmissiveColor = new float4(0, 1, 1, 1), // TODO: Implement in ShaderShards EmissiveMix = 0.5f, // TODO: Implement in ShaderShards EmissiveTexture = "emissiveTex.jpg" // TODO: Implement in ShaderShards } }), icosphereWithTangents } } } } } }; _guiDescRenderer = new SceneRendererForward(guiDescriptionScene); _renderer = new SceneRendererDeferred(_scene); }
// Start is called before the first frame update void Start() { // Make the icosphere sphere = new Icosphere(transform.position, radius); for (int sub = 0; sub < subdivsions; sub++) { sphere = sphere.SubdivideSphere(); } // Make the faces of the icosphere foreach (SCoord coord in sphere.Coordinates) { // Get the 3d coordinate of the sphere Vector3 point = sphere.GetPoint(coord); // Get the rotation of the face to make it tangent to the sphere Vector3 rotation = SCoord.GetRotation(coord); // Get the kind of object GameObject newObj = null; int degree = sphere.GetDegree(coord); if (degree == 5) { newObj = Instantiate(pentagonPrefab); } else { newObj = Instantiate(hexagonPrefab); } // Place and rotate object tangent to the sphere newObj.transform.eulerAngles = rotation; newObj.transform.position = point; newObj.transform.SetParent(this.transform); // Rotate the face to be line up correclty IEnumerator <SCoord> neighbors = sphere.GetNeighbors(coord).GetEnumerator(); neighbors.MoveNext(); SCoord neighbor = neighbors.Current; Vector3 targetVec = Vector3.ProjectOnPlane(neighbor.ToEuclidian() - coord.ToEuclidian(), newObj.transform.up).normalized; float angle = Mathf.Acos(Vector3.Dot(newObj.transform.right.normalized, targetVec)); if (float.IsNaN(angle)) { angle = 180; } Vector3 cross = Vector3.Cross(newObj.transform.right.normalized, targetVec); if (Vector3.Dot(newObj.transform.up.normalized, cross) < 0) { angle *= -1; } angle *= 180 / Mathf.PI; Debug.Log(angle); newObj.transform.Rotate(0, angle, 0, Space.Self); tiles.Add(coord, newObj); } }
public void Init(float radius, Icosphere icosphere, WorldData worldData) { _worldData = worldData; PlanetRadius = radius; Count = icosphere.Vertices.Length; Coordinate = new NativeArray <float2>(Count, Allocator.Persistent); SphericalPosition = new NativeArray <float3>(Count, Allocator.Persistent); CoriolisMultiplier = new NativeArray <float>(Count, Allocator.Persistent); Neighbors = new NativeArray <int>(Count * MaxNeighbors, Allocator.Persistent); ReverseNeighbors = new NativeArray <int>(Count * MaxNeighbors, Allocator.Persistent); NeighborsVert = new NativeArray <int>(Count * MaxNeighborsVert * worldData.AirLayers, Allocator.Persistent); ReverseNeighborsVert = new NativeArray <int>(Count * MaxNeighborsVert * worldData.AirLayers, Allocator.Persistent); NeighborDir = new NativeArray <float3>(Count * MaxNeighbors, Allocator.Persistent); NeighborDistInverse = new NativeArray <float>(Count * MaxNeighbors, Allocator.Persistent); NeighborTangent = new NativeArray <float3>(Count * MaxNeighbors, Allocator.Persistent); NeighborDiffInverse = new NativeArray <float3>(Count * MaxNeighbors, Allocator.Persistent); NeighborDist = new NativeArray <float>(Count * MaxNeighbors, Allocator.Persistent); float surfaceArea = 4 * math.PI * PlanetRadius * PlanetRadius; CellSurfaceArea = surfaceArea / Count; CellRadius = math.sqrt(CellSurfaceArea / math.PI); CellCircumference = math.PI * 2 * CellRadius; var neighborList = new List <Tuple <int, float3> > [Count]; for (int i = 0; i < Count; i++) { neighborList[i] = new List <Tuple <int, float3> >(); } for (int i = 0; i < Count; i++) { var v = icosphere.Vertices[i]; Coordinate[i] = new float2(-math.atan2(v.x, v.z), math.asin(v.y)); SphericalPosition[i] = new float3(v.x, v.y, v.z); } for (int i = 0; i < icosphere.Polygons.Count; i++) { var p = icosphere.Polygons[i]; for (int j = 0; j < 3; j++) { int vertIndex = p.m_Vertices[(j + 1) % 3]; neighborList[p.m_Vertices[j]].Add(new Tuple <int, float3>(vertIndex, SphericalPosition[vertIndex])); } } for (int i = 0; i < Count; i++) { var pos = SphericalPosition[i]; var forward = neighborList[i][0].Item2 - pos; float forwardLength = math.length(forward); neighborList[i].Sort(delegate(Tuple <int, float3> a, Tuple <int, float3> b) { float3 diffA = a.Item2 - pos; float3 diffB = b.Item2 - pos; float dotA = math.dot(diffA, forward); float dotB = math.dot(diffB, forward); float angleA = diffA.Equals(forward) ? 0 : math.acos(dotA / (math.length(diffA) * forwardLength)); float angleB = diffB.Equals(forward) ? 0 : math.acos(dotB / (math.length(diffB) * forwardLength)); angleA *= math.sign(math.dot(pos, math.cross(forward, diffA))); angleB *= math.sign(math.dot(pos, math.cross(forward, diffB))); return((int)math.sign(angleB - angleA)); }); for (int j = 0; j < MaxNeighbors; j++) { int index = i * MaxNeighbors + j; if (j < neighborList[i].Count) { int n = neighborList[i][j].Item1; Neighbors[index] = n; var diff = SphericalPosition[n] - pos; float dist = math.length(diff * PlanetRadius); NeighborDist[index] = dist; NeighborDistInverse[index] = 1.0f / dist; NeighborDir[index] = math.normalize(math.cross(math.cross(pos, diff), pos)); NeighborDiffInverse[index] = NeighborDir[index] * NeighborDistInverse[index]; NeighborTangent[index] = NeighborDir[index] * dist; } else { Neighbors[index] = -1; } } } for (int i = 0; i < Count * MaxNeighbors; i++) { ReverseNeighbors[i] = -1; int cellIndex = i / MaxNeighbors; int nIndex = Neighbors[i]; if (nIndex >= 0) { for (int j = 0; j < MaxNeighbors; j++) { if (Neighbors[nIndex * MaxNeighbors + j] == cellIndex) { ReverseNeighbors[i] = nIndex * MaxNeighbors + j; } } Debug.Assert(Neighbors[ReverseNeighbors[i]] == cellIndex); } } for (int i = 0; i < NeighborsVert.Length; i++) { int cellIndex = i / MaxNeighborsVert; int columnIndex = cellIndex % Count; int n = i - cellIndex * MaxNeighborsVert; int layer = cellIndex / Count; if (n == NeighborUp) { if (layer >= worldData.AirLayers - 2 || layer == 0) { NeighborsVert[i] = -1; } else { NeighborsVert[i] = cellIndex + Count; } } else if (n == NeighborDown) { if (layer <= 1 || layer == worldData.AirLayers - 1) { NeighborsVert[i] = -1; } else { NeighborsVert[i] = cellIndex - Count; } } else { int neighbor = Neighbors[columnIndex * MaxNeighbors + n]; if (neighbor >= 0) { NeighborsVert[i] = neighbor + layer * Count; } else { NeighborsVert[i] = -1; } } Debug.Assert(NeighborsVert[i] < Count * worldData.AirLayers); } for (int i = 0; i < NeighborsVert.Length; i++) { int cellIndex = i / MaxNeighborsVert; int columnIndex = cellIndex % Count; int n = i - cellIndex * MaxNeighborsVert; int layer = cellIndex / Count; if (n == NeighborUp) { if (layer >= worldData.AirLayers - 2 || layer == 0) { ReverseNeighborsVert[i] = -1; } else { ReverseNeighborsVert[i] = i + Count * MaxNeighborsVert - 1; } } else if (n == NeighborDown) { if (layer <= 1 || layer == worldData.AirLayers - 1) { ReverseNeighborsVert[i] = -1; } else { ReverseNeighborsVert[i] = i - Count * MaxNeighborsVert + 1; } } else { int neighbor = Neighbors[columnIndex * MaxNeighbors + n]; if (neighbor >= 0) { int reverseNeighbor = ReverseNeighbors[columnIndex * MaxNeighbors + n]; ReverseNeighborsVert[i] = (reverseNeighbor / MaxNeighbors) * MaxNeighborsVert + reverseNeighbor % MaxNeighbors + layer * Count * MaxNeighborsVert; } else { ReverseNeighborsVert[i] = -1; } } Debug.Assert(ReverseNeighborsVert[i] < 0 || NeighborsVert[ReverseNeighborsVert[i]] == cellIndex); } SortedDictionary <float, SortedDictionary <float, int> > vertsByCoord = new SortedDictionary <float, SortedDictionary <float, int> >(); for (int i = 0; i < Coordinate.Length; i++) { SortedDictionary <float, int> vertsAtLatitude; float latitude = Coordinate[i].y; if (!vertsByCoord.TryGetValue(latitude, out vertsAtLatitude)) { vertsAtLatitude = new SortedDictionary <float, int>(); vertsByCoord.Add(latitude, vertsAtLatitude); } vertsAtLatitude.Add(Coordinate[i].x, i); CoriolisMultiplier[i] = math.sin(latitude); } }
public void Draw(int onCount, bool sphereOnCamera) { _onCount = onCount; var renderId = MyGrid.Render.GetRenderObjectID(); var percent = DsState.State.ShieldPercent; var reInforce = DsState.State.ReInforce; var hitAnim = !reInforce && DsSet.Settings.HitWaveAnimation; var refreshAnim = !reInforce && DsSet.Settings.RefreshAnimation; var activeVisible = DetermineVisualState(reInforce); var impactPos = WorldImpactPosition; var webEffect = WebDamage && BulletCoolDown > -1 && WebCoolDown < 0; _localImpactPosition = Vector3D.NegativeInfinity; if (impactPos != Vector3D.NegativeInfinity && (BulletCoolDown < 0 || webEffect)) { if (webEffect) { WebCoolDown = 0; HitParticleStart(); } else { if (WebDamage) { WebCoolDown = 0; } BulletCoolDown = 0; HitParticleStart(); var cubeBlockLocalMatrix = MyGrid.PositionComp.LocalMatrix; var referenceWorldPosition = cubeBlockLocalMatrix.Translation; var worldDirection = impactPos - referenceWorldPosition; var localPosition = Vector3D.TransformNormal(worldDirection, MatrixD.Transpose(cubeBlockLocalMatrix)); _localImpactPosition = localPosition; } } WorldImpactPosition = Vector3D.NegativeInfinity; WebDamage = false; if (IsWorking) { var prevlod = _prevLod; var lod = CalculateLod(_onCount); if (_shapeChanged || _updateRender || lod != prevlod) { Icosphere.CalculateTransform(ShieldShapeMatrix, lod); if (!GridIsMobile) { Icosphere.ReturnPhysicsVerts(DetectionMatrix, ShieldComp.PhysicsOutside); } } Icosphere.ComputeEffects(ShieldShapeMatrix, _localImpactPosition, _shellPassive, _shellActive, prevlod, percent, activeVisible, refreshAnim); } if (hitAnim && sphereOnCamera && IsWorking) { Icosphere.Draw(renderId); } _updateRender = false; _shapeChanged = false; }