public void Read(AssetReader reader) { Vertices.Read(reader); UV.Read(reader); if (IsReadBindPoses(reader.Version)) { BindPoses.Read(reader); } Normals.Read(reader); Tangents.Read(reader); Weight.Read(reader); NormalSigns.Read(reader); TangentSigns.Read(reader); if (IsReadFloatColors(reader.Version)) { FloatColors.Read(reader); } BoneIndices.Read(reader); Triangles.Read(reader); if (IsReadColors(reader.Version)) { Colors.Read(reader); } if (IsReadUVInfo(reader.Version)) { UVInfo = reader.ReadUInt32(); } }
public void Write(AssetWriter writer) { Vertices.Write(writer); UV.Write(writer); if (HasBindPoses(writer.Version)) { BindPoses.Write(writer); } Normals.Write(writer); Tangents.Write(writer); Weights.Write(writer); NormalSigns.Write(writer); TangentSigns.Write(writer); if (HasFloatColors(writer.Version)) { FloatColors.Write(writer); } BoneIndices.Write(writer); Triangles.Write(writer); if (HasColors(writer.Version)) { Colors.Write(writer); } if (HasUVInfo(writer.Version)) { writer.Write(UVInfo); } }
public YAMLNode ExportYAML(IExportContainer container) { YAMLMappingNode node = new YAMLMappingNode(); node.Add(VerticesName, Vertices.ExportYAML(container)); node.Add(UVName, UV.ExportYAML(container)); if (HasBindPoses(container.ExportVersion)) { node.Add(BindPosesName, BindPoses.ExportYAML(container)); } node.Add(NormalsName, Normals.ExportYAML(container)); node.Add(TangentsName, Tangents.ExportYAML(container)); node.Add(WeightsName, Weights.ExportYAML(container)); node.Add(NormalSignsName, NormalSigns.ExportYAML(container)); node.Add(TangentSignsName, TangentSigns.ExportYAML(container)); if (HasFloatColors(container.ExportVersion)) { node.Add(FloatColorsName, FloatColors.ExportYAML(container)); } node.Add(BoneIndicesName, BoneIndices.ExportYAML(container)); node.Add(TrianglesName, Triangles.ExportYAML(container)); if (HasColors(container.ExportVersion)) { node.Add(ColorsName, Colors.ExportYAML(container)); } if (HasUVInfo(container.ExportVersion)) { node.Add(UVInfoName, UVInfo); } return(node); }
public void AddBlendShapesToMesh(Mesh mesh) { Dictionary <string, BlendShape> map = new Dictionary <string, BlendShape>(); foreach (var x in BlendShapes) { BlendShape bs = null; if (!map.TryGetValue(x.Name, out bs)) { bs = new BlendShape(); bs.Positions = Positions.ToArray(); bs.Normals = Normals.ToArray(); bs.Tangents = Tangents.Select(y => (Vector3)y).ToArray(); bs.Name = x.Name; bs.FrameWeight = x.FrameWeight; map.Add(x.Name, bs); } var j = x.VertexOffset; for (int i = 0; i < x.Positions.Length; ++i, ++j) { bs.Positions[j] = x.Positions[i]; bs.Normals[j] = x.Normals[i]; bs.Tangents[j] = x.Tangents[i]; } } foreach (var kv in map) { //Debug.LogFormat("AddBlendShapeFrame: {0}", kv.Key); mesh.AddBlendShapeFrame(kv.Key, kv.Value.FrameWeight, kv.Value.Positions, kv.Value.Normals, kv.Value.Tangents); } }
// Dubin curve distance public float Distance(DifferentialDriveState other) { Vector3 destination = other.position; float angle = Tangents.RotationAngle(orientation, destination - position); float v = maxVel; float omega = w; if (Mathf.Abs(angle) > 90) { angle = angle - 180 * Mathf.Sign(angle); } float d = Vector3.Distance(position, destination); //Debug.Log ("d: "+d); float absAngle = Mathf.Abs(angle); //Debug.Log ("phi: "+phi); float radius = (d / 2) / Mathf.Sin(absAngle * toRad); if (radius > r) { omega = v / radius; } return(Mathf.Abs(2 * (absAngle)) * toRad / omega); }
public static Tangents Create(Vector3 from, Vector3 to, float circleRadius, CellMatrix matrix) { var t = new Tangents(); t.Init(from, to, circleRadius, matrix); return(t); }
public static Tangents Create(Vector3 p1, Vector3 p3, float circleRadius) { var t = new Tangents(); t.Init(p1, p3, circleRadius); return(t); }
public void RecalculateTangents() { if (HasUVs() == false) { UVs.Resize(Vertices.Count); } //partialy stolen from http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/ int verticesNum = Vertices.Count; int indiciesNum = TriangleIndicies.Count; int[] counts = new int[verticesNum]; Tangents.Clear(); Tangents.Capacity = verticesNum; for (int i = 0; i < verticesNum; i++) { counts[i] = 0; Tangents.Add(Vector3.Zero); } for (int i = 0; i <= indiciesNum - 3; i += 3) { int ai = TriangleIndicies[i]; int bi = TriangleIndicies[i + 1]; int ci = TriangleIndicies[i + 2]; if (ai < verticesNum && bi < verticesNum && ci < verticesNum) { Vector3 av = Vertices[ai]; Vector3 deltaPos1 = Vertices[bi] - av; Vector3 deltaPos2 = Vertices[ci] - av; Vector2 auv = UVs[ai]; Vector2 deltaUV1 = UVs[bi] - auv; Vector2 deltaUV2 = UVs[ci] - auv; float r = 1.0f / (deltaUV1.X * deltaUV2.Y - deltaUV1.Y * deltaUV2.X); Vector3 t = (deltaPos1 * deltaUV2.Y - deltaPos2 * deltaUV1.Y) * r; Tangents[ai] += t; Tangents[bi] += t; Tangents[ci] += t; counts[ai]++; counts[bi]++; counts[ci]++; } } for (int i = 0; i < verticesNum; i++) { Tangents[i] /= counts[i]; } }
public void Dispose() { Vertexes.Dispose(); FaceIndexes.Dispose(); TriangleOrder.Dispose(); Normals.Dispose(); Tangents.Dispose(); Uvs.Dispose(); }
public void ToStream(BinaryWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } writer.Write(Vertices != null); if (Vertices != null) { Vertices.ToStream(writer.BaseStream); } writer.Write(Tangents != null); if (Tangents != null) { Tangents.ToStream(writer.BaseStream); } writer.Write(Colors != null); if (Colors != null) { Colors.ToStream(writer.BaseStream); } writer.Write(Normals != null); if (Normals != null) { Normals.ToStream(writer.BaseStream); } writer.Write(TexCoords != null); if (TexCoords != null) { TexCoords.ToStream(writer.BaseStream); } writer.Write(Indices != null); if (Indices != null) { Indices.ToStream(writer.BaseStream); } writer.Write((uint)Type); writer.Write((uint)DrawStyle); writer.Write((uint)FrontFace); writer.WriteNullableString(Name); var bounds = Bounds; writer.Write(bounds.Center); writer.Write(bounds.Size); writer.Write(bounds.Radius); }
/// <summary> /// Returns a value that indicates whether this instance and another <see cref="Mesh"/> are equal. /// </summary> /// <param name="other">The other <see cref="Mesh"/>.</param> /// <returns><see langword="true"/> if the two <see cref="Mesh"/> are equals; otherwise, <see langword="false"/>.</returns> public bool Equals(Mesh other) => _hashcode == other._hashcode && Material.Equals(other.Material) && Vertices.SequenceEqual(other.Vertices) && UVs.SequenceEqual(other.UVs) && Normals.SequenceEqual(other.Normals) && Faces.SequenceEqual(other.Faces) && Tangents.SequenceEqual(other.Tangents) && Bitangents.SequenceEqual(other.Bitangents) && Colors.SequenceEqual(other.Colors) && Bones.SequenceEqual(other.Bones);
protected override void OnClearAllGeometryData() { base.OnClearAllGeometryData(); Normals?.Clear(); Normals?.TrimExcess(); TextureCoordinates?.Clear(); TextureCoordinates?.TrimExcess(); Tangents?.Clear(); Tangents?.TrimExcess(); BiTangents?.Clear(); BiTangents?.TrimExcess(); }
// Creates a list of moves. /* Returns the shortest set of moves between two kinematic car states. */ public Tuple <List <Move>, DynamicCarState> MovesTo(DynamicCarState other) { List <Move> moves = new List <Move> (); // create the move //float dr = Tangents.RotationAngle (orientation, other.position - this.position); float time = timeStep; // Sign of the acceleration determined by the difference in velocities // magnitude of acceleration is either maxAcc or the value needed to accelerate to reach the target speed. float acc = (speed < other.speed ? 1 : -1) * Mathf.Min(maxAcc, Mathf.Abs(this.speed - other.speed) / time); ////Debug.Log ("acc:" + acc); // The angle from current orientation to the destination is used to determine how much and in which direction the car should steer. float rotAngle = Tangents.RotationAngle(orientation, other.position - this.position); // The sign of the steering * maximum or sufficient steering angle. float phi = Mathf.Sign(rotAngle) * Mathf.Min(Mathf.Abs(rotAngle), maxPhi); // turning radius determined and used to calculate the angular velocity float r = L / Mathf.Tan(Mathf.Abs(phi) * toRad); // Find the new state: DynamicCarState newState; float endSpeed = speed + acc * time; float angle = ((speed + endSpeed) / (2 * r)) * time * toDeg; Vector3 carToCenter = r * (Quaternion.Euler(0, 90 * Mathf.Sign(phi), 0) * orientation).normalized; Vector3 centerToCar = -carToCenter; Vector3 center = position + carToCenter; Vector3 newPosition = Quaternion.Euler(0, angle * Mathf.Sign(phi), 0) * centerToCar + center; Vector3 newOrientation = Quaternion.Euler(0, angle * Mathf.Sign(phi), 0) * orientation; newState = new DynamicCarState(newPosition.x, newPosition.z, newOrientation, speed + acc * time); ////Debug.Log ("pos: " + newState.position); //Debug.Log ("Moving from: "+position+", or: "+orientation+"speed: "+speed+ // "\nTowards: "+other.position+", or: "+other.orientation+"speed: "+other.speed+ // "\nphi: " + phi + ", r: "+r+", angle: "+angle+", acc: "+acc+ // "\nnew state: "+newState.position + ", or: "+newState.orientation+", speed"+newState.speed); // //Debug.Log (speed + acc * time); Move move = new DynamicCarMove(orientation, speed, acc, phi, r, newState, time); moves.Add(move); return(new Tuple <List <Move>, DynamicCarState> (moves, newState)); }
public void Write(AssetsWriter writer) { Verticies.Write(writer); UV.Write(writer); Normals.Write(writer); Tangents.Write(writer); Weights.Write(writer); NormalSigns.Write(writer); TangentSigns.Write(writer); FloatColors.Write(writer); BoneIndicies.Write(writer); Triangles.Write(writer); writer.Write(UVInfo); }
public YAMLNode ExportYAML(IExportContainer container) { YAMLMappingNode node = new YAMLMappingNode(); node.Add("m_Vertices", Vertices.ExportYAML(container)); node.Add("m_UV", UV.ExportYAML(container)); node.Add("m_Normals", Normals.ExportYAML(container)); node.Add("m_Tangents", Tangents.ExportYAML(container)); node.Add("m_Weights", Weight.ExportYAML(container)); node.Add("m_NormalSigns", NormalSigns.ExportYAML(container)); node.Add("m_TangentSigns", TangentSigns.ExportYAML(container)); node.Add("m_FloatColors", IsReadFloatColors(container.Version) ? FloatColors.ExportYAML(container) : default(PackedFloatVector).ExportYAML(container)); node.Add("m_BoneIndices", BoneIndices.ExportYAML(container)); node.Add("m_Triangles", Triangles.ExportYAML(container)); node.Add("m_UVInfo", UVInfo); return(node); }
public YAMLNode ExportYAML(IAssetsExporter exporter) { #warning TODO: values acording to read version (current 2017.3.0f3) YAMLMappingNode node = new YAMLMappingNode(); node.Add("m_Vertices", Vertices.ExportYAML(exporter)); node.Add("m_UV", UV.ExportYAML(exporter)); node.Add("m_Normals", Normals.ExportYAML(exporter)); node.Add("m_Tangents", Tangents.ExportYAML(exporter)); node.Add("m_Weights", Weight.ExportYAML(exporter)); node.Add("m_NormalSigns", NormalSigns.ExportYAML(exporter)); node.Add("m_TangentSigns", TangentSigns.ExportYAML(exporter)); node.Add("m_FloatColors", IsReadFloatColors(exporter.Version) ? FloatColors.ExportYAML(exporter) : default(PackedFloatVector).ExportYAML(exporter)); node.Add("m_BoneIndices", BoneIndices.ExportYAML(exporter)); node.Add("m_Triangles", Triangles.ExportYAML(exporter)); node.Add("m_UVInfo", UVInfo); return(node); }
public void Read(EndianStream stream) { if (IsReadMeshData) { Vertices.Read(stream); UV.Read(stream); if (IsReadBindPoses) { BindPoses.Read(stream); } Normals.Read(stream); Tangents.Read(stream); Weight.Read(stream); NormalSigns.Read(stream); TangentSigns.Read(stream); if (IsReadFloatColors) { FloatColors.Read(stream); } BoneIndices.Read(stream); Triangles.Read(stream); } if (IsReadPlainColors) { LocalAABB.Read(stream); m_plainColors = stream.ReadArray <Color>(); #warning TODO: todo what? m_collisionTriangles = stream.ReadByteArray(); CollisionVertexCount = stream.ReadInt32(); } else { if (IsReadCompressedColors) { Colors.Read(stream); } else { UVInfo = stream.ReadUInt32(); } } }
public bool TryMerge(SubMesh other) { // return false; if (MaterialID != other.MaterialID) { return(false); } int offset = Positions.Count; Positions.AddRange(other.Positions); Normals.AddRange(other.Normals); Tangents.AddRange(other.Tangents); TexCoords.AddRange(other.TexCoords); VertexColors.AddRange(other.VertexColors); foreach (int index in other.Indices) { Indices.Add(index + offset); } return(true); }
private void Dispose(bool disposing) { if (mDisposed) { return; } mDisposed = true; if (disposing) { Positions?.Dispose(); Normals?.Dispose(); Tangents?.Dispose(); TexCoords0?.Dispose(); TexCoords1?.Dispose(); TexCoords2?.Dispose(); TexCoords3?.Dispose(); Colors0?.Dispose(); Colors1?.Dispose(); } GL.DeleteVertexArray(Id); }
public YAMLNode ExportYAML() { #warning TODO: support different versions YAMLMappingNode node = new YAMLMappingNode(); node.Add("m_Vertices", Vertices.ExportYAML()); node.Add("m_UV", UV.ExportYAML()); node.Add("m_Normals", Normals.ExportYAML()); node.Add("m_Tangents", Tangents.ExportYAML()); node.Add("m_Weights", Weight.ExportYAML()); node.Add("m_NormalSigns", NormalSigns.ExportYAML()); node.Add("m_TangentSigns", TangentSigns.ExportYAML()); if (IsReadFloatColors) { node.Add("m_FloatColors", FloatColors.ExportYAML()); } else { node.Add("m_FloatColors", PackedFloatVector.Empty.ExportYAML()); } node.Add("m_BoneIndices", BoneIndices.ExportYAML()); node.Add("m_Triangles", Triangles.ExportYAML()); node.Add("m_UVInfo", UVInfo); return(node); }
public static Tangents Create(Vector3 p1, Vector3 p3, float circleRadius) { var t = new Tangents(); t.Init(p1, p3, circleRadius); return t; }
public void Push(SkinnedMeshRenderer renderer) { var mesh = renderer.sharedMesh; if (mesh == null) { Debug.LogWarningFormat("{0} has no mesh", renderer.name); return; } Renderers.Add(renderer); var indexOffset = Positions.Count; var boneIndexOffset = Bones.Count; Positions.AddRange(mesh.vertices); Normals.AddRange(mesh.normals); UV.AddRange(mesh.uv); Tangents.AddRange(mesh.tangents); if (mesh.vertexCount == mesh.boneWeights.Length) { BoneWeights.AddRange(mesh.boneWeights.Select(x => AddBoneIndexOffset(x, boneIndexOffset)).ToArray()); } else { BoneWeights.AddRange(Enumerable.Range(0, mesh.vertexCount).Select(x => new BoneWeight()).ToArray()); } BindPoses.AddRange(mesh.bindposes); Bones.AddRange(renderer.bones); for (int i = 0; i < mesh.subMeshCount; ++i) { var indices = mesh.GetIndices(i).Select(x => x + indexOffset); var mat = renderer.sharedMaterials[i]; var sameMaterialSubMeshIndex = SubMeshes.FindIndex(x => ReferenceEquals(x.Material, mat)); if (sameMaterialSubMeshIndex >= 0) { SubMeshes[sameMaterialSubMeshIndex].Indices.AddRange(indices); } else { SubMeshes.Add(new SubMesh { Indices = indices.ToList(), Material = mat, }); } } for (int i = 0; i < mesh.blendShapeCount; ++i) { var positions = (Vector3[])mesh.vertices.Clone(); var normals = (Vector3[])mesh.normals.Clone(); var tangents = mesh.tangents.Select(x => (Vector3)x).ToArray(); mesh.GetBlendShapeFrameVertices(i, 0, positions, normals, tangents); BlendShapes.Add(new BlendShape { VertexOffset = indexOffset, FrameWeight = mesh.GetBlendShapeFrameWeight(i, 0), Name = mesh.GetBlendShapeName(i), Positions = positions, Normals = normals, Tangents = tangents, }); } }
private static bool CanReducePath(IPositioned point1, IPositioned point3, IUnitProperties unitProps, CellMatrix matrix, ICellCostStrategy costStrategy) { Vector3 p1; Vector3 p3; //Assign the points so we start with the point with the lowest x-value to simplify things if (point1.position.x > point3.position.x) { p1 = point3.position; p3 = point1.position; } else { p1 = point1.position; p3 = point3.position; } var requesterRadius = unitProps.radius; var tan = Tangents.Create(p1, p3, requesterRadius); var incZ = tan.slopeDir; var cellSize = matrix.cellSize; var halfCell = cellSize / 2.0f; //Adjust the start and end cells to possibly include their immediate neighbour if the unit's radius crossed said boundary. var radiusAdjust = new Vector3(requesterRadius, 0.0f, requesterRadius * incZ); //Get the start and end cells, get the cost of the actual start and end, and then reassign the start and end with the above adjustment. var startCell = matrix.GetCell(p1, true); var startCost = costStrategy.GetCellCost(startCell, unitProps); startCell = matrix.GetCell(p1 - radiusAdjust, true); var endCell = matrix.GetCell(p3, true); var endCost = costStrategy.GetCellCost(endCell, unitProps); endCell = matrix.GetCell(p3 + radiusAdjust, true); //We want x to end up on cell boundaries, the first of which is this far from the first points position var xAdj = p1.x + (startCell.position.x - p1.x) + halfCell; //We want to adjust z so that we correctly count impacted cells, this adjusts z so it starts at the bottom boundary of the first cell (for purposes of calculation) var zAdj = p1.z - (halfCell + ((p1.z - startCell.position.z) * incZ)); //The movement across the x-axis float deltaX = 0.0f; var cellMatrix = matrix.rawMatrix; int indexX = 0; for (int x = startCell.matrixPosX; x <= endCell.matrixPosX; x++) { //So instead of just checking all cells in the bounding rect defined by the two cells p1 and p3, //we limit it to the cells immediately surrounding the proposed line (tangents), including enough cells that we ensure the unit will be able to pass through, //at the extreme routes between the two cells (i.e top corner to top corner and bottom corner to bottom corner int startZ; int endZ; //If the tangents are horizontal or vertical z range is obvious if (tan.isAxisAligned) { startZ = startCell.matrixPosZ; endZ = endCell.matrixPosZ + incZ; } else { if (indexX == 0) { startZ = startCell.matrixPosZ; } else { var startCellsPassed = Mathf.FloorToInt((tan.LowTangent(deltaX) - zAdj) / cellSize) * incZ; startZ = LimitStart( startCell.matrixPosZ + startCellsPassed, startCell.matrixPosZ, incZ); } //The movement this step will perform across the x-axis deltaX = xAdj + (indexX * cellSize); var endCellsIntercepted = Mathf.FloorToInt((tan.HighTangent(deltaX) - zAdj) / cellSize) * incZ; endZ = LimitEnd( startCell.matrixPosZ + endCellsIntercepted, endCell.matrixPosZ, incZ) + incZ; } indexX++; for (int z = startZ; z != endZ; z += incZ) { var intermediary = cellMatrix[x, z]; var intermediaryCost = costStrategy.GetCellCost(intermediary, unitProps); if (!intermediary.isWalkableFrom(startCell, unitProps) || (startCost < intermediaryCost && endCost < intermediaryCost)) { return(false); } } } return(true); }
// Obstructions, must check line and arc intersection override protected bool Obstructed( IEnumerable <Polygon> polys, Vector3 startPos) { Vector3 newPoint = this.PredictPosition(startPos); Vector2 sp = new Vector2(startPos.x, startPos.z); Vector2 np = new Vector2(newPoint.x, newPoint.z); // Length of the car float L = KinematicCarState.L; if (omega == 0.0f) // Check straight line intersection { Vector2 transVec = (np - sp).normalized * L; Vector2 midPoint = (sp + np) / 2; // TODO midPoint not necessary if you fix arc Edge e = new Edge(sp, np + transVec); // TODO check correctness foreach (Polygon p in polys) { if (p.Intersects(e) || p.IsInside(midPoint)) { return(true); } } } else // Check arc intersection // Center of turning circle { Vector3 center = startPos + centerOff; Vector2 cp = new Vector2(center.x, center.z); Vector2 cenToS = sp - cp; Vector2 cenToN = np - cp; // Angles of the arc float a1, a2; if (omega < 0) { a1 = Arc.Angle(Vector2.right, cenToS); a2 = Arc.Angle(Vector2.right, cenToN); } else { a1 = Arc.Angle(Vector2.right, cenToN); a2 = Arc.Angle(Vector2.right, cenToS); } /*Vector2 normal = Quaternion.Euler(0, 90, 0) * (sp - np); * float na = (a1 + a2) / 2; * Vector2 aaa2 = cp + normal * r; * Vector2 aaa3 = cp - normal * r; * float aaaa2 = Arc.Angle(Vector2.right, aaa2); * float aaaa3 = Arc.Angle(Vector2.right, aaa3); * Vector2 ffff = aaa2; * if (a1 < a2) { * if (aaaa2 > a1 && aaaa2 < a2) { * ffff = aaa2; * } * if (aaaa3 > a1 && aaaa3 < a2) { * ffff = aaa3; * } * } else { * if (aaaa2 > a1 && aaaa2 < a2 && aaaa2 < 360 && aaaa2 > 0) { * ffff = aaa2; * } * if (aaaa3 > a1 && aaaa3 < a2 && aaaa3 < 360 && aaaa3 > 0) { * ffff = aaa3; * } * }*/ // Checking the front of the vehicle Vector3 transVec = velocity.normalized * L; Vector3 cenToFront = -centerOff + transVec; float frontR = cenToFront.magnitude; float diffAngle = Tangents.RotationAngle(-centerOff, cenToFront); // Check if arc intersects with any of the polygons Arc arc = new Arc(cp, r, a1, a2); // TODO check correctness, if it is - or + diffAngle Arc frontArc = new Arc(cp, frontR, a1 - diffAngle, a2 - diffAngle); foreach (Polygon p in polys) { if (p.Intersects(arc) || p.Intersects(frontArc)) { return(true); } } } return(false); }
protected override YAMLMappingNode ExportYAMLRoot(IExportContainer container) { YAMLMappingNode node = base.ExportYAMLRoot(container); node.AddSerializedVersion(ToSerializedVersion(container.ExportVersion)); if (HasLODData(container.ExportVersion)) { node.Add(LODDataName, LODData.ExportYAML(container)); } else { if (HasUse16bitIndices(container.ExportVersion)) { node.Add(Use16BitIndicesName, Use16BitIndices); } if (IsIndexBufferFirst(container.ExportVersion)) { node.Add(IndexBufferName, IndexBuffer.ExportYAML()); } node.Add(SubMeshesName, SubMeshes.ExportYAML(container)); } if (HasBlendShapes(container.ExportVersion)) { if (HasBlendChannels(container.ExportVersion)) { node.Add(ShapesName, Shapes.ExportYAML(container)); } else { node.Add(ShapesName, BlendShapes.ExportYAML(container)); node.Add(ShapeVerticesName, ShapeVertices.ExportYAML(container)); } } if (HasBindPose(container.ExportVersion)) { if (IsBindPoseFirst(container.ExportVersion)) { node.Add(BindPoseName, BindPose.ExportYAML(container)); } } if (HasBoneNameHashes(container.ExportVersion)) { node.Add(BoneNameHashesName, BoneNameHashes.ExportYAML(true)); node.Add(RootBoneNameHashName, RootBoneNameHash); } if (HasBonesAABB(container.ExportVersion)) { node.Add(BonesAABBName, BonesAABB.ExportYAML(container)); node.Add(VariableBoneCountWeightsName, VariableBoneCountWeights.ExportYAML(container)); } if (HasMeshCompression(container.ExportVersion)) { node.Add(MeshCompressionName, (byte)MeshCompression); } if (HasStreamCompression(container.ExportVersion)) { node.Add(StreamCompressionName, StreamCompression); } if (HasIsReadable(container.ExportVersion)) { node.Add(IsReadableName, IsReadable); node.Add(KeepVerticesName, KeepVertices); node.Add(KeepIndicesName, KeepIndices); } if (HasIndexFormat(container.ExportVersion)) { node.Add(IndexFormatName, (int)IndexFormat); } if (!HasLODData(container.ExportVersion)) { if (!IsIndexBufferFirst(container.ExportVersion)) { node.Add(IndexBufferName, IndexBuffer.ExportYAML()); } } if (HasVertexData(container.ExportVersion)) { if (!IsOnlyVertexData(container.ExportVersion)) { if (MeshCompression != MeshCompression.Off) { node.Add(VerticesName, Vertices.ExportYAML(container)); } } } else { node.Add(VerticesName, Vertices.ExportYAML(container)); } if (HasSkin(container.ExportVersion)) { node.Add(SkinName, Skin.ExportYAML(container)); } if (HasBindPose(container.ExportVersion)) { if (!IsBindPoseFirst(container.ExportVersion)) { node.Add(BindPoseName, BindPose.ExportYAML(container)); } } if (HasVertexData(container.ExportVersion)) { if (IsOnlyVertexData(container.ExportVersion)) { node.Add(VertexDataName, VertexData.ExportYAML(container)); } else { if (MeshCompression == MeshCompression.Off) { node.Add(VertexDataName, VertexData.ExportYAML(container)); } else { node.Add(UVName, UV.ExportYAML(container)); node.Add(UV1Name, UV1.ExportYAML(container)); node.Add(TangentsName, Tangents.ExportYAML(container)); node.Add(NormalsName, Normals.ExportYAML(container)); node.Add(ColorsName, Colors.ExportYAML(container)); } } } else { node.Add(UVName, UV.ExportYAML(container)); if (HasUV1(container.ExportVersion)) { node.Add(UV1Name, UV1.ExportYAML(container)); } if (HasTangentSpace(container.ExportVersion)) { node.Add(TangentSpaceName, Tangents.ExportYAML(container)); } else { node.Add(TangentsName, Tangents.ExportYAML(container)); node.Add(NormalsName, Normals.ExportYAML(container)); } } if (HasCompressedMesh(container.ExportVersion)) { node.Add(CompressedMeshName, CompressedMesh.ExportYAML(container)); } node.Add(LocalAABBName, LocalAABB.ExportYAML(container)); if (!HasVertexData(container.ExportVersion)) { node.Add(ColorsName, Colors.ExportYAML(container)); } if (HasCollisionTriangles(container.ExportVersion)) { node.Add(CollisionTrianglesName, CollisionTriangles.ExportYAML(true)); node.Add(CollisionVertexCountName, CollisionVertexCount); } if (HasMeshUsageFlags(container.ExportVersion)) { node.Add(MeshUsageFlagsName, MeshUsageFlags); } if (HasCollision(container.ExportVersion)) { node.Add(BakedConvexCollisionMeshName, CollisionData.BakedConvexCollisionMesh.ExportYAML()); node.Add(BakedTriangleCollisionMeshName, CollisionData.BakedTriangleCollisionMesh.ExportYAML()); } if (HasMeshMetrics(container.ExportVersion)) { node.Add(MeshMetricsName + "[0]", MeshMetrics[0]); node.Add(MeshMetricsName + "[1]", MeshMetrics[1]); } if (HasMeshOptimization(container.ExportVersion, container.ExportFlags)) { if (IsMeshOptimizationFlags(container.ExportVersion)) { node.Add(MeshOptimizationFlagsName, (int)MeshOptimizationFlags); } else { node.Add(MeshOptimizedName, MeshOptimized); } } if (HasStreamData(container.ExportVersion)) { StreamingInfo streamData = new StreamingInfo(true); node.Add(StreamDataName, streamData.ExportYAML(container)); } return(node); }
public override void Write(AssetWriter writer) { base.Write(writer); if (HasLODData(writer.Version)) { LODData.Write(writer); } else { if (HasUse16bitIndices(writer.Version)) { writer.Write(Use16BitIndices); } if (IsIndexBufferFirst(writer.Version)) { IndexBuffer.Write(writer); writer.AlignStream(AlignType.Align4); } SubMeshes.Write(writer); } if (HasBlendShapes(writer.Version)) { if (HasBlendChannels(writer.Version)) { Shapes.Write(writer); } else { BlendShapes.Write(writer); writer.AlignStream(AlignType.Align4); ShapeVertices.Write(writer); } } if (HasBindPose(writer.Version)) { if (IsBindPoseFirst(writer.Version)) { BindPose.Write(writer); } } if (HasBoneNameHashes(writer.Version)) { BoneNameHashes.Write(writer); writer.Write(RootBoneNameHash); } if (HasBonesAABB(writer.Version)) { BonesAABB.Write(writer); VariableBoneCountWeights.Write(writer); } if (HasMeshCompression(writer.Version)) { writer.Write((byte)MeshCompression); } if (HasStreamCompression(writer.Version)) { writer.Write(StreamCompression); } if (HasIsReadable(writer.Version)) { writer.Write(IsReadable); writer.Write(KeepVertices); writer.Write(KeepIndices); } if (IsAlignFlags(writer.Version)) { writer.AlignStream(AlignType.Align4); } if (HasIndexFormat(writer.Version)) { if (IsIndexFormatCondition(writer.Version)) { if (MeshCompression == MeshCompression.Off) { writer.Write((int)IndexFormat); } } else { writer.Write((int)IndexFormat); } } if (!HasLODData(writer.Version)) { if (!IsIndexBufferFirst(writer.Version)) { IndexBuffer.Write(writer); writer.AlignStream(AlignType.Align4); } } if (HasVertexData(writer.Version)) { if (!IsOnlyVertexData(writer.Version)) { if (MeshCompression != MeshCompression.Off) { Vertices.Write(writer); } } } else { Vertices.Write(writer); } if (HasSkin(writer.Version)) { Skin.Write(writer); } if (HasBindPose(writer.Version)) { if (!IsBindPoseFirst(writer.Version)) { BindPose.Write(writer); } } if (HasVertexData(writer.Version)) { if (IsOnlyVertexData(writer.Version)) { VertexData.Write(writer); } else { if (MeshCompression == MeshCompression.Off) { VertexData.Write(writer); } else { UV.Write(writer); UV1.Write(writer); Tangents.Write(writer); Normals.Write(writer); Colors.Write(writer); } } } else { UV.Write(writer); if (HasUV1(writer.Version)) { UV1.Write(writer); } if (HasTangentSpace(writer.Version)) { TangentSpace.Write(writer); } else { Tangents.Write(writer); Normals.Write(writer); } } if (IsAlignVertex(writer.Version)) { writer.AlignStream(AlignType.Align4); } if (HasCompressedMesh(writer.Version)) { CompressedMesh.Write(writer); } LocalAABB.Write(writer); if (!HasVertexData(writer.Version)) { Colors.Write(writer); } if (HasCollisionTriangles(writer.Version)) { CollisionTriangles.Write(writer); writer.Write(CollisionVertexCount); } if (HasMeshUsageFlags(writer.Version)) { writer.Write(MeshUsageFlags); } if (HasCollision(writer.Version)) { CollisionData.Write(writer); } if (HasMeshMetrics(writer.Version)) { writer.Write(MeshMetrics[0]); writer.Write(MeshMetrics[1]); } #if UNIVERSAL if (HasMeshOptimization(writer.Version, writer.Flags)) { if (IsMeshOptimizationFlags(writer.Version)) { writer.Write((int)MeshOptimizationFlags); } else { writer.Write(MeshOptimized); } } #endif if (HasStreamData(writer.Version)) { writer.AlignStream(AlignType.Align4); StreamData.Write(writer); } }
public MeshIntegrationResult Integrate(MeshEnumerateOption onlyBlendShapeRenderers) { var mesh = new Mesh(); if (Positions.Count > ushort.MaxValue) { Debug.LogFormat("exceed 65535 vertices: {0}", Positions.Count); mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; } mesh.vertices = Positions.ToArray(); mesh.normals = Normals.ToArray(); mesh.uv = UV.ToArray(); mesh.tangents = Tangents.ToArray(); mesh.boneWeights = BoneWeights.ToArray(); mesh.subMeshCount = SubMeshes.Count; for (var i = 0; i < SubMeshes.Count; ++i) { mesh.SetIndices(SubMeshes[i].Indices.ToArray(), MeshTopology.Triangles, i); } mesh.bindposes = BindPoses.ToArray(); // blendshape switch (onlyBlendShapeRenderers) { case MeshEnumerateOption.OnlyWithBlendShape: { AddBlendShapesToMesh(mesh); mesh.name = INTEGRATED_MESH_WITH_BLENDSHAPE_NAME; break; } case MeshEnumerateOption.All: { AddBlendShapesToMesh(mesh); mesh.name = INTEGRATED_MESH_ALL_NAME; break; } case MeshEnumerateOption.OnlyWithoutBlendShape: { mesh.name = INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME; break; } } // meshName var meshNode = new GameObject(); switch (onlyBlendShapeRenderers) { case MeshEnumerateOption.OnlyWithBlendShape: { meshNode.name = INTEGRATED_MESH_WITH_BLENDSHAPE_NAME; break; } case MeshEnumerateOption.OnlyWithoutBlendShape: { meshNode.name = INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME; break; } case MeshEnumerateOption.All: { meshNode.name = INTEGRATED_MESH_ALL_NAME; break; } } var integrated = meshNode.AddComponent <SkinnedMeshRenderer>(); integrated.sharedMesh = mesh; integrated.sharedMaterials = SubMeshes.Select(x => x.Material).ToArray(); integrated.bones = Bones.ToArray(); Result.IntegratedRenderer = integrated; Result.MeshMap.Integrated = mesh; return(Result); }
public void Push(MeshRenderer renderer) { var meshFilter = renderer.GetComponent <MeshFilter>(); if (meshFilter == null) { Debug.LogWarningFormat("{0} has no mesh filter", renderer.name); return; } var mesh = meshFilter.sharedMesh; if (mesh == null) { Debug.LogWarningFormat("{0} has no mesh", renderer.name); return; } Result.SourceMeshRenderers.Add(renderer); Result.MeshMap.Sources.Add(mesh); var indexOffset = Positions.Count; var boneIndexOffset = Bones.Count; Positions.AddRange(mesh.vertices .Select(x => renderer.transform.TransformPoint(x)) ); Normals.AddRange(mesh.normals .Select(x => renderer.transform.TransformVector(x)) ); UV.AddRange(mesh.uv); Tangents.AddRange(mesh.tangents .Select(t => { var v = renderer.transform.TransformVector(t.x, t.y, t.z); return(new Vector4(v.x, v.y, v.z, t.w)); }) ); var self = renderer.transform; var bone = self.parent; if (bone == null) { Debug.LogWarningFormat("{0} is root gameobject.", self.name); return; } var bindpose = bone.worldToLocalMatrix; BoneWeights.AddRange(Enumerable.Range(0, mesh.vertices.Length) .Select(x => new BoneWeight() { boneIndex0 = Bones.Count, weight0 = 1, }) ); BindPoses.Add(bindpose); Bones.Add(bone); for (int i = 0; i < mesh.subMeshCount && i < renderer.sharedMaterials.Length; ++i) { var indices = mesh.GetIndices(i).Select(x => x + indexOffset); var mat = renderer.sharedMaterials[i]; var sameMaterialSubMeshIndex = SubMeshes.FindIndex(x => ReferenceEquals(x.Material, mat)); if (sameMaterialSubMeshIndex >= 0) { SubMeshes[sameMaterialSubMeshIndex].Indices.AddRange(indices); } else { SubMeshes.Add(new SubMesh { Indices = indices.ToList(), Material = mat, }); } } }
// Creates a list of moves. /* Returns the shortest set of moves between two kinematic car states. */ public Tuple <List <Move>, DifferentialDriveState> MovesTo(DifferentialDriveState other) { Vector3 destination = other.position; float angle = Tangents.RotationAngle(orientation, destination - position); float v = maxVel; float omega = w; //Debug.Log ("from: " + position + " to: " + destination); //Debug.Log ("Angle: "+angle); //Debug.Log ("orientation: "+orientation); //Debug.Log ("omega: "+omega); //Debug.Log ("v: "+v); Vector2 ori = orientation; int directionOfSpeed = 1; if (Mathf.Abs(angle) > 90) { angle = angle - 180 * Mathf.Sign(angle); ori = -ori; directionOfSpeed = -1; } //Debug.Log ("new Angle: "+angle + ", neworientation: " + ori + ", direction of speed: "+directionOfSpeed); float d = Vector3.Distance(position, destination); //Debug.Log ("d: "+d); float absAngle = Mathf.Abs(angle); //Debug.Log ("phi: "+phi); float radius = (d / 2) / Mathf.Sin(absAngle * toRad); //Debug.Log ("radius: "+radius); if (radius > r) { omega = v / radius; } else { v = omega * radius; } //Debug.Log ("new omega: "+omega); //Debug.Log ("new v: "+v); //Debug.Log ("orientation: "+orientation + ", v*direction: " + (v * directionOfSpeed) + ", omega*signAngle: "+(omega * toDeg * Mathf.Sign (angle) )+"time: "+Mathf.Abs (2 * phi) * toRad / omega); List <Move> move = new List <Move>(); move.Add(new KinematicCarMove(orientation, v * directionOfSpeed, omega * toDeg * Mathf.Sign(angle * directionOfSpeed), Mathf.Abs(2 * absAngle) * toRad / omega)); Vector3 newOrientation = Quaternion.Euler(0, 2 * angle, 0) * orientation; //Debug.Log ("destination.x: "+destination.x + ", destination.z: " + destination.z + ", newOrientation: "+newOrientation); DifferentialDriveState newState = new DifferentialDriveState(destination.x, destination.z, newOrientation); return(new Tuple <List <Move>, DifferentialDriveState>(move, newState)); }
/// <summary> /// Determines whether an unobstructed path exists between two points. /// </summary> /// <param name="from">The from point.</param> /// <param name="to">The to point.</param> /// <param name="unitProps">The unit properties to test against (Walkability).</param> /// <param name="matrix">The matrix where both <paramref name="from"/> and <paramref name="to"/> must be part of.</param> /// <param name="costStrategy">The cost strategy.</param> /// <returns><c>true</c> if an unobstructed path exists between the two points; otherwise <c>false</c>.</returns> public static bool CanReducePath(IPositioned from, IPositioned to, IUnitProperties unitProps, CellMatrix matrix, ICellCostStrategy costStrategy) { //The reference cell is always the from cell. The fact the points are swapped to simplify tangents does not affect this. var refCell = matrix.GetCell(from.position, false); Vector3 p1; Vector3 p2; //Assign the points so we start with the point with the lowest x-value to simplify things if (from.position.x > to.position.x) { p1 = to.position; p2 = from.position; } else { p1 = from.position; p2 = to.position; } var unitRadius = unitProps.radius; var tan = Tangents.Create(p1, p2, unitRadius, matrix); var slopeDir = tan.slopeDir; var cellSize = matrix.cellSize; var halfCell = cellSize * 0.5f; //Get the start and end cells, get the cost of the actual start and end, and then reassign the start and end to accommodate for unit size. var startCell = matrix.GetCell(p1, false); var startCost = costStrategy.GetCellCost(startCell, unitProps); startCell = matrix.GetCell(new Vector3(p1.x - unitRadius, p1.y, p1.z), true); var endCell = matrix.GetCell(p2, false); var endCost = costStrategy.GetCellCost(endCell, unitProps); endCell = matrix.GetCell(new Vector3(p2.x + unitRadius, p2.y, p2.z), true); //The movement across the x-axis float minXCoord = (startCell.position.x - matrix.start.x) - halfCell; float maxXCoord = (startCell.position.x - matrix.start.x) + halfCell; int minZ; int maxZ; if (slopeDir < 0) { var distLowerCellBoundary = halfCell - (endCell.position.z - p2.z); var minOverlap = Mathf.CeilToInt((unitRadius - distLowerCellBoundary) / cellSize); minZ = Math.Max(0, endCell.matrixPosZ - Math.Max(0, minOverlap)); var distUpperCellBoundary = halfCell - (p1.z - startCell.position.z); var maxOverlap = Mathf.CeilToInt((unitRadius - distUpperCellBoundary) / cellSize); maxZ = Math.Min(matrix.rows - 1, startCell.matrixPosZ + Math.Max(0, maxOverlap)); } else { var distLowerCellBoundary = halfCell - (startCell.position.z - p1.z); var minOverlap = Mathf.CeilToInt((unitRadius - distLowerCellBoundary) / cellSize); minZ = Math.Max(0, startCell.matrixPosZ - Math.Max(0, minOverlap)); var distUpperCellBoundary = halfCell - (p2.z - endCell.position.z); var maxOverlap = Mathf.CeilToInt((unitRadius - distUpperCellBoundary) / cellSize); maxZ = Math.Min(matrix.rows - 1, endCell.matrixPosZ + Math.Max(0, maxOverlap)); } int startX = startCell.matrixPosX; int endX = endCell.matrixPosX; bool isVertical = tan.isVertical; var cellMatrix = matrix.rawMatrix; for (int x = startX; x <= endX; x++) { int startZ; int endZ; if (isVertical) { startZ = Math.Min(startCell.matrixPosZ, endCell.matrixPosZ); endZ = Math.Max(startCell.matrixPosZ, endCell.matrixPosZ); } else { if (slopeDir < 0) { startZ = Math.Max((int)(tan.LowTangent(maxXCoord) / cellSize), minZ); endZ = Math.Min((int)(tan.HighTangent(minXCoord) / cellSize), maxZ); } else { startZ = Math.Max((int)(tan.LowTangent(minXCoord) / cellSize), minZ); endZ = Math.Min((int)(tan.HighTangent(maxXCoord) / cellSize), maxZ); } } for (int z = startZ; z <= endZ; z++) { var intermediary = cellMatrix[x, z]; if (!isVertical && tan.IsOutsideSecants(intermediary.position)) { continue; } var intermediaryCost = costStrategy.GetCellCost(intermediary, unitProps); if (!intermediary.IsWalkableFrom(refCell, unitProps) || (startCost < intermediaryCost || endCost < intermediaryCost)) { return(false); } } minXCoord = maxXCoord; maxXCoord = maxXCoord + cellSize; } return(true); }
/* Shortest dubin path between points on two seperate directed circles. */ private List <Move> getShortestMovesBetween(Vector3 initial, Vector3 veli, Vector3 final, Vector3 velf, Vector3 rci, Vector3 rcf) { Vector3 center1 = initial + rci; Vector3 center2 = final + rcf; Vector3 di = Vector3.Cross(veli, rci); Vector3 df = Vector3.Cross(velf, rcf); /*If the circles intersect there exist no crossing tangents*/ if (Vector3.Dot(di, df) < 1 && (center2 - center1).magnitude < 2 * r) { return(new List <Move>()); } /*Find the tangentpoints */ Vector3[] tangentPoints = (Vector3.Dot(di, df) > 1) ? Tangents.parallelTangentPoints(center1, center2, r) : Tangents.intersectingTangentPoints(center1, center2, r); //Vector3 direction = center2 - center1; //Debug.Log ("direction: " + direction); Vector3 tangent = tangentPoints [1] - tangentPoints [0]; //Debug.Log ("tangent: " + tangent); float sa, s, ea; Vector3 cross = Vector3.Cross(tangent, center1 - tangentPoints [0]); int index = (Mathf.Sign(cross.y * di.y) > 0) ? 0 : 2; //Debug.Log ("index: " + index); //Debug.Log ("TP1: " + tangentPoints[index] + " TP2: " + tangentPoints [index+1]); sa = Tangents.RotationAngle(-rci, tangentPoints[index] - center1); ea = Tangents.RotationAngle(tangentPoints [index + 1] - center2, -rcf); // We want to move along the directionality of the circles //Debug.Log ("from: " + initial + " to: " + final); //Debug.Log ("sa: " + sa + "\n ea: " + ea + "\n di: " + di.y + "\n df: "+df.y); if (Mathf.Sign(di.y * sa) < 0) { sa = Mathf.Sign(di.y) * (360 - Mathf.Abs(sa)); } // We want to move along the directionality of the circles if (Mathf.Sign(df.y * ea) < 0) { ea = Mathf.Sign(df.y) * (360 - Mathf.Abs(ea)); } Vector3 straight = tangentPoints [index + 1] - tangentPoints [index]; s = (straight).magnitude; //float l = Mathf.Abs(sa) + s + Mathf.Abs(ea); //Debug.Log ("sa: " + sa + "\n ea: " + ea + "\n di: " + di.y + "\n df: "+df.y + "\n s: " + s); List <Move> moves = new List <Move>(); /*Never back up!*/ float phi = maxPhi; float v = maxVel; // Constant speed. This will be altered when the path is finished. float W = v * Mathf.Tan(Mathf.Abs(phi) * toRad) / L; //Debug.Log ("v: " + v + " , W: " + W + ", di: " + di.y ); moves.Add(new KinematicCarMove(veli.normalized, v, W * toDeg * Mathf.Sign(di.y), Mathf.Abs(sa) * toRad / W)); Vector3 orientation = Quaternion.Euler(0, sa, 0) * veli.normalized; moves.Add(new KinematicCarMove(orientation, v, 0, s / Mathf.Abs(v))); moves.Add(new KinematicCarMove(orientation, v, W * toDeg * Mathf.Sign(df.y), Mathf.Abs(ea) * toRad / W)); return(moves); /* * // the angles and paths for the two tangents * float sa1 = Tangents.RotationAngle( -rci, tangentPoints[0] - center1); * Vector3 straight1 = tangentPoints [1] - tangentPoints [0]; * float s1 = (straight1).magnitude; * float ea1 = Tangents.RotationAngle ( tangentPoints [1] - center2, -rcf); * float l1 = Mathf.Abs(sa1) + s1 + Mathf.Abs(ea1); * * float sa2 = Tangents.RotationAngle(-rci, tangentPoints[2] - center1); * Vector3 straight2 = tangentPoints [3] - tangentPoints [2]; * float s2 = (straight2).magnitude; * float ea2 = Tangents.RotationAngle (tangentPoints [3] - center2, -rcf); * float l2 = Mathf.Abs(sa2) + s2 + Mathf.Abs(ea2); * * * //Assign our path the shorter one * float sa, s, ea; * Vector3 straight; * if (l1 < l2) { * sa = sa1; s = s1; ea = ea1; straight = straight1; * } else { * sa = sa2; s = s2; ea = ea2; straight = straight2; * } * * List<Move> moves = new List<Move>(); * //negative speed: back up! if the angle needed to make and the direction of the circle are of opposite sign the speed should be negative * float speed = maxVel * Mathf.Sign(sa) * Mathf.Sign(di.y); * moves.Add( new KinematicCarMove(veli.normalized, speed, w * toDeg * Mathf.Sign(di.y), Mathf.Abs(sa) * toRad/ w) ); * * Vector3 orientation = Quaternion.Euler(0, sa, 0) * veli.normalized; * speed = maxVel * ((Vector3.Angle (orientation, straight) < 90) ? 1 : -1); // If the orientation and straight path are opposite we need a negative velocity * moves.Add( new KinematicCarMove(orientation, speed, 0, s / Mathf.Abs(speed)) ); * * speed = maxVel * Mathf.Sign(ea) * Mathf.Sign(df.y); * moves.Add( new KinematicCarMove(orientation, speed, w * toDeg * Mathf.Sign(df.y), Mathf.Abs(ea) * toRad / w) ); * * return moves;*/ }