//========================================================================================= /// <summary> /// クロスに紐づくコライダーの表示 /// </summary> /// <param name="scr"></param> public static void DrawCollider(PhysicsTeam team) { if (ClothMonitorMenu.Monitor.UI.DrawClothCollider == false) { return; } var colliderlist = team.TeamData.ColliderList; foreach (var collider in colliderlist) { if (collider == null || collider.isActiveAndEnabled == false) { continue; } if (collider is MagicaSphereCollider) { MagicaSphereColliderGizmoDrawer.DrawGizmo(collider as MagicaSphereCollider, true); } else if (collider is MagicaCapsuleCollider) { MagicaCapsuleColliderGizmoDrawer.DrawGizmo(collider as MagicaCapsuleCollider, true); } } }
//========================================================================================= /// <summary> /// チームを作成する /// </summary> /// <returns></returns> public int CreateTeam(PhysicsTeam team, uint flag) { var data = new TeamData(); flag |= Flag_Enable; flag |= Flag_Reset_WorldInfluence; // 移動影響リセット data.flag = flag; data.friction = 0; data.boneIndex = team != null ? 0 : -1; // グローバルチームはボーン無し data.initScale = 0; data.scaleDirection = 1; data.scaleRatio = 1; data.quaternionScale = 1; //data.directionalDampingBoneIndex = team != null ? 0 : -1; // グローバルチームはボーン無し //data.directionalDampingLocalDir = new float3(0, 1, 0); data.timeScale = 1.0f; data.blendRatio = 1.0f; data.forceMassInfluence = 1.0f; data.forceWindInfluence = 1.0f; data.forceWindRandomScale = 0.0f; // 拘束チームインデックス data.restoreDistanceGroupIndex = -1; data.triangleBendGroupIndex = -1; data.clampDistanceGroupIndex = -1; data.clampDistance2GroupIndex = -1; data.clampPositionGroupIndex = -1; data.clampRotationGroupIndex = -1; data.restoreRotationGroupIndex = -1; data.adjustRotationGroupIndex = -1; data.springGroupIndex = -1; data.volumeGroupIndex = -1; data.airLineGroupIndex = -1; data.lineWorkerGroupIndex = -1; data.triangleWorkerGroupIndex = -1; data.selfCollisionGroupIndex = -1; data.edgeCollisionGroupIndex = -1; data.penetrationGroupIndex = -1; data.baseSkinningGroupIndex = -1; int teamId = teamDataList.Add(data); teamMassList.Add(new CurveParam(1.0f)); teamGravityList.Add(new CurveParam()); teamDragList.Add(new CurveParam()); teamMaxVelocityList.Add(new CurveParam()); //teamDirectionalDampingList.Add(new CurveParam()); teamWorldInfluenceList.Add(new WorldInfluence()); teamComponentDict.Add(teamId, team); if (team != null) { activeTeamCount++; } return(teamId); }
static void DrawLineRuntimeSub( PhysicsTeam team, Color color, RestoreDistanceConstraint.RestoreDistanceData[] distanceDataList ) { if (distanceDataList == null || distanceDataList.Length == 0) { return; } var manager = MagicaPhysicsManager.Instance; Gizmos.color = color; int cnt = distanceDataList.Length; for (int i = 0; i < cnt; i++) { var data = distanceDataList[i]; int vindex0, vindex1; vindex0 = data.vertexIndex; vindex1 = data.targetVertexIndex; int pindex0 = team.ParticleChunk.startIndex + vindex0; int pindex1 = team.ParticleChunk.startIndex + vindex1; Vector3 pos0 = manager.Particle.posList[pindex0]; Vector3 pos1 = manager.Particle.posList[pindex1]; Gizmos.DrawLine(pos0, pos1); } }
//========================================================================================= #if false static void DrawAdjustRotationLineRuntime( PhysicsTeam team, ClothData clothData ) { if (ClothMonitorMenu.Monitor.UI.DrawAdjustRotationLine == false) { return; } var manager = MagicaPhysicsManager.Instance; Gizmos.color = GizmoUtility.ColorAdjustLine; int cnt = clothData.AdjustRotationConstraintCount; for (int i = 0; i < cnt; i++) { var data = clothData.adjustRotationDataList[i]; int tindex = data.targetIndex; if (tindex < 0) { tindex = -tindex - 1; } int pindex0 = team.ParticleChunk.startIndex + data.keyIndex; int pindex1 = team.ParticleChunk.startIndex + tindex; Vector3 pos0 = manager.Particle.posList[pindex0]; Vector3 pos1 = manager.Particle.posList[pindex1]; Gizmos.DrawLine(pos0, pos1); } }
//========================================================================================= /// <summary> /// ブレンド率設定インスペクタ /// </summary> protected void UserBlendInspector() { PhysicsTeam scr = target as PhysicsTeam; EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.Slider(serializedObject.FindProperty("userBlendWeight"), 0.0f, 1.0f, "Blend Weight"); }
/// <summary> /// アバター着せ替えによるボーン置換 /// </summary> /// <param name="boneReplaceDict"></param> public void ReplaceBone(PhysicsTeam team, ClothParams param, Dictionary <Transform, Transform> boneReplaceDict) { // この呼び出しは ClothActive() の前なので注意! // ワールド移動影響ボーン切り替え Transform influenceTarget = param.GetInfluenceTarget(); if (influenceTarget && boneReplaceDict.ContainsKey(influenceTarget)) { param.SetInfluenceTarget(boneReplaceDict[influenceTarget]); } }
/// <summary> /// コライダー設定インスペクタ /// </summary> protected void ColliderInspector() { PhysicsTeam scr = target as PhysicsTeam; EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.LabelField("Collider", EditorStyles.boldLabel); EditorGUILayout.PropertyField(serializedObject.FindProperty("teamData.mergeAvatarCollider")); EditorInspectorUtility.DrawObjectList <ColliderComponent>( serializedObject.FindProperty("teamData.colliderList"), scr.gameObject, true, true ); }
public void ClothInactive(PhysicsTeam team) { if (MagicaPhysicsManager.IsInstance() == false) { return; } var manager = MagicaPhysicsManager.Instance; // 自身の登録ボーン開放 manager.Bone.RemoveBone(teamBoneIndex); manager.Team.SetBoneIndex(team.TeamId, -1); manager.Bone.RemoveBone(teamDirectionalDampingBoneIndex); manager.Team.SetDirectionalDampingBoneIndex(team.TeamId, false, -1, 0); }
//========================================================================================= /// <summary> /// クロス破棄 /// </summary> public void ClothDispose(PhysicsTeam team) { if (MagicaPhysicsManager.IsInstance() == false) { return; } // コンストレイント解放 MagicaPhysicsManager.Instance.Compute.RemoveTeam(team.TeamId); // パーティクル解放 team.RemoveAllParticle(); // 自身の登録ボーン開放 //MagicaPhysicsManager.Instance.Bone.RemoveBone(teamBoneIndex); }
//========================================================================================= public void ClothActive(PhysicsTeam team, ClothParams param, ClothData clothData) { var manager = MagicaPhysicsManager.Instance; // ワールド移動影響ボーンを登録 Transform influenceTarget = param.GetInfluenceTarget() ? param.GetInfluenceTarget() : team.transform; teamBoneIndex = manager.Bone.AddBone(influenceTarget); manager.Team.SetBoneIndex(team.TeamId, teamBoneIndex); team.InfluenceTarget = influenceTarget; // 重力方向減衰ボーンを登録 //Debug.Log("Damp dir:" + clothData.directionalDampingUpDir); influenceTarget = param.DirectionalDampingObject ? param.DirectionalDampingObject : team.transform; teamDirectionalDampingBoneIndex = manager.Bone.AddBone(influenceTarget); manager.Team.SetDirectionalDampingBoneIndex(team.TeamId, param.UseDirectionalDamping, teamDirectionalDampingBoneIndex, clothData.directionalDampingUpDir); }
//========================================================================================= /// <summary> /// ランタイム状態でのライン表示 /// </summary> /// <param name="scr"></param> /// <param name="deformer"></param> /// <param name="clothData"></param> static void DrawLineRuntime( PhysicsTeam team, ClothData clothData, ClothSetup setup, List <int> selList ) { if (ClothMonitorMenu.Monitor.UI.DrawClothStructDistanceLine) { DrawLineRuntimeSub(team, GizmoUtility.ColorStructLine, clothData.structDistanceDataList); } if (ClothMonitorMenu.Monitor.UI.DrawClothBendDistanceLine) { DrawLineRuntimeSub(team, GizmoUtility.ColorBendLine, clothData.bendDistanceDataList); } if (ClothMonitorMenu.Monitor.UI.DrawClothNearDistanceLine) { DrawLineRuntimeSub(team, GizmoUtility.ColorNearLine, clothData.nearDistanceDataList); } }
//========================================================================================= /// <summary> /// ランタイム状態での回転ライン表示 /// </summary> /// <param name="scr"></param> /// <param name="deformer"></param> /// <param name="clothData"></param> static void DrawRotationLineRuntime( PhysicsTeam team, ClothData clothData, ClothSetup setup, List <int> selList ) { if (ClothMonitorMenu.Monitor.UI.DrawClothRotationLine == false) { return; } if (clothData == null) { return; } if (clothData.parentList == null || clothData.parentList.Count != clothData.VertexUseCount) { return; } var manager = MagicaPhysicsManager.Instance; Gizmos.color = GizmoUtility.ColorRotationLine; for (int i = 0; i < clothData.VertexUseCount; i++) { int pi = clothData.parentList[i]; if (pi < 0) { continue; } int pindex0 = team.ParticleChunk.startIndex + i; int pindex1 = team.ParticleChunk.startIndex + pi; Vector3 pos0 = manager.Particle.posList[pindex0]; Vector3 pos1 = manager.Particle.posList[pindex1]; Gizmos.DrawLine(pos0, pos1); } }
//========================================================================================= #if false /// <summary> /// ランタイム状態でのボリューム表示 /// </summary> /// <param name="scr"></param> /// <param name="deformer"></param> /// <param name="clothData"></param> static void DrawVolumeRuntime( PhysicsTeam team, ClothData clothData, ClothSetup setup ) { if (ClothMonitorMenu.Monitor.UI.DrawClothVolume == false) { return; } var manager = MagicaPhysicsManager.Instance; Gizmos.color = GizmoUtility.ColorTriangle; int cnt = clothData.VolumeConstraintCount; for (int i = 0; i < cnt; i++) { var data = clothData.volumeDataList[i]; int pindex0 = team.ParticleChunk.startIndex + data.vindex0; int pindex1 = team.ParticleChunk.startIndex + data.vindex1; int pindex2 = team.ParticleChunk.startIndex + data.vindex2; int pindex3 = team.ParticleChunk.startIndex + data.vindex3; Vector3 pos0 = manager.Particle.posList[pindex0]; Vector3 pos1 = manager.Particle.posList[pindex1]; Vector3 pos2 = manager.Particle.posList[pindex2]; Vector3 pos3 = manager.Particle.posList[pindex3]; Gizmos.DrawLine(pos0, pos1); Gizmos.DrawLine(pos0, pos2); Gizmos.DrawLine(pos0, pos3); Gizmos.DrawLine(pos1, pos2); Gizmos.DrawLine(pos2, pos3); Gizmos.DrawLine(pos3, pos1); } }
//========================================================================================= public void ClothActive(PhysicsTeam team, ClothParams param, ClothData clothData) { var manager = MagicaPhysicsManager.Instance; // ワールド移動影響ボーンを登録 Transform influenceTarget = param.GetInfluenceTarget() ? param.GetInfluenceTarget() : team.transform; teamBoneIndex = manager.Bone.AddBone(influenceTarget); manager.Team.SetBoneIndex(team.TeamId, teamBoneIndex, clothData.initScale); team.InfluenceTarget = influenceTarget; // 重力方向減衰ボーンを登録 //Debug.Log("Damp dir:" + clothData.directionalDampingUpDir); //influenceTarget = param.DirectionalDampingObject ? param.DirectionalDampingObject : team.transform; //teamDirectionalDampingBoneIndex = manager.Bone.AddBone(influenceTarget); //manager.Team.SetDirectionalDampingBoneIndex(team.TeamId, param.UseDirectionalDamping, teamDirectionalDampingBoneIndex, clothData.directionalDampingUpDir); // ベーススキニング用ボーンを登録 //foreach (var bone in team.TeamData.SkinningBoneList) //{ // var boneIndex = manager.Bone.AddBone(bone); // manager.Team.AddSkinningBoneIndex(team.TeamId, boneIndex); //} }
//========================================================================================= /// <summary> /// ランタイム状態での浸透制限表示 /// </summary> /// <param name="team"></param> /// <param name="clothData"></param> /// <param name="selList"></param> static void DrawPenetrationRuntime( PhysicsTeam team, ClothParams param, ClothData clothData, List <int> selList ) { if (ClothMonitorMenu.Monitor.UI.DrawClothPenetration == false) { return; } if (clothData.penetrationDataList == null) { return; } if (clothData.penetrationReferenceList == null) { return; } //var mode = param.GetPenetrationMode(); var mode = clothData.penetrationMode; var colliderlist = team.TeamData.ColliderList; int vcnt = clothData.useVertexList.Count; for (int i = 0; i < vcnt; i++) { int vindex = clothData.useVertexList[i]; if (IsMove(vindex, selList) == false) { continue; } int pindex = team.ParticleChunk.startIndex + i; Vector3 pos = MagicaPhysicsManager.Instance.Particle.posList[pindex]; if (i >= clothData.penetrationReferenceList.Length) { return; } var refdata = clothData.penetrationReferenceList[i]; for (int j = 0; j < refdata.count; j++) { var dindex = refdata.startIndex + j; var data = clothData.penetrationDataList[dindex]; if (data.IsValid() == false) { continue; } if (mode == ClothParams.PenetrationMode.SurfacePenetration) { } else if (mode == ClothParams.PenetrationMode.ColliderPenetration) { int cindex = data.colliderIndex; if (cindex >= colliderlist.Count) { continue; } var col = colliderlist[cindex]; if (col == null) { continue; } var cp = col.transform.TransformPoint(data.localPos); //var pos = cp + col.transform.TransformDirection(data.localDir) * data.distance; Gizmos.color = GizmoUtility.ColorPenetration; Gizmos.DrawLine(pos, cp); } } } }
public static bool DrawClothGizmo( PhysicsTeam team, ClothData clothData, ClothParams param, ClothSetup setup, IEditorMesh editorMesh, IEditorCloth editorCloth ) { if (ClothMonitorMenu.Monitor.UI.DrawCloth == false) { return(false); } if (ClothMonitorMenu.Monitor.UI.DrawClothVertex == false && ClothMonitorMenu.Monitor.UI.DrawClothDepth == false && ClothMonitorMenu.Monitor.UI.DrawClothBase == false && ClothMonitorMenu.Monitor.UI.DrawClothCollider == false && ClothMonitorMenu.Monitor.UI.DrawClothStructDistanceLine == false && ClothMonitorMenu.Monitor.UI.DrawClothBendDistanceLine == false && ClothMonitorMenu.Monitor.UI.DrawClothNearDistanceLine == false && ClothMonitorMenu.Monitor.UI.DrawClothRotationLine == false && ClothMonitorMenu.Monitor.UI.DrawClothTriangleBend == false && ClothMonitorMenu.Monitor.UI.DrawClothPenetration == false //&& ClothMonitorMenu.Monitor.UI.DrawClothBaseSkinning == false && ClothMonitorMenu.Monitor.UI.DrawClothAxis == false //&& ClothMonitorMenu.Monitor.UI.DrawClothVolume == false #if MAGICACLOTH_DEBUG && ClothMonitorMenu.Monitor.UI.DrawClothVertexNumber == false && ClothMonitorMenu.Monitor.UI.DrawClothVertexIndex == false && ClothMonitorMenu.Monitor.UI.DrawPenetrationOrigin == false //&& ClothMonitorMenu.Monitor.UI.DrawAdjustRotationLine == false #endif ) { return(false); } if (clothData == null) { return(false); } if (Application.isPlaying) { if (clothData == null) { return(false); } if (team.IsActive() == false) { return(false); } // 頂点使用状態 //var useList = editorCloth.GetUseList(); var selList = editorCloth.GetSelectionList(); // 頂点情報 DrawVertexRuntime(team, clothData, param, setup, selList); // コライダー DrawCollider(team); // ライン DrawLineRuntime(team, clothData, setup, selList); // トライアングルベンド DrawTriangleBendRuntime(team, clothData, setup); // 回転ライン DrawRotationLineRuntime(team, clothData, setup, selList); // コライダー移動制限 DrawPenetrationRuntime(team, param, clothData, selList); // ボリューム //DrawVolumeRuntime(team, clothData, setup); // 回転調整ライン //DrawAdjustRotationLineRuntime(team, clothData); } else { // メッシュ頂点法線接線 List <Vector3> posList; List <Vector3> norList; List <Vector3> tanList; int vcnt = editorMesh.GetEditorPositionNormalTangent(out posList, out norList, out tanList); // 頂点使用状態 //var useList = editorCloth.GetUseList(); var selList = editorCloth.GetSelectionList(); // 頂点情報 DrawVertexClothData(clothData, param, vcnt, posList, norList, tanList, selList); // コライダー DrawCollider(team); // ライン DrawLineClothData(clothData, posList, selList); // トライアングルベンド DrawTriangleBendClothData(clothData, posList); // 回転ライン DrawRotationLineClothData(clothData, posList, selList); // コライダー移動制限 DrawPenetrationClothData(team, param, clothData, posList, norList, tanList, selList); // ベーススキニング //DrawBaseSkinningClothData(team, clothData, posList, selList); // ボリューム //DrawVolumeClothData(clothData, posList); // 回転調整ライン //DrawAdjustRotationLineClothData(clothData, posList); } return(true); }
//========================================================================================= /// <summary> /// ランタイムデータ変更 /// </summary> public void ChangeData(PhysicsTeam team, ClothParams param) { if (Application.isPlaying == false) { return; } if (MagicaPhysicsManager.IsInstance() == false) { return; } if (team == null) { return; } var manager = MagicaPhysicsManager.Instance; var compute = manager.Compute; bool changeMass = false; // 半径 if (param.ChangedParam(ClothParams.ParamType.Radius)) { // これはパーティクルごと for (int i = 0; i < team.ParticleChunk.dataLength; i++) { int pindex = team.ParticleChunk.startIndex + i; float depth = manager.Particle.depthList[pindex]; float radius = param.GetRadius(depth); manager.Particle.SetRadius(pindex, radius); } } // 重量 if (param.ChangedParam(ClothParams.ParamType.Mass)) { manager.Team.SetMass(team.TeamId, param.GetMass()); changeMass = true; } // 重力係数 if (param.ChangedParam(ClothParams.ParamType.Gravity)) { manager.Team.SetGravity(team.TeamId, param.GetGravity()); manager.Team.SetDirectionalDamping(team.TeamId, param.GetDirectionalDamping()); manager.Team.SetFlag(team.TeamId, PhysicsManagerTeamData.Flag_DirectionalDamping, param.UseDirectionalDamping); } // 空気抵抗 if (param.ChangedParam(ClothParams.ParamType.Drag)) { manager.Team.SetDrag(team.TeamId, param.GetDrag()); } // 最大速度 if (param.ChangedParam(ClothParams.ParamType.MaxVelocity)) { manager.Team.SetMaxVelocity(team.TeamId, param.GetMaxVelocity()); } // 外力 if (param.ChangedParam(ClothParams.ParamType.ExternalForce)) { manager.Team.SetExternalForce(team.TeamId, param.MassInfluence, param.WindInfluence, param.WindRandomScale); } // チームの摩擦係数変更 if (param.ChangedParam(ClothParams.ParamType.ColliderCollision)) { manager.Team.SetFriction(team.TeamId, param.Friction); } // チームワールド移動影響変更 if (param.ChangedParam(ClothParams.ParamType.WorldInfluence)) { manager.Team.SetWorldInfluence(team.TeamId, param.GetWorldMoveInfluence(), param.GetWorldRotationInfluence(), param.UseResetTeleport, param.TeleportDistance, param.TeleportRotation); } // 距離復元拘束パラメータ再設定 if (param.ChangedParam(ClothParams.ParamType.RestoreDistance) || changeMass) { compute.RestoreDistance.ChangeParam( team.TeamId, param.GetMass(), param.RestoreDistanceVelocityInfluence, param.GetStructDistanceStiffness(), param.UseBendDistance, param.GetBendDistanceStiffness(), param.UseNearDistance, param.GetNearDistanceStiffness() ); } // トライアングルベンド拘束パラメータ再設定 if (param.ChangedParam(ClothParams.ParamType.TriangleBend)) { compute.TriangleBend.ChangeParam(team.TeamId, param.UseTriangleBend, param.GetTriangleBendStiffness()); } // ボリューム拘束パラメータ再設定 //if (param.ChangedParam(ClothParams.ParamType.Volume)) //{ // compute.Volume.ChangeParam(team.TeamId, param.UseVolume, param.GetVolumeStretchStiffness(), param.GetVolumeShearStiffness()); //} // ルートからの最小最大距離拘束パラメータ再設定 if (param.ChangedParam(ClothParams.ParamType.ClampDistance)) { compute.ClampDistance.ChangeParam(team.TeamId, param.UseClampDistanceRatio, param.ClampDistanceMinRatio, param.ClampDistanceMaxRatio, param.ClampDistanceVelocityInfluence); } // 移動範囲拘束パラメータ再設定 if (param.ChangedParam(ClothParams.ParamType.ClampPosition)) { compute.ClampPosition.ChangeParam(team.TeamId, param.UseClampPositionLength, param.GetClampPositionLength(), param.ClampPositionAxisRatio, param.ClampPositionVelocityInfluence); } // 回転復元拘束パラメータ再設定 if (param.ChangedParam(ClothParams.ParamType.RestoreRotation)) { compute.RestoreRotation.ChangeParam(team.TeamId, param.UseRestoreRotation, param.GetRotationPower(), param.RestoreRotationVelocityInfluence); } // 最大回転拘束パラメータ再設定 if (param.ChangedParam(ClothParams.ParamType.ClampRotation)) { compute.ClampRotation.ChangeParam( team.TeamId, param.UseClampRotation, param.GetClampRotationAngle(), //param.GetClampRotationStiffness(), param.ClampRotationVelocityInfluence ); } // スプリング回転調整パラメータ再設定(これはワーカー) if (param.ChangedParam(ClothParams.ParamType.AdjustRotation)) { compute.AdjustRotationWorker.ChangeParam(team.TeamId, param.UseAdjustRotation, (int)param.AdjustRotationMode, param.AdjustRotationVector); } // コリジョン有無 if (param.ChangedParam(ClothParams.ParamType.ColliderCollision)) { manager.Team.SetFlag(team.TeamId, PhysicsManagerTeamData.Flag_Collision_KeepShape, param.KeepInitialShape); compute.Collision.ChangeParam(team.TeamId, param.UseCollision); //compute.EdgeCollision.ChangeParam(team.TeamId, param.UseCollision && param.UseEdgeCollision); } // スプリング拘束パラメータ再設定 if (param.ChangedParam(ClothParams.ParamType.Spring)) { compute.Spring.ChangeParam(team.TeamId, param.UseSpring, param.GetSpringPower()); } // 回転補間 if (param.ChangedParam(ClothParams.ParamType.RotationInterpolation)) { compute.LineWorker.ChangeParam(team.TeamId, param.UseLineAvarageRotation); manager.Team.SetFlag(team.TeamId, PhysicsManagerTeamData.Flag_FixedNonRotation, param.UseFixedNonRotation); } //変更フラグクリア param.ClearChangeParam(); }
//========================================================================================= /// <summary> /// クロス初期化 /// </summary> /// <param name="team"></param> /// <param name="meshData">メッシュデータ(不要ならnull)</param> /// <param name="clothData"></param> /// <param name="param"></param> /// <param name="funcUserFlag">各頂点の追加フラグ設定アクション</param> /// <param name="funcUserTransform">各頂点の連動トランスフォーム設定アクション</param> public void ClothInit( PhysicsTeam team, MeshData meshData, ClothData clothData, ClothParams param, System.Func <int, uint> funcUserFlag ) { var manager = MagicaPhysicsManager.Instance; var compute = manager.Compute; // チームデータ設定 manager.Team.SetMass(team.TeamId, param.GetMass()); manager.Team.SetGravity(team.TeamId, param.GetGravity()); manager.Team.SetDrag(team.TeamId, param.GetDrag()); manager.Team.SetMaxVelocity(team.TeamId, param.GetMaxVelocity()); manager.Team.SetFriction(team.TeamId, param.Friction); manager.Team.SetExternalForce(team.TeamId, param.MassInfluence, param.WindInfluence, param.WindRandomScale); manager.Team.SetDirectionalDamping(team.TeamId, param.GetDirectionalDamping()); // ワールド移動影響 manager.Team.SetWorldInfluence(team.TeamId, param.GetWorldMoveInfluence(), param.GetWorldRotationInfluence(), param.UseResetTeleport, param.TeleportDistance, param.TeleportRotation); int vcnt = clothData.VertexUseCount; Debug.Assert(vcnt > 0); Debug.Assert(clothData.useVertexList.Count > 0); // パーティクル追加(使用頂点のみ) var c = team.CreateParticle(team.TeamId, clothData.useVertexList.Count, // flag (i) => { bool isFix = clothData.IsFixedVertex(i) || clothData.IsExtendVertex(i); // 固定もしくは拡張 uint flag = 0; if (funcUserFlag != null) { flag = funcUserFlag(i); // ユーザーフラグ } if (isFix) { flag |= (PhysicsManagerParticleData.Flag_Kinematic | PhysicsManagerParticleData.Flag_Step_Update); } flag |= (param.UseCollision && !isFix) ? PhysicsManagerParticleData.Flag_Collision : 0; flag |= PhysicsManagerParticleData.Flag_Reset_Position; return(flag); }, // wpos null, // wrot null, // depth (i) => { return(clothData.vertexDepthList[i]); }, // radius (i) => { float depth = clothData.vertexDepthList[i]; return(param.GetRadius(depth)); }, // target local pos null ); manager.Team.SetParticleChunk(team.TeamId, c); // 原点スプリング拘束 if (param.UseSpring) { // 拘束データ int group = compute.Spring.AddGroup( team.TeamId, param.UseSpring, param.GetSpringPower() ); var teamData = manager.Team.teamDataList[team.TeamId]; teamData.springGroupIndex = group; manager.Team.teamDataList[team.TeamId] = teamData; } // 原点移動制限 if (param.UseClampPositionLength) { // 拘束データ int group = compute.ClampPosition.AddGroup( team.TeamId, param.UseClampPositionLength, param.GetClampPositionLength(), param.ClampPositionAxisRatio, param.ClampPositionVelocityInfluence ); var teamData = manager.Team.teamDataList[team.TeamId]; teamData.clampPositionGroupIndex = group; manager.Team.teamDataList[team.TeamId] = teamData; } // ルートからの最大最小距離拘束 if (param.UseClampDistanceRatio && clothData.ClampDistanceConstraintCount > 0) { // 拘束データ int group = compute.ClampDistance.AddGroup( team.TeamId, param.UseClampDistanceRatio, param.ClampDistanceMinRatio, param.ClampDistanceMaxRatio, param.ClampDistanceVelocityInfluence, clothData.rootDistanceDataList, clothData.rootDistanceReferenceList ); var teamData = manager.Team.teamDataList[team.TeamId]; teamData.clampDistanceGroupIndex = group; manager.Team.teamDataList[team.TeamId] = teamData; } // 距離復元拘束 if (clothData.StructDistanceConstraintCount > 0 || clothData.BendDistanceConstraintCount > 0 || clothData.NearDistanceConstraintCount > 0) { // 拘束データ int group = compute.RestoreDistance.AddGroup( team.TeamId, param.GetMass(), param.RestoreDistanceVelocityInfluence, param.GetStructDistanceStiffness(), clothData.structDistanceDataList, clothData.structDistanceReferenceList, param.UseBendDistance, param.GetBendDistanceStiffness(), clothData.bendDistanceDataList, clothData.bendDistanceReferenceList, param.UseNearDistance, param.GetNearDistanceStiffness(), clothData.nearDistanceDataList, clothData.nearDistanceReferenceList ); var teamData = manager.Team.teamDataList[team.TeamId]; teamData.restoreDistanceGroupIndex = group; manager.Team.teamDataList[team.TeamId] = teamData; } // 回転復元拘束 if (param.UseRestoreRotation && clothData.RestoreRotationConstraintCount > 0) { // 拘束データ int group = compute.RestoreRotation.AddGroup( team.TeamId, param.UseRestoreRotation, param.GetRotationPower(), param.RestoreRotationVelocityInfluence, clothData.restoreRotationDataList, clothData.restoreRotationReferenceList ); var teamData = manager.Team.teamDataList[team.TeamId]; teamData.restoreRotationGroupIndex = group; manager.Team.teamDataList[team.TeamId] = teamData; } // 最大回転復元拘束 if (param.UseClampRotation && clothData.ClampRotationConstraintDataCount > 0) { // 拘束データ int group = compute.ClampRotation.AddGroup( team.TeamId, param.UseClampRotation, param.GetClampRotationAngle(), param.ClampRotationVelocityInfluence, clothData.clampRotationDataList, clothData.clampRotationRootInfoList ); var teamData = manager.Team.teamDataList[team.TeamId]; teamData.clampRotationGroupIndex = group; manager.Team.teamDataList[team.TeamId] = teamData; } // トライアングルベンド拘束 if (param.UseTriangleBend && clothData.TriangleBendConstraintCount > 0) { int group = compute.TriangleBend.AddGroup( team.TeamId, param.UseTriangleBend, param.GetTriangleBendStiffness(), clothData.triangleBendDataList, clothData.triangleBendReferenceList, clothData.triangleBendWriteBufferCount ); var teamData = manager.Team.teamDataList[team.TeamId]; teamData.triangleBendGroupIndex = group; manager.Team.teamDataList[team.TeamId] = teamData; } // コライダーコリジョン if (param.UseCollision) { var teamData = manager.Team.teamDataList[team.TeamId]; // 形状維持フラグ teamData.SetFlag(PhysicsManagerTeamData.Flag_Collision_KeepShape, param.KeepInitialShape); // エッジコリジョン拘束 //if (param.UseEdgeCollision && clothData.EdgeCollisionConstraintCount > 0) //{ // int group = compute.EdgeCollision.AddGroup( // team.TeamId, // param.UseEdgeCollision, // clothData.edgeCollisionDataList, // clothData.edgeCollisionReferenceList, // clothData.edgeCollisionWriteBufferCount // ); // teamData.edgeCollisionGroupIndex = group; //} manager.Team.teamDataList[team.TeamId] = teamData; } #if false // ボリューム拘束 if (param.UseVolume && clothData.VolumeConstraintCount > 0) { //var sw = new StopWatch().Start(); int group = compute.Volume.AddGroup( team.TeamId, param.UseVolume, param.GetVolumeStretchStiffness(), param.GetVolumeShearStiffness(), clothData.volumeDataList, clothData.volumeReferenceList, clothData.volumeWriteBufferCount ); var teamData = manager.Team.teamDataList[team.TeamId]; teamData.volumeGroupIndex = group; manager.Team.teamDataList[team.TeamId] = teamData; //sw.Stop(); //Debug.Log("Volume.AddGroup():" + sw.ElapsedMilliseconds); } #endif // 回転調整(これはワーカー) if (param.UseAdjustRotation && param.AdjustRotationMode != ClothParams.AdjustMode.None) { // 拘束データ int group = compute.AdjustRotationWorker.AddGroup( team.TeamId, param.UseAdjustRotation, (int)param.AdjustRotationMode, param.AdjustRotationVector, clothData.adjustRotationDataList ); var teamData = manager.Team.teamDataList[team.TeamId]; teamData.adjustRotationGroupIndex = group; manager.Team.teamDataList[team.TeamId] = teamData; } // 回転補間(ワーカー) if (clothData.lineRotationDataList != null && clothData.lineRotationDataList.Length > 0) { // 拘束データ int group = compute.LineWorker.AddGroup( team.TeamId, param.UseLineAvarageRotation, clothData.lineRotationDataList, clothData.lineRotationRootInfoList ); var teamData = manager.Team.teamDataList[team.TeamId]; teamData.lineWorkerGroupIndex = group; manager.Team.teamDataList[team.TeamId] = teamData; } // 回転補間 manager.Team.SetFlag(team.TeamId, PhysicsManagerTeamData.Flag_FixedNonRotation, param.UseFixedNonRotation); }
//========================================================================================= /// <summary> /// ランタイム状態での頂点表示 /// </summary> /// <param name="scr"></param> /// <param name="deformer"></param> /// <param name="clothData"></param> static void DrawVertexRuntime( PhysicsTeam team, ClothData clothData, ClothParams param, ClothSetup setup, List <int> selList ) { bool drawVertex = ClothMonitorMenu.Monitor.UI.DrawClothVertex; bool drawRadius = ClothMonitorMenu.Monitor.UI.DrawClothRadius; bool drawDepth = ClothMonitorMenu.Monitor.UI.DrawClothDepth; bool drawBase = ClothMonitorMenu.Monitor.UI.DrawClothBase; bool drawAxis = ClothMonitorMenu.Monitor.UI.DrawClothAxis; #if MAGICACLOTH_DEBUG bool number = ClothMonitorMenu.Monitor.UI.DrawClothVertexNumber; bool drawIndex = ClothMonitorMenu.Monitor.UI.DrawClothVertexIndex; bool drawFriction = ClothMonitorMenu.Monitor.UI.DrawClothFriction; bool drawDepthNumber = ClothMonitorMenu.Monitor.UI.DrawClothDepthNumber; #else bool number = false; bool drawIndex = false; bool drawFriction = false; bool drawDepthNumber = false; #endif if (!number && !drawVertex && !drawDepth && !drawBase && !drawAxis && !drawIndex && !drawFriction && !drawDepthNumber) { return; } // チームスケール var teamTransform = team.InfluenceTarget ? team.InfluenceTarget : team.transform; float teamScale = clothData.initScale.magnitude > 0.0f ? teamTransform.lossyScale.magnitude / clothData.initScale.magnitude : 1.0f; int vcnt = clothData.useVertexList.Count; for (int i = 0; i < vcnt; i++) { int vindex = clothData.useVertexList[i]; int pindex = team.ParticleChunk.startIndex + i; Vector3 pos = MagicaPhysicsManager.Instance.Particle.posList[pindex]; float depth = MagicaPhysicsManager.Instance.Particle.depthList[pindex]; //float radius = PhysicsManager.Instance.Particle.radiusList[pindex]; float radius = drawRadius ? MagicaPhysicsManager.Instance.Particle.radiusList[pindex].x * teamScale : 0.001f; //float radius = param.GetRadius(depth); if (drawVertex || drawDepth || drawAxis) { Quaternion rot = MagicaPhysicsManager.Instance.Particle.rotList[pindex]; Gizmos.color = GetVertexColor(vindex, depth, selList); GizmoUtility.DrawWireSphere(pos, rot, Vector3.one, radius, drawVertex || drawDepth, drawAxis); } if (drawBase) { Vector3 bpos = MagicaPhysicsManager.Instance.Particle.basePosList[pindex]; Quaternion brot = MagicaPhysicsManager.Instance.Particle.baseRotList[pindex]; Gizmos.color = GizmoUtility.ColorBasePosition; GizmoUtility.DrawWireSphere(bpos, brot, Vector3.one, radius, true, false); } if (number) { Handles.Label(pos, i.ToString()); } if (drawIndex) { Handles.Label(pos, pindex.ToString()); } if (drawFriction) { float friction = MagicaPhysicsManager.Instance.Particle.frictionList[pindex]; Handles.Label(pos, string.Format("{0:#.##}", friction)); } //if (drawDepthNumber) if (drawDepth) { float d = MagicaPhysicsManager.Instance.Particle.depthList[pindex]; Handles.Label(pos, string.Format("{0:#.##}", d)); } } }
//========================================================================================= #if false /// <summary> /// エディタ状態でのベーススキニング表示 /// </summary> /// <param name="team"></param> /// <param name="clothData"></param> /// <param name="posList"></param> /// <param name="selList"></param> static void DrawBaseSkinningClothData( PhysicsTeam team, ClothData clothData, List <Vector3> posList, List <int> selList ) { if (ClothMonitorMenu.Monitor.UI.DrawClothBaseSkinning == false) { return; } if (clothData.baseSkinningDataList == null) { return; } //var boneList = team.TeamData.SkinningBoneList; var boneList = team.TeamData.ColliderList; //Gizmos.color = GizmoUtility.ColorPenetration; for (int i = 0; i < clothData.VertexUseCount; i++) { int vindex = clothData.useVertexList[i]; if (vindex >= posList.Count) { continue; } if (IsMove(vindex, selList) == false) { continue; } Vector3 pos = posList[vindex]; for (int j = 0; j < Define.Compute.BaseSkinningWeightCount; j++) { int dindex = i * Define.Compute.BaseSkinningWeightCount + j; if (dindex >= clothData.baseSkinningDataList.Length) { return; } var data = clothData.baseSkinningDataList[dindex]; if (data.IsValid() == false) { continue; } int bindex = data.boneIndex; if (bindex >= boneList.Count) { continue; } var bone = boneList[bindex]; if (bone == null) { continue; } //Gizmos.color = j == 0 ? Color.red : Color.yellow; Gizmos.color = Color.gray; #if true Vector3 p, dir, d; bone.CalcNearPoint(pos, out p, out dir, out d, true); Gizmos.DrawLine(pos, p); #else //var cp = bone.TransformPoint(data.localPos); Vector3 cp; MeshUtility.ClosestPtBoneLine(pos, bone, 0.03f, out cp); Gizmos.DrawLine(pos, cp); #endif } } }
//========================================================================================= /// <summary> /// ランタイム状態での浸透制限表示 /// </summary> /// <param name="team"></param> /// <param name="clothData"></param> /// <param name="selList"></param> static void DrawPenetrationRuntime( PhysicsTeam team, ClothParams param, ClothData clothData, List <int> selList ) { #if !MAGICACLOTH_DEBUG if (ClothMonitorMenu.Monitor.UI.DrawClothPenetration == false) { return; } #else if (ClothMonitorMenu.Monitor.UI.DrawClothPenetration == false && ClothMonitorMenu.Monitor.UI.DrawPenetrationOrigin == false) { return; } #endif if (clothData.penetrationDataList == null) { return; } if (clothData.penetrationReferenceList == null) { return; } //var mode = param.GetPenetrationMode(); var mode = clothData.penetrationMode; var colliderlist = team.TeamData.ColliderList; int vcnt = clothData.useVertexList.Count; for (int i = 0; i < vcnt; i++) { int vindex = clothData.useVertexList[i]; if (IsMove(vindex, selList) == false) { continue; } int pindex = team.ParticleChunk.startIndex + i; Vector3 pos = MagicaPhysicsManager.Instance.Particle.posList[pindex]; if (i >= clothData.penetrationReferenceList.Length) { return; } #if MAGICACLOTH_DEBUG Vector3 cen = Vector3.zero; Vector3 cdir = Vector3.zero; int ccnt = 0; GUIStyle style = new GUIStyle(); style.normal.textColor = Color.cyan; #endif var refdata = clothData.penetrationReferenceList[i]; for (int j = 0; j < refdata.count; j++) { var dindex = refdata.startIndex + j; var data = clothData.penetrationDataList[dindex]; if (data.IsValid() == false) { continue; } if (mode == ClothParams.PenetrationMode.SurfacePenetration) { } else if (mode == ClothParams.PenetrationMode.ColliderPenetration) { int cindex = data.colliderIndex; if (cindex >= colliderlist.Count) { continue; } var col = colliderlist[cindex]; if (col == null) { continue; } var cp = col.transform.TransformPoint(data.localPos); #if MAGICACLOTH_DEBUG var dir = col.transform.TransformDirection(data.localDir); var c = cp + dir * data.distance; cen += c; cdir += dir; ccnt++; #endif if (ClothMonitorMenu.Monitor.UI.DrawClothPenetration) { Gizmos.color = GizmoUtility.ColorPenetration; Gizmos.DrawLine(pos, cp); } } } #if MAGICACLOTH_DEBUG if (ClothMonitorMenu.Monitor.UI.DrawPenetrationOrigin && ccnt > 0) { cen /= ccnt; cdir /= ccnt; Gizmos.color = new Color(0.0f, 1.0f, 1.0f); Gizmos.DrawSphere(cen, 0.002f); Gizmos.color = Color.yellow; Gizmos.DrawLine(cen, cen + cdir.normalized * 0.02f); //Handles.color = Color.cyan; Handles.Label(cen, i.ToString(), style); } #endif } }
/// <summary> /// エディタ状態での浸透制限表示 /// </summary> /// <param name="team"></param> /// <param name="clothData"></param> /// <param name="posList"></param> /// <param name="selList"></param> static void DrawPenetrationClothData( PhysicsTeam team, ClothParams param, ClothData clothData, List <Vector3> posList, List <Vector3> norList, List <Vector3> tanList, List <int> selList ) { if (ClothMonitorMenu.Monitor.UI.DrawClothPenetration == false) { return; } if (clothData.penetrationDataList == null) { return; } if (clothData.penetrationReferenceList == null) { return; } var colliderlist = team.TeamData.ColliderList; //var mode = param.GetPenetrationMode(); var mode = clothData.penetrationMode; for (int i = 0; i < clothData.VertexUseCount; i++) { int vindex = clothData.useVertexList[i]; if (vindex >= posList.Count) { continue; } if (IsMove(vindex, selList) == false) { continue; } //Vector3 pos = posList[vindex]; if (i >= clothData.penetrationReferenceList.Length) { return; } var refdata = clothData.penetrationReferenceList[i]; for (int j = 0; j < refdata.count; j++) { var dindex = refdata.startIndex + j; var data = clothData.penetrationDataList[dindex]; if (data.IsValid() == false) { continue; } if (mode == ClothParams.PenetrationMode.SurfacePenetration) { var pos = posList[vindex]; var rot = Quaternion.LookRotation(norList[vindex], tanList[vindex]); var dir = rot * data.localDir; var depth = clothData.vertexDepthList[i]; var dist = param.GetPenetrationDistance().Evaluate(depth); Gizmos.color = GizmoUtility.ColorPenetration; Gizmos.DrawLine(pos, pos + dir * dist); break; } else if (mode == ClothParams.PenetrationMode.ColliderPenetration) { int cindex = data.colliderIndex; if (cindex >= colliderlist.Count) { continue; } var col = colliderlist[cindex]; if (col == null) { continue; } var cp = col.transform.TransformPoint(data.localPos); var pos = cp + col.transform.TransformDirection(data.localDir) * data.distance; Gizmos.color = GizmoUtility.ColorPenetration; Gizmos.DrawLine(pos, cp); } } } }