Skip to content

Use with Godot Engine

Jens Krumsieck edited this page Jun 30, 2023 · 6 revisions

Using the Package with Godot Engine is quite simple. You just need to add a reference to ChemSharp.Molecules into the Scripting Project to use the library.

<Project Sdk="Godot.NET.Sdk/3.3.0">
	<PropertyGroup>
		<TargetFramework>netstandard2.1</TargetFramework>
	</PropertyGroup>
	<ItemGroup>
		<PackageReference Include="ChemSharp.Molecules">
			<Version>2.0.0</Version>
		</PackageReference>
	</ItemGroup>
</Project>

Here is a sample script for Godot adding scaled Spheres as Atoms and Cylinders for bonds. It inherits from Spatial which is the root 3D scene object

public class Spatial : Godot.Spatial
{
	// Declare member variables here. Examples:
	// private int a = 2;
	// private string b = "text";
	private string path = @"C:\\ORILUY.cif";

	private Camera cam;
	[Export] public Material mat;

	private MeshInstance node;

	// Called when the node enters the scene tree for the first time.
	public override void _Ready()
	{
		cam = GetChild<Camera>(0);
		var mol = Molecule.FromFile(path);
		node = new MeshInstance();
		foreach (var a in mol.Atoms)
		{
			var mesh = new MeshInstance
			{
				Mesh = new SphereMesh(),
				Translation = new Vector3(a.Location.X, a.Location.Y, a.Location.Z),
				Scale = Vector3.One * (a.CovalentRadius ?? 100) / 150,
			};
			var color = ColorTranslator.FromHtml(a.Color);
			var material = (SpatialMaterial)mat.Duplicate();
			material.AlbedoColor = Godot.Color.Color8(color.R, color.G, color.B, color.A);
			mesh.MaterialOverride = material;
			node.AddChild(mesh);
		}

		// ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
		foreach (var b in mol.Bonds)
		{
			var start = new Vector3(b.Atom1.Location.X, b.Atom1.Location.Y, b.Atom1.Location.Z);
			var end = new Vector3(b.Atom2.Location.X, b.Atom2.Location.Y, b.Atom2.Location.Z);
			var loc = start.LinearInterpolate(end, .5f);
			var lineVec = end - start;
			var axis = Vector3.Up.Cross(lineVec).Normalized();
			var rad = Mathf.Acos(Vector3.Up.Dot(lineVec.Normalized()));
			var matrix = new Quat(axis, rad);
			var mesh = new MeshInstance
			{
				Mesh = new CylinderMesh(), 
				Translation = loc, 
				MaterialOverride = mat,
				Scale = new Vector3(0.05f, lineVec.Length() / 2f, .05f),
				Rotation = matrix.GetEuler()
			};
			node.AddChild(mesh);
		}
			AddChild(node);
	}
}
Clone this wiki locally