Skip to content

Instantly share code, notes, and snippets.

@w0wca7a
Last active March 27, 2025 00:37
Show Gist options
  • Select an option

  • Save w0wca7a/202ccfcdf1b9e937fbfec599f251e90b to your computer and use it in GitHub Desktop.

Select an option

Save w0wca7a/202ccfcdf1b9e937fbfec599f251e90b to your computer and use it in GitHub Desktop.
[WIP] Random galaxies creation in Stride Game Engine. For use, drag and drop script to scene entities list. Add one or more materials to materials list, otherwise generator will be ignored.
// Copyright (c) Stride contributors (https://stride3d.net).
// Distributed under the MIT license.
using System;
using System.Collections.Generic;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Core;
using Stride.Rendering;
using Stride.Core.Annotations;
using Stride.Rendering.ProceduralModels;
public class GalaxyCreator : StartupScript
{
[DataMember]
[DataMemberRange(10, 40, 1, 15, 0)]
public int SphereRadiusFactor { get; set; } = 20; //10~30
[DataMember]
public int StarsCount { get; set; } = 8000;
[DataMember]
public int ArmsCount { get; set; } = 2;
[DataMember]
[DataMemberRange(0,5,0.5,1,1)]
public float TwistValue { get; set; } = 4f;
[DataMember]
public List<Material> MaterialsList { get; set; } = [];
[DataMember]
public bool MaterialInstancePerObject { get; set; } = false;
private Vector2[] points; // All objects will place in one plane, we use only two coordinates
private Material[] materials; // Array for random using materials
private static Vector2[] GenerateGalaxy(int numOfStars, int numOfArms, float spin, double armSpread, double starsAtCenterRatio)
{
List<Vector2> result = new(numOfStars);
for (int i = 0; i < numOfArms; i++)
{
result.AddRange(ArmsCreator(numOfStars/numOfArms, i/numOfArms, spin, armSpread, starsAtCenterRatio));
}
return [.. result];
}
private static Vector2[] ArmsCreator(int numOfStars, float rotation, float spin, double armSpread, double starsAtCenterRatio)
{
Vector2[] result = new Vector2[numOfStars];
Random r = new();
for (int i = 0; i < numOfStars; i++)
{
double part = i/numOfStars;
part = Math.Pow(part, starsAtCenterRatio);
float distanceFromCenter = (float)part;
double position = (part * spin + rotation) * Math.PI * 2;
double xBeating = (Dispersal(r.NextDouble()) - Dispersal(r.NextDouble())) * armSpread;
double yBeating = (Dispersal(r.NextDouble()) - Dispersal(r.NextDouble())) * armSpread;
float resultX = (float)Math.Cos(position) * distanceFromCenter / 2 + 0.5f + (float)xBeating;
float resultY = (float)Math.Sin(position) * distanceFromCenter / 2 + 0.5f + (float)yBeating;
result[i] = new Vector2(resultX, resultY);
}
return result;
}
private static double Dispersal(double x)
{
double value = Math.Pow(x - 0.5, 3) * 4 + 0.5d;
return Math.Max(Math.Min(1, value), 0);
}
private Model MModel()
{
var sphere = new SphereProceduralModel() { Radius = 0.02f / SphereRadiusFactor };
var model = sphere.Generate(Services);
return model;
}
public override void Start()
{
MaterialInstance materialInstance = null;
// Initialization of the script.
if (MaterialsList.Count != 0) { materials = [.. MaterialsList]; }
else { return; } // If no materials skip generation
if (!MaterialInstancePerObject)
{
materialInstance = new()
{
Material = materials[new Random().Next(materials.Length)]
};
}
points = GenerateGalaxy(StarsCount, ArmsCount, TwistValue, 0.1d, 1);
// fine looking, but need more VRAM - GenerateGalaxy(80000, 2, 3f, 0.1d, 3);
for (int i = 0; i < points.Length; i++)
{
Entity e = new(name: i.ToString(), new Vector3(new Vector2(points[i].X,
points[i].Y), 0.0f), rotation: null, scale: null);
//Log.Debug(e.Name);
SceneSystem.SceneInstance.RootScene.Entities.Add(e);
//Entity.Scene.Entities.Add(e);
if (MaterialInstancePerObject)
{
materialInstance = new()
{
Material = materials[new Random().Next(materials.Length)]
};
}
var Mats = MModel();
Mats.Materials.Insert(0, materialInstance);
//MModel().Materials.Add(materialInstance);
e.GetOrCreate<ModelComponent>().Model = Mats;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment