public void Setup(TrailInitData initData, Transform pointStart, Transform pointEnd, Material material) { PointStart = pointStart; PointEnd = pointEnd; MyMaterial = material; Granularity = initData.Granularity; TrailLength = initData.TrailLength; Whitestep = initData.Whitestep; _elemPool = new ElementPool(TrailLength); _trailWidth = (PointStart.position - PointEnd.position).magnitude; _vertexPool = new VertexPool(MyMaterial, this); _vertexSegment = _vertexPool.GetVertices(Granularity * 3, (Granularity - 1) * 12); UpdateIndices(); _vertexPool.SetMeshObjectActive(false); _inited = true; }
public void UpdateIndices() { if (!IndexDirty) { return; } VertexPool pool = Vertexsegment.Pool; if (Head != 99999 && Head != Tail) { int num = Head; int num2 = 0; while (true) { int num3 = num + 1; if (num3 == MaxElements) { num3 = 0; } if (num3 * 2 >= 65536) { Debug.LogError("Too many elements!"); } int num4 = Vertexsegment.VertStart + num3 * 2; int num5 = Vertexsegment.VertStart + num * 2; int num6 = Vertexsegment.IndexStart + num2 * 6; pool.Indices[num6] = num5; pool.Indices[num6 + 1] = num5 + 1; pool.Indices[num6 + 2] = num4; pool.Indices[num6 + 3] = num5 + 1; pool.Indices[num6 + 4] = num4 + 1; pool.Indices[num6 + 5] = num4; if (num3 == Tail) { break; } num = num3; num2++; } pool.IndiceChanged = true; } IndexDirty = false; }
public void OnDestroy() { if (!mInited) { return; } Stop(); if (Application.isEditor) { DestroyImmediate(mMeshObj); } else { ResNode.DestroyRes(ref mMeshObj); } mVertexPool = null; mVertexSegment = null; }
public void UpdateIndices() { if (this.IndexDirty) { VertexPool pool = this.Vertexsegment.Pool; if ((this.Head != 0x1869f) && (this.Head != this.Tail)) { int head = this.Head; int num2 = 0; while (true) { int num3 = head + 1; if (num3 == this.MaxElements) { num3 = 0; } if ((num3 * 2) >= 0x10000) { Debug.LogError("Too many elements!"); } int num4 = this.Vertexsegment.VertStart + (num3 * 2); int num5 = this.Vertexsegment.VertStart + (head * 2); int index = this.Vertexsegment.IndexStart + (num2 * 6); pool.Indices[index] = num5; pool.Indices[index + 1] = num5 + 1; pool.Indices[index + 2] = num4; pool.Indices[index + 3] = num5 + 1; pool.Indices[index + 4] = num4 + 1; pool.Indices[index + 5] = num4; if (num3 == this.Tail) { break; } head = num3; num2++; } pool.IndiceChanged = true; } this.IndexDirty = false; } }
public void UpdateUV() { VertexPool pool = this.Vertexsegment.Pool; int vertStart = this.Vertexsegment.VertStart; if (this.UVDimensions.y > 0f) { pool.UVs[vertStart] = this.LowerLeftUV + Vector2.up * this.UVDimensions.y; pool.UVs[vertStart + 1] = this.LowerLeftUV; pool.UVs[vertStart + 2] = this.LowerLeftUV + Vector2.right * this.UVDimensions.x; pool.UVs[vertStart + 3] = this.LowerLeftUV + this.UVDimensions; } else { pool.UVs[vertStart] = this.LowerLeftUV; pool.UVs[vertStart + 1] = this.LowerLeftUV + Vector2.up * this.UVDimensions.y; pool.UVs[vertStart + 2] = this.LowerLeftUV + this.UVDimensions; pool.UVs[vertStart + 3] = this.LowerLeftUV + Vector2.right * this.UVDimensions.x; } this.Vertexsegment.Pool.UVChanged = true; }
void InitMeshObj() { //create a new mesh obj mMeshObj = new GameObject("WeaponTrialObje: " + gameObject.name); mMeshObj.layer = gameObject.layer; mMeshObj.hideFlags = HideFlags.HideAndDontSave; mMeshObj.SetActive(true); MeshFilter mf = mMeshObj.AddComponent <MeshFilter>(); m_Render = mMeshObj.AddComponent <MeshRenderer>(); m_Render.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; m_Render.receiveShadows = false; mf.sharedMesh = new Mesh(); mf.sharedMesh.name = "WeaponTrialMesh"; //init vertexpool mVertexPool = new VertexPool(mf.sharedMesh, GenerateMaterialInstance()); mVertexSegment = mVertexPool.GetVertices(GetGranularity() * 3, (GetGranularity() - 1) * 12); UpdateMaterial(); UpdateIndices(); }
public void UpdateUV() { VertexPool pool = Vertexsegment.Pool; int index = Vertexsegment.VertStart; if (UVDimensions.y > 0) { //From Lower-Left pool.UVs[index + 0] = LowerLeftUV + Vector2.up * UVDimensions.y; // Upper-left pool.UVs[index + 1] = LowerLeftUV; // Lower-left pool.UVs[index + 2] = LowerLeftUV + Vector2.right * UVDimensions.x; // Lower-right pool.UVs[index + 3] = LowerLeftUV + UVDimensions; // Upper-right } else {// From Upper Left pool.UVs[index + 0] = LowerLeftUV; pool.UVs[index + 1] = LowerLeftUV + Vector2.up * UVDimensions.y; pool.UVs[index + 2] = LowerLeftUV + UVDimensions; pool.UVs[index + 3] = LowerLeftUV + Vector2.right * UVDimensions.x; } Vertexsegment.Pool.UVChanged = true; }
public XEffectSprite(VertexPool.VertexSegment segment, float width, float height, STYPE type,ORIPOINT oripoint, Camera cam,int uvStretch,float maxFps) { UVChanged = ColorChanged = false; MyTransform.position = Vector3.zero; MyTransform.rotation = Quaternion.identity; LocalMat = WorldMat = Matrix4x4.identity; Vertexsegment = segment; UVStretch = uvStretch; LastMat = Matrix4x4.identity; ElapsedTime = 0f; Fps = 1f / maxFps; OriPoint = oripoint; RotateAxis = Vector3.zero; SetSizeXZ(width, height); RotateAxis.y = 1; Type = type; MainCamera = cam; ResetSegment(); }
public void Setup(TrailInitData initData, Transform pointStart, Transform pointEnd, Material material, bool editor) { PointStart = pointStart; PointEnd = pointEnd; Material = material; Granularity = initData.Granularity; TrailLength = initData.TrailLength; Whitestep = initData.Whitestep; gameObject.layer = 12; if (editor) { SortingOrder = 3; } _elemPool = new ElementPool(TrailLength); _vertexPool = new VertexPool(Material, this); _vertexSegment = _vertexPool.GetVertices(Granularity * 3, (Granularity - 1) * 12); UpdateIndices(); _vertexPool.SetMeshObjectActive(false); _inited = true; }
public RibbonTrail(VertexPool.VertexSegment segment, float width, int maxelemnt, float len, Vector3 pos, int stretchType,float maxFps) { if (maxelemnt <= 2) { Debug.LogError("ribbon trail's maxelement should > 2!"); } MaxElements = maxelemnt; Vertexsegment = segment; ElementArray = new Element[MaxElements]; Head = Tail = CHAIN_EMPTY; SetTrailLen(len); UnitWidth = width; HeadPosition = pos; StretchType = stretchType; Element dtls = new Element(HeadPosition, UnitWidth); IndexDirty = false; Fps = 1f / maxFps; // Add the start position AddElememt(dtls); // Add another on the same spot, this will extend Element dtls2 = new Element(HeadPosition, UnitWidth); AddElememt(dtls2); }
public void UpdateVertices(Vector3 eyePos) { float num = 0f; float num2 = this.ElemLength * (float)(this.MaxElements - 2); if (this.Head != 99999 && this.Head != this.Tail) { int num3 = this.Head; int num4 = this.Head; for (; ;) { if (num4 == this.MaxElements) { num4 = 0; } RibbonTrail.Element element = this.ElementArray[num4]; if (num4 * 2 >= 65536) { Debug.LogError("Too many elements!"); } int num5 = this.Vertexsegment.VertStart + num4 * 2; int num6 = num4 + 1; if (num6 == this.MaxElements) { num6 = 0; } Vector3 lhs; if (num4 == this.Head) { lhs = this.ElementArray[num6].Position - element.Position; } else if (num4 == this.Tail) { lhs = element.Position - this.ElementArray[num3].Position; } else { lhs = this.ElementArray[num6].Position - this.ElementArray[num3].Position; } Vector3 rhs = eyePos - element.Position; Vector3 vector = Vector3.Cross(lhs, rhs); vector.Normalize(); vector *= element.Width * 0.5f; Vector3 vector2 = element.Position - vector; Vector3 vector3 = element.Position + vector; VertexPool pool = this.Vertexsegment.Pool; float num7; if (this.StretchType == 0) { num7 = num / num2 * Mathf.Abs(this.UVDimensions.y); } else { num7 = num / num2 * Mathf.Abs(this.UVDimensions.x); } Vector2 zero = Vectors.v2zero; pool.Vertices[num5] = vector2; pool.Colors[num5] = this.Color; if (this.StretchType == 0) { zero.x = this.LowerLeftUV.x + this.UVDimensions.x; zero.y = this.LowerLeftUV.y - num7; } else { zero.x = this.LowerLeftUV.x + num7; zero.y = this.LowerLeftUV.y; } pool.UVs[num5] = zero; pool.Vertices[num5 + 1] = vector3; pool.Colors[num5 + 1] = this.Color; if (this.StretchType == 0) { zero.x = this.LowerLeftUV.x; zero.y = this.LowerLeftUV.y - num7; } else { zero.x = this.LowerLeftUV.x + num7; zero.y = this.LowerLeftUV.y - Mathf.Abs(this.UVDimensions.y); } pool.UVs[num5 + 1] = zero; if (num4 == this.Tail) { break; } num3 = num4; num += (this.ElementArray[num6].Position - element.Position).magnitude; num4++; } this.Vertexsegment.Pool.UVChanged = true; this.Vertexsegment.Pool.VertChanged = true; this.Vertexsegment.Pool.ColorChanged = true; } }
public void UpdateVertices(Vector3 eyePos) { Vector3 vector; float num = 0f; float num2 = 0f; float num3 = this.ElemLength * (this.MaxElements - 2); if ((this.Head == 0x1869f) || (this.Head == this.Tail)) { return; } int head = this.Head; int index = this.Head; Label_0053: if (index == this.MaxElements) { index = 0; } Element element = this.ElementArray[index]; if ((index * 2) >= 0x10000) { Debug.LogError("Too many elements!"); } int num6 = this.Vertexsegment.VertStart + (index * 2); int num7 = index + 1; if (num7 == this.MaxElements) { num7 = 0; } if (index == this.Head) { vector = this.ElementArray[num7].Position - element.Position; } else if (index == this.Tail) { vector = element.Position - this.ElementArray[head].Position; } else { vector = this.ElementArray[num7].Position - this.ElementArray[head].Position; } Vector3 rhs = eyePos - element.Position; Vector3 vector3 = Vector3.Cross(vector, rhs); vector3.Normalize(); vector3 = (Vector3)(vector3 * (element.Width * 0.5f)); Vector3 vector4 = element.Position - vector3; Vector3 vector5 = element.Position + vector3; VertexPool pool = this.Vertexsegment.Pool; if (this.StretchType == 0) { num = (num2 / num3) * Mathf.Abs(this.UVDimensions.y); } else { num = (num2 / num3) * Mathf.Abs(this.UVDimensions.x); } Vector2 zero = Vector2.zero; pool.Vertices[num6] = vector4; pool.Colors[num6] = this.Color; if (this.StretchType == 0) { zero.x = this.LowerLeftUV.x + this.UVDimensions.x; zero.y = this.LowerLeftUV.y - num; } else { zero.x = this.LowerLeftUV.x + num; zero.y = this.LowerLeftUV.y; } pool.UVs[num6] = zero; pool.Vertices[num6 + 1] = vector5; pool.Colors[num6 + 1] = this.Color; if (this.StretchType == 0) { zero.x = this.LowerLeftUV.x; zero.y = this.LowerLeftUV.y - num; } else { zero.x = this.LowerLeftUV.x + num; zero.y = this.LowerLeftUV.y - Mathf.Abs(this.UVDimensions.y); } pool.UVs[num6 + 1] = zero; if (index != this.Tail) { head = index; Vector3 vector7 = this.ElementArray[num7].Position - element.Position; num2 += vector7.magnitude; index++; goto Label_0053; } this.Vertexsegment.Pool.UVChanged = true; this.Vertexsegment.Pool.VertChanged = true; this.Vertexsegment.Pool.ColorChanged = true; }
public void UpdateVertices(Vector3 eyePos) { Vector3 chainTangent; float uvSegment = 0f; float uvLen = 0f; float trailLen = ElemLength * (MaxElements - 2); //Element headElem = ElementArray[Head]; //int nextElemIdx = Head + 1; //if (nextElemIdx == MaxElements) // nextElemIdx = 0; //Element nextElem = ElementArray[nextElemIdx]; //float headLen = (headElem.Position - nextElem.Position).magnitude; //float trailLen = ElemLength * (ElemCount - 2) + headLen; if (Head != CHAIN_EMPTY && Head != Tail) { int laste = Head; for (int e = Head; ; ++e) // until break { // Wrap forwards if (e == MaxElements) { e = 0; } Element elem = ElementArray[e]; if (e * 2 >= 65536) { Debug.LogError("Too many elements!"); } int baseIdx = Vertexsegment.VertStart + e * 2; // Get index of next item int nexte = e + 1; if (nexte == MaxElements) { nexte = 0; } if (e == Head) { // No laste, use next item chainTangent = ElementArray[nexte].Position - elem.Position; } else if (e == Tail) { // No nexte, use only last item chainTangent = elem.Position - ElementArray[laste].Position; } else { // A mid position, use tangent across both prev and next chainTangent = ElementArray[nexte].Position - ElementArray[laste].Position; } Vector3 vP1ToEye = eyePos - elem.Position; Vector3 vPerpendicular = Vector3.Cross(chainTangent, vP1ToEye); vPerpendicular.Normalize(); vPerpendicular *= (elem.Width * 0.5f); Vector3 pos0 = elem.Position - vPerpendicular; Vector3 pos1 = elem.Position + vPerpendicular; VertexPool pool = Vertexsegment.Pool; if (StretchType == 0) { uvSegment = (uvLen / trailLen) * Mathf.Abs(UVDimensions.y); } else { uvSegment = (uvLen / trailLen) * Mathf.Abs(UVDimensions.x); } Vector2 uvCoord = Vector2.zero; // pos0 pool.Vertices[baseIdx] = pos0; pool.Colors[baseIdx] = Color; if (StretchType == 0) { uvCoord.x = LowerLeftUV.x + UVDimensions.x; uvCoord.y = LowerLeftUV.y - uvSegment; } else { uvCoord.x = LowerLeftUV.x + uvSegment; uvCoord.y = LowerLeftUV.y; } pool.UVs[baseIdx] = uvCoord; //pos1 pool.Vertices[baseIdx + 1] = pos1; pool.Colors[baseIdx + 1] = Color; if (StretchType == 0) { uvCoord.x = LowerLeftUV.x; uvCoord.y = LowerLeftUV.y - uvSegment; } else { uvCoord.x = LowerLeftUV.x + uvSegment; uvCoord.y = LowerLeftUV.y - Mathf.Abs(UVDimensions.y); } pool.UVs[baseIdx + 1] = uvCoord; if (e == Tail) { break; // last one } laste = e; uvLen += (ElementArray[nexte].Position - elem.Position).magnitude; } // element Vertexsegment.Pool.UVChanged = true; Vertexsegment.Pool.VertChanged = true; Vertexsegment.Pool.ColorChanged = true; } // segment valid? }
internal void Load(EndianBinaryReader input, GxGame game) { int baseOffset = Convert.ToInt32(input.BaseStream.Position); // Load GCMF header if (input.ReadUInt32() != GcmfMagic) { throw new InvalidGmaFileException("Expected Gcmf[0x00] == GcmfMagic."); } SectionFlags = input.ReadUInt32(); BoundingSphereCenter = new Vector3(input.ReadSingle(), input.ReadSingle(), input.ReadSingle()); BoundingSphereRadius = input.ReadSingle(); int numMaterials = (int)input.ReadUInt16(); int numLayer1Meshes = (int)input.ReadUInt16(); int numLayer2Meshes = (int)input.ReadUInt16(); int transformMatrixCount = (int)input.ReadByte(); if (input.ReadByte() != 0) { throw new InvalidGmaFileException("Expected Gcmf[0x1F] == 0"); } int headerSize = input.ReadInt32(); if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Expected Gcmf[0x24] == 0"); } input.Read(TransformMatrixDefaultIdxs, 0, 8); if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Expected Gcmf[0x30] == 0"); } if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Expected Gcmf[0x34] == 0"); } if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Expected Gcmf[0x38] == 0"); } if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Expected Gcmf[0x3C] == 0"); } // Load materials for (int i = 0; i < numMaterials; i++) { GcmfMaterial mat = new GcmfMaterial(); mat.Load(input, i); Materials.Add(mat); } if ((SectionFlags & (uint)~(GcmfSectionFlags._16Bit | GcmfSectionFlags.StitchingModel | GcmfSectionFlags.SkinModel | GcmfSectionFlags.EffectiveModel)) != 0) { throw new InvalidGmaFileException("Unknown GCMF section flags."); } if ((SectionFlags & (uint)GcmfSectionFlags.StitchingModel) != 0 || (SectionFlags & (uint)GcmfSectionFlags.SkinModel) != 0) { for (int i = 0; i < transformMatrixCount; i++) { GcmfTransformMatrix tmtx = new GcmfTransformMatrix(); tmtx.Load(input); TransformMatrices.Add(tmtx); } } else { if (transformMatrixCount != 0) { throw new InvalidGmaFileException("GcmfSection: No transform matrices expected, but transformMatrixCount != 0?"); } } if (PaddingUtils.Align(Convert.ToInt32(input.BaseStream.Position), 0x20) != baseOffset + headerSize) { throw new InvalidGmaFileException("Gcmf [End Header Offset] mismatch."); } input.BaseStream.Position = baseOffset + headerSize; if ((SectionFlags & (uint)GcmfSectionFlags.SkinModel) != 0 || (SectionFlags & (uint)GcmfSectionFlags.EffectiveModel) != 0) { int sectionBaseOffset = Convert.ToInt32(input.BaseStream.Position); int numVertices = input.ReadInt32(); int offsetPartType8Unknown1 = input.ReadInt32(); int offsetPartVertexPool = input.ReadInt32(); int offsetPartMeshData = input.ReadInt32(); int offsetPartType8Unknown2 = input.ReadInt32(); if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Gcmf[PreSectionHdr-0x14]"); } if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Gcmf[PreSectionHdr-0x18]"); } if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Gcmf[PreSectionHdr-0x1C]"); } // Load the mesh headers List <GcmfMesh.HeaderSectionInfo> meshHeaderSectionInfos = new List <GcmfMesh.HeaderSectionInfo>(); for (int i = 0; i < numLayer1Meshes + numLayer2Meshes; i++) { GcmfMesh mesh = new GcmfMesh(); meshHeaderSectionInfos.Add(mesh.LoadHeader(input, (i < numLayer1Meshes) ? GcmfMesh.MeshLayer.Layer1 : GcmfMesh.MeshLayer.Layer2)); Meshes.Add(mesh); } if (Convert.ToInt32(input.BaseStream.Position) != sectionBaseOffset + offsetPartVertexPool) { throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartVertexPool doesn't match expected value."); } // Load the vertex pool, i.e. the vertices referenced from the indexed triangle strips for (int i = 0; i < numVertices; i++) { GcmfVertex vtx = new GcmfVertex(); vtx.LoadIndexed(input); VertexPool.Add(vtx); } // Just because it probably won't be there doesn't mean we shouldn't allow it // and some stages have the things that are not allowed /*if ((game == GxGame.SuperMonkeyBall || game == GxGame.SuperMonkeyBallDX) && (SectionFlags & (uint)GcmfSectionFlags.EffectiveModel) != 0) * { * // SMB doesn't have have any 0x08 section flags, so it's unknown how this field may work in that case * if (offsetPartType8Unknown1 != 0) * throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartType8Unknown1 is not zero on SMB."); * } * else * {*/ if (Convert.ToInt32(input.BaseStream.Position) != sectionBaseOffset + offsetPartType8Unknown1) { throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartType8Unknown1 doesn't match expected value."); } //} if ((SectionFlags & (uint)GcmfSectionFlags.SkinModel) != 0) { for (int i = 0; i < (offsetPartType8Unknown2 - offsetPartType8Unknown1) / 0x20; i++) { GcmfType8Unknown1 unk1 = new GcmfType8Unknown1(); unk1.Load(input); Type8Unknown1.Add(unk1); } } // Just because it probably won't be there doesn't mean we shouldn't allow it // and some stages have the things that are not allowed /*if ((game == GxGame.SuperMonkeyBall || game == GxGame.SuperMonkeyBallDX) && (SectionFlags & (uint)GcmfSectionFlags.EffectiveModel) != 0) * { * // SMB doesn't have have any 0x08 section flags, so it's unknown how this field may work in that case * if (offsetPartType8Unknown2 != 0) * throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartType8Unknown2 is not zero on SMB."); * } * else * {*/ if (Convert.ToInt32(input.BaseStream.Position) != sectionBaseOffset + offsetPartType8Unknown2) { throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartType8Unknown2 doesn't match expected value."); } //} if ((SectionFlags & (uint)GcmfSectionFlags.SkinModel) != 0) { // TODO figure out a better way to calculate this int numEntriesPart3 = Type8Unknown1.Max(u1 => u1.unk18) + 1; for (int i = 0; i < numEntriesPart3; i++) { Type8Unknown2.Add(input.ReadUInt16()); } if (PaddingUtils.Align(Convert.ToInt32(input.BaseStream.Position), 0x20) != sectionBaseOffset + offsetPartMeshData) { throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPart4 doesn't match expected value."); } input.BaseStream.Position = sectionBaseOffset + offsetPartMeshData; } if (Convert.ToInt32(input.BaseStream.Position) != sectionBaseOffset + offsetPartMeshData) { throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartMeshData doesn't match expected value."); } // Load the mesh data itself (the indexed triangle strips) for (int i = 0; i < numLayer1Meshes + numLayer2Meshes; i++) { Meshes[i].LoadIndexedData(input, VertexPool, meshHeaderSectionInfos[i]); } // Make sure that all the vertices in the vertex pool got their // vertex flags set when we read the indexed triangle strips, // that is, that they were referenced at least once. // Otherwise, we would have semi-initialized vertices in the vertex pool! if (VertexPool.Any(vtx => !vtx.IsIndexedVertexInitialized())) { throw new InvalidGmaFileException("Not all vertex flags of all vertices in the vertex pool got initialized!"); } } else { for (int i = 0; i < numLayer1Meshes + numLayer2Meshes; i++) { GcmfMesh mesh = new GcmfMesh(); GcmfMesh.HeaderSectionInfo headerSectionInfo = mesh.LoadHeader(input, (i < numLayer1Meshes) ? GcmfMesh.MeshLayer.Layer1 : GcmfMesh.MeshLayer.Layer2); mesh.LoadNonIndexedData(input, headerSectionInfo, (SectionFlags & (uint)GcmfSectionFlags._16Bit) != 0); Meshes.Add(mesh); } } }
public void Transform() { this.LocalMat.SetTRS(Vectors.zero, this.Rotation, this.ScaleVector); if (this.Type == STYPE.BILLBOARD) { Transform transform = this.MainCamera.transform; this.MyTransform.LookAt(this.MyTransform.position + transform.rotation * Vectors.up, transform.rotation * Vectors.back); } this.WorldMat.SetTRS(this.MyTransform.position, this.MyTransform.rotation, Vectors.one); Matrix4x4 matrix4x = this.WorldMat * this.LocalMat; VertexPool pool = this.Vertexsegment.Pool; int vertStart = this.Vertexsegment.VertStart; Vector3 vector = matrix4x.MultiplyPoint3x4(this.v1); Vector3 vector2 = matrix4x.MultiplyPoint3x4(this.v2); Vector3 vector3 = matrix4x.MultiplyPoint3x4(this.v3); Vector3 vector4 = matrix4x.MultiplyPoint3x4(this.v4); if (this.Type == STYPE.BILLBOARD_SELF) { Vector3 vector5 = Vectors.zero; Vector3 vector6 = Vectors.zero; float magnitude; if (this.UVStretch == 0) { vector5 = (vector + vector4) / 2f; vector6 = (vector2 + vector3) / 2f; magnitude = (vector4 - vector).magnitude; } else { vector5 = (vector + vector2) / 2f; vector6 = (vector4 + vector3) / 2f; magnitude = (vector2 - vector).magnitude; } Vector3 lhs = vector5 - vector6; Vector3 rhs = this.MainCamera.transform.position - vector5; Vector3 vector7 = Vector3.Cross(lhs, rhs); vector7.Normalize(); vector7 *= magnitude * 0.5f; Vector3 rhs2 = this.MainCamera.transform.position - vector6; Vector3 vector8 = Vector3.Cross(lhs, rhs2); vector8.Normalize(); vector8 *= magnitude * 0.5f; if (this.UVStretch == 0) { vector = vector5 - vector7; vector4 = vector5 + vector7; vector2 = vector6 - vector8; vector3 = vector6 + vector8; } else { vector = vector5 - vector7; vector2 = vector5 + vector7; vector4 = vector6 - vector8; vector3 = vector6 + vector8; } } pool.Vertices[vertStart] = vector; pool.Vertices[vertStart + 1] = vector2; pool.Vertices[vertStart + 2] = vector3; pool.Vertices[vertStart + 3] = vector4; }
public void UpdateVertices(Vector3 eyePos) { float num = 0f; float num2 = 0f; float num3 = ElemLength * (float)(MaxElements - 2); if (Head == 99999 || Head == Tail) { return; } int num4 = Head; int num5 = Head; while (true) { if (num5 == MaxElements) { num5 = 0; } Element element = ElementArray[num5]; if (num5 * 2 >= 65536) { Debug.LogError("Too many elements!"); } int num6 = Vertexsegment.VertStart + num5 * 2; int num7 = num5 + 1; if (num7 == MaxElements) { num7 = 0; } Vector3 lhs = (num5 == Head) ? (ElementArray[num7].Position - element.Position) : ((num5 != Tail) ? (ElementArray[num7].Position - ElementArray[num4].Position) : (element.Position - ElementArray[num4].Position)); Vector3 rhs = eyePos - element.Position; Vector3 b = Vector3.Cross(lhs, rhs); b.Normalize(); b *= element.Width * 0.5f; Vector3 vector = element.Position - b; Vector3 vector2 = element.Position + b; VertexPool pool = Vertexsegment.Pool; num = ((StretchType != 0) ? (num2 / num3 * Mathf.Abs(UVDimensions.x)) : (num2 / num3 * Mathf.Abs(UVDimensions.y))); Vector2 zero = Vector2.zero; pool.Vertices[num6] = vector; pool.Colors[num6] = Color; if (StretchType == 0) { zero.x = LowerLeftUV.x + UVDimensions.x; zero.y = LowerLeftUV.y - num; } else { zero.x = LowerLeftUV.x + num; zero.y = LowerLeftUV.y; } pool.UVs[num6] = zero; pool.Vertices[num6 + 1] = vector2; pool.Colors[num6 + 1] = Color; if (StretchType == 0) { zero.x = LowerLeftUV.x; zero.y = LowerLeftUV.y - num; } else { zero.x = LowerLeftUV.x + num; zero.y = LowerLeftUV.y - Mathf.Abs(UVDimensions.y); } pool.UVs[num6 + 1] = zero; if (num5 == Tail) { break; } num4 = num5; num2 += (ElementArray[num7].Position - element.Position).magnitude; num5++; } Vertexsegment.Pool.UVChanged = true; Vertexsegment.Pool.VertChanged = true; Vertexsegment.Pool.ColorChanged = true; }
private int SizeOf2VertexPool() { return(VertexPool.Sum(vtx => vtx.SizeOfIndexed())); }
//this function should be very optimized public void Transform() { LocalMat.SetTRS(Vector3.zero, Rotation, ScaleVector); if (Type == STYPE.BILLBOARD) { Transform t; t = MainCamera.transform; MyTransform.LookAt(MyTransform.position + t.rotation * Vector3.up, t.rotation * Vector3.back); } WorldMat.SetTRS(MyTransform.position, MyTransform.rotation, Vector3.one); Matrix4x4 mat = WorldMat * LocalMat; VertexPool pool = Vertexsegment.Pool; int index = Vertexsegment.VertStart; Vector3 v1w = mat.MultiplyPoint3x4(v1); Vector3 v2w = mat.MultiplyPoint3x4(v2); Vector3 v3w = mat.MultiplyPoint3x4(v3); Vector3 v4w = mat.MultiplyPoint3x4(v4); if (Type == STYPE.BILLBOARD_SELF) { Vector3 headElem = Vector3.zero; Vector3 tailElem = Vector3.zero; float vWidth = 0f; if (UVStretch == 0) { headElem = (v1w + v4w) / 2; tailElem = (v2w + v3w) / 2; vWidth = (v4w - v1w).magnitude; } else { headElem = (v1w + v2w) / 2; tailElem = (v4w + v3w) / 2; vWidth = (v2w - v1w).magnitude; } Vector3 chainTangent = headElem - tailElem; Vector3 vP1ToEye = MainCamera.transform.position - headElem; Vector3 vPerpendicular1 = Vector3.Cross(chainTangent, vP1ToEye); vPerpendicular1.Normalize(); vPerpendicular1 *= (vWidth * 0.5f); Vector3 vP2ToEye = MainCamera.transform.position - tailElem; Vector3 vPerpendicular2 = Vector3.Cross(chainTangent, vP2ToEye); vPerpendicular2.Normalize(); vPerpendicular2 *= (vWidth * 0.5f); if (UVStretch == 0) { v1w = headElem - vPerpendicular1; v4w = headElem + vPerpendicular1; v2w = tailElem - vPerpendicular2; v3w = tailElem + vPerpendicular2; } else { v1w = headElem - vPerpendicular1; v2w = headElem + vPerpendicular1; v4w = tailElem - vPerpendicular2; v3w = tailElem + vPerpendicular2; } } pool.Vertices[index + 0] = v1w; pool.Vertices[index + 1] = v2w; pool.Vertices[index + 2] = v3w; pool.Vertices[index + 3] = v4w; }
public int AddVertexPool(VertexPool vertexPool) { return(0); }
public int AddVertexPool(VertexPool vertexPool) { return(_renderer.AddVertexPool(vertexPool)); }
public void Transform() { LocalMat.SetTRS(Vector3.zero, Rotation, ScaleVector); if (Type == STYPE.BILLBOARD) { Transform transform = MainCamera.transform; MyTransform.LookAt(MyTransform.position + transform.rotation * Vector3.up, transform.rotation * Vector3.back); } WorldMat.SetTRS(MyTransform.position, MyTransform.rotation, Vector3.one); Matrix4x4 matrix4x = WorldMat * LocalMat; VertexPool pool = Vertexsegment.Pool; int vertStart = Vertexsegment.VertStart; Vector3 vector = matrix4x.MultiplyPoint3x4(v1); Vector3 vector2 = matrix4x.MultiplyPoint3x4(v2); Vector3 vector3 = matrix4x.MultiplyPoint3x4(v3); Vector3 vector4 = matrix4x.MultiplyPoint3x4(v4); if (Type == STYPE.BILLBOARD_SELF) { Vector3 zero = Vector3.zero; Vector3 zero2 = Vector3.zero; float num = 0f; if (UVStretch == 0) { zero = (vector + vector4) / 2f; zero2 = (vector2 + vector3) / 2f; num = (vector4 - vector).magnitude; } else { zero = (vector + vector2) / 2f; zero2 = (vector4 + vector3) / 2f; num = (vector2 - vector).magnitude; } Vector3 lhs = zero - zero2; Vector3 rhs = MainCamera.transform.position - zero; Vector3 b = Vector3.Cross(lhs, rhs); b.Normalize(); b *= num * 0.5f; Vector3 rhs2 = MainCamera.transform.position - zero2; Vector3 b2 = Vector3.Cross(lhs, rhs2); b2.Normalize(); b2 *= num * 0.5f; if (UVStretch == 0) { vector = zero - b; vector4 = zero + b; vector2 = zero2 - b2; vector3 = zero2 + b2; } else { vector = zero - b; vector2 = zero + b; vector4 = zero2 - b2; vector3 = zero2 + b2; } } pool.Vertices[vertStart] = vector; pool.Vertices[vertStart + 1] = vector2; pool.Vertices[vertStart + 2] = vector3; pool.Vertices[vertStart + 3] = vector4; }
public void Transform() { this.LocalMat.SetTRS(Vector3.zero, this.Rotation, this.ScaleVector); if (this.Type == STYPE.BILLBOARD) { UnityEngine.Transform transform = this.MainCamera.transform; this.MyTransform.LookAt(this.MyTransform.position + (transform.rotation * Vector3.up), (Vector3)(transform.rotation * Vector3.back)); } this.WorldMat.SetTRS(this.MyTransform.position, this.MyTransform.rotation, Vector3.one); Matrix4x4 matrixx = this.WorldMat * this.LocalMat; VertexPool pool = this.Vertexsegment.Pool; int vertStart = this.Vertexsegment.VertStart; Vector3 vector = matrixx.MultiplyPoint3x4(this.v1); Vector3 vector2 = matrixx.MultiplyPoint3x4(this.v2); Vector3 vector3 = matrixx.MultiplyPoint3x4(this.v3); Vector3 vector4 = matrixx.MultiplyPoint3x4(this.v4); if (this.Type == STYPE.BILLBOARD_SELF) { Vector3 zero = Vector3.zero; Vector3 vector6 = Vector3.zero; float magnitude = 0f; if (this.UVStretch == 0) { zero = (Vector3)((vector + vector4) / 2f); vector6 = (Vector3)((vector2 + vector3) / 2f); Vector3 vector12 = vector4 - vector; magnitude = vector12.magnitude; } else { zero = (Vector3)((vector + vector2) / 2f); vector6 = (Vector3)((vector4 + vector3) / 2f); Vector3 vector13 = vector2 - vector; magnitude = vector13.magnitude; } Vector3 lhs = zero - vector6; Vector3 rhs = this.MainCamera.transform.position - zero; Vector3 vector9 = Vector3.Cross(lhs, rhs); vector9.Normalize(); vector9 = (Vector3)(vector9 * (magnitude * 0.5f)); Vector3 vector10 = this.MainCamera.transform.position - vector6; Vector3 vector11 = Vector3.Cross(lhs, vector10); vector11.Normalize(); vector11 = (Vector3)(vector11 * (magnitude * 0.5f)); if (this.UVStretch == 0) { vector = zero - vector9; vector4 = zero + vector9; vector2 = vector6 - vector11; vector3 = vector6 + vector11; } else { vector = zero - vector9; vector2 = zero + vector9; vector4 = vector6 - vector11; vector3 = vector6 + vector11; } } pool.Vertices[vertStart] = vector; pool.Vertices[vertStart + 1] = vector2; pool.Vertices[vertStart + 2] = vector3; pool.Vertices[vertStart + 3] = vector4; }
internal void Load(EndianBinaryReader input, GcGame game) { int baseOffset = Convert.ToInt32(input.BaseStream.Position); // Load GCMF header if (input.ReadUInt32() != GcmfMagic) { throw new InvalidGmaFileException("Expected Gcmf[0x00] == GcmfMagic."); } SectionFlags = input.ReadUInt32(); BoundingSphereCenter = new Vector3(input.ReadSingle(), input.ReadSingle(), input.ReadSingle()); BoundingSphereRadius = input.ReadSingle(); int numMaterials = (int)input.ReadUInt16(); int numLayer1Meshes = (int)input.ReadUInt16(); int numLayer2Meshes = (int)input.ReadUInt16(); int numTransformMatrices = (int)input.ReadByte(); if (input.ReadByte() != 0) { throw new InvalidGmaFileException("Expected Gcmf[0x1F] == 0"); } int headerSize = input.ReadInt32(); if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Expected Gcmf[0x24] == 0"); } input.Read(TransformMatrixDefaultIdxs, 0, 8); if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Expected Gcmf[0x30] == 0"); } if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Expected Gcmf[0x34] == 0"); } if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Expected Gcmf[0x38] == 0"); } if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Expected Gcmf[0x3C] == 0"); } // Check that the combination of flags is correct if ((SectionFlags & (uint)~(GcmfSectionFlags._16Bit | GcmfSectionFlags.StitchingModel | GcmfSectionFlags.SkinModel | GcmfSectionFlags.EffectiveModel)) != 0) { throw new InvalidGmaFileException("Unknown GCMF section flags."); } if ((SectionFlags & (uint)GcmfSectionFlags.SkinModel) != 0 && !GcmfVersionDetails.IsGcmfSkinModelSupported(game)) { throw new InvalidGmaFileException("GCMF with skin model flag is not supported in this game."); } // Load materials for (int i = 0; i < numMaterials; i++) { GcmfMaterial mat = new GcmfMaterial(); mat.Load(input, i); Materials.Add(mat); } // Load transform matrices if ((SectionFlags & (uint)GcmfSectionFlags.StitchingModel) != 0 || (SectionFlags & (uint)GcmfSectionFlags.SkinModel) != 0) { for (int i = 0; i < numTransformMatrices; i++) { GcmfTransformMatrix tmtx = new GcmfTransformMatrix(); tmtx.Load(input); TransformMatrices.Add(tmtx); } } else { if (numTransformMatrices != 0) { throw new InvalidGmaFileException("GcmfSection: No transform matrices expected, but transformMatrixCount != 0?"); } } if (PaddingUtils.Align(Convert.ToInt32(input.BaseStream.Position), 0x20) != baseOffset + headerSize) { throw new InvalidGmaFileException("Gcmf [End Header Offset] mismatch."); } input.BaseStream.Position = baseOffset + headerSize; if ((SectionFlags & (uint)GcmfSectionFlags.SkinModel) != 0 || (SectionFlags & (uint)GcmfSectionFlags.EffectiveModel) != 0) { int sectionBaseOffset = Convert.ToInt32(input.BaseStream.Position); int numVertices = input.ReadInt32(); int offsetPartType8Unknown1 = input.ReadInt32(); int offsetPartVertexPool = input.ReadInt32(); int offsetPartMeshData = input.ReadInt32(); int offsetPartType8Unknown2 = input.ReadInt32(); if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Gcmf[PreSectionHdr-0x14]"); } if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Gcmf[PreSectionHdr-0x18]"); } if (input.ReadUInt32() != 0) { throw new InvalidGmaFileException("Gcmf[PreSectionHdr-0x1C]"); } // Load the mesh headers List <GcmfMesh.HeaderSectionInfo> meshHeaderSectionInfos = new List <GcmfMesh.HeaderSectionInfo>(); for (int i = 0; i < numLayer1Meshes + numLayer2Meshes; i++) { GcmfMesh mesh = new GcmfMesh(); meshHeaderSectionInfos.Add(mesh.LoadHeader(input, (i < numLayer1Meshes) ? GcmfMesh.MeshLayer.Layer1 : GcmfMesh.MeshLayer.Layer2)); Meshes.Add(mesh); } if (Convert.ToInt32(input.BaseStream.Position) != sectionBaseOffset + offsetPartVertexPool) { throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartVertexPool doesn't match expected value."); } // Load the vertex pool, i.e. the vertices referenced from the indexed triangle strips // On SMB1, the 16 bit flag is ignored in effective models bool isVtx16Bit = (SectionFlags & (uint)GcmfSectionFlags._16Bit) != 0 && !GcmfVersionDetails.Is16BitEffectiveModelIgnored(game); for (int i = 0; i < numVertices; i++) { GcmfVertex vtx = new GcmfVertex(); vtx.LoadIndexed(input, isVtx16Bit); VertexPool.Add(vtx); } // Load type 8 unknown 1 / unknown 2 if (GcmfVersionDetails.IsGcmfSkinModelSupported(game)) { if (Convert.ToInt32(input.BaseStream.Position) != sectionBaseOffset + offsetPartType8Unknown1) { throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartType8Unknown1 doesn't match expected value."); } if ((SectionFlags & (uint)GcmfSectionFlags.SkinModel) != 0) { for (int i = 0; i < (offsetPartType8Unknown2 - offsetPartType8Unknown1) / 0x20; i++) { GcmfType8Unknown1 unk1 = new GcmfType8Unknown1(); unk1.Load(input); Type8Unknown1.Add(unk1); } } if (Convert.ToInt32(input.BaseStream.Position) != sectionBaseOffset + offsetPartType8Unknown2) { throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartType8Unknown2 doesn't match expected value."); } if ((SectionFlags & (uint)GcmfSectionFlags.SkinModel) != 0) { for (int i = 0; i < numTransformMatrices; i++) { Type8Unknown2.Add(input.ReadUInt16()); } if (PaddingUtils.Align(Convert.ToInt32(input.BaseStream.Position), 0x20) != sectionBaseOffset + offsetPartMeshData) { throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartMeshData doesn't match expected value."); } input.BaseStream.Position = sectionBaseOffset + offsetPartMeshData; } } else { // We already made sure that the section flags are not skin model if it's not supported, // so if we're here, the flag is set to effective model. // In this case, the offsets of those sections must be zero // SMB doesn't have have any 0x08 section flags, so those offsets are zero if (offsetPartType8Unknown1 != 0) { throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartType8Unknown1 is not zero on SMB."); } if (offsetPartType8Unknown2 != 0) { throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartType8Unknown2 is not zero on SMB."); } } // Load the mesh data itself (the indexed triangle strips) if (Convert.ToInt32(input.BaseStream.Position) != sectionBaseOffset + offsetPartMeshData) { throw new InvalidGmaFileException("Gcmf [PreSectionHdr] offsetPartMeshData doesn't match expected value."); } for (int i = 0; i < numLayer1Meshes + numLayer2Meshes; i++) { Meshes[i].LoadIndexedData(input, isVtx16Bit, VertexPool, meshHeaderSectionInfos[i]); } // Make sure that all the vertices in the vertex pool got their // vertex flags set when we read the indexed triangle strips, // that is, that they were referenced at least once. // Otherwise, we would have semi-initialized vertices in the vertex pool! if (VertexPool.Any(vtx => !vtx.IsIndexedVertexInitialized())) { throw new InvalidGmaFileException("Not all vertex flags of all vertices in the vertex pool got initialized!"); } } else { for (int i = 0; i < numLayer1Meshes + numLayer2Meshes; i++) { GcmfMesh mesh = new GcmfMesh(); GcmfMesh.HeaderSectionInfo headerSectionInfo = mesh.LoadHeader(input, (i < numLayer1Meshes) ? GcmfMesh.MeshLayer.Layer1 : GcmfMesh.MeshLayer.Layer2); mesh.LoadNonIndexedData(input, headerSectionInfo, (SectionFlags & (uint)GcmfSectionFlags._16Bit) != 0); Meshes.Add(mesh); } } }
public VertexSegment(int start, int count, int istart, int icount,VertexPool pool) { VertStart = start; VertCount = count; IndexCount = icount; IndexStart = istart; Pool = pool; }