public VertexSegment(int start, int count, int istart, int icount, VertexPool pool) { VertStart = start; VertCount = count; IndexCount = icount; IndexStart = istart; Pool = pool; }
public Cone(VertexPool.VertexSegment segment, Vector2 size, int numseg, float angle, Vector3 dir, int uvStretch, float maxFps) { Vertexsegment = segment; Size = size; Direction = dir; UVStretch = uvStretch; Fps = 1f / maxFps; SetColor(Color.white); NumSegment = numseg; SpreadAngle = angle; OriSpreadAngle = angle; InitVerts(); }
private void InitMeshObj() { mMeshObj = new GameObject("_XWeaponTrailMesh: " + gameObject.name); mMeshObj.layer = gameObject.layer; mMeshObj.SetActive(true); var filter = mMeshObj.AddComponent <MeshFilter>(); var renderer = mMeshObj.AddComponent <MeshRenderer>(); renderer.castShadows = false; renderer.receiveShadows = false; renderer.renderer.sharedMaterial = MyMaterial; filter.sharedMesh = new Mesh(); mVertexPool = new VertexPool(filter.sharedMesh, MyMaterial); mVertexSegment = mVertexPool.GetVertices(Granularity * 3, (Granularity - 1) * 12); UpdateIndices(); }
public CustomMesh(VertexPool.VertexSegment segment, Mesh mesh,Vector3 dir, float maxFps,EffectNode owner) { MyMesh = mesh; m_owner = owner; MeshVerts = new Vector3[mesh.vertices.Length]; mesh.vertices.CopyTo(MeshVerts,0); Vertexsegment = segment; MyDirection = dir; Fps = 1f / maxFps; SetPosition(Vector3.zero); InitVerts(); }
private void InitMeshObj() { this.mMeshObj = new GameObject("_XWeaponTrailMesh: " + base.gameObject.name); this.mMeshObj.layer = base.gameObject.layer; this.mMeshObj.SetActive(true); MeshFilter filter = this.mMeshObj.AddComponent <MeshFilter>(); MeshRenderer renderer = this.mMeshObj.AddComponent <MeshRenderer>(); renderer.castShadows = false; renderer.receiveShadows = false; renderer.GetComponent <Renderer>().sharedMaterial = this.MyMaterial; filter.sharedMesh = new Mesh(); this.mVertexPool = new VertexPool(filter.sharedMesh, this.MyMaterial); this.mVertexSegment = this.mVertexPool.GetVertices(this.Granularity * 3, (this.Granularity - 1) * 12); this.UpdateIndices(); }
void LateUpdate() { //make sure each mesh position is always zero. for (int i = 0; i < MeshList.Count; i++) { GameObject obj = MeshList[i]; if (obj != null) { obj.transform.position = Vector3.zero; obj.transform.rotation = Quaternion.identity; } } for (int i = 0; i < MatList.Count; i++) { VertexPool vp = MatList[i]; vp.LateUpdate(); } if (ElapsedTime > LifeTime && LifeTime >= 0) { DoFinish(); } else if (LifeTime < 0 && EflList.Count > 0) { //Xffect LifeTime < 0, 且又是EmitByRate的话,会自动判断是否已经没有活动节点,没有则自动Deactive()。 float deltaTime = (float)(CurTime - LastTime); bool allEfLFinished = true; for (int i = 0; i < EflList.Count; i++) { EffectLayer el = EflList[i]; if (!el.EmitOver(deltaTime)) { allEfLFinished = false; } } if (allEfLFinished) { DoFinish(); } } }
public RibbonTrail(VertexPool.VertexSegment segment, Camera mainCam, bool useFaceObj, Transform faceobj, 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; OriHeadPos = pos; SetTrailLen(len); UnitWidth = width; HeadPosition = pos; StretchType = stretchType; Vector3 dir; if (UseFaceObject) dir = faceobj.position - HeadPosition; else dir = Vector3.zero; Element dtls = new Element(HeadPosition, UnitWidth); dtls.Normal = dir.normalized; 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); dtls2.Normal = dir.normalized; AddElememt(dtls2); //Use ElementPool to reduce gc alloc! for (int i = 0; i < MaxElements; i++) { ElementPool.Add(new Element(HeadPosition, UnitWidth)); } MainCam = mainCam; UseFaceObject = useFaceObj; FaceObject = faceobj; }
//x for displacement control //y for dissolve control. public override void ApplyShaderParam(float x, float y) { Vector2 param = Vector2.one; param.x = x; param.y = y; VertexPool pool = Vertexsegment.Pool; int index = Vertexsegment.VertStart; for (int i = 0; i < Vertexsegment.VertCount; i++) { pool.UVs2[index + i] = param; } Vertexsegment.Pool.UV2Changed = true; }
void UpdateMeshObj() { //make sure each mesh position is always zero. for (int i = 0; i < MeshList.Count; i++) { GameObject obj = MeshList[i]; if (obj != null) { obj.transform.position = Vector3.zero; obj.transform.rotation = Quaternion.identity; } } if (MergeSameMaterialMesh) { //ElementAt() STILL CAUSE GC ALLOC!! SO WE CAN'T AVOID GC ALLOC IN DICTIONARY? //for (int i = 0; i < MatDic.Count; i++) //{ // KeyValuePair<string,VertexPool> pair = MatDic.ElementAt(i); // pair.Value.LateUpdate(); //} //foreach (KeyValuePair<string, VertexPool> pair in MatDic) //{ // pair.Value.LateUpdate(); //} //Thanks to Ali Abdul-Karim's solution, no gc alloced now. var enumerator = MatDic.GetEnumerator(); while (enumerator.MoveNext()) { var element = enumerator.Current; // loop body goes here element.Value.LateUpdate(); } } else { for (int i = 0; i < MatList.Count; i++) { VertexPool vp = MatList[i]; vp.LateUpdate(); } } }
void RetreiveDecalMesh() { VertexPool pool = mVertexsegment.Pool; int index = mVertexsegment.IndexStart; int vindex = mVertexsegment.VertStart; int vcount = mVertexsegment.VertCount; int icount = mVertexsegment.IndexCount; Matrix4x4 localToWorldMatrix; Vector3 temp = Node.Owner.transform.position; Node.Owner.transform.position = Node.CurWorldPos; localToWorldMatrix = Node.Owner.transform.localToWorldMatrix; Node.Owner.transform.position = temp; MyColor = Color.white; //if the vert is not enough, just return.. for (int i = 0; i < bufVertices.Count; i++) { if (i >= vcount) { break; } Vector3 v1 = localToWorldMatrix.MultiplyPoint(bufVertices[i]); pool.Vertices[vindex + i] = v1; pool.UVs[i + vindex] = bufTexCoords[i]; pool.Colors[vindex + i] = MyColor; } for (int i = 0; i < bufIndices.Count; i++) { if (i >= icount) { break; } pool.Indices[i + index] = bufIndices[i] + vindex; } pool.IndiceChanged = pool.VertChanged = pool.UVChanged = pool.ColorChanged = true; }
public void UpdateColor() { VertexPool pool = mVertexsegment.Pool; int index = mVertexsegment.VertStart; int vcount = mVertexsegment.VertCount; for (int i = 0; i < bufVertices.Count; i++) { if (i >= vcount) { break; } pool.Colors[index + i] = MyColor; } mVertexsegment.Pool.ColorChanged = true; }
public void UpdateUV() { VertexPool pool = Vertexsegment.Pool; int index = Vertexsegment.VertStart; float uvSeg = UVDimensions.x / NumSegment; for (int i = 0; i < NumSegment + 1; i++) { pool.UVs[index + i] = LowerLeftUV; pool.UVs[index + i].x += i * uvSeg; } for (int i = NumSegment + 1; i < NumVerts; i++) { pool.UVs[index + i] = LowerLeftUV + Vector2.up * UVDimensions.y; pool.UVs[index + i].x += (i - NumSegment - 1) * uvSeg; } Vertexsegment.Pool.UVChanged = true; }
public void Transform() { if (Node.Owner.RotAffectorEnable || OriRotAngle != 0f) { UpdateVerts(); } Quaternion rot; if (Node.Owner.AlwaysSyncRotation) { rot = Quaternion.FromToRotation(Vector3.up, Node.Owner.transform.rotation * Direction); } else { rot = Quaternion.FromToRotation(Vector3.up, Direction); } for (int i = 0; i < NumSegment + 1; i++) { VertsTemp[i] = Verts[i] * Scale.x; VertsTemp[i] = rot * VertsTemp[i]; VertsTemp[i] = VertsTemp[i] + Position; } for (int i = NumSegment + 1; i < NumVerts; i++) {//注意只扩大Y轴。 //VertsTemp[i] = Verts[i]; VertsTemp[i] = Verts[i] * Scale.x; VertsTemp[i].y = Verts[i].y * Scale.y; VertsTemp[i] = rot * VertsTemp[i]; VertsTemp[i] = VertsTemp[i] + Position; } VertexPool pool = Vertexsegment.Pool; int index = Vertexsegment.VertStart; for (int i = 0; i < NumVerts; i++) { pool.Vertices[index + i] = VertsTemp[i]; } }
public void Transform() { Quaternion rot = Quaternion.FromToRotation(Vector3.up, MyDirection); Vector3 scale = Vector3.one; scale.x = scale.z = MyScale.x; scale.y = MyScale.y; LocalMat.SetTRS(Vector3.zero, rot * MyRotation, scale); WorldMat.SetTRS(MyPosition, Quaternion.identity, Vector3.one); Matrix4x4 mat = WorldMat * LocalMat; VertexPool pool = Vertexsegment.Pool; for (int i = Vertexsegment.VertStart; i < Vertexsegment.VertStart + Vertexsegment.VertCount; i++) { pool.Vertices[i] = mat.MultiplyPoint3x4(MeshVerts[i - Vertexsegment.VertStart]); } }
void InitMeshObj() { //create a new mesh obj mMeshObj = new GameObject("_XWeaponTrailMesh: " + gameObject.name); mMeshObj.layer = gameObject.layer; mMeshObj.SetActive(true); MeshFilter mf = mMeshObj.AddComponent <MeshFilter>(); MeshRenderer mr = mMeshObj.AddComponent <MeshRenderer>(); mr.castShadows = false; mr.receiveShadows = false; mr.renderer.sharedMaterial = MyMaterial; mf.sharedMesh = new Mesh(); //init vertexpool mVertexPool = new VertexPool(mf.sharedMesh, MyMaterial); mVertexSegment = mVertexPool.GetVertices(Granularity * 3, (Granularity - 1) * 12); UpdateIndices(); }
public override void Update(float deltaTime) { //if (Node.Owner.ColorAffectorEnable || Node.mIsFade) SetColor(Node.Color); if (Node.Owner.UVAffectorEnable || Node.Owner.UVRotAffectorEnable || Node.Owner.UVScaleAffectorEnable) { SetUVCoord(Node.LowerLeftUV, Node.UVDimensions); } SetPosition(Node.CurWorldPos); if (UVChanged) { UpdateUV(); } if (ColorChanged) { UpdateColor(); } UVChanged = ColorChanged = false; UpdateCenterPos(); mRadius = Node.Scale.x * Node.Owner.SpriteWidth * Node.OriScaleX; //set radius to shader!!! VertexPool pool = Vertexsegment.Pool; int index = Vertexsegment.VertStart; Vector2 param = Vector2.one; param.x = mRadius; //set rotation! param.y = ((float)Node.OriRotateAngle + Node.RotateAngle) * Mathf.PI / 180f; pool.UVs2[index + 0] = param; pool.UVs2[index + 1] = param; pool.UVs2[index + 2] = param; pool.UVs2[index + 3] = param; Vertexsegment.Pool.UV2Changed = true; }
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; }
private void UpdateVertex() { VertexPool pool = this.mVertexSegment.Pool; for (int i = 0; i < this.Granularity; i++) { int index = this.mVertexSegment.VertStart + (i * 3); float num3 = ((float)i) / ((float)this.Granularity); float tl = num3 * this.mFadeT; if ((int)FengGameManagerMKII.settings[360] == 0) { tl = num3 * 1.5f; } Vector2 zero = Vector2.zero; Vector3 vector2 = this.mSpline.InterpolateByLen(tl); Vector3 vector3 = this.mSpline.InterpolateNormalByLen(tl); Vector3 vector4 = vector2 + ((Vector3)((vector3.normalized * this.mTrailWidth) * 0.5f)); Vector3 vector5 = vector2 - ((Vector3)((vector3.normalized * this.mTrailWidth) * 0.5f)); pool.Vertices[index] = vector4; pool.Colors[index] = this.MyColor; zero.x = 0f; zero.y = num3; pool.UVs[index] = zero; pool.Vertices[index + 1] = vector2; pool.Colors[index + 1] = this.MyColor; zero.x = 0.5f; zero.y = num3; pool.UVs[index + 1] = zero; pool.Vertices[index + 2] = vector5; pool.Colors[index + 2] = this.MyColor; zero.x = 1f; zero.y = num3; pool.UVs[index + 2] = zero; } this.mVertexSegment.Pool.UVChanged = true; this.mVertexSegment.Pool.VertChanged = true; this.mVertexSegment.Pool.ColorChanged = true; }
//x for displacement control //y for dissolve control. public override void ApplyShaderParam(float x, float y) { //haven't retrieve the verts. if (mVertexsegment == null) { return; } Vector2 param = Vector2.one; param.x = x; param.y = y; VertexPool pool = mVertexsegment.Pool; int index = mVertexsegment.VertStart; for (int i = 0; i < mVertexsegment.VertCount; i++) { pool.UVs2[index + i] = param; } mVertexsegment.Pool.UV2Changed = true; }
public Sprite(VertexPool.VertexSegment segment, float width, float height, STYPE type, ORIPOINT oripoint, Camera cam, int uvStretch, float maxFps,bool simple) { 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; Simple = simple; OriPoint = oripoint; RotateAxis = Vector3.zero; SetSizeXZ(width, height); RotateAxis.y = 1; Type = type; MainCamera = cam; ResetSegment(); }
public void UpdateUV() { VertexPool pool = Vertexsegment.Pool; int vindex = Vertexsegment.VertStart; for (int i = 0; i < m_oriUvs.Length; i++) { Vector2 curScale = LowerLeftUV + Vector2.Scale(m_oriUvs[i], UVDimensions); //fix wrap : repeat. if (curScale.x > UVDimensions.x + LowerLeftUV.x) { float delta = curScale.x - UVDimensions.x - LowerLeftUV.x; delta = Mathf.Repeat(delta, UVDimensions.x + LowerLeftUV.x); curScale.x = LowerLeftUV.x + delta * UVDimensions.x; } pool.UVs[i + vindex] = curScale; } Vertexsegment.Pool.UVChanged = true; }
private void UpdateIndices() { VertexPool pool = mVertexSegment.Pool; for (int i = 0; i < Granularity - 1; i++) { int num = mVertexSegment.VertStart + i * 3; int num2 = mVertexSegment.VertStart + (i + 1) * 3; int num3 = mVertexSegment.IndexStart + i * 12; pool.Indices[num3] = num2; pool.Indices[num3 + 1] = num2 + 1; pool.Indices[num3 + 2] = num; pool.Indices[num3 + 3] = num2 + 1; pool.Indices[num3 + 4] = num + 1; pool.Indices[num3 + 5] = num; pool.Indices[num3 + 6] = num2 + 1; pool.Indices[num3 + 7] = num2 + 2; pool.Indices[num3 + 8] = num + 1; pool.Indices[num3 + 9] = num2 + 2; pool.Indices[num3 + 10] = num + 2; pool.Indices[num3 + 11] = num + 1; } pool.IndiceChanged = true; }
void UpdateMeshObj() { //make sure each mesh position is always zero. for (int i = 0; i < MeshList.Count; i++) { GameObject obj = MeshList[i]; if (obj != null) { obj.transform.position = Vector3.zero; obj.transform.rotation = Quaternion.identity; } } if (MergeSameMaterialMesh) { //ElementAt() STILL CAUSE GC ALLOC!! SO WE CAN'T AVOID GC ALLOC IN DICTIONARY? //for (int i = 0; i < MatDic.Count; i++) //{ // KeyValuePair<string,VertexPool> pair = MatDic.ElementAt(i); // pair.Value.LateUpdate(); //} foreach (KeyValuePair <string, VertexPool> pair in MatDic) { pair.Value.LateUpdate(); } } else { for (int i = 0; i < MatList.Count; i++) { VertexPool vp = MatList[i]; vp.LateUpdate(); } } }
private void UpdateIndices() { VertexPool pool = this.mVertexSegment.Pool; for (int i = 0; i < (this.Granularity - 1); i++) { int num2 = this.mVertexSegment.VertStart + (i * 3); int num3 = this.mVertexSegment.VertStart + ((i + 1) * 3); int index = this.mVertexSegment.IndexStart + (i * 12); pool.Indices[index] = num3; pool.Indices[index + 1] = num3 + 1; pool.Indices[index + 2] = num2; pool.Indices[index + 3] = num3 + 1; pool.Indices[index + 4] = num2 + 1; pool.Indices[index + 5] = num2; pool.Indices[index + 6] = num3 + 1; pool.Indices[index + 7] = num3 + 2; pool.Indices[index + 8] = num2 + 1; pool.Indices[index + 9] = num3 + 2; pool.Indices[index + 10] = num2 + 2; pool.Indices[index + 11] = num2 + 1; } pool.IndiceChanged = true; }
void LateUpdate() { //make sure each mesh position is always zero. for (int i = 0; i < MeshList.Count; i++) { GameObject obj = MeshList[i]; if (obj != null) { obj.transform.position = Vector3.zero; obj.transform.rotation = Quaternion.identity; } } if (MergeSameMaterialMesh) { //ElementAt() STILL CAUSE GC ALLOC!! SO WE CAN'T AVOID GC ALLOC IN DICTIONARY? //for (int i = 0; i < MatDic.Count; i++) //{ // KeyValuePair<string,VertexPool> pair = MatDic.ElementAt(i); // pair.Value.LateUpdate(); //} foreach (KeyValuePair <string, VertexPool> pair in MatDic) { pair.Value.LateUpdate(); } } else { for (int i = 0; i < MatList.Count; i++) { VertexPool vp = MatList[i]; vp.LateUpdate(); } } if (ElapsedTime > LifeTime && LifeTime >= 0) { DoFinish(); } else if (LifeTime < 0 && EflList.Count > 0) { //Xffect LifeTime < 0, 且又是EmitByRate的话,会自动判断是否已经没有活动节点,没有则自动Deactive()。 float deltaTime = (float)(CurTime - LastTime); bool allEfLFinished = true; for (int i = 0; i < EflList.Count; i++) { EffectLayer el = EflList[i]; if (!el.EmitOver(deltaTime)) { allEfLFinished = false; } } if (allEfLFinished) { DoFinish(); } } }
//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 Decal(VertexPool pool) { mPool = pool; buffPolygon = new DecalPolygon(); }
//this function should be very optimized public void Transform() { // 2017.03.23 法师技能中断线,Node.MyCamera == null,抛异常 if (Node == null || Node.MyCamera == null) { return; } LocalMat.SetTRS(Vector3.zero, Rotation, ScaleVector); Transform t = Node.MyCamera.transform; if (Type == STYPE.BILLBOARD) { MyTransform.LookAt(t.rotation * Vector3.up, t.rotation * Vector3.back); } else if (Type == STYPE.BILLBOARD_Y) { Vector3 diff = t.position - MyTransform.position; diff.y = 0f; MyTransform.LookAt(Vector3.up, diff); } else if (Type == STYPE.XY) { if (Node.Owner.AlwaysSyncRotation) { MyTransform.rotation = Node.Owner.transform.rotation * MyTransform.rotation; } } 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; Vector3 mscale = Vector3.one * (Node.Owner.Owner.Scale); if (Node.Owner.SpriteUVStretch == UV_STRETCH.Vertical) { 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; //fixed ver 2.1.2: the scale may influence the direction! //Vector3 vP1ToEye = MainCamera.transform.position - headElem; Vector3 vP1ToEye = t.position - Vector3.Scale(headElem, mscale); Vector3 vPerpendicular1 = Vector3.Cross(chainTangent, vP1ToEye); vPerpendicular1.Normalize(); vPerpendicular1 *= (vWidth * 0.5f); //Vector3 vP2ToEye = MainCamera.transform.position - tailElem; Vector3 vP2ToEye = t.position - Vector3.Scale(tailElem, mscale); Vector3 vPerpendicular2 = Vector3.Cross(chainTangent, vP2ToEye); vPerpendicular2.Normalize(); vPerpendicular2 *= (vWidth * 0.5f); //Debug.DrawRay(MainCamera.transform.position,-vP2ToEye * 1000f,Color.red,10f); if (Node.Owner.SpriteUVStretch == UV_STRETCH.Vertical) { 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].Set(v1w.x, UseCustomHeight ? h1 : v1w.y, v1w.z); pool.Vertices[index + 1].Set(v2w.x, UseCustomHeight ? h2 : v2w.y, v2w.z); pool.Vertices[index + 2].Set(v3w.x, UseCustomHeight ? h3 : v3w.y, v3w.z); pool.Vertices[index + 3].Set(v4w.x, UseCustomHeight ? h4 : v4w.y, v4w.z); }
void UpdateVertices() { VertexPool pool = mVertexSegment.Pool; Vector3 chainTangent = Vector3.zero; Vector3 eyePos = Node.MyCamera.transform.position; for (int i = 0; i < mElementList.Count; i++) { Element elem = mElementList[i]; int baseIdx = mVertexSegment.VertStart + i * 3; Vector2 uvCoord = Vector2.zero; float uvSegment = (float)i / (mLastValidElemIndex); if (i > mLastValidElemIndex) { Vector3 lastPos = mElementList[mLastValidElemIndex].Position; //ignore this segment: pool.Vertices[baseIdx] = lastPos; pool.Colors[baseIdx] = Color.clear; uvCoord.x = 0f; uvCoord.y = 1f; pool.UVs[baseIdx] = uvCoord; //pos pool.Vertices[baseIdx + 1] = lastPos; pool.Colors[baseIdx + 1] = Color.clear; uvCoord.x = 0.5f; uvCoord.y = 1f; pool.UVs[baseIdx + 1] = uvCoord; //pos1 pool.Vertices[baseIdx + 2] = lastPos; pool.Colors[baseIdx + 2] = Color.clear; uvCoord.x = 1f; uvCoord.y = 1f; pool.UVs[baseIdx + 2] = uvCoord; continue; } if (i == 0) { //tail Element prevElem = mElementList[i + 1]; chainTangent = elem.Position - prevElem.Position; } else if (i == mLastValidElemIndex) { //head Element nextElem = mElementList[i - 1]; chainTangent = nextElem.Position - elem.Position; } else { //mid Element nextElem = mElementList[i - 1]; Element prevElem = mElementList[i + 1]; chainTangent = nextElem.Position - prevElem.Position; } Vector3 vP1ToEye = eyePos - elem.Position; Vector3 vPerpendicular = Vector3.Cross(chainTangent, vP1ToEye); vPerpendicular.Normalize(); vPerpendicular *= (elem.Width * 0.5f * Node.Scale.x * Node.OriScaleX); Vector3 pos = elem.Position; Vector3 pos0 = elem.Position - vPerpendicular; Vector3 pos1 = elem.Position + vPerpendicular; // pos0 pool.Vertices[baseIdx] = pos0; pool.Colors[baseIdx] = mColor; uvCoord.x = 0f; uvCoord.y = uvSegment; pool.UVs[baseIdx] = uvCoord; //pos pool.Vertices[baseIdx + 1] = pos; pool.Colors[baseIdx + 1] = mColor; uvCoord.x = 0.5f; uvCoord.y = uvSegment; pool.UVs[baseIdx + 1] = uvCoord; //pos1 pool.Vertices[baseIdx + 2] = pos1; pool.Colors[baseIdx + 2] = mColor; uvCoord.x = 1f; uvCoord.y = uvSegment; pool.UVs[baseIdx + 2] = uvCoord; } mVertexSegment.Pool.UVChanged = true; mVertexSegment.Pool.VertChanged = true; mVertexSegment.Pool.ColorChanged = true; }
void InitMeshObj() { //init vertexpool mVertexPool = new VertexPool(MyMaterial, this); mVertexSegment = mVertexPool.GetVertices(Granularity * 3, (Granularity - 1) * 12); UpdateIndices(); }
public void UpdateVertices() { float uvSegment = 0f; float uvLen = 0f; //NOTE: ONLY USE THE DUMMY NODE'S UV CHANGE Vector2 LowerLeftUV = dummyNode.LowerLeftUV; Vector2 UVDimensions = dummyNode.UVDimensions; // change to lower left coord? UVDimensions.y = -UVDimensions.y; LowerLeftUV.y = 1f - LowerLeftUV.y; float totalUVLen = Owner.RopeUVLen; if (Owner.RopeFixUVLen) { float t = 0; for (int i = 0; i < NodeList.Count - 1; i++) { t += (NodeList[i + 1].GetWorldPos() - NodeList[i].GetWorldPos()).magnitude; } totalUVLen = t; } for (int i = NodeList.Count - 1; i >= 0; i--) { EffectNode node = NodeList[i]; EffectNode prevNode = i + 1 < NodeList.Count ? NodeList[i + 1] : null; EffectNode nextNode = i - 1 >= 0 ? NodeList[i - 1] : null; Vector3 chainTangent; if (nextNode == null) { //tail node chainTangent = node.GetWorldPos() - prevNode.GetWorldPos(); } else if (prevNode == null) { //head node chainTangent = nextNode.GetWorldPos() - node.GetWorldPos(); } else { chainTangent = nextNode.GetWorldPos() - prevNode.GetWorldPos(); } Vector3 eyePos = Owner.MyCamera.transform.position; Vector3 vP1ToEye = eyePos - node.GetWorldPos(); Vector3 vPerpendicular = Vector3.Cross(chainTangent, vP1ToEye); vPerpendicular.Normalize(); vPerpendicular *= (Owner.RopeWidth * 0.5f * node.Scale.x); //Debug.DrawRay(node.GetWorldPos(), vPerpendicular, Color.red, 1f); Vector3 pos0 = node.GetWorldPos() - vPerpendicular; Vector3 pos1 = node.GetWorldPos() + vPerpendicular; VertexPool pool = Vertexsegment.Pool; //if (Owner.StretchType == 0) uvSegment = (uvLen / totalUVLen) * Mathf.Abs(UVDimensions.y); // else // uvSegment = (uvLen / totalUVLen) * Mathf.Abs(UVDimensions.x); Vector2 uvCoord = Vector2.zero; int baseIdx = Vertexsegment.VertStart + node.Index * 2; pool.Vertices[baseIdx] = pos0; pool.Colors[baseIdx] = node.Color; //if (Owner.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] = node.Color; //if (Owner.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 (nextNode != null) { uvLen += (nextNode.GetWorldPos() - node.GetWorldPos()).magnitude; } else { uvLen += (node.GetWorldPos() - prevNode.GetWorldPos()).magnitude; } } Vertexsegment.Pool.UVChanged = true; Vertexsegment.Pool.VertChanged = true; 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; // fixed 2012.7.7 to use slash trail. if (!UseFaceObject) { vP1ToEye = eyePos - elem.Position; } else { vP1ToEye = elem.Normal; } 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? }
void InitMeshObj() { //create a new mesh obj mMeshObj = new GameObject("_XWeaponTrailMesh: " + gameObject.name); mMeshObj.layer = gameObject.layer; mMeshObj.SetActive(true); MeshFilter mf = mMeshObj.AddComponent<MeshFilter>(); MeshRenderer mr = mMeshObj.AddComponent<MeshRenderer>(); mr.castShadows = false; mr.receiveShadows = false; mr.GetComponent<Renderer>().sharedMaterial = MyMaterial; mf.sharedMesh = new Mesh(); //init vertexpool mVertexPool = new VertexPool(mf.sharedMesh, MyMaterial); mVertexSegment = mVertexPool.GetVertices(Granularity * 3, (Granularity - 1) * 12); UpdateIndices(); }
//this function should be very optimized public void Transform() { LocalMat.SetTRS(Vector3.zero, Rotation, ScaleVector); Transform t = MainCamera.transform; if (Type == STYPE.BILLBOARD) { MyTransform.LookAt(t.rotation * Vector3.up, t.rotation * Vector3.back); } else if (Type == STYPE.BILLBOARD_Y) { Vector3 diff = t.position - MyTransform.position; diff.y = 0f; MyTransform.LookAt(Vector3.up, diff); } 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; Vector3 mscale = Vector3.one * (Owner.Owner.Owner.Scale); 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; //fixed ver 2.1.2: the scale may influence the direction! //Vector3 vP1ToEye = MainCamera.transform.position - headElem; Vector3 vP1ToEye = MainCamera.transform.position - Vector3.Scale(headElem, mscale); Vector3 vPerpendicular1 = Vector3.Cross(chainTangent, vP1ToEye); vPerpendicular1.Normalize(); vPerpendicular1 *= (vWidth * 0.5f); //Vector3 vP2ToEye = MainCamera.transform.position - tailElem; Vector3 vP2ToEye = MainCamera.transform.position - Vector3.Scale(tailElem, mscale); Vector3 vPerpendicular2 = Vector3.Cross(chainTangent, vP2ToEye); vPerpendicular2.Normalize(); vPerpendicular2 *= (vWidth * 0.5f); //Debug.DrawRay(MainCamera.transform.position,-vP2ToEye * 1000f,Color.red,10f); 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; if (UseCustomHeight) { pool.Vertices[index + 0].y = h1; pool.Vertices[index + 1].y = h2; pool.Vertices[index + 2].y = h3; pool.Vertices[index + 3].y = h4; } }
public SphericalBillboard(VertexPool.VertexSegment segment) { UVChanged = ColorChanged = false; Vertexsegment = segment; ResetSegment(); }
//更新每个顶点元素的位置 public void UpdateVertices(Vector3 eyePos) { Vector3 chainTangent; float uvSegment = 0f; float uvLen = 0f; float trailLen = ElemLength * (MaxElements - 2); Vector3 mscale = Vector3.one * Owner.Owner.Owner.Scale; if (Head != CHAIN_EMPTY && Head != Tail) { int laste = Head; float totalUVLen = 0; if (IsScale) { for (int e = Head; ; ++e) { if (e == MaxElements) { e = 0; } Element elem = ElementArray[e]; if (e * 2 >= 65536) { Debug.LogError("Too many elements!"); } int nexte = e + 1; if (nexte == MaxElements) { nexte = 0; } if (e == Tail) { break; // last one } totalUVLen += (ElementArray[nexte].Position - elem.Position).magnitude; } } //使用Sine波动每个元素 位置 if (Owner.IsSine) { float SineFreqTime = Owner.SineFreqTime; float SineFreqDist = Owner.SineFreqDist; float SineMag = Owner.SineMagnitude; float t = Owner.GetElapsedTime(); float pi2 = 2 * Mathf.PI; for (int e = Head; ; ++e) { if (e == MaxElements) { e = 0; } Element elem = ElementArray[e]; int nexte = e + 1; if (nexte == MaxElements) { nexte = 0; } if (e == Tail) { break; } //根据 下一个顶点的位置 和 当前的顶点位置 Element next = ElementArray[nexte]; var dir = elem.InitPos - next.InitPos; var xDir = Vector3.Cross(dir, Vector3.up); float x = elem.Position.x; float z = elem.Position.z; float dist = Mathf.Sqrt(x * x + z * z); var virbrate = SineMag * Mathf.Sin(pi2 * SineFreqTime * t + pi2 * SineFreqDist * dist) * xDir.normalized; elem.Position = elem.InitPos + virbrate; elem.EndPos = elem.InitEndPos + virbrate; } } //重新计算VertexPool里面每一个顶点的世界坐标位置 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; chainTangent = Vector3.Scale(ElementArray[nexte].Position, mscale) - Vector3.Scale(elem.Position, mscale); } else if (e == Tail) { // No nexte, use only last item //chainTangent = elem.Position - ElementArray[laste].Position; chainTangent = Vector3.Scale(elem.Position, mscale) - Vector3.Scale(ElementArray[laste].Position, mscale); } else { // A mid position, use tangent across both prev and next //chainTangent = ElementArray[nexte].Position - ElementArray[laste].Position; chainTangent = Vector3.Scale(ElementArray[nexte].Position, mscale) - Vector3.Scale(ElementArray[laste].Position, mscale); } Vector3 vP1ToEye; // fixed 2012.7.7 to use slash trail. if (!UseFaceObject) { //vP1ToEye = eyePos - elem.Position; vP1ToEye = eyePos - Vector3.Scale(elem.Position, mscale); } else { vP1ToEye = elem.Normal; } Vector3 vPerpendicular = Vector3.Cross(chainTangent, vP1ToEye); vPerpendicular.Normalize(); vPerpendicular *= (elem.Width * 0.5f); Vector3 pos0; Vector3 pos1; if (IsWeapon) { pos0 = elem.Position; pos1 = elem.EndPos; } else { pos0 = elem.Position - vPerpendicular; pos1 = elem.Position + vPerpendicular; } VertexPool pool = Vertexsegment.Pool; if (IsScale) { if (StretchType == 0) { uvSegment = (uvLen / totalUVLen) * Mathf.Abs(UVDimensions.y); } else { uvSegment = (uvLen / totalUVLen) * Mathf.Abs(UVDimensions.x); } } else { 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? }