浏览代码

more work on buoyancy jobs conversion

/main
Andre McGrail 7 年前
当前提交
d9fd1934
共有 5 个文件被更改,包括 1579 次插入298 次删除
  1. 1
      Assets/Objects/boats/Temp/Prefabs/_Boat.prefab
  2. 19
      Assets/Scripts/Boat/OnlineTut/BoatPhysics.cs
  3. 849
      Assets/Scripts/Boat/OnlineTut/ModifyBoatMesh.cs
  4. 1001
      Assets/scenes/Testing/BoatPhysics.unity
  5. 7
      Assets/scenes/Testing/BoatPhysics.unity.meta

1
Assets/Objects/boats/Temp/Prefabs/_Boat.prefab


m_Script: {fileID: 11500000, guid: 01c46922a8ed04b0081de10e51b3762f, type: 3}
m_Name:
m_EditorClassIdentifier:
vel: {x: 0, y: 0, z: 0}
torque: 0.01
horsePower: 35
throttle: 0

19
Assets/Scripts/Boat/OnlineTut/BoatPhysics.cs


//Script that's doing everything needed with the boat mesh, such as finding out which part is above the water
private ModifyBoatMesh modifyBoatMesh;
public ModifyBoatMesh.TriangleData[] triangleData;
//Mesh for debugging
private Mesh underWaterMesh;

void Update()
{
Profiler.BeginSample("GenerateUnderwaterMesh");
//Generate the under water mesh
modifyBoatMesh.GenerateUnderwaterMesh();
Profiler.EndSample();
StartCoroutine(modifyBoatMesh.ModifyBoatData());
triangleData = modifyBoatMesh.underWaterTriangleData.ToArray();
if(debugMesh)
modifyBoatMesh.DisplayMesh(underWaterMesh, "UnderWater Mesh", modifyBoatMesh.underWaterTriangleData);
//if(debugMesh)
//modifyBoatMesh.DisplayMesh(underWaterMesh, "UnderWater Mesh", modifyBoatMesh.underWaterTriangleData);
}
//Add all forces that act on the squares below the water

List<TriangleData> underWaterTriangleData = modifyBoatMesh.underWaterTriangleData;
List<ModifyBoatMesh.TriangleData> underWaterTriangleData = modifyBoatMesh.underWaterTriangleData;
TriangleData triangleData = underWaterTriangleData[i];
ModifyBoatMesh.TriangleData triangleData = underWaterTriangleData[i];
//Calculate the buoyancy force
Vector3 buoyancyForce = BuoyancyForce(rhoWater, triangleData);

}
//The buoyancy force so the boat can float
private Vector3 BuoyancyForce(float rho, TriangleData triangleData)
private Vector3 BuoyancyForce(float rho, ModifyBoatMesh.TriangleData triangleData)
{
//Buoyancy is a hydrostatic force - it's there even if the water isn't flowing or if the boat stays still

849
Assets/Scripts/Boat/OnlineTut/ModifyBoatMesh.cs


for(var i = 0; i < boatTris.Length; i++)
boatTris[i] = mesh.triangles[i];
boatTransformMatrix = boatObj.transform.localToWorldMatrix;
boatTransformMatrix = boatTrans.localToWorldMatrix;
}
void OnDisable()

