-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUnivarsalGravitationController.cs
134 lines (101 loc) · 4.09 KB
/
UnivarsalGravitationController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using System;
using System.Linq;
using UnityEditor;
public class UnivarsalGravitationController : MonoBehaviour
{
[Tooltip("Please add the objects to be subjected to universal gravitation to the list by dragging and dropping them from the Hierarchy view.")]
[SerializeField]
public List<Rigidbody> TargetsList;
[Tooltip("Turn on to add all Rigidbodies to the list.")]
public bool AddAllRigidbody;
// Coefficient to multiply for a given force (to visible easily)
[SerializeField]
[Range(1, 100000000000)] // Range is able to change if necessary
public float COEFFICIENT;
// Universal constant of gravitation
[HideInInspector]
public float CONSTANT;
[SerializeField]
private ComputeShader _computeShader;
private ComputeBuffer _input_buffer;
private ComputeBuffer _result_buffer;
private int _kernel;
private struct InputBufferData
{
public float mass;
public Vector3 position;
}
private struct ResultBufferData
{
public Vector3 force;
}
/// <summary>
/// List of data to be sent to ComputeShader
/// </summary>
private List<InputBufferData> inputBufferDataList = new List<InputBufferData>();
/// <summary>
/// Array to store the data received
/// </summary>
private ResultBufferData[] resultBufferDataArray;
void Awake()
{
// Add Rigidbodies to the Target List
if(AddAllRigidbody){
Rigidbody[] rblist = FindObjectsOfType<Rigidbody>();
TargetsList = TargetsList.Union(rblist).ToList();
}
else if(TargetsList.Count == 0){
Debug.LogError("Please add Rigidbodies to the Target List.");
EditorApplication.isPlaying = false;
}
// Calculate universal constant of gravitation
CONSTANT = 6.674f * Mathf.Pow(10, -11);
// Disable useGravity on all Rigidbodies
for (int i = 0; i < TargetsList.Count; i++) TargetsList[i].useGravity = false;
// Initialisation of compute buffer
_input_buffer = new ComputeBuffer(TargetsList.Count, Marshal.SizeOf(typeof(InputBufferData)));
_result_buffer = new ComputeBuffer(TargetsList.Count, Marshal.SizeOf(typeof(ResultBufferData)));
// Set buffers in compute shader
_kernel = _computeShader.FindKernel("UGCalc");
_computeShader.SetBuffer(_kernel, "InputBuffer", _input_buffer);
_computeShader.SetBuffer(_kernel, "ResultBuffer", _result_buffer);
// Set each value
_computeShader.SetFloat("constant", CONSTANT);
_computeShader.SetFloat("coefficient",COEFFICIENT);
_computeShader.SetInt("listCount", TargetsList.Count);
// Initialized by setting the number of elements in the array to be received
resultBufferDataArray = new ResultBufferData[TargetsList.Count];
}
void FixedUpdate()
{
for (int i = 0; i < TargetsList.Count; i++)
{
// Create InputBufferData one by one from TargetList and add them to the list
InputBufferData inputBufferData = new InputBufferData(){
mass = TargetsList[i].mass,
position = TargetsList[i].transform.position
};
inputBufferDataList.Add(inputBufferData);
}
// Send the list via Buffer to the ComputeShader
_input_buffer.SetData(inputBufferDataList, 0, 0, inputBufferDataList.Count);
// Let ComputeShader do the calculation
_computeShader.Dispatch(_kernel,inputBufferDataList.Count,1,1);
// Receive data array
_result_buffer.GetData(resultBufferDataArray);
// Empty the elements of the used list
for (int i = 0; i < resultBufferDataArray.Length; i++){
TargetsList[i].AddForce(resultBufferDataArray[i].force, ForceMode.Force);
}
inputBufferDataList.Clear();
}
private void OnDestroy()
{
_input_buffer.Release();
_result_buffer.Release();
}
}