您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

254 行
8.3 KiB

using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.Jobs;
using UnityEngine.Profiling;
using Unity.Mathematics;
[DisableAutoCreation]
public class HandleTranslateScaleSpawns : InitializeComponentGroupSystem<TranslateScale, HandleTranslateScaleSpawns.Initialized>
{
ComponentGroup Group;
public struct Initialized : IComponentData {}
public HandleTranslateScaleSpawns(GameWorld world) : base(world) { }
protected override void OnCreateManager(int capacity)
{
base.OnCreateManager(capacity);
Group = GetComponentGroup(typeof(TranslateScale), ComponentType.Subtractive<DespawningEntity>());
}
protected override void Initialize(ref ComponentGroup group)
{
// Get all components of type, not just spawned/de-spawned ones
var array = Group.GetComponentArray<TranslateScale>();
TranslateScaleSystem.SetupTranslateScaleComponents(ref array);
}
}
[DisableAutoCreation]
public class HandleTranslateScaleDespawns : DeinitializeComponentGroupSystem<TranslateScale>
{
ComponentGroup Group;
public HandleTranslateScaleDespawns(GameWorld world) : base(world) { }
protected override void OnCreateManager(int capacity)
{
base.OnCreateManager(capacity);
Group = GetComponentGroup(typeof(TranslateScale), ComponentType.Subtractive<DespawningEntity>());
}
protected override void Deinitialize(ref ComponentGroup group)
{
// Get all components of type, not just spawned/de-spawned ones
var array = Group.GetComponentArray<TranslateScale>();
TranslateScaleSystem.SetupTranslateScaleComponents(ref array);
}
}
public class TranslateScaleSystem
{
public TranslateScaleSystem(GameWorld world)
{
m_HandleTranslateScaleSpawns = world.GetECSWorld().CreateManager<HandleTranslateScaleSpawns>(world);
m_HandleTranslateScaleDespawns = world.GetECSWorld().CreateManager<HandleTranslateScaleDespawns>(world);
m_World = world;
s_SourceJoints = new TransformAccessArray(k_MaxDrivers, 1);
s_SourceData = new NativeArray<SourceData>(k_MaxDrivers, Allocator.Persistent);
s_DrivenJoints = new TransformAccessArray(k_MaxDrivenJoints, 1);
s_TargetData = new NativeArray<TargetData>(k_MaxDrivenJoints, Allocator.Persistent);
}
public void ShutDown()
{
Complete();
s_SourceData.Dispose();
s_SourceJoints.Dispose();
s_DrivenJoints.Dispose();
s_TargetData.Dispose();
m_World.GetECSWorld().DestroyManager(m_HandleTranslateScaleSpawns);
m_World.GetECSWorld().DestroyManager(m_HandleTranslateScaleDespawns);
}
public void HandleSpawning()
{
m_HandleTranslateScaleSpawns.Update();
}
public void HandleDepawning()
{
m_HandleTranslateScaleDespawns.Update();
}
public static void SetupTranslateScaleComponents(ref ComponentArray<TranslateScale> translateScaleComponents)
{
s_DriverIndex = 0;
s_DrivenIndex = 0;
s_SourceJoints.SetTransforms(null);
s_DrivenJoints.SetTransforms(null);
for (var i = 0; i < translateScaleComponents.Length; i++)
{
for (var j = 0; j < translateScaleComponents[i].chains.Count; j++)
{
AddTranslateScaleChains(translateScaleComponents[i].chains[j]);
}
}
}
static void AddTranslateScaleChains(TranslateScale.TranslateScaleChain translateScaleChain)
{
if (!translateScaleChain.HasValidData())
return;
GameDebug.Assert(s_SourceJoints.length < k_MaxDrivers, "You are trying to add more translate scale chains then there is allocated space for.");
GameDebug.Assert(s_DrivenJoints.length + translateScaleChain.drivenJoints.Count <= k_MaxDrivenJoints, "You are trying to add more driven joint then there is allocated space for.");
s_SourceJoints.Add(translateScaleChain.driver);
s_SourceData[s_DriverIndex] = new SourceData
{
bindpose = translateScaleChain.bindpose
};
for (var j = 0; j < translateScaleChain.drivenJoints.Count; j++)
{
if (translateScaleChain.drivenJoints[j].joint != null)
{
s_DrivenJoints.Add(translateScaleChain.drivenJoints[j].joint);
s_TargetData[s_DrivenIndex] = new TargetData
{
sourceIndex = s_DriverIndex,
bindpose = translateScaleChain.drivenJoints[j].bindpose,
stretchFactor = translateScaleChain.drivenJoints[j].strectchFactor,
scaleFactor = translateScaleChain.drivenJoints[j].scaleFactor
};
s_DrivenIndex++;
}
}
s_DriverIndex++;
}
public JobHandle Schedule()
{
Profiler.BeginSample("TranslateScaleSystem.Schedule");
var readJob = new ReadJob(s_SourceData);
var readHandle = readJob.Schedule(s_SourceJoints);
var writeJob = new WriteJob(s_SourceData, s_TargetData);
m_WriteHandle = writeJob.Schedule(s_DrivenJoints, readHandle);
Profiler.EndSample();
return m_WriteHandle;
}
public JobHandle Schedule(JobHandle dependency)
{
Profiler.BeginSample("TranslateScaleSystem.Schedule");
var readJob = new ReadJob(s_SourceData);
var readHandle = readJob.Schedule(s_SourceJoints, dependency);
var writeJob = new WriteJob(s_SourceData, s_TargetData);
m_WriteHandle = writeJob.Schedule(s_DrivenJoints, readHandle);
Profiler.EndSample();
return m_WriteHandle;
}
public void Complete()
{
m_WriteHandle.Complete();
}
struct SourceData
{
public Vector3 bindpose;
public float stretchOffset;
public float stretchFactor;
}
struct TargetData
{
public int sourceIndex;
public float3 bindpose;
public float scaleFactor;
public float stretchFactor;
}
// TODO: Check the performance delta by using burst
[Unity.Burst.BurstCompile(CompileSynchronously = true)]
struct ReadJob : IJobParallelForTransform
{
NativeArray<SourceData> m_SourceData;
public ReadJob(NativeArray<SourceData> sourceData)
{
m_SourceData = sourceData;
}
public void Execute(int i, TransformAccess transform)
{
var data = m_SourceData[i];
data.stretchOffset = transform.localPosition.y - m_SourceData[i].bindpose.y;
data.stretchFactor = transform.localPosition.y / m_SourceData[i].bindpose.y;
m_SourceData[i] = data;
}
}
[Unity.Burst.BurstCompile(CompileSynchronously = true)]
struct WriteJob : IJobParallelForTransform
{
[ReadOnly]
NativeArray<SourceData> m_SourceData;
[ReadOnly]
NativeArray<TargetData> m_TargetData;
public WriteJob(NativeArray<SourceData> sourceData, NativeArray<TargetData> targetData)
{
m_SourceData = sourceData;
m_TargetData = targetData;
}
public void Execute(int i, TransformAccess transform)
{
// todo: Get rid of any unneeded allocations
// todo: new style math and burst?
transform.localPosition = m_TargetData[i].bindpose + new float3(0f, m_SourceData[m_TargetData[i].sourceIndex].stretchOffset * m_TargetData[i].stretchFactor, 0f);
var volumeScale = -m_TargetData[i].scaleFactor * m_SourceData[m_TargetData[i].sourceIndex].stretchFactor + 1 + m_TargetData[i].scaleFactor;
transform.localScale = new Vector3(volumeScale, 1f, volumeScale);
}
}
const int k_MaxDrivers = 1200;
const int k_MaxDrivenJoints = 4800;
static int s_DriverIndex;
static int s_DrivenIndex;
// TODO: (sunke) Move these onto unique component in the world?
static TransformAccessArray s_SourceJoints;
static TransformAccessArray s_DrivenJoints;
static NativeArray<SourceData> s_SourceData;
static NativeArray<TargetData> s_TargetData;
JobHandle m_WriteHandle;
protected GameWorld m_World;
readonly HandleTranslateScaleSpawns m_HandleTranslateScaleSpawns;
readonly HandleTranslateScaleDespawns m_HandleTranslateScaleDespawns;
}