NativeArray<int> boatTris;
Matrix4x4 boatTransformMatrix;
IEnumerator ModifyBoatData()
public IEnumerator ModifyBoatData()
{
///setup jobs
///Waves specfic

NativeArray<Vector3> wavePos = new NativeArray<Vector3>(128, Allocator.Temp); // To store the waves between calcs
///ModifyBoatMesh specific
//Triangledata array
//Triangledata array, finalDatapoint
boatTransformMatrix = boatTrans.localToWorldMatrix;
//Triangledatabase array, intermediate point
NativeArray<TriangleDataBase> triDataBase = new NativeArray<TriangleDataBase>(128, Allocator.TempJob);
int triDataBaseCount = 0;
//VertexData for both one above and two above
NativeArray<VertexDataSet> oneAbove = new NativeArray<VertexDataSet>(32, Allocator.TempJob);
int oneAboveCount = 0;
NativeArray<VertexDataSet> twoAbove = new NativeArray<VertexDataSet>(32, Allocator.TempJob);
int twoAboveCount = 0;
var localToWorld = new GlobalVertConversion()
{
inPos = boatVerts,
outPos = globalVertChecklist
};
//>>pass data to job2
var localToWorld = new GlobalVertConversion(){inPos = boatVerts, outPos = globalVertChecklist, matrix = boatTransformMatrix};
//>>pass globalVertChecklist data to job2 for distance
var localToWorldHandle = localToWorld.Schedule(boatVerts.Length, 32);
// ///JOB02 - dependant on job1
// //Height of all global verts

time = Time.time,
outPosition = wavePos
};
//>>pass wavePos to job2
var heightPass1Handle = heightPass1.Schedule(globalVertChecklist.Length, 4, localToWorldHandle);
var addTris = new AddTriangles()
{
wavePositions = wavePos,
globalVertexPos = globalVertChecklist,
boatTris = boatTris,
triDataBase = triDataBase,
triDataBaseCount = triDataBaseCount,
OneAbove = oneAbove,
OneAboveCount = oneAboveCount,
TwoAbove = twoAbove,
TwoAboveCount = twoAboveCount
};
var addTrisHandle = addTris.Schedule(heightPass1Handle);
var addOne = new OneAbove()
{
input = oneAbove,
inputCount = oneAboveCount,
output = triDataBase
};
var addOneHandle = addOne.Schedule(addTrisHandle);
///Mini job - add triangles 2 above
var addTwo = new TwoAbove()
{
input = twoAbove,
inputCount = twoAboveCount,
output = triDataBase
};
var addTwoHandle = addTwo.Schedule(addOneHandle);
///Mini job - add triangles 2 above
var triDataSorting = new TriangleDataSorting()
{
input = triDataBase,
output = triData
};
var dependancy = JobHandle.CombineDependencies(addTrisHandle, addOneHandle, addTwoHandle);
var triDataSortingHandle = triDataSorting.Schedule(triDataBase.Length, 4, dependancy);
while(!triDataSortingHandle.IsCompleted) yield return new WaitForEndOfFrame();
triDataSortingHandle.Complete();
///JOB04 - dependant on job3/minijob1/minijob2
//Height of all add tirangles
// var heightPass2 = new GerstnerWavesJobs.HeightJob()

