V minulém vlákně jsem se ptal na simulaci ohýbání papíru. Nakonec jsem jakž takž sesmolil kód, který však zcela nefunguje.
Podle rady hpjohna, uživatele mezinárodního Unity fóra, se snažím simulovat ohýbání papíru překrýváním dvou totožných meshů a pak zneviditelnit části obou nad přímkou, která znázorňuje ohyb...
Snad hpjohnův obrázek poslouží k hlubšímu pochopení:http://img62.imageshack.us/img62/414/b82.gif
Vše jsem jakž takž zpracoval, napsal jsem hrubý shader. Bohužel, meshe se nezneviditelňují podle správné přímky. Chybná je sice s onou vytouženou rovnoběžná, ale její vzdálenost není v pořádku... Toto je můj kód:
Kód: Vybrat vše
using UnityEngine;
using System.Collections;
public class Deform : MonoBehaviour {
Vector2[] initialUVs; //UV coordinates of the initial mesh
Transform obj2;//top object that moves (bottom object doesnt move)
Vector3 clickedPos = new Vector3(0,0,0);
Vector3 dir;
Vector3 dir2;
Vector3 midLine;
Vector3 perpendicular;
Vector3 currentMouse;
Vector3 mousePos;
Vector3 endPoint;
Vector3 dif;
Vector3 linePos;
bool bend;
Matrix4x4 m2;
Matrix4x4 m;
public Transform prefab;
void Start () {
}
void FixedUpdate () {
mousePos = Input.mousePosition;
mousePos.z = -Camera.main.transform.position.z;
mousePos = Camera.main.ScreenToWorldPoint(mousePos);
dif = transform.position;
var fwd = transform.TransformDirection (Vector3.forward);
if(Input.GetButtonDown("Bend") && Physics.Raycast (mousePos, fwd, 10) && !bend) {
clickedPos = mousePos;
bend = true;
obj2 = (Transform) Instantiate(prefab,mousePos,Quaternion.identity);
}
if(Input.GetButton("Bend") && bend){
currentMouse = mousePos;
dir = currentMouse - clickedPos;
midLine = ( clickedPos + currentMouse ) / 2;
perpendicular = new Vector3 ( dir.y, -dir.x, 0 );
}
if(Input.GetButtonUp("Bend")){
bend = false;
}
obj2.position = ((Vector3.Project( -(midLine - dif), perpendicular) + dif) + midLine - dif - dif/2) * 2 + Vector3.forward * 0.1f;
obj2.rotation = Quaternion.LookRotation( Vector3.forward, (clickedPos - transform.position) - (obj2.position - transform.position) ) * Quaternion.LookRotation( Vector3.forward, (currentMouse - transform.position));
obj2.renderer.material.SetColor("_Color", Color.yellow);
Matrix4x4 m2 = Matrix4x4.TRS(midLine,obj2.rotation,Vector3.one).inverse;
dir2 = m2.MultiplyVector(dir);
obj2.renderer.material.SetFloat("_a", dir2.x);
obj2.renderer.material.SetFloat("_b", dir2.y );
obj2.renderer.material.SetFloat("_c", -dir2.x * midLine.x - dir2.y * midLine.y);*/
renderer.material.SetFloat("_a", dir.x);
renderer.material.SetFloat("_b", dir.y);
renderer.material.SetFloat("_c", -dir.x * midLine.x - dir.y * midLine.y);
public static Vector3 RotateZ( Vector3 v, float angle){
float sin = Mathf.Sin( angle );
float cos = Mathf.Cos( angle );
float tx = (cos * v.x) - (sin * v.y);
float ty = (cos * v.y) + (sin * v.x);
return new Vector3 (tx,ty,0);
}
}
Kód: Vybrat vše
Shader "Custom/FoldInvis" {
Properties {
_MainTex ("Base (RGB) Trans(A)", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
_a ("a", float) = 0
_b ("b", float) = 0
_c ("c", float) = 0
}
SubShader {
Tags{"Queue"="Transparent"}
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
float4 _Color;
float _a;
float _b;
float _c;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 result = tex2D (_MainTex, IN.uv_MainTex);
clip (_a*IN.uv_MainTex.x + _b*IN.uv_MainTex.y + _c);
o.Albedo = result.rgb * _Color.rgb;
o.Alpha = result.a;
}
ENDCG
}
FallBack "Diffuse"
}
Netuším, kde mám chybu. Trochu mám z tohoto problému třas v krku, protože mi očividně uniká nějaký logický vztah. Vidíte vy chybu? Pokud ano, budu rád za jakoukoliv pomoc či odezvu...
Předem děkuji a přeji hezký den...