FlyCam additions, improve struct

Added property to get the camera from the player
Removed pointer magic
This commit is contained in:
Norbi Peti 2021-04-27 01:52:54 +02:00
parent 55b38f1678
commit 6e03847ab0
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
4 changed files with 163 additions and 104 deletions

View file

@ -1,26 +1,119 @@
using GamecraftModdingAPI.Players; using GamecraftModdingAPI.Players;
using GamecraftModdingAPI.Utility;
using RobocraftX.Physics;
using Svelto.ECS.EntityStructs; using Svelto.ECS.EntityStructs;
using Techblox.FlyCam;
using Unity.Mathematics; using Unity.Mathematics;
using UnityEngine;
namespace GamecraftModdingAPI namespace GamecraftModdingAPI
{ {
public class FlyCam public class FlyCam
{ {
private static FlyCamEngine Engine; private static FlyCamEngine Engine = new FlyCamEngine();
public uint Id { get; } public uint Id { get; }
public FlyCam(uint id) => Id = id; public FlyCam(uint id) => Id = id;
public unsafe float3 Position /// <summary>
/// The local player's camera.
/// </summary>
public static FlyCam LocalCamera => new FlyCam(Player.LocalPlayer.Id);
/// <summary>
/// The current position of the camera.
/// </summary>
public float3 Position
{ {
get => Engine.GetComponent<PositionEntityStruct>(Id).Map(pos => &pos->position); get => Engine.GetComponent<PositionEntityStruct>(Id).Get().position;
set => Engine.GetComponent<PositionEntityStruct>(Id).Map(pos => &pos->position).Set(value); set
{
Engine.GetComponent<PositionEntityStruct>(Id).Get().position = value;
Engine.GetComponent<RigidBodyEntityStruct>(Id).Get().position = value;
}
}
/// <summary>
/// The current rotation of the camera.
/// </summary>
public float3 Rotation
{
get => ((Quaternion) Engine.GetComponent<RotationEntityStruct>(Id).Get().rotation).eulerAngles;
set
{
Engine.GetComponent<RotationEntityStruct>(Id).Get().rotation = Quaternion.Euler(value);
Engine.GetComponent<RigidBodyEntityStruct>(Id).Get().rotation = Quaternion.Euler(value);
}
}
/// <summary>
/// The current direction the camera is moving.
/// </summary>
public float3 MovementDirection
{
get => Engine.GetComponent<FlyCamMovementComponent>(Id).Get().movementDirection;
set => Engine.GetComponent<FlyCamMovementComponent>(Id).Get().movementDirection = value;
}
/// <summary>
/// Whether the camera (player) is sprinting.
/// </summary>
public bool Sprinting
{
get => Engine.GetComponent<FlyCamMovementComponent>(Id).Get().sprinting;
set => Engine.GetComponent<FlyCamMovementComponent>(Id).Get().sprinting = value;
}
/// <summary>
/// The speed setting of the camera.
/// </summary>
public float Speed
{
get => Engine.GetComponent<FlyCamMovementSettingsComponent>(Id).Get().speed;
set => Engine.GetComponent<FlyCamMovementSettingsComponent>(Id).Get().speed = value;
}
/// <summary>
/// The multiplier setting to use when sprinting.
/// </summary>
public float SpeedSprintMultiplier
{
get => Engine.GetComponent<FlyCamMovementSettingsComponent>(Id).Get().speedSprintMultiplier;
set => Engine.GetComponent<FlyCamMovementSettingsComponent>(Id).Get().speedSprintMultiplier = value;
}
/// <summary>
/// The acceleration setting of the camera.
/// </summary>
public float Acceleration
{
get => Engine.GetComponent<FlyCamMovementSettingsComponent>(Id).Get().acceleration;
set => Engine.GetComponent<FlyCamMovementSettingsComponent>(Id).Get().acceleration = value;
}
/// <summary>
/// The current velocity of the camera.
/// </summary>
public float3 Velocity
{
get => Engine.GetComponent<RigidBodyEntityStruct>(Id).Get().velocity;
set => Engine.GetComponent<RigidBodyEntityStruct>(Id).Get().velocity = value;
}
/// <summary>
/// The current angular velocity of the camera.
/// </summary>
public float3 AngularVelocity
{
get => Engine.GetComponent<RigidBodyEntityStruct>(Id).Get().angularVelocity;
set => Engine.GetComponent<RigidBodyEntityStruct>(Id).Get().angularVelocity = value;
} }
public static void Init() public static void Init()
{ {
Engine = new FlyCamEngine(); GameEngineManager.AddGameEngine(Engine);
} }
} }
} }