// };
//Schedule all jobs
underWaterTriangleData.Clear();
int len = addTris.triDataBaseCount + (addTris.OneAboveCount * 2) + addTris.TwoAboveCount;
Debug.Log("Triangles to process " + len + " Datasample=" + addTris.boatTris[0]);
NativeSlice<TriangleData> triSlice = new NativeSlice<TriangleData>(triData, 0, len);
underWaterTriangleData.AddRange(triSlice.ToArray());
return null;
waveData.Dispose();
wavePos.Dispose();
triData.Dispose();
triDataBase.Dispose();
oneAbove.Dispose();
twoAbove.Dispose();
globalVertChecklist.Dispose();
}
//Job Get global positions to check

}
//Generate the underwater mesh
public void GenerateUnderwaterMesh()
{
//Reset
underWaterTriangleData.Clear();
//Find all the distances to water once because some triangles share vertices, so reuse
for (int j = 0; j < boatVertices.Length; j++)
{
//The coordinate should be in global position
Vector3 globalPos = boatTrans.TransformPoint(boatVertices[j]);
// public void GenerateUnderwaterMesh()
// {
// //Reset
// underWaterTriangleData.Clear();
// //Find all the distances to water once because some triangles share vertices, so reuse
// for (int j = 0; j < boatVertices.Length; j++)
// {
// //The coordinate should be in global position
// Vector3 globalPos = boatTrans.TransformPoint(boatVertices[j]);
//Save the global position so we only need to calculate it once here
//And if we want to debug we can convert it back to local
boatVerticesGlobal[j] = globalPos;
if(j%2==0)
{
allDistancesToWater[j] = -Water.Instance.GetWaterHeight(globalPos);
// //Save the global position so we only need to calculate it once here
// //And if we want to debug we can convert it back to local
// boatVerticesGlobal[j] = globalPos;
// if(j%2==0)
// {
// allDistancesToWater[j] = -Water.Instance.GetWaterHeight(globalPos);
}
else
{
allDistancesToWater[j] = allDistancesToWater[j-1];
}
}
// }
// else
// {
// allDistancesToWater[j] = allDistancesToWater[j-1];
// }
// }
// //Add the triangles that are below the water
// Profiler.BeginSample("AddTriangles");
// AddTriangles();
// Profiler.EndSample();
// }
//Add the triangles that are below the water
Profiler.BeginSample("AddTriangles");
AddTriangles();
Profiler.EndSample();
}
/*
struct AddTriangles : IJobParallelFor
struct AddTriangles : IJob
{
[ReadOnly]
public NativeArray<Vector3> wavePositions;

public NativeArray<int> boatTris;
public NativeArray<TriangleData> triData;
public int index;
public NativeArray<TriangleDataBase> triDataBase;
public int triDataBaseCount;
public void Execute(int i) // this has to process 3 verts at a time to make a tri calculation
{
VertexData[] vertData = new VertexData[3];
TriangleData triangle = new TriangleData();
int countAboveWater = 3;
int id = i;
//Two vert data out, one for add1 above and one for add two above
public NativeArray<VertexDataSet> OneAbove;
public int OneAboveCount;
public NativeArray<VertexDataSet> TwoAbove;
public int TwoAboveCount;
public float skipped;
for (int x = 0; x < 3; x++)
public void Execute() // this has to process 3 verts at a time to make a tri calculation
{
skipped += 1;
for(var i = 0; i < boatTris.Length; i += 3)
//Save the data we need
vertData[x].distance = globalVertexPos[id].y - wavePositions[id].y;
VertexData[] vertData = new VertexData[3];
TriangleDataBase triangle = new TriangleDataBase();
int countAboveWater = 3;
int id = i;
if(vertData[x].distance < 0f)
countAboveWater--;
for (int x = 0; x < 3; x++)
{
//Save the data we need
vertData[x].distance = globalVertexPos[boatTris[id]].y - wavePositions[boatTris[id]].y;
vertData[x].index = x;
if(vertData[x].distance < 0f)
countAboveWater--;
vertData[x].globalVertexPos = globalVertexPos[boatTris[id]];
id++;
}
vertData[x].index = x;
switch(countAboveWater)
{
case 3:
break;
case 0:
{
Vector3 p1 = vertData[0].globalVertexPos;
Vector3 p2 = vertData[1].globalVertexPos;
Vector3 p3 = vertData[2].globalVertexPos;
Vector3 d = new Vector3(vertData[0].distance, vertData[1].distance, vertData[2].distance);
//Save the triangle
triangle.p1 = p1;
triangle.p2 = p2;
triangle.p3 = p3;
triData[index].Add(new TriangleData(p1, p2, p3, d, true));
index++;
vertData[x].globalVertexPos = globalVertexPos[boatTris[id]];
id++;
break;
case 1:
switch(countAboveWater)
Array.Sort(vertData, delegate(VertexData v1, VertexData v2){return v2.distance.CompareTo(v1.distance);});
Profiler.BeginSample("AddTrianglesOneAboveWater");
AddTrianglesOneAboveWater();
Profiler.EndSample();
}
break;
case 2:
{
Array.Sort(vertexData, delegate(VertexData v1, VertexData v2){return v2.distance.CompareTo(v1.distance);});
Profiler.BeginSample("AddTrianglesTwoAboveWater");
AddTrianglesTwoAboveWater();
Profiler.EndSample();
case 3:
break;
case 0:
{
Vector3 p1 = vertData[0].globalVertexPos;
Vector3 p2 = vertData[1].globalVertexPos;
Vector3 p3 = vertData[2].globalVertexPos;
Vector3 d = new Vector3(vertData[0].distance, vertData[1].distance, vertData[2].distance);
//Save the triangle
triangle.p1 = p1;
triangle.p2 = p2;
triangle.p3 = p3;
triangle.distance = d;
triangle.full = 1;
triDataBase[triDataBaseCount] = triangle;
triDataBaseCount++;
}
break;
case 1:
{
Array.Sort(vertData, delegate(VertexData v1, VertexData v2){return v2.distance.CompareTo(v1.distance);});
VertexDataSet vs = new VertexDataSet();
vs.v1 = vertData[0];
vs.v2 = vertData[1];
vs.v3 = vertData[2];
OneAbove[OneAboveCount] = vs;
OneAboveCount++;
}
break;
case 2:
{
Array.Sort(vertData, delegate(VertexData v1, VertexData v2){return v2.distance.CompareTo(v1.distance);});
VertexDataSet vs = new VertexDataSet();
vs.v1 = vertData[0];
vs.v2 = vertData[1];
vs.v3 = vertData[2];
TwoAbove[TwoAboveCount] = vs;
TwoAboveCount++;
}
break;
break;
}*/
}
private void AddTriangles()
// private void AddTriangles()
// {
// //Loop through all the triangles (3 vertices at a time = 1 triangle)
// int i = 0;
// while(i < boatTriangles.Length)
// {
// int countAboveWater = 3;
// //Loop through the 3 vertices
// for (int x = 0; x < 3; x++)
// {
// //Save the data we need
// vertexData[x].distance = allDistancesToWater[boatTriangles[i]];
// if(vertexData[x].distance < 0f)
// countAboveWater--;
// vertexData[x].index = x;
// vertexData[x].globalVertexPos = boatVerticesGlobal[boatTriangles[i]];
// i++;
// }
// switch(countAboveWater)
// {
// case 3:
// break;
// case 0:
// {
// Vector3 p1 = vertexData[0].globalVertexPos;
// Vector3 p2 = vertexData[1].globalVertexPos;
// Vector3 p3 = vertexData[2].globalVertexPos;
// Vector3 d = new Vector3(vertexData[0].distance, vertexData[1].distance, vertexData[2].distance);
// //Save the triangle
// underWaterTriangleData.Add(new TriangleData(p1, p2, p3, d, true));
// }
// break;
// case 1:
// {
// Array.Sort(vertexData, delegate(VertexData v1, VertexData v2){return v2.distance.CompareTo(v1.distance);});
// Profiler.BeginSample("AddTrianglesOneAboveWater");
// AddTrianglesOneAboveWater();
// Profiler.EndSample();
// }
// break;
// case 2:
// {
// Array.Sort(vertexData, delegate(VertexData v1, VertexData v2){return v2.distance.CompareTo(v1.distance);});
// Profiler.BeginSample("AddTrianglesTwoAboveWater");
// AddTrianglesTwoAboveWater();
// Profiler.EndSample();
// }
// break;
// }
// }
// }
struct OneAbove : IJob
//Loop through all the triangles (3 vertices at a time = 1 triangle)
int i = 0;
while(i < boatTriangles.Length)
[ReadOnly]
public NativeArray<VertexDataSet> input;
[ReadOnly]
public int inputCount;
public NativeArray<TriangleDataBase> output;
public void Execute()
int countAboveWater = 3;
//Loop through the 3 vertices
for (int x = 0; x < 3; x++)
for(var i = 0; i < input.Length; i++)
{
VertexDataSet vds = input[i];
//H is always at position 0
Vector3 H = vds.v1.globalVertexPos;
//Left of H is M
//Right of H is L
//Find the index of M
int M_index = vds.v1.index - 1;
if (M_index < 0)
//Save the data we need
vertexData[x].distance = allDistancesToWater[boatTriangles[i]];
M_index = 2;
}
//We also need the heights to water
float h_H = vds.v1.distance;
float h_M = 0f;
float h_L = 0f;
if(vertexData[x].distance < 0f)
countAboveWater--;
Vector3 M = Vector3.zero;
Vector3 L = Vector3.zero;
vertexData[x].index = x;
//This means M is at position 1 in the List
if (vds.v2.index == M_index)
{
M = vds.v2.globalVertexPos;
L = vds.v3.globalVertexPos;
vertexData[x].globalVertexPos = boatVerticesGlobal[boatTriangles[i]];
i++;
h_M = vds.v2.distance;
h_L = vds.v3.distance;
else
{
M = vds.v3.globalVertexPos;
L = vds.v2.globalVertexPos;
// if(countAboveWater < 2)
// {
// Vector3 p1 = vertexData[0].globalVertexPos;
// Vector3 p2 = vertexData[1].globalVertexPos;
// Vector3 p3 = vertexData[2].globalVertexPos;
// //Save the triangle
// underWaterTriangleData.Add(new TriangleData(p1, p2, p3));
// }
// else
// {
// break;
// }
//Debug.Log(countAboveWater);
switch(countAboveWater)
{
case 3:
break;
case 0:
{
Vector3 p1 = vertexData[0].globalVertexPos;
Vector3 p2 = vertexData[1].globalVertexPos;
Vector3 p3 = vertexData[2].globalVertexPos;
Vector3 d = new Vector3(vertexData[0].distance, vertexData[1].distance, vertexData[2].distance);
//Save the triangle
underWaterTriangleData.Add(new TriangleData(p1, p2, p3, d, true));
}
break;
case 1:
{
Array.Sort(vertexData, delegate(VertexData v1, VertexData v2){return v2.distance.CompareTo(v1.distance);});
Profiler.BeginSample("AddTrianglesOneAboveWater");
AddTrianglesOneAboveWater();
Profiler.EndSample();
}
break;
case 2:
{
Array.Sort(vertexData, delegate(VertexData v1, VertexData v2){return v2.distance.CompareTo(v1.distance);});
Profiler.BeginSample("AddTrianglesTwoAboveWater");
AddTrianglesTwoAboveWater();
Profiler.EndSample();
}
break;
h_M = vds.v3.distance;
h_L = vds.v2.distance;
}
//Now we can calculate where we should cut the triangle to form 2 new triangles
//because the resulting area will always form a square
//Point I_M
Vector3 MH = H - M;
float t_M = -h_M / (h_H - h_M);
Vector3 MI_M = t_M * MH;
Vector3 I_M = MI_M + M;
//Point I_L
Vector3 LH = H - L;
float t_L = -h_L / (h_H - h_L);
Vector3 LI_L = t_L * LH;
Vector3 I_L = LI_L + L;
//Save the data, such as normal, area, etc
//2 triangles below the water
TriangleDataBase tri1 = new TriangleDataBase();
tri1.p1 = M;
tri1.p2 = I_M;
tri1.p2 = I_L;
tri1.distance = Vector3.zero;
tri1.full = 0;
output[inputCount + i*2] = tri1;
TriangleDataBase tri2 = new TriangleDataBase();
tri2.p1 = M;
tri2.p2 = I_L;
tri2.p2 = L;
tri2.distance = Vector3.zero;
tri2.full = 0;
output[inputCount + i*2 + 1] = tri2;
//Build the new triangles where one of the old vertices is above the water
private void AddTrianglesOneAboveWater()
struct TwoAbove : IJob
//H is always at position 0
Vector3 H = vertexData[0].globalVertexPos;
[ReadOnly]
public NativeArray<VertexDataSet> input;
[ReadOnly]
public int inputCount;
public int oneAboveCount;
//Left of H is M
//Right of H is L
public NativeArray<TriangleDataBase> output;
//Find the index of M
int M_index = vertexData[0].index - 1;
if (M_index < 0)
public void Execute()
M_index = 2;
}
for(var i = 0; i < input.Length; i++)
{
VertexDataSet vds = input[i];
//H and M are above the water
//H is after the vertice that's below water, which is L
//So we know which one is L because it is last in the sorted list
Vector3 L = vds.v3.globalVertexPos;
//We also need the heights to water
float h_H = vertexData[0].distance;
float h_M = 0f;
float h_L = 0f;
//Find the index of H
int H_index = vds.v3.index + 1;
if (H_index > 2)
{
H_index = 0;
}
Vector3 M = Vector3.zero;
Vector3 L = Vector3.zero;
//This means M is at position 1 in the List
if (vertexData[1].index == M_index)
{
M = vertexData[1].globalVertexPos;
L = vertexData[2].globalVertexPos;
//We also need the heights to water
float h_L = vds.v3.distance;
float h_H = 0f;
float h_M = 0f;
h_M = vertexData[1].distance;
h_L = vertexData[2].distance;
}
else
{
M = vertexData[2].globalVertexPos;
L = vertexData[1].globalVertexPos;
Vector3 H = Vector3.zero;
Vector3 M = Vector3.zero;
h_M = vertexData[2].distance;
h_L = vertexData[1].distance;
}
//This means that H is at position 1 in the list
if (vds.v2.index == H_index)
{
H = vds.v2.globalVertexPos;
M = vds.v1.globalVertexPos;
//Now we can calculate where we should cut the triangle to form 2 new triangles
//because the resulting area will always form a square
h_H = vds.v2.distance;
h_M = vds.v1.distance;
}
else
{
H = vds.v1.globalVertexPos;
M = vds.v2.globalVertexPos;
//Point I_M
Vector3 MH = H - M;
h_H = vds.v1.distance;
h_M = vds.v2.distance;
}
float t_M = -h_M / (h_H - h_M);
Vector3 MI_M = t_M * MH;
//Now we can find where to cut the triangle
Vector3 I_M = MI_M + M;
//Point J_M
Vector3 LM = M - L;
float t_M = -h_L / (h_M - h_L);
Vector3 LJ_M = t_M * LM;
Vector3 J_M = LJ_M + L;
//Point I_L
Vector3 LH = H - L;
//Point J_H
Vector3 LH = H - L;
float t_L = -h_L / (h_H - h_L);
float t_H = -h_L / (h_H - h_L);
Vector3 LI_L = t_L * LH;
Vector3 LJ_H = t_H * LH;
Vector3 I_L = LI_L + L;
Vector3 J_H = LJ_H + L;
//Save the data, such as normal, area, etc
//2 triangles below the water
underWaterTriangleData.Add(new TriangleData(M, I_M, I_L, Vector3.zero, false));
underWaterTriangleData.Add(new TriangleData(M, I_L, L, Vector3.zero, false));
//Save the data, such as normal, area, etc
//1 triangles below the water
TriangleDataBase tri1 = new TriangleDataBase();
tri1.p1 = L;
tri1.p2 = J_H;
tri1.p2 = J_M;
tri1.distance = Vector3.zero;
tri1.full = 0;
output[inputCount + oneAboveCount * 2 + i] = tri1;
}
}
//Build the new triangles where two of the old vertices are above the water
private void AddTrianglesTwoAboveWater()
struct TriangleDataSorting : IJobParallelFor
//H and M are above the water
//H is after the vertice that's below water, which is L
//So we know which one is L because it is last in the sorted list
Vector3 L = vertexData[2].globalVertexPos;
[ReadOnly]
public NativeArray<TriangleDataBase> input;
public NativeArray<TriangleData> output;
//Find the index of H
int H_index = vertexData[2].index + 1;
if (H_index > 2)
public void Execute(int i)
H_index = 0;
}
TriangleData triangleData = new TriangleData();
triangleData.p1 = input[i].p1;
triangleData.p2 = input[i].p2;
triangleData.p3 = input[i].p3;
//Center of the triangle
triangleData.center = (input[i].p1 + input[i].p2 + input[i].p3) * 0.3333f;
//We also need the heights to water
float h_L = vertexData[2].distance;
float h_H = 0f;
float h_M = 0f;
//Distance to the surface from the center of the triangle, we average it if triangle uncut
if(input[i].full == 1)
triangleData.distanceToSurface = Math.Abs((input[i].distance.x + input[i].distance.y + input[i].distance.z) * 0.3333f);
else
triangleData.distanceToSurface = 1234;
Vector3 H = Vector3.zero;
Vector3 M = Vector3.zero;
//Normal to the triangle
triangleData.normal = Vector3.Cross(input[i].p2 - input[i].p1, input[i].p3 - input[i].p1).normalized;
//This means that H is at position 1 in the list
if (vertexData[1].index == H_index)
{
H = vertexData[1].globalVertexPos;
M = vertexData[0].globalVertexPos;
//Area of the triangle
float a = Vector3.Distance(input[i].p1, input[i].p2);
h_H = vertexData[1].distance;
h_M = vertexData[0].distance;
}
else
{
H = vertexData[0].globalVertexPos;
M = vertexData[1].globalVertexPos;
float c = Vector3.Distance(input[i].p3, input[i].p1);
h_H = vertexData[0].distance;
h_M = vertexData[1].distance;
triangleData.area = (a * c * Mathf.Sin(Vector3.Angle(input[i].p2 - input[i].p1, input[i].p3 - input[i].p1) * Mathf.Deg2Rad)) * 0.5f;
triangleData.underWater = 1;
output[i] = triangleData;
}
//Build the new triangles where one of the old vertices is above the water
// private void AddTrianglesOneAboveWater()
// {
// //H is always at position 0
// Vector3 H = vertexData[0].globalVertexPos;
//Now we can find where to cut the triangle
// //Left of H is M
// //Right of H is L
//Point J_M
Vector3 LM = M - L;
// //Find the index of M
// int M_index = vertexData[0].index - 1;
// if (M_index < 0)
// {
// M_index = 2;
// }
float t_M = -h_L / (h_M - h_L);
// //We also need the heights to water
// float h_H = vertexData[0].distance;
// float h_M = 0f;
// float h_L = 0f;
// Vector3 M = Vector3.zero;
// Vector3 L = Vector3.zero;
// //This means M is at position 1 in the List
// if (vertexData[1].index == M_index)
// {
// M = vertexData[1].globalVertexPos;
// L = vertexData[2].globalVertexPos;
// h_M = vertexData[1].distance;
// h_L = vertexData[2].distance;
// }
// else
// {
// M = vertexData[2].globalVertexPos;
// L = vertexData[1].globalVertexPos;
Vector3 LJ_M = t_M * LM;
// h_M = vertexData[2].distance;
// h_L = vertexData[1].distance;
// }
Vector3 J_M = LJ_M + L;
// //Now we can calculate where we should cut the triangle to form 2 new triangles
// //because the resulting area will always form a square
// //Point I_M
// Vector3 MH = H - M;
//Point J_H
Vector3 LH = H - L;
// float t_M = -h_M / (h_H - h_M);
float t_H = -h_L / (h_H - h_L);
// Vector3 MI_M = t_M * MH;
Vector3 LJ_H = t_H * LH;
// Vector3 I_M = MI_M + M;
Vector3 J_H = LJ_H + L;
// //Point I_L
// Vector3 LH = H - L;
//Save the data, such as normal, area, etc
//1 triangle below the water
underWaterTriangleData.Add(new TriangleData(L, J_H, J_M, Vector3.zero, false));
}
// float t_L = -h_L / (h_H - h_L);
// Vector3 LI_L = t_L * LH;
// Vector3 I_L = LI_L + L;
// //Save the data, such as normal, area, etc
// //2 triangles below the water
// underWaterTriangleData.Add(new TriangleData(M, I_M, I_L, Vector3.zero, false));
// underWaterTriangleData.Add(new TriangleData(M, I_L, L, Vector3.zero, false));
// }
// //Build the new triangles where two of the old vertices are above the water
// private void AddTrianglesTwoAboveWater()
// {
// //H and M are above the water
// //H is after the vertice that's below water, which is L
// //So we know which one is L because it is last in the sorted list
// Vector3 L = vertexData[2].globalVertexPos;
// //Find the index of H
// int H_index = vertexData[2].index + 1;
// if (H_index > 2)
// {
// H_index = 0;
// }
// //We also need the heights to water
// float h_L = vertexData[2].distance;
// float h_H = 0f;
// float h_M = 0f;
// Vector3 H = Vector3.zero;
// Vector3 M = Vector3.zero;
// //This means that H is at position 1 in the list
// if (vertexData[1].index == H_index)
// {
// H = vertexData[1].globalVertexPos;
// M = vertexData[0].globalVertexPos;
// h_H = vertexData[1].distance;
// h_M = vertexData[0].distance;
// }
// else
// {
// H = vertexData[0].globalVertexPos;
// M = vertexData[1].globalVertexPos;
// h_H = vertexData[0].distance;
// h_M = vertexData[1].distance;
// }
// //Now we can find where to cut the triangle
// //Point J_M
// Vector3 LM = M - L;
// float t_M = -h_L / (h_M - h_L);
// Vector3 LJ_M = t_M * LM;
// Vector3 J_M = LJ_M + L;
// //Point J_H
// Vector3 LH = H - L;
// float t_H = -h_L / (h_H - h_L);
// Vector3 LJ_H = t_H * LH;
// Vector3 J_H = LJ_H + L;
// //Save the data, such as normal, area, etc
// //1 triangle below the water
// underWaterTriangleData.Add(new TriangleData(L, J_H, J_M, Vector3.zero, false));
// }
//Help class to store triangle data so we can sort the distances
private struct VertexData

