/// <summary> /// If we need this GPU solver, we should re-allocate in init; /// </summary> public void Init() { PositionOldRT = new RenderTexture[2]; Init_RT(sim.numberOfParticles(), RTFormat.RG, ref PositionRT); Init_RT(sim.numberOfParticles(), RTFormat.RG, ref PositionOldRT[curr]); Init_RT(sim.numberOfParticles(), RTFormat.RG, ref PositionOldRT[next]); //initialize the temporary texture2d for exchanging position bewteen cpu and gpu tempPos = new Texture2D(width, height, TextureFormat.RGBAFloat, false); tempPos.filterMode = FilterMode.Point; tempRect = new Rect(0f, 0f, (float)width, (float)height);//initialize the rect for readpixels particlePositionColor = new Color[width * height]; SendToGPU_ParticlePosition(); Graphics.Blit(PositionRT, PositionOldRT[curr]); GenerateParticleUV(); GenerateQuadMesh(); simSpring = new SimBuffer_Spring(sim, this.particleUV, width, height); simAngle = new SimBuffer_Angle(sim, this.particleUV, width, height); cBuffer = new CommandBuffer(); cBuffer.name = "SimBufferCommand"; cBuffer.Clear(); verletMpb = new MaterialPropertyBlock(); }
public void LateUpdate() { // if (mpb==null) { // mpb = new MaterialPropertyBlock (); // mpb.AddColor("_Color",color); // } if (mesh != null) { //if the sim changes data topology if (this.particleNumCache != sim.numberOfParticles() || this.stringNumCache != sim.numberOfSprings()) { //Debug.Log(this.particleNumCache); //Debug.Log(sim.numberOfParticles()); mesh.Clear(); CreateMesh(); this.particleNumCache = sim.numberOfParticles(); this.stringNumCache = sim.numberOfSprings(); } else { if (sim.numberOfParticles() > 2) { if (Application.isPlaying) { mesh.vertices = sim.getVerticesNonAlloc(); } else { mesh.vertices = sim.getVertices(); } mesh.RecalculateBounds(); } // else { } } } else { mesh = new Mesh(); CreateMesh(); this.meshFilter.sharedMesh = this.mesh; this.particleNumCache = sim.numberOfParticles(); this.stringNumCache = sim.numberOfSprings(); } if (color != colorCache) { SetColor(color); colorCache = color; } }
//called by editor script to set up data public void MeshLineRender_Ctor() { this.sim = this.GetComponent <IFormLayer>().GetSimulation; this.particleNumCache = sim.numberOfParticles(); this.stringNumCache = sim.numberOfSprings(); meshRenderer = this.GetComponent <MeshRenderer>(); if (meshRenderer == null) { meshRenderer = this.gameObject.AddComponent <MeshRenderer>(); } meshRenderer.receiveShadows = false; meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; meshRenderer.useLightProbes = false; meshRenderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; meshRenderer.sharedMaterial = Mtl; meshRenderer.hideFlags = HideFlags.HideInInspector; mpb = new MaterialPropertyBlock(); meshRenderer.GetPropertyBlock(mpb); mpb.SetColor("_Color", color); meshRenderer.SetPropertyBlock(mpb); colorCache = color; if (mesh == null) { mesh = new Mesh(); CreateMesh(); this.particleNumCache = sim.numberOfParticles(); this.stringNumCache = sim.numberOfSprings(); } meshFilter = this.GetComponent <MeshFilter>(); if (meshFilter == null) { meshFilter = this.gameObject.AddComponent <MeshFilter>(); } meshFilter.sharedMesh = mesh; meshFilter.hideFlags = HideFlags.HideInInspector; }
public static SimBuffer Create(Simulation sim) { int x, y; float u; if (sim.maxAngleConvergenceID <= 0 || sim.maxAngleConvergenceID <= 0) { Debug.LogError("The simualtion does not have correct convergence group, GPU solver cannot be created!"); return(null); } if (!SimBuffer.GetTexDimension(sim.numberOfParticles(), out x, out y, out u)) { Debug.LogError("Cannot create GPU rendertexture with wrong dimension"); return(null); } return(new SimBuffer(x, y, sim)); }
public SimBuffer_Spring(Simulation sim, Vector2[] particleUV, int width, int height) { this.sim = sim; rt = new RenderTexture[sim.maxSpringConvergenceID]; int parNum = sim.numberOfParticles(); ID_SpringParamRT = Shader.PropertyToID("_SpringParamRT"); ID_SpringConstant = Shader.PropertyToID("_SpringConstant"); ID_PositionRT = Shader.PropertyToID("_PositionRT"); //rg = the other end point's uv, b = restlength, a = state Color[] tempColor = new Color[width * height]; Texture2D tempTex = new Texture2D(width, height, TextureFormat.RGBAFloat, false, false); for (int i = 0; i < sim.maxSpringConvergenceID; i++) { //init rt rt[i] = new RenderTexture(width, height, 0, RTFormat.ARGB); rt[i].Create(); //prepare temp color for (int k = 0; k < width * height; k++) { if (k < parNum) { Vector2 uv = particleUV[k]; tempColor[k] = new Color(uv.x, uv.y, 1f, (sim.getParticle(k).IsFree) ? 1f : 0f); } else { tempColor[k] = new Color(0f, 0f, 1f, 0f); } } //get info for (int j = 0; j < sim.numberOfSprings(); j++) { Spring2D sp = sim.getSpring(j); if (sp.convergenceGroupID == i + 1) { int a = sim.getParticleIndex(sp.ParticleA); int b = sim.getParticleIndex(sp.ParticleB); tempColor[a].r = particleUV[b].x; tempColor[a].g = particleUV[b].y; tempColor[a].b = sp.restLength2; tempColor[a].a = (sp.ParticleA.IsFree) ? 1f : 0f; tempColor[b].r = particleUV[a].x; tempColor[b].g = particleUV[a].y; tempColor[b].b = sp.restLength2; tempColor[b].a = (sp.ParticleB.IsFree) ? 1f : 0f; } } //blit tempTex.SetPixels(tempColor); tempTex.Apply(); Graphics.Blit(tempTex, rt[i]); } Extension.ObjDestroy(tempTex); //mpb mpb = new MaterialPropertyBlock[sim.maxSpringConvergenceID]; for (int i = 0; i < sim.maxSpringConvergenceID; i++) { mpb[i] = new MaterialPropertyBlock(); mpb[i].SetTexture(ID_SpringParamRT, rt[i]); mpb[i].SetFloat(ID_SpringConstant, sim.Settings.springConstant); } //tempRT tempRT = new RenderTexture[sim.maxSpringConvergenceID - 1]; }
public SimBuffer_Angle(Simulation sim, Vector2[] particleUV, int width, int height) { this.sim = sim; int angleNum = sim.numberOfAngleConstraints(); int parNum = sim.numberOfParticles(); //angle uv float usage = 0f; if (!SimBuffer.GetTexDimension(angleNum, out deltaRTWidth, out deltaRTHeight, out usage)) { Debug.LogError("Cannot create SimBuffer Angle deltaw rt with wrong dimesnion!"); return; } angleUV = new Vector2[angleNum]; int count = 0; float halfW = 0.5f / deltaRTWidth; float halfH = 0.5f / deltaRTHeight; for (int y = 0; y < deltaRTHeight; y++) { for (int x = 0; x < deltaRTWidth; x++) { if (count < angleNum) { angleUV[count] = new Vector2((float)x / (float)deltaRTWidth + halfW, (float)y / (float)deltaRTHeight + halfH); } count++; } } tempRT = new RenderTexture[sim.maxAngleConvergenceID - 1]; tempDeltaRT = new RenderTexture[sim.maxAngleConvergenceID]; paramRT = new RenderTexture[sim.maxAngleConvergenceID]; deltaMesh = new Mesh[sim.maxAngleConvergenceID]; ID_AngleParamRT = Shader.PropertyToID("_AngleParamRT"); ID_AngleConstant = Shader.PropertyToID("_AngleConstant"); ID_PositionRT = Shader.PropertyToID("_PositionRT"); ID_AngleDeltaRT = Shader.PropertyToID("_AngleDeltaRT"); //rg = the other end point's uv, ba = uv in the delta rt Color[] paramRTColor = new Color[width * height]; Texture2D tempTex = new Texture2D(width, height, TextureFormat.RGBAFloat, false, false); for (int i = 0; i < sim.maxAngleConvergenceID; i++) { //delta mesh int agbyid = sim.numberOfAnglesByConvID(i + 1); deltaMesh[i] = SimBuffer.PointMesh(agbyid); List <Vector3> vtc = new List <Vector3> (agbyid); //xy = a uv,y=fixedangle List <Color> cl = new List <Color> (agbyid); //rg=b uv,ba = m uv; List <Vector2> uv = new List <Vector2> (agbyid); //delta rt uv; //init rt paramRT[i] = new RenderTexture(width, height, 0, RTFormat.ARGB); paramRT[i].Create(); //prepare temp color for (int k = 0; k < width * height; k++) { if (k < parNum) { Vector2 puv = particleUV[k]; paramRTColor[k] = new Color(puv.x, puv.y, 0f, 0f); //rg = other end,ba = uv in deltart } else { paramRTColor[k] = Color.clear; } } //get info for (int j = 0; j < angleNum; j++) { AngleConstraint2D ag = sim.getAngleConstraint(j); if (ag.convergenceGroupID == i + 1) { int a = sim.getParticleIndex(ag.ParticleB); int b = sim.getParticleIndex(ag.ParticleM); int aIndex = sim.getParticleIndex(ag.ParticleA); //if it's free, rg = the other end's uv, else = own uv if (ag.ParticleB.IsFree) { paramRTColor[a].r = particleUV[b].x; paramRTColor[a].g = particleUV[b].y; } if (ag.ParticleM.IsFree) { paramRTColor[b].r = particleUV[a].x; paramRTColor[b].g = particleUV[a].y; } paramRTColor[a].b = paramRTColor[b].b = angleUV[j].x; paramRTColor[a].a = paramRTColor[b].a = angleUV[j].y; //mesh vtc and cl vtc.Add(new Vector3(angleUV[j].x, angleUV[j].y, ag.angle_Fixed)); uv.Add(particleUV[aIndex]); cl.Add(new Color(particleUV[a].x, particleUV[a].y, particleUV[b].x, particleUV[b].y)); } } //blit tempTex.SetPixels(paramRTColor); tempTex.Apply(); Graphics.Blit(tempTex, paramRT[i]); //delta mesh deltaMesh[i].vertices = vtc.ToArray(); deltaMesh[i].colors = cl.ToArray(); deltaMesh[i].uv = uv.ToArray(); //deltaMesh[i].UploadMeshData(true); } Extension.ObjDestroy(tempTex); //mpb mpb = new MaterialPropertyBlock[sim.maxSpringConvergenceID]; for (int i = 0; i < sim.maxAngleConvergenceID; i++) { mpb[i] = new MaterialPropertyBlock(); mpb[i].SetTexture(ID_AngleParamRT, paramRT[i]); mpb[i].SetFloat(ID_AngleConstant, sim.Settings.angleConstant); } }