public void CreateExampleJoint(Character character) { // Generate a simple cubic spline that will act as the radius of a long bone: SortedList <float, float> splinePoints = new SortedList <float, float>(); splinePoints.Add(0.0f, 0.5f * 1.1f); splinePoints.Add(0.02f, 0.5f * 1.1f); splinePoints.Add(0.15f, 0.5f * 0.95f); splinePoints.Add(0.3f, 0.5f * 0.9f); splinePoints.Add(0.5f, 0.5f * 1.2f); splinePoints.Add(0.7f, 0.5f * 0.9f); splinePoints.Add(0.8f, 0.5f * 0.95f); splinePoints.Add(0.98f, 0.5f * 1.1f); splinePoints.Add(1.0f, 0.5f * 1.1f); CubicSpline1D jointSpline = new CubicSpline1D(splinePoints); // Define the center curve of the long bone: Line centerLine = new Line(new Numerics.Vector3(-0.6f, 0.0f, 3.0f), new Numerics.Vector3(0.6f, 0.0f, 3.0f)); // Add a long bone to the character: character.joints.Add(new Anatomy.Joints.HingeJoint(centerLine, jointSpline)); // Generate the geometry vertices of the first bone with resolution U=32 and resolution V=32: UVMesh mesh = character.joints[0].GetArticularSurface().GenerateMesh(64, 64); // Finally upload the mesh to Godot: MeshInstance newMesh = new MeshInstance(); newMesh.Mesh = new GodotMeshConverter(mesh); AddChild(newMesh); }
/// <summary> /// Construct a new 3D cubic spline using three one-dimensional cubic splines. /// </summary> public SpatialCubicSpline(CubicSpline1D x, CubicSpline1D y, CubicSpline1D z) { this.X = x; this.Y = y; this.Z = z; GenerateCurveNormal(); }
/// <summary> /// Construct a new 3D cubic spline using three one-dimensional cubic splines. /// </summary> public SpatialCubicSpline(CubicSpline1D x, CubicSpline1D y, CubicSpline1D z) { X = x; Y = y; Z = z; GenerateCurveNormal(); }
/// <summary> /// Pre-generate an approximation to the curve's normal by traversing through all the points in the spline. /// </summary> /// <remarks> /// This code is called during construction. It must remain ready for an inconsistent state. /// </remarks> private void GenerateCurveNormal() { // Generate a tangent at key points: // TODO: make the precision adapt to the precision of centerCurve! SortedList <float, float> normalX = new SortedList <float, float>(); SortedList <float, float> normalY = new SortedList <float, float>(); SortedList <float, float> normalZ = new SortedList <float, float>(); // No normal supplied, pick arbitrary normal vector and calculate a binormal: Vector3 binormal = Vector3.Cross(VectorUtilities.InventNormal(GetTangentAt(0.0f)), GetTangentAt(0.0f)); // Traverse through all the points in the spline, and calculate the next normal, maintaining smoothness by // memorizing the previous normal: float previousValue = X.Points.Key[0]; // X.Points.Key is guaranteed to have at least 2 entries, this is safe. for (int i = 1; i < X.Points.Count; i++) { float currentValue = X.Points.Key[i]; float segmentSize = currentValue - previousValue; // Interpolate between each two points: for (int j = 0; j < kInterpolationStepCount; j++) { float t = previousValue + segmentSize * (float)j / (float)kInterpolationStepCount; Vector3 direction = Vector3.Normalize(GetTangentAt(t)); Vector3 normal = Vector3.Normalize(Vector3.Cross(direction, binormal)); binormal = Vector3.Cross(normal, direction); normalX.Add(t, normal.X); normalY.Add(t, normal.Y); normalZ.Add(t, normal.Z); } previousValue = currentValue; } // Add the final point as well: { float t = X.Points.Key[X.Points.Count - 1]; Vector3 direction = Vector3.Normalize(GetTangentAt(t)); Vector3 normal = Vector3.Normalize(Vector3.Cross(direction, binormal)); binormal = Vector3.Cross(normal, direction); normalX.Add(t, normal.X); normalY.Add(t, normal.Y); normalZ.Add(t, normal.Z); } this.NormalX = new CubicSpline1D(normalX); this.NormalY = new CubicSpline1D(normalY); this.NormalZ = new CubicSpline1D(normalZ); }
/// <summary> /// Pre-generate an approximation to the curve's normal by traversing through all the points in the spline. /// </summary> /// <remarks> /// This code is called during construction. It must remain ready for an inconsistent state. /// </remarks> private void GenerateCurveNormal() { // Generate a tangent at key points: // TODO: make the precision adapt to the precision of centerCurve! SortedList <double, double> normalX = new SortedList <double, double>(); SortedList <double, double> normalY = new SortedList <double, double>(); SortedList <double, double> normalZ = new SortedList <double, double>(); // No normal supplied, pick arbitrary normal vector and calculate a binormal: dvec3 binormal = dvec3.Cross(VectorUtilities.InventNormal(GetTangentAt(0.0)), GetTangentAt(0.0)); // Traverse through all the points in the spline, and calculate the next normal, maintaining smoothness by // memorizing the previous normal: double previousValue = X.Points.Key[0]; // Location.Points.Key is guaranteed to have at least 2 entries, this is safe. for (int i = 1; i < X.Points.Count; i++) { double currentValue = X.Points.Key[i]; double segmentSize = currentValue - previousValue; // Interpolate between each two points: for (int j = 0; j < kInterpolationStepCount; j++) { double t = previousValue + segmentSize * j / kInterpolationStepCount; dvec3 direction = GetTangentAt(t).Normalized; dvec3 normal = dvec3.Cross(direction, binormal).Normalized; binormal = dvec3.Cross(normal, direction); normalX.Add(t, normal.x); normalY.Add(t, normal.y); normalZ.Add(t, normal.z); } previousValue = currentValue; } // Add the final point as well: { double t = X.Points.Key[X.Points.Count - 1]; dvec3 direction = GetTangentAt(t).Normalized; dvec3 normal = dvec3.Cross(direction, binormal).Normalized; binormal = dvec3.Cross(normal, direction); normalX.Add(t, normal.x); normalY.Add(t, normal.y); normalZ.Add(t, normal.z); } NormalX = new CubicSpline1D(normalX); NormalY = new CubicSpline1D(normalY); NormalZ = new CubicSpline1D(normalZ); }
public SpatialCubicSpline(SortedList <float, Vector3> points) { // Note: slow implementation, can be optimized in C++. SortedList <float, float> x = new SortedList <float, float>(); SortedList <float, float> y = new SortedList <float, float>(); SortedList <float, float> z = new SortedList <float, float>(); foreach (var item in points) { x.Add(item.Key, item.Value.X); y.Add(item.Key, item.Value.Y); z.Add(item.Key, item.Value.Z); } this.X = new CubicSpline1D(x); this.Y = new CubicSpline1D(y); this.Z = new CubicSpline1D(z); }
public void CreateExampleBone(Character character) { // Generate a simple cubic spline that will act as the radius of a long bone: SortedList <float, float> radiusPoints = new SortedList <float, float>(); radiusPoints.Add(0.0f, 0.7f * 0.92f); radiusPoints.Add(0.02f, 0.7f * 0.92f); radiusPoints.Add(0.15f, 0.7f * 0.8f); radiusPoints.Add(0.5f, 0.7f * 0.7f); radiusPoints.Add(0.8f, 0.7f * 0.76f); radiusPoints.Add(0.98f, 0.7f * 0.8f); radiusPoints.Add(1.0f, 0.7f * 0.8f); CubicSpline1D boneRadius = new CubicSpline1D(radiusPoints); // Define the center curve of the long bone: SortedList <float, Numerics.Vector3> centerPoints = new SortedList <float, Numerics.Vector3>(); centerPoints.Add(0.0f, new Numerics.Vector3(0.0f, 0.0f, 2.7f)); centerPoints.Add(0.25f, new Numerics.Vector3(-0.3f, -0.5f, 1.0f)); centerPoints.Add(0.5f, new Numerics.Vector3(0.3f, 1.0f, 0.0f)); centerPoints.Add(0.75f, new Numerics.Vector3(0.8f, 1.0f, -1.0f)); centerPoints.Add(1.0f, new Numerics.Vector3(0.6f, -0.5f, -0.9f)); SpatialCubicSpline boneCenter = new SpatialCubicSpline(centerPoints); //Line centerLine = new Line(new Numerics.Vector3(0.0f, 0.0f, 1.7f), // new Numerics.Vector3(0f, 0.0f, -1.7f)); // Add a long bone to the character: character.bones.Add(new Anatomy.Bones.LongBone(boneCenter, boneRadius)); // Generate the geometry vertices of the first bone with resolution U=32 and resolution V=32: UVMesh mesh = character.bones[0].GetGeometry().GenerateMesh(64, 1024); // Finally upload the mesh to Godot: MeshInstance newMesh = new MeshInstance(); newMesh.Mesh = new GodotMeshConverter(mesh); newMesh.SetSurfaceMaterial(0, (Material)GD.Load("res://gui/BoneMaterial.tres")); AddChild(newMesh); }
/// <summary> /// Construct a new 3D cubic spline using a list of 3D points. /// </summary> public SpatialCubicSpline(SortedList <double, dvec3> points) { // Note: slow implementation, can be optimized in C++. SortedList <double, double> x = new SortedList <double, double>(); SortedList <double, double> y = new SortedList <double, double>(); SortedList <double, double> z = new SortedList <double, double>(); foreach (var item in points) { x.Add(item.Key, item.Value.x); y.Add(item.Key, item.Value.y); z.Add(item.Key, item.Value.z); } X = new CubicSpline1D(x); Y = new CubicSpline1D(y); Z = new CubicSpline1D(z); GenerateCurveNormal(); }
public SpatialCubicSpline(SortedList <float, float> x, SortedList <float, float> y, SortedList <float, float> z) { this.X = new CubicSpline1D(x); this.Y = new CubicSpline1D(y); this.Z = new CubicSpline1D(z); }
public SpatialCubicSpline(CubicSpline1D x, CubicSpline1D y, CubicSpline1D z) { this.X = x; this.Y = y; this.Z = z; }