View file

@ -1,99 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using GamecraftModdingAPI.Blocks;
using Svelto.DataStructures;
using Svelto.ECS;
namespace GamecraftModdingAPI
{
public struct OptionalRef<T> where T : unmanaged
{
private bool exists;
private NB<T> array;
private uint index;
private unsafe T* pointer;
public OptionalRef(NB<T> array, uint index)
{
exists = true;
this.array = array;
this.index = index;
unsafe
{
pointer = null;
}
}
public OptionalRef(ref T value)
{
unsafe
{
fixed(T* p = &value) pointer = p;
}
exists = true;
array = default;
index = default;
}
public ref T Get()
{
unsafe
{
if (pointer != null && exists)
return ref *pointer;
}
if (exists)
return ref array[index];
throw new InvalidOperationException("Calling Get() on an empty OptionalRef");
}
public T Value
{
get
{
unsafe
{
if (pointer != null && exists)
return *pointer;
}
if (exists)
return array[index];
return default;
}
}
public unsafe void Set(T value) //Can't use properties because it complains that you can't set struct members
{
if (pointer != null && exists)
*pointer = value;
}
public bool Exists => exists;
public static implicit operator T(OptionalRef<T> opt) => opt.Value;
public static implicit operator bool(OptionalRef<T> opt) => opt.exists;
public delegate ref TR Mapper<TR>(ref T component) where TR : unmanaged;
public unsafe delegate TR* PMapper<TR>(T* component) where TR : unmanaged;
/*public OptionalRef<TR> Map<TR>(Mapper<TR> mapper) where TR : unmanaged =>
exists ? new OptionalRef<TR>(ref mapper(ref Get())) : new OptionalRef<TR>();*/
/*public OptionalRef<TR> Map<TR>(Expression<Func<T, TR>> expression) where TR : unmanaged
{
if (expression.Body.NodeType == ExpressionType.MemberAccess)
Console.WriteLine(((MemberExpression) expression.Body).Member);
}*/
public unsafe OptionalRef<TR> Map<TR>(PMapper<TR> mapper) where TR : unmanaged =>
exists ? new OptionalRef<TR>(ref *mapper(pointer)) : new OptionalRef<TR>();
}
}

View file

@ -414,6 +414,11 @@ namespace GamecraftModdingAPI
return playerEngine.GetSelectedBlocks(Id); return playerEngine.GetSelectedBlocks(Id);
} }
/// <summary>
/// The camera of this player used when building.
/// </summary>
public FlyCam BuildCamera => new FlyCam(Id);
public bool Equals(Player other) public bool Equals(Player other)
{ {
if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(null, other)) return false;

View file

@ -0,0 +1,60 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using GamecraftModdingAPI.Blocks;
using Svelto.DataStructures;
using Svelto.ECS;
namespace GamecraftModdingAPI
{
public struct OptionalRef<T> where T : unmanaged
{
private bool exists;
private NB<T> array;
private uint index;
public OptionalRef(NB<T> array, uint index)
{
exists = true;
this.array = array;
this.index = index;
}
public OptionalRef(ref T value)
{
exists = true;
array = default;
index = default;
}
public ref T Get(T def = default)
{
if (exists)
return ref array[index];
return ref CompRefCache<T>._default;
}
public bool Exists => exists;
public static implicit operator T(OptionalRef<T> opt) => opt.Get();
public static implicit operator bool(OptionalRef<T> opt) => opt.exists;
/*public delegate ref TR Mapper<TR>(ref T component) where TR : unmanaged;
public unsafe delegate TR* PMapper<TR>(T* component) where TR : unmanaged;
public unsafe OptionalRef<TR> Map<TR>(PMapper<TR> mapper) where TR : unmanaged =>
exists ? new OptionalRef<TR>(ref *mapper(pointer)) : new OptionalRef<TR>();*/
/// <summary>
/// Creates an instance of a struct T that can be referenced.
/// </summary>
/// <typeparam name="T">The struct type to cache</typeparam>
private struct CompRefCache<T> where T : unmanaged
{
public static T _default;
}
}
}