public Vector3 globalVertexPos;
}
private struct VertexDataSet
{
//set of vertdata to make tri
public VertexData v1;
public VertexData v2;
public VertexData v3;
}
//Display the underwater mesh
public void DisplayMesh(Mesh mesh, string name, List<TriangleData> triangesData)
{

mesh.RecalculateBounds();
}
}
//To save space so we don't have to send millions of parameters to each method
public struct TriangleData
{
//The corners of this triangle in global coordinates
public Vector3 p1;
public Vector3 p2;
public Vector3 p3;
//The center of the triangle
public Vector3 center;
//The distance to the surface from the center of the triangle
public float distanceToSurface;
//The normal to the triangle
public Vector3 normal;
//The area of the triangle
public float area;
//Intermediate TriangleDataBase
public struct TriangleDataBase
{
public Vector3 p1;
public Vector3 p2;
public Vector3 p3;
public Vector3 distance;
public int full;
}
public bool underWater;
public TriangleData(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 distances, bool full)
//To save space so we don't have to send millions of parameters to each method
[System.Serializable]
public struct TriangleData
this.p1 = p1;
this.p2 = p2;
this.p3 = p3;
//Center of the triangle
this.center = (p1 + p2 + p3) / 3f;
//Distance to the surface from the center of the triangle, we average it if triangle uncut
if(full)
this.distanceToSurface = Mathf.Abs((distances.x + distances.y + distances.z) / 3f);
else
this.distanceToSurface = Mathf.Abs(Water.Instance.GetWaterHeight(this.center));
//Normal to the triangle
this.normal = Vector3.Cross(p2 - p1, p3 - p1).normalized;
//Area of the triangle
float a = Vector3.Distance(p1, p2);
float c = Vector3.Distance(p3, p1);
this.area = (a * c * Mathf.Sin(Vector3.Angle(p2 - p1, p3 - p1) * Mathf.Deg2Rad)) / 2f;
this.underWater = true;
//The corners of this triangle in global coordinates
public Vector3 p1;
public Vector3 p2;
public Vector3 p3;
//The center of the triangle
public Vector3 center;
//The distance to the surface from the center of the triangle
public float distanceToSurface;
//The normal to the triangle
public Vector3 normal;
//The area of the triangle
public float area;
public int underWater;
}
}
}

1001
Assets/scenes/Testing/BoatPhysics.unity
文件差异内容过多而无法显示
查看文件

7
Assets/scenes/Testing/BoatPhysics.unity.meta


fileFormatVersion: 2
guid: f24d35b2f498c4055868a646b52a1f81
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存