From bcc74f04654f99137bf73054b7c2206e0b9e3366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=8F=B7=E6=95=AC?= <153802103@qq.com> Date: Wed, 18 Dec 2024 02:18:45 +0800 Subject: [PATCH] add --- xiaofang/Assets/Obi.meta | 9 + xiaofang/Assets/Obi/CHANGELOG_rope.txt | 525 + xiaofang/Assets/Obi/CHANGELOG_rope.txt.meta | 9 + xiaofang/Assets/Obi/Editor.meta | 9 + xiaofang/Assets/Obi/Editor/Common.meta | 8 + .../Assets/Obi/Editor/Common/Blueprints.meta | 8 + .../Blueprints/BlueprintEditorTools.meta | 8 + .../ObiBlueprintEditorTool.cs | 40 + .../ObiBlueprintEditorTool.cs.meta | 11 + .../ObiPaintBrushEditorTool.cs | 130 + .../ObiPaintBrushEditorTool.cs.meta | 11 + .../ObiParticleSelectionEditorTool.cs | 336 + .../ObiParticleSelectionEditorTool.cs.meta | 11 + .../ObiPropertyTextureEditorTool.cs | 166 + .../ObiPropertyTextureEditorTool.cs.meta | 11 + .../BlueprintEditorTools/ObiTethersTool.cs | 86 + .../ObiTethersTool.cs.meta | 11 + .../Obi/Editor/Common/Blueprints/Brushes.meta | 8 + .../Common/Blueprints/Brushes/BrushModes.meta | 8 + .../Brushes/BrushModes/IObiBrushMode.cs | 9 + .../Brushes/BrushModes/IObiBrushMode.cs.meta | 11 + .../BrushModes/ObiColorPaintBrushMode.cs | 38 + .../BrushModes/ObiColorPaintBrushMode.cs.meta | 11 + .../BrushModes/ObiColorSmoothBrushMode.cs | 53 + .../ObiColorSmoothBrushMode.cs.meta | 11 + .../BrushModes/ObiFloatAddBrushMode.cs | 36 + .../BrushModes/ObiFloatAddBrushMode.cs.meta | 11 + .../BrushModes/ObiFloatCopyBrushMode.cs | 42 + .../BrushModes/ObiFloatCopyBrushMode.cs.meta | 11 + .../BrushModes/ObiFloatPaintBrushMode.cs | 37 + .../BrushModes/ObiFloatPaintBrushMode.cs.meta | 11 + .../BrushModes/ObiFloatSmoothBrushMode.cs | 55 + .../ObiFloatSmoothBrushMode.cs.meta | 11 + .../BrushModes/ObiIntPaintBrushMode.cs | 33 + .../BrushModes/ObiIntPaintBrushMode.cs.meta | 11 + .../ObiMasterSlavePaintBrushMode.cs | 39 + .../ObiMasterSlavePaintBrushMode.cs.meta | 11 + .../Brushes/BrushModes/ObiSelectBrushMode.cs | 33 + .../BrushModes/ObiSelectBrushMode.cs.meta | 11 + .../Common/Blueprints/Brushes/ObiBrushBase.cs | 161 + .../Blueprints/Brushes/ObiBrushBase.cs.meta | 11 + .../Brushes/ObiBrushMirrorSettings.cs | 51 + .../Brushes/ObiBrushMirrorSettings.cs.meta | 11 + .../Blueprints/Brushes/ObiRaycastBrush.cs | 125 + .../Brushes/ObiRaycastBrush.cs.meta | 11 + .../Blueprints/Brushes/ObiScreenSpaceBrush.cs | 61 + .../Brushes/ObiScreenSpaceBrush.cs.meta | 11 + .../Blueprints/ObiActorBlueprintEditor.cs | 477 + .../ObiActorBlueprintEditor.cs.meta | 11 + .../ObiActorBlueprintEditorStage.cs | 72 + .../ObiActorBlueprintEditorStage.cs.meta | 11 + .../ObiMeshBasedActorBlueprintEditor.cs | 275 + .../ObiMeshBasedActorBlueprintEditor.cs.meta | 11 + .../Editor/Common/Blueprints/ObiMeshUtils.cs | 93 + .../Common/Blueprints/ObiMeshUtils.cs.meta | 11 + .../Blueprints/ObiParticleEditorDrawing.cs | 127 + .../ObiParticleEditorDrawing.cs.meta | 11 + .../Editor/Common/Blueprints/Properties.meta | 8 + .../Blueprints/Properties/BaseTypes.meta | 8 + .../BaseTypes/ObiBlueprintBoolProperty.cs | 24 + .../ObiBlueprintBoolProperty.cs.meta | 11 + .../BaseTypes/ObiBlueprintColorProperty.cs | 31 + .../ObiBlueprintColorProperty.cs.meta | 11 + .../BaseTypes/ObiBlueprintFloatProperty.cs | 94 + .../ObiBlueprintFloatProperty.cs.meta | 11 + .../BaseTypes/ObiBlueprintIntProperty.cs | 41 + .../BaseTypes/ObiBlueprintIntProperty.cs.meta | 11 + .../BaseTypes/ObiBlueprintMaskProperty.cs | 28 + .../ObiBlueprintMaskProperty.cs.meta | 11 + .../BaseTypes/ObiBlueprintProperty.cs | 79 + .../BaseTypes/ObiBlueprintProperty.cs.meta | 11 + .../IObiPropertyEditableProvider.cs | 13 + .../IObiPropertyEditableProvider.cs.meta | 11 + .../Properties/ObiBlueprintColor.cs | 33 + .../Properties/ObiBlueprintColor.cs.meta | 11 + .../Properties/ObiBlueprintFilterCategory.cs | 32 + .../ObiBlueprintFilterCategory.cs.meta | 11 + .../Properties/ObiBlueprintFilterMask.cs | 32 + .../Properties/ObiBlueprintFilterMask.cs.meta | 11 + .../Blueprints/Properties/ObiBlueprintMass.cs | 33 + .../Properties/ObiBlueprintMass.cs.meta | 11 + .../Properties/ObiBlueprintRadius.cs | 37 + .../Properties/ObiBlueprintRadius.cs.meta | 11 + .../Properties/ObiBlueprintSelected.cs | 29 + .../Properties/ObiBlueprintSelected.cs.meta | 11 + .../Editor/Common/Blueprints/RenderModes.meta | 8 + .../RenderModes/ObiBlueprintRenderMode.cs | 25 + .../ObiBlueprintRenderMode.cs.meta | 11 + ...ueprintRenderModeAerodynamicConstraints.cs | 63 + ...ntRenderModeAerodynamicConstraints.cs.meta | 11 + .../ObiBlueprintRenderModeBendConstraints.cs | 44 + ...BlueprintRenderModeBendConstraints.cs.meta | 11 + ...iBlueprintRenderModeDistanceConstraints.cs | 44 + ...printRenderModeDistanceConstraints.cs.meta | 11 + .../RenderModes/ObiBlueprintRenderModeMesh.cs | 46 + .../ObiBlueprintRenderModeMesh.cs.meta | 11 + .../ObiBlueprintRenderModeParticles.cs | 65 + .../ObiBlueprintRenderModeParticles.cs.meta | 11 + ...printRenderModeShapeMatchingConstraints.cs | 54 + ...RenderModeShapeMatchingConstraints.cs.meta | 11 + ...ObiBlueprintRenderModeTetherConstraints.cs | 43 + ...ueprintRenderModeTetherConstraints.cs.meta | 11 + .../Assets/Obi/Editor/Common/Collisions.meta | 8 + .../Common/Collisions/ObiColliderEditor.cs | 104 + .../Collisions/ObiColliderEditor.cs.meta | 12 + .../Collisions/ObiDistanceFieldEditor.cs | 178 + .../Collisions/ObiDistanceFieldEditor.cs.meta | 12 + .../Common/Collisions/ObiForceZoneEditor.cs | 30 + .../Collisions/ObiForceZoneEditor.cs.meta | 11 + .../Assets/Obi/Editor/Common/Constraints.meta | 8 + .../ObiConstraintParametersDrawer.cs | 73 + .../ObiConstraintParametersDrawer.cs.meta | 12 + .../Obi/Editor/Common/ObiAboutWindow.cs | 73 + .../Obi/Editor/Common/ObiAboutWindow.cs.meta | 12 + .../Obi/Editor/Common/ObiSettingsProvider.cs | 81 + .../Editor/Common/ObiSettingsProvider.cs.meta | 11 + .../Assets/Obi/Editor/Common/Rendering.meta | 8 + .../Rendering/ObiParticleRendererEditor.cs | 32 + .../ObiParticleRendererEditor.cs.meta | 12 + xiaofang/Assets/Obi/Editor/Common/Solver.meta | 8 + .../Editor/Common/Solver/ObiSolverEditor.cs | 344 + .../Common/Solver/ObiSolverEditor.cs.meta | 12 + xiaofang/Assets/Obi/Editor/Common/Utils.meta | 8 + .../Editor/Common/Utils/BooleanPreference.cs | 46 + .../Common/Utils/BooleanPreference.cs.meta | 11 + .../Obi/Editor/Common/Utils/ObiEditorUtils.cs | 254 + .../Common/Utils/ObiEditorUtils.cs.meta | 12 + .../Common/Utils/ObiFoamGeneratorEditor.cs | 24 + .../Utils/ObiFoamGeneratorEditor.cs.meta | 11 + .../Utils/ObiParticleAttachmentEditor.cs | 121 + .../Utils/ObiParticleAttachmentEditor.cs.meta | 11 + .../Obi/Editor/Common/Utils/ObiRaycastHit.cs | 26 + .../Editor/Common/Utils/ObiRaycastHit.cs.meta | 11 + .../Obi/Editor/Common/Utils/PreviewHelpers.cs | 150 + .../Common/Utils/PreviewHelpers.cs.meta | 12 + xiaofang/Assets/Obi/Editor/Obi.Editor.asmdef | 33 + .../Assets/Obi/Editor/Obi.Editor.asmdef.meta | 7 + .../Assets/Obi/Editor/ObiParticleSelection.cs | 186 + .../Obi/Editor/ObiParticleSelection.cs.meta | 11 + .../Assets/Obi/Editor/ObiStitcherEditor.cs | 287 + .../Obi/Editor/ObiStitcherEditor.cs.meta | 12 + xiaofang/Assets/Obi/Editor/Resources.meta | 9 + .../Obi/Editor/Resources/AddControlPoint.psd | Bin 0 -> 36186 bytes .../Editor/Resources/AddControlPoint.psd.meta | 59 + .../Assets/Obi/Editor/Resources/AddIcon.psd | Bin 0 -> 30742 bytes .../Obi/Editor/Resources/AddIcon.psd.meta | 55 + .../Obi/Editor/Resources/AddTetherButton.psd | Bin 0 -> 29202 bytes .../Editor/Resources/AddTetherButton.psd.meta | 59 + .../Obi/Editor/Resources/BackfacesButton.psd | Bin 0 -> 32976 bytes .../Editor/Resources/BackfacesButton.psd.meta | 59 + .../Obi/Editor/Resources/BranchButton.png | Bin 0 -> 4936 bytes .../Editor/Resources/BranchButton.png.meta | 117 + .../Obi/Editor/Resources/BrushHandle.psd | Bin 0 -> 95778 bytes .../Obi/Editor/Resources/BrushHandle.psd.meta | 55 + .../Assets/Obi/Editor/Resources/BrushIcon.psd | Bin 0 -> 30792 bytes .../Obi/Editor/Resources/BrushIcon.psd.meta | 55 + .../Obi/Editor/Resources/ClearButton.psd | Bin 0 -> 28652 bytes .../Obi/Editor/Resources/ClearButton.psd.meta | 59 + .../Editor/Resources/ClearTethersButton.psd | Bin 0 -> 31210 bytes .../Resources/ClearTethersButton.psd.meta | 59 + .../Editor/Resources/DistanceFieldPreview.mat | 87 + .../Resources/DistanceFieldPreview.mat.meta | 8 + .../Resources/DistanceFieldPreview.shader | 121 + .../DistanceFieldPreview.shader.meta | 9 + .../Obi/Editor/Resources/EditCurves.psd | Bin 0 -> 36662 bytes .../Obi/Editor/Resources/EditCurves.psd.meta | 116 + .../Obi/Editor/Resources/EditParticles.psd | Bin 0 -> 28553 bytes .../Editor/Resources/EditParticles.psd.meta | 57 + .../Editor/Resources/EditorLineShader.shader | 17 + .../Resources/EditorLineShader.shader.meta | 9 + .../Obi/Editor/Resources/EditorLines.mat | 81 + .../Obi/Editor/Resources/EditorLines.mat.meta | 8 + .../Obi/Editor/Resources/EditorParticle.mat | 76 + .../Editor/Resources/EditorParticle.mat.meta | 8 + .../Editor/Resources/EditorParticle.shader | 60 + .../Resources/EditorParticle.shader.meta | 9 + .../Resources/EditorParticleShader.shader | 118 + .../EditorParticleShader.shader.meta | 9 + .../Obi/Editor/Resources/FillButton.psd | Bin 0 -> 32399 bytes .../Obi/Editor/Resources/FillButton.psd.meta | 59 + .../Obi/Editor/Resources/FrontfacesButton.psd | Bin 0 -> 31893 bytes .../Resources/FrontfacesButton.psd.meta | 95 + .../Obi/Editor/Resources/GaussianButton.psd | Bin 0 -> 30004 bytes .../Editor/Resources/GaussianButton.psd.meta | 55 + .../Obi/Editor/Resources/HandleButton.psd | Bin 0 -> 33182 bytes .../Editor/Resources/HandleButton.psd.meta | 59 + .../Assets/Obi/Editor/Resources/Icons.meta | 9 + .../Icons/ObiActorBlueprint Icon.png | Bin 0 -> 4918 bytes .../Icons/ObiActorBlueprint Icon.png.meta | 117 + .../Icons/ObiAerodynamicConstraints Icon.png | Bin 0 -> 3973 bytes .../ObiAerodynamicConstraints Icon.png.meta | 92 + .../Icons/ObiBendConstraints Icon.png | Bin 0 -> 4561 bytes .../Icons/ObiBendConstraints Icon.png.meta | 92 + .../Icons/ObiBendTwistConstraints Icon.png | Bin 0 -> 4670 bytes .../ObiBendTwistConstraints Icon.png.meta | 95 + .../Editor/Resources/Icons/ObiBone Icon.png | Bin 0 -> 4151 bytes .../Resources/Icons/ObiBone Icon.png.meta | 140 + .../Icons/ObiChainConstraints Icon.png | Bin 0 -> 4135 bytes .../Icons/ObiChainConstraints Icon.png.meta | 95 + .../Editor/Resources/Icons/ObiCloth Icon.png | Bin 0 -> 3713 bytes .../Resources/Icons/ObiCloth Icon.png.meta | 92 + .../Resources/Icons/ObiClothRenderer Icon.png | Bin 0 -> 5229 bytes .../Icons/ObiClothRenderer Icon.png.meta | 103 + .../Resources/Icons/ObiCollider Icon.png | Bin 0 -> 4533 bytes .../Resources/Icons/ObiCollider Icon.png.meta | 92 + .../Resources/Icons/ObiCollider2D Icon.png | Bin 0 -> 3043 bytes .../Icons/ObiCollider2D Icon.png.meta | 92 + .../Icons/ObiCollisionMaterial Icon.png | Bin 0 -> 5904 bytes .../Icons/ObiCollisionMaterial Icon.png.meta | 92 + .../Editor/Resources/Icons/ObiCurve Icon.png | Bin 0 -> 5351 bytes .../Resources/Icons/ObiCurve Icon.png.meta | 92 + .../Icons/ObiDistanceConstraints Icon.png | Bin 0 -> 4087 bytes .../ObiDistanceConstraints Icon.png.meta | 92 + .../Resources/Icons/ObiDistanceField Icon.png | Bin 0 -> 6301 bytes .../Icons/ObiDistanceField Icon.png.meta | 92 + .../Icons/ObiDistanceFieldRenderer Icon.png | Bin 0 -> 6596 bytes .../ObiDistanceFieldRenderer Icon.png.meta | 92 + .../Resources/Icons/ObiEmitter Icon.png | Bin 0 -> 8396 bytes .../Resources/Icons/ObiEmitter Icon.png.meta | 92 + .../Icons/ObiEmitterMaterialFluid Icon.png | Bin 0 -> 4440 bytes .../ObiEmitterMaterialFluid Icon.png.meta | 92 + .../Icons/ObiEmitterMaterialGranular Icon.png | Bin 0 -> 5931 bytes .../ObiEmitterMaterialGranular Icon.png.meta | 92 + .../Icons/ObiEmitterShapeCube Icon.png | Bin 0 -> 3467 bytes .../Icons/ObiEmitterShapeCube Icon.png.meta | 92 + .../Icons/ObiEmitterShapeDisk Icon.png | Bin 0 -> 5263 bytes .../Icons/ObiEmitterShapeDisk Icon.png.meta | 92 + .../Icons/ObiEmitterShapeEdge Icon.png | Bin 0 -> 3304 bytes .../Icons/ObiEmitterShapeEdge Icon.png.meta | 92 + .../Icons/ObiEmitterShapeMesh Icon.png | Bin 0 -> 4371 bytes .../Icons/ObiEmitterShapeMesh Icon.png.meta | 128 + .../Icons/ObiEmitterShapeSphere Icon.png | Bin 0 -> 7686 bytes .../Icons/ObiEmitterShapeSphere Icon.png.meta | 92 + .../Icons/ObiEmitterShapeSquare Icon.png | Bin 0 -> 3056 bytes .../Icons/ObiEmitterShapeSquare Icon.png.meta | 100 + .../Resources/Icons/ObiFluidRenderer Icon.png | Bin 0 -> 6460 bytes .../Icons/ObiFluidRenderer Icon.png.meta | 92 + .../Resources/Icons/ObiFoamGenerator Icon.png | Bin 0 -> 5404 bytes .../Icons/ObiFoamGenerator Icon.png.meta | 122 + .../Resources/Icons/ObiForceZone Icon.png | Bin 0 -> 5679 bytes .../Icons/ObiForceZone Icon.png.meta | 92 + .../Resources/Icons/ObiMeshTopology Icon.png | Bin 0 -> 6506 bytes .../Icons/ObiMeshTopology Icon.png.meta | 92 + .../Icons/ObiParticleHandle Icon.png | Bin 0 -> 5115 bytes .../Icons/ObiParticleHandle Icon.png.meta | 92 + .../Icons/ObiParticlePicker Icon.png | Bin 0 -> 4182 bytes .../Icons/ObiParticlePicker Icon.png.meta | 92 + .../Icons/ObiParticleRenderer Icon.png | Bin 0 -> 3943 bytes .../Icons/ObiParticleRenderer Icon.png.meta | 92 + .../Resources/Icons/ObiPathSmoother Icon.png | Bin 0 -> 5994 bytes .../Icons/ObiPathSmoother Icon.png.meta | 122 + .../Icons/ObiPinConstraints Icon.png | Bin 0 -> 3994 bytes .../Icons/ObiPinConstraints Icon.png.meta | 92 + .../Editor/Resources/Icons/ObiPlant Icon.png | Bin 0 -> 4124 bytes .../Resources/Icons/ObiPlant Icon.png.meta | 117 + .../Resources/Icons/ObiProfiler Icon.png | Bin 0 -> 3159 bytes .../Resources/Icons/ObiProfiler Icon.png.meta | 92 + .../Resources/Icons/ObiRigidbody Icon.png | Bin 0 -> 6044 bytes .../Icons/ObiRigidbody Icon.png.meta | 92 + .../Resources/Icons/ObiRigidbody2D Icon.png | Bin 0 -> 5340 bytes .../Icons/ObiRigidbody2D Icon.png.meta | 92 + .../Editor/Resources/Icons/ObiRod Icon.png | Bin 0 -> 3248 bytes .../Resources/Icons/ObiRod Icon.png.meta | 95 + .../Editor/Resources/Icons/ObiRope Icon.png | Bin 0 -> 4225 bytes .../Resources/Icons/ObiRope Icon.png.meta | 123 + .../Icons/ObiRopeChainRenderer Icon.png | Bin 0 -> 6023 bytes .../Icons/ObiRopeChainRenderer Icon.png.meta | 95 + .../Resources/Icons/ObiRopeCursor Icon.png | Bin 0 -> 3120 bytes .../Icons/ObiRopeCursor Icon.png.meta | 100 + .../Icons/ObiRopeExtrudedRenderer Icon.png | Bin 0 -> 5536 bytes .../ObiRopeExtrudedRenderer Icon.png.meta | 95 + .../Icons/ObiRopeLineRenderer Icon.png | Bin 0 -> 5682 bytes .../Icons/ObiRopeLineRenderer Icon.png.meta | 95 + .../Icons/ObiRopeMeshRenderer Icon.png | Bin 0 -> 3884 bytes .../Icons/ObiRopeMeshRenderer Icon.png.meta | 95 + .../Resources/Icons/ObiRopeSection Icon.png | Bin 0 -> 3980 bytes .../Icons/ObiRopeSection Icon.png.meta | 92 + .../ObiShapeMatchingConstraints Icon.png | Bin 0 -> 4677 bytes .../ObiShapeMatchingConstraints Icon.png.meta | 92 + .../Icons/ObiSkinConstraints Icon.png | Bin 0 -> 5754 bytes .../Icons/ObiSkinConstraints Icon.png.meta | 92 + .../Resources/Icons/ObiSkinnedCloth Icon.png | Bin 0 -> 4060 bytes .../Icons/ObiSkinnedCloth Icon.png.meta | 103 + .../Icons/ObiSkinnedClothRenderer Icon.png | Bin 0 -> 5830 bytes .../ObiSkinnedClothRenderer Icon.png.meta | 103 + .../Resources/Icons/ObiSoftbody Icon.png | Bin 0 -> 4696 bytes .../Resources/Icons/ObiSoftbody Icon.png.meta | 92 + .../Icons/ObiSoftbodySkinner Icon.png | Bin 0 -> 4719 bytes .../Icons/ObiSoftbodySkinner Icon.png.meta | 117 + .../Editor/Resources/Icons/ObiSolver Icon.png | Bin 0 -> 5347 bytes .../Resources/Icons/ObiSolver Icon.png.meta | 92 + .../Resources/Icons/ObiStitcher Icon.png | Bin 0 -> 4296 bytes .../Resources/Icons/ObiStitcher Icon.png.meta | 100 + .../Icons/ObiStretchShearConstraints Icon.png | Bin 0 -> 3999 bytes .../ObiStretchShearConstraints Icon.png.meta | 95 + .../Resources/Icons/ObiTearableCloth Icon.png | Bin 0 -> 4277 bytes .../Icons/ObiTearableCloth Icon.png.meta | 103 + .../Icons/ObiTearableClothRenderer Icon.png | Bin 0 -> 5744 bytes .../ObiTearableClothRenderer Icon.png.meta | 103 + .../Icons/ObiTetherConstraints Icon.png | Bin 0 -> 4763 bytes .../Icons/ObiTetherConstraints Icon.png.meta | 92 + .../Resources/Icons/ObiVoidZone Icon.png | Bin 0 -> 5518 bytes .../Resources/Icons/ObiVoidZone Icon.png.meta | 122 + .../Icons/ObiVolumeConstraints Icon.png | Bin 0 -> 5631 bytes .../Icons/ObiVolumeConstraints Icon.png.meta | 92 + .../Obi/Editor/Resources/InvertButton.psd | Bin 0 -> 28744 bytes .../Editor/Resources/InvertButton.psd.meta | 59 + .../Obi/Editor/Resources/LeafButton.png | Bin 0 -> 5109 bytes .../Obi/Editor/Resources/LeafButton.png.meta | 117 + .../Obi/Editor/Resources/MaskButton.psd | Bin 0 -> 31899 bytes .../Obi/Editor/Resources/MaskButton.psd.meta | 59 + .../Obi/Editor/Resources/OpenCloseCurve.psd | Bin 0 -> 28549 bytes .../Editor/Resources/OpenCloseCurve.psd.meta | 59 + .../Obi/Editor/Resources/OptimizeButton.psd | Bin 0 -> 30007 bytes .../Editor/Resources/OptimizeButton.psd.meta | 127 + .../Editor/Resources/OrientControlPoint.psd | Bin 0 -> 32589 bytes .../Resources/OrientControlPoint.psd.meta | 59 + .../Obi/Editor/Resources/PaddingMaterial.mat | 77 + .../Editor/Resources/PaddingMaterial.mat.meta | 8 + .../Obi/Editor/Resources/PaddingShader.shader | 81 + .../Resources/PaddingShader.shader.meta | 9 + .../Obi/Editor/Resources/PauseButton.psd | Bin 0 -> 33636 bytes .../Obi/Editor/Resources/PauseButton.psd.meta | 57 + .../Obi/Editor/Resources/PencilButton.psd | Bin 0 -> 29168 bytes .../Editor/Resources/PencilButton.psd.meta | 55 + .../Assets/Obi/Editor/Resources/PinButton.psd | Bin 0 -> 29243 bytes .../Obi/Editor/Resources/PinButton.psd.meta | 59 + .../Obi/Editor/Resources/PinTranslation.psd | Bin 0 -> 33039 bytes .../Editor/Resources/PinTranslation.psd.meta | 95 + .../Obi/Editor/Resources/PlayButton.psd | Bin 0 -> 30640 bytes .../Obi/Editor/Resources/PlayButton.psd.meta | 55 + .../Resources/PropertyGradientMaterial.mat | 76 + .../PropertyGradientMaterial.mat.meta | 8 + .../Resources/PropertyGradientMaterial.shader | 95 + .../PropertyGradientMaterial.shader.meta | 9 + .../Obi/Editor/Resources/RadiusIndicator.psd | Bin 0 -> 47051 bytes .../Editor/Resources/RadiusIndicator.psd.meta | 59 + .../Assets/Obi/Editor/Resources/RecButton.psd | Bin 0 -> 27590 bytes .../Obi/Editor/Resources/RecButton.psd.meta | 57 + .../Obi/Editor/Resources/RemoveButton.psd | Bin 0 -> 29664 bytes .../Editor/Resources/RemoveButton.psd.meta | 127 + .../Editor/Resources/RemoveControlPoint.psd | Bin 0 -> 32178 bytes .../Resources/RemoveControlPoint.psd.meta | 59 + .../Obi/Editor/Resources/RemoveIcon.psd | Bin 0 -> 26154 bytes .../Obi/Editor/Resources/RemoveIcon.psd.meta | 55 + .../Obi/Editor/Resources/RestoreButton.psd | Bin 0 -> 31300 bytes .../Editor/Resources/RestoreButton.psd.meta | 127 + .../Obi/Editor/Resources/RewindButton.psd | Bin 0 -> 30935 bytes .../Editor/Resources/RewindButton.psd.meta | 55 + .../Editor/Resources/RotateControlPoint.psd | Bin 0 -> 33801 bytes .../Resources/RotateControlPoint.psd.meta | 59 + .../Editor/Resources/ScaleControlPoint.psd | Bin 0 -> 41233 bytes .../Resources/ScaleControlPoint.psd.meta | 55 + .../Obi/Editor/Resources/SelectIcon.psd | Bin 0 -> 25951 bytes .../Obi/Editor/Resources/SelectIcon.psd.meta | 55 + .../Editor/Resources/SelectedWorld_bck.psd | Bin 0 -> 23396 bytes .../Resources/SelectedWorld_bck.psd.meta | 55 + .../Obi/Editor/Resources/SeparatorLine.psd | Bin 0 -> 25656 bytes .../Editor/Resources/SeparatorLine.psd.meta | 59 + .../Editor/Resources/ShowTangentHandles.psd | Bin 0 -> 31146 bytes .../Resources/ShowTangentHandles.psd.meta | 59 + .../Editor/Resources/ShowThicknessHandles.psd | Bin 0 -> 31848 bytes .../Resources/ShowThicknessHandles.psd.meta | 59 + .../Obi/Editor/Resources/SmoothButton.psd | Bin 0 -> 29579 bytes .../Editor/Resources/SmoothButton.psd.meta | 59 + .../Obi/Editor/Resources/StepButton.psd | Bin 0 -> 30792 bytes .../Obi/Editor/Resources/StepButton.psd.meta | 55 + .../Obi/Editor/Resources/StopButton.psd | Bin 0 -> 26662 bytes .../Obi/Editor/Resources/StopButton.psd.meta | 55 + .../Obi/Editor/Resources/StopRecButton.psd | Bin 0 -> 32128 bytes .../Editor/Resources/StopRecButton.psd.meta | 57 + .../Obi/Editor/Resources/TextureIcon.psd | Bin 0 -> 27170 bytes .../Obi/Editor/Resources/TextureIcon.psd.meta | 98 + .../Editor/Resources/ToggleableGroupBg.psd | Bin 0 -> 24638 bytes .../Resources/ToggleableGroupBg.psd.meta | 59 + .../Editor/Resources/TopologyBorders.shader | 54 + .../Resources/TopologyBorders.shader.meta | 9 + .../Obi/Editor/Resources/TopologyPreview.mat | 81 + .../Editor/Resources/TopologyPreview.mat.meta | 8 + .../Resources/TopologyPreviewBorder.mat | 76 + .../Resources/TopologyPreviewBorder.mat.meta | 8 + .../Resources/TranslateControlPoint.psd | Bin 0 -> 54590 bytes .../Resources/TranslateControlPoint.psd.meta | 116 + .../Obi/Editor/Resources/TrunkButton.png | Bin 0 -> 5688 bytes .../Obi/Editor/Resources/TrunkButton.png.meta | 117 + .../Obi/Editor/Resources/UVSpaceColor.shader | 47 + .../Editor/Resources/UVSpaceColor.shader.meta | 9 + .../Editor/Resources/UVSpaceColorMaterial.mat | 76 + .../Resources/UVSpaceColorMaterial.mat.meta | 8 + .../Obi/Editor/Resources/UnpinButton.psd | Bin 0 -> 31753 bytes .../Obi/Editor/Resources/UnpinButton.psd.meta | 59 + .../Obi/Editor/Resources/VoxelMaterial.mat | 79 + .../Editor/Resources/VoxelMaterial.mat.meta | 8 + .../Obi/Editor/Resources/VoxelMaterial.shader | 63 + .../Resources/VoxelMaterial.shader.meta | 9 + .../Obi/Editor/Resources/obi_editor_logo.png | Bin 0 -> 14374 bytes .../Editor/Resources/obi_editor_logo.png.meta | 59 + xiaofang/Assets/Obi/Editor/RopeAndRod.meta | 10 + .../Obi/Editor/RopeAndRod/Blueprints.meta | 8 + .../Blueprints/ObiRopeBaseBlueprintEditor.cs | 58 + .../ObiRopeBaseBlueprintEditor.cs.meta | 11 + .../RopeAndRod/BonePropertyCurveDrawer.cs | 29 + .../BonePropertyCurveDrawer.cs.meta | 11 + .../Editor/RopeAndRod/IgnoredBoneDrawer.cs | 30 + .../RopeAndRod/IgnoredBoneDrawer.cs.meta | 11 + .../Obi/Editor/RopeAndRod/ObiBoneEditor.cs | 225 + .../Editor/RopeAndRod/ObiBoneEditor.cs.meta | 11 + .../Obi/Editor/RopeAndRod/ObiDraggableIcon.cs | 73 + .../RopeAndRod/ObiDraggableIcon.cs.meta | 11 + .../Obi/Editor/RopeAndRod/ObiPathEditor.cs | 1241 + .../Editor/RopeAndRod/ObiPathEditor.cs.meta | 11 + .../Obi/Editor/RopeAndRod/ObiPathHandles.cs | 271 + .../Editor/RopeAndRod/ObiPathHandles.cs.meta | 11 + .../RopeAndRod/ObiPathSmootherEditor.cs | 37 + .../RopeAndRod/ObiPathSmootherEditor.cs.meta | 11 + .../Obi/Editor/RopeAndRod/ObiRodEditor.cs | 216 + .../Editor/RopeAndRod/ObiRodEditor.cs.meta | 11 + .../RopeAndRod/ObiRopeChainRendererEditor.cs | 54 + .../ObiRopeChainRendererEditor.cs.meta | 13 + .../Editor/RopeAndRod/ObiRopeCursorEditor.cs | 98 + .../RopeAndRod/ObiRopeCursorEditor.cs.meta | 11 + .../Obi/Editor/RopeAndRod/ObiRopeEditor.cs | 213 + .../Editor/RopeAndRod/ObiRopeEditor.cs.meta | 11 + .../ObiRopeExtrudedRendererEditor.cs | 55 + .../ObiRopeExtrudedRendererEditor.cs.meta | 13 + .../RopeAndRod/ObiRopeLineRendererEditor.cs | 38 + .../ObiRopeLineRendererEditor.cs.meta | 13 + .../RopeAndRod/ObiRopeMeshRendererEditor.cs | 52 + .../ObiRopeMeshRendererEditor.cs.meta | 13 + .../Editor/RopeAndRod/ObiRopeSectionEditor.cs | 213 + .../RopeAndRod/ObiRopeSectionEditor.cs.meta | 13 + xiaofang/Assets/Obi/QuickstartGuide_rope.pdf | Bin 0 -> 53087 bytes .../Assets/Obi/QuickstartGuide_rope.pdf.meta | 9 + xiaofang/Assets/Obi/README.rtf | 38 + xiaofang/Assets/Obi/README.rtf.meta | 8 + xiaofang/Assets/Obi/Resources.meta | 9 + xiaofang/Assets/Obi/Resources/Compute.meta | 8 + .../Compute/AerodynamicConstraints.compute | 61 + .../AerodynamicConstraints.compute.meta | 8 + .../Obi/Resources/Compute/AtomicDeltas.cginc | 75 + .../Resources/Compute/AtomicDeltas.cginc.meta | 9 + .../Resources/Compute/BendConstraints.compute | 83 + .../Compute/BendConstraints.compute.meta | 8 + .../Compute/BendTwistConstraints.compute | 78 + .../Compute/BendTwistConstraints.compute.meta | 8 + .../Obi/Resources/Compute/BitonicSort.compute | 39 + .../Compute/BitonicSort.compute.meta | 8 + .../Assets/Obi/Resources/Compute/Bounds.cginc | 127 + .../Obi/Resources/Compute/Bounds.cginc.meta | 9 + .../Resources/Compute/BoundsReduction.compute | 93 + .../Compute/BoundsReduction.compute.meta | 8 + .../Obi/Resources/Compute/BoxShape.compute | 125 + .../Resources/Compute/BoxShape.compute.meta | 8 + .../Resources/Compute/BoxShapeQuery.compute | 136 + .../Compute/BoxShapeQuery.compute.meta | 8 + .../Resources/Compute/CapsuleShape.compute | 122 + .../Compute/CapsuleShape.compute.meta | 8 + .../Compute/ChainConstraints.compute | 159 + .../Compute/ChainConstraints.compute.meta | 8 + .../Resources/Compute/ClothRendering.compute | 180 + .../Compute/ClothRendering.compute.meta | 8 + .../ColliderCollisionConstraints.compute | 219 + .../ColliderCollisionConstraints.compute.meta | 8 + .../Compute/ColliderDefinitions.cginc | 80 + .../Compute/ColliderDefinitions.cginc.meta | 9 + .../ColliderFrictionConstraints.compute | 192 + .../ColliderFrictionConstraints.compute.meta | 8 + .../Resources/Compute/ColliderGrid.compute | 473 + .../Compute/ColliderGrid.compute.meta | 8 + .../Resources/Compute/CollisionMaterial.cginc | 109 + .../Compute/CollisionMaterial.cginc.meta | 9 + .../Resources/Compute/ContactHandling.cginc | 228 + .../Compute/ContactHandling.cginc.meta | 9 + .../Compute/DeformableTriangles.compute | 139 + .../Compute/DeformableTriangles.compute.meta | 8 + .../Compute/DensityConstraints.compute | 326 + .../Compute/DensityConstraints.compute.meta | 8 + .../Compute/DistanceConstraints.compute | 69 + .../Compute/DistanceConstraints.compute.meta | 8 + .../Compute/DistanceFieldShape.compute | 212 + .../Compute/DistanceFieldShape.compute.meta | 8 + .../Resources/Compute/EdgeMeshShape.compute | 208 + .../Compute/EdgeMeshShape.compute.meta | 8 + .../Resources/Compute/FluidChunkDefs.cginc | 33 + .../Compute/FluidChunkDefs.cginc.meta | 9 + .../Obi/Resources/Compute/FluidFoam.compute | 432 + .../Resources/Compute/FluidFoam.compute.meta | 8 + .../Compute/FluidFoamDensity.compute | 172 + .../Compute/FluidFoamDensity.compute.meta | 8 + .../Obi/Resources/Compute/FluidKernels.cginc | 40 + .../Resources/Compute/FluidKernels.cginc.meta | 9 + .../Resources/Compute/FluidMeshChunks.compute | 205 + .../Compute/FluidMeshChunks.compute.meta | 8 + .../Compute/FluidSurfaceMeshBuilding.compute | 604 + .../FluidSurfaceMeshBuilding.compute.meta | 8 + .../Obi/Resources/Compute/GridUtils.cginc | 166 + .../Resources/Compute/GridUtils.cginc.meta | 9 + .../Compute/HeightfieldShape.compute | 230 + .../Compute/HeightfieldShape.compute.meta | 8 + .../Obi/Resources/Compute/InertialFrame.cginc | 18 + .../Compute/InertialFrame.cginc.meta | 9 + .../InstancedParticleRendering.compute | 44 + .../InstancedParticleRendering.compute.meta | 8 + .../Obi/Resources/Compute/Integration.cginc | 38 + .../Resources/Compute/Integration.cginc.meta | 9 + .../Resources/Compute/InterlockedUtils.cginc | 46 + .../Compute/InterlockedUtils.cginc.meta | 9 + .../Obi/Resources/Compute/MathUtils.cginc | 557 + .../Resources/Compute/MathUtils.cginc.meta | 9 + .../Assets/Obi/Resources/Compute/Matrix.cginc | 108 + .../Obi/Resources/Compute/Matrix.cginc.meta | 9 + .../Resources/Compute/NormalCompression.cginc | 32 + .../Compute/NormalCompression.cginc.meta | 9 + .../Obi/Resources/Compute/Optimization.cginc | 126 + .../Resources/Compute/Optimization.cginc.meta | 9 + .../ParticleCollisionConstraints.compute | 189 + .../ParticleCollisionConstraints.compute.meta | 8 + .../ParticleFrictionConstraints.compute | 187 + .../ParticleFrictionConstraints.compute.meta | 8 + .../Resources/Compute/ParticleGrid.compute | 600 + .../Compute/ParticleGrid.compute.meta | 8 + .../Compute/ParticleMeshBuilding.compute | 72 + .../Compute/ParticleMeshBuilding.compute.meta | 8 + .../Obi/Resources/Compute/PathFrame.cginc | 158 + .../Resources/Compute/PathFrame.cginc.meta | 9 + .../Resources/Compute/PathSmoothing.compute | 235 + .../Compute/PathSmoothing.compute.meta | 8 + .../Assets/Obi/Resources/Compute/Phases.cginc | 13 + .../Obi/Resources/Compute/Phases.cginc.meta | 9 + .../Resources/Compute/PinConstraints.compute | 205 + .../Compute/PinConstraints.compute.meta | 8 + .../Obi/Resources/Compute/Quaternion.cginc | 230 + .../Resources/Compute/Quaternion.cginc.meta | 9 + .../Resources/Compute/QueryDefinitions.cginc | 30 + .../Compute/QueryDefinitions.cginc.meta | 9 + .../Resources/Compute/RayShapeQuery.compute | 132 + .../Compute/RayShapeQuery.compute.meta | 8 + .../Obi/Resources/Compute/Rigidbody.cginc | 108 + .../Resources/Compute/Rigidbody.cginc.meta | 7 + .../Compute/RopeChainRendering.compute | 109 + .../Compute/RopeChainRendering.compute.meta | 8 + .../Compute/RopeExtrudedRendering.compute | 164 + .../RopeExtrudedRendering.compute.meta | 8 + .../Compute/RopeLineRendering.compute | 162 + .../Compute/RopeLineRendering.compute.meta | 8 + .../Compute/RopeMeshRendering.compute | 218 + .../Compute/RopeMeshRendering.compute.meta | 8 + .../Assets/Obi/Resources/Compute/Scan.compute | 78 + .../Obi/Resources/Compute/Scan.compute.meta | 8 + .../Compute/ShapeMatchingConstraints.compute | 266 + .../ShapeMatchingConstraints.compute.meta | 8 + .../Obi/Resources/Compute/Simplex.cginc | 89 + .../Obi/Resources/Compute/Simplex.cginc.meta | 9 + .../Resources/Compute/SkinConstraints.compute | 71 + .../Compute/SkinConstraints.compute.meta | 8 + .../Compute/SoftbodyRendering.compute | 145 + .../Compute/SoftbodyRendering.compute.meta | 8 + .../Obi/Resources/Compute/Solver.compute | 240 + .../Obi/Resources/Compute/Solver.compute.meta | 8 + .../Resources/Compute/SolverParameters.cginc | 22 + .../Compute/SolverParameters.cginc.meta | 9 + .../Compute/SortParticleData.compute | 30 + .../Compute/SortParticleData.compute.meta | 8 + .../Resources/Compute/SpatialQueries.compute | 314 + .../Compute/SpatialQueries.compute.meta | 8 + .../Obi/Resources/Compute/SphereShape.compute | 96 + .../Compute/SphereShape.compute.meta | 8 + .../Compute/SphereShapeQuery.compute | 107 + .../Compute/SphereShapeQuery.compute.meta | 8 + .../Compute/StitchConstraints.compute | 64 + .../Compute/StitchConstraints.compute.meta | 8 + .../Compute/StretchShearConstraints.compute | 86 + .../StretchShearConstraints.compute.meta | 8 + .../Obi/Resources/Compute/SurfacePoint.cginc | 19 + .../Resources/Compute/SurfacePoint.cginc.meta | 9 + .../Compute/TetherConstraints.compute | 64 + .../Compute/TetherConstraints.compute.meta | 8 + .../Obi/Resources/Compute/Transform.cginc | 98 + .../Resources/Compute/Transform.cginc.meta | 9 + .../Compute/TriangleMeshShape.compute | 208 + .../Compute/TriangleMeshShape.compute.meta | 8 + .../Compute/VolumeConstraints.compute | 153 + .../Compute/VolumeConstraints.compute.meta | 8 + .../Obi/Resources/DefaultRopeSection.asset | 26 + .../Resources/DefaultRopeSection.asset.meta | 10 + xiaofang/Assets/Obi/Resources/GUI.meta | 9 + .../Obi/Resources/GUI/ProfilerSkin.guiskin | 1494 + .../Resources/GUI/ProfilerSkin.guiskin.meta | 8 + .../Assets/Obi/Resources/GUI/profiler_bck.png | Bin 0 -> 2801 bytes .../Obi/Resources/GUI/profiler_bck.png.meta | 92 + .../Obi/Resources/GUI/profiler_toolbar.png | Bin 0 -> 2878 bytes .../Resources/GUI/profiler_toolbar.png.meta | 92 + .../Assets/Obi/Resources/GUI/scroll_peg.png | Bin 0 -> 2821 bytes .../Obi/Resources/GUI/scroll_peg.png.meta | 92 + .../Assets/Obi/Resources/GUI/task_bck.png | Bin 0 -> 2801 bytes .../Obi/Resources/GUI/task_bck.png.meta | 59 + .../Assets/Obi/Resources/GUI/thread_bck.png | Bin 0 -> 2829 bytes .../Obi/Resources/GUI/thread_bck.png.meta | 92 + .../Assets/Obi/Resources/ObiMaterials.meta | 9 + .../BuiltInStandardBackfaces.meta | 8 + .../StandardVertexColors.shader | 51 + .../StandardVertexColors.shader.meta | 9 + .../Obi/Resources/ObiMaterials/Common.meta | 8 + .../ObiMaterials/Common/Instanced.meta | 8 + .../ObiMaterials/Common/Instanced/Burst.meta | 8 + .../Common/Instanced/Burst/Instanced.mat | 136 + .../Common/Instanced/Burst/Instanced.mat.meta | 8 + .../Common/Instanced/Compute.meta | 8 + .../Instanced/Compute/ProceduralInstanced.mat | 95 + .../Compute/ProceduralInstanced.mat.meta | 8 + .../Compute/ProceduralInstanced.shadergraph | 1049 + .../ProceduralInstanced.shadergraph.meta | 10 + .../Compute/ProceduralInstancing.cginc | 33 + .../Compute/ProceduralInstancing.cginc.meta | 7 + .../ObiMaterials/Common/ObiEllipsoids.cginc | 103 + .../Common/ObiEllipsoids.cginc.meta | 9 + .../Common/ObiEllipsoidsHDRP.cginc | 104 + .../Common/ObiEllipsoidsHDRP.cginc.meta | 7 + .../ObiMaterials/Common/ObiUtils.cginc | 28 + .../ObiMaterials/Common/ObiUtils.cginc.meta | 9 + .../Common/ParticleShader.shadergraph | 5867 +++ .../Common/ParticleShader.shadergraph.meta | 10 + .../ObiMaterials/Common/Particles.mat | 123 + .../ObiMaterials/Common/Particles.mat.meta | 8 + .../ObiMaterials/Common/particle.png | Bin 0 -> 4796 bytes .../ObiMaterials/Common/particle.png.meta | 59 + .../ObiMaterials/DistanceFields.meta | 8 + .../DistanceFields/DistanceFieldRendering.mat | 91 + .../DistanceFieldRendering.mat.meta | 9 + .../DistanceFields/DistanceFieldSlice.shader | 66 + .../DistanceFieldSlice.shader.meta | 9 + xiaofang/Assets/Obi/Samples.meta | 9 + xiaofang/Assets/Obi/Samples/Common.meta | 8 + .../Obi/Samples/Common/SampleResources.meta | 8 + .../Common/SampleResources/Animations.meta | 8 + .../Animations/FanHorizontal.anim | 205 + .../Animations/FanHorizontal.anim.meta | 8 + .../Animations/FanRoot.controller | 72 + .../Animations/FanRoot.controller.meta | 8 + .../Animations/HumanoidCrouch.fbx | Bin 0 -> 5422240 bytes .../Animations/HumanoidCrouch.fbx.meta | 1606 + .../Animations/HumanoidIdle.fbx | Bin 0 -> 1411008 bytes .../Animations/HumanoidIdle.fbx.meta | 2376 + .../Animations/HumanoidIdleJumpUp.fbx | Bin 0 -> 467824 bytes .../Animations/HumanoidIdleJumpUp.fbx.meta | 3389 ++ .../Animations/HumanoidJumpAndFall.fbx | Bin 0 -> 957744 bytes .../Animations/HumanoidJumpAndFall.fbx.meta | 2262 + .../Animations/HumanoidMidAir.fbx | Bin 0 -> 654976 bytes .../Animations/HumanoidMidAir.fbx.meta | 2641 + .../Animations/HumanoidRun.fbx | Bin 0 -> 972704 bytes .../Animations/HumanoidRun.fbx.meta | 2814 + .../Animations/HumanoidRunTurn.fbx | Bin 0 -> 657424 bytes .../Animations/HumanoidRunTurn.fbx.meta | 2467 + .../Animations/HumanoidRunTurnSharp.fbx | Bin 0 -> 534944 bytes .../Animations/HumanoidRunTurnSharp.fbx.meta | 2402 + .../Animations/HumanoidStandTurn.fbx | Bin 0 -> 1130880 bytes .../Animations/HumanoidStandTurn.fbx.meta | 2922 ++ .../Animations/HumanoidWalk.fbx | Bin 0 -> 732176 bytes .../Animations/HumanoidWalk.fbx.meta | 2358 + .../Animations/HumanoidWalkTurn.fbx | Bin 0 -> 657216 bytes .../Animations/HumanoidWalkTurn.fbx.meta | 2390 + .../Animations/HumanoidWalkTurnSharp.fbx | Bin 0 -> 630256 bytes .../Animations/HumanoidWalkTurnSharp.fbx.meta | 2390 + .../ThirdPersonAnimatorController.controller | 937 + ...rdPersonAnimatorController.controller.meta | 12 + .../SampleResources/CollisionMaterials.meta | 8 + .../CharacterFriction.physicMaterial | 14 + .../CharacterFriction.physicMaterial.meta | 9 + .../CollisionMaterials/HighFriction.asset | 22 + .../HighFriction.asset.meta | 8 + .../HighStaticFriction.asset | 22 + .../HighStaticFriction.asset.meta | 8 + .../CollisionMaterials/Ice.asset | 22 + .../CollisionMaterials/Ice.asset.meta | 8 + .../CollisionMaterials/LowFriction.asset | 22 + .../CollisionMaterials/LowFriction.asset.meta | 8 + .../CollisionMaterials/MediumFriction.asset | 22 + .../MediumFriction.asset.meta | 8 + .../CollisionMaterials/RollingFriction.asset | 22 + .../RollingFriction.asset.meta | 8 + .../CollisionMaterials/VerySticky.asset | 22 + .../CollisionMaterials/VerySticky.asset.meta | 8 + .../SampleResources/DistanceFields.meta | 8 + .../DistanceFields/EnvironmentDF.asset | 43450 ++++++++++++++++ .../DistanceFields/EnvironmentDF.asset.meta | 9 + .../Common/SampleResources/Materials.meta | 8 + .../SampleResources/Materials/Checker.mat | 130 + .../Materials/Checker.mat.meta | 8 + .../Materials/CoarseChecker.mat | 134 + .../Materials/CoarseChecker.mat.meta | 8 + .../SampleResources/Materials/FinishLine.mat | 82 + .../Materials/FinishLine.mat.meta | 8 + .../SampleResources/Materials/Flesh.mat | 80 + .../SampleResources/Materials/Flesh.mat.meta | 11 + .../SampleResources/Materials/Metal.mat | 83 + .../SampleResources/Materials/Metal.mat.meta | 8 + .../Materials/TestEnvironment.mat | 114 + .../Materials/TestEnvironment.mat.meta | 8 + .../Materials/VertexColors.mat | 84 + .../Materials/VertexColors.mat.meta | 12 + .../SampleResources/Materials/Walls.mat | 83 + .../SampleResources/Materials/Walls.mat.meta | 8 + .../Common/SampleResources/Models.meta | 8 + .../SampleResources/Models/CubicSphere.fbx | Bin 0 -> 24624 bytes .../Models/CubicSphere.fbx.meta | 80 + .../Common/SampleResources/Models/Fan.fbx | Bin 0 -> 43392 bytes .../SampleResources/Models/Fan.fbx.meta | 171 + .../Models/TestEnvironment.fbx | Bin 0 -> 24352 bytes .../Models/TestEnvironment.fbx.meta | 120 + .../Common/SampleResources/Scripts.meta | 8 + .../Scripts/ActorCOMTransform.cs | 21 + .../Scripts/ActorCOMTransform.cs.meta | 11 + .../SampleResources/Scripts/ActorSpawner.cs | 29 + .../Scripts/ActorSpawner.cs.meta | 11 + .../Scripts/AddRandomVelocity.cs | 16 + .../Scripts/AddRandomVelocity.cs.meta | 11 + .../Common/SampleResources/Scripts/Blinker.cs | 23 + .../SampleResources/Scripts/Blinker.cs.meta | 12 + .../Scripts/CharacterController.meta | 9 + .../CharacterController/ObiCharacter.cs | 229 + .../CharacterController/ObiCharacter.cs.meta | 11 + .../SampleCharacterController.cs | 72 + .../SampleCharacterController.cs.meta | 11 + .../Scripts/ColliderHighlighter.cs | 45 + .../Scripts/ColliderHighlighter.cs.meta | 12 + .../Scripts/CollisionEventHandler.cs | 184 + .../Scripts/CollisionEventHandler.cs.meta | 12 + .../SampleResources/Scripts/ColorFromPhase.cs | 38 + .../Scripts/ColorFromPhase.cs.meta | 11 + .../Scripts/ColorFromVelocity.cs | 43 + .../Scripts/ColorFromVelocity.cs.meta | 11 + .../Scripts/ColorRandomizer.cs | 26 + .../Scripts/ColorRandomizer.cs.meta | 11 + .../Scripts/DebugParticleFrames.cs | 39 + .../Scripts/DebugParticleFrames.cs.meta | 11 + .../Scripts/ExtrapolationCamera.cs | 76 + .../Scripts/ExtrapolationCamera.cs.meta | 11 + .../SampleResources/Scripts/FPSDisplay.cs | 77 + .../Scripts/FPSDisplay.cs.meta | 12 + .../Scripts/LookAroundCamera.cs | 81 + .../Scripts/LookAroundCamera.cs.meta | 11 + .../SampleResources/Scripts/MoveAndRotate.cs | 39 + .../Scripts/MoveAndRotate.cs.meta | 11 + .../Scripts/ObiActorTeleport.cs | 15 + .../Scripts/ObiActorTeleport.cs.meta | 12 + .../Scripts/ObiParticleCounter.cs | 53 + .../Scripts/ObiParticleCounter.cs.meta | 11 + .../SampleResources/Scripts/ObjectDragger.cs | 23 + .../Scripts/ObjectDragger.cs.meta | 12 + .../SampleResources/Scripts/ObjectLimit.cs | 22 + .../Scripts/ObjectLimit.cs.meta | 12 + .../SampleResources/Scripts/SlowmoToggler.cs | 10 + .../Scripts/SlowmoToggler.cs.meta | 12 + .../Scripts/WorldSpaceGravity.cs | 21 + .../Scripts/WorldSpaceGravity.cs.meta | 11 + .../SampleResources/SparksEmitter.prefab | 4965 ++ .../SampleResources/SparksEmitter.prefab.meta | 9 + .../Common/SampleResources/Textures.meta | 8 + .../SampleResources/Textures/ClothPattern.png | Bin 0 -> 16584 bytes .../Textures/ClothPattern.png.meta | 55 + .../Textures/ClothPattern_SM.psd | Bin 0 -> 497474 bytes .../Textures/ClothPattern_SM.psd.meta | 55 + .../SampleResources/Textures/checker.psd | Bin 0 -> 25134 bytes .../SampleResources/Textures/checker.psd.meta | 100 + xiaofang/Assets/Obi/Samples/RopeAndRod.meta | 10 + .../Obi/Samples/RopeAndRod/Chains.unity | 2389 + .../Obi/Samples/RopeAndRod/Chains.unity.meta | 9 + .../RopeAndRod/ChainsSettings.lighting | 64 + .../RopeAndRod/ChainsSettings.lighting.meta | 8 + .../RopeAndRod/CharacterTentacles.unity | 3902 ++ .../RopeAndRod/CharacterTentacles.unity.meta | 9 + .../Obi/Samples/RopeAndRod/ComputeRopes.unity | 39781 ++++++++++++++ .../RopeAndRod/ComputeRopes.unity.meta | 9 + .../Assets/Obi/Samples/RopeAndRod/Crane.unity | 2888 + .../Obi/Samples/RopeAndRod/Crane.unity.meta | 9 + .../Samples/RopeAndRod/ElectricalWires.unity | 2996 ++ .../RopeAndRod/ElectricalWires.unity.meta | 9 + .../Obi/Samples/RopeAndRod/Firehose.unity | 6334 +++ .../Samples/RopeAndRod/Firehose.unity.meta | 9 + .../RopeAndRod/FirehoseSettings.lighting | 64 + .../RopeAndRod/FirehoseSettings.lighting.meta | 8 + .../Obi/Samples/RopeAndRod/FreightLift.unity | 2619 + .../Samples/RopeAndRod/FreightLift.unity.meta | 9 + .../Obi/Samples/RopeAndRod/Plectoneme.unity | 2009 + .../Samples/RopeAndRod/Plectoneme.unity.meta | 9 + .../RopeAndRod/PlectonemeSettings.lighting | 64 + .../PlectonemeSettings.lighting.meta | 8 + .../Obi/Samples/RopeAndRod/RenderModes.unity | 1590 + .../Samples/RopeAndRod/RenderModes.unity.meta | 7 + .../Obi/Samples/RopeAndRod/Rocker.unity | 1855 + .../Obi/Samples/RopeAndRod/Rocker.unity.meta | 9 + .../RopeAndRod/RockerSettings.lighting | 64 + .../RopeAndRod/RockerSettings.lighting.meta | 8 + .../Samples/RopeAndRod/RopeAndJoints.unity | 2569 + .../RopeAndRod/RopeAndJoints.unity.meta | 9 + .../RopeAndRod/RopeAndJointsSettings.lighting | 64 + .../RopeAndJointsSettings.lighting.meta | 8 + .../Obi/Samples/RopeAndRod/RopeCutting.unity | 2083 + .../Samples/RopeAndRod/RopeCutting.unity.meta | 9 + .../RopeAndRod/RopeGrapplingHook.unity | 1459 + .../RopeAndRod/RopeGrapplingHook.unity.meta | 9 + .../RopeGrapplingHookSettings.lighting | 64 + .../RopeGrapplingHookSettings.lighting.meta | 8 + .../Obi/Samples/RopeAndRod/RopeNet.unity | 506 + .../Obi/Samples/RopeAndRod/RopeNet.unity.meta | 9 + .../Obi/Samples/RopeAndRod/RopeShowcase.unity | 2754 + .../RopeAndRod/RopeShowcase.unity.meta | 9 + .../RopeAndRod/RopeShowcaseSettings.lighting | 64 + .../RopeShowcaseSettings.lighting.meta | 8 + .../Samples/RopeAndRod/SampleResources.meta | 8 + .../SampleResources/Animations.meta | 8 + .../Animations/BenderAnimation.anim | 205 + .../Animations/BenderAnimation.anim.meta | 10 + .../Animations/Bending.controller | 72 + .../Animations/Bending.controller.meta | 10 + .../Animations/Obi Rod.controller | 72 + .../Animations/Obi Rod.controller.meta | 10 + .../Animations/PlectonemeTwister.anim | 819 + .../Animations/PlectonemeTwister.anim.meta | 10 + .../PlectonemeTwisterController.controller | 72 + ...lectonemeTwisterController.controller.meta | 10 + .../Animations/Rocker.controller | 72 + .../Animations/Rocker.controller.meta | 10 + .../Animations/RockerAnimation.anim | 277 + .../Animations/RockerAnimation.anim.meta | 10 + .../Animations/RopeCircuit.controller | 72 + .../Animations/RopeCircuit.controller.meta | 10 + .../Animations/RopeCircuitAnimation.anim | 205 + .../Animations/RopeCircuitAnimation.anim.meta | 10 + .../Animations/RopeHangerAnimation.anim | 205 + .../Animations/RopeHangerAnimation.anim.meta | 10 + .../Animations/RopeStretcher.anim | 205 + .../Animations/RopeStretcher.anim.meta | 8 + .../Animations/RopeStretcher.controller | 72 + .../Animations/RopeStretcher.controller.meta | 10 + .../Animations/SpringBase.anim | 459 + .../Animations/SpringBase.anim.meta | 8 + .../Animations/SpringBase.controller | 72 + .../Animations/SpringBase.controller.meta | 10 + .../SampleResources/Blueprints.meta | 8 + .../SampleResources/Blueprints/Chain.asset | 2220 + .../Blueprints/Chain.asset.meta | 8 + .../SampleResources/Blueprints/Crane.asset | 2809 + .../Blueprints/Crane.asset.meta | 8 + .../Blueprints/CuttableRope.asset | 2519 + .../Blueprints/CuttableRope.asset.meta | 8 + .../SampleResources/Blueprints/Firehose.asset | 780 + .../Blueprints/Firehose.asset.meta | 8 + .../Blueprints/Freightlift cable.asset | 2084 + .../Blueprints/Freightlift cable.asset.meta | 8 + .../Blueprints/Joints rope 1.asset | 2266 + .../Blueprints/Joints rope 1.asset.meta | 8 + .../Blueprints/Joints rope 2.asset | 2100 + .../Blueprints/Joints rope 2.asset.meta | 8 + .../Blueprints/Plectoneme rod.asset | 1103 + .../Blueprints/Plectoneme rod.asset.meta | 8 + .../SampleResources/Blueprints/Snake.asset | 2219 + .../Blueprints/Snake.asset.meta | 8 + .../Blueprints/SpringRod.asset | 2751 + .../Blueprints/SpringRod.asset.meta | 8 + .../Blueprints/Straight long rope.asset | 1994 + .../Blueprints/Straight long rope.asset.meta | 8 + .../Blueprints/Straight short rope.asset | 1948 + .../Blueprints/Straight short rope.asset.meta | 8 + .../Blueprints/TangledRopeA.asset | 1607 + .../Blueprints/TangledRopeA.asset.meta | 8 + .../Blueprints/TangledRopeB.asset | 2166 + .../Blueprints/TangledRopeB.asset.meta | 8 + .../Blueprints/Tearable cable.asset | 2040 + .../Blueprints/Tearable cable.asset.meta | 8 + .../Blueprints/Very long cable.asset | 2098 + .../Blueprints/Very long cable.asset.meta | 8 + .../Blueprints/WrappingRope.asset | 1978 + .../Blueprints/WrappingRope.asset.meta | 8 + .../RopeAndRod/SampleResources/Materials.meta | 8 + .../SampleResources/Materials/ChainRed.mat | 83 + .../Materials/ChainRed.mat.meta | 10 + .../SampleResources/Materials/ChainWhite.mat | 83 + .../Materials/ChainWhite.mat.meta | 10 + .../SampleResources/Materials/GreenRope.mat | 88 + .../Materials/GreenRope.mat.meta | 10 + .../SampleResources/Materials/LineRope.mat | 84 + .../Materials/LineRope.mat.meta | 10 + .../SampleResources/Materials/RedRope.mat | 84 + .../Materials/RedRope.mat.meta | 10 + .../SampleResources/Materials/Rod.mat | 83 + .../SampleResources/Materials/Rod.mat.meta | 10 + .../SampleResources/Materials/Shark.mat | 81 + .../SampleResources/Materials/Shark.mat.meta | 8 + .../SampleResources/Materials/Snake.mat | 80 + .../SampleResources/Materials/Snake.mat.meta | 8 + .../SampleResources/Materials/TanglePeg.mat | 80 + .../Materials/TanglePeg.mat.meta | 8 + .../SampleResources/Materials/WrapPeg.mat | 80 + .../Materials/WrapPeg.mat.meta | 8 + .../RopeAndRod/SampleResources/Models.meta | 8 + .../SampleResources/Models/ChainLink.fbx | Bin 0 -> 20288 bytes .../SampleResources/Models/ChainLink.fbx.meta | 99 + .../Models/ChainLinkRed.prefab | 85 + .../Models/ChainLinkRed.prefab.meta | 9 + .../Models/ChainLinkWhite.prefab | 85 + .../Models/ChainLinkWhite.prefab.meta | 9 + .../SampleResources/Models/shark.obj | 11018 ++++ .../SampleResources/Models/shark.obj.meta | 105 + .../SampleResources/Models/tentacle_guy.fbx | Bin 0 -> 613536 bytes .../Models/tentacle_guy.fbx.meta | 609 + .../RopeAndRod/SampleResources/Prefabs.meta | 8 + .../SampleResources/Prefabs/SnakeBamboo.asset | 22 + .../Prefabs/SnakeBamboo.asset.meta | 8 + .../SampleResources/Prefabs/SnakeBody.asset | 22 + .../Prefabs/SnakeBody.asset.meta | 8 + .../SampleResources/Prefabs/SnakeFloor.asset | 22 + .../Prefabs/SnakeFloor.asset.meta | 8 + .../SampleResources/Prefabs/TanglePeg.prefab | 202 + .../Prefabs/TanglePeg.prefab.meta | 7 + .../Prefabs/TanglePegSlot.prefab | 100 + .../Prefabs/TanglePegSlot.prefab.meta | 7 + .../SampleResources/Prefabs/WrapPeg.prefab | 134 + .../Prefabs/WrapPeg.prefab.meta | 7 + .../RopeAndRod/SampleResources/Scripts.meta | 8 + .../Scripts/CharacterControl2D.cs | 33 + .../Scripts/CharacterControl2D.cs.meta | 13 + .../Scripts/CraneController.cs | 37 + .../Scripts/CraneController.cs.meta | 13 + .../Scripts/CursorController.cs | 49 + .../Scripts/CursorController.cs.meta | 13 + .../Scripts/ExtendableGrapplingHook.cs | 223 + .../Scripts/ExtendableGrapplingHook.cs.meta | 13 + .../SampleResources/Scripts/GrapplingHook.cs | 152 + .../Scripts/GrapplingHook.cs.meta | 13 + .../SampleResources/Scripts/HosePump.cs | 83 + .../SampleResources/Scripts/HosePump.cs.meta | 12 + .../Scripts/RopeBetweenTwoPoints.cs | 69 + .../Scripts/RopeBetweenTwoPoints.cs.meta | 11 + .../SampleResources/Scripts/RopeNet.cs | 128 + .../SampleResources/Scripts/RopeNet.cs.meta | 13 + .../SampleResources/Scripts/RopeSweepCut.cs | 148 + .../Scripts/RopeSweepCut.cs.meta | 11 + .../SampleResources/Scripts/RopeTenser.cs | 14 + .../Scripts/RopeTenser.cs.meta | 11 + .../Scripts/RopeTensionColorizer.cs | 58 + .../Scripts/RopeTensionColorizer.cs.meta | 11 + .../Scripts/SnakeController.cs | 124 + .../Scripts/SnakeController.cs.meta | 11 + .../SampleResources/Scripts/SpiralCurve.cs | 50 + .../Scripts/SpiralCurve.cs.meta | 13 + .../SampleResources/Scripts/TangledPeg.cs | 86 + .../Scripts/TangledPeg.cs.meta | 11 + .../SampleResources/Scripts/TangledPegSlot.cs | 32 + .../Scripts/TangledPegSlot.cs.meta | 11 + .../Scripts/TangledRopesGameController.cs | 136 + .../TangledRopesGameController.cs.meta | 11 + .../Scripts/WrapRopeGameController.cs | 72 + .../Scripts/WrapRopeGameController.cs.meta | 11 + .../Scripts/WrapRopePlayerController.cs | 42 + .../Scripts/WrapRopePlayerController.cs.meta | 11 + .../SampleResources/Scripts/Wrappable.cs | 41 + .../SampleResources/Scripts/Wrappable.cs.meta | 11 + .../RopeAndRod/SampleResources/Textures.meta | 8 + .../SampleResources/Textures/Rod.png | Bin 0 -> 2886 bytes .../SampleResources/Textures/Rod.png.meta | 123 + .../SampleResources/Textures/Rope_NRM.png | Bin 0 -> 56208 bytes .../Textures/Rope_NRM.png.meta | 90 + .../SampleResources/Textures/Rope_OCC.png | Bin 0 -> 29236 bytes .../Textures/Rope_OCC.png.meta | 90 + .../SampleResources/Textures/Rope_red.png | Bin 0 -> 2872 bytes .../Textures/Rope_red.png.meta | 134 + .../SampleResources/Textures/cylinder_NRM.png | Bin 0 -> 6378 bytes .../Textures/cylinder_NRM.png.meta | 121 + .../Textures/greatwhiteshark.png | Bin 0 -> 223818 bytes .../Textures/greatwhiteshark.png.meta | 98 + .../Textures/greatwhiteshark_n.png | Bin 0 -> 139242 bytes .../Textures/greatwhiteshark_n.png.meta | 98 + .../Assets/Obi/Samples/RopeAndRod/Snake.unity | 1729 + .../Obi/Samples/RopeAndRod/Snake.unity.meta | 9 + .../Obi/Samples/RopeAndRod/SpringRod.unity | 1327 + .../Samples/RopeAndRod/SpringRod.unity.meta | 9 + .../RopeAndRod/SpringRodSettings.lighting | 64 + .../SpringRodSettings.lighting.meta | 8 + .../Obi/Samples/RopeAndRod/TangledRopes.unity | 2884 + .../RopeAndRod/TangledRopes.unity.meta | 7 + .../Obi/Samples/RopeAndRod/WrapTheRope.unity | 2677 + .../Samples/RopeAndRod/WrapTheRope.unity.meta | 7 + .../RopeAndRod/WrapTheRopeSettings.lighting | 64 + .../WrapTheRopeSettings.lighting.meta | 8 + xiaofang/Assets/Obi/Scripts.meta | 9 + xiaofang/Assets/Obi/Scripts/Common.meta | 8 + .../Assets/Obi/Scripts/Common/Actors.meta | 8 + .../Common/Actors/IObiParticleCollection.cs | 25 + .../Actors/IObiParticleCollection.cs.meta | 11 + .../Obi/Scripts/Common/Actors/ObiActor.cs | 1261 + .../Scripts/Common/Actors/ObiActor.cs.meta | 12 + .../Assets/Obi/Scripts/Common/Backends.meta | 8 + .../Obi/Scripts/Common/Backends/Burst.meta | 8 + .../Common/Backends/Burst/BurstBackend.cs | 26 + .../Backends/Burst/BurstBackend.cs.meta | 11 + .../Common/Backends/Burst/BurstIntegration.cs | 48 + .../Backends/Burst/BurstIntegration.cs.meta | 11 + .../Common/Backends/Burst/BurstJobHandle.cs | 22 + .../Backends/Burst/BurstJobHandle.cs.meta | 11 + .../Common/Backends/Burst/BurstMath.cs | 1023 + .../Common/Backends/Burst/BurstMath.cs.meta | 11 + .../Common/Backends/Burst/Collisions.meta | 8 + .../Backends/Burst/Collisions/BurstBox.cs | 155 + .../Burst/Collisions/BurstBox.cs.meta | 11 + .../Backends/Burst/Collisions/BurstCapsule.cs | 136 + .../Burst/Collisions/BurstCapsule.cs.meta | 11 + .../Burst/Collisions/BurstColliderShape.cs | 41 + .../Collisions/BurstColliderShape.cs.meta | 11 + .../Burst/Collisions/BurstColliderWorld.cs | 625 + .../Collisions/BurstColliderWorld.cs.meta | 11 + .../Backends/Burst/Collisions/BurstDFNode.cs | 65 + .../Burst/Collisions/BurstDFNode.cs.meta | 11 + .../Burst/Collisions/BurstDistanceField.cs | 188 + .../Collisions/BurstDistanceField.cs.meta | 11 + .../Burst/Collisions/BurstEdgeMesh.cs | 211 + .../Burst/Collisions/BurstEdgeMesh.cs.meta | 11 + .../Burst/Collisions/BurstHeightField.cs | 273 + .../Burst/Collisions/BurstHeightField.cs.meta | 11 + .../Collisions/BurstLocalOptimization.cs | 207 + .../Collisions/BurstLocalOptimization.cs.meta | 11 + .../Backends/Burst/Collisions/BurstSimplex.cs | 65 + .../Burst/Collisions/BurstSimplex.cs.meta | 11 + .../Backends/Burst/Collisions/BurstSphere.cs | 127 + .../Burst/Collisions/BurstSphere.cs.meta | 11 + .../Burst/Collisions/BurstTriangleMesh.cs | 220 + .../Collisions/BurstTriangleMesh.cs.meta | 11 + .../Common/Backends/Burst/Constraints.meta | 8 + .../Burst/Constraints/Aerodynamics.meta | 8 + .../BurstAerodynamicConstraints.cs | 26 + .../BurstAerodynamicConstraints.cs.meta | 11 + .../BurstAerodynamicConstraintsBatch.cs | 112 + .../BurstAerodynamicConstraintsBatch.cs.meta | 11 + .../Backends/Burst/Constraints/Bend.meta | 8 + .../Constraints/Bend/BurstBendConstraints.cs | 26 + .../Bend/BurstBendConstraints.cs.meta | 11 + .../Bend/BurstBendConstraintsBatch.cs | 168 + .../Bend/BurstBendConstraintsBatch.cs.meta | 11 + .../Backends/Burst/Constraints/BendTwist.meta | 8 + .../BendTwist/BurstBendTwistConstraints.cs | 26 + .../BurstBendTwistConstraints.cs.meta | 11 + .../BurstBendTwistConstraintsBatch.cs | 181 + .../BurstBendTwistConstraintsBatch.cs.meta | 11 + .../Constraints/BurstConstraintsBatchImpl.cs | 110 + .../BurstConstraintsBatchImpl.cs.meta | 11 + .../Burst/Constraints/BurstConstraintsImpl.cs | 145 + .../Constraints/BurstConstraintsImpl.cs.meta | 11 + .../Backends/Burst/Constraints/Chain.meta | 8 + .../Chain/BurstChainConstraints.cs | 26 + .../Chain/BurstChainConstraints.cs.meta | 11 + .../Chain/BurstChainConstraintsBatch.cs | 222 + .../Chain/BurstChainConstraintsBatch.cs.meta | 11 + .../Burst/Constraints/ColliderCollision.meta | 8 + .../ApplyCollisionConstraintsJob.cs | 49 + .../ApplyCollisionConstraintsJob.cs.meta | 11 + .../BurstColliderCollisionConstraints.cs | 31 + .../BurstColliderCollisionConstraints.cs.meta | 11 + .../BurstColliderCollisionConstraintsBatch.cs | 344 + ...tColliderCollisionConstraintsBatch.cs.meta | 11 + .../BurstColliderFrictionConstraints.cs | 33 + .../BurstColliderFrictionConstraints.cs.meta | 11 + .../BurstColliderFrictionConstraintsBatch.cs | 280 + ...stColliderFrictionConstraintsBatch.cs.meta | 11 + .../Backends/Burst/Constraints/Density.meta | 8 + .../Density/BurstDensityConstraints.cs | 502 + .../Density/BurstDensityConstraints.cs.meta | 11 + .../Density/BurstDensityConstraintsBatch.cs | 403 + .../BurstDensityConstraintsBatch.cs.meta | 11 + .../Burst/Constraints/Density/Kernels.meta | 8 + .../Density/Kernels/CohesionKernel.cs | 15 + .../Density/Kernels/CohesionKernel.cs.meta | 11 + .../Density/Kernels/Poly6Kernel.cs | 36 + .../Density/Kernels/Poly6Kernel.cs.meta | 11 + .../Density/Kernels/SpikyKernel.cs | 35 + .../Density/Kernels/SpikyKernel.cs.meta | 11 + .../Backends/Burst/Constraints/Distance.meta | 8 + .../Distance/BurstDistanceConstraints.cs | 26 + .../Distance/BurstDistanceConstraints.cs.meta | 11 + .../Distance/BurstDistanceConstraintsBatch.cs | 146 + .../BurstDistanceConstraintsBatch.cs.meta | 11 + .../Burst/Constraints/ParticleCollision.meta | 8 + ...pplyBatchedCollisionConstraintsBatchJob.cs | 62 + ...atchedCollisionConstraintsBatchJob.cs.meta | 11 + .../BurstParticleCollisionConstraints.cs | 32 + .../BurstParticleCollisionConstraints.cs.meta | 11 + .../BurstParticleCollisionConstraintsBatch.cs | 344 + ...tParticleCollisionConstraintsBatch.cs.meta | 11 + .../BurstParticleFrictionConstraints.cs | 31 + .../BurstParticleFrictionConstraints.cs.meta | 11 + .../BurstParticleFrictionConstraintsBatch.cs | 289 + ...stParticleFrictionConstraintsBatch.cs.meta | 11 + .../Backends/Burst/Constraints/Pin.meta | 8 + .../Constraints/Pin/BurstPinConstraints.cs | 26 + .../Pin/BurstPinConstraints.cs.meta | 11 + .../Pin/BurstPinConstraintsBatch.cs | 354 + .../Pin/BurstPinConstraintsBatch.cs.meta | 11 + .../Burst/Constraints/ShapeMatching.meta | 8 + .../BurstShapeMatchingConstraints.cs | 26 + .../BurstShapeMatchingConstraints.cs.meta | 11 + .../BurstShapeMatchingConstraintsBatch.cs | 472 + ...BurstShapeMatchingConstraintsBatch.cs.meta | 11 + .../Backends/Burst/Constraints/Skin.meta | 8 + .../Constraints/Skin/BurstSkinConstraints.cs | 26 + .../Skin/BurstSkinConstraints.cs.meta | 11 + .../Skin/BurstSkinConstraintsBatch.cs | 151 + .../Skin/BurstSkinConstraintsBatch.cs.meta | 11 + .../Backends/Burst/Constraints/Stitch.meta | 8 + .../Stitch/BurstStitchConstraints.cs | 26 + .../Stitch/BurstStitchConstraints.cs.meta | 11 + .../Stitch/BurstStitchConstraintsBatch.cs | 152 + .../BurstStitchConstraintsBatch.cs.meta | 11 + .../Burst/Constraints/StretchShear.meta | 8 + .../BurstStretchShearConstraints.cs | 26 + .../BurstStretchShearConstraints.cs.meta | 11 + .../BurstStretchShearConstraintsBatch.cs | 206 + .../BurstStretchShearConstraintsBatch.cs.meta | 11 + .../Backends/Burst/Constraints/Tether.meta | 8 + .../Tether/BurstTetherConstraints.cs | 26 + .../Tether/BurstTetherConstraints.cs.meta | 11 + .../Tether/BurstTetherConstraintsBatch.cs | 141 + .../BurstTetherConstraintsBatch.cs.meta | 11 + .../Backends/Burst/Constraints/Volume.meta | 8 + .../Volume/BurstVolumeConstraints.cs | 26 + .../Volume/BurstVolumeConstraints.cs.meta | 11 + .../Volume/BurstVolumeConstraintsBatch.cs | 232 + .../BurstVolumeConstraintsBatch.cs.meta | 11 + .../Common/Backends/Burst/DataStructures.meta | 8 + .../Burst/DataStructures/BurstAabb.cs | 156 + .../Burst/DataStructures/BurstAabb.cs.meta | 11 + .../DataStructures/BurstAffineTransform.cs | 95 + .../BurstAffineTransform.cs.meta | 11 + .../Burst/DataStructures/BurstCellSpan.cs | 60 + .../DataStructures/BurstCellSpan.cs.meta | 11 + .../DataStructures/BurstCollisionMaterial.cs | 78 + .../BurstCollisionMaterial.cs.meta | 11 + .../DataStructures/BurstInertialFrame.cs | 60 + .../DataStructures/BurstInertialFrame.cs.meta | 11 + .../Burst/DataStructures/BurstPrefixSum.cs | 128 + .../DataStructures/BurstPrefixSum.cs.meta | 11 + .../Burst/DataStructures/BurstQueryShape.cs | 16 + .../DataStructures/BurstQueryShape.cs.meta | 11 + .../Burst/DataStructures/BurstRigidbody.cs | 23 + .../DataStructures/BurstRigidbody.cs.meta | 11 + .../DataStructures/ConstraintBatcher.meta | 8 + .../ConstraintBatcher/BatchLUT.cs | 49 + .../ConstraintBatcher/BatchLUT.cs.meta | 11 + .../ConstraintBatcher/ConstraintBatcher.cs | 216 + .../ConstraintBatcher.cs.meta | 11 + .../ConstraintBatcher/ConstraintSorter.cs | 160 + .../ConstraintSorter.cs.meta | 11 + .../ConstraintBatcher/ContactProvider.cs | 41 + .../ConstraintBatcher/ContactProvider.cs.meta | 11 + .../FluidInteractionProvider.cs | 32 + .../FluidInteractionProvider.cs.meta | 11 + .../ConstraintBatcher/IConstraint.cs | 10 + .../ConstraintBatcher/IConstraint.cs.meta | 11 + .../ConstraintBatcher/IConstraintProvider.cs | 12 + .../IConstraintProvider.cs.meta | 11 + .../Burst/DataStructures/FluidInteraction.cs | 19 + .../DataStructures/FluidInteraction.cs.meta | 11 + .../Backends/Burst/DataStructures/GridHash.cs | 76 + .../Burst/DataStructures/GridHash.cs.meta | 11 + .../DataStructures/NativeMultilevelGrid.cs | 282 + .../NativeMultilevelGrid.cs.meta | 11 + .../Burst/DataStructures/ParticleGrid.cs | 448 + .../Burst/DataStructures/ParticleGrid.cs.meta | 11 + .../Burst/DataStructures/Queries.meta | 8 + .../DataStructures/Queries/BurstContact.cs | 163 + .../Queries/BurstContact.cs.meta | 11 + .../Queries/BurstQueryResult.cs | 18 + .../Queries/BurstQueryResult.cs.meta | 11 + .../Common/Backends/Burst/Queries.meta | 8 + .../Backends/Burst/Queries/BurstBoxQuery.cs | 98 + .../Burst/Queries/BurstBoxQuery.cs.meta | 11 + .../Common/Backends/Burst/Queries/BurstRay.cs | 92 + .../Backends/Burst/Queries/BurstRay.cs.meta | 11 + .../Burst/Queries/BurstSphereQuery.cs | 69 + .../Burst/Queries/BurstSphereQuery.cs.meta | 11 + .../Backends/Burst/Queries/SpatialQueryJob.cs | 129 + .../Burst/Queries/SpatialQueryJob.cs.meta | 11 + .../Common/Backends/Burst/Rendering.meta | 8 + .../Backends/Burst/Rendering/Common.meta | 8 + .../Common/BuildParticleMeshDataJob.cs | 62 + .../Common/BuildParticleMeshDataJob.cs.meta | 11 + .../Rendering/Common/BurstFoamRenderSystem.cs | 242 + .../Common/BurstFoamRenderSystem.cs.meta | 11 + .../BurstInstancedParticleRenderSystem.cs | 100 + ...BurstInstancedParticleRenderSystem.cs.meta | 11 + .../Common/BurstParticleRenderSystem.cs | 58 + .../Common/BurstParticleRenderSystem.cs.meta | 11 + .../Backends/Burst/Rendering/RopeAndRod.meta | 10 + .../RopeAndRod/BurstChainRopeRenderSystem.cs | 139 + .../BurstChainRopeRenderSystem.cs.meta | 11 + .../BurstExtrudedRopeRenderSystem.cs | 215 + .../BurstExtrudedRopeRenderSystem.cs.meta | 11 + .../RopeAndRod/BurstLineRopeRenderSystem.cs | 215 + .../BurstLineRopeRenderSystem.cs.meta | 11 + .../RopeAndRod/BurstMeshRopeRenderSystem.cs | 272 + .../BurstMeshRopeRenderSystem.cs.meta | 11 + .../Rendering/RopeAndRod/BurstPathFrame.cs | 170 + .../RopeAndRod/BurstPathFrame.cs.meta | 11 + .../BurstPathSmootherRenderSystem.cs | 63 + .../BurstPathSmootherRenderSystem.cs.meta | 11 + .../RopeAndRod/ChaikinSmoothChunksJob.cs | 93 + .../RopeAndRod/ChaikinSmoothChunksJob.cs.meta | 11 + .../Rendering/RopeAndRod/DecimateChunksJob.cs | 79 + .../RopeAndRod/DecimateChunksJob.cs.meta | 11 + .../RopeAndRod/ParallelTransportJob.cs | 89 + .../RopeAndRod/ParallelTransportJob.cs.meta | 11 + .../Scripts/Common/Backends/Burst/Solver.meta | 8 + .../Burst/Solver/ApplyInertialForcesJob.cs | 46 + .../Solver/ApplyInertialForcesJob.cs.meta | 11 + .../Burst/Solver/BoundsReductionJob.cs | 86 + .../Burst/Solver/BoundsReductionJob.cs.meta | 11 + .../Backends/Burst/Solver/BurstSolverImpl.cs | 265 + .../Burst/Solver/BurstSolverImpl.cs.meta | 11 + .../Burst/Solver/DequeueIntoArrayJob.cs | 26 + .../Burst/Solver/DequeueIntoArrayJob.cs.meta | 11 + .../Burst/Solver/FindFluidParticlesJob.cs | 33 + .../Solver/FindFluidParticlesJob.cs.meta | 11 + .../Backends/Burst/Solver/FoamParticlesJob.cs | 325 + .../Burst/Solver/FoamParticlesJob.cs.meta | 11 + .../Backends/Burst/Solver/InterpolationJob.cs | 53 + .../Burst/Solver/InterpolationJob.cs.meta | 11 + .../Burst/Solver/PredictPositionsJob.cs | 82 + .../Burst/Solver/PredictPositionsJob.cs.meta | 11 + .../Backends/Burst/Solver/UpdateNormalsJob.cs | 121 + .../Burst/Solver/UpdateNormalsJob.cs.meta | 11 + .../Burst/Solver/UpdatePositionsJob.cs | 68 + .../Burst/Solver/UpdatePositionsJob.cs.meta | 11 + .../Burst/Solver/UpdateVelocitiesJob.cs | 58 + .../Burst/Solver/UpdateVelocitiesJob.cs.meta | 11 + .../Obi/Scripts/Common/Backends/Compute.meta | 8 + .../Common/Backends/Compute/Collisions.meta | 8 + .../Backends/Compute/Collisions/ComputeBox.cs | 42 + .../Compute/Collisions/ComputeBox.cs.meta | 11 + .../Compute/Collisions/ComputeCapsule.cs | 42 + .../Compute/Collisions/ComputeCapsule.cs.meta | 11 + .../Collisions/ComputeColliderWorld.cs | 472 + .../Collisions/ComputeColliderWorld.cs.meta | 11 + .../Collisions/ComputeDistanceField.cs | 50 + .../Collisions/ComputeDistanceField.cs.meta | 11 + .../Compute/Collisions/ComputeEdgeMesh.cs | 53 + .../Collisions/ComputeEdgeMesh.cs.meta | 11 + .../Compute/Collisions/ComputeHeightField.cs | 51 + .../Collisions/ComputeHeightField.cs.meta | 11 + .../Compute/Collisions/ComputeSphere.cs | 42 + .../Compute/Collisions/ComputeSphere.cs.meta | 11 + .../Compute/Collisions/ComputeTriangleMesh.cs | 53 + .../Collisions/ComputeTriangleMesh.cs.meta | 11 + .../Compute/Collisions/SpatialQueries.cs | 245 + .../Compute/Collisions/SpatialQueries.cs.meta | 11 + .../Common/Backends/Compute/ComputeBackend.cs | 17 + .../Backends/Compute/ComputeBackend.cs.meta | 11 + .../Backends/Compute/ComputeJobHandle.cs | 15 + .../Backends/Compute/ComputeJobHandle.cs.meta | 11 + .../Common/Backends/Compute/ComputeMath.cs | 16 + .../Backends/Compute/ComputeMath.cs.meta | 11 + .../Common/Backends/Compute/Constraints.meta | 8 + .../Compute/Constraints/Aerodynamics.meta | 8 + .../ComputeAerodynamicConstraints.cs | 30 + .../ComputeAerodynamicConstraints.cs.meta | 11 + .../ComputeAerodynamicConstraintsBatch.cs | 52 + ...ComputeAerodynamicConstraintsBatch.cs.meta | 11 + .../Backends/Compute/Constraints/Bend.meta | 8 + .../Bend/ComputeBendConstraints.cs | 32 + .../Bend/ComputeBendConstraints.cs.meta | 11 + .../Bend/ComputeBendConstraintsBatch.cs | 75 + .../Bend/ComputeBendConstraintsBatch.cs.meta | 11 + .../Compute/Constraints/BendTwist.meta | 8 + .../BendTwist/ComputeBendTwistConstraints.cs | 32 + .../ComputeBendTwistConstraints.cs.meta | 11 + .../ComputeBendTwistConstraintsBatch.cs | 81 + .../ComputeBendTwistConstraintsBatch.cs.meta | 11 + .../Backends/Compute/Constraints/Chain.meta | 8 + .../Chain/ComputeChainConstraints.cs | 32 + .../Chain/ComputeChainConstraints.cs.meta | 11 + .../Chain/ComputeChainConstraintsBatch.cs | 97 + .../ComputeChainConstraintsBatch.cs.meta | 11 + .../Constraints/ColliderCollision.meta | 8 + .../ComputeColliderCollisionConstraints.cs | 36 + ...omputeColliderCollisionConstraints.cs.meta | 11 + ...omputeColliderCollisionConstraintsBatch.cs | 126 + ...eColliderCollisionConstraintsBatch.cs.meta | 11 + .../ComputeColliderFrictionConstraints.cs | 32 + ...ComputeColliderFrictionConstraints.cs.meta | 11 + ...ComputeColliderFrictionConstraintsBatch.cs | 86 + ...teColliderFrictionConstraintsBatch.cs.meta | 11 + .../ComputeConstraintsBatchImpl.cs | 82 + .../ComputeConstraintsBatchImpl.cs.meta | 11 + .../Constraints/ComputeConstraintsImpl.cs | 126 + .../ComputeConstraintsImpl.cs.meta | 11 + .../Backends/Compute/Constraints/Density.meta | 8 + .../Density/ComputeDensityConstraints.cs | 151 + .../Density/ComputeDensityConstraints.cs.meta | 11 + .../Density/ComputeDensityConstraintsBatch.cs | 94 + .../ComputeDensityConstraintsBatch.cs.meta | 11 + .../Compute/Constraints/Distance.meta | 8 + .../Distance/ComputeDistanceConstraints.cs | 44 + .../ComputeDistanceConstraints.cs.meta | 11 + .../ComputeDistanceConstraintsBatch.cs | 85 + .../ComputeDistanceConstraintsBatch.cs.meta | 11 + .../Constraints/ParticleCollision.meta | 8 + .../ComputeParticleCollisionConstraints.cs | 34 + ...omputeParticleCollisionConstraints.cs.meta | 11 + ...omputeParticleCollisionConstraintsBatch.cs | 104 + ...eParticleCollisionConstraintsBatch.cs.meta | 11 + .../ComputeParticleFrictionConstraints.cs | 32 + ...ComputeParticleFrictionConstraints.cs.meta | 11 + ...ComputeParticleFrictionConstraintsBatch.cs | 79 + ...teParticleFrictionConstraintsBatch.cs.meta | 11 + .../Backends/Compute/Constraints/Pin.meta | 8 + .../Constraints/Pin/ComputePinConstraints.cs | 48 + .../Pin/ComputePinConstraints.cs.meta | 11 + .../Pin/ComputePinConstraintsBatch.cs | 140 + .../Pin/ComputePinConstraintsBatch.cs.meta | 11 + .../Compute/Constraints/ShapeMatching.meta | 8 + .../ComputeShapeMatchingConstraints.cs | 48 + .../ComputeShapeMatchingConstraints.cs.meta | 11 + .../ComputeShapeMatchingConstraintsBatch.cs | 204 + ...mputeShapeMatchingConstraintsBatch.cs.meta | 11 + .../Backends/Compute/Constraints/Skin.meta | 8 + .../Skin/ComputeSkinConstraints.cs | 32 + .../Skin/ComputeSkinConstraints.cs.meta | 11 + .../Skin/ComputeSkinConstraintsBatch.cs | 81 + .../Skin/ComputeSkinConstraintsBatch.cs.meta | 11 + .../Backends/Compute/Constraints/Stitch.meta | 8 + .../Stitch/ComputeStitchConstraints.cs | 32 + .../Stitch/ComputeStitchConstraints.cs.meta | 11 + .../Stitch/ComputeStitchConstraintsBatch.cs | 71 + .../ComputeStitchConstraintsBatch.cs.meta | 11 + .../Compute/Constraints/StretchShear.meta | 8 + .../StretchShear/StretchShearConstraints.cs | 32 + .../StretchShearConstraints.cs.meta | 11 + .../StretchShearConstraintsBatch.cs | 91 + .../StretchShearConstraintsBatch.cs.meta | 11 + .../Backends/Compute/Constraints/Tether.meta | 8 + .../Tether/ComputeTetherConstraints.cs | 32 + .../Tether/ComputeTetherConstraints.cs.meta | 11 + .../Tether/ComputeTetherConstraintsBatch.cs | 75 + .../ComputeTetherConstraintsBatch.cs.meta | 11 + .../Backends/Compute/Constraints/Volume.meta | 8 + .../Volume/ComputeVolumeConstraints.cs | 40 + .../Volume/ComputeVolumeConstraints.cs.meta | 11 + .../Volume/ComputeVolumeConstraintsBatch.cs | 223 + .../ComputeVolumeConstraintsBatch.cs.meta | 11 + .../Backends/Compute/DataStructures.meta | 8 + .../DataStructures/ComputeParticleGrid.cs | 405 + .../ComputeParticleGrid.cs.meta | 11 + .../DataStructures/ComputePrefixSum.cs | 82 + .../DataStructures/ComputePrefixSum.cs.meta | 11 + .../Compute/DataStructures/ComputeSort.cs | 46 + .../DataStructures/ComputeSort.cs.meta | 11 + .../Common/Backends/Compute/Queries.meta | 8 + .../Compute/Queries/ComputeBoxQuery.cs | 42 + .../Compute/Queries/ComputeBoxQuery.cs.meta | 11 + .../Compute/Queries/ComputeRayQuery.cs | 42 + .../Compute/Queries/ComputeRayQuery.cs.meta | 11 + .../Compute/Queries/ComputeSphereQuery.cs | 42 + .../Queries/ComputeSphereQuery.cs.meta | 11 + .../Common/Backends/Compute/Rendering.meta | 8 + .../Backends/Compute/Rendering/Common.meta | 8 + .../Common/ComputeFoamRenderSystem.cs | 154 + .../Common/ComputeFoamRenderSystem.cs.meta | 11 + .../ComputeInstancedParticleRenderSystem.cs | 104 + ...mputeInstancedParticleRenderSystem.cs.meta | 11 + .../Common/ComputeParticleRenderSystem.cs | 71 + .../ComputeParticleRenderSystem.cs.meta | 11 + .../Compute/Rendering/RopeAndRod.meta | 10 + .../ComputeChainRopeRenderSystem.cs | 107 + .../ComputeChainRopeRenderSystem.cs.meta | 11 + .../ComputeExtrudedRopeRenderSystem.cs | 101 + .../ComputeExtrudedRopeRenderSystem.cs.meta | 11 + .../RopeAndRod/ComputeLineRopeRenderSystem.cs | 103 + .../ComputeLineRopeRenderSystem.cs.meta | 11 + .../RopeAndRod/ComputeMeshRopeRenderSystem.cs | 108 + .../ComputeMeshRopeRenderSystem.cs.meta | 11 + .../ComputePathSmootherRenderSystem.cs | 94 + .../ComputePathSmootherRenderSystem.cs.meta | 11 + .../Common/Backends/Compute/Solver.meta | 8 + .../Compute/Solver/ComputeSolverImpl.cs | 1275 + .../Compute/Solver/ComputeSolverImpl.cs.meta | 11 + .../Scripts/Common/Backends/Interface.meta | 8 + .../Common/Backends/Interface/Collisions.meta | 8 + .../Collisions/IColliderWorldImpl.cs | 24 + .../Collisions/IColliderWorldImpl.cs.meta | 11 + .../Collisions/IColliderWorldImpl.cs.orig | 27 + .../IColliderWorldImpl.cs.orig.meta | 7 + .../Backends/Interface/Constraints.meta | 8 + .../IAerodynamicConstraintsBatchImpl.cs | 10 + .../IAerodynamicConstraintsBatchImpl.cs.meta | 11 + .../Constraints/IBendConstraintsBatchImpl.cs | 10 + .../IBendConstraintsBatchImpl.cs.meta | 11 + .../IBendTwistConstraintsBatchImpl.cs | 10 + .../IBendTwistConstraintsBatchImpl.cs.meta | 11 + .../Constraints/IChainConstraintsBatchImpl.cs | 10 + .../IChainConstraintsBatchImpl.cs.meta | 11 + .../IColliderCollisionConstraintsBatchImpl.cs | 10 + ...liderCollisionConstraintsBatchImpl.cs.meta | 11 + .../IColliderFrictionConstraintsBatchImpl.cs | 10 + ...lliderFrictionConstraintsBatchImpl.cs.meta | 11 + .../Constraints/IConstraintsBatchImpl.cs | 29 + .../Constraints/IConstraintsBatchImpl.cs.meta | 11 + .../Interface/Constraints/IConstraintsImpl.cs | 22 + .../Constraints/IConstraintsImpl.cs.meta | 11 + .../IDensityConstraintsBatchImpl.cs | 10 + .../IDensityConstraintsBatchImpl.cs.meta | 11 + .../IDistanceConstraintsBatchImpl.cs | 10 + .../IDistanceConstraintsBatchImpl.cs.meta | 11 + .../IParticleCollisionConstraintsBatchImpl.cs | 10 + ...ticleCollisionConstraintsBatchImpl.cs.meta | 11 + .../IParticleFrictionConstraintsBatchImpl.cs | 10 + ...rticleFrictionConstraintsBatchImpl.cs.meta | 11 + .../Constraints/IPinConstraintsBatchImpl.cs | 10 + .../IPinConstraintsBatchImpl.cs.meta | 11 + .../IShapeMatchingConstraintsBatchImpl.cs | 20 + ...IShapeMatchingConstraintsBatchImpl.cs.meta | 11 + .../Constraints/ISkinConstraintsBatchImpl.cs | 10 + .../ISkinConstraintsBatchImpl.cs.meta | 11 + .../IStitchConstraintsBatchImpl.cs | 10 + .../IStitchConstraintsBatchImpl.cs.meta | 11 + .../IStretchShearConstraintsBatchImpl.cs | 10 + .../IStretchShearConstraintsBatchImpl.cs.meta | 11 + .../ITetherConstraintsBatchImpl.cs | 10 + .../ITetherConstraintsBatchImpl.cs.meta | 11 + .../IVolumeConstraintsBatchImpl.cs | 16 + .../IVolumeConstraintsBatchImpl.cs.meta | 11 + .../Common/Backends/Interface/IObiBackend.cs | 18 + .../Backends/Interface/IObiBackend.cs.meta | 11 + .../Backends/Interface/IObiJobHandle.cs | 8 + .../Backends/Interface/IObiJobHandle.cs.meta | 11 + .../Backends/Interface/JobHandlePool.cs | 40 + .../Backends/Interface/JobHandlePool.cs.meta | 11 + .../Common/Backends/Interface/Rendering.meta | 8 + .../Interface/Rendering/IRenderSystem.cs | 93 + .../Interface/Rendering/IRenderSystem.cs.meta | 11 + .../Common/Backends/Interface/Solver.meta | 8 + .../Backends/Interface/Solver/ISolverImpl.cs | 64 + .../Interface/Solver/ISolverImpl.cs.meta | 11 + .../Obi/Scripts/Common/Backends/Null.meta | 8 + .../Common/Backends/Null/NullBackend.cs | 15 + .../Common/Backends/Null/NullBackend.cs.meta | 11 + .../Common/Backends/Null/NullSolverImpl.cs | 134 + .../Backends/Null/NullSolverImpl.cs.meta | 11 + .../Assets/Obi/Scripts/Common/Blueprints.meta | 8 + .../Common/Blueprints/Constraints.meta | 8 + .../Blueprints/Constraints/Batches.meta | 8 + .../Batches/IStructuralConstraintBatch.cs | 13 + .../IStructuralConstraintBatch.cs.meta | 11 + .../Batches/ObiAerodynamicConstraintsBatch.cs | 107 + .../ObiAerodynamicConstraintsBatch.cs.meta | 11 + .../Batches/ObiBendConstraintsBatch.cs | 128 + .../Batches/ObiBendConstraintsBatch.cs.meta | 11 + .../Batches/ObiBendTwistConstraintsBatch.cs | 129 + .../ObiBendTwistConstraintsBatch.cs.meta | 11 + .../Batches/ObiChainConstraintsBatch.cs | 133 + .../Batches/ObiChainConstraintsBatch.cs.meta | 11 + .../Batches/ObiConstraintsBatch.cs | 212 + .../Batches/ObiConstraintsBatch.cs.meta | 11 + .../Batches/ObiDistanceConstraintsBatch.cs | 148 + .../ObiDistanceConstraintsBatch.cs.meta | 11 + .../Batches/ObiPinConstraintsBatch.cs | 155 + .../Batches/ObiPinConstraintsBatch.cs.meta | 11 + .../ObiShapeMatchingConstraintsBatch.cs | 235 + .../ObiShapeMatchingConstraintsBatch.cs.meta | 11 + .../Batches/ObiSkinConstraintsBatch.cs | 146 + .../Batches/ObiSkinConstraintsBatch.cs.meta | 11 + .../ObiStretchShearConstraintsBatch.cs | 156 + .../ObiStretchShearConstraintsBatch.cs.meta | 11 + .../Batches/ObiTetherConstraintsBatch.cs | 156 + .../Batches/ObiTetherConstraintsBatch.cs.meta | 11 + .../Batches/ObiVolumeConstraintsBatch.cs | 147 + .../Batches/ObiVolumeConstraintsBatch.cs.meta | 11 + .../Common/Blueprints/Constraints/Groups.meta | 8 + .../Groups/ObiAerodynamicConstraintsData.cs | 28 + .../ObiAerodynamicConstraintsData.cs.meta | 11 + .../Groups/ObiBendConstraintsData.cs | 49 + .../Groups/ObiBendConstraintsData.cs.meta | 11 + .../Groups/ObiBendTwistConstraintsData.cs | 28 + .../ObiBendTwistConstraintsData.cs.meta | 11 + .../Groups/ObiChainConstraintsData.cs | 32 + .../Groups/ObiChainConstraintsData.cs.meta | 11 + .../Groups/ObiDistanceConstraintsData.cs | 43 + .../Groups/ObiDistanceConstraintsData.cs.meta | 11 + .../Groups/ObiPinConstraintsData.cs | 16 + .../Groups/ObiPinConstraintsData.cs.meta | 11 + .../Groups/ObiShapeMatchingConstraintsData.cs | 55 + .../ObiShapeMatchingConstraintsData.cs.meta | 11 + .../Groups/ObiSkinConstraintsData.cs | 26 + .../Groups/ObiSkinConstraintsData.cs.meta | 11 + .../Groups/ObiStretchShearConstraintsData.cs | 28 + .../ObiStretchShearConstraintsData.cs.meta | 11 + .../Groups/ObiTetherConstraintsData.cs | 38 + .../Groups/ObiTetherConstraintsData.cs.meta | 11 + .../Groups/ObiVolumeConstraintsData.cs | 37 + .../Groups/ObiVolumeConstraintsData.cs.meta | 11 + .../Blueprints/Constraints/ObiConstraints.cs | 178 + .../Constraints/ObiConstraints.cs.meta | 11 + .../Constraints/StructuralConstraint.cs | 37 + .../Constraints/StructuralConstraint.cs.meta | 11 + .../Common/Blueprints/GraphColoring.cs | 1 + .../Common/Blueprints/GraphColoring.cs.meta | 11 + .../Common/Blueprints/ObiActorBlueprint.cs | 702 + .../Blueprints/ObiActorBlueprint.cs.meta | 11 + .../Blueprints/ObiMeshBasedActorBlueprint.cs | 13 + .../ObiMeshBasedActorBlueprint.cs.meta | 11 + .../Common/Blueprints/ObiParticleGroup.cs | 35 + .../Blueprints/ObiParticleGroup.cs.meta | 11 + .../Assets/Obi/Scripts/Common/Collisions.meta | 9 + .../Common/Collisions/ColliderTrackers.meta | 9 + .../ColliderTrackers/Trackers2D.meta | 9 + .../Trackers2D/ObiBoxShapeTracker2D.cs | 48 + .../Trackers2D/ObiBoxShapeTracker2D.cs.meta | 12 + .../Trackers2D/ObiCapsuleShapeTracker2D.cs | 53 + .../ObiCapsuleShapeTracker2D.cs.meta | 12 + .../Trackers2D/ObiCircleShapeTracker2D.cs | 52 + .../ObiCircleShapeTracker2D.cs.meta | 12 + .../Trackers2D/ObiEdgeShapeTracker2D.cs | 72 + .../Trackers2D/ObiEdgeShapeTracker2D.cs.meta | 12 + .../ColliderTrackers/Trackers3D.meta | 9 + .../Trackers3D/ObiBoxShapeTracker.cs | 51 + .../Trackers3D/ObiBoxShapeTracker.cs.meta | 12 + .../Trackers3D/ObiCapsuleShapeTracker.cs | 49 + .../Trackers3D/ObiCapsuleShapeTracker.cs.meta | 12 + .../ObiCharacterControllerShapeTracker.cs | 52 + ...ObiCharacterControllerShapeTracker.cs.meta | 11 + .../ObiDistanceFieldShapeTracker.cs | 88 + .../ObiDistanceFieldShapeTracker.cs.meta | 12 + .../Trackers3D/ObiMeshShapeTracker.cs | 91 + .../Trackers3D/ObiMeshShapeTracker.cs.meta | 12 + .../Trackers3D/ObiShapeTracker.cs | 20 + .../Trackers3D/ObiShapeTracker.cs.meta | 12 + .../Trackers3D/ObiSphereShapeTracker.cs | 50 + .../Trackers3D/ObiSphereShapeTracker.cs.meta | 12 + .../Trackers3D/ObiTerrainShapeTracker.cs | 75 + .../Trackers3D/ObiTerrainShapeTracker.cs.meta | 12 + .../Scripts/Common/Collisions/ObiCollider.cs | 117 + .../Common/Collisions/ObiCollider.cs.meta | 11 + .../Common/Collisions/ObiCollider2D.cs | 82 + .../Common/Collisions/ObiCollider2D.cs.meta | 12 + .../Common/Collisions/ObiColliderBase.cs | 228 + .../Common/Collisions/ObiColliderBase.cs.meta | 12 + .../Common/Collisions/ObiColliderWorld.cs | 646 + .../Collisions/ObiColliderWorld.cs.meta | 11 + .../Collisions/ObiColliderWorld.cs.orig | 452 + .../Collisions/ObiColliderWorld.cs.orig.meta | 7 + .../Common/Collisions/ObiCollisionMaterial.cs | 80 + .../Collisions/ObiCollisionMaterial.cs.meta | 12 + .../Common/Collisions/ObiDistanceField.cs | 129 + .../Collisions/ObiDistanceField.cs.meta | 12 + .../Collisions/ObiDistanceFieldContainer.cs | 103 + .../ObiDistanceFieldContainer.cs.meta | 11 + .../Common/Collisions/ObiEdgeMeshContainer.cs | 163 + .../Collisions/ObiEdgeMeshContainer.cs.meta | 11 + .../Collisions/ObiHeightFieldContainer.cs | 114 + .../ObiHeightFieldContainer.cs.meta | 11 + .../Scripts/Common/Collisions/ObiRigidbody.cs | 101 + .../Common/Collisions/ObiRigidbody.cs.meta | 12 + .../Common/Collisions/ObiRigidbody2D.cs | 98 + .../Common/Collisions/ObiRigidbody2D.cs.meta | 12 + .../Common/Collisions/ObiRigidbodyBase.cs | 55 + .../Collisions/ObiRigidbodyBase.cs.meta | 12 + .../Collisions/ObiTriangleMeshContainer.cs | 171 + .../ObiTriangleMeshContainer.cs.meta | 11 + .../Obi/Scripts/Common/DataStructures.meta | 8 + .../Scripts/Common/DataStructures/ASDF.meta | 8 + .../Common/DataStructures/ASDF/ASDF.cs | 187 + .../Common/DataStructures/ASDF/ASDF.cs.meta | 11 + .../Common/DataStructures/ASDF/DFNode.cs | 66 + .../Common/DataStructures/ASDF/DFNode.cs.meta | 11 + .../Obi/Scripts/Common/DataStructures/Aabb.cs | 53 + .../Common/DataStructures/Aabb.cs.meta | 11 + .../Common/DataStructures/AffineTransform.cs | 65 + .../DataStructures/AffineTransform.cs.meta | 11 + .../Scripts/Common/DataStructures/BVH.meta | 8 + .../Scripts/Common/DataStructures/BVH/BIH.cs | 262 + .../Common/DataStructures/BVH/BIH.cs.meta | 11 + .../Common/DataStructures/BVH/BIHNode.cs | 25 + .../Common/DataStructures/BVH/BIHNode.cs.meta | 11 + .../Common/DataStructures/BVH/IBounded.cs | 10 + .../DataStructures/BVH/IBounded.cs.meta | 11 + .../Scripts/Common/DataStructures/CellSpan.cs | 17 + .../Common/DataStructures/CellSpan.cs.meta | 11 + .../DataStructures/ColliderRigidbody.cs | 68 + .../DataStructures/ColliderRigidbody.cs.meta | 11 + .../Common/DataStructures/ColliderShape.cs | 55 + .../DataStructures/ColliderShape.cs.meta | 11 + .../DataStructures/CollisionMaterial.cs | 35 + .../DataStructures/CollisionMaterial.cs.meta | 11 + .../DataStructures/ContactEffectiveMasses.cs | 93 + .../ContactEffectiveMasses.cs.meta | 11 + .../Common/DataStructures/EmitPoint.cs | 40 + .../Common/DataStructures/EmitPoint.cs.meta | 11 + .../DataStructures/EmittedParticleData.cs | 15 + .../EmittedParticleData.cs.meta | 11 + .../Common/DataStructures/ForceZone.cs | 40 + .../Common/DataStructures/ForceZone.cs.meta | 11 + .../Common/DataStructures/InertialFrame.cs | 56 + .../DataStructures/InertialFrame.cs.meta | 11 + .../Common/DataStructures/NativeList.meta | 8 + .../NativeList/ObiNativeAabbList.cs | 18 + .../NativeList/ObiNativeAabbList.cs.meta | 11 + .../ObiNativeAffineTransformList.cs | 18 + .../ObiNativeAffineTransformList.cs.meta | 11 + .../NativeList/ObiNativeBIHNodeList.cs | 17 + .../NativeList/ObiNativeBIHNodeList.cs.meta | 11 + .../NativeList/ObiNativeBoneWeightList.cs | 18 + .../ObiNativeBoneWeightList.cs.meta | 11 + .../NativeList/ObiNativeByteList.cs | 18 + .../NativeList/ObiNativeByteList.cs.meta | 11 + .../NativeList/ObiNativeCellSpanList.cs | 18 + .../NativeList/ObiNativeCellSpanList.cs.meta | 11 + .../NativeList/ObiNativeColliderShapeList.cs | 18 + .../ObiNativeColliderShapeList.cs.meta | 11 + .../ObiNativeCollisionMaterialList.cs | 18 + .../ObiNativeCollisionMaterialList.cs.meta | 11 + .../NativeList/ObiNativeColorList.cs | 17 + .../NativeList/ObiNativeColorList.cs.meta | 11 + .../NativeList/ObiNativeContactList.cs | 17 + .../NativeList/ObiNativeContactList.cs.meta | 11 + .../NativeList/ObiNativeDFNodeList.cs | 18 + .../NativeList/ObiNativeDFNodeList.cs.meta | 11 + .../ObiNativeDistanceFieldHeaderList.cs | 17 + .../ObiNativeDistanceFieldHeaderList.cs.meta | 11 + .../NativeList/ObiNativeEdgeList.cs | 17 + .../NativeList/ObiNativeEdgeList.cs.meta | 11 + .../NativeList/ObiNativeEdgeMeshHeaderList.cs | 17 + .../ObiNativeEdgeMeshHeaderList.cs.meta | 11 + .../ObiNativeEffectiveMassesList.cs | 17 + .../ObiNativeEffectiveMassesList.cs.meta | 11 + .../NativeList/ObiNativeEmitPointList.cs | 17 + .../NativeList/ObiNativeEmitPointList.cs.meta | 11 + .../NativeList/ObiNativeFloatList.cs | 18 + .../NativeList/ObiNativeFloatList.cs.meta | 11 + .../NativeList/ObiNativeForceZoneList.cs | 18 + .../NativeList/ObiNativeForceZoneList.cs.meta | 11 + .../ObiNativeHeightFieldHeaderList.cs | 18 + .../ObiNativeHeightFieldHeaderList.cs.meta | 11 + .../NativeList/ObiNativeInt4List.cs | 22 + .../NativeList/ObiNativeInt4List.cs.meta | 11 + .../NativeList/ObiNativeIntList.cs | 17 + .../NativeList/ObiNativeIntList.cs.meta | 11 + .../NativeList/ObiNativeIntPtrList.cs | 16 + .../NativeList/ObiNativeIntPtrList.cs.meta | 11 + .../NativeList/ObiNativeList.cs | 700 + .../NativeList/ObiNativeList.cs.meta | 11 + .../NativeList/ObiNativeMatrix4x4List.cs | 23 + .../NativeList/ObiNativeMatrix4x4List.cs.meta | 11 + .../NativeList/ObiNativeQuaternionList.cs | 24 + .../ObiNativeQuaternionList.cs.meta | 11 + .../NativeList/ObiNativeQueryResultList.cs | 17 + .../ObiNativeQueryResultList.cs.meta | 11 + .../NativeList/ObiNativeQueryShapeList.cs | 17 + .../ObiNativeQueryShapeList.cs.meta | 11 + .../NativeList/ObiNativeRigidbodyList.cs | 18 + .../NativeList/ObiNativeRigidbodyList.cs.meta | 11 + .../NativeList/ObiNativeTriangleList.cs | 18 + .../NativeList/ObiNativeTriangleList.cs.meta | 11 + .../ObiNativeTriangleMeshHeaderList.cs | 18 + .../ObiNativeTriangleMeshHeaderList.cs.meta | 11 + .../NativeList/ObiNativeUIntList.cs | 18 + .../NativeList/ObiNativeUIntList.cs.meta | 11 + .../NativeList/ObiNativeVector2List.cs | 18 + .../NativeList/ObiNativeVector2List.cs.meta | 11 + .../NativeList/ObiNativeVector3List.cs | 18 + .../NativeList/ObiNativeVector3List.cs.meta | 11 + .../NativeList/ObiNativeVector4List.cs | 36 + .../NativeList/ObiNativeVector4List.cs.meta | 11 + .../Scripts/Common/DataStructures/ObiList.cs | 165 + .../Common/DataStructures/ObiList.cs.meta | 12 + .../Common/DataStructures/ParticlePair.cs | 24 + .../DataStructures/ParticlePair.cs.meta | 11 + .../Common/DataStructures/Queries.meta | 8 + .../DataStructures/Queries/QueryResult.cs | 17 + .../Queries/QueryResult.cs.meta | 11 + .../DataStructures/Queries/QueryShape.cs | 36 + .../DataStructures/Queries/QueryShape.cs.meta | 11 + .../Common/DataStructures/RegularGrid.meta | 8 + .../DataStructures/RegularGrid/RegularGrid.cs | 106 + .../RegularGrid/RegularGrid.cs.meta | 11 + .../Common/DataStructures/SimplexCounts.cs | 46 + .../DataStructures/SimplexCounts.cs.meta | 11 + .../Scripts/Common/DataStructures/VInt4.cs | 41 + .../Common/DataStructures/VInt4.cs.meta | 11 + .../Common/DataStructures/Voxelization.meta | 8 + .../Voxelization/MeshVoxelizer.cs | 607 + .../Voxelization/MeshVoxelizer.cs.meta | 12 + .../Voxelization/PriorityQueue.cs | 101 + .../Voxelization/PriorityQueue.cs.meta | 11 + .../Voxelization/VoxelDistanceField.cs | 190 + .../Voxelization/VoxelDistanceField.cs.meta | 11 + .../Voxelization/VoxelPathFinder.cs | 135 + .../Voxelization/VoxelPathFinder.cs.meta | 11 + .../Obi/Scripts/Common/ObiEditorSettings.cs | 94 + .../Scripts/Common/ObiEditorSettings.cs.meta | 11 + .../Assets/Obi/Scripts/Common/Rendering.meta | 8 + .../Scripts/Common/Rendering/DataBatches.meta | 8 + .../Rendering/DataBatches/MeshDataBatch.cs | 316 + .../DataBatches/MeshDataBatch.cs.meta | 11 + .../DataBatches/SkeletonDataBatch.cs | 117 + .../DataBatches/SkeletonDataBatch.cs.meta | 11 + .../Common/Rendering/ISurfaceChunkUser.cs | 10 + .../Rendering/ISurfaceChunkUser.cs.meta | 11 + .../Common/Rendering/ObiActorRenderer.cs | 48 + .../Common/Rendering/ObiActorRenderer.cs.meta | 11 + .../Rendering/ObiDistanceFieldRenderer.cs | 166 + .../ObiDistanceFieldRenderer.cs.meta | 12 + .../Common/Rendering/ObiFoamRenderSystem.cs | 96 + .../Rendering/ObiFoamRenderSystem.cs.meta | 11 + .../ObiInstancedParticleRenderSystem.cs | 151 + .../ObiInstancedParticleRenderSystem.cs.meta | 11 + .../Rendering/ObiInstancedParticleRenderer.cs | 63 + .../ObiInstancedParticleRenderer.cs.meta | 13 + .../Rendering/ObiParticleRenderSystem.cs | 145 + .../Rendering/ObiParticleRenderSystem.cs.meta | 11 + .../Common/Rendering/ObiParticleRenderer.cs | 78 + .../Rendering/ObiParticleRenderer.cs.meta | 12 + .../Scripts/Common/Rendering/ObiRenderer.cs | 63 + .../Common/Rendering/ObiRenderer.cs.meta | 11 + .../Rendering/ParticleImpostorRendering.cs | 164 + .../ParticleImpostorRendering.cs.meta | 11 + .../Common/Rendering/RenderBatches.meta | 8 + .../RenderBatches/DynamicRenderBatch.cs | 368 + .../RenderBatches/DynamicRenderBatch.cs.meta | 11 + .../Rendering/RenderBatches/IRenderBatch.cs | 77 + .../RenderBatches/IRenderBatch.cs.meta | 11 + .../RenderBatches/InstanceRenderBatch.cs | 141 + .../RenderBatches/InstanceRenderBatch.cs.meta | 11 + .../RenderBatches/ProceduralRenderBatch.cs | 180 + .../ProceduralRenderBatch.cs.meta | 11 + .../Assets/Obi/Scripts/Common/Solver.meta | 9 + .../Solver/ObiActorEditorSelectionHandler.cs | 225 + .../ObiActorEditorSelectionHandler.cs.meta | 11 + .../Common/Solver/ObiRenderSystemStack.cs | 92 + .../Solver/ObiRenderSystemStack.cs.meta | 11 + .../Obi/Scripts/Common/Solver/ObiSolver.cs | 2425 + .../Scripts/Common/Solver/ObiSolver.cs.meta | 11 + xiaofang/Assets/Obi/Scripts/Common/Utils.meta | 9 + .../Obi/Scripts/Common/Utils/Attributes.meta | 9 + .../Common/Utils/Attributes/ChildrenOnly.cs | 45 + .../Utils/Attributes/ChildrenOnly.cs.meta | 12 + .../Common/Utils/Attributes/DisplayAs.cs | 26 + .../Common/Utils/Attributes/DisplayAs.cs.meta | 12 + .../Scripts/Common/Utils/Attributes/Indent.cs | 25 + .../Common/Utils/Attributes/Indent.cs.meta | 12 + .../Attributes/InspectorButtonAttribute.cs | 56 + .../InspectorButtonAttribute.cs.meta | 12 + .../Common/Utils/Attributes/LayerField.cs | 21 + .../Utils/Attributes/LayerField.cs.meta | 11 + .../Utils/Attributes/MinMaxAttribute.cs | 41 + .../Utils/Attributes/MinMaxAttribute.cs.meta | 11 + .../Common/Utils/Attributes/MultiDelayed.cs | 29 + .../Utils/Attributes/MultiDelayed.cs.meta | 12 + .../Attributes/MultiPropertyAttribute.cs | 97 + .../Attributes/MultiPropertyAttribute.cs.meta | 12 + .../Common/Utils/Attributes/MultiRange.cs | 34 + .../Utils/Attributes/MultiRange.cs.meta | 12 + .../Utils/Attributes/SerializeProperty.cs | 168 + .../Attributes/SerializeProperty.cs.meta | 12 + .../Common/Utils/Attributes/VisibleIf.cs | 63 + .../Common/Utils/Attributes/VisibleIf.cs.meta | 12 + .../Obi/Scripts/Common/Utils/Coroutines.meta | 9 + .../Common/Utils/Coroutines/CoroutineJob.cs | 130 + .../Utils/Coroutines/CoroutineJob.cs.meta | 12 + .../Utils/Coroutines/EditorCoroutine.cs | 36 + .../Utils/Coroutines/EditorCoroutine.cs.meta | 12 + .../Obi/Scripts/Common/Utils/Forces.meta | 9 + .../Common/Utils/Forces/ObiForceZone.cs | 128 + .../Common/Utils/Forces/ObiForceZone.cs.meta | 11 + .../Common/Utils/ObiContactEventDispatcher.cs | 154 + .../Utils/ObiContactEventDispatcher.cs.meta | 11 + .../Scripts/Common/Utils/ObiContactGrabber.cs | 178 + .../Common/Utils/ObiContactGrabber.cs.meta | 11 + .../Scripts/Common/Utils/ObiFoamGenerator.cs | 98 + .../Common/Utils/ObiFoamGenerator.cs.meta | 11 + .../Scripts/Common/Utils/ObiIntegration.cs | 50 + .../Common/Utils/ObiIntegration.cs.meta | 11 + .../Common/Utils/ObiParticleAttachment.cs | 64 + .../Utils/ObiParticleAttachment.cs.meta | 11 + .../Common/Utils/ObiParticleDragger.cs | 84 + .../Common/Utils/ObiParticleDragger.cs.meta | 11 + .../Scripts/Common/Utils/ObiParticlePicker.cs | 140 + .../Common/Utils/ObiParticlePicker.cs.meta | 11 + .../Obi/Scripts/Common/Utils/ObiStitcher.cs | 232 + .../Scripts/Common/Utils/ObiStitcher.cs.meta | 12 + .../Obi/Scripts/Common/Utils/ObiUtils.cs | 83 + .../Obi/Scripts/Common/Utils/ObiUtils.cs.meta | 12 + .../Obi/Scripts/Common/Utils/ObiVectorMath.cs | 48 + .../Common/Utils/ObiVectorMath.cs.meta | 11 + .../Obi/Scripts/Common/Utils/SetCategory.cs | 38 + .../Scripts/Common/Utils/SetCategory.cs.meta | 11 + xiaofang/Assets/Obi/Scripts/Obi.asmdef | 42 + xiaofang/Assets/Obi/Scripts/Obi.asmdef.meta | 7 + xiaofang/Assets/Obi/Scripts/Oni.cs | 248 + xiaofang/Assets/Obi/Scripts/Oni.cs.meta | 12 + xiaofang/Assets/Obi/Scripts/RopeAndRod.meta | 10 + .../Assets/Obi/Scripts/RopeAndRod/Actors.meta | 8 + .../Obi/Scripts/RopeAndRod/Actors/ObiBone.cs | 690 + .../Scripts/RopeAndRod/Actors/ObiBone.cs.meta | 11 + .../Obi/Scripts/RopeAndRod/Actors/ObiRod.cs | 265 + .../Scripts/RopeAndRod/Actors/ObiRod.cs.meta | 11 + .../Obi/Scripts/RopeAndRod/Actors/ObiRope.cs | 468 + .../Scripts/RopeAndRod/Actors/ObiRope.cs.meta | 11 + .../Scripts/RopeAndRod/Actors/ObiRopeBase.cs | 163 + .../RopeAndRod/Actors/ObiRopeBase.cs.meta | 11 + .../RopeAndRod/Actors/ObiRopeCursor.cs | 284 + .../RopeAndRod/Actors/ObiRopeCursor.cs.meta | 11 + .../Obi/Scripts/RopeAndRod/Blueprints.meta | 8 + .../RopeAndRod/Blueprints/ObiBoneBlueprint.cs | 348 + .../Blueprints/ObiBoneBlueprint.cs.meta | 11 + .../RopeAndRod/Blueprints/ObiRodBlueprint.cs | 288 + .../Blueprints/ObiRodBlueprint.cs.meta | 11 + .../RopeAndRod/Blueprints/ObiRopeBlueprint.cs | 236 + .../Blueprints/ObiRopeBlueprint.cs.meta | 11 + .../Blueprints/ObiRopeBlueprintBase.cs | 109 + .../Blueprints/ObiRopeBlueprintBase.cs.meta | 11 + .../Scripts/RopeAndRod/DataStructures.meta | 8 + .../DataStructures/ObiRopeSection.cs | 52 + .../DataStructures/ObiRopeSection.cs.meta | 13 + .../DataStructures/ObiStructuralElement.cs | 16 + .../ObiStructuralElement.cs.meta | 11 + .../RopeAndRod/DataStructures/Path.meta | 8 + .../DataStructures/Path/DataChannels.meta | 8 + .../Path/DataChannels/ObiColorDataChannel.cs | 12 + .../DataChannels/ObiColorDataChannel.cs.meta | 11 + .../Path/DataChannels/ObiFilterDataChannel.cs | 10 + .../DataChannels/ObiFilterDataChannel.cs.meta | 11 + .../Path/DataChannels/ObiMassDataChannel.cs | 12 + .../DataChannels/ObiMassDataChannel.cs.meta | 11 + .../Path/DataChannels/ObiNormalDataChannel.cs | 12 + .../DataChannels/ObiNormalDataChannel.cs.meta | 11 + .../Path/DataChannels/ObiPathDataChannel.cs | 88 + .../DataChannels/ObiPathDataChannel.cs.meta | 11 + .../ObiPathDataChannelIdentity.cs | 94 + .../ObiPathDataChannelIdentity.cs.meta | 11 + .../Path/DataChannels/ObiPointsDataChannel.cs | 124 + .../DataChannels/ObiPointsDataChannel.cs.meta | 11 + .../ObiRotationalMassDataChannel.cs | 12 + .../ObiRotationalMassDataChannel.cs.meta | 11 + .../DataChannels/ObiThicknessDataChannel.cs | 12 + .../ObiThicknessDataChannel.cs.meta | 11 + .../DataStructures/Path/Interpolators.meta | 8 + .../ObiCatmullRomInterpolator.cs | 49 + .../ObiCatmullRomInterpolator.cs.meta | 11 + .../ObiCatmullRomInterpolator3D.cs | 46 + .../ObiCatmullRomInterpolator3D.cs.meta | 11 + .../Interpolators/ObiColorInterpolator3D.cs | 49 + .../ObiColorInterpolator3D.cs.meta | 11 + .../Interpolators/ObiConstantInterpolator.cs | 33 + .../ObiConstantInterpolator.cs.meta | 11 + .../Path/Interpolators/ObiInterpolator.cs | 13 + .../Interpolators/ObiInterpolator.cs.meta | 11 + .../RopeAndRod/DataStructures/Path/ObiPath.cs | 408 + .../DataStructures/Path/ObiPath.cs.meta | 11 + .../DataStructures/Path/ObiPathFrame.cs | 170 + .../DataStructures/Path/ObiPathFrame.cs.meta | 11 + .../DataStructures/Path/ObiPathSmoother.cs | 101 + .../Path/ObiPathSmoother.cs.meta | 11 + .../DataStructures/Path/ObiWingedPoint.cs | 100 + .../Path/ObiWingedPoint.cs.meta | 11 + .../Obi/Scripts/RopeAndRod/Rendering.meta | 8 + .../Rendering/ObiChainRopeRenderSystem.cs | 216 + .../ObiChainRopeRenderSystem.cs.meta | 11 + .../Rendering/ObiExtrudedRopeRenderSystem.cs | 278 + .../ObiExtrudedRopeRenderSystem.cs.meta | 11 + .../Rendering/ObiLineRopeRenderSystem.cs | 230 + .../Rendering/ObiLineRopeRenderSystem.cs.meta | 11 + .../Rendering/ObiMeshRopeRenderSystem.cs | 296 + .../Rendering/ObiMeshRopeRenderSystem.cs.meta | 11 + .../Rendering/ObiPathSmootherRenderSystem.cs | 325 + .../ObiPathSmootherRenderSystem.cs.meta | 11 + .../Rendering/ObiRopeChainRenderer.cs | 79 + .../Rendering/ObiRopeChainRenderer.cs.meta | 11 + .../Rendering/ObiRopeExtrudedRenderer.cs | 74 + .../Rendering/ObiRopeExtrudedRenderer.cs.meta | 13 + .../Rendering/ObiRopeLineRenderer.cs | 68 + .../Rendering/ObiRopeLineRenderer.cs.meta | 11 + .../Rendering/ObiRopeMeshRenderer.cs | 86 + .../Rendering/ObiRopeMeshRenderer.cs.meta | 11 + .../Assets/Obi/Scripts/RopeAndRod/Utils.meta | 8 + .../Scripts/RopeAndRod/Utils/ObiRopeAttach.cs | 23 + .../RopeAndRod/Utils/ObiRopeAttach.cs.meta | 11 + .../RopeAndRod/Utils/ObiRopePrefabPlugger.cs | 108 + .../Utils/ObiRopePrefabPlugger.cs.meta | 11 + .../Scripts/RopeAndRod/Utils/ObiRopeReel.cs | 62 + .../RopeAndRod/Utils/ObiRopeReel.cs.meta | 11 + xiaofang/Assets/ObiEditorSettings.asset | 49 + xiaofang/Assets/ObiEditorSettings.asset.meta | 8 + xiaofang/Assets/ProtoBuf/ProtoBuffer.cs | 107 +- xiaofang/Assets/UnityCommon | 2 +- xiaofang/Packages/manifest.json | 50 + xiaofang/Packages/packages-lock.json | 425 + xiaofang/ProjectSettings/AudioManager.asset | 20 + .../AutoStreamingSettings.asset | 21 + .../ProjectSettings/ClusterInputManager.asset | 6 + .../ProjectSettings/DynamicsManager.asset | 38 + .../ProjectSettings/EditorBuildSettings.asset | 8 + xiaofang/ProjectSettings/EditorSettings.asset | 44 + .../ProjectSettings/GraphicsSettings.asset | 68 + xiaofang/ProjectSettings/InputManager.asset | 488 + xiaofang/ProjectSettings/MemorySettings.asset | 35 + xiaofang/ProjectSettings/NavMeshAreas.asset | 93 + .../PackageManagerSettings.asset | 36 + .../ProjectSettings/Physics2DSettings.asset | 56 + xiaofang/ProjectSettings/PresetManager.asset | 7 + .../ProjectSettings/ProjectSettings.asset | 756 + xiaofang/ProjectSettings/ProjectVersion.txt | 2 + .../ProjectSettings/QualitySettings.asset | 248 + .../SceneTemplateSettings.json | 121 + .../ProjectSettings/ShaderGraphSettings.asset | 16 + xiaofang/ProjectSettings/TagManager.asset | 43 + xiaofang/ProjectSettings/TimeManager.asset | 9 + .../UnityConnectSettings.asset | 38 + xiaofang/ProjectSettings/VFXManager.asset | 16 + .../VersionControlSettings.asset | 8 + xiaofang/ProjectSettings/boot.config | 0 .../UserSettings/EditorUserSettings.asset | 56 + xiaofang/UserSettings/Search.settings | 1 + 1918 files changed, 319686 insertions(+), 12 deletions(-) create mode 100644 xiaofang/Assets/Obi.meta create mode 100644 xiaofang/Assets/Obi/CHANGELOG_rope.txt create mode 100644 xiaofang/Assets/Obi/CHANGELOG_rope.txt.meta create mode 100644 xiaofang/Assets/Obi/Editor.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiBlueprintEditorTool.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiBlueprintEditorTool.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPaintBrushEditorTool.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPaintBrushEditorTool.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiParticleSelectionEditorTool.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiParticleSelectionEditorTool.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPropertyTextureEditorTool.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPropertyTextureEditorTool.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiTethersTool.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiTethersTool.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/IObiBrushMode.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/IObiBrushMode.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorPaintBrushMode.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorPaintBrushMode.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorSmoothBrushMode.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorSmoothBrushMode.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatAddBrushMode.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatAddBrushMode.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatCopyBrushMode.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatCopyBrushMode.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatPaintBrushMode.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatPaintBrushMode.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatSmoothBrushMode.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatSmoothBrushMode.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiIntPaintBrushMode.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiIntPaintBrushMode.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiMasterSlavePaintBrushMode.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiMasterSlavePaintBrushMode.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiSelectBrushMode.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiSelectBrushMode.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushBase.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushBase.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushMirrorSettings.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushMirrorSettings.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiRaycastBrush.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiRaycastBrush.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiScreenSpaceBrush.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiScreenSpaceBrush.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditorStage.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditorStage.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshBasedActorBlueprintEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshBasedActorBlueprintEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshUtils.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshUtils.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiParticleEditorDrawing.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiParticleEditorDrawing.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintBoolProperty.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintBoolProperty.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintColorProperty.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintColorProperty.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintFloatProperty.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintFloatProperty.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintIntProperty.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintIntProperty.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintMaskProperty.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintMaskProperty.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintProperty.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintProperty.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/IObiPropertyEditableProvider.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/IObiPropertyEditableProvider.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintColor.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintColor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterCategory.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterCategory.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterMask.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterMask.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintMass.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintMass.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintRadius.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintRadius.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintSelected.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintSelected.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderMode.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderMode.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeAerodynamicConstraints.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeAerodynamicConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeBendConstraints.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeBendConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeDistanceConstraints.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeDistanceConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeMesh.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeMesh.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeParticles.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeParticles.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeShapeMatchingConstraints.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeShapeMatchingConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeTetherConstraints.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeTetherConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Collisions.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Collisions/ObiColliderEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Collisions/ObiColliderEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Collisions/ObiDistanceFieldEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Collisions/ObiDistanceFieldEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Collisions/ObiForceZoneEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Collisions/ObiForceZoneEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Constraints.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Constraints/ObiConstraintParametersDrawer.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Constraints/ObiConstraintParametersDrawer.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/ObiAboutWindow.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/ObiAboutWindow.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/ObiSettingsProvider.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/ObiSettingsProvider.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Rendering.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Rendering/ObiParticleRendererEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Rendering/ObiParticleRendererEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Solver.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Solver/ObiSolverEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Solver/ObiSolverEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils/BooleanPreference.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils/BooleanPreference.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils/ObiEditorUtils.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils/ObiEditorUtils.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils/ObiFoamGeneratorEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils/ObiFoamGeneratorEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils/ObiParticleAttachmentEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils/ObiParticleAttachmentEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils/ObiRaycastHit.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils/ObiRaycastHit.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils/PreviewHelpers.cs create mode 100644 xiaofang/Assets/Obi/Editor/Common/Utils/PreviewHelpers.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Obi.Editor.asmdef create mode 100644 xiaofang/Assets/Obi/Editor/Obi.Editor.asmdef.meta create mode 100644 xiaofang/Assets/Obi/Editor/ObiParticleSelection.cs create mode 100644 xiaofang/Assets/Obi/Editor/ObiParticleSelection.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/ObiStitcherEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/ObiStitcherEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/AddControlPoint.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/AddControlPoint.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/AddIcon.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/AddIcon.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/AddTetherButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/AddTetherButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/BackfacesButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/BackfacesButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/BranchButton.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/BranchButton.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/BrushHandle.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/BrushHandle.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/BrushIcon.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/BrushIcon.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/ClearButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/ClearButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/ClearTethersButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/ClearTethersButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.mat create mode 100644 xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.mat.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.shader create mode 100644 xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.shader.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditCurves.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditCurves.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditParticles.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditParticles.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditorLineShader.shader create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditorLineShader.shader.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditorLines.mat create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditorLines.mat.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditorParticle.mat create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditorParticle.mat.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditorParticle.shader create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditorParticle.shader.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditorParticleShader.shader create mode 100644 xiaofang/Assets/Obi/Editor/Resources/EditorParticleShader.shader.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/FillButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/FillButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/FrontfacesButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/FrontfacesButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/GaussianButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/GaussianButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/HandleButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/HandleButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiActorBlueprint Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiActorBlueprint Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiAerodynamicConstraints Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiAerodynamicConstraints Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendConstraints Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendConstraints Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendTwistConstraints Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendTwistConstraints Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBone Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBone Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiChainConstraints Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiChainConstraints Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCloth Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCloth Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiClothRenderer Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiClothRenderer Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollider Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollider Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollider2D Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollider2D Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollisionMaterial Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollisionMaterial Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCurve Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCurve Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceConstraints Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceConstraints Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceField Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceField Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceFieldRenderer Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceFieldRenderer Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitter Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitter Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterMaterialFluid Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterMaterialFluid Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterMaterialGranular Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterMaterialGranular Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeCube Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeCube Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeDisk Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeDisk Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeEdge Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeEdge Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeMesh Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeMesh Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeSphere Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeSphere Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeSquare Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeSquare Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiFluidRenderer Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiFluidRenderer Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiFoamGenerator Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiFoamGenerator Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiForceZone Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiForceZone Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiMeshTopology Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiMeshTopology Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleHandle Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleHandle Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticlePicker Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticlePicker Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleRenderer Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleRenderer Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPathSmoother Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPathSmoother Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPinConstraints Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPinConstraints Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPlant Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPlant Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiProfiler Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiProfiler Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRigidbody Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRigidbody Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRigidbody2D Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRigidbody2D Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRod Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRod Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRope Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRope Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeChainRenderer Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeChainRenderer Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeCursor Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeCursor Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeExtrudedRenderer Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeExtrudedRenderer Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeLineRenderer Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeLineRenderer Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeMeshRenderer Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeMeshRenderer Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeSection Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeSection Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiShapeMatchingConstraints Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiShapeMatchingConstraints Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinConstraints Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinConstraints Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinnedCloth Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinnedCloth Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinnedClothRenderer Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinnedClothRenderer Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSoftbody Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSoftbody Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSoftbodySkinner Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSoftbodySkinner Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSolver Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSolver Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiStitcher Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiStitcher Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiStretchShearConstraints Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiStretchShearConstraints Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiTearableCloth Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiTearableCloth Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiTearableClothRenderer Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiTearableClothRenderer Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiTetherConstraints Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiTetherConstraints Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVoidZone Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVoidZone Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVolumeConstraints Icon.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVolumeConstraints Icon.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/InvertButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/InvertButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/LeafButton.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/LeafButton.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/MaskButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/MaskButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/OpenCloseCurve.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/OpenCloseCurve.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/OptimizeButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/OptimizeButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/OrientControlPoint.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/OrientControlPoint.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PaddingMaterial.mat create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PaddingMaterial.mat.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PaddingShader.shader create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PaddingShader.shader.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PauseButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PauseButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PencilButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PencilButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PinButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PinButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PinTranslation.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PinTranslation.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PlayButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PlayButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PropertyGradientMaterial.mat create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PropertyGradientMaterial.mat.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PropertyGradientMaterial.shader create mode 100644 xiaofang/Assets/Obi/Editor/Resources/PropertyGradientMaterial.shader.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RadiusIndicator.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RadiusIndicator.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RecButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RecButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RemoveButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RemoveButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RemoveControlPoint.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RemoveControlPoint.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RemoveIcon.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RemoveIcon.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RestoreButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RestoreButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RewindButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RewindButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RotateControlPoint.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/RotateControlPoint.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/ScaleControlPoint.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/ScaleControlPoint.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/SelectIcon.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/SelectIcon.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/SelectedWorld_bck.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/SelectedWorld_bck.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/SeparatorLine.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/SeparatorLine.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/ShowTangentHandles.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/ShowTangentHandles.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/ShowThicknessHandles.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/ShowThicknessHandles.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/SmoothButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/SmoothButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/StepButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/StepButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/StopButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/StopButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/StopRecButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/StopRecButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/TextureIcon.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/TextureIcon.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/ToggleableGroupBg.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/ToggleableGroupBg.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/TopologyBorders.shader create mode 100644 xiaofang/Assets/Obi/Editor/Resources/TopologyBorders.shader.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/TopologyPreview.mat create mode 100644 xiaofang/Assets/Obi/Editor/Resources/TopologyPreview.mat.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/TopologyPreviewBorder.mat create mode 100644 xiaofang/Assets/Obi/Editor/Resources/TopologyPreviewBorder.mat.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/TranslateControlPoint.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/TranslateControlPoint.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/TrunkButton.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/TrunkButton.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/UVSpaceColor.shader create mode 100644 xiaofang/Assets/Obi/Editor/Resources/UVSpaceColor.shader.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/UVSpaceColorMaterial.mat create mode 100644 xiaofang/Assets/Obi/Editor/Resources/UVSpaceColorMaterial.mat.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/UnpinButton.psd create mode 100644 xiaofang/Assets/Obi/Editor/Resources/UnpinButton.psd.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.mat create mode 100644 xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.mat.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.shader create mode 100644 xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.shader.meta create mode 100644 xiaofang/Assets/Obi/Editor/Resources/obi_editor_logo.png create mode 100644 xiaofang/Assets/Obi/Editor/Resources/obi_editor_logo.png.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/Blueprints.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/Blueprints/ObiRopeBaseBlueprintEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/Blueprints/ObiRopeBaseBlueprintEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/BonePropertyCurveDrawer.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/BonePropertyCurveDrawer.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/IgnoredBoneDrawer.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/IgnoredBoneDrawer.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiBoneEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiBoneEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiDraggableIcon.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiDraggableIcon.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathHandles.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathHandles.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathSmootherEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathSmootherEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRodEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRodEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeChainRendererEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeChainRendererEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeCursorEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeCursorEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeExtrudedRendererEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeExtrudedRendererEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeLineRendererEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeLineRendererEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeMeshRendererEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeMeshRendererEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeSectionEditor.cs create mode 100644 xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeSectionEditor.cs.meta create mode 100644 xiaofang/Assets/Obi/QuickstartGuide_rope.pdf create mode 100644 xiaofang/Assets/Obi/QuickstartGuide_rope.pdf.meta create mode 100644 xiaofang/Assets/Obi/README.rtf create mode 100644 xiaofang/Assets/Obi/README.rtf.meta create mode 100644 xiaofang/Assets/Obi/Resources.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/AerodynamicConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/AerodynamicConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/AtomicDeltas.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/AtomicDeltas.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/BendConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/BendConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/BendTwistConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/BendTwistConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/BitonicSort.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/BitonicSort.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Bounds.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Bounds.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/BoundsReduction.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/BoundsReduction.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/BoxShape.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/BoxShape.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/BoxShapeQuery.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/BoxShapeQuery.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/CapsuleShape.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/CapsuleShape.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ChainConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ChainConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ClothRendering.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ClothRendering.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ColliderCollisionConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ColliderCollisionConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ColliderDefinitions.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ColliderDefinitions.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ColliderFrictionConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ColliderFrictionConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ColliderGrid.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ColliderGrid.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/CollisionMaterial.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/CollisionMaterial.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ContactHandling.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ContactHandling.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/DeformableTriangles.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/DeformableTriangles.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/DensityConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/DensityConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/DistanceConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/DistanceConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/DistanceFieldShape.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/DistanceFieldShape.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/EdgeMeshShape.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/EdgeMeshShape.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/FluidChunkDefs.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/FluidChunkDefs.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/FluidFoam.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/FluidFoam.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/FluidFoamDensity.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/FluidFoamDensity.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/FluidKernels.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/FluidKernels.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/FluidMeshChunks.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/FluidMeshChunks.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/FluidSurfaceMeshBuilding.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/FluidSurfaceMeshBuilding.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/GridUtils.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/GridUtils.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/HeightfieldShape.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/HeightfieldShape.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/InertialFrame.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/InertialFrame.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/InstancedParticleRendering.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/InstancedParticleRendering.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Integration.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Integration.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/InterlockedUtils.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/InterlockedUtils.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/MathUtils.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/MathUtils.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Matrix.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Matrix.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/NormalCompression.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/NormalCompression.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Optimization.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Optimization.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ParticleCollisionConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ParticleCollisionConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ParticleFrictionConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ParticleFrictionConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ParticleGrid.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ParticleGrid.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ParticleMeshBuilding.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ParticleMeshBuilding.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/PathFrame.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/PathFrame.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/PathSmoothing.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/PathSmoothing.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Phases.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Phases.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/PinConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/PinConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Quaternion.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Quaternion.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/QueryDefinitions.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/QueryDefinitions.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/RayShapeQuery.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/RayShapeQuery.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Rigidbody.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Rigidbody.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/RopeChainRendering.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/RopeChainRendering.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/RopeExtrudedRendering.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/RopeExtrudedRendering.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/RopeLineRendering.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/RopeLineRendering.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/RopeMeshRendering.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/RopeMeshRendering.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Scan.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Scan.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ShapeMatchingConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/ShapeMatchingConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Simplex.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Simplex.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SkinConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SkinConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SoftbodyRendering.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SoftbodyRendering.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Solver.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Solver.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SolverParameters.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SolverParameters.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SortParticleData.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SortParticleData.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SpatialQueries.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SpatialQueries.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SphereShape.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SphereShape.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SphereShapeQuery.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SphereShapeQuery.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/StitchConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/StitchConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/StretchShearConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/StretchShearConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SurfacePoint.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/SurfacePoint.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/TetherConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/TetherConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Transform.cginc create mode 100644 xiaofang/Assets/Obi/Resources/Compute/Transform.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/TriangleMeshShape.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/TriangleMeshShape.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/Compute/VolumeConstraints.compute create mode 100644 xiaofang/Assets/Obi/Resources/Compute/VolumeConstraints.compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/DefaultRopeSection.asset create mode 100644 xiaofang/Assets/Obi/Resources/DefaultRopeSection.asset.meta create mode 100644 xiaofang/Assets/Obi/Resources/GUI.meta create mode 100644 xiaofang/Assets/Obi/Resources/GUI/ProfilerSkin.guiskin create mode 100644 xiaofang/Assets/Obi/Resources/GUI/ProfilerSkin.guiskin.meta create mode 100644 xiaofang/Assets/Obi/Resources/GUI/profiler_bck.png create mode 100644 xiaofang/Assets/Obi/Resources/GUI/profiler_bck.png.meta create mode 100644 xiaofang/Assets/Obi/Resources/GUI/profiler_toolbar.png create mode 100644 xiaofang/Assets/Obi/Resources/GUI/profiler_toolbar.png.meta create mode 100644 xiaofang/Assets/Obi/Resources/GUI/scroll_peg.png create mode 100644 xiaofang/Assets/Obi/Resources/GUI/scroll_peg.png.meta create mode 100644 xiaofang/Assets/Obi/Resources/GUI/task_bck.png create mode 100644 xiaofang/Assets/Obi/Resources/GUI/task_bck.png.meta create mode 100644 xiaofang/Assets/Obi/Resources/GUI/thread_bck.png create mode 100644 xiaofang/Assets/Obi/Resources/GUI/thread_bck.png.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/BuiltInStandardBackfaces.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/BuiltInStandardBackfaces/StandardVertexColors.shader create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/BuiltInStandardBackfaces/StandardVertexColors.shader.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Burst.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Burst/Instanced.mat create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Burst/Instanced.mat.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Compute.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Compute/ProceduralInstanced.mat create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Compute/ProceduralInstanced.mat.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Compute/ProceduralInstanced.shadergraph create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Compute/ProceduralInstanced.shadergraph.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Compute/ProceduralInstancing.cginc create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Compute/ProceduralInstancing.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoids.cginc create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoids.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoidsHDRP.cginc create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoidsHDRP.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiUtils.cginc create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiUtils.cginc.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ParticleShader.shadergraph create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ParticleShader.shadergraph.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Particles.mat create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Particles.mat.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/particle.png create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/Common/particle.png.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/DistanceFields.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/DistanceFields/DistanceFieldRendering.mat create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/DistanceFields/DistanceFieldRendering.mat.meta create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/DistanceFields/DistanceFieldSlice.shader create mode 100644 xiaofang/Assets/Obi/Resources/ObiMaterials/DistanceFields/DistanceFieldSlice.shader.meta create mode 100644 xiaofang/Assets/Obi/Samples.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/FanHorizontal.anim create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/FanHorizontal.anim.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/FanRoot.controller create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/FanRoot.controller.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidCrouch.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidCrouch.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidIdle.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidIdle.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidIdleJumpUp.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidIdleJumpUp.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidJumpAndFall.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidJumpAndFall.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidMidAir.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidMidAir.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidRun.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidRun.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidRunTurn.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidRunTurn.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidRunTurnSharp.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidRunTurnSharp.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidStandTurn.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidStandTurn.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidWalk.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidWalk.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidWalkTurn.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidWalkTurn.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidWalkTurnSharp.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/HumanoidWalkTurnSharp.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/ThirdPersonAnimatorController.controller create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Animations/ThirdPersonAnimatorController.controller.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/CharacterFriction.physicMaterial create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/CharacterFriction.physicMaterial.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/HighFriction.asset create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/HighFriction.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/HighStaticFriction.asset create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/HighStaticFriction.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/Ice.asset create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/Ice.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/LowFriction.asset create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/LowFriction.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/MediumFriction.asset create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/MediumFriction.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/RollingFriction.asset create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/RollingFriction.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/VerySticky.asset create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/CollisionMaterials/VerySticky.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/DistanceFields.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/DistanceFields/EnvironmentDF.asset create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/DistanceFields/EnvironmentDF.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/Checker.mat create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/Checker.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/CoarseChecker.mat create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/CoarseChecker.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/FinishLine.mat create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/FinishLine.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/Flesh.mat create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/Flesh.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/Metal.mat create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/Metal.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/TestEnvironment.mat create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/TestEnvironment.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/VertexColors.mat create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/VertexColors.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/Walls.mat create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Materials/Walls.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Models.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Models/CubicSphere.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Models/CubicSphere.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Models/Fan.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Models/Fan.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Models/TestEnvironment.fbx create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Models/TestEnvironment.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ActorCOMTransform.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ActorCOMTransform.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ActorSpawner.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ActorSpawner.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/AddRandomVelocity.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/AddRandomVelocity.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/Blinker.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/Blinker.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/CharacterController.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/CharacterController/ObiCharacter.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/CharacterController/ObiCharacter.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/CharacterController/SampleCharacterController.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/CharacterController/SampleCharacterController.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ColliderHighlighter.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ColliderHighlighter.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/CollisionEventHandler.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/CollisionEventHandler.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ColorFromPhase.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ColorFromPhase.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ColorFromVelocity.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ColorFromVelocity.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ColorRandomizer.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ColorRandomizer.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/DebugParticleFrames.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/DebugParticleFrames.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ExtrapolationCamera.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ExtrapolationCamera.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/FPSDisplay.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/FPSDisplay.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/LookAroundCamera.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/LookAroundCamera.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/MoveAndRotate.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/MoveAndRotate.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ObiActorTeleport.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ObiActorTeleport.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ObiParticleCounter.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ObiParticleCounter.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ObjectDragger.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ObjectDragger.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ObjectLimit.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/ObjectLimit.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/SlowmoToggler.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/SlowmoToggler.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/WorldSpaceGravity.cs create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Scripts/WorldSpaceGravity.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/SparksEmitter.prefab create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/SparksEmitter.prefab.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Textures.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Textures/ClothPattern.png create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Textures/ClothPattern.png.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Textures/ClothPattern_SM.psd create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Textures/ClothPattern_SM.psd.meta create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Textures/checker.psd create mode 100644 xiaofang/Assets/Obi/Samples/Common/SampleResources/Textures/checker.psd.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/Chains.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/Chains.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/ChainsSettings.lighting create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/ChainsSettings.lighting.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/CharacterTentacles.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/CharacterTentacles.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/ComputeRopes.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/ComputeRopes.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/Crane.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/Crane.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/ElectricalWires.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/ElectricalWires.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/Firehose.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/Firehose.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/FirehoseSettings.lighting create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/FirehoseSettings.lighting.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/FreightLift.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/FreightLift.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/Plectoneme.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/Plectoneme.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/PlectonemeSettings.lighting create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/PlectonemeSettings.lighting.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RenderModes.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RenderModes.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/Rocker.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/Rocker.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RockerSettings.lighting create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RockerSettings.lighting.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeAndJoints.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeAndJoints.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeAndJointsSettings.lighting create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeAndJointsSettings.lighting.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeCutting.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeCutting.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeGrapplingHook.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeGrapplingHook.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeGrapplingHookSettings.lighting create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeGrapplingHookSettings.lighting.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeNet.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeNet.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeShowcase.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeShowcase.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeShowcaseSettings.lighting create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/RopeShowcaseSettings.lighting.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/BenderAnimation.anim create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/BenderAnimation.anim.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/Bending.controller create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/Bending.controller.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/Obi Rod.controller create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/Obi Rod.controller.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/PlectonemeTwister.anim create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/PlectonemeTwister.anim.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/PlectonemeTwisterController.controller create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/PlectonemeTwisterController.controller.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/Rocker.controller create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/Rocker.controller.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/RockerAnimation.anim create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/RockerAnimation.anim.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/RopeCircuit.controller create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/RopeCircuit.controller.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/RopeCircuitAnimation.anim create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/RopeCircuitAnimation.anim.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/RopeHangerAnimation.anim create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/RopeHangerAnimation.anim.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/RopeStretcher.anim create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/RopeStretcher.anim.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/RopeStretcher.controller create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/RopeStretcher.controller.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/SpringBase.anim create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/SpringBase.anim.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/SpringBase.controller create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Animations/SpringBase.controller.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Chain.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Chain.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Crane.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Crane.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/CuttableRope.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/CuttableRope.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Firehose.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Firehose.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Freightlift cable.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Freightlift cable.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Joints rope 1.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Joints rope 1.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Joints rope 2.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Joints rope 2.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Plectoneme rod.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Plectoneme rod.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Snake.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Snake.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/SpringRod.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/SpringRod.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Straight long rope.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Straight long rope.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Straight short rope.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Straight short rope.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/TangledRopeA.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/TangledRopeA.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/TangledRopeB.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/TangledRopeB.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Tearable cable.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Tearable cable.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Very long cable.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/Very long cable.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/WrappingRope.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Blueprints/WrappingRope.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/ChainRed.mat create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/ChainRed.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/ChainWhite.mat create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/ChainWhite.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/GreenRope.mat create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/GreenRope.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/LineRope.mat create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/LineRope.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/RedRope.mat create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/RedRope.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/Rod.mat create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/Rod.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/Shark.mat create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/Shark.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/Snake.mat create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/Snake.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/TanglePeg.mat create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/TanglePeg.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/WrapPeg.mat create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Materials/WrapPeg.mat.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Models.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Models/ChainLink.fbx create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Models/ChainLink.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Models/ChainLinkRed.prefab create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Models/ChainLinkRed.prefab.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Models/ChainLinkWhite.prefab create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Models/ChainLinkWhite.prefab.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Models/shark.obj create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Models/shark.obj.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Models/tentacle_guy.fbx create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Models/tentacle_guy.fbx.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs/SnakeBamboo.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs/SnakeBamboo.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs/SnakeBody.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs/SnakeBody.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs/SnakeFloor.asset create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs/SnakeFloor.asset.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs/TanglePeg.prefab create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs/TanglePeg.prefab.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs/TanglePegSlot.prefab create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs/TanglePegSlot.prefab.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs/WrapPeg.prefab create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Prefabs/WrapPeg.prefab.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/CharacterControl2D.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/CharacterControl2D.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/CraneController.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/CraneController.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/CursorController.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/CursorController.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/ExtendableGrapplingHook.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/ExtendableGrapplingHook.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/GrapplingHook.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/GrapplingHook.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/HosePump.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/HosePump.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/RopeBetweenTwoPoints.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/RopeBetweenTwoPoints.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/RopeNet.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/RopeNet.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/RopeSweepCut.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/RopeSweepCut.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/RopeTenser.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/RopeTenser.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/RopeTensionColorizer.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/RopeTensionColorizer.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/SnakeController.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/SnakeController.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/SpiralCurve.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/SpiralCurve.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/TangledPeg.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/TangledPeg.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/TangledPegSlot.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/TangledPegSlot.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/TangledRopesGameController.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/TangledRopesGameController.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/WrapRopeGameController.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/WrapRopeGameController.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/WrapRopePlayerController.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/WrapRopePlayerController.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/Wrappable.cs create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Scripts/Wrappable.cs.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/Rod.png create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/Rod.png.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/Rope_NRM.png create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/Rope_NRM.png.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/Rope_OCC.png create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/Rope_OCC.png.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/Rope_red.png create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/Rope_red.png.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/cylinder_NRM.png create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/cylinder_NRM.png.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/greatwhiteshark.png create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/greatwhiteshark.png.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/greatwhiteshark_n.png create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SampleResources/Textures/greatwhiteshark_n.png.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/Snake.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/Snake.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SpringRod.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SpringRod.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SpringRodSettings.lighting create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/SpringRodSettings.lighting.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/TangledRopes.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/TangledRopes.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/WrapTheRope.unity create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/WrapTheRope.unity.meta create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/WrapTheRopeSettings.lighting create mode 100644 xiaofang/Assets/Obi/Samples/RopeAndRod/WrapTheRopeSettings.lighting.meta create mode 100644 xiaofang/Assets/Obi/Scripts.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Actors.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Actors/IObiParticleCollection.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Actors/IObiParticleCollection.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Actors/ObiActor.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Actors/ObiActor.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/BurstBackend.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/BurstBackend.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/BurstIntegration.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/BurstIntegration.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/BurstJobHandle.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/BurstJobHandle.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/BurstMath.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/BurstMath.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstBox.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstBox.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstCapsule.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstCapsule.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstColliderShape.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstColliderShape.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstColliderWorld.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstColliderWorld.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstDFNode.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstDFNode.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstDistanceField.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstDistanceField.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstEdgeMesh.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstEdgeMesh.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstHeightField.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstHeightField.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstLocalOptimization.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstLocalOptimization.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstSimplex.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstSimplex.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstSphere.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstSphere.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstTriangleMesh.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Collisions/BurstTriangleMesh.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Aerodynamics.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Aerodynamics/BurstAerodynamicConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Aerodynamics/BurstAerodynamicConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Aerodynamics/BurstAerodynamicConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Aerodynamics/BurstAerodynamicConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Bend.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Bend/BurstBendConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Bend/BurstBendConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Bend/BurstBendConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Bend/BurstBendConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/BendTwist.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/BendTwist/BurstBendTwistConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/BendTwist/BurstBendTwistConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/BendTwist/BurstBendTwistConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/BendTwist/BurstBendTwistConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/BurstConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/BurstConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/BurstConstraintsImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/BurstConstraintsImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Chain.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Chain/BurstChainConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Chain/BurstChainConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Chain/BurstChainConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Chain/BurstChainConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ColliderCollision.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ColliderCollision/ApplyCollisionConstraintsJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ColliderCollision/ApplyCollisionConstraintsJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ColliderCollision/BurstColliderCollisionConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ColliderCollision/BurstColliderCollisionConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ColliderCollision/BurstColliderCollisionConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ColliderCollision/BurstColliderCollisionConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ColliderCollision/BurstColliderFrictionConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ColliderCollision/BurstColliderFrictionConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ColliderCollision/BurstColliderFrictionConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ColliderCollision/BurstColliderFrictionConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Density.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Density/BurstDensityConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Density/BurstDensityConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Density/BurstDensityConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Density/BurstDensityConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Density/Kernels.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Density/Kernels/CohesionKernel.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Density/Kernels/CohesionKernel.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Density/Kernels/Poly6Kernel.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Density/Kernels/Poly6Kernel.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Density/Kernels/SpikyKernel.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Density/Kernels/SpikyKernel.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Distance.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Distance/BurstDistanceConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Distance/BurstDistanceConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Distance/BurstDistanceConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Distance/BurstDistanceConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ParticleCollision.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ParticleCollision/ApplyBatchedCollisionConstraintsBatchJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ParticleCollision/ApplyBatchedCollisionConstraintsBatchJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ParticleCollision/BurstParticleCollisionConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ParticleCollision/BurstParticleCollisionConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ParticleCollision/BurstParticleCollisionConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ParticleCollision/BurstParticleCollisionConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ParticleCollision/BurstParticleFrictionConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ParticleCollision/BurstParticleFrictionConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ParticleCollision/BurstParticleFrictionConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ParticleCollision/BurstParticleFrictionConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Pin.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Pin/BurstPinConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Pin/BurstPinConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Pin/BurstPinConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Pin/BurstPinConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ShapeMatching.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ShapeMatching/BurstShapeMatchingConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ShapeMatching/BurstShapeMatchingConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ShapeMatching/BurstShapeMatchingConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/ShapeMatching/BurstShapeMatchingConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Skin.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Skin/BurstSkinConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Skin/BurstSkinConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Skin/BurstSkinConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Skin/BurstSkinConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Stitch.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Stitch/BurstStitchConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Stitch/BurstStitchConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Stitch/BurstStitchConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Stitch/BurstStitchConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/StretchShear.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/StretchShear/BurstStretchShearConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/StretchShear/BurstStretchShearConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/StretchShear/BurstStretchShearConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/StretchShear/BurstStretchShearConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Tether.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Tether/BurstTetherConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Tether/BurstTetherConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Tether/BurstTetherConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Tether/BurstTetherConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Volume.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Volume/BurstVolumeConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Volume/BurstVolumeConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Volume/BurstVolumeConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Volume/BurstVolumeConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstAabb.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstAabb.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstAffineTransform.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstAffineTransform.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstCellSpan.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstCellSpan.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstCollisionMaterial.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstCollisionMaterial.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstInertialFrame.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstInertialFrame.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstPrefixSum.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstPrefixSum.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstQueryShape.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstQueryShape.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstRigidbody.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/BurstRigidbody.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/BatchLUT.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/BatchLUT.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/ConstraintBatcher.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/ConstraintBatcher.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/ConstraintSorter.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/ConstraintSorter.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/ContactProvider.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/ContactProvider.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/FluidInteractionProvider.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/FluidInteractionProvider.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/IConstraint.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/IConstraint.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/IConstraintProvider.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ConstraintBatcher/IConstraintProvider.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/FluidInteraction.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/FluidInteraction.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/GridHash.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/GridHash.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/NativeMultilevelGrid.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/NativeMultilevelGrid.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ParticleGrid.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/ParticleGrid.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/Queries.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/Queries/BurstContact.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/Queries/BurstContact.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/Queries/BurstQueryResult.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/DataStructures/Queries/BurstQueryResult.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Queries.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Queries/BurstBoxQuery.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Queries/BurstBoxQuery.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Queries/BurstRay.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Queries/BurstRay.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Queries/BurstSphereQuery.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Queries/BurstSphereQuery.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Queries/SpatialQueryJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Queries/SpatialQueryJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/Common.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/Common/BuildParticleMeshDataJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/Common/BuildParticleMeshDataJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/Common/BurstFoamRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/Common/BurstFoamRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/Common/BurstInstancedParticleRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/Common/BurstInstancedParticleRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/Common/BurstParticleRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/Common/BurstParticleRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/BurstChainRopeRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/BurstChainRopeRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/BurstExtrudedRopeRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/BurstExtrudedRopeRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/BurstLineRopeRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/BurstLineRopeRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/BurstMeshRopeRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/BurstMeshRopeRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/BurstPathFrame.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/BurstPathFrame.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/BurstPathSmootherRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/BurstPathSmootherRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/ChaikinSmoothChunksJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/ChaikinSmoothChunksJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/DecimateChunksJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/DecimateChunksJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/ParallelTransportJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/ParallelTransportJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/ApplyInertialForcesJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/ApplyInertialForcesJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/BoundsReductionJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/BoundsReductionJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/BurstSolverImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/BurstSolverImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/DequeueIntoArrayJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/DequeueIntoArrayJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/FindFluidParticlesJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/FindFluidParticlesJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/FoamParticlesJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/FoamParticlesJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/InterpolationJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/InterpolationJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/PredictPositionsJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/PredictPositionsJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/UpdateNormalsJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/UpdateNormalsJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/UpdatePositionsJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/UpdatePositionsJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/UpdateVelocitiesJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Burst/Solver/UpdateVelocitiesJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeBox.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeBox.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeCapsule.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeCapsule.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeColliderWorld.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeColliderWorld.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeDistanceField.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeDistanceField.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeEdgeMesh.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeEdgeMesh.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeHeightField.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeHeightField.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeSphere.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeSphere.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeTriangleMesh.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/ComputeTriangleMesh.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/SpatialQueries.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Collisions/SpatialQueries.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/ComputeBackend.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/ComputeBackend.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/ComputeJobHandle.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/ComputeJobHandle.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/ComputeMath.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/ComputeMath.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Aerodynamics.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Aerodynamics/ComputeAerodynamicConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Aerodynamics/ComputeAerodynamicConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Aerodynamics/ComputeAerodynamicConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Aerodynamics/ComputeAerodynamicConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Bend.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Bend/ComputeBendConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Bend/ComputeBendConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Bend/ComputeBendConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Bend/ComputeBendConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/BendTwist.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/BendTwist/ComputeBendTwistConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/BendTwist/ComputeBendTwistConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/BendTwist/ComputeBendTwistConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/BendTwist/ComputeBendTwistConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Chain.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Chain/ComputeChainConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Chain/ComputeChainConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Chain/ComputeChainConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Chain/ComputeChainConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ColliderCollision.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ColliderCollision/ComputeColliderCollisionConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ColliderCollision/ComputeColliderCollisionConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ColliderCollision/ComputeColliderCollisionConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ColliderCollision/ComputeColliderCollisionConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ColliderCollision/ComputeColliderFrictionConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ColliderCollision/ComputeColliderFrictionConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ColliderCollision/ComputeColliderFrictionConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ColliderCollision/ComputeColliderFrictionConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ComputeConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ComputeConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ComputeConstraintsImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ComputeConstraintsImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Density.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Density/ComputeDensityConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Density/ComputeDensityConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Density/ComputeDensityConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Density/ComputeDensityConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Distance.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Distance/ComputeDistanceConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Distance/ComputeDistanceConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Distance/ComputeDistanceConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Distance/ComputeDistanceConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ParticleCollision.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ParticleCollision/ComputeParticleCollisionConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ParticleCollision/ComputeParticleCollisionConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ParticleCollision/ComputeParticleCollisionConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ParticleCollision/ComputeParticleCollisionConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ParticleCollision/ComputeParticleFrictionConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ParticleCollision/ComputeParticleFrictionConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ParticleCollision/ComputeParticleFrictionConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ParticleCollision/ComputeParticleFrictionConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Pin.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Pin/ComputePinConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Pin/ComputePinConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Pin/ComputePinConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Pin/ComputePinConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ShapeMatching.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ShapeMatching/ComputeShapeMatchingConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ShapeMatching/ComputeShapeMatchingConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ShapeMatching/ComputeShapeMatchingConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/ShapeMatching/ComputeShapeMatchingConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Skin.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Skin/ComputeSkinConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Skin/ComputeSkinConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Skin/ComputeSkinConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Skin/ComputeSkinConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Stitch.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Stitch/ComputeStitchConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Stitch/ComputeStitchConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Stitch/ComputeStitchConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Stitch/ComputeStitchConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/StretchShear.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/StretchShear/StretchShearConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/StretchShear/StretchShearConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/StretchShear/StretchShearConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/StretchShear/StretchShearConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Tether.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Tether/ComputeTetherConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Tether/ComputeTetherConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Tether/ComputeTetherConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Tether/ComputeTetherConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Volume.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Volume/ComputeVolumeConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Volume/ComputeVolumeConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Volume/ComputeVolumeConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Constraints/Volume/ComputeVolumeConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/DataStructures.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/DataStructures/ComputeParticleGrid.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/DataStructures/ComputeParticleGrid.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/DataStructures/ComputePrefixSum.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/DataStructures/ComputePrefixSum.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/DataStructures/ComputeSort.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/DataStructures/ComputeSort.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Queries.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Queries/ComputeBoxQuery.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Queries/ComputeBoxQuery.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Queries/ComputeRayQuery.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Queries/ComputeRayQuery.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Queries/ComputeSphereQuery.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Queries/ComputeSphereQuery.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/Common.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/Common/ComputeFoamRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/Common/ComputeFoamRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/Common/ComputeInstancedParticleRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/Common/ComputeInstancedParticleRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/Common/ComputeParticleRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/Common/ComputeParticleRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/RopeAndRod.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/RopeAndRod/ComputeChainRopeRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/RopeAndRod/ComputeChainRopeRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/RopeAndRod/ComputeExtrudedRopeRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/RopeAndRod/ComputeExtrudedRopeRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/RopeAndRod/ComputeLineRopeRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/RopeAndRod/ComputeLineRopeRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/RopeAndRod/ComputeMeshRopeRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/RopeAndRod/ComputeMeshRopeRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/RopeAndRod/ComputePathSmootherRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Rendering/RopeAndRod/ComputePathSmootherRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Solver.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Solver/ComputeSolverImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Compute/Solver/ComputeSolverImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Collisions.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Collisions/IColliderWorldImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Collisions/IColliderWorldImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Collisions/IColliderWorldImpl.cs.orig create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Collisions/IColliderWorldImpl.cs.orig.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IAerodynamicConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IAerodynamicConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IBendConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IBendConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IBendTwistConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IBendTwistConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IChainConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IChainConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IColliderCollisionConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IColliderCollisionConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IColliderFrictionConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IColliderFrictionConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IConstraintsImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IConstraintsImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IDensityConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IDensityConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IDistanceConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IDistanceConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IParticleCollisionConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IParticleCollisionConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IParticleFrictionConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IParticleFrictionConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IPinConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IPinConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IShapeMatchingConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IShapeMatchingConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/ISkinConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/ISkinConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IStitchConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IStitchConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IStretchShearConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IStretchShearConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/ITetherConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/ITetherConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IVolumeConstraintsBatchImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Constraints/IVolumeConstraintsBatchImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/IObiBackend.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/IObiBackend.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/IObiJobHandle.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/IObiJobHandle.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/JobHandlePool.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/JobHandlePool.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Rendering.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Rendering/IRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Rendering/IRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Solver.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Solver/ISolverImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Interface/Solver/ISolverImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Null.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Null/NullBackend.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Null/NullBackend.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Null/NullSolverImpl.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Backends/Null/NullSolverImpl.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/IStructuralConstraintBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/IStructuralConstraintBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiAerodynamicConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiAerodynamicConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiBendConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiBendConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiBendTwistConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiBendTwistConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiChainConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiChainConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiDistanceConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiDistanceConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiPinConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiPinConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiShapeMatchingConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiShapeMatchingConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiSkinConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiSkinConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiStretchShearConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiStretchShearConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiTetherConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiTetherConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiVolumeConstraintsBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Batches/ObiVolumeConstraintsBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiAerodynamicConstraintsData.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiAerodynamicConstraintsData.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiBendConstraintsData.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiBendConstraintsData.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiBendTwistConstraintsData.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiBendTwistConstraintsData.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiChainConstraintsData.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiChainConstraintsData.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiDistanceConstraintsData.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiDistanceConstraintsData.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiPinConstraintsData.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiPinConstraintsData.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiShapeMatchingConstraintsData.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiShapeMatchingConstraintsData.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiSkinConstraintsData.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiSkinConstraintsData.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiStretchShearConstraintsData.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiStretchShearConstraintsData.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiTetherConstraintsData.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiTetherConstraintsData.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiVolumeConstraintsData.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/Groups/ObiVolumeConstraintsData.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/ObiConstraints.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/ObiConstraints.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/StructuralConstraint.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/Constraints/StructuralConstraint.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/GraphColoring.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/GraphColoring.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/ObiActorBlueprint.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/ObiActorBlueprint.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/ObiMeshBasedActorBlueprint.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/ObiMeshBasedActorBlueprint.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/ObiParticleGroup.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Blueprints/ObiParticleGroup.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers2D.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers2D/ObiBoxShapeTracker2D.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers2D/ObiBoxShapeTracker2D.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers2D/ObiCapsuleShapeTracker2D.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers2D/ObiCapsuleShapeTracker2D.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers2D/ObiCircleShapeTracker2D.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers2D/ObiCircleShapeTracker2D.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers2D/ObiEdgeShapeTracker2D.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers2D/ObiEdgeShapeTracker2D.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiBoxShapeTracker.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiBoxShapeTracker.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiCapsuleShapeTracker.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiCapsuleShapeTracker.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiCharacterControllerShapeTracker.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiCharacterControllerShapeTracker.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiDistanceFieldShapeTracker.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiDistanceFieldShapeTracker.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiMeshShapeTracker.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiMeshShapeTracker.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiShapeTracker.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiShapeTracker.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiSphereShapeTracker.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiSphereShapeTracker.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiTerrainShapeTracker.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ColliderTrackers/Trackers3D/ObiTerrainShapeTracker.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiCollider.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiCollider.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiCollider2D.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiCollider2D.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiColliderBase.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiColliderBase.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiColliderWorld.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiColliderWorld.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiColliderWorld.cs.orig create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiColliderWorld.cs.orig.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiCollisionMaterial.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiCollisionMaterial.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiDistanceField.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiDistanceField.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiDistanceFieldContainer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiDistanceFieldContainer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiEdgeMeshContainer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiEdgeMeshContainer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiHeightFieldContainer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiHeightFieldContainer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiRigidbody.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiRigidbody.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiRigidbody2D.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiRigidbody2D.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiRigidbodyBase.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiRigidbodyBase.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiTriangleMeshContainer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Collisions/ObiTriangleMeshContainer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ASDF.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ASDF/ASDF.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ASDF/ASDF.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ASDF/DFNode.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ASDF/DFNode.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Aabb.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Aabb.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/AffineTransform.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/AffineTransform.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/BVH.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/BVH/BIH.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/BVH/BIH.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/BVH/BIHNode.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/BVH/BIHNode.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/BVH/IBounded.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/BVH/IBounded.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/CellSpan.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/CellSpan.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ColliderRigidbody.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ColliderRigidbody.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ColliderShape.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ColliderShape.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/CollisionMaterial.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/CollisionMaterial.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ContactEffectiveMasses.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ContactEffectiveMasses.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/EmitPoint.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/EmitPoint.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/EmittedParticleData.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/EmittedParticleData.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ForceZone.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ForceZone.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/InertialFrame.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/InertialFrame.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeAabbList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeAabbList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeAffineTransformList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeAffineTransformList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeBIHNodeList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeBIHNodeList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeBoneWeightList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeBoneWeightList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeByteList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeByteList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeCellSpanList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeCellSpanList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeColliderShapeList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeColliderShapeList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeCollisionMaterialList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeCollisionMaterialList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeColorList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeColorList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeContactList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeContactList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeDFNodeList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeDFNodeList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeDistanceFieldHeaderList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeDistanceFieldHeaderList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeEdgeList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeEdgeList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeEdgeMeshHeaderList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeEdgeMeshHeaderList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeEffectiveMassesList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeEffectiveMassesList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeEmitPointList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeEmitPointList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeFloatList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeFloatList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeForceZoneList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeForceZoneList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeHeightFieldHeaderList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeHeightFieldHeaderList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeInt4List.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeInt4List.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeIntList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeIntList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeIntPtrList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeIntPtrList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeMatrix4x4List.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeMatrix4x4List.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeQuaternionList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeQuaternionList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeQueryResultList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeQueryResultList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeQueryShapeList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeQueryShapeList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeRigidbodyList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeRigidbodyList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeTriangleList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeTriangleList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeTriangleMeshHeaderList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeTriangleMeshHeaderList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeUIntList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeUIntList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeVector2List.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeVector2List.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeVector3List.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeVector3List.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeVector4List.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeVector4List.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ObiList.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ObiList.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ParticlePair.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/ParticlePair.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Queries.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Queries/QueryResult.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Queries/QueryResult.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Queries/QueryShape.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Queries/QueryShape.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/RegularGrid.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/RegularGrid/RegularGrid.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/RegularGrid/RegularGrid.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/SimplexCounts.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/SimplexCounts.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/VInt4.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/VInt4.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Voxelization.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Voxelization/MeshVoxelizer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Voxelization/MeshVoxelizer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Voxelization/PriorityQueue.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Voxelization/PriorityQueue.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Voxelization/VoxelDistanceField.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Voxelization/VoxelDistanceField.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Voxelization/VoxelPathFinder.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/DataStructures/Voxelization/VoxelPathFinder.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/ObiEditorSettings.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/ObiEditorSettings.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/DataBatches.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/DataBatches/MeshDataBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/DataBatches/MeshDataBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/DataBatches/SkeletonDataBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/DataBatches/SkeletonDataBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ISurfaceChunkUser.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ISurfaceChunkUser.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiActorRenderer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiActorRenderer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiDistanceFieldRenderer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiDistanceFieldRenderer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiFoamRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiFoamRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiInstancedParticleRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiInstancedParticleRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiInstancedParticleRenderer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiInstancedParticleRenderer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiParticleRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiParticleRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiParticleRenderer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiParticleRenderer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiRenderer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ObiRenderer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ParticleImpostorRendering.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/ParticleImpostorRendering.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/RenderBatches.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/RenderBatches/DynamicRenderBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/RenderBatches/DynamicRenderBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/RenderBatches/IRenderBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/RenderBatches/IRenderBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/RenderBatches/InstanceRenderBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/RenderBatches/InstanceRenderBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/RenderBatches/ProceduralRenderBatch.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Rendering/RenderBatches/ProceduralRenderBatch.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Solver.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Solver/ObiActorEditorSelectionHandler.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Solver/ObiActorEditorSelectionHandler.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Solver/ObiRenderSystemStack.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Solver/ObiRenderSystemStack.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Solver/ObiSolver.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Solver/ObiSolver.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/ChildrenOnly.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/ChildrenOnly.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/DisplayAs.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/DisplayAs.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/Indent.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/Indent.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/InspectorButtonAttribute.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/InspectorButtonAttribute.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/LayerField.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/LayerField.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/MinMaxAttribute.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/MinMaxAttribute.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/MultiDelayed.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/MultiDelayed.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/MultiPropertyAttribute.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/MultiPropertyAttribute.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/MultiRange.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/MultiRange.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/SerializeProperty.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/SerializeProperty.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/VisibleIf.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Attributes/VisibleIf.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Coroutines.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Coroutines/CoroutineJob.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Coroutines/CoroutineJob.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Coroutines/EditorCoroutine.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Coroutines/EditorCoroutine.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Forces.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Forces/ObiForceZone.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/Forces/ObiForceZone.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiContactEventDispatcher.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiContactEventDispatcher.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiContactGrabber.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiContactGrabber.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiFoamGenerator.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiFoamGenerator.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiIntegration.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiIntegration.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiParticleAttachment.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiParticleAttachment.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiParticleDragger.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiParticleDragger.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiParticlePicker.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiParticlePicker.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiStitcher.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiStitcher.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiUtils.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiUtils.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiVectorMath.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/ObiVectorMath.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/SetCategory.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Common/Utils/SetCategory.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Obi.asmdef create mode 100644 xiaofang/Assets/Obi/Scripts/Obi.asmdef.meta create mode 100644 xiaofang/Assets/Obi/Scripts/Oni.cs create mode 100644 xiaofang/Assets/Obi/Scripts/Oni.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Actors.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Actors/ObiBone.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Actors/ObiBone.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Actors/ObiRod.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Actors/ObiRod.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Actors/ObiRope.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Actors/ObiRope.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Actors/ObiRopeBase.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Actors/ObiRopeBase.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Actors/ObiRopeCursor.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Actors/ObiRopeCursor.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Blueprints.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Blueprints/ObiBoneBlueprint.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Blueprints/ObiBoneBlueprint.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Blueprints/ObiRodBlueprint.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Blueprints/ObiRodBlueprint.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Blueprints/ObiRopeBlueprint.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Blueprints/ObiRopeBlueprint.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Blueprints/ObiRopeBlueprintBase.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Blueprints/ObiRopeBlueprintBase.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/ObiRopeSection.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/ObiRopeSection.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/ObiStructuralElement.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/ObiStructuralElement.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiColorDataChannel.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiColorDataChannel.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiFilterDataChannel.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiFilterDataChannel.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiMassDataChannel.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiMassDataChannel.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiNormalDataChannel.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiNormalDataChannel.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiPathDataChannel.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiPathDataChannel.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiPathDataChannelIdentity.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiPathDataChannelIdentity.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiPointsDataChannel.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiPointsDataChannel.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiRotationalMassDataChannel.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiRotationalMassDataChannel.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiThicknessDataChannel.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/DataChannels/ObiThicknessDataChannel.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/Interpolators.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/Interpolators/ObiCatmullRomInterpolator.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/Interpolators/ObiCatmullRomInterpolator.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/Interpolators/ObiCatmullRomInterpolator3D.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/Interpolators/ObiCatmullRomInterpolator3D.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/Interpolators/ObiColorInterpolator3D.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/Interpolators/ObiColorInterpolator3D.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/Interpolators/ObiConstantInterpolator.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/Interpolators/ObiConstantInterpolator.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/Interpolators/ObiInterpolator.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/Interpolators/ObiInterpolator.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/ObiPath.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/ObiPath.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/ObiPathFrame.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/ObiPathFrame.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/ObiPathSmoother.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/ObiPathSmoother.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/ObiWingedPoint.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/DataStructures/Path/ObiWingedPoint.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiChainRopeRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiChainRopeRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiExtrudedRopeRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiExtrudedRopeRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiLineRopeRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiLineRopeRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiMeshRopeRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiMeshRopeRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiPathSmootherRenderSystem.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiPathSmootherRenderSystem.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiRopeChainRenderer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiRopeChainRenderer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiRopeExtrudedRenderer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiRopeExtrudedRenderer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiRopeLineRenderer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiRopeLineRenderer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiRopeMeshRenderer.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Rendering/ObiRopeMeshRenderer.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Utils.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Utils/ObiRopeAttach.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Utils/ObiRopeAttach.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Utils/ObiRopePrefabPlugger.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Utils/ObiRopePrefabPlugger.cs.meta create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Utils/ObiRopeReel.cs create mode 100644 xiaofang/Assets/Obi/Scripts/RopeAndRod/Utils/ObiRopeReel.cs.meta create mode 100644 xiaofang/Assets/ObiEditorSettings.asset create mode 100644 xiaofang/Assets/ObiEditorSettings.asset.meta create mode 100644 xiaofang/Packages/manifest.json create mode 100644 xiaofang/Packages/packages-lock.json create mode 100644 xiaofang/ProjectSettings/AudioManager.asset create mode 100644 xiaofang/ProjectSettings/AutoStreamingSettings.asset create mode 100644 xiaofang/ProjectSettings/ClusterInputManager.asset create mode 100644 xiaofang/ProjectSettings/DynamicsManager.asset create mode 100644 xiaofang/ProjectSettings/EditorBuildSettings.asset create mode 100644 xiaofang/ProjectSettings/EditorSettings.asset create mode 100644 xiaofang/ProjectSettings/GraphicsSettings.asset create mode 100644 xiaofang/ProjectSettings/InputManager.asset create mode 100644 xiaofang/ProjectSettings/MemorySettings.asset create mode 100644 xiaofang/ProjectSettings/NavMeshAreas.asset create mode 100644 xiaofang/ProjectSettings/PackageManagerSettings.asset create mode 100644 xiaofang/ProjectSettings/Physics2DSettings.asset create mode 100644 xiaofang/ProjectSettings/PresetManager.asset create mode 100644 xiaofang/ProjectSettings/ProjectSettings.asset create mode 100644 xiaofang/ProjectSettings/ProjectVersion.txt create mode 100644 xiaofang/ProjectSettings/QualitySettings.asset create mode 100644 xiaofang/ProjectSettings/SceneTemplateSettings.json create mode 100644 xiaofang/ProjectSettings/ShaderGraphSettings.asset create mode 100644 xiaofang/ProjectSettings/TagManager.asset create mode 100644 xiaofang/ProjectSettings/TimeManager.asset create mode 100644 xiaofang/ProjectSettings/UnityConnectSettings.asset create mode 100644 xiaofang/ProjectSettings/VFXManager.asset create mode 100644 xiaofang/ProjectSettings/VersionControlSettings.asset create mode 100644 xiaofang/ProjectSettings/boot.config create mode 100644 xiaofang/UserSettings/EditorUserSettings.asset create mode 100644 xiaofang/UserSettings/Search.settings diff --git a/xiaofang/Assets/Obi.meta b/xiaofang/Assets/Obi.meta new file mode 100644 index 00000000..a1435212 --- /dev/null +++ b/xiaofang/Assets/Obi.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 36112b76e54ae47b48e48d646aee4ed0 +folderAsset: yes +timeCreated: 1435850625 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/CHANGELOG_rope.txt b/xiaofang/Assets/Obi/CHANGELOG_rope.txt new file mode 100644 index 00000000..2c68695a --- /dev/null +++ b/xiaofang/Assets/Obi/CHANGELOG_rope.txt @@ -0,0 +1,525 @@ +# Change Log +All notable changes to “Obi - Advanced ropes for Unity” will be documented in this file. + +## [7.0.4] + +### Fixed +- Bug that caused inactive particles to still be rendered by ObiInstancedParticleRenderer. +- Bug that preventing pin constraints' break threshold from working when using the Compute backend. + +## [7.0.3] + +### Added +- Object layer support for all renderers. +- New "Synchronous Fixed" solver synchronization mode, similar to Obi 6, offers tighter integration with rigidbody physics. +- New "Tangled Ropes" sample scene. + +## [7.0.2] + +### Fixed +- Solvers not placed at the scene origin would result in actors having incorrect motion blur in HDRP. +- Fixed issue when disabling all solvers and colliders simultaneously: ipon re-enabling them, the colliders would be ignored. +- Issue withe ElectricalSparks sample scene, ObiRopePrefabPlugger sample component may sometimes thorw an exception dependin on Unity's OnEnable call order. +- Rope would sometimes disappear when using aerodynamic constraints with zero wind in Burst, due to a math.project returning NaN. Replaced with math.projectsafe. + +## [7.0.1] + +### Added +- BakeMesh functionality to ObiRopeChainRenderer, you can now export baked chain meshes. +- Render layer mask support to all rope renderers and particle renderers. + +### Fixed +- Sceneview mouse lookaround in flytrough mode (right click + drag) didn't work in the path editor in Windows. +- Having a ObiParticleRenderer with no material applied resulted in a exception in builds due GetInstanceID() returning 0 in editor but raising a nullref exception in the build. + +## [7.0] + +### Added +- Compute shader based GPU solver backend. +- More efficient solver update cycle, that also removes the need to have ObiUpdater components. +- Aerodynamic constraint support for ObiRope, ObiRod and ObiBone. + +### Changed +- Rendering system is now fully multithreaded, integrated with the solver backend. + +### Removed +- Native library based 'Oni' solver backend. +- ObiUpdater and all derived classes have been removed. + +## [6.5.1] + +### Added +- Support for holes in terrain colliders. + +## [6.5] + +### Added +- Improved constraint coloring, which results in much faster blueprint generation. + +### Fixed +- Memory leak when using collision constraints in the Burst backend. +- Performance drop when using collision constraints in Burst >1.7 +- Incorrect lighting on particles in the blueprint editor, when opening the editor without having previously opened any scene. + +## [6.4] + +### Added +- Support for configurable enter play mode (domain and scene reload disabling). +- Support for in-editor hot reloading. +- Numerical fields to edit control point position and tangents added to the path editor. + +### Changed +- Better path editor integration using Unity's editor custom tool API. +- GrapplingHook sample scene now features a hook rope that extends over time, instead of extending instantly. +- Reduced memory allocation in ObiPathSmoother Decimate() method. +- Introduced a job handle pool to avoid runtime allocation of handles by both Burst and Oni backends. +- Constraint padding array in Burst solver has been turned into a member variable instead of allocating anew it every frame. +- Collision and friction batches are pooled instead of allocated every frame. + +### Fixed +- InvalidOperationException when performing certain spatial queries with jobs debugger enabled in the Burst backend. +- ObiBone collision category was internally resetting to zero upon pressing play. +- Particle render mode in blueprint editor wasn't updated every frame under specific circumstances. + +## [6.3] + +### Added +- New ObiBone actor, creates a particle-based representation of a bone hierarchy and simulates it using rod constraints. +- Built-in support for applying solver gravity in world-space. + +### Fixed +- Bug in attachments: prefab modifications were not being applied to the component. +- Slight reduction in solver memory allocation. +- Object disposed exception when using contact callbacks with a non-visible solver. + +## [6.2] + +#IMPORTANT: If updating from an older version, you’ll need to readjust collision filtering in your scenes. +Phase-based collision filtering has been replaced by mask/categroy based system. + +### Added +- New spatial query API, that allows to perform efficient distance, overlap and raycast queries. + +### Changed +- Collision phase filtering has been replaced by a category/mask system. If you upgrade existing projects to Obi 6.2, you will have to set up categories and masks appropiately. + + +## [6.1] + +### Added +- RopeCutting sample scene, where screen-space line dragged by the user is used to cut multiple 3D ropes. +- Snake sample scene, where a snake-like character implemented using a rope can be controlled by the user. + +### Changed +- Decreased minimum error in distance fields to 1e-07 + +### Fixed +- Bug in Oni backend: collision stickiness resulted in rapid particle separation from the collision surface. +- Bug that caused NaN velocity assignments to rigidbodies after removing all actors from a solver. + +## [6.0.1] + +### Fixed +- Bug in Burst backend, resulting in InvalidOperationException when enabling Burst safety checks. +- Bug in ObiSolver that caused particleToActor array entries to be null. + +## [6.0] + +### Added +- Optional simplex-based surface collion pipeline for more accurate collision detection/response. +- Predictive variable-step constraint solving that makes syncing Unity's physics no longer necessary when using substeps. +- Amount of CCD is now adjustable per-solver. +- Collision margin is now adjustable per-solver. +- Bend and bend/twist constraints now support plasticity. +- One-sided collision detection between particles. Particles with one-sided collision detection will always project penetrating particles to the side defined by their associated normal. + +### Fixed +- Bug in dynamic particle attachments that would case colliders parented under a solver to lose their attachments upon enabling/reenabling a solver. + +### Changed +- Contacts "particle" and "other" have been renamed to "bodyA" and "bodyB". bodyB might be a simplex or collider index, depending on the contact type.To access +particle indices from simplex indices, use the solver.simplices array. + +## [5.6.2] + +### Fixed +- Missed collisions using certain meshes for MeshColliders, due to a bug in bounding interval hierarchy generation. +- Corrected orientation error in the first particle of rods, when there's multiple rods in a solver. +- Corrected rendering error in rods, when there's multiple rods in a solver. + +## [5.6.1] + +### Fixed +- Bug in Burst backend: solver bounding box size was typically underestimated. +- Bug in Burst backend: when using volume constraints: "InvalidOperationException: The NativeContainer ApplyVolumeConstraintsBatchJob.particleIndices has not been assigned or constructed" +- Bug in Burst backend: not releasing native arrays when empty solvers -with zero actors in them- are present in the scene. +- Bug in Oni backend: volume constraints not working properly when multiple actors are present in the solver. +- Fixed crash when using ObiLateUpdater or ObiLateFixedUpdater with the Burst backend. +- Reduced GC allocation in dynamic particle attachments. +- Fixed bug in Skin constraints, that caused them to fail restricting particle movement in certain circumstances. + +### Changed +- Updated Oni iOS library to XCode 12.1. Make sure to use XCode 12.1 or up to build for iOS when using the Oni backend. +- ObiKinematicVelocities component has been removed. Its functionality is now built into the engine, and automatically used for kinematic rigidbodies. + +### Added +- Sample ObiContactDispatcher component, that will call custom enter/stay/exit contact events. +- Support for multiple solvers in sample script in ObiContactGrabber. +- Added util LookAroundCamera component. + +## [5.6] + +### Added +- Faster SDF generation. +- New sample scene. + +### Fixed +- Bug that causes out of bounds access when dinamically adding/removing colliders at runtime. +- Bug that prevented stitch constraints from working first time they were enabled. +- Offset in particle selection brush on high density screens. + +### Changed +- Constraint batches of multiple actors are now merged together. This greatly reduces the amount of dispatched jobs and improves performance on both backends. +- Colliders no longer have a "use distance fields" boolean value, they will always use the SDF as long as they have one. + +## [5.5] + +### Added +- Backend system: abstracts the underlying particle-based physics engine used. To the native, built-in engine (Oni), we have added a Burst-based implementation that +will run on all platforms supported by Burst. + +### Changed +- Improved path smoother, line and extruded renderer performance. + +## [5.4] + +### Fixed +- Bug that caused a crash when using Obi in conjunction with Mirror networking system (NetworkIdentity component). +- Bug that could cause a crash when disabling an actor under a disabled solver. +- Bug that prevented self-collisions to work correctly between particles created at runtime by a ObiRopeCursor. + +### Changed +- Recompiled iOS libraries using XCode 11.3.1, to circumvent bitcode compatibility issues now that XCode 11.4 and up have a bug that cause linking against Obi to fail. + + +## [5.3] + +### Added +- Added adaptive rendering decimation to ObiPathSmoother, controllable using a curvature threshold. +- Greatly increased numerical precision for rigidbody interaction when solvers are far away from the origin. +- 2D colliders now span infinitely in the Z axis. + +### Fixed +- Issue in the ObiStitcher editor that picked up incorrect particles when adding stitches. +- Issue that caused a 1-frame delay for collider geometry parented inside a solver. +- Issue in ObiParticleDragger that caused incorrect behavior with multiple solvers. +- Bug in particle advection, that assumed diffuse particle positions to be expreseed in world space. Now advection works correctly +for solvers not positioned at 0,0,0. + +## [5.2] + +### Added +- Rope tear callback (cloth.OnRopeTorn) +- Function to reset particle positions orientations and and velocities in an actor (actor.ResetParticles()) +- Added support for ObiRopeLineRenderer in SRPs. + +### Fixed +- Issue with inertia rotations, that caused wrong inertia tensors for complex compound colliders. +- Issue in particle attachments, that forced to call Bind() manually after changing their target or particle group at runtime. + + +## [5.1] + +### Added +-Smooth initial overlap resolution by using clamped depenetration velocity. +-Actors now automatically create a solver root when editing them in prefab mode. +-Brought back rope mesh baking. + +### Fixed +- Bug that caused solvers with no actors in their hierarchy to freeze Unity when updated by a fixed updater. +- Bug that prevented multiple colliders in the same object to be notified of transform changes. + +### Fixed +-Fixed bug that caused null ref when attempting to edit a rope with no blueprint. + +## [5.0] + +#IMPORTANT: You’ll need to re-create all your 4.x ObiRope components. Data serialization and workflows are significantly different from previous versions. + +### Changed +- Introduced blueprints: particle/constraint object representations are now stored in assets called "blueprints" (as opposed to being stored in the actor itself, as in previous versions). This improves +memory consumption, editor performance, completely separates data from the runtime components that operate on it, and enables easier and faster workflow. +- Non-linear, non-destructive rope editing with instant feedback. +- Simplified underlying engine, constraints are grouped in batches using graph coloring for optimal parallelism. +- Unified handles and pin constraints as "attachments". +- Pin and distance constraints now correctly report forces in Newtons. +- Unitless "Stiffness" parameters have been replaced by "Compliance" parameters in most constraint types, expressed in Newtons/meter. + +### Added +- Support for multiple cursors in a single rope. + +### Removed +- World space/local space simulation. Simulation is now always performed in solver space. +- Solvers no longer have a maxParticles attribute. They dynamically change their capacity at runtime. + +### Fixed +- Crash in certain iOS devices using the A12 cpu. + +## [4.2] + +### Added +- Remade all sample scenes to work in Unity 2019.1 and above. + + +## [4.1] + +#IMPORTANT: You’ll need to re-create all your 3.x ObiRope components, as internal data layout of previous versions as well as serialized GameObject data from previous versions is not compatible with 4.x. + +### Added +- Now you can bake the rope mesh anytime, saving it as a new mesh asset in your project. Useful for set dressing and generating static geometry. Only works for ObiRopeExtrudedMeshRederer and ObiRopeMeshRenderer. +- More accurate collision/contact model, using staggered projections. +- Approximate shock propagation for particle contacts. This makes particle stacking easier and stabler. A new parameter has been added to the solver that controls the amount of shock propagation. +- Split material friction into static and dynamic friction. +- Added rolling contacts w/ rolling friction. These are slightly more expensive than regular contacts. Can be controlled on a per-collision material basis. +- Added ObiInstancedParticleRenderer, allows to draw particles as instances of an arbitrary mesh (requires GPU instancing). +- Particle-particle collision callbacks (solver.OnParticleCollision) + +### Fixed +- Bug that caused mesh colliders with negative thickness to crash. + +### Changed +- More reliable, higher precision algorithm for distance field generation. Specially noticeable in sharp corners/crevices. + +## [4.0.2] + +#IMPORTANT: You’ll need to re-create all your 3.x ObiRope components, as internal data layout of previous versions as well as serialized GameObject data from previous versions is not compatible with 4.x. + +### Changed +- Switched the Windows compiler to Clang/LLVM, resulting in a huge performance improvement. + +### Fixed +- Null ref exception when copying a ObiCloth component. +- Issue with pin constraints overshooting when solver set to world space mode. +- Issue that prevented pin constraints being torn. + +## [4.0] + +#IMPORTANT: You’ll need to re-create all your ObiRope components, as internal data layout of previous versions as well as serialized GameObject data from previous versions is not compatible with 4.x. + +### Added +- New ObiRod actor: advanced rope that models torsion, as well as anisotropic bending and shearing. +- Added 3 new constraint types: Shear/Stretch, Bend/Twist and Chain. +- Achieved zero garbage generation trough the use of new Unity API for camera frustum planes. + +### Changed +- All particle buffers (positions, velocities, etc). are now shared between C++/C# using pointers to aligned memory. This completely eliminates the need for copying data back and forth, simplifies the API + and improves performance. The entire Oni.Get/SetParticle* family of methods has disappeared, now you can work with the particle buffers directly. +- Rope rendering modes have been replaced by ObiRopeRenderer components. + +### Fixed +- Null ref exception when initializing a disabled actor. +- Bug that caused XPBD to be time step dependent. + +## [3.5] + +### Added +- Support for 32 and 64 bit Linux architectures. +- Two-way rigidbody interaction for local-space solvers. +- Added world inertia scale. +- ObiCollider now takes a reference to a Collider, enabling the use of multiple colliders in the same GameObject. + +### Changed +- Separated world velocity scale into linear and angular components. +- World velocity scale is no longer specified per-actor, but per-solver. +- Better ObiProfiler: it now shows a per-thread pyramid diagram of internal jobs, with more human-readable names. + +### Removed +- Solvers no longer have a Collision Layers property. All solvers share the same colliders. Note that you can still use phases to ignore collisions with certain colliders. +- Local space solvers no longer need their own copy of each ObiCollider in the scene, they can all share the same colliders. This results in much higher performance for multiple local-space solvers. + +### Fixed +- Added (float3x3) typecast to particle shaders, to be GLES friendly. + +## [3.4.1] + +### Added +- "Thickness from particles" now works in Custom Mesh render mode. +- Custom Mesh mode now has a "volume scaling" parameter that squashes and stretches the mesh together with the rope. + +## [3.4] + +### Added +- Perspective-correct particle rendering. +- ObiParticleRenderer now supports custom shaders for rendering. + +### Fixed +- Bug that required to disable and re-enable ObiParticleRenderer when moving the actor to a new solver. +- Bug that caused twitching when performing more than 1 physics step per frame when using handles. + +## [3.3.1] + +### Fixed +- Removed unused variable warnings introduced in 3.3 +- Fixed null ref exception when creating a new distance field asset. +- Fixed crash when using multiple solvers in different update modes. +- Fixed some sample scenes lacking collision due to missing distance field. + +## [3.3] + +### Added +- Support for 2D rigidbody coupling has been brought back. +- Added substepping to the core solver. This allows to update each solver at a different effective frequency, and decouple the Obi + physics loop from Unity’s. +- New implementation of fine-grained parallel tasks in core solver, that boosts performance up to x1.5. +- Support for a new type of rope rendering, that can deform any mesh to follow the rope curve. +- Support for a new collision primitive: distance fields. +- Support for per-particle coloring of rope. +- ObiCollider automatically creates ObiRigidbody component if needed when reparenting it. +- Helper script (ObiKinematicVelocities) that calculates angular and linear velocities for kinematic rigidbodies that are transformed around. Useful for continuous collision detection and friction effects against objects that are being moved around using their transform instead of forces. + +### Changed +- Near-zero garbage generation for OnCollision and ObFluidUpdated solver events. +- Near-zero garbage generation for rope rendering. +- Constraints.GetBatches() now returns an IEnumerable. This means it cannot be accesed by index. There’s a helper method GetFirstBatch() that returns +the correctly typed first batch, or null if there’s none. + +### Fixed +- Null reference exception in pin constraints when visualization is enabled. +- Bug that caused asleep particles to miss collisions upon reactivation. +- Bug that caused copying a rope to “steal“ the mesh from the original one. + +## [3.2] +### Added +- Support for CapsuleCollider2D. + +### Changed +- Rope is still rendered (though not simulated) when the ObiRope component is disabled. +- Colliders/rigidbodies are no longer copied over to the C++ library each frame. Instead, only colliders that have their transform or any collision-related property altered are copied to the solver. This greatly improves performance when many colliders are present, and greatly reduces memory allocation and GC activity. +- AllocateParticles() and FreeParticles() have been merged with AddActor() and RemoveActor() respectively. A new per-particle array “particleToActor” makes it faster and easier to know which actor a particle belongs to. + +### Removed +- ObiCollisionGroup has disappeared. It is no longer necessary to manually add colliders to a group, instead each ObiSolver automatically picks up all ObiColliders in a given layer. +- MeshColliders are now always treated as two-sided thin concave meshes. Solid and one-sided modes have disappeared. + +### Fixed +- Android issue that prevented some devices from finding the Oni library. +- Removed redundant menu items. + +## [3.1.1] +### Added +- New “Line” rendering mode for ropes. This will render the rope as a camera-oriented quad strip, similar to what Unity’s LineRenderer does. This is useful for lightweight rendering and 2D games. +- Particle renderer is now much faster and also allocates less memory. +- New “hierarchical” method to generate tether constraints: this method generates more constraints than the traditional “anchor to fixed” approach, but works in the general case even if there are no fixed particles. + +### Changed +- Installation is no longer required. Obi now works right out of the box, so the installation window has been removed, and the “Editor default resources” and “Gizmos” folders removed. + +## [3.1] +### Added +- You can now choose where should the solver be updated: FixedUpdate, AfterFixedUpdate, or LateUpdate. +- Rope rendering now supports variable thickness, based on particle radii. Enabled by default, disable “thickness from particles” to get uniform thickness regardless of particle radii variations. +- Edit-time preview of “smoothness” rope parameter. +- Utility method to calculate actual rope length. +- Support for triggers. A trigger collider will generate contact constraints, but won´t enforce them. +- Contact structs returned by the OnCollision event now include the contact tangent and bitangent vectors. +- Added per-particle layer properties, for finer collision control. + +### Changed +- Faster and more accurate rigidbody impulse application, which results in better collision resolution. +- Greatly improved pin constraint stability for large mass ratios. +- ObiColliderGroup’s Colliders and Colliders2D properties are now plain arrays: “colliders” and “colliders2D”. +- Memory allocation for rope mesh generation has been reduced by 90%. +- ObiParticleRenderer memory allocation has been greatly reduced, and its performance improved. +- Pin constraints are now always drawn in particle edit mode, not only when the particles are selected. + +### Fixed +- Got rid of warnings related to obsolete platform enums in sample scripts. +- Potential bug in GCHandle deallocation affecting upcoming Unity versions (thanks to the guys at Unity for pointing me at this) +- Tearable pin constraints now work correctly. + +## [3.0.1] +### Added +- Support for iOS simulator. +- Faster collision contact generation. + +### Fixed +- Crash in Crane scene due to a bug in pin constraints. + +## [3.0] + +#IMPORTANT: You’ll need to re-generate all your ropes as internal data layout of previous versions is not compatible with this update. +### Added +- Welcome window with automatic installer. +- Upgraded constraint projection to XPBD (extended position-based dynamics). This decouples stiffness and damping from the amount of iterations, resulting in more realistic simulation. +- Solver constraint enforcement order can now be changed. This allows to change the relative importance of constraints. +- The solver now uses a task-based threading system which allows to exploit parallelism between multiple solvers. +- Custom multithreading profiler, that allows to fine-tune performance. +- Optional local-space simulation, for better numerical accuracy in large-scale worlds and greater control. +- ObiStitcher component allows to stitch together separate ropes. +- Added pencil paint mode to particle editor. +- Automatic self-collisions disabling for particles that intersect in rest pose. This allows to set larger particle radii + to ensure better self-collisions, without worrying about constraint fighting. +- Breakable pin constraints. +- Ropes are now tearable, and custom prefabs can be instantiated at both sides of the tear. +- Rope length can be changed at runtime, using the ObiRopeCursor component. +- Procedural curve geometry smoothing. + +### Changed +- Actor particle limit is no longer 16384 but 65536, matching Unity’s own vertex limit. +- Particle editor paint brush falloff has ben changed from linear to gaussian. +- Distance constraints’ compression stiffness has been replaced by a slack percentage. +- Performance improvement in mesh colliders and edge colliders. + +### Fixed +- Bug in collision detection against terrains. +- Crash in 32-bit windows systems due to memory misalignment. +- Bug that caused slow convergence and excessive jittering for particle-particle sequential contact resolution. +- Bug in hierarchical grid update that caused a crash in some cases when a hash key collision happened. +- Bug in continuous collision detection that caused particles to be pushed to the other side of very thin objects. +- Bug in ray/bounding box intersection test caused by non-IEEE754 compliant SSE division by zero. +- Bug that caused ObiParticleRenderer to ignore camera culling mask, and render in all cameras. +- Bug that caused a crash under certain conditions in 32 bit systems. +- Bug that caused particle property value field to reset to the value of the last particle when painting. +- Fixed collision stabilization bug that caused particles to sink slightly when over a dynamic rigidbody. + +## [1.2] + +### Added +- Android support. +- Upgraded constraint projection to XPBD (extended position-based dynamics). This decouples stiffness and damping from the amount of iterations. +- Solver constraint enforcement order can now be changed. This allows to change the relative importance of constraints. +- Welcome window with automatic installer. +- Resolution-preserving method to change rope length dynamically. +- Added pencil paint mode to particle editor. +- Optional local-space simulation, for better numerical accuracy in large-scale worlds and greater control. +- Custom multithreading profiler, that allows to fine-tune performance. +- Better particle visualization in editor. +- Breakable pin constraints. + +### Changed +- Actor particle limit is no longer 16384 but 65536, matching Unity’s own vertex limit. +- Particle editor paint brush falloff has ben changed from linear to gaussian. +- Distance constraints’ compression stiffness has been replaced by a slack percentage. + +### Fixed +- Bug that caused an index out of bounds exception when initializing rope with zero resolution. +- Bug that caused an error message regarding MeshFilter destruction when entering play mode with a rope selected in the hierarchy. +- Bug that prevented the particle editor window from appearing on retina displays. +- 1-frame delay between particle and rigid body physics, which affected pin and collision constraints. + +## [1.1] + +### Added +- MeshColliders are now fully supported. +- Support for 2D physics, Box2D, Circle2D and Edge2D colliders. +- Chain rendering. +- Sleep threshold that keeps particles fixed in place when their kinetic energy is low. +- Chain constraints, that allow for 100% inextensible ropes. +- Rope thickness, twist, cap sections and section shape can now be changed without the need to re-initialize the rope. +- Required constraint components are automatically removed from the object when removing the rope component in editor. + +### Fixed +- Issue with box colliders, that caused incorrect contact generation in corners when using contactOffset. + +## [1.0.0] - 2015-07-16 +- Initial release. diff --git a/xiaofang/Assets/Obi/CHANGELOG_rope.txt.meta b/xiaofang/Assets/Obi/CHANGELOG_rope.txt.meta new file mode 100644 index 00000000..7cc321af --- /dev/null +++ b/xiaofang/Assets/Obi/CHANGELOG_rope.txt.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8d9d04260bc994f1b9d444b675212dc6 +labels: +- ObiRope +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor.meta b/xiaofang/Assets/Obi/Editor.meta new file mode 100644 index 00000000..ec618e6c --- /dev/null +++ b/xiaofang/Assets/Obi/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d6a0c47fa0afb4e1fb441061faa32d50 +folderAsset: yes +timeCreated: 1435569421 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common.meta b/xiaofang/Assets/Obi/Editor/Common.meta new file mode 100644 index 00000000..5684f1cf --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3d5722720e25b4db69e767c6920cf081 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints.meta new file mode 100644 index 00000000..5576b955 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1af54f7feeec0410cada2fc051752b61 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools.meta new file mode 100644 index 00000000..6737bc72 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: aa63386a67f904b399175c9931270250 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiBlueprintEditorTool.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiBlueprintEditorTool.cs new file mode 100644 index 00000000..54dcca92 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiBlueprintEditorTool.cs @@ -0,0 +1,40 @@ +using UnityEngine; +using UnityEditor; + +namespace Obi +{ + public abstract class ObiBlueprintEditorTool + { + protected ObiActorBlueprintEditor editor; + protected string m_Name; + protected Texture m_Icon; + + public string name + { + get { return m_Name; } + } + + public Texture icon + { + get + { + return m_Icon; + } + } + + public ObiBlueprintEditorTool(ObiActorBlueprintEditor editor) + { + this.editor = editor; + } + + public virtual void OnEnable(){} + public virtual void OnDisable(){} + public virtual void OnDestroy(){} + public virtual string GetHelpString() { return string.Empty; } + + public abstract void OnInspectorGUI(); + public virtual void OnSceneGUI(SceneView sceneView){} + + public virtual bool Editable(int index) { return editor.visible[index]; } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiBlueprintEditorTool.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiBlueprintEditorTool.cs.meta new file mode 100644 index 00000000..95c9d3dd --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiBlueprintEditorTool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca0c1c4cbbd024d49b15bf3439506500 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPaintBrushEditorTool.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPaintBrushEditorTool.cs new file mode 100644 index 00000000..c2c9e123 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPaintBrushEditorTool.cs @@ -0,0 +1,130 @@ +using UnityEngine; +using UnityEditor; + +namespace Obi +{ + public class ObiPaintBrushEditorTool : ObiBlueprintEditorTool + { + public ObiRaycastBrush paintBrush; + public bool selectionMask = false; + public int sourcePropertyIndex = 0; /**("BrushIcon"); + m_Name = "Property painting"; + + paintBrush = new ObiRaycastBrush(editor.sourceMesh, + () => + { + // As RecordObject diffs with the end of the current frame, + // and this is a multi-frame operation, we need to use RegisterCompleteObjectUndo instead. + Undo.RegisterCompleteObjectUndo(editor.blueprint, "Paint particles"); + }, + () => + { + editor.Refresh(); + }, + () => + { + EditorUtility.SetDirty(editor.blueprint); + }); + + } + + public override string GetHelpString() + { + return "Paint particle properties directly on the mesh. Most brushes have an alternate mode, accesed by holding 'shift' while painting."; + } + + public override void OnInspectorGUI() + { + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + EditorGUILayout.Space(); + + // toolbar with available brush modes for the current property: + editor.currentProperty.BrushModes(paintBrush); + + EditorGUILayout.Space(); + + EditorGUI.BeginChangeCheck(); + editor.currentPropertyIndex = editor.PropertySelector(editor.currentPropertyIndex); + if (EditorGUI.EndChangeCheck()) + { + editor.Refresh(); + editor.currentProperty.OnSelect(paintBrush); + } + + if (paintBrush.brushMode is ObiFloatCopyBrushMode) + { + EditorGUI.BeginChangeCheck(); + sourcePropertyIndex = editor.PropertySelector(sourcePropertyIndex, "Copy from"); + var sourceProperty = editor.GetProperty(sourcePropertyIndex) as ObiBlueprintFloatProperty; + if (EditorGUI.EndChangeCheck()) + { + (paintBrush.brushMode as ObiFloatCopyBrushMode).source = sourceProperty; + } + if (sourceProperty == null) + EditorGUILayout.HelpBox("You can't copy value from this property.", MessageType.Error); + } + + if (paintBrush.brushMode.needsInputValue) + editor.currentProperty.PropertyField(); + + paintBrush.radius = EditorGUILayout.Slider("Brush size", paintBrush.radius, 0.0001f, 0.5f); + paintBrush.innerRadius = EditorGUILayout.Slider("Brush inner size", paintBrush.innerRadius, 0, 1); + paintBrush.opacity = EditorGUILayout.Slider("Brush opacity", paintBrush.opacity, 0, 1); + paintBrush.mirror.axis = (ObiBrushMirrorSettings.MirrorAxis)EditorGUILayout.EnumPopup("Brush mirror axis", paintBrush.mirror.axis); + paintBrush.mirror.space = (ObiBrushMirrorSettings.MirrorSpace)EditorGUILayout.EnumPopup("Brush mirror space", paintBrush.mirror.space); + + EditorGUI.BeginChangeCheck(); + meshBasedEditor.particleCulling = (ObiMeshBasedActorBlueprintEditor.ParticleCulling)EditorGUILayout.EnumPopup("Culling", meshBasedEditor.particleCulling); + if (ObiActorBlueprintEditor.selectedCount == 0) + { + EditorGUILayout.HelpBox("Select at least one particle to use selection mask.", MessageType.Info); + selectionMask = false; + GUI.enabled = false; + } + selectionMask = EditorGUILayout.Toggle("Selection mask", selectionMask); + if (EditorGUI.EndChangeCheck()) + SceneView.RepaintAll(); + GUI.enabled = true; + + EditorGUILayout.EndVertical(); + + EditorGUILayout.Space(); + GUILayout.Box(GUIContent.none, ObiEditorUtils.GetSeparatorLineStyle()); + + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + + editor.RenderModeSelector(); + editor.currentProperty.VisualizationOptions(); + + EditorGUILayout.EndVertical(); + } + + public override bool Editable(int index) + { + return editor.visible[index] && (!selectionMask || ObiActorBlueprintEditor.selectionStatus[index]); + } + + public override void OnSceneGUI(SceneView view) + { + if (Camera.current != null) + { + var blueprint = meshBasedEditor.blueprint as ObiMeshBasedActorBlueprint; + paintBrush.raycastTransform = blueprint != null ? Matrix4x4.TRS(Vector3.zero, blueprint.rotation, blueprint.scale) : Matrix4x4.identity; + + paintBrush.raycastTarget = meshBasedEditor.sourceMesh; + paintBrush.DoBrush(editor.blueprint.positions); + } + } + + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPaintBrushEditorTool.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPaintBrushEditorTool.cs.meta new file mode 100644 index 00000000..b0abbdf5 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPaintBrushEditorTool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 332bb5fc94a774291b4c4ebe50f61205 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiParticleSelectionEditorTool.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiParticleSelectionEditorTool.cs new file mode 100644 index 00000000..6a21eb66 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiParticleSelectionEditorTool.cs @@ -0,0 +1,336 @@ +using UnityEngine; +using UnityEditor; +using UnityEditorInternal; + +namespace Obi +{ + public class ObiParticleSelectionEditorTool : ObiBlueprintEditorTool + { + ObiScreenSpaceBrush selectionBrush; + ObiSelectBrushMode selectMode; + ObiTethersTool tethersTool; + + protected ReorderableList particleGroupList; + protected bool mixedPropertyValue = false; + protected float minSelectionValue; + protected float maxSelectionValue; + + public ObiParticleSelectionEditorTool(ObiActorBlueprintEditor editor) : base(editor) + { + m_Icon = Resources.Load("SelectIcon"); + m_Name = "Particle selection"; + + selectionBrush = new ObiScreenSpaceBrush(null, UpdateSelection, null); + selectMode = new ObiSelectBrushMode(new ObiBlueprintSelected(editor)); + + selectionBrush.brushMode = selectMode; + tethersTool = new ObiTethersTool(); + + InitializeGroupsList(); + } + + + public override string GetHelpString() + { + if (ObiActorBlueprintEditor.selectedCount > 0) + return "" + ObiActorBlueprintEditor.selectedCount + " selected particles."; + else + return "No particles selected. Click and drag over particles to select them."; + } + + private void InitializeGroupsList() + { + particleGroupList = new ReorderableList(editor.serializedObject, + editor.serializedObject.FindProperty("groups"), + false, true, true, true); + + particleGroupList.drawHeaderCallback = (Rect rect) => + { + EditorGUI.LabelField(rect, "Groups"); + }; + + particleGroupList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => + { + var element = particleGroupList.serializedProperty.GetArrayElementAtIndex(index); + rect.y += 4; + + SerializedObject obj = new SerializedObject(element.objectReferenceValue); + ObiParticleGroup group = obj.targetObject as ObiParticleGroup; + + EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), + obj.FindProperty("m_Name"), new GUIContent("Name")); + rect.y += EditorGUIUtility.singleLineHeight + 2; + + if (GUI.Button(new Rect(rect.x, rect.y, rect.width * 0.5f, EditorGUIUtility.singleLineHeight), "Select", EditorStyles.miniButtonLeft)) + { + if ((Event.current.modifiers & EventModifiers.Shift) == 0) + { + for (int p = 0; p < ObiActorBlueprintEditor.selectionStatus.Length; p++) + ObiActorBlueprintEditor.selectionStatus[p] = false; + } + + foreach (int p in group.particleIndices) + ObiActorBlueprintEditor.selectionStatus[p] = true; + + UpdateSelection(); + } + + if (GUI.Button(new Rect(rect.x + rect.width * 0.5f, rect.y, rect.width * 0.5f, EditorGUIUtility.singleLineHeight), "Set", EditorStyles.miniButtonRight)) + { + group.particleIndices.Clear(); + for (int p = 0; p < ObiActorBlueprintEditor.selectionStatus.Length; p++) + { + if (ObiActorBlueprintEditor.selectionStatus[p]) + group.particleIndices.Add(p); + } + } + + obj.ApplyModifiedProperties(); + }; + + particleGroupList.elementHeight = (EditorGUIUtility.singleLineHeight + 2) * 2 + 8; + + particleGroupList.onAddCallback = (ReorderableList list) => + { + + var group = editor.blueprint.AppendNewParticleGroup("new group"); + + for (int i = 0; i < ObiActorBlueprintEditor.selectionStatus.Length; i++) + { + if (ObiActorBlueprintEditor.selectionStatus[i]) + group.particleIndices.Add(i); + } + + AssetDatabase.SaveAssets(); + }; + + particleGroupList.onRemoveCallback = (ReorderableList list) => + { + editor.blueprint.RemoveParticleGroupAt(list.index); + }; + } + + private void SelectionTools() + { + EditorGUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + if (GUILayout.Button(new GUIContent(Resources.Load("InvertButton"), "Invert selection"), GUILayout.MaxHeight(24), GUILayout.MaxWidth(48))) + { + for (int i = 0; i < ObiActorBlueprintEditor.selectionStatus.Length; i++) + { + if (editor.blueprint.IsParticleActive(i)) + ObiActorBlueprintEditor.selectionStatus[i] = !ObiActorBlueprintEditor.selectionStatus[i]; + } + UpdateSelection(); + } + + GUI.enabled = ObiActorBlueprintEditor.selectedCount > 0; + if (GUILayout.Button(new GUIContent(Resources.Load("ClearButton"), "Clear selection"), GUILayout.MaxHeight(24), GUILayout.MaxWidth(48))) + { + for (int i = 0; i < ObiActorBlueprintEditor.selectionStatus.Length; i++) + ObiActorBlueprintEditor.selectionStatus[i] = false; + UpdateSelection(); + } + + if (GUILayout.Button(new GUIContent(Resources.Load("OptimizeButton"), "Optimize selected"), GUILayout.MaxHeight(24), GUILayout.MaxWidth(48))) + { + Undo.RecordObject(editor.blueprint, "Optimize particles away"); + editor.blueprint.RemoveSelectedParticles(ref ObiActorBlueprintEditor.selectionStatus); + editor.Refresh(); + } + + if (GUILayout.Button(new GUIContent(Resources.Load("RemoveButton"), "Remove selected"), GUILayout.MaxHeight(24), GUILayout.MaxWidth(48))) + { + Undo.RecordObject(editor.blueprint, "Remove particles"); + editor.blueprint.RemoveSelectedParticles(ref ObiActorBlueprintEditor.selectionStatus, false); + editor.Refresh(); + } + GUI.enabled = true; + + if (GUILayout.Button(new GUIContent(Resources.Load("RestoreButton"), "Restore removed particles"), GUILayout.MaxHeight(24), GUILayout.MaxWidth(48))) + { + Undo.RecordObject(editor.blueprint, "Restore removed particles"); + editor.blueprint.RestoreRemovedParticles(); + editor.Refresh(); + } + + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Property-based selection", EditorStyles.boldLabel); + var property = editor.currentProperty as ObiBlueprintFloatProperty; + if (property != null) + { + if (!Mathf.Approximately(property.minVisualizationValue,property.maxVisualizationValue)) + { + EditorGUILayout.HelpBox("Drag the slider to select based on " + property.name + ". You can choose a different property in the \"Property\" dropdown below.", MessageType.None); + minSelectionValue = Mathf.Max(minSelectionValue, property.minVisualizationValue); + maxSelectionValue = Mathf.Min(maxSelectionValue, property.maxVisualizationValue); + maxSelectionValue = Mathf.Max(maxSelectionValue, minSelectionValue); + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.MinMaxSlider("Select by " + property.name, ref minSelectionValue, ref maxSelectionValue, property.minVisualizationValue, property.maxVisualizationValue); + minSelectionValue = EditorGUILayout.FloatField("Minimum " + property.name, minSelectionValue); + maxSelectionValue = EditorGUILayout.FloatField("Maximum " + property.name, maxSelectionValue); + if (EditorGUI.EndChangeCheck()) + { + for (int i = 0; i < ObiActorBlueprintEditor.selectionStatus.Length; i++) + { + if (editor.blueprint.IsParticleActive(i)) + { + var value = property.Get(i); + ObiActorBlueprintEditor.selectionStatus[i] = value >= minSelectionValue && value <= maxSelectionValue; + } + } + UpdateSelection(); + } + } + else + { + EditorGUILayout.HelpBox("All particles have the same " + property.name + " value.", MessageType.Info); + } + } + else + { + EditorGUILayout.HelpBox("Property-based selection only works with scalar properties.",MessageType.Info); + } + } + + public override void OnInspectorGUI() + { + // Selection tools: + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + EditorGUILayout.Space(); + + selectionBrush.radius = EditorGUILayout.Slider("Brush size", selectionBrush.radius, 5, 200); + + if (editor is ObiMeshBasedActorBlueprintEditor) + { + EditorGUI.BeginChangeCheck(); + (editor as ObiMeshBasedActorBlueprintEditor).particleCulling = (ObiMeshBasedActorBlueprintEditor.ParticleCulling)EditorGUILayout.EnumPopup("Culling", (editor as ObiMeshBasedActorBlueprintEditor).particleCulling); + if (EditorGUI.EndChangeCheck()) + SceneView.RepaintAll(); + } + + + EditorGUILayout.Space(); + SelectionTools(); + + EditorGUILayout.EndVertical(); + + + // Properties: + EditorGUILayout.Space(); + GUILayout.Box(GUIContent.none, ObiEditorUtils.GetSeparatorLineStyle()); + + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Properties", EditorStyles.boldLabel); + EditorGUILayout.HelpBox("Select a property to view and edit. Currently editing " + editor.currentProperty.name+".", MessageType.None); + + EditorGUI.BeginChangeCheck(); + editor.currentPropertyIndex = editor.PropertySelector(editor.currentPropertyIndex); + if (EditorGUI.EndChangeCheck()) + { + editor.Refresh(); + UpdateSelection(); + } + + // Property value: + EditorGUI.showMixedValue = mixedPropertyValue; + EditorGUI.BeginChangeCheck(); + editor.currentProperty.PropertyField(); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(editor.blueprint, "Set particle property"); + for (int i = 0; i < ObiActorBlueprintEditor.selectionStatus.Length; i++) + { + if (!ObiActorBlueprintEditor.selectionStatus[i]) continue; + editor.currentProperty.SetDefaultToIndex(i); + } + editor.Refresh(); + } + + EditorGUI.showMixedValue = false; + + EditorGUILayout.EndVertical(); + + + // Particle groups: + EditorGUILayout.Space(); + GUILayout.Box(GUIContent.none, ObiEditorUtils.GetSeparatorLineStyle()); + + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Particle groups", EditorStyles.boldLabel); + particleGroupList.DoLayoutList(); + + EditorGUILayout.EndVertical(); + + + + if (editor.blueprint.usesTethers) + { + EditorGUILayout.Space(); + GUILayout.Box(GUIContent.none, ObiEditorUtils.GetSeparatorLineStyle()); + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + EditorGUILayout.Space(); + tethersTool.DoTethers(editor); + EditorGUILayout.EndVertical(); + } + + EditorGUILayout.Space(); + GUILayout.Box(GUIContent.none, ObiEditorUtils.GetSeparatorLineStyle()); + + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + + editor.RenderModeSelector(); + ObiActorBlueprintEditor.dotRadiusScale = EditorGUILayout.Slider(new GUIContent("Particle dot size"), ObiActorBlueprintEditor.dotRadiusScale, 0, 5); + editor.currentProperty.VisualizationOptions(); + + EditorGUILayout.EndVertical(); + } + + public override void OnSceneGUI(SceneView sceneView) + { + if (Camera.current != null) + selectionBrush.DoBrush(editor.blueprint.positions); + } + + protected void UpdateSelection() + { + ObiActorBlueprintEditor.selectedCount = 0; + mixedPropertyValue = false; + + // Find out how many selected particles we have, and whether they all have the same value for the current property: + for (int i = 0; i < ObiActorBlueprintEditor.selectionStatus.Length; i++) + { + if (editor.blueprint.IsParticleActive(i) && ObiActorBlueprintEditor.selectionStatus[i]) + { + ObiActorBlueprintEditor.selectedCount++; + + if (ObiActorBlueprintEditor.activeParticle >= 0) + { + if (!editor.currentProperty.Equals(ObiActorBlueprintEditor.activeParticle, i)) + mixedPropertyValue = true; + } + else + ObiActorBlueprintEditor.activeParticle = i; + } + else if (ObiActorBlueprintEditor.activeParticle == i) + ObiActorBlueprintEditor.activeParticle = -1; + } + + // Set initial property value: + if (!mixedPropertyValue && ObiActorBlueprintEditor.activeParticle >= 0) + editor.currentProperty.GetDefaultFromIndex(ObiActorBlueprintEditor.activeParticle); + + editor.Repaint(); + SceneView.RepaintAll(); + + } + + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiParticleSelectionEditorTool.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiParticleSelectionEditorTool.cs.meta new file mode 100644 index 00000000..774ebafc --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiParticleSelectionEditorTool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b3940c62f9ffe4808afc4d2d70ae5e28 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPropertyTextureEditorTool.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPropertyTextureEditorTool.cs new file mode 100644 index 00000000..8ceee4b0 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPropertyTextureEditorTool.cs @@ -0,0 +1,166 @@ +using UnityEngine; +using UnityEditor; +using UnityEditorInternal; +using System.Collections; +using System; + +namespace Obi +{ + public class ObiPropertyTextureEditorTool : ObiBlueprintEditorTool + { + public enum TextureChannel + { + Red = 0, + Green = 1, + Blue = 2, + Alpha = 3, + } + + protected bool selectionMask = false; + protected bool import = true; + protected bool export = true; + + protected float minPropertyValue = 0; + protected float maxPropertyValue = 10; + + protected int exportWidth = 512; + protected int exportHeight = 512; + protected int padding = 64; + + protected Texture2D propertyTexture; + protected TextureChannel textureChannel; + + protected ObiBlueprintFloatProperty floatProperty; + protected ObiBlueprintColorProperty colorProperty; + protected Action textureReadCallback; + + public ObiMeshBasedActorBlueprintEditor meshBasedEditor + { + get { return editor as ObiMeshBasedActorBlueprintEditor; } + } + + public ObiPropertyTextureEditorTool(ObiMeshBasedActorBlueprintEditor editor) : base(editor) + { + m_Icon = Resources.Load("TextureIcon"); + m_Name = "Texture import/export"; + } + + public override string GetHelpString() + { + return "Import/export particle properties to textures. Assumes that your mesh has non-overlapping UVs."; + } + + private void FloatFromTexture(int i, Color color) + { + if (!selectionMask || ObiActorBlueprintEditor.selectionStatus[i]) + { + float value = minPropertyValue + color[(int)textureChannel] * (maxPropertyValue - minPropertyValue); + floatProperty.Set(i, value); + } + } + + private void ColorFromTexture(int i, Color color) + { + if (!selectionMask || ObiActorBlueprintEditor.selectionStatus[i]) + colorProperty.Set(i, color); + } + + public override void OnInspectorGUI() + { + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + EditorGUILayout.Space(); + + EditorGUI.BeginChangeCheck(); + editor.currentPropertyIndex = editor.PropertySelector(editor.currentPropertyIndex); + if (EditorGUI.EndChangeCheck()) + editor.Refresh(); + + EditorGUILayout.EndVertical(); + + EditorGUILayout.Space(); + GUILayout.Box(GUIContent.none, ObiEditorUtils.GetSeparatorLineStyle()); + + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + import = EditorGUILayout.BeginFoldoutHeaderGroup(import, "Import texture"); + + if (import) + { + propertyTexture = (Texture2D)EditorGUILayout.ObjectField("Source", propertyTexture, typeof(Texture2D), false); + + floatProperty = editor.currentProperty as ObiBlueprintFloatProperty; + colorProperty = editor.currentProperty as ObiBlueprintColorProperty; + + if (floatProperty != null) + { + textureReadCallback = FloatFromTexture; + textureChannel = (TextureChannel)EditorGUILayout.EnumPopup("Source channel", textureChannel); + minPropertyValue = EditorGUILayout.FloatField("Min value", minPropertyValue); + maxPropertyValue = EditorGUILayout.FloatField("Max value", maxPropertyValue); + } + else if (colorProperty != null) + { + textureReadCallback = ColorFromTexture; + } + + if (GUILayout.Button("Import")) + { + Undo.RecordObject(editor.blueprint, "Import particle property"); + if (!meshBasedEditor.ReadParticlePropertyFromTexture(propertyTexture, textureReadCallback)) + { + EditorUtility.DisplayDialog("Invalid texture", "The texture is either null or not readable.", "Ok"); + } + + // force automatic range calculation for floating point properties. + if (floatProperty != null) + floatProperty.autoRange = true; + editor.Refresh(); + } + } + EditorGUILayout.EndFoldoutHeaderGroup(); + EditorGUILayout.EndVertical(); + + EditorGUILayout.Space(); + GUILayout.Box(GUIContent.none, ObiEditorUtils.GetSeparatorLineStyle()); + + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + export = EditorGUILayout.BeginFoldoutHeaderGroup(export, "Export texture"); + + if (export) + { + exportWidth = EditorGUILayout.IntField("Texture width", exportWidth); + exportHeight = EditorGUILayout.IntField("Texture height", exportHeight); + padding = EditorGUILayout.IntField("Padding", padding); + if (GUILayout.Button("Export")) + { + var path = EditorUtility.SaveFilePanel("Save texture as PNG", + "", + "property.png", + "png"); + if (path.Length > 0) + { + // force automatic range calculation for floating point properties. + if (floatProperty != null) + floatProperty.autoRange = true; + editor.Refresh(); + + if (!meshBasedEditor.WriteParticlePropertyToTexture(path, exportWidth, exportHeight, padding)) + { + EditorUtility.DisplayDialog("Invalid path", "Could not write a texture to that location.", "Ok"); + } + } + } + } + + EditorGUILayout.EndFoldoutHeaderGroup(); + EditorGUILayout.EndVertical(); + + EditorGUILayout.Space(); + GUILayout.Box(GUIContent.none, ObiEditorUtils.GetSeparatorLineStyle()); + + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + editor.RenderModeSelector(); + EditorGUILayout.EndVertical(); + } + + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPropertyTextureEditorTool.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPropertyTextureEditorTool.cs.meta new file mode 100644 index 00000000..0655a767 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiPropertyTextureEditorTool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7727285b07aa44d6e8f65a8bc1f5d972 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiTethersTool.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiTethersTool.cs new file mode 100644 index 00000000..a1e4d29f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiTethersTool.cs @@ -0,0 +1,86 @@ +using UnityEngine; +using UnityEditor; +using System; + + +namespace Obi +{ + public class ObiTethersTool + { + protected Rect tetherDropdownRect; + protected bool[] tetheredGroups = new bool[0]; + + // the GenericMenu.MenuFunction2 event handler for when a menu item is selected + void OnTetherGroupSelected(object index) + { + int i = (int)index; + tetheredGroups[i] = !tetheredGroups[i]; + } + + public void DoTethers(ObiActorBlueprintEditor editor) + { + EditorGUILayout.LabelField("Tethers", EditorStyles.boldLabel); + + var tethers = editor.blueprint.GetConstraintsByType(Oni.ConstraintType.Tether); + int tetherCount = 0; + if (tethers != null) + tetherCount = tethers.GetConstraintCount(); + + if (tetherCount > 0) + EditorGUILayout.LabelField("" + tetherCount + " tether constraints.", EditorStyles.helpBox); + else + EditorGUILayout.LabelField("No tether constraints. Select at least one particle group in the dropdown, then click 'Generate Tethers'.", EditorStyles.helpBox); + + Array.Resize(ref tetheredGroups, editor.blueprint.groups.Count); + + // display the GenericMenu when pressing a button + if (GUILayout.Button("Tethered groups", EditorStyles.popup)) + { + // create the menu and add items to it + GenericMenu menu = new GenericMenu(); + + // forward slashes nest menu items under submenus + for (int i = 0; i < editor.blueprint.groups.Count; ++i) + { + menu.AddItem(new GUIContent(editor.blueprint.groups[i].name), tetheredGroups[i], OnTetherGroupSelected, i); + } + + // display the menu + menu.DropDown(tetherDropdownRect); + } + + if (Event.current.type == EventType.Repaint) + tetherDropdownRect = GUILayoutUtility.GetLastRect(); + + + EditorGUILayout.BeginHorizontal(); + if (GUILayout.Button("Generate tethers",GUILayout.MinHeight(32))) + { + // Select all particles in the tethered groups: + for (int i = 0; i < ObiActorBlueprintEditor.selectionStatus.Length; ++i) + { + ObiActorBlueprintEditor.selectionStatus[i] = false; + for (int j = 0; j < tetheredGroups.Length; ++j) + { + if (tetheredGroups[j] && editor.blueprint.groups[j].ContainsParticle(i)) + { + ObiActorBlueprintEditor.selectionStatus[i] = true; + break; + } + } + } + + editor.blueprint.GenerateTethers(ObiActorBlueprintEditor.selectionStatus); + editor.Refresh(); + } + + if (GUILayout.Button("Clear tethers",GUILayout.MinHeight(32))) + { + editor.blueprint.ClearTethers(); + editor.Refresh(); + } + EditorGUILayout.EndHorizontal(); + + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiTethersTool.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiTethersTool.cs.meta new file mode 100644 index 00000000..fd2ba16f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/BlueprintEditorTools/ObiTethersTool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6aefc9e7e74be461e93ee58f15c5a1dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes.meta new file mode 100644 index 00000000..23624c35 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 625a6e0c1ba72483190830373b7b45fe +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes.meta new file mode 100644 index 00000000..9bdbd1de --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4fc4d44dc6d334c2985875fc6f7b8cb1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/IObiBrushMode.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/IObiBrushMode.cs new file mode 100644 index 00000000..4257fe69 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/IObiBrushMode.cs @@ -0,0 +1,9 @@ +namespace Obi +{ + public interface IObiBrushMode + { + string name{get;} + bool needsInputValue{ get; } + void ApplyStamps(ObiBrushBase brush, bool modified); + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/IObiBrushMode.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/IObiBrushMode.cs.meta new file mode 100644 index 00000000..ab2580d1 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/IObiBrushMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c46364da0f1641c7ab84e12348a6a4b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorPaintBrushMode.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorPaintBrushMode.cs new file mode 100644 index 00000000..e094e7c1 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorPaintBrushMode.cs @@ -0,0 +1,38 @@ +using UnityEngine; + +namespace Obi +{ + public class ObiColorPaintBrushMode : IObiBrushMode + { + ObiBlueprintColorProperty property; + + public ObiColorPaintBrushMode(ObiBlueprintColorProperty property) + { + this.property = property; + } + + public string name + { + get { return "Paint"; } + } + + public bool needsInputValue + { + get { return true; } + } + + public void ApplyStamps(ObiBrushBase brush, bool modified) + { + for (int i = 0; i < brush.weights.Length; ++i) + { + if (!property.Masked(i) && brush.weights[i] > 0) + { + Color currentValue = property.Get(i); + Color delta = brush.weights[i] * brush.opacity * brush.speed * (property.GetDefault() - currentValue); + + property.Set(i, currentValue + delta * (modified ? -1 : 1)); + } + } + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorPaintBrushMode.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorPaintBrushMode.cs.meta new file mode 100644 index 00000000..d9fe6014 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorPaintBrushMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1fd033c8f79b1494d8b8de5c8311f8c1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorSmoothBrushMode.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorSmoothBrushMode.cs new file mode 100644 index 00000000..a5fd9c63 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorSmoothBrushMode.cs @@ -0,0 +1,53 @@ +using UnityEngine; + +namespace Obi +{ + public class ObiColorSmoothBrushMode : IObiBrushMode + { + ObiBlueprintColorProperty property; + + public ObiColorSmoothBrushMode(ObiBlueprintColorProperty property) + { + this.property = property; + } + + public string name + { + get { return "Smooth"; } + } + + public bool needsInputValue + { + get { return false; } + } + + public void ApplyStamps(ObiBrushBase brush, bool modified) + { + Color averageValue = Color.black; + float totalWeight = 0; + + for (int i = 0; i < brush.weights.Length; ++i) + { + if (!property.Masked(i) && brush.weights[i] > 0) + { + averageValue += property.Get(i) * brush.weights[i]; + totalWeight += brush.weights[i]; + } + + } + averageValue /= totalWeight; + + for (int i = 0; i < brush.weights.Length; ++i) + { + if (!property.Masked(i) && brush.weights[i] > 0) + { + Color currentValue = property.Get(i); + Color delta = brush.opacity * brush.speed * (Color.Lerp(currentValue, averageValue, brush.weights[i]) - currentValue); + + property.Set(i, currentValue + delta * (modified ? -1 : 1)); + } + } + + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorSmoothBrushMode.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorSmoothBrushMode.cs.meta new file mode 100644 index 00000000..8a0a75a7 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiColorSmoothBrushMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a69a8a1614478445cbb770a5e123ab18 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatAddBrushMode.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatAddBrushMode.cs new file mode 100644 index 00000000..8c2a5aa8 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatAddBrushMode.cs @@ -0,0 +1,36 @@ +namespace Obi +{ + public class ObiFloatAddBrushMode : IObiBrushMode + { + ObiBlueprintFloatProperty property; + + public ObiFloatAddBrushMode(ObiBlueprintFloatProperty property) + { + this.property = property; + } + + public string name + { + get { return "Add"; } + } + + public bool needsInputValue + { + get { return true; } + } + + public void ApplyStamps(ObiBrushBase brush, bool modified) + { + for (int i = 0; i < brush.weights.Length; ++i) + { + if (!property.Masked(i) && brush.weights[i] > 0) + { + float currentValue = property.Get(i); + float delta = brush.weights[i] * brush.opacity * brush.speed * property.GetDefault(); + + property.Set(i, currentValue + delta * (modified ? -1 : 1)); + } + } + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatAddBrushMode.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatAddBrushMode.cs.meta new file mode 100644 index 00000000..66272b90 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatAddBrushMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8b39e10cedc94461083b3b19c3ddb343 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatCopyBrushMode.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatCopyBrushMode.cs new file mode 100644 index 00000000..ae0b60fe --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatCopyBrushMode.cs @@ -0,0 +1,42 @@ +namespace Obi +{ + public class ObiFloatCopyBrushMode : IObiBrushMode + { + ObiBlueprintFloatProperty property; + public ObiBlueprintFloatProperty source; + + public ObiFloatCopyBrushMode(ObiBlueprintFloatProperty property, ObiBlueprintFloatProperty source) + { + this.property = property; + this.source = source; + } + + public string name + { + get { return "Copy"; } + } + + public bool needsInputValue + { + get { return false; } + } + + public void ApplyStamps(ObiBrushBase brush, bool modified) + { + if (property != null && source != null) + { + for (int i = 0; i < brush.weights.Length; ++i) + { + if (!property.Masked(i) && brush.weights[i] > 0) + { + float currentValue = property.Get(i); + float sourceValue = source.Get(i); + float delta = brush.weights[i] * brush.opacity * brush.speed * (sourceValue - currentValue); + + property.Set(i, currentValue + delta * (modified ? -1 : 1)); + } + } + } + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatCopyBrushMode.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatCopyBrushMode.cs.meta new file mode 100644 index 00000000..a51236b7 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatCopyBrushMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 95bb470841f42415ab256cd64adb9242 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatPaintBrushMode.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatPaintBrushMode.cs new file mode 100644 index 00000000..369a0d1e --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatPaintBrushMode.cs @@ -0,0 +1,37 @@ + +namespace Obi +{ + public class ObiFloatPaintBrushMode : IObiBrushMode + { + ObiBlueprintFloatProperty property; + + public ObiFloatPaintBrushMode(ObiBlueprintFloatProperty property) + { + this.property = property; + } + + public string name + { + get { return "Paint"; } + } + + public bool needsInputValue + { + get { return true; } + } + + public void ApplyStamps(ObiBrushBase brush, bool modified) + { + for (int i = 0; i < brush.weights.Length; ++i) + { + if (!property.Masked(i) && brush.weights[i] > 0) + { + float currentValue = property.Get(i); + float delta = brush.weights[i] * brush.opacity * brush.speed * (property.GetDefault() - currentValue); + + property.Set(i, currentValue + delta * (modified ? -1 : 1)); + } + } + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatPaintBrushMode.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatPaintBrushMode.cs.meta new file mode 100644 index 00000000..94c33004 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatPaintBrushMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb3d176006d404a508bef284d2701ab0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatSmoothBrushMode.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatSmoothBrushMode.cs new file mode 100644 index 00000000..35cfcdbc --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatSmoothBrushMode.cs @@ -0,0 +1,55 @@ +using UnityEngine; + +namespace Obi +{ + public class ObiFloatSmoothBrushMode : IObiBrushMode + { + ObiBlueprintFloatProperty property; + + public ObiFloatSmoothBrushMode(ObiBlueprintFloatProperty property) + { + this.property = property; + } + + public string name + { + get { return "Smooth"; } + } + + public bool needsInputValue + { + get { return false; } + } + + public void ApplyStamps(ObiBrushBase brush, bool modified) + { + var floatProperty = (ObiBlueprintFloatProperty)property; + + float averageValue = 0; + float totalWeight = 0; + + for (int i = 0; i < brush.weights.Length; ++i) + { + if (!property.Masked(i) && brush.weights[i] > 0) + { + averageValue += floatProperty.Get(i) * brush.weights[i]; + totalWeight += brush.weights[i]; + } + + } + averageValue /= totalWeight; + + for (int i = 0; i < brush.weights.Length; ++i) + { + if (!property.Masked(i) && brush.weights[i] > 0) + { + float currentValue = floatProperty.Get(i); + float delta = brush.opacity * brush.speed * (Mathf.Lerp(currentValue,averageValue,brush.weights[i]) - currentValue); + + floatProperty.Set(i, currentValue + delta * (modified ? -1 : 1)); + } + } + + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatSmoothBrushMode.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatSmoothBrushMode.cs.meta new file mode 100644 index 00000000..d3a486a2 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiFloatSmoothBrushMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63dad56a994af4db7bb3449382022c54 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiIntPaintBrushMode.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiIntPaintBrushMode.cs new file mode 100644 index 00000000..426e4c68 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiIntPaintBrushMode.cs @@ -0,0 +1,33 @@ +namespace Obi +{ + public class ObiIntPaintBrushMode : IObiBrushMode + { + ObiBlueprintIntProperty property; + + public ObiIntPaintBrushMode(ObiBlueprintIntProperty property) + { + this.property = property; + } + + public string name + { + get { return "Paint"; } + } + + public bool needsInputValue + { + get { return true; } + } + + public void ApplyStamps(ObiBrushBase brush, bool modified) + { + for (int i = 0; i < brush.weights.Length; ++i) + { + if (!property.Masked(i) && brush.weights[i] > (1 - brush.opacity)) + { + property.Set(i, property.GetDefault()); + } + } + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiIntPaintBrushMode.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiIntPaintBrushMode.cs.meta new file mode 100644 index 00000000..0bef4606 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiIntPaintBrushMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d8882849c81104cef80b3dfdab2021c9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiMasterSlavePaintBrushMode.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiMasterSlavePaintBrushMode.cs new file mode 100644 index 00000000..2691275a --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiMasterSlavePaintBrushMode.cs @@ -0,0 +1,39 @@ +namespace Obi +{ + public class ObiMasterSlavePaintBrushMode : IObiBrushMode + { + ObiBlueprintIntProperty property; + + public ObiMasterSlavePaintBrushMode(ObiBlueprintIntProperty property) + { + this.property = property; + } + + public string name + { + get { return "Master/Slave paint"; } + } + + public bool needsInputValue + { + get { return true; } + } + + public void ApplyStamps(ObiBrushBase brush, bool modified) + { + for (int i = 0; i < brush.weights.Length; ++i) + { + if (!property.Masked(i) && brush.weights[i] > (1 - brush.opacity)) + { + int currentValue = property.Get(i); + + if (modified) + currentValue &= ~(int)(1 << property.GetDefault()); + else currentValue |= (int)(1 << property.GetDefault()); + + property.Set(i, currentValue); + } + } + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiMasterSlavePaintBrushMode.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiMasterSlavePaintBrushMode.cs.meta new file mode 100644 index 00000000..83254b41 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiMasterSlavePaintBrushMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62f8e9adfc17440359a9b51005cd0948 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiSelectBrushMode.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiSelectBrushMode.cs new file mode 100644 index 00000000..66d732c0 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiSelectBrushMode.cs @@ -0,0 +1,33 @@ +namespace Obi +{ + public class ObiSelectBrushMode : IObiBrushMode + { + ObiBlueprintSelected property; + string customName; + + public ObiSelectBrushMode(ObiBlueprintSelected property, string customName = "Select") + { + this.property = property; + this.customName = customName; + } + + public string name + { + get { return customName; } + } + + public bool needsInputValue + { + get { return true; } + } + + public void ApplyStamps(ObiBrushBase brush, bool modified) + { + for (int i = 0; i < brush.weights.Length; ++i) + { + if (brush.weights[i] > 0 && !property.Masked(i)) + property.Set(i,!modified); + } + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiSelectBrushMode.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiSelectBrushMode.cs.meta new file mode 100644 index 00000000..ed3edeab --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/BrushModes/ObiSelectBrushMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9cea7ef42253f4d2b9b5a222521cdee8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushBase.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushBase.cs new file mode 100644 index 00000000..37951d48 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushBase.cs @@ -0,0 +1,161 @@ +using UnityEngine; +using UnityEditor; +using System; + +namespace Obi +{ + + public abstract class ObiBrushBase + { + static int particleBrushHash = "ObiBrushHash".GetHashCode(); + + public IObiBrushMode brushMode; + public float radius = 1; + public float innerRadius = 0.5f; + public float opacity = 1; + public float[] weights = new float[0]; + public bool drag = true; + public float speed = 0.1f; + + protected int controlID; + protected Action onStrokeStart; + protected Action onStrokeUpdate; + protected Action onStrokeEnd; + + public float SqrRadius + { + get{ return radius * radius; } + } + + public ObiBrushBase(Action onStrokeStart, Action onStrokeUpdate, Action onStrokeEnd) + { + this.onStrokeStart = onStrokeStart; + this.onStrokeUpdate = onStrokeUpdate; + this.onStrokeEnd = onStrokeEnd; + } + + protected virtual float WeightFromDistance(float distance) + { + // anything outside the brush should have zero weight: + if (distance > radius) + return 0; + + float t = Mathf.InverseLerp(innerRadius * radius, radius, distance); + return Mathf.SmoothStep(1, 0, t); + } + + protected abstract void GenerateWeights(Vector3[] positions); + + protected virtual void OnMouseDown(Vector3[] positions) + { + if (Event.current.button != 0 || (Event.current.modifiers & ~EventModifiers.Shift) != EventModifiers.None) + return; + + GUIUtility.hotControl = controlID; + + GenerateWeights(positions); + + if (onStrokeStart != null) + onStrokeStart(); + + if (brushMode != null) + brushMode.ApplyStamps(this, (Event.current.modifiers & EventModifiers.Shift) != 0); + + if (onStrokeUpdate != null) + onStrokeUpdate(); + + Event.current.Use(); + } + + protected virtual void OnMouseMove(Vector3[] positions) + { + + } + + protected virtual void OnMouseDrag(Vector3[] positions) + { + + if (GUIUtility.hotControl == controlID && drag) + { + + GenerateWeights(positions); + + if (brushMode != null) + brushMode.ApplyStamps(this, (Event.current.modifiers & EventModifiers.Shift) != 0); + + if (onStrokeUpdate != null) + onStrokeUpdate(); + + Event.current.Use(); + + } + } + + protected virtual void OnMouseUp(Vector3[] positions) + { + if (GUIUtility.hotControl == controlID) + { + + GUIUtility.hotControl = 0; + Event.current.Use(); + + if (onStrokeEnd != null) + onStrokeEnd(); + } + } + + protected virtual void OnRepaint() + { + } + + public void DoBrush(Vector3[] positions) + { + + Matrix4x4 cachedMatrix = Handles.matrix; + + controlID = GUIUtility.GetControlID(particleBrushHash, FocusType.Passive); + Array.Resize(ref weights, positions.Length); + + switch (Event.current.GetTypeForControl(controlID)) + { + + case EventType.MouseDown: + + OnMouseDown(positions); + + break; + + case EventType.MouseMove: + + OnMouseMove(positions); + + SceneView.RepaintAll(); + break; + + case EventType.MouseDrag: + + OnMouseDrag(positions); + + break; + + case EventType.MouseUp: + + OnMouseUp(positions); + + break; + + case EventType.Repaint: + + Handles.matrix = Matrix4x4.identity; + + OnRepaint(); + + Handles.matrix = cachedMatrix; + + break; + + } + } + } +} + diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushBase.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushBase.cs.meta new file mode 100644 index 00000000..692767df --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 094253962d646436792561e708e62376 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushMirrorSettings.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushMirrorSettings.cs new file mode 100644 index 00000000..c4bd65c1 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushMirrorSettings.cs @@ -0,0 +1,51 @@ +using System; +using UnityEngine; + +[Serializable] +public struct ObiBrushMirrorSettings +{ + [Flags] + public enum MirrorAxis + { + None = 0x0, + X = 0x1, + Y = 0x2, + Z = 0x4 + } + + public enum MirrorSpace + { + World = 0, + Camera = 1 + } + + public MirrorAxis axis; + public MirrorSpace space; + + public Vector3 ToAxis() + { + uint m = (uint)axis; + + bool xMirror = (m & (uint)MirrorAxis.X) > 0; + bool yMirror = (m & (uint)MirrorAxis.Y) > 0; + bool zMirror = (m & (uint)MirrorAxis.Z) > 0; + + if (axis < 0 || ((int)axis > (int)MirrorAxis.X + (int)MirrorAxis.Y + (int)MirrorAxis.Z)) + { + return Vector3.one; + } + + Vector3 reflection = Vector3.one; + + if (xMirror) + reflection.x = -1f; + + if (yMirror) + reflection.y = -1f; + + if (zMirror) + reflection.z = -1f; + + return reflection; + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushMirrorSettings.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushMirrorSettings.cs.meta new file mode 100644 index 00000000..d33b4379 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiBrushMirrorSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d10a9257ac23248418439eb80e02a611 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiRaycastBrush.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiRaycastBrush.cs new file mode 100644 index 00000000..0578e888 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiRaycastBrush.cs @@ -0,0 +1,125 @@ +using UnityEngine; +using UnityEditor; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Obi +{ + + public class ObiRaycastBrush : ObiBrushBase + { + public Matrix4x4 raycastTransform = Matrix4x4.identity; + public Mesh raycastTarget = null; + public bool drawVolume = false; + private List rays = new List(); + private List hits = new List(); + + public ObiBrushMirrorSettings mirror; + + public ObiRaycastBrush(Mesh raycastTarget, Action onStrokeStart, Action onStrokeUpdate, Action onStrokeEnd) : base(onStrokeStart, onStrokeUpdate, onStrokeEnd) + { + radius = 0.1f; + this.raycastTarget = raycastTarget; + rays = new List(); + } + + protected override void GenerateWeights(Vector3[] positions) + { + if (raycastTarget != null) + { + rays.Clear(); + hits.Clear(); + + for (int i = 0; i < positions.Length; i++) + weights[i] = 0; + + var vertices = raycastTarget.vertices; + var triangles = raycastTarget.triangles; + + Ray mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); + rays.Add(mouseRay); + + ObiBrushMirrorSettings currentAxis = mirror; + + if (mirror.axis != ObiBrushMirrorSettings.MirrorAxis.None) + { + for (int i = 0; i < 3; i++) + { + currentAxis.axis = (ObiBrushMirrorSettings.MirrorAxis)(1u << i); + if (((uint)mirror.axis & (1u << i)) < 1) + continue; + + Vector3 mirrorVector = currentAxis.ToAxis(); + + if (currentAxis.space == ObiBrushMirrorSettings.MirrorSpace.World) + { + Vector3 center = raycastTarget.bounds.center; + rays.Add(new Ray(Vector3.Scale(mouseRay.origin - center, mirrorVector) + center, + Vector3.Scale(mouseRay.direction, mirrorVector))); + } + else + { + Transform t = SceneView.lastActiveSceneView.camera.transform; + Vector3 o = t.InverseTransformPoint(mouseRay.origin); + Vector3 d = t.InverseTransformDirection(mouseRay.direction); + rays.Add(new Ray(t.TransformPoint(Vector3.Scale(o, mirrorVector)), + t.TransformDirection(Vector3.Scale(d, mirrorVector)))); + } + } + } + + foreach (var ray in rays) + { + if (ObiMeshUtils.WorldRaycast(ray, raycastTransform, vertices, triangles, out ObiRaycastHit hit)) + { + hit.position = raycastTransform.MultiplyPoint3x4(hit.position); + hit.normal = raycastTransform.MultiplyVector(hit.normal); + hits.Add(hit); + + for (int i = 0; i < positions.Length; i++) + { + // get distance from hit position to particle position: + float weight = WeightFromDistance(Vector3.Distance(hit.position, positions[i])); + weights[i] = Mathf.Max(weights[i], weight); + } + } + } + } + } + + protected override void OnMouseMove(Vector3[] positions) + { + base.OnMouseMove(positions); + GenerateWeights(positions); + } + + protected override void OnRepaint() + { + base.OnRepaint(); + + if (raycastTarget != null) + { + Color brushColor = ObiEditorSettings.GetOrCreateSettings().brushColor; + + foreach (var hit in hits) + { + if (hit != null && hit.triangle >= 0) + { + Handles.color = brushColor; + Handles.DrawLine(hit.position, hit.position + hit.normal.normalized * radius); + Handles.DrawWireDisc(hit.position, hit.normal, radius); + Handles.DrawWireDisc(hit.position, hit.normal, innerRadius * radius); + + if (drawVolume) + { + Handles.color = new Color(brushColor.r, brushColor.g, brushColor.b, 0.2f); + Handles.SphereHandleCap(0, hit.position, Quaternion.identity, radius * 2, EventType.Repaint); + } + } + } + } + } + } +} + diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiRaycastBrush.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiRaycastBrush.cs.meta new file mode 100644 index 00000000..d3e4fb08 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiRaycastBrush.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d925323750dca4dcaa5cca91b18521b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiScreenSpaceBrush.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiScreenSpaceBrush.cs new file mode 100644 index 00000000..341b491b --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiScreenSpaceBrush.cs @@ -0,0 +1,61 @@ +using UnityEngine; +using UnityEditor; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Obi +{ + + public class ObiScreenSpaceBrush : ObiBrushBase + { + public ObiScreenSpaceBrush(Action onStrokeStart, Action onStrokeUpdate, Action onStrokeEnd) : base(onStrokeStart, onStrokeUpdate, onStrokeEnd) + { + radius = 32; + } + + protected override float WeightFromDistance(float distance) + { + // anything outside the brush should have zero weight: + if (distance * EditorGUIUtility.pixelsPerPoint > radius) + return 0; + return 1; + } + + protected override void GenerateWeights(Vector3[] positions) + { + for (int i = 0; i < positions.Length; i++) + { + // get particle position in gui space: + Vector2 pos = HandleUtility.WorldToGUIPoint(positions[i]); + + // get distance from mouse position to particle position: + weights[i] = WeightFromDistance(Vector3.Distance(Event.current.mousePosition, pos)); + } + } + + protected override void OnRepaint() + { + base.OnRepaint(); + + Camera cam = Camera.current; + float depth = (cam.nearClipPlane + cam.farClipPlane) * 0.5f; + + float ppp = EditorGUIUtility.pixelsPerPoint; + Vector2 mousePos = new Vector2(Event.current.mousePosition.x * ppp, + cam.pixelHeight - Event.current.mousePosition.y * ppp); + + Handles.color = ObiEditorSettings.GetOrCreateSettings().brushColor; + Vector3 point = new Vector3(mousePos.x, mousePos.y, depth); + Vector3 wsPoint = cam.ScreenToWorldPoint(point); + + var p1 = cam.ScreenToWorldPoint(new Vector3(1, 0, depth)); + var p2 = cam.ScreenToWorldPoint(new Vector3(0, 0, depth)); + float units = Vector3.Distance(p1, p2); + + Handles.DrawWireDisc(wsPoint, cam.transform.forward, radius * units); + } + + } +} + diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiScreenSpaceBrush.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiScreenSpaceBrush.cs.meta new file mode 100644 index 00000000..71c3ff40 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Brushes/ObiScreenSpaceBrush.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38fc5288fb3c94ebeb7eaa88a3bc5119 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditor.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditor.cs new file mode 100644 index 00000000..0e819c69 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditor.cs @@ -0,0 +1,477 @@ +using UnityEngine; +using UnityEngine.Rendering; +using UnityEditor; +using UnityEngine.SceneManagement; +using UnityEditor.SceneManagement; +using System.Collections; +using System.Collections.Generic; +using System; +using System.Linq; + +namespace Obi +{ + + [CustomEditor(typeof(ObiActorBlueprint), true)] + public class ObiActorBlueprintEditor : Editor, IObiSelectableParticleProvider + { + public List tools = new List(); + public int currentToolIndex = 0; + + public List properties = new List(); + public int currentPropertyIndex = 0; + + public List renderModes = new List(); + public int renderModeFlags = 0; + BooleanPreference showRenderModes; + + public bool autoGenerate = false; + public bool editMode = false; + public bool isEditing = false; + protected UnityEngine.Object oldSelection; + + //Additional status info for all particles: + public static float dotRadiusScale = 1; + public static int selectedCount = 0; + public static int activeParticle = -1; + public static bool[] selectionStatus = new bool[0]; + + public bool[] visible = new bool[0]; + public Color[] tint = new Color[0]; + protected float[] sqrDistanceToCamera = new float[0]; + public int[] sortedIndices = new int[0]; + + public ObiActorBlueprint blueprint + { + get { return target as ObiActorBlueprint; } + } + + public ObiBlueprintPropertyBase currentProperty + { + get { return GetProperty(currentPropertyIndex); } + } + + public ObiBlueprintEditorTool currentTool + { + get { return GetTool(currentToolIndex); } + } + + public override bool UseDefaultMargins() + { + return false; + } + + public ObiBlueprintPropertyBase GetProperty(int index) + { + return (properties.Count > index && index >= 0) ? properties[index] : null; + } + + public ObiBlueprintEditorTool GetTool(int index) + { + return (tools.Count > index && index >= 0) ? tools[index] : null; + } + +#if (UNITY_2019_1_OR_NEWER) + System.Action renderCallback; +#endif + + public virtual void OnEnable() + { + properties.Clear(); + renderModes.Clear(); + tools.Clear(); + + properties.Add(new ObiBlueprintMass(this)); + properties.Add(new ObiBlueprintRadius(this)); + properties.Add(new ObiBlueprintFilterCategory(this)); + properties.Add(new ObiBlueprintFilterMask(this)); + + renderModes.Add(new ObiBlueprintRenderModeParticles(this)); + showRenderModes = new BooleanPreference($"{target.GetType()}.showRenderModes", false); + +#if (UNITY_2019_1_OR_NEWER) + renderCallback = new System.Action((cntxt, cam) => { DrawWithCamera(cam); }); + RenderPipelineManager.beginCameraRendering += renderCallback; +#endif + Camera.onPreCull += DrawWithCamera; + SceneView.duringSceneGui += OnSceneGUI; + + EditorApplication.playModeStateChanged += OnPlayModeStateChanged; + } + + public virtual void OnDisable() + { + ExitBlueprintEditMode(); + +#if (UNITY_2019_1_OR_NEWER) + RenderPipelineManager.beginCameraRendering -= renderCallback; +#endif + Camera.onPreCull -= DrawWithCamera; + SceneView.duringSceneGui -= OnSceneGUI; + EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; + + foreach (var tool in tools) + { + tool.OnDisable(); + tool.OnDestroy(); + } + + foreach (var renderMode in renderModes) + { + renderMode.OnDestroy(); + } + } + + void OnPlayModeStateChanged(PlayModeStateChange playmodeState) + { + if (playmodeState == PlayModeStateChange.ExitingEditMode) + { + if (StageUtility.GetCurrentStage() is ObiActorBlueprintEditorStage) + StageUtility.GoToMainStage(); + } + } + + protected bool Generate() + { + if (!blueprint.edited) + { + EditorUtility.SetDirty(target); + CoroutineJob job = new CoroutineJob(); + IEnumerator routine = job.Start(blueprint.Generate()); + EditorCoroutine.ShowCoroutineProgressBar("Generating blueprint...", routine); + Refresh(); + EditorGUIUtility.ExitGUI(); + } + else + { + if (EditorUtility.DisplayDialog("Blueprint generation", "This blueprint contains manually edited data. If you regenerate the blueprint, these changes will be lost. Are you sure you want to proceed?", "Ok", "Cancel")) + { + EditorUtility.SetDirty(target); + CoroutineJob job = new CoroutineJob(); + IEnumerator routine = job.Start(blueprint.Generate()); + EditorCoroutine.ShowCoroutineProgressBar("Generating blueprint...", routine); + Refresh(); + EditorGUIUtility.ExitGUI(); + } + else return false; + } + return true; + } + + protected virtual bool ValidateBlueprint() { return true; } + + private void DrawGenerationControls() + { + GUILayout.BeginHorizontal(); + + float originalLabelWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 72; + autoGenerate = EditorGUILayout.ToggleLeft("Auto Generate", autoGenerate, GUILayout.ExpandWidth(false)); + EditorGUIUtility.labelWidth = originalLabelWidth; + + GUI.enabled = !autoGenerate; + if (GUILayout.Button("Generate", GUI.skin.FindStyle("LargeButton"), GUILayout.Height(32))) + Generate(); + + GUILayout.EndHorizontal(); + } + + public override void OnInspectorGUI() + { + serializedObject.UpdateIfRequiredOrScript(); + + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + + EditorGUI.BeginChangeCheck(); + DrawBlueprintProperties(); + bool blueprintPropertiesChanged = EditorGUI.EndChangeCheck(); + bool blueprintValid = ValidateBlueprint(); + + GUILayout.Space(10); + + GUI.enabled = blueprintValid; + DrawGenerationControls(); + + GUI.enabled = (blueprint != null && !blueprint.empty && !Application.isPlaying); + EditorGUI.BeginChangeCheck(); + editMode = GUILayout.Toggle(editMode, editMode ? "Done" : "Edit", "Button"); + if (EditorGUI.EndChangeCheck()) + { + if (editMode) + EditorApplication.delayCall += EnterBlueprintEditMode; + else + EditorApplication.delayCall += ExitBlueprintEditMode; + } + EditorGUILayout.EndVertical(); + GUI.enabled = true; + + if (isEditing) + DrawTools(); + + if (GUI.changed) + { + serializedObject.ApplyModifiedPropertiesWithoutUndo(); + + if (autoGenerate && blueprintValid && blueprintPropertiesChanged) + blueprint.GenerateImmediate(); + + // There might be blueprint editing operations that have no undo entry, so do this to + // ensure changes are serialized to disk by Unity. + EditorUtility.SetDirty(target); + } + + } + + protected virtual void DrawBlueprintProperties() + { + Editor.DrawPropertiesExcluding(serializedObject, "m_Script"); + } + + private void DrawWithCamera(Camera camera) + { + if (editMode) + { + for (int i = 0; i < renderModes.Count; ++i) + { + if ((1 << i & renderModeFlags) != 0) + renderModes[i].DrawWithCamera(camera); + } + } + } + + void EnterBlueprintEditMode() + { + if (!isEditing) + { + ActiveEditorTracker.sharedTracker.isLocked = true; + + string assetPath = AssetDatabase.GetAssetPath(blueprint); + ObiActorBlueprintEditorStage stage = ObiActorBlueprintEditorStage.CreateStage(assetPath, this); + StageUtility.GoToStage(stage, true); + + isEditing = true; + } + } + + void ExitBlueprintEditMode() + { + if (isEditing) + { + isEditing = false; + AssetDatabase.SaveAssets(); + StageUtility.GoToMainStage(); + } + } + + public void CleanupEditor() + { + ActiveEditorTracker.sharedTracker.isLocked = false; + ObiParticleEditorDrawing.DestroyParticlesMesh(); + } + + public virtual void OnSceneGUI(SceneView sceneView) + { + + if (!isEditing || sceneView.camera == null) + return; + + ResizeParticleArrays(); + + Event e = Event.current; + + if (e.type == EventType.Repaint) + { + + // Update camera facing status and world space positions array: + UpdateParticleVisibility(sceneView.camera); + + // Generate sorted indices for back-to-front rendering: + for (int i = 0; i < sortedIndices.Length; i++) + sortedIndices[i] = i; + Array.Sort(sortedIndices, (a, b) => sqrDistanceToCamera[b].CompareTo(sqrDistanceToCamera[a])); + + // render modes OnSceneRepaint: + for (int i = 0; i < renderModes.Count; ++i) + { + if ((1 << i & renderModeFlags) != 0) + renderModes[i].OnSceneRepaint(sceneView); + } + + // property OnSceneRepaint: + currentProperty.OnSceneRepaint(); + + // update particle color based on visiblity, etc. + UpdateTintColor(); + + // Draw particle handles: + ObiParticleEditorDrawing.DrawParticles(sceneView.camera, blueprint, visible, tint, sortedIndices, dotRadiusScale); + + } + + if (currentTool != null) + currentTool.OnSceneGUI(sceneView); + + } + + protected virtual void UpdateTintColor() + { + Color regularColor = ObiEditorSettings.GetOrCreateSettings().particleColor; + Color selectedColor = ObiEditorSettings.GetOrCreateSettings().selectedParticleColor; + Color activeColor = ObiEditorSettings.GetOrCreateSettings().activeParticleColor; + + for (int i = 0; i < blueprint.positions.Length; i++) + { + // get particle color: + if (activeParticle == i) + tint[i] = activeColor; + else + tint[i] = selectionStatus[i] ? selectedColor : regularColor; + + tint[i].a = visible[i] ? 1 : 0.15f; + } + } + + protected void ResizeParticleArrays() + { + if (blueprint.positions != null) + { + activeParticle = Mathf.Min(activeParticle, blueprint.positions.Length - 1); + Array.Resize(ref selectionStatus, blueprint.positions.Length); + Array.Resize(ref visible, blueprint.positions.Length); + Array.Resize(ref tint, blueprint.positions.Length); + Array.Resize(ref sqrDistanceToCamera, blueprint.positions.Length); + Array.Resize(ref sortedIndices, blueprint.positions.Length); + } + + } + + public int PropertySelector(int propertyIndex, string label = "Property") + { + // get all particle properties: + string[] propertyNames = new string[properties.Count]; + for (int i = 0; i < properties.Count; ++i) + propertyNames[i] = properties[i].name; + + // Draw a selection dropdown: + return EditorGUILayout.Popup(label, propertyIndex, propertyNames); + } + + public virtual void RenderModeSelector() + { + showRenderModes.value = EditorGUILayout.BeginFoldoutHeaderGroup(showRenderModes, "Render modes"); + if (showRenderModes) + { + EditorGUI.BeginChangeCheck(); + for (int i = 0; i < renderModes.Count; ++i) + { + int value = 1 << i; + + if (EditorGUILayout.Toggle(renderModes[i].name, (value & renderModeFlags) != 0)) + renderModeFlags |= value; + else + renderModeFlags &= ~value; + } + if (EditorGUI.EndChangeCheck()) + Refresh(); + } + EditorGUILayout.EndFoldoutHeaderGroup(); + } + + public void Refresh() + { + // currentProperty might be null after reloading editor during + // asset saving. + currentProperty?.RecalculateMinMax(); + + // refresh render modes: + for (int i = 0; i < renderModes.Count; ++i) + { + if ((1 << i & renderModeFlags) != 0) + renderModes[i].Refresh(); + } + + SceneView.RepaintAll(); + } + + public virtual void UpdateParticleVisibility(Camera cam) + { + + for (int i = 0; i < blueprint.positions.Length; i++) + { + if (blueprint.IsParticleActive(i)) + { + visible[i] = true; + + if (Camera.current != null) + { + Vector3 camToParticle = cam.transform.position - blueprint.positions[i]; + sqrDistanceToCamera[i] = camToParticle.sqrMagnitude; + } + } + } + + if ((renderModeFlags & 1) != 0) + Refresh(); + } + + protected void DrawTools() + { + + GUIContent[] contents = new GUIContent[tools.Count]; + + for (int i = 0; i < tools.Count; ++i) + contents[i] = new GUIContent(tools[i].icon, tools[i].name); + + EditorGUILayout.Space(); + GUILayout.Box(GUIContent.none, ObiEditorUtils.GetSeparatorLineStyle()); + EditorGUILayout.Space(); + + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + EditorGUI.BeginChangeCheck(); + int newSelectedTool = ObiEditorUtils.DoToolBar(currentToolIndex, contents); + EditorGUILayout.EndVertical(); + + if (EditorGUI.EndChangeCheck()) + { + if (currentTool != null) + currentTool.OnDisable(); + + currentToolIndex = newSelectedTool; + + if (currentTool != null) + currentTool.OnEnable(); + + SceneView.RepaintAll(); + } + + if (currentTool != null) + { + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + EditorGUILayout.LabelField(currentTool.name, EditorStyles.boldLabel); + + string help = currentTool.GetHelpString(); + if (!help.Equals(string.Empty)) + EditorGUILayout.LabelField(help, EditorStyles.helpBox); + EditorGUILayout.EndVertical(); + + currentTool.OnInspectorGUI(); + } + + } + + public void SetSelected(int particleIndex, bool selected) + { + selectionStatus[particleIndex] = selected; + } + + public bool IsSelected(int particleIndex) + { + return selectionStatus[particleIndex]; + } + + public bool Editable(int particleIndex) + { + return currentTool.Editable(particleIndex) && blueprint.IsParticleActive(particleIndex); + } + } + +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditor.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditor.cs.meta new file mode 100644 index 00000000..c1fbbade --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e39e6eea226f4ecbbe091613ff79f85 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditorStage.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditorStage.cs new file mode 100644 index 00000000..561ee897 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditorStage.cs @@ -0,0 +1,72 @@ +using System; +using System.IO; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; + +namespace Obi +{ + [Serializable] + class ObiActorBlueprintEditorStage : PreviewSceneStage + { + ObiActorBlueprintEditor m_BlueprintEditor; + + string m_AssetPath; + public override string assetPath { get { return m_AssetPath; } } + + internal static ObiActorBlueprintEditorStage CreateStage(string assetPath, ObiActorBlueprintEditor avatarEditor) + { + ObiActorBlueprintEditorStage stage = CreateInstance(); + stage.Init(assetPath, avatarEditor); + return stage; + } + + private void Init(string modelAssetPath, ObiActorBlueprintEditor avatarEditor) + { + m_AssetPath = modelAssetPath; + m_BlueprintEditor = avatarEditor; + } + + protected override bool OnOpenStage() + { + base.OnOpenStage(); + + if (!File.Exists(assetPath)) + { + Debug.LogError("ActivateStage called on BlueprintStage with an invalid path: Blueprint file not found " + assetPath); + return false; + } + + return true; + } + + protected override void OnCloseStage() + { + m_BlueprintEditor.CleanupEditor(); + + base.OnCloseStage(); + } + + protected override void OnFirstTimeOpenStageInSceneView(SceneView sceneView) + { + // Frame in scene view + sceneView.Frame(m_BlueprintEditor.blueprint.bounds); + + // Setup Scene view state + sceneView.sceneViewState.showFlares = false; + sceneView.sceneViewState.alwaysRefresh = false; + sceneView.sceneViewState.showFog = false; + sceneView.sceneViewState.showSkybox = false; + sceneView.sceneViewState.showImageEffects = false; + sceneView.sceneViewState.showParticleSystems = false; + sceneView.sceneLighting = true; + } + + protected override GUIContent CreateHeaderContent() + { + return new GUIContent( + "Blueprint Editor", + Resources.Load("Icons/ObiActorBlueprint Icon")); + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditorStage.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditorStage.cs.meta new file mode 100644 index 00000000..91b16abe --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiActorBlueprintEditorStage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c8d9d8042d49436c89c515b001088ac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshBasedActorBlueprintEditor.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshBasedActorBlueprintEditor.cs new file mode 100644 index 00000000..98630677 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshBasedActorBlueprintEditor.cs @@ -0,0 +1,275 @@ +using UnityEngine; +using UnityEditor; +using System; +using System.IO; + +namespace Obi +{ + [CustomEditor(typeof(ObiMeshBasedActorBlueprint), true)] + public abstract class ObiMeshBasedActorBlueprintEditor : ObiActorBlueprintEditor + { + + [Flags] + public enum ParticleCulling + { + Off = 0, + Back = 1 << 0, + Front = 1 << 1 + } + + protected Mesh visualizationMesh; + protected Mesh visualizationWireMesh; + public ParticleCulling particleCulling = ParticleCulling.Back; + + protected Material gradientMaterial; + protected Material textureExportMaterial; + protected Material paddingMaterial; + + public override void OnEnable() + { + base.OnEnable(); + gradientMaterial = Resources.Load("PropertyGradientMaterial"); + textureExportMaterial = Resources.Load("UVSpaceColorMaterial"); + paddingMaterial = Resources.Load("PaddingMaterial"); + } + + public abstract Mesh sourceMesh + { + get; + } + + protected void NonReadableMeshWarning(Mesh mesh) + { + EditorGUILayout.BeginVertical(EditorStyles.helpBox); + Texture2D icon = EditorGUIUtility.Load("icons/console.erroricon.png") as Texture2D; + EditorGUILayout.LabelField(new GUIContent("The input mesh is not readable. Read/Write must be enabled in the mesh import settings.", icon), EditorStyles.wordWrappedMiniLabel); + + EditorGUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + if (GUILayout.Button("Fix now", GUILayout.MaxWidth(100), GUILayout.MinHeight(32))) + { + string assetPath = AssetDatabase.GetAssetPath(mesh); + ModelImporter modelImporter = AssetImporter.GetAtPath(assetPath) as ModelImporter; + if (modelImporter != null) + { + modelImporter.isReadable = true; + } + modelImporter.SaveAndReimport(); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.EndVertical(); + } + + protected override bool ValidateBlueprint() + { + if (sourceMesh != null) + { + if (!sourceMesh.isReadable) + { + NonReadableMeshWarning(sourceMesh); + return false; + } + return true; + } + return false; + } + + public abstract int VertexToParticle(int vertexIndex); + + public override void UpdateParticleVisibility(Camera cam) + { + if (cam != null) + { + for (int i = 0; i < blueprint.positions.Length; i++) + { + if (blueprint.IsParticleActive(i)) + { + Vector3 camToParticle = cam.transform.position - blueprint.positions[i]; + sqrDistanceToCamera[i] = camToParticle.sqrMagnitude; + + Vector3 normal; + + switch (particleCulling) + { + case ParticleCulling.Off: + visible[i] = true; + break; + case ParticleCulling.Back: + normal = blueprint.restOrientations[i] * Vector3.forward; + visible[i] = Vector3.Dot(normal, camToParticle) > 0; + break; + case ParticleCulling.Front: + normal = blueprint.restOrientations[i] * Vector3.forward; + visible[i] = Vector3.Dot(normal, camToParticle) <= 0; + break; + } + } + } + + if ((renderModeFlags & 1) != 0) + Refresh(); + } + } + + public void DrawGradientMesh(float[] vertexWeights = null, float[] wireframeWeights = null) + { + // Due to this Unity bug: https://issuetracker.unity3d.com/issues/drawmeshnow-is-not-drawing-mesh-immediately-dx12 + // we need to create two meshes insteaf of one :( + if (sourceMesh == null) + return; + + visualizationMesh = GameObject.Instantiate(sourceMesh); + visualizationWireMesh = GameObject.Instantiate(sourceMesh); + + if (gradientMaterial.SetPass(0)) + { + var matrix = Matrix4x4.TRS(Vector3.zero, (blueprint as ObiMeshBasedActorBlueprint).rotation, (blueprint as ObiMeshBasedActorBlueprint).scale); + + Color[] colors = new Color[visualizationMesh.vertexCount]; + for (int i = 0; i < colors.Length; i++) + { + int particle = VertexToParticle(i); + if (particle >= 0 && particle < blueprint.particleCount) + { + float weight = 1; + if (vertexWeights != null) + weight = vertexWeights[particle]; + + colors[i] = weight * currentProperty.ToColor(particle); + } + else + colors[i] = Color.gray; + } + + visualizationMesh.colors = colors; + Graphics.DrawMeshNow(visualizationMesh, matrix); + + Color wireColor = ObiEditorSettings.GetOrCreateSettings().brushWireframeColor; + + if (gradientMaterial.SetPass(1)) + { + for (int i = 0; i < colors.Length; i++) + { + int particle = VertexToParticle(i); + if (particle >= 0 && particle < blueprint.particleCount) + { + if (wireframeWeights != null) + colors[i] = wireColor * wireframeWeights[particle]; + else + colors[i] = wireColor; + } + else + colors[i] = Color.gray; + } + + visualizationWireMesh.colors = colors; + GL.wireframe = true; + Graphics.DrawMeshNow(visualizationWireMesh, matrix); + GL.wireframe = false; + } + + } + + GameObject.DestroyImmediate(visualizationMesh); + GameObject.DestroyImmediate(visualizationWireMesh); + } + + + /** + * Reads particle data from a 2D texture. Can be used to adjust per particle mass, skin radius, etc. using + * a texture instead of painting it in the editor. + * + * Will call onReadProperty once for each particle, passing the particle index and the bilinearly interpolated + * color of the texture at its coordinate. + * + * Be aware that, if a particle corresponds to more than + * one physical vertex and has multiple uv coordinates, + * onReadProperty will be called multiple times for that particle. + */ + public bool ReadParticlePropertyFromTexture(Texture2D source, Action onReadProperty) + { + + if (source == null || onReadProperty == null) + return false; + + Vector2[] uvs = sourceMesh.uv; + + // Iterate over all vertices in the mesh reading back colors from the texture: + for (int i = 0; i < sourceMesh.vertexCount; ++i) + { + try + { + onReadProperty(VertexToParticle(i), source.GetPixelBilinear(uvs[i].x, uvs[i].y)); + } + catch (UnityException e) + { + Debug.LogException(e); + return false; + } + } + + return true; + } + + public bool WriteParticlePropertyToTexture(string path, int width, int height, int padding) + { + + if (path == null || textureExportMaterial == null || !textureExportMaterial.SetPass(0)) + return false; + + if (visualizationMesh == null) + { + visualizationMesh = GameObject.Instantiate(sourceMesh); + } + + RenderTexture tempRT = RenderTexture.GetTemporary(width, height, 0); + RenderTexture paddingRT = RenderTexture.GetTemporary(width, height, 0); + + RenderTexture old = RenderTexture.active; + RenderTexture.active = tempRT; + + GL.PushMatrix(); + + var proj = Matrix4x4.Ortho(0, 1, 0, 1, -1, 1); if (Camera.current != null) proj = proj * Camera.current.worldToCameraMatrix.inverse; GL.LoadProjectionMatrix(proj); + + Color[] colors = new Color[sourceMesh.vertexCount]; + for (int i = 0; i < colors.Length; i++) + colors[i] = currentProperty.ToColor(VertexToParticle(i)); + + visualizationMesh.colors = colors; + Graphics.DrawMeshNow(visualizationMesh, Matrix4x4.identity); + + GL.PopMatrix(); + + // Perform padding/edge dilation + paddingMaterial.SetFloat("_Padding", padding); + Graphics.Blit(tempRT, paddingRT, paddingMaterial); + + // Read result into our Texture2D. + RenderTexture.active = paddingRT; + Texture2D texture = new Texture2D(width, height, TextureFormat.RGBA32, false); + texture.ReadPixels(new Rect(0, 0, width, height), 0, 0); + + RenderTexture.active = old; + RenderTexture.ReleaseTemporary(paddingRT); + RenderTexture.ReleaseTemporary(tempRT); + + byte[] png = texture.EncodeToPNG(); + GameObject.DestroyImmediate(texture); + + try + { + File.WriteAllBytes(path, png); + } + catch (Exception e) + { + Debug.LogException(e); + return false; + } + + AssetDatabase.Refresh(); + + return true; + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshBasedActorBlueprintEditor.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshBasedActorBlueprintEditor.cs.meta new file mode 100644 index 00000000..497250ff --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshBasedActorBlueprintEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c81a94632ae434014aedb4cc241e73e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshUtils.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshUtils.cs new file mode 100644 index 00000000..02ae7b5d --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshUtils.cs @@ -0,0 +1,93 @@ +using UnityEngine; +using System.Collections; + +namespace Obi +{ + public static class ObiMeshUtils + { + // Temporary vector3 values + static Vector3 tv1, tv2, tv3, tv4; + + public static bool RayIntersectsTriangle(Vector3 origin, + Vector3 dir, + Vector3 vert0, + Vector3 vert1, + Vector3 vert2, + ref float distance, + ref Vector3 normal) + { + float det; + + ObiVectorMath.Subtract(vert0, vert1, ref tv1); + ObiVectorMath.Subtract(vert0, vert2, ref tv2); + + ObiVectorMath.Cross(dir, tv2, ref tv4); + det = Vector3.Dot(tv1, tv4); + + if (det < Mathf.Epsilon) + return false; + + ObiVectorMath.Subtract(vert0, origin, ref tv3); + + float u = Vector3.Dot(tv3, tv4); + + if (u < 0f || u > det) + return false; + + ObiVectorMath.Cross(tv3, tv1, ref tv4); + + float v = Vector3.Dot(dir, tv4); + + if (v < 0f || u + v > det) + return false; + + distance = Vector3.Dot(tv2, tv4) * (1f / det); + ObiVectorMath.Cross(tv1, tv2, ref normal); + + return true; + } +
 /**
 * Find the nearest triangle intersected by InWorldRay on this mesh. InWorldRay is in world space.
 * @hit contains information about the hit point. @distance limits how far from @InWorldRay.origin the hit
 * point may be. @cullingMode determines what face orientations are tested (Culling.Front only tests front
 * faces, Culling.Back only tests back faces, and Culling.FrontBack tests both).
 * Ray origin and position values are in local space.
 */
 public static bool WorldRaycast(Ray InWorldRay, Matrix4x4 transform, Vector3[] vertices, int[] triangles, out ObiRaycastHit hit, float distance = Mathf.Infinity)
 { + Ray ray = InWorldRay; + if (transform != null) + { + Matrix4x4 inv = transform.inverse; + ray.origin = inv.MultiplyPoint3x4(ray.origin); + ray.direction = inv.MultiplyVector(ray.direction); + }
 return MeshRaycast(ray, vertices, triangles, out hit, distance);
 }

 /**
 * Cast a ray (in model space) against a mesh.
 */
 public static bool MeshRaycast(Ray InRay, Vector3[] vertices, int[] triangles, out ObiRaycastHit hit, float distance = Mathf.Infinity)
 { + Vector3 hitNormal = Vector3.zero; // vars used in loop + Vector3 vert0, vert1, vert2; + Vector3 origin = InRay.origin, direction = InRay.direction; + + hit = new ObiRaycastHit(Mathf.Infinity, + Vector3.zero, + Vector3.zero, + -1); + /** + * Iterate faces, testing for nearest hit to ray origin. + */ + for (int CurTri = 0; CurTri < triangles.Length; CurTri += 3) + { + if (CurTri + 2 >= triangles.Length) continue; + if (triangles[CurTri + 2] >= vertices.Length) continue; + + vert0 = vertices[triangles[CurTri + 0]]; + vert1 = vertices[triangles[CurTri + 1]]; + vert2 = vertices[triangles[CurTri + 2]]; + + // Second pass, test intersection with triangle + if (RayIntersectsTriangle(origin, direction, vert0, vert1, vert2, ref distance, ref hitNormal)) + { + if (distance < hit.distance) + { + hit.distance = distance; + hit.triangle = CurTri / 3; + hit.position = InRay.GetPoint(hit.distance); + hit.normal = hitNormal; + } + } + } + + return hit.triangle > -1;
 } + } + +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshUtils.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshUtils.cs.meta new file mode 100644 index 00000000..90c00ab9 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiMeshUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4d2a4dd4e807c4053b4e4af4d43db45e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiParticleEditorDrawing.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiParticleEditorDrawing.cs new file mode 100644 index 00000000..b3af4d4a --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiParticleEditorDrawing.cs @@ -0,0 +1,127 @@ +using UnityEngine; +using UnityEditor; +using System.Collections; +using System.Collections.Generic; + +namespace Obi +{ + public class ObiParticleEditorDrawing : MonoBehaviour + { + public static Mesh particlesMesh; + public static Material particleMaterial; + + private static void CreateParticlesMesh() + { + if (particlesMesh == null) + { + particlesMesh = new Mesh(); + particlesMesh.hideFlags = HideFlags.HideAndDontSave; + } + } + + private static void CreateParticleMaterials() + { + if (!particleMaterial) + { + particleMaterial = Resources.Load("EditorParticle"); + } + } + + public static void DestroyParticlesMesh() + { + GameObject.DestroyImmediate(particlesMesh); + } + + public static void DrawParticles(Camera cam, ObiActorBlueprint blueprint, bool[] visible, Color[] baseColor, int[] sortedIndices, float radiusScale = 1) + { + CreateParticlesMesh(); + CreateParticleMaterials(); + + if (!particleMaterial.SetPass(0)) + return; + + //because each vertex needs to be drawn as a quad. + int particlesPerDrawcall = Constants.maxVertsPerMesh / 4; + int drawcallCount = blueprint.particleCount / particlesPerDrawcall + 1; + particlesPerDrawcall = Mathf.Min(particlesPerDrawcall, blueprint.particleCount); + + List vertices = new List(blueprint.activeParticleCount* 4); + List normals = new List(blueprint.activeParticleCount * 4); + List uvs = new List(blueprint.activeParticleCount * 4); + List colors = new List(blueprint.activeParticleCount * 4); + List triangles = new List(blueprint.activeParticleCount * 6); + + Vector3 particleOffset0 = new Vector3(1, 1, 0); + Vector3 particleOffset1 = new Vector3(-1, 1, 0); + Vector3 particleOffset2 = new Vector3(-1, -1, 0); + Vector3 particleOffset3 = new Vector3(1, -1, 0); + + Vector4 radius = new Vector4(1, 0, 0, 0.005f * radiusScale); + + for (int i = 0; i < drawcallCount; ++i) + { + //Draw all cloth vertices: + particlesMesh.Clear(); + vertices.Clear(); + uvs.Clear(); + normals.Clear(); + colors.Clear(); + triangles.Clear(); + + int index = 0; + + // Run over all particles (not only active ones), since they're reordered based on distance to camera. + // Then test if the sorted index is active or not, and skip inactive ones. + int limit = Mathf.Min((i + 1) * particlesPerDrawcall, blueprint.particleCount); + + for (int j = i * particlesPerDrawcall; j < limit; ++j) + { + int sortedIndex = sortedIndices[j]; + + // skip inactive ones: + if (!blueprint.IsParticleActive(sortedIndex)) + continue; + + normals.Add(particleOffset0); + normals.Add(particleOffset1); + normals.Add(particleOffset2); + normals.Add(particleOffset3); + + uvs.Add(radius); + uvs.Add(radius); + uvs.Add(radius); + uvs.Add(radius); + + vertices.Add(blueprint.positions[sortedIndex]); + vertices.Add(blueprint.positions[sortedIndex]); + vertices.Add(blueprint.positions[sortedIndex]); + vertices.Add(blueprint.positions[sortedIndex]); + + colors.Add(baseColor[sortedIndex]); + colors.Add(baseColor[sortedIndex]); + colors.Add(baseColor[sortedIndex]); + colors.Add(baseColor[sortedIndex]); + + triangles.Add(index + 2); + triangles.Add(index + 1); + triangles.Add(index); + triangles.Add(index + 3); + triangles.Add(index + 2); + triangles.Add(index); + + index += 4; + } + + particlesMesh.SetVertices(vertices); + particlesMesh.SetNormals(normals); + particlesMesh.SetColors(colors); + particlesMesh.SetUVs(0, uvs); + particlesMesh.SetTriangles(triangles,0, true); + + Graphics.DrawMeshNow(particlesMesh, Matrix4x4.identity); + } + } + + } + +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiParticleEditorDrawing.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiParticleEditorDrawing.cs.meta new file mode 100644 index 00000000..561f8c74 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/ObiParticleEditorDrawing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 982f73e0e40c749f09db403624bbd8e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties.meta new file mode 100644 index 00000000..1efd01e8 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dfda10b0e82f747998295540d5750108 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes.meta new file mode 100644 index 00000000..1de2e12b --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7b9ba4ddc644a4bfa8ab44a5826b8007 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintBoolProperty.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintBoolProperty.cs new file mode 100644 index 00000000..d3b35a8d --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintBoolProperty.cs @@ -0,0 +1,24 @@ +using UnityEngine; +using UnityEditor; +using System.Collections; + +namespace Obi +{ + public abstract class ObiBlueprintBoolProperty : ObiBlueprintProperty + { + public override bool Equals(int firstIndex, int secondIndex) + { + return Get(firstIndex) == Get(secondIndex); + } + + public override void PropertyField() + { + value = EditorGUILayout.Toggle(name, value); + } + + public override Color ToColor(int index) + { + return value ? Color.white : Color.gray; + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintBoolProperty.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintBoolProperty.cs.meta new file mode 100644 index 00000000..719c085a --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintBoolProperty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19cb8e21747094d6dae8dff155654066 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintColorProperty.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintColorProperty.cs new file mode 100644 index 00000000..a62d0c3b --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintColorProperty.cs @@ -0,0 +1,31 @@ +using UnityEngine; +using UnityEditor; +using System.Collections; + +namespace Obi +{ + public abstract class ObiBlueprintColorProperty : ObiBlueprintProperty + { + public ObiActorBlueprintEditor editor; + + public ObiBlueprintColorProperty(ObiActorBlueprintEditor editor) + { + this.editor = editor; + } + + public override bool Equals(int firstIndex, int secondIndex) + { + return Get(firstIndex) == Get(secondIndex); + } + + public override void PropertyField() + { + value = EditorGUILayout.ColorField(name, value); + } + + public override Color ToColor(int index) + { + return editor.blueprint.colors[index]; + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintColorProperty.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintColorProperty.cs.meta new file mode 100644 index 00000000..226bed79 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintColorProperty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 64ab0b4fad7614808acc3cdb75215c50 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintFloatProperty.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintFloatProperty.cs new file mode 100644 index 00000000..8b521744 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintFloatProperty.cs @@ -0,0 +1,94 @@ +using UnityEngine; +using UnityEditor; + +namespace Obi +{ + public abstract class ObiBlueprintFloatProperty : ObiBlueprintProperty + { + public float minVisualizationValue = 0; + public float maxVisualizationValue = 10; + protected float minUserVisualizationValue = 0; + protected float maxUserVisualizationValue = 10; + + protected float? minValue = null; + protected float? maxValue = null; + + public bool autoRange = true; + public ObiActorBlueprintEditor editor; + + public ObiBlueprintFloatProperty(ObiActorBlueprintEditor editor, float? minValue = null, float? maxValue = null) + { + this.editor = editor; + this.minValue = minValue; + this.maxValue = maxValue; + } + + public override bool Equals(int firstIndex, int secondIndex) + { + float v1 = Get(firstIndex); + float v2 = Get(secondIndex); + if (v1 == v2) return true; + return Mathf.Approximately(v1,v2); + } + + public override void PropertyField() + { + EditorGUI.BeginChangeCheck(); + value = EditorGUILayout.FloatField(name, value); + if (EditorGUI.EndChangeCheck()) + { + if (minValue.HasValue) + value = Mathf.Max(minValue.Value, value); + if (maxValue.HasValue) + value = Mathf.Min(maxValue.Value, value); + } + } + + public override void RecalculateMinMax() + { + if (editor != null && autoRange) + { + maxVisualizationValue = float.MinValue; + minVisualizationValue = float.MaxValue; + + for (int i = 0; i < editor.blueprint.activeParticleCount; i++) + { + float v = Get(i); + maxVisualizationValue = Mathf.Max(maxVisualizationValue, v); + minVisualizationValue = Mathf.Min(minVisualizationValue, v); + } + } + else + { + maxVisualizationValue = maxUserVisualizationValue; + minVisualizationValue = minUserVisualizationValue; + } + } + + public override void VisualizationOptions() + { + EditorGUI.BeginChangeCheck(); + autoRange = EditorGUILayout.Toggle("Automatic property range", autoRange); + GUI.enabled = !autoRange; + EditorGUI.indentLevel++; + minUserVisualizationValue = EditorGUILayout.FloatField("Min", minUserVisualizationValue); + maxUserVisualizationValue = EditorGUILayout.FloatField("Max", maxUserVisualizationValue); + EditorGUI.indentLevel--; + GUI.enabled = true; + + if (EditorGUI.EndChangeCheck()) + { + RecalculateMinMax(); + editor.Refresh(); + } + } + + public override Color ToColor(int index) + { + Gradient gradient = ObiEditorSettings.GetOrCreateSettings().propertyGradient; + if (!Mathf.Approximately(minVisualizationValue, maxVisualizationValue)) + return gradient.Evaluate(Mathf.InverseLerp(minVisualizationValue, maxVisualizationValue, Get(index))); + else return gradient.Evaluate(0); + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintFloatProperty.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintFloatProperty.cs.meta new file mode 100644 index 00000000..a8a2539d --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintFloatProperty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be67f2576200242f080bbcc074dc598a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintIntProperty.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintIntProperty.cs new file mode 100644 index 00000000..4cbc05b8 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintIntProperty.cs @@ -0,0 +1,41 @@ +using UnityEngine; +using UnityEditor; + +namespace Obi +{ + public abstract class ObiBlueprintIntProperty : ObiBlueprintProperty + { + protected int? minValue = null; + protected int? maxValue = null; + + public ObiBlueprintIntProperty(int? minValue = null, int? maxValue = null) + { + this.minValue = minValue; + this.maxValue = maxValue; + } + + public override bool Equals(int firstIndex, int secondIndex) + { + return Get(firstIndex) == Get(secondIndex); + } + + public override void PropertyField() + { + EditorGUI.BeginChangeCheck(); + value = EditorGUILayout.IntField(name, value); + if (EditorGUI.EndChangeCheck()) + { + if (minValue.HasValue) + value = Mathf.Max(minValue.Value, value); + if (maxValue.HasValue) + value = Mathf.Min(maxValue.Value, value); + } + } + + public override Color ToColor(int index) + { + int colorIndex = Get(index) % ObiUtils.colorAlphabet.Length; + return ObiUtils.colorAlphabet[colorIndex]; + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintIntProperty.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintIntProperty.cs.meta new file mode 100644 index 00000000..069bfc02 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintIntProperty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d8661f9e9cfd044c7bb759145c2a8d73 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintMaskProperty.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintMaskProperty.cs new file mode 100644 index 00000000..e4b0713e --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintMaskProperty.cs @@ -0,0 +1,28 @@ +using UnityEngine; +using UnityEditor; + +namespace Obi +{ + public abstract class ObiBlueprintMaskProperty : ObiBlueprintIntProperty + { + public ObiBlueprintMaskProperty() : base(null,null) + { + } + + public override void PropertyField() + { + value = EditorGUILayout.MaskField(name, value, ObiUtils.categoryNames); + } + + private int MathMod(int a, int b) + { + return (Mathf.Abs(a * b) + a) % b; + } + + public override Color ToColor(int index) + { + int colorIndex = MathMod(Get(index),ObiUtils.colorAlphabet.Length); + return ObiUtils.colorAlphabet[colorIndex]; + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintMaskProperty.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintMaskProperty.cs.meta new file mode 100644 index 00000000..60f3c178 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintMaskProperty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 165ad17d69adf415ea7609a9373de001 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintProperty.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintProperty.cs new file mode 100644 index 00000000..fb768124 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintProperty.cs @@ -0,0 +1,79 @@ +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace Obi +{ + public abstract class ObiBlueprintPropertyBase + { + protected List brushModes = new List(); + private int selectedBrushMode; + + public abstract string name + { + get; + } + + public abstract void PropertyField(); + public virtual void VisualizationOptions(){} + public virtual void OnSceneRepaint(){} + + public abstract bool Equals(int firstIndex, int secondIndex); + + public abstract void GetDefaultFromIndex(int index); + public abstract void SetDefaultToIndex(int index); + public virtual bool Masked(int index) + { + return false; + } + + public virtual void RecalculateMinMax() { } + public virtual Color ToColor(int index) { return Color.white; } + + protected void Initialize(ObiBrushBase paintBrush) + { + // Initialize the brush if there's no brush mode set: + if (paintBrush.brushMode == null && brushModes.Count > 0) + { + selectedBrushMode = 0; + paintBrush.brushMode = brushModes[selectedBrushMode]; + } + } + + public void OnSelect(ObiBrushBase paintBrush) + { + // Upon selecting the property, change to the last selected brush mode: + if (brushModes.Count > selectedBrushMode) + paintBrush.brushMode = brushModes[selectedBrushMode]; + + } + + public void BrushModes(ObiBrushBase paintBrush) + { + Initialize(paintBrush); + + GUIContent[] contents = new GUIContent[brushModes.Count]; + for (int i = 0; i < brushModes.Count; ++i) + contents[i] = new GUIContent(brushModes[i].name); + + EditorGUI.BeginChangeCheck(); + selectedBrushMode = ObiEditorUtils.DoToolBar(selectedBrushMode, contents); + if (EditorGUI.EndChangeCheck()) + { + paintBrush.brushMode = brushModes[selectedBrushMode]; + } + } + } + + public abstract class ObiBlueprintProperty : ObiBlueprintPropertyBase + { + protected T value; + + public T GetDefault() { return value; } + public override void GetDefaultFromIndex(int index) { value = Get(index); } + public override void SetDefaultToIndex(int index) { Set(index, value); } + + public abstract T Get(int index); + public abstract void Set(int index, T value); + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintProperty.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintProperty.cs.meta new file mode 100644 index 00000000..ba7b85be --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/BaseTypes/ObiBlueprintProperty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 60a83ba184caf4a1aba4da6754776a1d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/IObiPropertyEditableProvider.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/IObiPropertyEditableProvider.cs new file mode 100644 index 00000000..f5345891 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/IObiPropertyEditableProvider.cs @@ -0,0 +1,13 @@ +using UnityEngine; +using System.Collections; + +namespace Obi +{ + public interface IObiSelectableParticleProvider + { + void SetSelected(int particleIndex, bool selected); + bool IsSelected(int particleIndex); + bool Editable(int particleIndex); + } + +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/IObiPropertyEditableProvider.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/IObiPropertyEditableProvider.cs.meta new file mode 100644 index 00000000..3bf0408f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/IObiPropertyEditableProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c3a2643915854763af75d63fa1ec0c9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintColor.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintColor.cs new file mode 100644 index 00000000..83d73b9f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintColor.cs @@ -0,0 +1,33 @@ +using UnityEngine; + +namespace Obi +{ + public class ObiBlueprintColor : ObiBlueprintColorProperty + { + public ObiBlueprintColor(ObiActorBlueprintEditor editor) : base(editor) + { + brushModes.Add(new ObiColorPaintBrushMode(this)); + brushModes.Add(new ObiColorSmoothBrushMode(this)); + } + + public override string name + { + get { return "Color"; } + } + + public override Color Get(int index) + { + return editor.blueprint.colors[index]; + } + public override void Set(int index, Color value) + { + editor.blueprint.colors[index] = value; + editor.blueprint.edited = true; + } + public override bool Masked(int index) + { + return !editor.Editable(index); + } + + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintColor.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintColor.cs.meta new file mode 100644 index 00000000..a371aaca --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintColor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 810c95482e60a44209c5ece07e287153 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterCategory.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterCategory.cs new file mode 100644 index 00000000..acd53eef --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterCategory.cs @@ -0,0 +1,32 @@ +namespace Obi +{ + public class ObiBlueprintFilterCategory : ObiBlueprintIntProperty + { + public ObiActorBlueprintEditor editor; + + public ObiBlueprintFilterCategory(ObiActorBlueprintEditor editor) : base(ObiUtils.MinCategory, ObiUtils.MaxCategory) + { + this.editor = editor; + brushModes.Add(new ObiIntPaintBrushMode(this)); + } + + public override string name + { + get { return "Category"; } + } + + public override int Get(int index) + { + return ObiUtils.GetCategoryFromFilter(editor.blueprint.filters[index]); + } + public override void Set(int index, int value) + { + editor.blueprint.filters[index] = ObiUtils.MakeFilter(ObiUtils.GetMaskFromFilter(editor.blueprint.filters[index]), value); + editor.blueprint.edited = true; + } + public override bool Masked(int index) + { + return !editor.Editable(index); + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterCategory.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterCategory.cs.meta new file mode 100644 index 00000000..50307493 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterCategory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 08502999496e54f49bb9dee0e0855794 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterMask.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterMask.cs new file mode 100644 index 00000000..6c2d57b5 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterMask.cs @@ -0,0 +1,32 @@ +namespace Obi +{ + public class ObiBlueprintFilterMask : ObiBlueprintMaskProperty + { + public ObiActorBlueprintEditor editor; + + public ObiBlueprintFilterMask(ObiActorBlueprintEditor editor) + { + this.editor = editor; + brushModes.Add(new ObiIntPaintBrushMode(this)); + } + + public override string name + { + get { return "Collides with"; } + } + + public override int Get(int index) + { + return ObiUtils.GetMaskFromFilter(editor.blueprint.filters[index]); + } + public override void Set(int index, int value) + { + editor.blueprint.filters[index] = ObiUtils.MakeFilter(value,ObiUtils.GetCategoryFromFilter(editor.blueprint.filters[index])); + editor.blueprint.edited = true; + } + public override bool Masked(int index) + { + return !editor.Editable(index); + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterMask.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterMask.cs.meta new file mode 100644 index 00000000..2bdf6b4a --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintFilterMask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ead8a00c964834718a2411be5d7361f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintMass.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintMass.cs new file mode 100644 index 00000000..32b0e3dd --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintMass.cs @@ -0,0 +1,33 @@ +namespace Obi +{ + public class ObiBlueprintMass : ObiBlueprintFloatProperty + { + + public ObiBlueprintMass(ObiActorBlueprintEditor editor) : base(editor,0) + { + brushModes.Add(new ObiFloatPaintBrushMode(this)); + brushModes.Add(new ObiFloatAddBrushMode(this)); + brushModes.Add(new ObiFloatCopyBrushMode(this, this)); + brushModes.Add(new ObiFloatSmoothBrushMode(this)); + } + + public override string name + { + get { return "Mass"; } + } + + public override float Get(int index) + { + return ObiUtils.InvMassToMass(editor.blueprint.invMasses[index]); + } + public override void Set(int index, float value) + { + editor.blueprint.invMasses[index] = ObiUtils.MassToInvMass(value); + editor.blueprint.edited = true; + } + public override bool Masked(int index) + { + return !editor.Editable(index); + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintMass.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintMass.cs.meta new file mode 100644 index 00000000..7dcb1686 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintMass.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd39fbd4c226542e58dc8ecceb5f8f14 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintRadius.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintRadius.cs new file mode 100644 index 00000000..21f8d384 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintRadius.cs @@ -0,0 +1,37 @@ +using UnityEngine; + +namespace Obi +{ + public class ObiBlueprintRadius : ObiBlueprintFloatProperty + { + + public ObiBlueprintRadius(ObiActorBlueprintEditor editor) : base(editor,0.0000001f) + { + brushModes.Add(new ObiFloatPaintBrushMode(this)); + brushModes.Add(new ObiFloatAddBrushMode(this)); + brushModes.Add(new ObiFloatCopyBrushMode(this, this)); + brushModes.Add(new ObiFloatSmoothBrushMode(this)); + } + + public override string name + { + get { return "Radius"; } + } + + public override float Get(int index) + { + return editor.blueprint.principalRadii[index][0]; + } + public override void Set(int index, float value) + { + value = Mathf.Max(0.0000001f, value); + float ratio = value / Get(index); + editor.blueprint.principalRadii[index] = editor.blueprint.principalRadii[index] * ratio; + editor.blueprint.edited = true; + } + public override bool Masked(int index) + { + return !editor.Editable(index); + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintRadius.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintRadius.cs.meta new file mode 100644 index 00000000..17400981 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintRadius.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5c61b50f6f4a468aa246f01e5268831 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintSelected.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintSelected.cs new file mode 100644 index 00000000..920a5020 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintSelected.cs @@ -0,0 +1,29 @@ +namespace Obi +{ + public class ObiBlueprintSelected : ObiBlueprintBoolProperty + { + public IObiSelectableParticleProvider provider; + public ObiBlueprintSelected(IObiSelectableParticleProvider provider) + { + this.provider = provider; + } + + public override string name + { + get { return "Selected"; } + } + + public override bool Get(int index) + { + return provider.IsSelected(index); + } + public override void Set(int index, bool value) + { + provider.SetSelected(index,value); + } + public override bool Masked(int index) + { + return !provider.Editable(index); + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintSelected.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintSelected.cs.meta new file mode 100644 index 00000000..d46419e1 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/Properties/ObiBlueprintSelected.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 270971958421b4fec9e5a5ba95699518 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes.meta new file mode 100644 index 00000000..d44e8e2f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: be5de82c95ded480d881176f73fc19b7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderMode.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderMode.cs new file mode 100644 index 00000000..0b780b88 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderMode.cs @@ -0,0 +1,25 @@ +using UnityEngine; +using UnityEditor; +using System.Collections; + +namespace Obi +{ + public abstract class ObiBlueprintRenderMode + { + protected ObiActorBlueprintEditor editor; + public abstract string name + { + get; + } + public ObiBlueprintRenderMode(ObiActorBlueprintEditor editor) + { + this.editor = editor; + } + + public virtual void DrawWithCamera(Camera camera) {} + public virtual void OnSceneRepaint(SceneView sceneView) {} + public virtual void Refresh(){} + + public virtual void OnDestroy() { } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderMode.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderMode.cs.meta new file mode 100644 index 00000000..585711f9 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d60f616a126974e6d8be81fbbe459bac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeAerodynamicConstraints.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeAerodynamicConstraints.cs new file mode 100644 index 00000000..eeb6854b --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeAerodynamicConstraints.cs @@ -0,0 +1,63 @@ +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace Obi +{ + public class ObiBlueprintRenderModeAerodynamicConstraints : ObiBlueprintRenderMode + { + public override string name + { + get { return "Aerodynamic constraints"; } + } + + public ObiMeshBasedActorBlueprintEditor meshBasedEditor + { + get { return editor as ObiMeshBasedActorBlueprintEditor; } + } + + public ObiBlueprintRenderModeAerodynamicConstraints(ObiMeshBasedActorBlueprintEditor editor) : base(editor) + { + } + + public override void OnSceneRepaint(SceneView sceneView) + { + var meshEditor = editor as ObiMeshBasedActorBlueprintEditor; + if (meshEditor != null) + { + // Get per-particle normals: + Vector3[] normals = meshEditor.sourceMesh.normals; + Vector3[] particleNormals = new Vector3[meshEditor.blueprint.particleCount]; + for (int i = 0; i < normals.Length; ++i) + { + int welded = meshEditor.VertexToParticle(i); + particleNormals[welded] = normals[i]; + } + + using (new Handles.DrawingScope(Color.blue, Matrix4x4.identity)) + { + var constraints = editor.blueprint.GetConstraintsByType(Oni.ConstraintType.Aerodynamics) as ObiConstraints; + if (constraints != null) + { + Vector3[] lines = new Vector3[constraints.GetActiveConstraintCount() * 2]; + int lineIndex = 0; + + foreach (var batch in constraints.batches) + { + for (int i = 0; i < batch.activeConstraintCount; ++i) + { + int particleIndex = batch.particleIndices[i]; + Vector3 position = editor.blueprint.GetParticlePosition(particleIndex); + lines[lineIndex++] = position; + lines[lineIndex++] = position + particleNormals[particleIndex] * 0.025f; + } + } + + Handles.DrawLines(lines); + } + } + } + } + + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeAerodynamicConstraints.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeAerodynamicConstraints.cs.meta new file mode 100644 index 00000000..c6efaed7 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeAerodynamicConstraints.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 18881e26e784d47aaa8aa27c93fe0b49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeBendConstraints.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeBendConstraints.cs new file mode 100644 index 00000000..a5f68cb9 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeBendConstraints.cs @@ -0,0 +1,44 @@ +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace Obi +{ + public class ObiBlueprintRenderModeBendConstraints : ObiBlueprintRenderMode + { + public override string name + { + get { return "Bend constraints"; } + } + + public ObiBlueprintRenderModeBendConstraints(ObiActorBlueprintEditor editor) : base(editor) + { + } + + public override void OnSceneRepaint(SceneView sceneView) + { + using (new Handles.DrawingScope(Color.magenta, Matrix4x4.identity)) + { + var constraints = editor.blueprint.GetConstraintsByType(Oni.ConstraintType.Bending) as ObiConstraints; + if (constraints != null) + { + Vector3[] lines = new Vector3[constraints.GetActiveConstraintCount() * 2]; + int lineIndex = 0; + + foreach (var batch in constraints.batches) + { + for (int i = 0; i < batch.activeConstraintCount; ++i) + { + lines[lineIndex++] = editor.blueprint.GetParticlePosition(batch.particleIndices[i * 3]); + lines[lineIndex++] = editor.blueprint.GetParticlePosition(batch.particleIndices[i * 3 + 1]); + } + } + + Handles.DrawLines(lines); + } + } + + } + + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeBendConstraints.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeBendConstraints.cs.meta new file mode 100644 index 00000000..ec81849a --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeBendConstraints.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15e21bc6bea1c4320948413c8d7334bd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeDistanceConstraints.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeDistanceConstraints.cs new file mode 100644 index 00000000..b4fb4f07 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeDistanceConstraints.cs @@ -0,0 +1,44 @@ +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace Obi +{ + public class ObiBlueprintRenderModeDistanceConstraints : ObiBlueprintRenderMode + { + public override string name + { + get { return "Distance constraints"; } + } + + public ObiBlueprintRenderModeDistanceConstraints(ObiActorBlueprintEditor editor) : base(editor) + { + } + + public override void OnSceneRepaint(SceneView sceneView) + { + + using (new Handles.DrawingScope(Color.green, Matrix4x4.identity)) + { + var constraints = editor.blueprint.GetConstraintsByType(Oni.ConstraintType.Distance) as ObiConstraints; + if (constraints != null) + { + Vector3[] lines = new Vector3[constraints.GetActiveConstraintCount() * 2]; + int lineIndex = 0; + + foreach (var batch in constraints.batches) + { + for (int i = 0; i < batch.activeConstraintCount; ++i) + { + lines[lineIndex++] = editor.blueprint.GetParticlePosition(batch.particleIndices[i * 2]); + lines[lineIndex++] = editor.blueprint.GetParticlePosition(batch.particleIndices[i * 2 + 1]); + } + } + + Handles.DrawLines(lines); + } + } + } + + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeDistanceConstraints.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeDistanceConstraints.cs.meta new file mode 100644 index 00000000..c6b32ad1 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeDistanceConstraints.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac734c05a2b994f148fd43cd5829b1be +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeMesh.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeMesh.cs new file mode 100644 index 00000000..2f3473b9 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeMesh.cs @@ -0,0 +1,46 @@ +using UnityEditor; + +namespace Obi +{ + public class ObiBlueprintRenderModeMesh : ObiBlueprintRenderMode + { + public override string name + { + get { return "Mesh"; } + } + + public ObiMeshBasedActorBlueprintEditor meshBasedEditor + { + get { return editor as ObiMeshBasedActorBlueprintEditor; } + } + + public ObiBlueprintRenderModeMesh(ObiMeshBasedActorBlueprintEditor editor) : base(editor) + { + } + + public override void OnSceneRepaint(SceneView sceneView) + { + if (meshBasedEditor.currentTool is ObiPaintBrushEditorTool) + { + ObiPaintBrushEditorTool paintTool = (ObiPaintBrushEditorTool)meshBasedEditor.currentTool; + + float[] weights = new float[ObiActorBlueprintEditor.selectionStatus.Length]; + for (int i = 0; i < weights.Length; i++) + { + if (paintTool.selectionMask && !ObiActorBlueprintEditor.selectionStatus[i]) + weights[i] = 0; + else + weights[i] = 1; + } + + float[] wireframeWeights = new float[paintTool.paintBrush.weights.Length]; + for (int i = 0; i < wireframeWeights.Length; i++) + wireframeWeights[i] = paintTool.paintBrush.weights[i]; + + meshBasedEditor.DrawGradientMesh(weights, wireframeWeights); + } + else + meshBasedEditor.DrawGradientMesh(); + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeMesh.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeMesh.cs.meta new file mode 100644 index 00000000..19cb4d49 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeMesh.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dbcd302f71d6446cd976f736b365c7ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeParticles.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeParticles.cs new file mode 100644 index 00000000..47135af0 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeParticles.cs @@ -0,0 +1,65 @@ +using UnityEngine; +using System.Collections; + +namespace Obi +{ + public class ObiBlueprintRenderModeParticles : ObiBlueprintRenderMode + { + public override string name + { + get { return "Particles"; } + } + + private Shader shader; + private Material material; + private ParticleImpostorRendering impostorDrawer; + private MaterialPropertyBlock mpb; + + public ObiBlueprintRenderModeParticles(ObiActorBlueprintEditor editor) :base(editor) + { + impostorDrawer = new ParticleImpostorRendering(); + impostorDrawer.UpdateMeshes(editor.blueprint); + mpb = new MaterialPropertyBlock(); + } + + void CreateMaterialIfNeeded() + { + if (shader == null) + { + shader = Shader.Find("Obi/EditorParticles"); + if (shader != null) + { + if (!shader.isSupported) + Debug.LogWarning("Particle rendering shader not suported."); + + if (material == null || material.shader != shader) + { + GameObject.DestroyImmediate(material); + material = new Material(shader); + material.hideFlags = HideFlags.HideAndDontSave; + } + } + } + } + + public override void DrawWithCamera(Camera camera) + { + CreateMaterialIfNeeded(); + mpb.SetFloat("_RadiusScale", 1); + mpb.SetColor("_ParticleColor", Color.white); + foreach (Mesh mesh in impostorDrawer.Meshes) + Graphics.DrawMesh(mesh, Matrix4x4.identity, material, 0, camera, 0, mpb); + } + + public override void Refresh() + { + impostorDrawer.UpdateMeshes(editor.blueprint, editor.visible, editor.tint); + } + + public override void OnDestroy() + { + GameObject.DestroyImmediate(material); + impostorDrawer.ClearMeshes(); + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeParticles.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeParticles.cs.meta new file mode 100644 index 00000000..7e91ad77 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeParticles.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b51ea2becbebe48ba9d77e9d28403f51 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeShapeMatchingConstraints.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeShapeMatchingConstraints.cs new file mode 100644 index 00000000..58224382 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeShapeMatchingConstraints.cs @@ -0,0 +1,54 @@ +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace Obi +{ + public class ObiBlueprintRenderModeShapeMatchingConstraints : ObiBlueprintRenderMode + { + public override string name + { + get { return "Shape matching clusters"; } + } + + public ObiBlueprintRenderModeShapeMatchingConstraints(ObiActorBlueprintEditor editor) : base(editor) + { + } + + public override void OnSceneRepaint(SceneView sceneView) + { + + using (new Handles.DrawingScope(Color.cyan, Matrix4x4.identity)) + { + var constraints = editor.blueprint.GetConstraintsByType(Oni.ConstraintType.ShapeMatching) as ObiConstraints; + if (constraints != null) + { + List lines = new List(); + + foreach (var batch in constraints.batches) + { + for (int i = 0; i < batch.activeConstraintCount; ++i) + { + int first = batch.firstIndex[i]; + Vector3 p1 = editor.blueprint.GetParticlePosition(batch.particleIndices[first]); + + for (int j = 1; j < batch.numIndices[i]; ++j) + { + + int index = first + j; + Vector3 p2 = editor.blueprint.GetParticlePosition(batch.particleIndices[index]); + + lines.Add(p1); + lines.Add(p2); + } + + } + } + + Handles.DrawLines(lines.ToArray()); + } + } + } + + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeShapeMatchingConstraints.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeShapeMatchingConstraints.cs.meta new file mode 100644 index 00000000..201059f1 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeShapeMatchingConstraints.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e5ff128cfebee45ffb8266eb3e75522e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeTetherConstraints.cs b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeTetherConstraints.cs new file mode 100644 index 00000000..bd33fafd --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeTetherConstraints.cs @@ -0,0 +1,43 @@ +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace Obi +{ + public class ObiBlueprintRenderModeTetherConstraints : ObiBlueprintRenderMode + { + public override string name + { + get { return "Tether constraints"; } + } + + public ObiBlueprintRenderModeTetherConstraints(ObiActorBlueprintEditor editor) : base(editor) + { + } + + public override void OnSceneRepaint(SceneView sceneView) + { + using (new Handles.DrawingScope(Color.yellow, Matrix4x4.identity)) + { + var constraints = editor.blueprint.GetConstraintsByType(Oni.ConstraintType.Tether) as ObiConstraints; + if (constraints != null) + { + Vector3[] lines = new Vector3[constraints.GetActiveConstraintCount() * 2]; + int lineIndex = 0; + + foreach (var batch in constraints.batches) + { + for (int i = 0; i < batch.activeConstraintCount; ++i) + { + lines[lineIndex++] = editor.blueprint.GetParticlePosition(batch.particleIndices[i * 2]); + lines[lineIndex++] = editor.blueprint.GetParticlePosition(batch.particleIndices[i * 2 + 1]); + } + } + + Handles.DrawLines(lines); + } + } + } + + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeTetherConstraints.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeTetherConstraints.cs.meta new file mode 100644 index 00000000..94886036 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Blueprints/RenderModes/ObiBlueprintRenderModeTetherConstraints.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63054cbedb75c4aa7906bf1c24552085 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Collisions.meta b/xiaofang/Assets/Obi/Editor/Common/Collisions.meta new file mode 100644 index 00000000..e3f2bc76 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Collisions.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5759f1c7beafc485489fb47abffaa269 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiColliderEditor.cs b/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiColliderEditor.cs new file mode 100644 index 00000000..a12dae90 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiColliderEditor.cs @@ -0,0 +1,104 @@ +using UnityEditor; +using UnityEngine; + +namespace Obi{ + + [CustomEditor(typeof(ObiColliderBase), true), CanEditMultipleObjects] + public class ObiColliderEditor : Editor + { + + ObiColliderBase collider; + SerializedProperty collisionFilter; + + public void OnEnable() + { + collider = (ObiColliderBase)target; + collisionFilter = serializedObject.FindProperty("filter"); + } + + protected void NonReadableMeshWarning(Mesh mesh) + { + EditorGUILayout.BeginVertical(EditorStyles.helpBox); + Texture2D icon = EditorGUIUtility.Load("icons/console.erroricon.png") as Texture2D; + EditorGUILayout.LabelField(new GUIContent("The input mesh is not readable. Read/Write must be enabled in the mesh import settings.", icon), EditorStyles.wordWrappedMiniLabel); + + EditorGUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + if (GUILayout.Button("Fix now", GUILayout.MaxWidth(100), GUILayout.MinHeight(32))) + { + string assetPath = AssetDatabase.GetAssetPath(mesh); + ModelImporter modelImporter = AssetImporter.GetAtPath(assetPath) as ModelImporter; + if (modelImporter != null) + { + modelImporter.isReadable = true; + } + modelImporter.SaveAndReimport(); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.EndVertical(); + } + + public override void OnInspectorGUI() + { + + serializedObject.UpdateIfRequiredOrScript(); + + foreach (ObiColliderBase t in targets) + { + ObiMeshShapeTracker meshTracker = t.Tracker as ObiMeshShapeTracker; + if (meshTracker != null) + { + if (meshTracker.targetMesh != null && !meshTracker.targetMesh.isReadable) + NonReadableMeshWarning(meshTracker.targetMesh); + } + } + + var rect = EditorGUILayout.GetControlRect(); + var label = EditorGUI.BeginProperty(rect, new GUIContent("Collision category"), collisionFilter); + rect = EditorGUI.PrefixLabel(rect, label); + + EditorGUI.BeginChangeCheck(); + var newCategory = EditorGUI.Popup(rect, ObiUtils.GetCategoryFromFilter(collider.Filter), ObiUtils.categoryNames); + if (EditorGUI.EndChangeCheck()) + { + foreach (ObiColliderBase t in targets) + { + Undo.RecordObject(t, "Set collision category"); + t.Filter = ObiUtils.MakeFilter(ObiUtils.GetMaskFromFilter(t.Filter), newCategory); + PrefabUtility.RecordPrefabInstancePropertyModifications(t); + } + } + EditorGUI.EndProperty(); + + rect = EditorGUILayout.GetControlRect(); + label = EditorGUI.BeginProperty(rect, new GUIContent("Collides with"), collisionFilter); + rect = EditorGUI.PrefixLabel(rect, label); + + EditorGUI.BeginChangeCheck(); + var newMask = EditorGUI.MaskField(rect, ObiUtils.GetMaskFromFilter(collider.Filter), ObiUtils.categoryNames); + if (EditorGUI.EndChangeCheck()) + { + foreach (ObiColliderBase t in targets) + { + Undo.RecordObject(t, "Set collision mask"); + t.Filter = ObiUtils.MakeFilter(newMask, ObiUtils.GetCategoryFromFilter(t.Filter)); + PrefabUtility.RecordPrefabInstancePropertyModifications(t); + } + } + EditorGUI.EndProperty(); + + DrawPropertiesExcluding(serializedObject, "m_Script", "CollisionMaterial", "filter", "Thickness", "Inverted"); + + + // Apply changes to the serializedProperty + if (GUI.changed) + { + serializedObject.ApplyModifiedProperties(); + } + + } + + } +} + + diff --git a/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiColliderEditor.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiColliderEditor.cs.meta new file mode 100644 index 00000000..0373df8a --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiColliderEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7c99a0a8358754501b3c8089185b0e6f +timeCreated: 1502034385 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiDistanceFieldEditor.cs b/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiDistanceFieldEditor.cs new file mode 100644 index 00000000..1ca4989c --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiDistanceFieldEditor.cs @@ -0,0 +1,178 @@ +using UnityEngine; +using UnityEditor; +using System.IO; +using System.Collections; + +namespace Obi{ + [CustomEditor(typeof(ObiDistanceField))] + public class ObiDistanceFieldEditor : Editor + { + + ObiDistanceField distanceField; + + PreviewHelpers previewHelper; + Vector2 previewDir; + Material previewMaterial; + + Mesh previewMesh; + Texture3D volumeTexture; + + protected IEnumerator routine; + + private void UpdatePreview(){ + + CleanupPreview(); + + if (distanceField.InputMesh != null){ + + previewMesh = CreateMeshForBounds(distanceField.FieldBounds); + previewMesh.hideFlags = HideFlags.HideAndDontSave; + + volumeTexture = distanceField.GetVolumeTexture(64); + volumeTexture.hideFlags = HideFlags.HideAndDontSave; + + previewMaterial = Resources.Load("DistanceFieldPreview"); + previewMaterial.SetTexture("_Volume",volumeTexture); + previewMaterial.SetVector("_AABBMin",-distanceField.FieldBounds.extents); + previewMaterial.SetVector("_AABBMax",distanceField.FieldBounds.extents); + } + + } + + private void CleanupPreview(){ + GameObject.DestroyImmediate(previewMesh); + GameObject.DestroyImmediate(volumeTexture); + } + + public void OnEnable(){ + distanceField = (ObiDistanceField) target; + previewHelper = new PreviewHelpers(); + UpdatePreview(); + } + + public void OnDisable(){ + EditorUtility.ClearProgressBar(); + previewHelper.Cleanup(); + CleanupPreview(); + } + + public override void OnInspectorGUI() { + + serializedObject.UpdateIfRequiredOrScript(); + + Editor.DrawPropertiesExcluding(serializedObject,"m_Script"); + + GUI.enabled = (distanceField.InputMesh != null); + if (GUILayout.Button("Generate")){ + // Start a coroutine job in the editor. + EditorUtility.SetDirty(target); + CoroutineJob job = new CoroutineJob(); + routine = job.Start( distanceField.Generate()); + EditorCoroutine.ShowCoroutineProgressBar("Generating distance field", routine); + UpdatePreview(); + EditorGUIUtility.ExitGUI(); + } + GUI.enabled = true; + + int nodeCount = (distanceField.nodes != null ? distanceField.nodes.Count : 0); + float resolution = distanceField.FieldBounds.size.x / distanceField.EffectiveSampleSize; + EditorGUILayout.HelpBox("Nodes: "+ nodeCount+"\n"+ + "Size in memory: "+ (nodeCount * 0.062f).ToString("0.#") +" kB\n"+ + "Compressed to: " + (nodeCount / Mathf.Pow(resolution,3) * 100).ToString("0.##") + "%",MessageType.Info); + + if (GUI.changed) + serializedObject.ApplyModifiedProperties(); + + } + + public override bool HasPreviewGUI(){ + return true; + } + + public override void OnInteractivePreviewGUI(Rect region, GUIStyle background) + { + previewDir = PreviewHelpers.Drag2D(previewDir, region); + + if (Event.current.type != EventType.Repaint || previewMesh == null) + { + return; + } + + Quaternion quaternion = Quaternion.Euler(this.previewDir.y, 0f, 0f) * Quaternion.Euler(0f, this.previewDir.x, 0f) * Quaternion.Euler(0, 120, -20f); + + previewHelper.BeginPreview(region, background); + + Bounds bounds = previewMesh.bounds; + float magnitude = Mathf.Sqrt(bounds.extents.sqrMagnitude); + float num = 4f * magnitude; + previewHelper.m_Camera.transform.position = -Vector3.forward * num; + previewHelper.m_Camera.transform.rotation = Quaternion.identity; + previewHelper.m_Camera.nearClipPlane = num - magnitude * 1.1f; + previewHelper.m_Camera.farClipPlane = num + magnitude * 1.1f; + + // Compute matrix to rotate the mesh around the center of its bounds: + Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero,quaternion,Vector3.one) * Matrix4x4.TRS(-bounds.center,Quaternion.identity,Vector3.one); + + Graphics.DrawMesh(previewMesh, matrix, previewMaterial,1, previewHelper.m_Camera, 0); + + Texture texture = previewHelper.EndPreview(); + GUI.DrawTexture(region, texture, ScaleMode.StretchToFill, true); + + } + + /** + * Creates a solid mesh from some Bounds. This is used to display the distance field volumetric preview. + */ + private Mesh CreateMeshForBounds(Bounds b){ + Mesh m = new Mesh(); + + /** Indices of bounds corners: + + Y + 2 6 + +------+ + 3 .'| 7 .'| + +---+--+' | + | | | | + | +--+---+ X + | .' 0 | .' 4 + +------+' + Z 1 5 + + */ + Vector3[] vertices = new Vector3[8]{ + b.center + new Vector3(-b.extents.x,-b.extents.y,-b.extents.z), //0 + b.center + new Vector3(-b.extents.x,-b.extents.y,b.extents.z), //1 + b.center + new Vector3(-b.extents.x,b.extents.y,-b.extents.z), //2 + b.center + new Vector3(-b.extents.x,b.extents.y,b.extents.z), //3 + b.center + new Vector3(b.extents.x,-b.extents.y,-b.extents.z), //4 + b.center + new Vector3(b.extents.x,-b.extents.y,b.extents.z), //5 + b.center + new Vector3(b.extents.x,b.extents.y,-b.extents.z), //6 + b.center + new Vector3(b.extents.x,b.extents.y,b.extents.z) //7 + }; + int[] triangles = new int[36]{ + 2,3,7, + 6,2,7, + + 7,5,4, + 6,7,4, + + 3,1,5, + 7,3,5, + + 2,0,3, + 3,0,1, + + 6,4,2, + 2,4,0, + + 4,5,0, + 5,1,0 + }; + + m.vertices = vertices; + m.triangles = triangles; + return m; + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiDistanceFieldEditor.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiDistanceFieldEditor.cs.meta new file mode 100644 index 00000000..60e8555c --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiDistanceFieldEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5d47dd3a8215841aca1fe5b272cb24f2 +timeCreated: 1507046737 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiForceZoneEditor.cs b/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiForceZoneEditor.cs new file mode 100644 index 00000000..884ac4c0 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiForceZoneEditor.cs @@ -0,0 +1,30 @@ +using UnityEditor; +using UnityEngine; + +namespace Obi +{ + + /** + * Custom inspector for ObiForceZone component. + */ + + [CustomEditor(typeof(ObiForceZone)), CanEditMultipleObjects] + public class ObiForceZoneEditor : Editor + { + + public override void OnInspectorGUI() + { + + serializedObject.UpdateIfRequiredOrScript(); + + DrawPropertiesExcluding(serializedObject, "m_Script"); + + // Apply changes to the serializedProperty + if (GUI.changed) + serializedObject.ApplyModifiedProperties(); + } + + } + +} + diff --git a/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiForceZoneEditor.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiForceZoneEditor.cs.meta new file mode 100644 index 00000000..99479b1e --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Collisions/ObiForceZoneEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 724435a7a84154b27bb0c8ea49b611df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Constraints.meta b/xiaofang/Assets/Obi/Editor/Common/Constraints.meta new file mode 100644 index 00000000..8cfd63c9 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Constraints.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cf28ba8ff6a7140e6a7e50a5030ff3e7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Constraints/ObiConstraintParametersDrawer.cs b/xiaofang/Assets/Obi/Editor/Common/Constraints/ObiConstraintParametersDrawer.cs new file mode 100644 index 00000000..579843b3 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Constraints/ObiConstraintParametersDrawer.cs @@ -0,0 +1,73 @@ +using UnityEngine; +using UnityEditor; +using System; + +namespace Obi +{ + + [CustomPropertyDrawer(typeof(Oni.ConstraintParameters))] + public class ObiConstraintParametersDrawer : PropertyDrawer + { + public static float padding = 4; + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + float propHeight = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + + EditorGUI.BeginProperty(position, label, property); + + SerializedProperty enabled = property.FindPropertyRelative("enabled"); + Rect contRect = new Rect(position.x+padding, position.y+padding, position.width-padding*2, propHeight); + + // Draw a box around the parameters: + GUI.enabled = enabled.boolValue; + GUI.Box(position,"",ObiEditorUtils.GetToggleablePropertyGroupStyle()); + GUI.enabled = true; + + // Draw main constraint toggle: + EditorGUI.BeginProperty(position, label, enabled); + EditorGUI.BeginChangeCheck(); + var newEnabled = EditorGUI.ToggleLeft(contRect, label.text, enabled.boolValue, EditorStyles.boldLabel); + // Only assign the value back if it was actually changed by the user. + // Otherwise a single value will be assigned to all objects when multi-object editing, + // even when the user didn't touch the control. + if (EditorGUI.EndChangeCheck()) + { + enabled.boolValue = newEnabled; + } + EditorGUI.EndProperty(); + + if (enabled.boolValue){ + + Rect evalRect = new Rect(position.x+padding, position.y+propHeight+padding, position.width-padding*2, propHeight); + Rect iterRect = new Rect(position.x+padding, position.y+propHeight*2+padding, position.width-padding*2, propHeight); + Rect sorRect = new Rect(position.x+padding, position.y+propHeight*3+padding, position.width-padding*2, EditorGUIUtility.singleLineHeight); + + EditorGUI.indentLevel++; + Rect evalCtrl = EditorGUI.PrefixLabel(evalRect,new GUIContent("Evaluation")); + EditorGUI.PropertyField(evalCtrl, property.FindPropertyRelative("evaluationOrder"),GUIContent.none); + + Rect iterCtrl = EditorGUI.PrefixLabel(iterRect,new GUIContent("Iterations")); + EditorGUI.PropertyField(iterCtrl, property.FindPropertyRelative("iterations"),GUIContent.none); + + Rect sorCtrl = EditorGUI.PrefixLabel(sorRect,new GUIContent("Relaxation")); + EditorGUI.PropertyField(sorCtrl, property.FindPropertyRelative("SORFactor"),GUIContent.none); + EditorGUI.indentLevel--; + + } + + EditorGUI.EndProperty(); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + SerializedProperty enabled = property.FindPropertyRelative("enabled"); + if (enabled.boolValue) + return EditorGUIUtility.singleLineHeight*4 + EditorGUIUtility.standardVerticalSpacing*3 + padding*2; + else + return EditorGUIUtility.singleLineHeight + padding*2; + } + } + +} + diff --git a/xiaofang/Assets/Obi/Editor/Common/Constraints/ObiConstraintParametersDrawer.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Constraints/ObiConstraintParametersDrawer.cs.meta new file mode 100644 index 00000000..ec24a969 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Constraints/ObiConstraintParametersDrawer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bc70cbc4838a4467687180e4d555b069 +timeCreated: 1515057027 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/ObiAboutWindow.cs b/xiaofang/Assets/Obi/Editor/Common/ObiAboutWindow.cs new file mode 100644 index 00000000..e7b22a08 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/ObiAboutWindow.cs @@ -0,0 +1,73 @@ + +using System; +using UnityEditor; +using UnityEngine; + +namespace Obi +{ + public class ObiAboutWindow : EditorWindow + { + + [MenuItem ("Window/Obi/About")] + public static void Init() + { + ObiAboutWindow window = (ObiAboutWindow)EditorWindow.GetWindow(typeof(ObiAboutWindow),true,"Welcome to Obi!"); + window.position = new Rect(Screen.width / 2, Screen.height / 2, 380, 300); + window.maxSize = window.minSize = new Vector2(380,300); + window.ShowPopup(); + } + + void OnGUI() + { + // Draw logo and copyright notice: + EditorGUILayout.BeginHorizontal(); + + GUILayout.Label(Resources.Load("obi_editor_logo")); + + EditorGUILayout.BeginVertical(GUILayout.MaxHeight(119.0f/EditorGUIUtility.pixelsPerPoint)); + + GUILayout.FlexibleSpace(); + + Color oldColor = GUI.contentColor; + GUI.contentColor = Color.black; + GUILayout.Label("Obi - Unified particle physics",EditorStyles.centeredGreyMiniLabel); + GUI.contentColor = oldColor; + + GUILayout.Label("© Copyright Virtual Method, 2015-2016.\nAll rights reserved.",EditorStyles.centeredGreyMiniLabel); + + GUILayout.FlexibleSpace(); + + EditorGUILayout.EndVertical(); + + EditorGUILayout.EndHorizontal(); + + DrawAboutGUI(); + + } + + void DrawAboutGUI(){ + + GUILayout.FlexibleSpace(); + + EditorGUILayout.LabelField("Programming:",EditorStyles.centeredGreyMiniLabel); + EditorGUILayout.LabelField("José María Méndez González",EditorStyles.centeredGreyMiniLabel); + + EditorGUILayout.LabelField("Additional resources:",EditorStyles.centeredGreyMiniLabel); + EditorGUILayout.LabelField("Lidia Martínez Prado",EditorStyles.centeredGreyMiniLabel); + + GUILayout.FlexibleSpace(); + + if (GUILayout.Button("Manual",EditorStyles.toolbarButton)) + Application.OpenURL("http://obi.virtualmethodstudio.com/tutorials/"); + if (GUILayout.Button("API docs",EditorStyles.toolbarButton)) + Application.OpenURL("http://obi.virtualmethodstudio.com/docs/"); + if (GUILayout.Button("visit www.virtualmethodstudio.com",EditorStyles.toolbarButton)) + Application.OpenURL("http://www.virtualmethodstudio.com"); + if (GUILayout.Button("Create preferences file", EditorStyles.toolbarButton)) + ObiEditorSettings.GetOrCreateSettings(); + + } + } +} + + diff --git a/xiaofang/Assets/Obi/Editor/Common/ObiAboutWindow.cs.meta b/xiaofang/Assets/Obi/Editor/Common/ObiAboutWindow.cs.meta new file mode 100644 index 00000000..6166f573 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/ObiAboutWindow.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c6764c51caa004a25ab49afc9865d2b3 +timeCreated: 1498062614 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/ObiSettingsProvider.cs b/xiaofang/Assets/Obi/Editor/Common/ObiSettingsProvider.cs new file mode 100644 index 00000000..a03cb52b --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/ObiSettingsProvider.cs @@ -0,0 +1,81 @@ +using System.Collections.Generic; +using System.IO; +using UnityEditor; +using UnityEngine; + +namespace Obi +{ + class ObiSettingsProvider : SettingsProvider + { + private SerializedObject m_ObiSettings; + + class Styles + { + public static GUIContent particleBrush = new GUIContent("Brush"); + public static GUIContent brushWireframe = new GUIContent("Brush wireframe"); + public static GUIContent particle = new GUIContent("Particle"); + public static GUIContent selectedParticle = new GUIContent("Selected particle"); + public static GUIContent activeParticle = new GUIContent("Active particle"); + public static GUIContent propertyGradient = new GUIContent("Property gradient"); + public static GUIContent particlePicking = new GUIContent("Particle GO picking"); + } + + const string m_ObiEditorSettingsPath = "Assets/ObiEditorSettings.asset"; + public ObiSettingsProvider(string path, SettingsScope scope = SettingsScope.User) + : base(path, scope) { } + + public static bool IsSettingsAvailable() + { + return File.Exists(m_ObiEditorSettingsPath); + } + +#if UNITY_2019_1_OR_NEWER + public override void OnActivate(string searchContext, UnityEngine.UIElements.VisualElement rootElement) +#else + public override void OnActivate(string searchContext, UnityEngine.Experimental.UIElements.VisualElement rootElement) +#endif + { + // This function is called when the user clicks on the MyCustom element in the Settings window. + m_ObiSettings = ObiEditorSettings.GetSerializedSettings(); + } + + public override void OnDeactivate() + { + base.OnDeactivate(); + + if (m_ObiSettings != null) + m_ObiSettings.ApplyModifiedProperties(); + } + + public override void OnGUI(string searchContext) + { + EditorGUILayout.LabelField("Colors", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(m_ObiSettings.FindProperty("m_ParticleBrush"), Styles.particleBrush); + EditorGUILayout.PropertyField(m_ObiSettings.FindProperty("m_BrushWireframe"),Styles.brushWireframe); + EditorGUILayout.PropertyField(m_ObiSettings.FindProperty("m_Particle"),Styles.particle); + EditorGUILayout.PropertyField(m_ObiSettings.FindProperty("m_SelectedParticle"),Styles.selectedParticle); + EditorGUILayout.PropertyField(m_ObiSettings.FindProperty("m_ActiveParticle"), Styles.activeParticle); + EditorGUILayout.PropertyField(m_ObiSettings.FindProperty("m_PropertyGradient"), Styles.propertyGradient); + + EditorGUILayout.LabelField("Scene view", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(m_ObiSettings.FindProperty("m_ParticlePicking"), Styles.particlePicking); + } + + // Register the SettingsProvider + [SettingsProvider] + public static SettingsProvider CreateMyCustomSettingsProvider() + { + if (IsSettingsAvailable()) + { + var provider = new ObiSettingsProvider("Preferences/Obi", SettingsScope.User); + + // Automatically extract all keywords from the Styles. + provider.keywords = GetSearchKeywordsFromGUIContentProperties(); + return provider; + } + + // Settings Asset doesn't exist yet; no need to display anything in the Settings window. + return null; + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Common/ObiSettingsProvider.cs.meta b/xiaofang/Assets/Obi/Editor/Common/ObiSettingsProvider.cs.meta new file mode 100644 index 00000000..7c37da33 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/ObiSettingsProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19ac664f594284b3c92ddb354155d814 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Rendering.meta b/xiaofang/Assets/Obi/Editor/Common/Rendering.meta new file mode 100644 index 00000000..07c70140 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Rendering.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 60a71308789c34bb8a53415b380a6706 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Rendering/ObiParticleRendererEditor.cs b/xiaofang/Assets/Obi/Editor/Common/Rendering/ObiParticleRendererEditor.cs new file mode 100644 index 00000000..310ac05e --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Rendering/ObiParticleRendererEditor.cs @@ -0,0 +1,32 @@ +using UnityEditor; +using UnityEngine; + +namespace Obi{ + + /** + * Custom inspector for ObiParticleRenderer component. + */ + + [CustomEditor(typeof(ObiParticleRenderer)), CanEditMultipleObjects] + public class ObiParticleHandleEditor : Editor + { + + public override void OnInspectorGUI() { + + serializedObject.UpdateIfRequiredOrScript(); + + Editor.DrawPropertiesExcluding(serializedObject,"m_Script"); + + // Apply changes to the serializedProperty + if (GUI.changed){ + + serializedObject.ApplyModifiedProperties(); + + } + + } + + } + +} + diff --git a/xiaofang/Assets/Obi/Editor/Common/Rendering/ObiParticleRendererEditor.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Rendering/ObiParticleRendererEditor.cs.meta new file mode 100644 index 00000000..e249bdb5 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Rendering/ObiParticleRendererEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2a7e6fcc51ab349e687aa6ca5bdf6739 +timeCreated: 1463090765 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Solver.meta b/xiaofang/Assets/Obi/Editor/Common/Solver.meta new file mode 100644 index 00000000..0d6cdda6 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Solver.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d82f874c48e764fb8b49f1767f76a94a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Solver/ObiSolverEditor.cs b/xiaofang/Assets/Obi/Editor/Common/Solver/ObiSolverEditor.cs new file mode 100644 index 00000000..542a1dc5 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Solver/ObiSolverEditor.cs @@ -0,0 +1,344 @@ +using UnityEditor; +using UnityEngine; +using UnityEditorInternal; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Obi +{ + + /** + * Custom inspector for ObiSolver components. + * Allows particle selection and constraint edition. + * + * Selection: + * + * - To select a particle, left-click on it. + * - You can select multiple particles by holding shift while clicking. + * - To deselect all particles, click anywhere on the object except a particle. + * + * Constraints: + * + * - To edit particle constraints, select the particles you wish to edit. + * - Constraints affecting any of the selected particles will appear in the inspector. + * - To add a new pin constraint to the selected particle(s), click on "Add Pin Constraint". + * + */ + [CustomEditor(typeof(ObiSolver)), CanEditMultipleObjects] + public class ObiSolverEditor : Editor + { + + [MenuItem("GameObject/3D Object/Obi/Obi Solver", false, 100)] + static void CreateObiSolver(MenuCommand menuCommand) + { + GameObject go = ObiEditorUtils.CreateNewSolver(); + GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject); + Selection.activeGameObject = go; + } + + ObiSolver solver; + + SerializedProperty backend; + SerializedProperty substeps; + SerializedProperty maxStepsPerFrame; + SerializedProperty synchronization; + SerializedProperty simulateWhenInvisible; + SerializedProperty parameters; + SerializedProperty gravity; + SerializedProperty gravitySpace; + SerializedProperty ambientWind; + SerializedProperty windSpace; + SerializedProperty worldLinearInertiaScale; + SerializedProperty worldAngularInertiaScale; + + SerializedProperty foamSubsteps; + SerializedProperty maxFoamVelocityStretch; + SerializedProperty foamFade; + SerializedProperty foamAccelAgingRange; + SerializedProperty foamAccelAging; + + SerializedProperty distanceConstraintParameters; + SerializedProperty bendingConstraintParameters; + SerializedProperty particleCollisionConstraintParameters; + SerializedProperty particleFrictionConstraintParameters; + SerializedProperty collisionConstraintParameters; + SerializedProperty frictionConstraintParameters; + SerializedProperty skinConstraintParameters; + SerializedProperty volumeConstraintParameters; + SerializedProperty shapeMatchingConstraintParameters; + SerializedProperty tetherConstraintParameters; + SerializedProperty pinConstraintParameters; + SerializedProperty stitchConstraintParameters; + SerializedProperty densityConstraintParameters; + SerializedProperty stretchShearConstraintParameters; + SerializedProperty bendTwistConstraintParameters; + SerializedProperty chainConstraintParameters; + + SerializedProperty maxSurfaceChunks; + SerializedProperty maxQueryResults; + SerializedProperty maxFoamParticles; + SerializedProperty maxParticleNeighbors; + SerializedProperty maxParticleContacts; + + BooleanPreference solverFoldout; + BooleanPreference simulationFoldout; + BooleanPreference advectionFoldout; + BooleanPreference collisionsFoldout; + BooleanPreference constraintsFoldout; + BooleanPreference memoryFoldout; + + GUIContent constraintLabelContent; + + public void OnEnable() + { + solver = (ObiSolver)target; + constraintLabelContent = new GUIContent(); + + solverFoldout = new BooleanPreference($"{target.GetType()}.solverFoldout", true); + simulationFoldout = new BooleanPreference($"{target.GetType()}.simulationFoldout", false); + advectionFoldout = new BooleanPreference($"{target.GetType()}.advectionFoldout", false); + collisionsFoldout = new BooleanPreference($"{target.GetType()}.collisionsFoldout", false); + constraintsFoldout = new BooleanPreference($"{target.GetType()}.constraintsFoldout", false); + memoryFoldout = new BooleanPreference($"{target.GetType()}.memoryFoldout", false); + + backend = serializedObject.FindProperty("m_Backend"); + substeps = serializedObject.FindProperty("substeps"); + maxStepsPerFrame = serializedObject.FindProperty("maxStepsPerFrame"); + synchronization = serializedObject.FindProperty("synchronization"); + simulateWhenInvisible = serializedObject.FindProperty("simulateWhenInvisible"); + parameters = serializedObject.FindProperty("parameters"); + gravity = serializedObject.FindProperty("gravity"); + gravitySpace = serializedObject.FindProperty("gravitySpace"); + ambientWind = serializedObject.FindProperty("ambientWind"); + windSpace = serializedObject.FindProperty("windSpace"); + worldLinearInertiaScale = serializedObject.FindProperty("worldLinearInertiaScale"); + worldAngularInertiaScale = serializedObject.FindProperty("worldAngularInertiaScale"); + + foamSubsteps = serializedObject.FindProperty("foamSubsteps"); + maxFoamVelocityStretch = serializedObject.FindProperty("maxFoamVelocityStretch"); + foamFade = serializedObject.FindProperty("foamFade"); + foamAccelAgingRange = serializedObject.FindProperty("foamAccelAgingRange"); + foamAccelAging = serializedObject.FindProperty("foamAccelAging"); + + distanceConstraintParameters = serializedObject.FindProperty("distanceConstraintParameters"); + bendingConstraintParameters = serializedObject.FindProperty("bendingConstraintParameters"); + particleCollisionConstraintParameters = serializedObject.FindProperty("particleCollisionConstraintParameters"); + particleFrictionConstraintParameters = serializedObject.FindProperty("particleFrictionConstraintParameters"); + collisionConstraintParameters = serializedObject.FindProperty("collisionConstraintParameters"); + frictionConstraintParameters = serializedObject.FindProperty("frictionConstraintParameters"); + skinConstraintParameters = serializedObject.FindProperty("skinConstraintParameters"); + volumeConstraintParameters = serializedObject.FindProperty("volumeConstraintParameters"); + shapeMatchingConstraintParameters = serializedObject.FindProperty("shapeMatchingConstraintParameters"); + tetherConstraintParameters = serializedObject.FindProperty("tetherConstraintParameters"); + pinConstraintParameters = serializedObject.FindProperty("pinConstraintParameters"); + stitchConstraintParameters = serializedObject.FindProperty("stitchConstraintParameters"); + densityConstraintParameters = serializedObject.FindProperty("densityConstraintParameters"); + stretchShearConstraintParameters = serializedObject.FindProperty("stretchShearConstraintParameters"); + bendTwistConstraintParameters = serializedObject.FindProperty("bendTwistConstraintParameters"); + chainConstraintParameters = serializedObject.FindProperty("chainConstraintParameters"); + + maxSurfaceChunks = serializedObject.FindProperty("m_MaxSurfaceChunks"); + maxQueryResults = serializedObject.FindProperty("maxQueryResults"); + maxFoamParticles = serializedObject.FindProperty("maxFoamParticles"); + maxParticleNeighbors = serializedObject.FindProperty("maxParticleNeighbors"); + maxParticleContacts = serializedObject.FindProperty("maxParticleContacts"); + } + + public override void OnInspectorGUI() + { + serializedObject.UpdateIfRequiredOrScript(); + EditorGUILayout.HelpBox("Particles:" + solver.allocParticleCount + "\n" + + "Simplices:" + solver.simplexCounts.simplexCount + "\n" + + "Contacts:" + solver.contactCount + "\n" + + "Simplex contacts:" + solver.particleContactCount, MessageType.None); + + solverFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(solverFoldout, "Solver settings"); + if (solverFoldout) + { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(backend); + +#if !(OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS) + if (backend.enumValueIndex == (int)ObiSolver.BackendType.Burst) + EditorGUILayout.HelpBox("The Burst backend depends on the following packages: Mathematics, Collections, Jobs and Burst. Please install the required dependencies. The solver will try to fall back to the Compute backend instead.", MessageType.Warning); +#endif + if (!SystemInfo.supportsComputeShaders) + { + EditorGUILayout.HelpBox("This platform doesn't support compute shaders. Please switch to the Burst backend.", MessageType.Error); + } + + + if (EditorGUI.EndChangeCheck()) + { + serializedObject.ApplyModifiedProperties(); + foreach (var t in targets) + (t as ObiSolver).UpdateBackend(); + } + + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("mode")); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("interpolation")); + EditorGUILayout.PropertyField(synchronization); + EditorGUILayout.PropertyField(substeps); + EditorGUILayout.PropertyField(maxStepsPerFrame); + } + EditorGUILayout.EndFoldoutHeaderGroup(); + + simulationFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(simulationFoldout, "Simulation settings"); + if (simulationFoldout) + { + EditorGUILayout.PropertyField(gravitySpace); + EditorGUILayout.PropertyField(gravity); + EditorGUILayout.PropertyField(windSpace); + EditorGUILayout.PropertyField(ambientWind); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("sleepThreshold")); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("maxVelocity")); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("maxAngularVelocity")); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("damping")); + EditorGUILayout.PropertyField(worldLinearInertiaScale); + EditorGUILayout.PropertyField(worldAngularInertiaScale); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("maxAnisotropy")); + EditorGUILayout.PropertyField(simulateWhenInvisible); + } + EditorGUILayout.EndFoldoutHeaderGroup(); + + advectionFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(advectionFoldout, "Foam settings"); + if (advectionFoldout) + { + EditorGUILayout.PropertyField(foamSubsteps); + EditorGUILayout.PropertyField(maxFoamVelocityStretch); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("foamGravityScale")); + EditorGUILayout.PropertyField(foamFade); + EditorGUILayout.PropertyField(foamAccelAgingRange); + EditorGUILayout.PropertyField(foamAccelAging); + } + EditorGUILayout.EndFoldoutHeaderGroup(); + + collisionsFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(collisionsFoldout, "Collision settings"); + if (collisionsFoldout) + { + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("colliderCCD")); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("particleCCD")); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("collisionMargin")); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("maxDepenetration")); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("shockPropagation")); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("surfaceCollisionIterations")); + EditorGUILayout.PropertyField(parameters.FindPropertyRelative("surfaceCollisionTolerance")); + } + EditorGUILayout.EndFoldoutHeaderGroup(); + + constraintsFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(constraintsFoldout, "Constraint settings"); + if (constraintsFoldout) + { + constraintLabelContent.text = "Distance"; + EditorGUILayout.PropertyField(distanceConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Bending"; + EditorGUILayout.PropertyField(bendingConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Particle collision / Queries"; + EditorGUILayout.PropertyField(particleCollisionConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Particle friction"; + EditorGUILayout.PropertyField(particleFrictionConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Collision"; + EditorGUILayout.PropertyField(collisionConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Friction"; + EditorGUILayout.PropertyField(frictionConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Skin"; + EditorGUILayout.PropertyField(skinConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Volume"; + EditorGUILayout.PropertyField(volumeConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Shape matching"; + EditorGUILayout.PropertyField(shapeMatchingConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Tether"; + EditorGUILayout.PropertyField(tetherConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Pin"; + EditorGUILayout.PropertyField(pinConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Stitch"; + EditorGUILayout.PropertyField(stitchConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Density"; + EditorGUILayout.PropertyField(densityConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Stretch & Shear"; + EditorGUILayout.PropertyField(stretchShearConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Bend & Twist"; + EditorGUILayout.PropertyField(bendTwistConstraintParameters, constraintLabelContent); + + constraintLabelContent.text = "Chain"; + EditorGUILayout.PropertyField(chainConstraintParameters, constraintLabelContent); + } + EditorGUILayout.EndFoldoutHeaderGroup(); + + memoryFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(memoryFoldout, "Memory budget"); + if (memoryFoldout) + { + EditorGUILayout.PropertyField(maxQueryResults); + EditorGUILayout.PropertyField(maxFoamParticles); + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(maxSurfaceChunks); + if (EditorGUI.EndChangeCheck()) + { + serializedObject.ApplyModifiedProperties(); + foreach (var t in targets) + (t as ObiSolver).dirtyRendering |= (int)Oni.RenderingSystemType.Fluid; + } + + EditorGUILayout.PropertyField(maxParticleNeighbors); + EditorGUILayout.PropertyField(maxParticleContacts); + + uint usedChunks = solver.usedSurfaceChunks; + float usagePercentage = usedChunks / (float)maxSurfaceChunks.intValue; + uint foamParticles = solver.initialized ? solver.implementation.activeFoamParticleCount : 0; + + // memory consumption per chunk: + // (8 + 12 + 64*4 + 64*6*4 + 64*16) = 2836 bytes + EditorGUILayout.HelpBox("Active foam particles: " + foamParticles + "/" + maxFoamParticles.intValue + "\n"+ + "Surface memory (Mb): " + string.Format("{0:N2}", maxSurfaceChunks.intValue * 0.002836f)+ "\n"+ + "Used surface chunks: "+ usedChunks + "/"+ maxSurfaceChunks.intValue + ", hashtable usage "+ string.Format("{0:N1}", usagePercentage * 100) + "%", MessageType.None); + + if (usagePercentage >= 0.5f) + { + EditorGUILayout.HelpBox("Hashtable usage should be below 50% for best performance. Increase max surface chunks if % is too high.", MessageType.Warning); + } + } + EditorGUILayout.EndFoldoutHeaderGroup(); + + // Apply changes to the serializedProperty + if (GUI.changed) + { + serializedObject.ApplyModifiedProperties(); + solver.PushSolverParameters(); + } + + } + + [DrawGizmo(GizmoType.InSelectionHierarchy | GizmoType.Selected)] + static void DrawGizmoForSolver(ObiSolver solver, GizmoType gizmoType) + { + + if ((gizmoType & GizmoType.InSelectionHierarchy) != 0) + { + + Gizmos.color = new Color(1, 1, 1, 0.5f); + var bounds = solver.bounds; + Gizmos.DrawWireCube(bounds.center, bounds.size); + } + + } + + } +} + + diff --git a/xiaofang/Assets/Obi/Editor/Common/Solver/ObiSolverEditor.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Solver/ObiSolverEditor.cs.meta new file mode 100644 index 00000000..07e52a91 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Solver/ObiSolverEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d776094922a7647ccb5194d08e93ceaf +timeCreated: 1444024856 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils.meta b/xiaofang/Assets/Obi/Editor/Common/Utils.meta new file mode 100644 index 00000000..b0089603 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b7a80ed0e578946aaad351df0313281a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils/BooleanPreference.cs b/xiaofang/Assets/Obi/Editor/Common/Utils/BooleanPreference.cs new file mode 100644 index 00000000..d74b8dc4 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils/BooleanPreference.cs @@ -0,0 +1,46 @@ + +using UnityEditor; + +namespace Obi +{ + public class BooleanPreference + { + bool m_Value; + string m_Name; + bool m_Loaded; + + public BooleanPreference(string name, bool value) + { + m_Name = name; + m_Loaded = false; + m_Value = value; + } + + private void Load() + { + if (m_Loaded) + return; + + m_Loaded = true; + m_Value = EditorPrefs.GetBool(m_Name, m_Value); + } + + public bool value + { + get { Load(); return m_Value; } + set + { + Load(); + if (m_Value == value) + return; + m_Value = value; + EditorPrefs.SetBool(m_Name, value); + } + } + + public static implicit operator bool(BooleanPreference s) + { + return s.value; + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils/BooleanPreference.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Utils/BooleanPreference.cs.meta new file mode 100644 index 00000000..f74e188c --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils/BooleanPreference.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4af60554659c94226a5b3cf0b5987a5f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils/ObiEditorUtils.cs b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiEditorUtils.cs new file mode 100644 index 00000000..be05d5a3 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiEditorUtils.cs @@ -0,0 +1,254 @@ +using System; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEditor; +using UnityEditor.SceneManagement; +using System.IO; +using UnityEngine.Rendering; + +namespace Obi{ + + public static class ObiEditorUtils + { + static GUIStyle separatorLine; + static GUIStyle toggleablePropertyGroup; + static GUIStyle boldToggle; + + public static GUIStyle GetSeparatorLineStyle() + { + if (separatorLine == null) + { + separatorLine = new GUIStyle(EditorGUIUtility.GetBuiltinSkin(EditorSkin.Scene).box); + separatorLine.normal.background = Resources.Load("SeparatorLine"); + separatorLine.border = new RectOffset(3, 3, 0, 0); + separatorLine.padding = new RectOffset(0, 0, 0, 0); + separatorLine.margin = new RectOffset(0, 0, 0, 0); + separatorLine.fixedHeight = 3; + separatorLine.stretchWidth = true; + } + return separatorLine; + } + + public static GUIStyle GetToggleablePropertyGroupStyle() + { + if (toggleablePropertyGroup == null) + { + toggleablePropertyGroup = new GUIStyle(); + toggleablePropertyGroup.normal.background = Resources.Load("ToggleableGroupBg"); + toggleablePropertyGroup.border = new RectOffset(3, 3, 3, 3); + toggleablePropertyGroup.padding = new RectOffset(0, 0, 0, 0); + toggleablePropertyGroup.margin = new RectOffset(0, 0, 3, 3); + } + return toggleablePropertyGroup; + } + + public static GUIStyle GetBoldToggleStyle() + { + if (boldToggle == null) + { + boldToggle = new GUIStyle(EditorStyles.toggle); + boldToggle.fontStyle = FontStyle.Bold; + } + return boldToggle; + } + + public static void SaveMesh (Mesh mesh, string title, string name, bool makeNewInstance = true, bool optimizeMesh = true) { + + string path = EditorUtility.SaveFilePanel(title, "Assets/", name, "asset"); + if (string.IsNullOrEmpty(path)) return; + + path = FileUtil.GetProjectRelativePath(path); + + Mesh meshToSave = (makeNewInstance) ? GameObject.Instantiate(mesh) as Mesh : mesh; + + if (optimizeMesh) + MeshUtility.Optimize(meshToSave); + + AssetDatabase.CreateAsset(meshToSave, path); + AssetDatabase.SaveAssets(); + } + + public static void PlaceActorRoot(GameObject element, MenuCommand menuCommand) + { + GameObject parent = menuCommand.context as GameObject; + + if (parent == null) + { + parent = GetOrCreateSolverObject(); + } + + if (parent.GetComponentsInParent(true).Length == 0) + { + // Create solver under context GameObject, + // and make that be the parent which actor is added under. + GameObject solver = CreateNewSolver(); + solver.transform.SetParent(parent.transform, false); + parent = solver; + } + + // The element needs to be already in its destination scene when the + // RegisterCreatedObjectUndo is performed; otherwise the scene it was created in is dirtied. + SceneManager.MoveGameObjectToScene(element, parent.scene); + + Undo.RegisterCreatedObjectUndo(element, "Create " + element.name); + + if (element.transform.parent == null) + Undo.SetTransformParent(element.transform, parent.transform, "Parent " + element.name); + + GameObjectUtility.EnsureUniqueNameForSibling(element); + + // We have to fix up the undo name since the name of the object was only known after reparenting it. + Undo.SetCurrentGroupName("Create " + element.name); + + GameObjectUtility.SetParentAndAlign(element, parent); + Selection.activeGameObject = element; + } + + // Helper function that returns a Solver GameObject; preferably a parent of the selection, or other existing Canvas. + private static GameObject GetOrCreateSolverObject() + { + GameObject selectedGo = Selection.activeGameObject; + + // Try to find a gameobject that is the selected GO or one if its parents. + ObiSolver solver = (selectedGo != null) ? selectedGo.GetComponentInParent() : null; + if (IsValidSolver(solver)) + return solver.gameObject; + + // No solver in selection or its parents? Then use any valid solver. + // We have to find all loaded solvers, not just the ones in main scenes. + ObiSolver[] solverArray = StageUtility.GetCurrentStageHandle().FindComponentsOfType(); + for (int i = 0; i < solverArray.Length; i++) + if (IsValidSolver(solverArray[i])) + return solverArray[i].gameObject; + + // No solver in the scene at all? Then create a new one. + return CreateNewSolver(); + } + + public static GameObject CreateNewSolver() + { + // Root for the actors. + var root = new GameObject("Obi Solver", typeof(ObiSolver)); + + // Works for all stages. + StageUtility.PlaceGameObjectInCurrentStage(root); + Undo.RegisterCreatedObjectUndo(root, "Create " + root.name); + + return root; + } + + static bool IsValidSolver(ObiSolver solver) + { + if (solver == null || !solver.gameObject.activeInHierarchy) + return false; + + if (EditorUtility.IsPersistent(solver) || (solver.hideFlags & HideFlags.HideInHierarchy) != 0) + return false; + + if (StageUtility.GetStageHandle(solver.gameObject) != StageUtility.GetCurrentStageHandle()) + return false; + + return true; + } + + public static void DoPropertyGroup(GUIContent content, System.Action action) + { + EditorGUILayout.BeginVertical(GetToggleablePropertyGroupStyle()); + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField(content, EditorStyles.boldLabel); + EditorGUILayout.EndHorizontal(); + + if (action != null) + { + EditorGUI.indentLevel++; + action(); + EditorGUI.indentLevel--; + } + } + EditorGUILayout.EndVertical(); + } + + public static void DoToggleablePropertyGroup(SerializedProperty enabledProperty, GUIContent content, System.Action action) + { + bool enabled = GUI.enabled; + GUI.enabled &= enabledProperty.boolValue; + EditorGUILayout.BeginVertical(GetToggleablePropertyGroupStyle()); + GUI.enabled = enabled; + { + EditorGUILayout.BeginHorizontal(); + enabledProperty.boolValue = EditorGUILayout.ToggleLeft(content,enabledProperty.boolValue,EditorStyles.boldLabel); + EditorGUILayout.EndHorizontal(); + + if (enabledProperty.boolValue && action != null) + { + EditorGUI.indentLevel++; + action(); + EditorGUI.indentLevel--; + } + } + EditorGUILayout.EndVertical(); + } + + public static int DoToolBar(int selected, GUIContent[] items) + { + // Keep the selected index within the bounds of the items array + selected = selected < 0 ? 0 : selected >= items.Length ? items.Length - 1 : selected; + + GUIStyle style = GUI.skin.FindStyle("Button"); + + EditorGUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + for (int i = 0; i < items.Length; i++) + { + if (i == 0 && items.Length > 1) + style = GUI.skin.FindStyle("ButtonLeft"); + else if (items.Length > 1 && i == items.Length-1) + style = GUI.skin.FindStyle("ButtonRight"); + else if (i > 0) + style = GUI.skin.FindStyle("ButtonMid"); + + + // Display toggle. Get if toggle changed. + bool change = GUILayout.Toggle(selected == i, items[i],style,GUILayout.Height(24)); + // If changed, set selected to current index. + if (change) + selected = i; + } + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + + // Return the currently selected item's index + return selected; + } + + public static void DrawArrowHandle(Vector3 posA, Vector3 posB, float headAngle = 30, float headLength = 0.18f) { + Handles.DrawLine(posA, posB); + + var look = Quaternion.LookRotation(posA - posB, Camera.current.transform.forward); + var one = look * Quaternion.Euler(0, 180 + headAngle, 0) * new Vector3(0, 0, 1); + var two = look * Quaternion.Euler(0, 180 - headAngle, 0) * new Vector3(0, 0, 1); + + var sizeA = HandleUtility.GetHandleSize(posA) * headLength; + Handles.DrawLine(posA, posA + one * sizeA); + Handles.DrawLine(posA, posA + two * sizeA); + + var sizeB = HandleUtility.GetHandleSize(posB) * headLength; + Handles.DrawLine(posB, posB - one * sizeB); + Handles.DrawLine(posB, posB - two * sizeB); } + + public static Material GetDefaultMaterial() + { + if (GraphicsSettings.defaultRenderPipeline != null) + { + return GraphicsSettings.defaultRenderPipeline.defaultMaterial; + } + else + { + return AssetDatabase.GetBuiltinExtraResource("Default-Diffuse.mat"); + } + } + } +} + + diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils/ObiEditorUtils.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiEditorUtils.cs.meta new file mode 100644 index 00000000..582e6640 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiEditorUtils.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 57c936f7a4f99456d944beed51c5b935 +timeCreated: 1452817402 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils/ObiFoamGeneratorEditor.cs b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiFoamGeneratorEditor.cs new file mode 100644 index 00000000..42d4e21d --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiFoamGeneratorEditor.cs @@ -0,0 +1,24 @@ +using UnityEditor; +using UnityEngine; + +namespace Obi +{ + + [CustomEditor(typeof(ObiFoamGenerator)), CanEditMultipleObjects] + public class ObiFoamGeneratorEditor : Editor + { + public override void OnInspectorGUI() + { + serializedObject.UpdateIfRequiredOrScript(); + + DrawPropertiesExcluding(serializedObject, "m_Script"); + + // Apply changes to the serializedProperty + if (GUI.changed) + serializedObject.ApplyModifiedProperties(); + } + + } + +} + diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils/ObiFoamGeneratorEditor.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiFoamGeneratorEditor.cs.meta new file mode 100644 index 00000000..baab1807 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiFoamGeneratorEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b9656e2c54d9e4c478c74ca6d97428f8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils/ObiParticleAttachmentEditor.cs b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiParticleAttachmentEditor.cs new file mode 100644 index 00000000..1da9fd36 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiParticleAttachmentEditor.cs @@ -0,0 +1,121 @@ +using UnityEditor; +using UnityEditorInternal; +using UnityEngine; +using System.Collections.Generic; +using System.Linq; + + +namespace Obi +{ + + [CustomEditor(typeof(ObiParticleAttachment))] + public class ObiParticleAttachmentEditor : Editor + { + + SerializedProperty targetTransform; + SerializedProperty particleGroup; + SerializedProperty attachmentType; + SerializedProperty constrainOrientation; + SerializedProperty compliance; + SerializedProperty breakThreshold; + + ObiParticleAttachment attachment; + + public void OnEnable() + { + + attachment = target as ObiParticleAttachment; + targetTransform = serializedObject.FindProperty("m_Target"); + particleGroup = serializedObject.FindProperty("m_ParticleGroup"); + attachmentType = serializedObject.FindProperty("m_AttachmentType"); + constrainOrientation = serializedObject.FindProperty("m_ConstrainOrientation"); + compliance = serializedObject.FindProperty("m_Compliance"); + breakThreshold = serializedObject.FindProperty("m_BreakThreshold"); + } + + public override void OnInspectorGUI() + { + + serializedObject.UpdateIfRequiredOrScript(); + + // warn about incorrect setups: + if (!attachmentType.hasMultipleDifferentValues && !targetTransform.hasMultipleDifferentValues) + { + if (attachmentType.enumValueIndex == (int)ObiParticleAttachment.AttachmentType.Dynamic) + { + var targetValue = targetTransform.objectReferenceValue as UnityEngine.Component; + if (targetValue != null) + { + var collider = targetValue.GetComponent(); + if (collider == null) + { + EditorGUILayout.HelpBox("Dynamic attachments require the target object to have a ObiCollider component. Either add one, or change the attachment type to Static.", MessageType.Warning); + } + } + } + } + + EditorGUI.BeginChangeCheck(); + Transform trget = EditorGUILayout.ObjectField("Target", attachment.target, typeof(Transform), true) as Transform; + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(attachment, "Set target"); + attachment.target = trget; + PrefabUtility.RecordPrefabInstancePropertyModifications(attachment); + } + + + var blueprint = attachment.actor.sourceBlueprint; + + if (blueprint != null) + { + var rect = EditorGUILayout.GetControlRect(); + var label = EditorGUI.BeginProperty(rect, new GUIContent("Particle group"), particleGroup); + rect = EditorGUI.PrefixLabel(rect, label); + + if (GUI.Button(rect, attachment.particleGroup != null ? attachment.particleGroup.name : "None", EditorStyles.popup)) + { + // create the menu and add items to it + GenericMenu menu = new GenericMenu(); + menu.allowDuplicateNames = true; + + for (int i = 0; i < blueprint.groups.Count; ++i) + { + menu.AddItem(new GUIContent(blueprint.groups[i].name), blueprint.groups[i] == attachment.particleGroup, OnParticleGroupSelected, blueprint.groups[i]); + } + + // display the menu + menu.DropDown(rect); + } + + EditorGUI.EndProperty(); + } + + EditorGUILayout.PropertyField(attachmentType, new GUIContent("Type")); + + if (attachment.actor.usesOrientedParticles) + EditorGUILayout.PropertyField(constrainOrientation, new GUIContent("Constraint Orientation")); + + if (attachment.attachmentType == ObiParticleAttachment.AttachmentType.Dynamic) + { + EditorGUILayout.PropertyField(compliance, new GUIContent("Compliance")); + EditorGUILayout.PropertyField(breakThreshold, new GUIContent("Break threshold")); + } + + if (GUI.changed) + serializedObject.ApplyModifiedProperties(); + + } + + // the GenericMenu.MenuFunction2 event handler for when a menu item is selected + void OnParticleGroupSelected(object index) + { + Undo.RecordObject(attachment, "Set particle group"); + attachment.particleGroup = index as ObiParticleGroup; + PrefabUtility.RecordPrefabInstancePropertyModifications(attachment); + } + } + +} + + diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils/ObiParticleAttachmentEditor.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiParticleAttachmentEditor.cs.meta new file mode 100644 index 00000000..4d17dbba --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiParticleAttachmentEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1587d981fa96c4b2291e19484a5a5b13 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils/ObiRaycastHit.cs b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiRaycastHit.cs new file mode 100644 index 00000000..d56e3277 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiRaycastHit.cs @@ -0,0 +1,26 @@ +using UnityEngine; +using System.Collections.Generic; + +namespace Obi +{ + public class ObiRaycastHit + { + + /// Distance from the Raycast origin to the point of impact. + public float distance; + /// The position in model space where a raycast intercepted a triangle. + public Vector3 position; + /// The normal in model space of the triangle that this raycast hit. + public Vector3 normal; + /// The triangle index of the hit face. + public int triangle; + + public ObiRaycastHit(float distance, Vector3 position, Vector3 normal, int triangle) + { + this.distance = distance; + this.position = position; + this.normal = normal; + this.triangle = triangle; + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils/ObiRaycastHit.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiRaycastHit.cs.meta new file mode 100644 index 00000000..27e33591 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils/ObiRaycastHit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2eb47a91b4f7c4f4aa52d4b914caa96e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils/PreviewHelpers.cs b/xiaofang/Assets/Obi/Editor/Common/Utils/PreviewHelpers.cs new file mode 100644 index 00000000..5ba601a9 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils/PreviewHelpers.cs @@ -0,0 +1,150 @@ +using System; +using UnityEditor; +using UnityEngine; + +namespace Obi{ + + class PreviewHelpers + { + + // Preview interaction related stuff: + static int sliderHash = "Slider".GetHashCode(); + public static Vector2 Drag2D(Vector2 scrollPosition, Rect position) + { + int controlID = GUIUtility.GetControlID(PreviewHelpers.sliderHash, FocusType.Passive); + Event current = Event.current; + switch (current.GetTypeForControl(controlID)) + { + case EventType.MouseDown: + if (position.Contains(current.mousePosition) && position.width > 50f) + { + GUIUtility.hotControl = controlID; + current.Use(); + EditorGUIUtility.SetWantsMouseJumping(1); + } + break; + case EventType.MouseUp: + if (GUIUtility.hotControl == controlID) + { + GUIUtility.hotControl = 0; + } + EditorGUIUtility.SetWantsMouseJumping(0); + break; + case EventType.MouseDrag: + if (GUIUtility.hotControl == controlID) + { + scrollPosition -= current.delta * (float)((!current.shift) ? 1 : 3) / Mathf.Min(position.width, position.height) * 140f; + scrollPosition.y = Mathf.Clamp(scrollPosition.y, -90f, 90f); + current.Use(); + GUI.changed = true; + } + break; + } + return scrollPosition; + } + + public Camera m_Camera; + public float m_CameraFieldOfView = 30f; + public Light[] m_Light = new Light[2]; + internal RenderTexture m_RenderTexture; + public PreviewHelpers() : this(false) + { + } + public PreviewHelpers(bool renderFullScene) + { + GameObject gameObject = EditorUtility.CreateGameObjectWithHideFlags("PreRenderCamera", HideFlags.HideAndDontSave, new Type[] + { + typeof(Camera) + }); + this.m_Camera = gameObject.GetComponent(); + this.m_Camera.fieldOfView = this.m_CameraFieldOfView; + this.m_Camera.cullingMask = 1 << 1; + this.m_Camera.enabled = false; + this.m_Camera.clearFlags = CameraClearFlags.SolidColor; + this.m_Camera.farClipPlane = 10f; + this.m_Camera.nearClipPlane = 1f; + this.m_Camera.backgroundColor = new Color(0.192156866f, 0.192156866f, 0.192156866f, 0); + this.m_Camera.renderingPath = RenderingPath.Forward; + this.m_Camera.useOcclusionCulling = false; + + for (int i = 0; i < 2; i++) + { + GameObject gameObject2 = EditorUtility.CreateGameObjectWithHideFlags("PreRenderLight", HideFlags.HideAndDontSave, new Type[] + { + typeof(Light) + }); + this.m_Light[i] = gameObject2.GetComponent(); + this.m_Light[i].type = LightType.Directional; + this.m_Light[i].intensity = 1f; + this.m_Light[i].enabled = false; + } + + this.m_Light[0].color = new Color(0.4f, 0.4f, 0.45f, 0f); + this.m_Light[1].transform.rotation = Quaternion.Euler(340f, 218f, 177f); + this.m_Light[1].color = new Color(0.4f, 0.4f, 0.45f, 0f) * 0.7f; + } + public void Cleanup() + { + if (this.m_Camera) + { + UnityEngine.Object.DestroyImmediate(this.m_Camera.gameObject, true); + } + if (this.m_RenderTexture) + { + UnityEngine.Object.DestroyImmediate(this.m_RenderTexture); + this.m_RenderTexture = null; + } + Light[] light = this.m_Light; + for (int i = 0; i < light.Length; i++) + { + Light light2 = light[i]; + if (light2) + { + UnityEngine.Object.DestroyImmediate(light2.gameObject, true); + } + } + } + + private void InitPreview(Rect r) + { + int num = (int)r.width; + int num2 = (int)r.height; + if (!this.m_RenderTexture || this.m_RenderTexture.width != num || this.m_RenderTexture.height != num2) + { + if (this.m_RenderTexture) + { + UnityEngine.Object.DestroyImmediate(this.m_RenderTexture); + this.m_RenderTexture = null; + } + float scaleFactor = this.GetScaleFactor((float)num, (float)num2); + this.m_RenderTexture = new RenderTexture((int)((float)num * scaleFactor), (int)((float)num2 * scaleFactor), 16); + this.m_RenderTexture.hideFlags = HideFlags.HideAndDontSave; + this.m_Camera.targetTexture = this.m_RenderTexture; + } + float num3 = (this.m_RenderTexture.width > 0) ? Mathf.Max(1f, (float)this.m_RenderTexture.height / (float)this.m_RenderTexture.width) : 1f; + this.m_Camera.fieldOfView = Mathf.Atan(num3 * Mathf.Tan(this.m_CameraFieldOfView * 0.5f * 0.0174532924f)) * 57.29578f * 2f; + + } + public float GetScaleFactor(float width, float height) + { + float a = Mathf.Max(Mathf.Min(width * 2f, 1024f), width) / width; + float b = Mathf.Max(Mathf.Min(height * 2f, 1024f), height) / height; + return Mathf.Min(a, b); + } + + public void BeginPreview(Rect r, GUIStyle previewBackground) + { + this.InitPreview(r); + if (previewBackground == null || previewBackground == GUIStyle.none) + { + return; + } + } + public Texture EndPreview() + { + m_Camera.Render(); + return this.m_RenderTexture; + } + + } +} diff --git a/xiaofang/Assets/Obi/Editor/Common/Utils/PreviewHelpers.cs.meta b/xiaofang/Assets/Obi/Editor/Common/Utils/PreviewHelpers.cs.meta new file mode 100644 index 00000000..8ff77efc --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Common/Utils/PreviewHelpers.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 886ef4783c97a4dac9034b48a6c94b6c +timeCreated: 1438171037 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Obi.Editor.asmdef b/xiaofang/Assets/Obi/Editor/Obi.Editor.asmdef new file mode 100644 index 00000000..3c97604a --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Obi.Editor.asmdef @@ -0,0 +1,33 @@ +{ + "name": "Obi.Editor", + "references": [ + "GUID:da7abd44cdeea48609605c1c2c9609c0" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.collections", + "expression": "0.8.0-preview.5", + "define": "OBI_COLLECTIONS" + }, + { + "name": "com.unity.burst", + "expression": "1.2.3-verified", + "define": "OBI_BURST" + }, + { + "name": "com.unity.mathematics", + "expression": "1.0.1", + "define": "OBI_MATHEMATICS" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Obi.Editor.asmdef.meta b/xiaofang/Assets/Obi/Editor/Obi.Editor.asmdef.meta new file mode 100644 index 00000000..770027d7 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Obi.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 180639cf42b5c450c8fdad7e31d2ec13 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/ObiParticleSelection.cs b/xiaofang/Assets/Obi/Editor/ObiParticleSelection.cs new file mode 100644 index 00000000..06f1bb9d --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/ObiParticleSelection.cs @@ -0,0 +1,186 @@ +using UnityEngine; +using UnityEditor; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Obi +{ + + public static class ObiParticleSelection + { + + static int particleSelectorHash = "ObiParticleSelectorHash".GetHashCode(); + + static Vector2 startPos; + static Vector2 currentPos; + static bool dragging = false; + static Rect marquee; + + public static bool DoSelection(Vector3[] positions, + bool[] selectionStatus, + bool[] facingCamera) + { + + Matrix4x4 cachedMatrix = Handles.matrix; + + int controlID = GUIUtility.GetControlID(particleSelectorHash, FocusType.Passive); + int selectedParticleIndex = -1; + bool selectionStatusChanged = false; + + // select vertex on mouse click: + switch (Event.current.GetTypeForControl(controlID)) + { + + case EventType.MouseDown: + + if (Event.current.button != 0) break; + + startPos = Event.current.mousePosition; + marquee.Set(0, 0, 0, 0); + + // If the user is not pressing shift, clear selection. + if ((Event.current.modifiers & EventModifiers.Shift) == 0 && (Event.current.modifiers & EventModifiers.Alt) == 0) + { + for (int i = 0; i < selectionStatus.Length; i++) + selectionStatus[i] = false; + } + + // Allow use of marquee selection + if (Event.current.modifiers == EventModifiers.None || (Event.current.modifiers & EventModifiers.Shift) != 0) + GUIUtility.hotControl = controlID; + + float minSqrDistance = System.Single.MaxValue; + + for (int i = 0; i < positions.Length; i++) + { + // skip not selectable particles: + //if (!facingCamera[i] && (selectBackfaces & ObiActorBlueprintEditor.ParticleCulling.Back) != 0) continue; + //if (facingCamera[i] && (selectBackfaces & ObiActorBlueprintEditor.ParticleCulling.Front) != 0) continue; + + // get particle position in gui space: + Vector2 pos = HandleUtility.WorldToGUIPoint(positions[i]); + + // get distance from mouse position to particle position: + float sqrDistance = Vector2.SqrMagnitude(startPos - pos); + + // check if this particle is closer to the cursor that any previously considered particle. + if (sqrDistance < 100 && sqrDistance < minSqrDistance) + { //magic number 100 = 10*10, where 10 is min distance in pixels to select a particle. + minSqrDistance = sqrDistance; + selectedParticleIndex = i; + } + + } + + if (selectedParticleIndex >= 0) + { // toggle particle selection status. + + selectionStatus[selectedParticleIndex] = !selectionStatus[selectedParticleIndex]; + selectionStatusChanged = true; + GUIUtility.hotControl = controlID; + Event.current.Use(); + + } + else if (Event.current.modifiers == EventModifiers.None) + { // deselect all particles: + for (int i = 0; i < selectionStatus.Length; i++) + selectionStatus[i] = false; + + selectionStatusChanged = true; + } + + break; + + case EventType.MouseMove: + SceneView.RepaintAll(); + break; + + case EventType.MouseDrag: + + if (GUIUtility.hotControl == controlID) + { + + currentPos = Event.current.mousePosition; + if (!dragging && Vector2.Distance(startPos, currentPos) > 5) + { + dragging = true; + } + else + { + GUIUtility.hotControl = controlID; + Event.current.Use(); + } + + //update marquee rect: + float left = Mathf.Min(startPos.x, currentPos.x); + float right = Mathf.Max(startPos.x, currentPos.x); + float bottom = Mathf.Min(startPos.y, currentPos.y); + float top = Mathf.Max(startPos.y, currentPos.y); + + marquee = new Rect(left, bottom, right - left, top - bottom); + + } + + break; + + case EventType.MouseUp: + + if (GUIUtility.hotControl == controlID) + { + + dragging = false; + + for (int i = 0; i < positions.Length; i++) + { + + // skip not selectable particles: + //switch (selectBackfaces) + { + //case ObiActorBlueprintEditor.ParticleCulling.Back: if (!facingCamera[i]) continue; break; + //case ObiActorBlueprintEditor.ParticleCulling.Front: if (facingCamera[i]) continue; break; + } + + // get particle position in gui space: + Vector2 pos = HandleUtility.WorldToGUIPoint(positions[i]); + + if (pos.x > marquee.xMin && pos.x < marquee.xMax && pos.y > marquee.yMin && pos.y < marquee.yMax) + { + selectionStatus[i] = true; + selectionStatusChanged = true; + } + + } + + GUIUtility.hotControl = 0; + Event.current.Use(); + } + + break; + + case EventType.Repaint: + + Handles.matrix = Matrix4x4.identity; + + if (dragging) + { + GUISkin oldSkin = GUI.skin; + GUI.skin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Scene); + Handles.BeginGUI(); + GUI.Box(new Rect(marquee.xMin, marquee.yMin, marquee.width, marquee.height), ""); + Handles.EndGUI(); + GUI.skin = oldSkin; + } + + Handles.matrix = cachedMatrix; + + break; + + } + + return selectionStatusChanged; + } + + } +} + diff --git a/xiaofang/Assets/Obi/Editor/ObiParticleSelection.cs.meta b/xiaofang/Assets/Obi/Editor/ObiParticleSelection.cs.meta new file mode 100644 index 00000000..c877a037 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/ObiParticleSelection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7020925dabebf42b7915da74e58c3b5e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/ObiStitcherEditor.cs b/xiaofang/Assets/Obi/Editor/ObiStitcherEditor.cs new file mode 100644 index 00000000..0c4b395b --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/ObiStitcherEditor.cs @@ -0,0 +1,287 @@ +using UnityEditor; +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace Obi{ + + /** + * Custom inspector for ObiStitcher component. + */ + + [CustomEditor(typeof(ObiStitcher))] + public class ObiStitcherEditor : Editor + { + + ObiStitcher stitcher; + static public bool editing = false; + + static public Vector3 sewingToolHandle1 = Vector3.zero; + static public Vector3 sewingToolHandle2 = Vector3.one; + + static public bool[] selectionStatus = new bool[0]; + + public void OnEnable(){ + stitcher = (ObiStitcher)target; + + // initialize sewing tool to sensible values: + if (stitcher.Actor1 != null && stitcher.Actor2 != null){ + sewingToolHandle1 = stitcher.Actor1.transform.position; + sewingToolHandle2 = stitcher.Actor2.transform.position; + } + } + + public override void OnInspectorGUI() { + + serializedObject.UpdateIfRequiredOrScript(); + + EditorGUI.BeginChangeCheck(); + ObiActor actor1 = EditorGUILayout.ObjectField("First actor",stitcher.Actor1, typeof(ObiActor),true) as ObiActor; + if (EditorGUI.EndChangeCheck()){ + Undo.RecordObject(stitcher, "Set first actor"); + stitcher.Actor1 = actor1; + if (actor1 != null) + sewingToolHandle1 = actor1.transform.position; + PrefabUtility.RecordPrefabInstancePropertyModifications(stitcher); + } + + EditorGUI.BeginChangeCheck(); + ObiActor actor2 = EditorGUILayout.ObjectField("Second actor",stitcher.Actor2, typeof(ObiActor),true) as ObiActor; + if (EditorGUI.EndChangeCheck()){ + Undo.RecordObject(stitcher, "Set second actor"); + stitcher.Actor2 = actor2; + if (actor2 != null) + sewingToolHandle2 = actor2.transform.position; + PrefabUtility.RecordPrefabInstancePropertyModifications(stitcher); + } + + if (stitcher.Actor1 != null && stitcher.Actor2 != null && stitcher.Actor1.solver != stitcher.Actor2.solver){ + EditorGUILayout.HelpBox("Both actors must be managed by the same solver.",MessageType.Error); + } + + EditorGUILayout.HelpBox("Stitch count: " + stitcher.StitchCount,MessageType.None); + + // edit mode: + GUI.enabled = stitcher.Actor1 != null && stitcher.Actor2 != null; + editing = GUILayout.Toggle(editing,"Edit","LargeButton"); + + if (editing){ + + // Clear all stitches + if (GUILayout.Button("Clear all stitches")){ + if (EditorUtility.DisplayDialog("Clearing stitches","Are you sure you want to remove all stitches?","Ok","Cancel")){ + Undo.RecordObject(stitcher, "Clear all stitches"); + stitcher.Clear(); + PrefabUtility.RecordPrefabInstancePropertyModifications(stitcher); + } + } + + // Remove selected stitches + if (GUILayout.Button("Remove selected stitches")){ + + List removedStitches = new List(); + + for(int i = 0; i < selectionStatus.Length; ++i){ + if (selectionStatus[i]){ + removedStitches.Add(i); + selectionStatus[i] = false; + } + } + + if (removedStitches.Count > 0){ + + Undo.RecordObject(stitcher, "Remove stitches"); + + // Remove from last to first, to avoid throwing off subsequent indices: + foreach(int i in removedStitches.OrderByDescending(i => i)){ + stitcher.RemoveStitch(i); + } + PrefabUtility.RecordPrefabInstancePropertyModifications(stitcher); + } + } + + // Add stitch: + if (GUILayout.Button("Add Stitch")) + { + FindClosestParticles(out int particle1, out int particle2); + + if (particle1 >= 0 && particle2 >= 0) + { + Undo.RecordObject(stitcher, "Add stitch"); + stitcher.AddStitch(particle1, particle2); + PrefabUtility.RecordPrefabInstancePropertyModifications(stitcher); + } + } + } + GUI.enabled = true; + + // Apply changes to the serializedProperty + if (GUI.changed){ + + serializedObject.ApplyModifiedProperties(); + + //stitcher.PushDataToSolver(ParticleData.NONE); + + } + + } + + public void FindClosestParticles(out int particle1, out int particle2) + { + particle1 = -1; + particle2 = -1; + float minDistance = float.MaxValue; + + if (stitcher.Actor1 == null || stitcher.Actor2 == null) + return; + + var handle1 = HandleUtility.WorldToGUIPointWithDepth(sewingToolHandle1); + var handle2 = HandleUtility.WorldToGUIPointWithDepth(sewingToolHandle2); + + if (stitcher.Actor1 == stitcher.Actor2) + { + float minDistance2 = float.MaxValue; + for (int i = 0; i < stitcher.Actor1.activeParticleCount;++i) + { + Vector3 pos = stitcher.Actor1.GetParticlePosition(stitcher.Actor1.solverIndices[i]); + pos = HandleUtility.WorldToGUIPointWithDepth(pos); + + float distance1 = (pos - handle1).sqrMagnitude; + float distance2 = (pos - handle2).sqrMagnitude; + if (distance1 < minDistance){ + minDistance = distance1; + particle1 = i; + } + if (distance2 < minDistance2){ + minDistance2 = distance2; + particle2 = i; + } + } + }else{ + + // find closest particle to each end of the sewing tool: + for (int i = 0; i < stitcher.Actor1.activeParticleCount; ++i) + { + Vector3 pos = stitcher.Actor1.GetParticlePosition(stitcher.Actor1.solverIndices[i]); + pos = HandleUtility.WorldToGUIPointWithDepth(pos); + + float min = (pos - handle1).sqrMagnitude; + if (min < minDistance) + { + minDistance = min; + particle1 = i; + } + } + + minDistance = float.MaxValue; + for (int i = 0; i < stitcher.Actor2.activeParticleCount; ++i) + { + Vector3 pos = stitcher.Actor2.GetParticlePosition(stitcher.Actor2.solverIndices[i]); + pos = HandleUtility.WorldToGUIPointWithDepth(pos); + + float min = (pos - handle2).sqrMagnitude; + if (min < minDistance) + { + minDistance = min; + particle2 = i; + } + } + } + } + + public void DrawSewingTool() + { + + FindClosestParticles(out int particle1, out int particle2); + + if (particle1 >= 0 && particle2 >= 0) + { + sewingToolHandle1 = stitcher.Actor1.GetParticlePosition(stitcher.Actor1.solverIndices[particle1]); + sewingToolHandle2 = stitcher.Actor2.GetParticlePosition(stitcher.Actor2.solverIndices[particle2]); + + float radius1 = stitcher.Actor1.GetParticleMaxRadius(stitcher.Actor1.solverIndices[particle1]); + float radius2 = stitcher.Actor2.GetParticleMaxRadius(stitcher.Actor2.solverIndices[particle2]); + + Handles.color = Color.white; +#if (UNITY_2022_1_OR_NEWER) + sewingToolHandle1 = Handles.FreeMoveHandle(sewingToolHandle1, radius1 * 2, new Vector3(.5f,.5f,.5f),Handles.SphereHandleCap); + sewingToolHandle2 = Handles.FreeMoveHandle(sewingToolHandle2, radius2 * 2, new Vector3(.5f,.5f,.5f),Handles.SphereHandleCap); +#else + sewingToolHandle1 = Handles.FreeMoveHandle(sewingToolHandle1, Quaternion.identity, radius1 * 2, new Vector3(.5f, .5f, .5f), Handles.SphereHandleCap); + sewingToolHandle2 = Handles.FreeMoveHandle(sewingToolHandle2, Quaternion.identity, radius2 * 2, new Vector3(.5f, .5f, .5f), Handles.SphereHandleCap); +#endif + + Vector3 direction = Vector3.Normalize(sewingToolHandle2 - sewingToolHandle1); + Handles.color = Color.yellow; + ObiEditorUtils.DrawArrowHandle(sewingToolHandle1 + direction*(radius1 + 0.05f), sewingToolHandle2 - direction*(radius2+0.05f)); + } + } + + /** + * Draws selected stitches in the scene view and allows their selection. + */ + public void OnSceneGUI(){ + + Array.Resize(ref selectionStatus,stitcher.StitchCount); + + if (!editing) + return; + + DrawSewingTool(); + + if (stitcher.Actor1 != null && stitcher.Actor2 != null){ + + int controlID = GUIUtility.GetControlID("stitcher".GetHashCode(),FocusType.Passive); + float distanceToClosest = float.MaxValue; + int selectedIndex = -1; + int i = 0; + + foreach(ObiStitcher.Stitch stitch in stitcher.Stitches){ + + Vector3 pos1 = stitcher.Actor1.GetParticlePosition(stitcher.Actor1.solverIndices[stitch.particleIndex1]); + Vector3 pos2 = stitcher.Actor2.GetParticlePosition(stitcher.Actor2.solverIndices[stitch.particleIndex2]); + + switch (Event.current.GetTypeForControl(controlID)){ + case EventType.MouseDown: + + if (Event.current.button != 0) break; + + // If the user is pressing shift, accumulate selection. + if ((Event.current.modifiers & EventModifiers.Shift) == 0 && (Event.current.modifiers & EventModifiers.Alt) == 0){ + for(int j = 0; j < selectionStatus.Length; j++) + selectionStatus[j] = false; + } + + float distance = HandleUtility.DistanceToLine(pos1,pos2); + if (distance < 10 && distance < distanceToClosest){ + + distanceToClosest = distance; + selectedIndex = i; + + // Prevent deselection if we have selected a stitch: + GUIUtility.hotControl = controlID; + Event.current.Use(); + + } + break; + case EventType.Repaint: + Handles.color = selectionStatus[i]?Color.red:Color.cyan; + Handles.DrawDottedLine(pos1,pos2,2); + break; + } + ++i; + } + + if (selectedIndex >= 0){ + selectionStatus[selectedIndex] = !selectionStatus[selectedIndex]; + } + + } + + } + + } +} + diff --git a/xiaofang/Assets/Obi/Editor/ObiStitcherEditor.cs.meta b/xiaofang/Assets/Obi/Editor/ObiStitcherEditor.cs.meta new file mode 100644 index 00000000..b0c18e2e --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/ObiStitcherEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7d360f36068814e1a9e2835455e6be61 +timeCreated: 1489407253 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources.meta b/xiaofang/Assets/Obi/Editor/Resources.meta new file mode 100644 index 00000000..2f133580 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a89eef02b8abc42e2b56e6150832233d +folderAsset: yes +timeCreated: 1498032496 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/AddControlPoint.psd b/xiaofang/Assets/Obi/Editor/Resources/AddControlPoint.psd new file mode 100644 index 0000000000000000000000000000000000000000..d968222e829e6ce15316d04acb28ab08d1d9733f GIT binary patch literal 36186 zcmeHw30zah7WdqQB<#EU772nIs}c}Jb`%9cz_qp-k^qsAU=lX9b*-(Uu`ac4b+4^m zw6(3rjA`<2L=W4g+l+Jz9B+kP;Y*4U{G*CAp8mag8GJs2*ZOz z`G&)5pgn{Js3ck8X>kdL>>w85m7~$*hX(`{6&3jx_3>A#vIBzp_3MY#1PA+pgrB-Z zp%E4PDbxZ+iBV6SR4rD?@-;H0f{*ozGL;3I2rn<3k?AnhD=*)akwWcH>gX?4<^>ds z@&khW0|QK&A>jbPBs^9n6={^J45d;&kg0iUj#8sk=P2{}vFSp7_hgY+roe40h6{7%>a_Up0qBY-)}C z0+pOJx!dnGfJ<{R5)KtPk| zf4bDr%E`&5g1^*^^6~;+W`1f-d?8q-!O~xvQk_wfFAYeOs+9#Qu{6FAaA-1jgHa|Y zhbJo38j(UQO^h1|#qpQPB;kR=#v&8SVqvP>p>Nu&KGx{PkKq_5Urlp|HNWZZg>cP3*+j*i@A=OD2~NRHqG!;U~t&3WNFyg?_>QLFQ`AXDC&{VS_Iol$-dNZvS;-U++E>f_SHJ%t6pnR+f+2@<2 zAx6~1$TbQ>i5xQvWO9v6K~w_Yj!4HQj~UAB((R8`u>9cGRAYCu8mEw*s%qf3!IH80 z8ilbEP{~Y{DUz10PBukiRf^cAh(gm8Ny?O~O`KubnnF_~K2IKJiU5vHs$;~t*#;mO zlo0Hdh=tOSP0nc&K3}3N$c$3n#3dxhAeG_;T8#WfxfqosV}wGJAV`zrwly6watZ%s z^fa|xL+Gi+@~AYExP75i414)te=6+eHCRPzcB(k9-Kv*^ntbBBwLE!r6}rt(9Yj zN~BQ3MnNrcxN1EKO=EFa)%p5 zO6-e!4)jB&??H$~WUB~uFbc@Z0*)N+TtcA?l=UlCnkcxo6dDV6qYSPGg>b(#P>9Z2 zh$GzZ>6aet`Hf?3;1L zxUeT*AyHfS9I*zBjHxp2sHWZkM2p^pVw!p#AJ{0ZsZ-%NR}H(trRtILB-a2d$ zwr7Mf1#=Sfvib1%Z`Yp<+vl4Ndj$OElw@^w^P!O|l4~+V+0CS!#ZtLELt3m!R1eNb zPBJ=QTO+xduw9N)H91-?%QlXUE==VI8_7^}o2sFkck0F&@iO}V{NBV=EF;cT59fX?d9N>U!Xc>5;y(=-2s|C$5Nd1w(dA1 zcxwQ2j;thM#<#i7oo`7FX z5Nu22o+5SABd@-ZEk z+A}j3hgsOmc&ea)5N?aZ*-W@MkzvA7I4sFifPu4cne!!i5*$7Z;r9y*u;H_lAUvl~ zCM|;SuMqZ@7v#wxjJ>L7o>T;#(FSAYt&xgzARGu`M^#1|jM+8=5VCd5HVbE(g*9M- zAd6y^`6Z-H_}#@l`0#@uVf?|;BDqwf@k@o@IT5KO@GB&F`6303U`(BHD&+pc-cLei zZY?s+O*HRy@RBBj9o*( zW0M|vj`v5dzjz|{qf^Mn!vV3!tpN^YYPTf2kuak`XjGSbjNL;R_~hQ~###tbmRd%J z1r(c>!50^(3KBY4P|Ap-ehI7Cb1^7X0x=c<*W^?FIhWS2UsUr z7g#r0f3T|9i0!~`&F;$fV~4S0*(vO?>@2p5{SJE`dl`EJdnaPDxbxm<2*t}i!~JD59$JCQquJD>Y8cN=#<_bj)9TgBt?+VOhv zB6ul05l_RL!&|}olDCg{j(3MwYwKX!#WvVB!FH^z!gi+ZGTYB>_u8Jby=U8C=W5r@ zF5E7~PGVPLx6p2r-5$GN?C#h#*t^;L+DF)D*iW>dVZYpdtNjuCYxd6^92~qH`Z)}D zkU30uSnlw(!*PdlhdM`h$DWR{j^i8)9JP+0I_`J8;`q$T$;rnl%4w{V#!2h6#p#gK zb*EZq4`+YpL}!WfH0M>$JDkrsKX$Qm>E;sc@|MeFmt`*By8Pnu(ACb>$2HbfFg7KHGhx`yuxV54MNEBi2LgG0S6< z#}SV^o?K5~&qU9Oo~52&d7k#HY~|jnZ>y25id(H}^<%4>t=X-8S|_%aw_ezKd+Up> z>)Ui{6WvDIW^S9UZO*l+Y1^S~R9k7=d2P3~z0kJ49lu?CyWDn*+U;yt*50Ol&-TOH z7qws0{z&_W9Xvbq?;!3lufz5Zzjb7F?AbA`|>9)5FfK zJ4bb%*m-H^y`3L)@#r$Ji>%AiF8jLt&Tqw!=F9oZ`G@(HT|0Ii+_j+V`mU$DHhB4Z zjqsZ3wau$cU@r(0WC@lE4hky0yLcyiPxb!7`?qd(-NL%%bo;2=v2Ha!zCNRT-t*b% zbKkeEZ=&yH-!FWxb$99>*?m&?4c&k3!R-;&Be%!LJ$QIJN+LAcn6FPSQKz9Kpz+qC=c8e zcs0m9Xh_h^pglo<2KNjW2d@hLwU1Mugg(>y?CSHhZ?C@6zH9nk4)F*{4tX!+U`V4d zRHzbe6+Q^{4xJFXI`mSQXIN_3{IKKwIQ?S!P3!kVzq)W?xF&pi_>=yA{d4<&-v9mp z-vQDAn+8-wctwaJ)<@hN$R9Xi;JSe~BfCb5A~!_diV{RgqBcj}i|!FUG5X8s$1#C1 zs+jL%YGT7<-;UiM$Br8mH!tpVynFnJ_?7Y36TA|#6TV2O927EW%Aoy&IfI7|UNrbp zVy8rL;+Dk9A)!Ow9&&i7D~H}n>Y1cU+LO#m9+JEy`P#5lqD%; zslKU`QvWraJ3Mvxs^NFjg3_j@9ZUB}AD{ktdUZxj#=?xNBf5_$7;$i<%gAvfw~VYA z6*p?}sGFk$M!!A!@3@lRlhOsT!)An8%t$p9-ecAh`=k}SqVy=Fk zWZqAufu+kzb@RpZe_9Zncb6U+K8Tln^V!w0_41pAE}4ayJ%kyt`@SremLkeX?b9`^}}B8$VTidh@fi z&kk=1-LmELj-N05g7rng7Z1K1_vM+d;=bCo)o<(iZLPPJevQ5^`1<#6CVX>o`_SzN zzYY6#>v!G0Tm8Mq_w#m8J4$v`?#$VFbJv(%XLk?TeQ;0zJ>UP!|6iZ}(DjE^KeqaD z;a>Z_v-i^bChx1-pTGa%f$Ren2ge`0dT8{aUk?vIeEP`HBgc;>96fX_`q;kX5yyWx z5q@I#PhmgpJSjZ6<5bA0?|%;Y`TNtt(>s0%{bkpgerNWa9dLHhx=zYxBxn%a&d5czwf-9yhk#6yE%? zJg)rIt@K-0E5sFl+*aS#-I;yY>F%<7UG8nUAAJ9Z2MG_({Qk!8cmBx#qv7G4M{bW+ zKkokcyC+dkPF0Ssyz^A`l>T%6vv$uuect!^!K&1%>(zPH4K?#>+tq$n7gl$yepLOv zh9VtLx4f}O;~xD`{WUs|rpa8xle`V!mjPy`kKdq?>rlAi_X)n?n!rp)Tmw*BMA4V& zTaKgQM@`13rllk#CdDHPWdHG;1hTTuNsMz9>zu?oCxH&}HzyZ=GZ|!Pepu%u);WoF zPGX&tSmz|xIf->nVx5!x-Fe>a$uQG+jGRdfNv6Y_2}NH;vyr2%t*xD{ zqn(|jn}fZBTPqhwN0(M@Jv>@@c(iqMB!}U_L@e)=lY@hkvy-c{v#Y1Gv$H3@IeRim z++Ifky&t*R!qkY*ro0f#jbgh|bQyfJ$f6HZkx)tweB=p-;Z=%_D3%R}%d@q!cc3hp z@Xb5h$aF=N4aH{JusA%fEr;#c2bgYbo38Fboao^q53flxg1MfH)_)Tt@NSiMAhS zAa@%m!6YvaPVkIHp11@D(#}@)@y;w)&0HLt-b$?Q`?MPu7l7vza_}4!Vq+Ug{0N~& zddpOVSC_!IsR;CM$dOI*bVHG-s#o6Dm1TKb9mR3Gk4(5ywWeWf!JDD2E-hQ`W7lx= zn*}u5>0bYf^wRj!^Ao#muCWuGS`>Lj+}!S6w_c>F^r2P16$D;Wer2X8juYak|Sr%8f=t zj?(D-8*S_Q-u~6^ldH?8T^h0IjOyt=>AY|KCloex*nSKZD*8uk)s=nTc9Z7%&g!wh z{9YF`x_^>FK5gamZ*KDsT{>oW=GVC?9gp8y_<7`pE&JUf2icTwT_#w}uRNLf&Jy~} zxKOqxw_UsnI_jdw9sBbB8x~>c1L!V*aeiK^=Xwhx9oX943A6(fu7=1LNMF z>M>{KW$oZuha-kJ`s|FoU)*n(uYmuXTzJ{8b(pO)KgT{}a!KUqoG;ppo7(#RV@-~_ z!?r(H*KF!ue`v}0D-+l63cI&xW5T|nza5J>4RE*qCGkPu=f4ddJM>Y>s=NWaK3Uk# zr?b{J_RX9W@BQTqH$xpyQIX?2-V+ZEI_6%i-QMU+Utzwx>`J=B2;7Tt&v1d|9}-v) zl?jVN`0!;$4umyusYxgwBs~5?f{$WhDU}c_WODF=AfkeklTl9y*diX~PL>!!rvrL> zvh)jQok?{tg(p(o4Kgf{2_nk}_#mUAf=L*EIe(^Fa+_ucMmEw~l4XgTId56vl#Za4GmI1D+IKQ_)lx%B!g^ zR8RA|uqdMrDwx%zn<#@De20utVV?MNAeVIzL#Q@Sq>v@1CE&$T4>3Jj5r-E!oPx_0 zE}RAq!(t0uA{3pFZvGuON>C*#Ub-~Gn2P8CDY7i0kLRcHSPLk5`GN{#D)Mzzg1Xtt z3CLSzzB~#gs1sDiyz!z7qxPg&g;^PKz0#Cqxri;!8y^IN^(5FaFG~gAE0gv&tFy80 z?E>LD)WfviAOUs*-<{!$gV!rjMC?0mn7rj##jp;FMZQS~sTcDn*7AzAaL#!mwMME+7@b}u z(};77D?w14Dm|xpaWMtdlcio#g(%Y`nhXmGjVtzI?V}aLmzD})uombwN zfaT3hjoP1RO=pd{&bqa&{Fcnh9!ltwl8fzLxg)lww$czBcRJg*>bWlFj|ov z^_EEn#i=z4<9bBnLJ!Q1&CN5dQ*4q3&m}KVy-a?XQY~fZDzUkIv_cbYTvUiMREqTG zP^RbP$AUPvJ~S+k&o?Z$;h`iXgOz$xvSyFyi&Yi!4gHGMTt}=b6}LFiF<3QOftPZU zB!=5al}2n%`|H$E%9|zy#?)psC%LFZs)8@(#ZnQo78M}IeM=731O041B=g&&{a((rfg%~3%v^$kZzN#&SXfV<(;_W;DPw9TcpaKqw{4i#(@87{|X}aUHZ_>Sc&wDt=-r zep1b1MlP17hz!<%sb-onmhu7x#vYf;4pwN$;go^5SCf}0!x#YnQb`4T8+DE-pQI^~ zNpKvlu{bW4XJX5+!C>OJOp#S=;FEZ+A{UP#Sf1%u>in!`aj_ihx5a#XU>)k5Je-64)g_D(^z1O|G^XfmqJ()E<4hjGh}&E>?EQu)@})_JQ~U9R0OAj1TF{B znN_U9z8vdnb})4;By|SHOt^5L#}{6S3h#Zy9<>n0{Q>7XjQFczWDFmI(>IOF_Hn@X zgv+R-9faE%Y74D_b^Z0_m=55>s0<63@=HJg&ZAH*&W51IFh)0FVtm8FC41eGN@*RR z4O;}P<1@Az>-da4nRR@|zWCoApVfJIhKEO`zdt^+$=FCd80axSY)}+Lr^99Wv_boU zIvp;{XG_{%CXdtGyflv}!x+Yln;k*U5k54)drtBVVf37-N?;oAc#E8^uWq==_r{*lf%qN6q+b3!5r-@p| z3}%N(vOJlF>=heh5^HTHgmaD+<(n2Fkk-8PBwZ{{hhKEeb4wSCQBjPH@lJe4iP<|Se1;7laXP}TOHbGdyZw=cUZ2cAAgwCnd{g+>BGmg zez~mm#!mWCsX(??PHQLPixdU(;_!gk~zkbkaAZ0K{j8JD#|rvtd#Fc;tMm$7FI>~>W;F#oJdV@V?;7zq?$L;$v%}CWP3p|ybWU1|p|jT! zbdLbKN22O6@ZF2{-m9;_x3{Q!Ei7OM6J-6p^N#NCo&O+5?VZ1M{(~F^cmCE%aEgY>uGy}{`zFbEUNENT!&ieqZ~keHbG``3c;9@i zT%^W)JZRfuY7+c=T+pc-IbfK%L<10#`@)bf!Ign&km!M>yM(ct-=b6O4-O zP%8vqN*m7q-Sk~iSHy=4pIsni3^VlR@y;*syOz`Vtfn0r>uTy78fu?Cd|0iorE6(Q zS68EBKe_!>S5Mc|9{PHn?)lM=XBWRc@8iSIbh`5L8oiEgpj+wdbai`+-dXwGky9rR zez$I4jqd)1=lVukN4EjillLaCKXI$FwozA8dF#aXKXi9aKiBIqvtCy@_1!%cwGh#j zJ*V}x6$hW_&Yi8%(~UH(u)uJBxdSpUgPa5-6z)?fyb%S9eU@d+6IQzKyz#F z>-Oxg!kil2>XoWwQu|cLD|=q6 ztDA9&Ax%Bi2&5Hdjk>xi=Yhnn)y+MrD_fx}g3@H<>WT>O3B&tSx8`8&^D^C8;N@=9 zods2Ox~q(;N4i7ixmN4;EX28T9_pU0ZC1{DT`4Iir|PlpfO*~Ob=QkY-MEdnbv0jC zm?P4lTf7Jm0VtoA>mD3@Vh&}4?szeVvXSQLZr;;9I*prwUABU0h6Y`QW-V?8Xu_Hc zcXYL7cc2NMm*FO?2WHVC+=RICpZ|QeL05J6_ouaujdj&vK1Vf+PT|IHpl$Te&+WKg zqvPIKT)g%ywiaw*HRZcE?6~rzuI|Z|@8*^)+Ioj-r+#_!dQwZw)EcKqn*=4A^PE?vL-s=kgC=}-4Vtj#z#{GZT+)Qtj-NrU+J&1>+^%k@yu5R% zRy!+C`x9<_Y{$>eu6Vyj%bly%tUiOSh1l`Uo!S|5N*63BoinYVK)dsX(T*#x?%%xN z?V_T$7i`{t726}R;|JF-o;!E(`U49)E?YWE=@Kx=t^PR#cc z^am#CuSJ3Y>70LII~E8SfBd<>AcgVAykp+J6J|61SYY(W>wN?>4E{J>Ftm6#0bgMB z#}fr%dl-LwLC|aBdeUl`iS77uZ^7G)KQ0vvnnrvUW??&)36l3$WBV8(cw=P+_QwW} zev2S=re)OOyZAy1*)GLfwZEmR^Y?<+`a;t z!5<5#5pv>>Zwq=eyy1dz27fG|e!L0HaWlRrM1DiHLNZMposu3~pdpujsJZ?Ty_ zo)KCj;D(KB=8yMGA0F1LTen_eDLEyJ_n7OFrDN{cJ6*|K8V@(xC>_%HsrG ze`3vh6H_8WLZedDM;qvC105+m-EQM>l76&hzPMj!S00OP>)N^B+fV882uDhfnQQ3E zPo@v<#G~Lf)7ueIyiVhu(#HdB_3&W^FIr#!)yyb27JNoQQ@P%HWXE#LX`oBH!spYC zh(8przG3PM--NepR6NeJfx8G`mKU#P|uSs#OXOh$-PA~d-ffuIN(@P_G zPidaFqZ6&0-IF0L3t<5%*V~rXmHGpT`v<)~lp$%UP3Y(iP3ZQ14PCKbjhhgdlw-tEny&g%)Z3BAAHJ%R)}LLa7UITl zfN!2114{4I(A?YGwbDRrEns1kEkAMY!HTNJ#;S_L8yBb(yJ8EgMJ{ZYZc%S&-YqSC zSMx?xH*Ak!t}MIOUOoN&dwR9DW7UEM)51>uQ_?e1`U{0o=_x7cQ9>ca(+zQ;b_p9Y zGCnkP@aQ37LScM-sE~=rk0f!p+v89u#6hl6=t>x&jF=D$cVSe+9TZ1FCM0gi2xr%Y zFd#q}V-lJRg184R0aj(mX(*2Cg|H^}w15IY8EIL-Aw$gz2q-kKBF3G)}g zU`j}uyjg2uy9mW4Wa?tFMd%Oj1%DXvFEK zs|}LoIJG{SF=DZkN9(0Jh1Q_ZsQK8gq*h}zjEsuH1z8Vsy;NFjL27+GsbjoUqe^I& zXcGkSi3wKAkTDZ5$q?yii9w^Q(rA=fOwB9mH3p5oUZdrU#6td{GKo~7#*D$43C!*yBb6$lyYSN+@*5#C&5_=1PJPvMEuBzF>orE5l+JGi9Bkok4$88!jAFIkAW=){ z;=C+yCtjhDWh4sIpc|$RPfSe$QXoi6O3KMgEGS6J5u^%o1i2)#9J4yc1jzC`cN9~k&_h?9 zZiz;w?~|Am)6*QemS9yXNQ`PFIz5e%9~otV-hL!tEa5z)1v4a49Cuk#JT}m>%mfFn z%`N9_if$V1p6D{R?Xuq8ep5ZIb~Umvrij+vjp#LXh9-%Q&XGeL+W0e+5Z6gJT(0qPlDgq? z0>pLF4VPYwOhRX>M*GV^AuJLh_y5VvH z#C6gQmuq~Sq;9yJ0CAmk!{r(uC#f4QCqP^$-Eg_a$4Tmj%Lx$INjF@s@o|#6;c^1R zbastG4 z(hZkue4M0ixSRlSopi(H8XqUA8!jh6TqoUdxyHvy>W0e+5Z6gJT(0qPlDgq?0>pLF zC0stXjiO_Hu*s5W z6srw1tv0H#0Mqy`QtEIzfaDb`nz2T%!hrK&F=La~jghG6s{EQNU@?U;8DLLx;W;$2eAU6ZSpoCzrgb2JLo0=+}-GU0{ss&o>y9yT)4YUy-tj#67M;R~3E3?mvzaP>n~ z5cLwIMtX>K3D7jqQZ$`tc%dAm1b#h8_()*hb)G_G{ox9sVlt5wLNfbA5=DIMXSTwq zR1=;bN#Nb_%_QB+n(mL&?5ia0O|EdEh{v(G=RiMX`W{d$qT4~ZMJS=J4kSvrdJ+z0 z=B!@6!pgz5rO-sUT6AzdD1`f^nL}*;25E%*y{X%S{Sy{D5%GJ*v*O}6)w6yD}< zOC^#N#o)ogUSq#;XRRUHUW8*FVOZIa5l(Z9;kH7E{2~F-?TwRcTz{tKIEkQznG@64 zuJd8fFy+$`9N2!ooo{RxZ<%=wAs5w_g z*GY`zQQ+N3>kQqfS6kSQ>b|vdvIEc#+#tq&ZlP5GS1MoJUbLMGThoQ4EEmNr>z**R5 ztxP4u^nRe9Y&7D)XO{v!uTeoa0euYU7^P9A02+^}p(` z;fc-3M97OLx1($AXahtb=pvCuJDs!%e~@%AAASxbjbB7JDQSZtt^$7LM52?yZ;+_8 z5;Z)(m^$NJDEN+@pM=d^Tng>kK8Tr+*q|K=CLpGi*r;Vps17kBhzt~G`yxQdm zZGRl0p5NGbF{@yTI~SpCU)a?r9LI~@&!Z@4X*>qhdfZdNs(E+9uDp0$o^{tOKac6c zd>qwM*pzG3@nN1JrTKBrL44mC?cB2SV^}3!N8|Yn&98?~lCiEAK2*4{>;ljBj~7omuK=@8rK0QwvqLC4Xzs13EF z3+M{Ej&4#E#ijhH5ULjyK@FgWQZRj^vZ#Ejl&YjAP*W&5rKXJ3!_;Hc0%|F>f?7>& zpx&W&PI`+B`jzTru~|G;D61c9AS;2D#>!!pu&P)Ou;i?1tQoAitVOJ4 ztTn8+Sld{8S)a3xv)Wh}SRHJ{_GO2&BiV86G`5Ic&YsAwW9!(Dvgfl~*lXAu**n<> z*%G(a3-5OCn?6B4u|6Yxs(hyU%=TI4v(e{c zpHn_peSLkSeA9i$`YL>9`7ZN)+xHXSGrqs`f_X!DBHkpPk++Dqp0|hhHSemQpWi^g zY`=+q2ERpq8~i@<`_At-{}BIp|6+fc|4jdt{@eVI`d<$44j2%S6YyZbjDVJaEdgHy zTnzLM92h7HlmtE+xH51@;K{&_ppYOzPlu8TLU~TR1y> zV0dx3GJJ9P=I|5Yojv;X$mv1%c&f+79!GoJ=-H=dc2BzJ{GOY79`D)Ni{C51S3|F7 zdTsA@x;Llykltf^H}!tG_s6|2_6hAXqK~xC{63reeAAcJcSzsLz7O?%weO+69sTeZD1JVZ64|rj~ z!2vf0#ts}m@QH!j2mTb>GqyN(M(mrhrv~{A8Z~Izpf!Vz4fY(IHn?H%OM{OLVGT(c zQa@znkS~U^h6;x&hQ2hkb(qJn^kM2@YlfYSW@S(%$;V%#W zDkUVPEai!meJNeSRH06|QFuNzCUr{ci>W8mLenbJ7N&iY?vb9GJ~Mq+`tKRS3`54| zjDL-Y8__W0jS)X(#%9u)YctP|j2bB!xq4(<7C&oB)~c+wQIVr0qt=Z2K07*Fmc1_f zT+ZN}sX1@uT+U6*)#Yx@y&=jFJtEqZ$IdIvo1b?$KRAC}{)+tX3Ze?+1#cEyDNHGR zsBlk_M^Q=9Geswh`xQ%zHxyqPojUrF(fdnyCE}75CEu40Db+t*ov_$$NpF;sC>Bcpg2T4S^S3hdR1=K;;L`Q4H{=0 zx34;&dQ$a<>Ko(p#xEV;R+CWkNX_RHdQVVHcyA(iV)evz6FdHv|F`G=);=j^(!5D0 z9*BLQ`GHR#?ERqf!4D<}OqNXEGR0%c_$hBpxg{x=tdVro7T3O5dqpaez979I%a%PS zJ5P_Km(u6zM%FE@`$;}h{;d3b{iynu`ilyYVuj+DsYO#?nR=t4ykUKVNjYA*N#&)Q zqS~PjRyU~kYx--NHLcpA+IiZxX&KX=pLRu8qFbk@^bhFYGlarq>X31e@p0ps#;nGb zjlVTjH*IMSYF0NNnm%OuQ`67QD46luL!5`C5AAz6^5NMJpLrzbk=2hLn+h8THKT zOM{lqSbFx^vS+tF$A51AbJw1q{QRda!&_c?!RH0z3vJ6vm%X< z<)#<=zWCIOH(rvxboAxymp8uB@0A6wbgojY`f7FI>TPQVu4#GI^VP;ze_UI=_TX!2 zuWeY@d)SF4??qOWKx=?+$qP#jPP*=WnC7P2YB9d;Rvd_a?m8x?}W?eLF|& z-1>g}`|Ec_?ppal*awS0^!ae^ho;>#c6aR2?zy;EzW40D$@{+jsOF<%`^WA-{Bg<0 zpByMS@X^7XgS$T&`N^(NGd|t%S=wjYKNo(!?NG|0t^Y{*$JWEb!`r?{{o=hN=|^_9 zX10EKbkxzkU*>&z;8^jo&ySBe-g;u(iLXvhI@$J>?5m%?R(}19qc{TJOYre7Cc?R9niwc*$HbyReG zcU^V;=8gHk_4@7g-_w3S*g3xQ+|8z2+*`}K26yeeU2^-BNo6vTca2ao8^Du+i6o6@ z&?pf94+)-6@XhBG=5-|C66%R4(^sbNc{T8pCX*{F%L|H2^AY^V!N31b0!6vsNi6Rw z?spRRI|+1%`+T{$&umbj{o#Hmaleze-$~r>B<^<-_dALEoy7f4^55}JV!DKQz*KB@lVBWJ;viyCo z8iYNLj{Bbeb<5n3zBHb_S`ho(+Q;90e*du_uD!PPYTGnklaN@`7sfFX^ zO;5bAe*3|b=WYZc77M)P5TCf79x23yNI@_MJeU?0;*m7_nNaM(-pbZ1$uYHObaR%9 z#9>nX@LvXaVh6YbQ}!JNCtmF#%O58+(BE5KxVs0jHWy6aARe2P8H7fmj&bE1Is(4_ z?b7>ScBEz|D=+?0j-Og(s%EAXU4&r1BVZ&hHt&3 zf3Sba9v0HiOgY@uE?)8D>O~<7>!Mqtb549aX?tAevvXf#O$*s@e$4uk3&VaEP8h## z>LXLqo;nq|fA(9cH>#KZkP&Z8>y`R|R=-l(`@lR@`tFWzF2{AX?|%Hm+gH`sh6bpX zOk(c|<{o`|qi)is6yB1#v|!lg-ix+vl()Q`et7Kcp0kf!TW>mYEo;lsi$4$BboA}& z&Zp+IO^R&IVEyxS&4klEVp-1^PbMAMv3K@c3dK_2^{37~`tyYoGbiqQKb1E=Z^qNj z&Hjlzt}u0`qUy&THL|(wJ-z8AM>@8hj63v2-!r{R7iRyQAwFcd{mQe)bjo!rdx@t? zA1wK1Qt>pX@;|zc?>M^Cvmm_wvz^x`Y+WRsc%Y>#Zr5c!;5Pf{7VYMQ_Xi0+e6{z1 zt&2`yD|u;D{_b7dj3FR}u9<8{pIvN(&kx_t4-Y5iEleVuMTxQ9vRpsjLhQ0m2J$ zsbI1^2)YdLdy{2bxaeA{kCmQE4KnMnKu18n{O5y?j!Ggl{=bc-PbkQj{y6XJa2`WG zw`L&(Yd*~Pd;H8kg5S;;;vc(DO6FUB^&ZS1_A1Ke-zt{14E`#%jmC;_cvA311l%dS zBEnV|D#}(DYKVPZSd_&EmBg~yCdS|b-vDD&m^=Pon}Ai2Lg+V@M6D>UEWit!E@FO; zIu9>VI0R=PoH!30=A{zYBa~Ahw*Lkj73hl9-7ajfm4mqS=` zkuRGH^bYGDplqG}(k4`(FVI=a#!DtF)=NcdJ0EeqDm7%WhZimz9|VKdgzT%T)4{jG zr2XycY^l319~Sz&OV$T0rxF`eO}Byb87@H$e+$5b(jduQ z1s5D$jy4#71~KcFuszo&S6naA(tH87E!K!MU=Md4JFm?xMKFgIiF}8pCU;pxH?wUP z7{P~i5uIfB~+(BHw`n>(25?q}*ig?5-nOSskN$>!2&?bO1oU8x(xeOrZiwI@H)&tQtMd%75|)q z_3dgMI(uWERfJ`$_27BG`b}YY6!nk_CM^YI*j9 zRvnb5H>fS^2rWxAuvFBbvaT<*X~U?cH0rw3AEVLJ3|}X;*UwQKax9AhQI$?Dc7#$~ zuN8qhjC!yjMaAcv7s_x^DN?`+JDRMuBlbkPM!vaEu^erPbQQS8iH#!N3^iVYNwSzP z)jEUJo_Fuu*_t-10ZVQ>o}W@Ooz}ru>QY+5tRV%6N&G?dz~HnHGIMcSs#1$Fjg6UA zWO^Aa`#{NXvMgO0H8XNpjl0w%hIfQ9rZOt|6t&xtsc@N{y$FA7*%8ie&(z43xODtr zvXzdm-ozg!8~jNaHG*9BJOz_$=)H15745Ut(v3>UGKOTcRM89rE(RlnD`{CL2zpj$ zS-W==beI){_7a>6{%iss8KdAND;)87hR`Re_yg8}ZK0V;HLCOt&;m<9Kt=%k^t#Kz zjC|b-dEgTGf5$3nA-c(A|{`#S|I3mA^`osnRDEU~{c)-cEUWF*e|I8BjK zF@;OFzcUhS$=)xVrn;?*O@j6L=6serV+~83Pex+Vv%fQa#;C?^iJw7Sm`LF@v|2J5 zGq0nCKdYnz8AlI~7}Ce4D`YqgCt1-cRo3Dt;3O+_rAEEwnKB%Bw&#i${v%KL&kA8pIK9cpP^D1Oc)-ay z;itJYe#+y-54}360yMB6#AaQyP75@)|F`sLuo42Ub*RGogvHY}| zXllJ*qRVvt7W?!ylZg<^Pn(IR)_V}t>E)eG;7e6QXA_&rMqNAI*$S+NO`Wa8B=Pb7 zUAtz2Lb{qLrj}s6tCdvUf(5=q5sRo(S4r&`Q7xy;g#O6=5&**@_Nl9+_KVmpr_6-@ z$UO+^R7do1xtEW1T089S&&LhMmarXXQ13XT(bm`5t1nXT#NY$P2h_=K> zv>CaZ(UiFn?t=h4qAl?eZEk4bnB(K_1QQ?8)HtP6d_+@9yZE>dj{rqWE*J5E&XCVF zc=l2;yz7V%4KZe7apL_FUGP9=$H3@Fh=v$5u{iM_1QpZJxfp!eva)kAo5@D;VmcFn zwX&)+k(eYt-oIN=N`*A&bqNEBAeB)QV&w?NG+e=OHWWhA=7Ml> z5kvq45lkp>R0Q=9>;X1qE~x~kZwtMcqTm{A@rCiNctTBK>MbF+u%=KbOf9T23E8;V zE@2q1YDFgYgH+e-nWOwpC?d=iOvC1dPEY_S)y@u%F0pqIP;jgwE+Nwq3rCQ;!6L#A zWh)j?G{FLDncv$|TYG0yQwbJbLX_%fu9vyaT|z%cFib*UU|1X8EVqGSjsq*^cYwio zNSfTCwQyXdVh@=*+BLk{72MucInY83N|p%0MKdjB4U7njDGUZw9-Afwn$smzP2o); z3y`=i3@T(I7DVP|n}D0&q2ZYz=n{G`P?&@vP&mpeOIVmY L{GGkP(j)#0KCFvy literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/AddIcon.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/AddIcon.psd.meta new file mode 100644 index 00000000..4ac9b4ed --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/AddIcon.psd.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: d11f3f1468cd5453d961042f3ae9799d +timeCreated: 1440144040 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/AddTetherButton.psd b/xiaofang/Assets/Obi/Editor/Resources/AddTetherButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..f0f2cd2aa73471ad07a03181bc42ea1cb25b5d92 GIT binary patch literal 29202 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/AddTetherButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/AddTetherButton.psd.meta new file mode 100644 index 00000000..9cf24278 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/AddTetherButton.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: c8a8952cc5f5744e88c765ee83f6a865 +timeCreated: 1478799531 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/BackfacesButton.psd b/xiaofang/Assets/Obi/Editor/Resources/BackfacesButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..325bbf2ec2fa184c21921652017d192a09a89f22 GIT binary patch literal 32976 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 M2mGU>z%U~I2cIOKy#N3J literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/BrushIcon.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/BrushIcon.psd.meta new file mode 100644 index 00000000..aa215c88 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/BrushIcon.psd.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 652e8f881c4764ec9a7705aac5ed0e84 +timeCreated: 1442227627 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/ClearButton.psd b/xiaofang/Assets/Obi/Editor/Resources/ClearButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..fca2599fc7656b0c74d008a353e2ebd66e5fdee9 GIT binary patch literal 28652 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 X1JE6z`O}@i&@A*F{>ffo=n?+~Q-8~d literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/ClearButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/ClearButton.psd.meta new file mode 100644 index 00000000..ec97fbfb --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/ClearButton.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: e6e3e5775eebd49e6aee6abb8470baa9 +timeCreated: 1478799645 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/ClearTethersButton.psd b/xiaofang/Assets/Obi/Editor/Resources/ClearTethersButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..12467dd84a243210c1610a07b6141e7b7e183dfb GIT binary patch literal 31210 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/ClearTethersButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/ClearTethersButton.psd.meta new file mode 100644 index 00000000..b06e21fb --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/ClearTethersButton.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 0458bb2ee7da84bf6b990ed5679e8e22 +timeCreated: 1478799645 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.mat b/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.mat new file mode 100644 index 00000000..a3f31843 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.mat @@ -0,0 +1,87 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: DistanceFieldPreview + m_Shader: {fileID: 4800000, guid: f667dd333ac88440587339a2a1ac0027, type: 3} + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Volume: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _Absorption: 2 + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _Glossiness: 0.5 + - _MaxSteps: 300 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SrcBlend: 1 + - _StepSize: 0.01 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _AABBMax: {r: 0.4081963, g: 0.4081963, b: 0.4081963, a: 0} + - _AABBMin: {r: -0.4081963, g: -0.4081963, b: -0.4081963, a: 0} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _InsideColor: {r: 1, g: 1, b: 1, a: 1} + - _OutsideColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.mat.meta b/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.mat.meta new file mode 100644 index 00000000..0e5f4b00 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5dde1f45f471c48a1a13fc4b8c0b5b43 +timeCreated: 1438180916 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.shader b/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.shader new file mode 100644 index 00000000..5b6de21f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.shader @@ -0,0 +1,121 @@ +// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' + +// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject' + + +Shader "Obi/Distance Field Preview" { + Properties { + _Volume ("Texture", 3D) = "" {} + _AABBMin("AABB Min",Vector) = (-0.5,-0.5,-0.5) + _AABBMax("AABB Max",Vector) = (0.5,0.5,0.5) + _InsideColor("Inside color",Color) = (1,1,1,1) + _OutsideColor("Outside color",Color) = (0,0,0,1) + _Absorption("Absorption",Float) = 1.5 + _StepSize("Step size",Float) = 0.01 + _MaxSteps("Max steps",Int) = 300 + } + SubShader { + Pass { + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma exclude_renderers flash gles + + #include "UnityCG.cginc" + + struct vs_input { + float4 vertex : POSITION; + }; + + struct ps_input { + float4 pos : SV_POSITION; + float3 eyeOrigin : TEXCOORD0; + float3 eyeDir : TEXCOORD1; + }; + + + ps_input vert (vs_input v) + { + ps_input o; + o.pos = UnityObjectToClipPos (v.vertex); + + o.eyeOrigin = mul((float3x3)unity_WorldToObject, _WorldSpaceCameraPos); // object space eye origin + o.eyeDir = -ObjSpaceViewDir(v.vertex); // object space eye direction + return o; + } + + sampler3D _Volume; + float3 _AABBMin; + float3 _AABBMax; + float _Absorption; + float _StepSize; + int _MaxSteps; + half4 _InsideColor; + half4 _OutsideColor; + + bool IntersectBox(float3 rayOrigin, float3 rayDir, float3 aabbMin, float3 aabbMax, out float t0, out float t1) + { + float3 invR = 1.0 / rayDir; + float3 tbot = invR * (aabbMin-rayOrigin); + float3 ttop = invR * (aabbMax-rayOrigin); + float3 tmin = min(ttop, tbot); + float3 tmax = max(ttop, tbot); + float2 t = max(tmin.xx, tmin.yz); + t0 = max(t.x, t.y); + t = min(tmax.xx, tmax.yz); + t1 = min(t.x, t.y); + return t0 <= t1; + } + + + float4 frag (ps_input input) : COLOR + { + float4 dst = float4(0.0, 0.0, 0.0, 0.0); + + // Calculate ray direction + float3 eyeDirection = normalize(input.eyeDir); + + //Calculate intersection with bounding box: + float tnear, tfar; + if (IntersectBox(input.eyeOrigin,eyeDirection,_AABBMin,_AABBMax,tnear,tfar)){ + if (tnear < 0.0) tnear = 0.0; + + //Calculate ray start and stop positions: + float3 rayStart = input.eyeOrigin + eyeDirection * tnear; + float3 rayStop = input.eyeOrigin + eyeDirection * tfar; + + // Transform from object space bounds to texture coordinate space: + float3 aabbSize = _AABBMax-_AABBMin; + rayStart = (rayStart-_AABBMin) / aabbSize; + rayStop = (rayStop-_AABBMin) / aabbSize; + + // Raytrace: + float3 pos = rayStart; + float3 step = normalize(rayStop-rayStart) * _StepSize; + float travel = distance(rayStop,rayStart); + + for (int i=0; i < _MaxSteps && travel > 0.0; ++i, pos += step, travel -= _StepSize) { + + float value = tex3Dlod(_Volume, float4(pos,0)).a; + float4 color; + if (value > 0.5){ //outside the surface. + color = _OutsideColor * (1 - value) * 2; + }else{ //inside the surface. + color = _InsideColor * value * 2; + } + dst += color * _StepSize * _Absorption; + + } + } + + return dst; + } + + ENDCG + + } + } + + Fallback "VertexLit" +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.shader.meta b/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.shader.meta new file mode 100644 index 00000000..84621625 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f667dd333ac88440587339a2a1ac0027 +timeCreated: 1438180827 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/EditCurves.psd b/xiaofang/Assets/Obi/Editor/Resources/EditCurves.psd new file mode 100644 index 0000000000000000000000000000000000000000..2a82cde45909f6c82f0c27a0b390280b6828192d GIT binary patch literal 36662 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 Vbp-S0DuLN7Ocnm#T41gb{|7Wzm1+tV` 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 Q0#mmzCj7HmV9JR90l>; map it to <0,1> + #if SHADER_API_OPENGL || SHADER_API_GLCORE || SHADER_API_GLES || SHADER_API_GLES3 + fo.depth = 0.5*fo.depth + 0.5; + #endif + + return fo; + } + + ENDCG + + } + + } +FallBack "Diffuse" +} + diff --git a/xiaofang/Assets/Obi/Editor/Resources/EditorParticleShader.shader.meta b/xiaofang/Assets/Obi/Editor/Resources/EditorParticleShader.shader.meta new file mode 100644 index 00000000..7e76c5af --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/EditorParticleShader.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f909e74f185674832ad45806b9c6e60f +timeCreated: 1438934781 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/FillButton.psd b/xiaofang/Assets/Obi/Editor/Resources/FillButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..ee57c7baf74253ddf31f365e4dff197418854309 GIT binary patch literal 32399 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/FillButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/FillButton.psd.meta new file mode 100644 index 00000000..70102da7 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/FillButton.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 5aa30f0cf5bab4c7dab839a28bd5a3b8 +timeCreated: 1478802054 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/FrontfacesButton.psd b/xiaofang/Assets/Obi/Editor/Resources/FrontfacesButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..39119469836c66dfa31a256e0a5cd3e9a0653a79 GIT binary patch literal 31893 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%0D!^kB?ug+; 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/FrontfacesButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/FrontfacesButton.psd.meta new file mode 100644 index 00000000..188af017 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/FrontfacesButton.psd.meta @@ -0,0 +1,95 @@ +fileFormatVersion: 2 +guid: 5f827adfcd494429faa0357b10a2b866 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/GaussianButton.psd b/xiaofang/Assets/Obi/Editor/Resources/GaussianButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..42afd42591cd5e9b4aede7cc7e1a30c78ab05129 GIT binary patch literal 30004 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
PB`nMh{>fHgX%YVe#qC3=

literal 0
HcmV?d00001

diff --git a/xiaofang/Assets/Obi/Editor/Resources/GaussianButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/GaussianButton.psd.meta
new file mode 100644
index 00000000..8d580bc4
--- /dev/null
+++ b/xiaofang/Assets/Obi/Editor/Resources/GaussianButton.psd.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: 23303a76d97ac4435b47284e747a1e8f
+timeCreated: 1442227197
+licenseType: Store
+TextureImporter:
+  fileIDToRecycleName: {}
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 1
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 0
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  cubemapConvolution: 0
+  cubemapConvolutionSteps: 8
+  cubemapConvolutionExponent: 1.5
+  seamlessCubemap: 0
+  textureFormat: -1
+  maxTextureSize: 2048
+  textureSettings:
+    filterMode: -1
+    aniso: 1
+    mipBias: -1
+    wrapMode: 1
+  nPOTScale: 0
+  lightmap: 0
+  rGBM: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 2
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/xiaofang/Assets/Obi/Editor/Resources/HandleButton.psd b/xiaofang/Assets/Obi/Editor/Resources/HandleButton.psd
new file mode 100644
index 0000000000000000000000000000000000000000..3b65a0f9b5183d1060e3c013e3a7748d6e126088
GIT binary patch
literal 33182
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
Z5^x`Y?g;MBb^?=I7(4u{y};BX{s-Z&NF@LO

literal 0
HcmV?d00001

diff --git a/xiaofang/Assets/Obi/Editor/Resources/HandleButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/HandleButton.psd.meta
new file mode 100644
index 00000000..a6a59584
--- /dev/null
+++ b/xiaofang/Assets/Obi/Editor/Resources/HandleButton.psd.meta
@@ -0,0 +1,59 @@
+fileFormatVersion: 2
+guid: 25ef265869b174c41bd35bcb371e0fa9
+timeCreated: 1478802054
+licenseType: Store
+TextureImporter:
+  fileIDToRecycleName: {}
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 1
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: 0.25
+    normalMapFilter: 0
+  isReadable: 0
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  cubemapConvolution: 0
+  cubemapConvolutionSteps: 7
+  cubemapConvolutionExponent: 1.5
+  seamlessCubemap: 0
+  textureFormat: -1
+  maxTextureSize: 2048
+  textureSettings:
+    filterMode: -1
+    aniso: 1
+    mipBias: -1
+    wrapMode: 1
+  nPOTScale: 0
+  lightmap: 0
+  rGBM: 0
+  compressionQuality: 50
+  allowsAlphaSplitting: 0
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: 0.5, y: 0.5}
+  spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  spriteTessellationDetail: -1
+  textureType: 2
+  buildTargetSettings: []
+  spriteSheet:
+    serializedVersion: 2
+    sprites: []
+    outline: []
+  spritePackingTag: 
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons.meta
new file mode 100644
index 00000000..3382ebe4
--- /dev/null
+++ b/xiaofang/Assets/Obi/Editor/Resources/Icons.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 292753011b5614e38934aacb2697fd86
+folderAsset: yes
+timeCreated: 1482921919
+licenseType: Store
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiActorBlueprint Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiActorBlueprint Icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..850ee5f48f40ba71aa222d1dbff9a19d1f4a6bca
GIT binary patch
literal 4918
zcmZuzX*3jm)c(zkZOAs35!si7l%gzIA{kjDjF4qQwurID7|9Y@%DxjNLMqExh9RkgiGk!S>R9_D3g|FgY>AZ
z$eCPmg5%Ao$otVImhyl3#|kTh0w}Ai2R{$$7c&
zLM$>s;*CJN^u2a=(9Q+QjlVpk2Z;c<`Uk2Dfnr9m@=sfZ8VnaDj3L4Bn{!2UAO-@`
z#I;1AYIVTIB*aJxN@@nVC2B&_RHQNp-n{CH78FmU20pRqcxE*lfKOAG>H-4tP@uub
z)(sQTh2>rzXq+mt_6Q@OAb>

Q2!axXMmQ>f`p^Seu#=oN0Fbq;8A6z~TU(6Ut1< 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiAerodynamicConstraints Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiAerodynamicConstraints Icon.png.meta new file mode 100644 index 00000000..fa9e5e66 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiAerodynamicConstraints Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 8626b43f419d1466a9dc1c1509308b13 +timeCreated: 1448330601 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendConstraints Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendConstraints Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a07cacc4af15994c4d09d11f0f4068743066b640 GIT binary patch literal 4561 zcmai0c{mi_*S|CNec#EhvhS5Wl2L>ygJetD8QDjSkw|vgcOgrLC`GbNc8zTm31#fb zGGyO>zTfxx{qz3uzJHwax%YgY^W1aq^W4ul&rNR`FwpYS0st5cVb|bii228;DbIYn zmIM9_XuM%oz5vj%{bLZ2oy!dXt+A_~o~fw|(huqDg7g+L)YB94_CY$idOQRmXgu$B zpk>M~r`FW&Lnego*m`Y-M>r4>#Zvb$TNN?C01i)?S#>%iqiGTB94xso^NuGYw6MJB znZgSV&R1ii@5Y+nySyeiS@u3On6$cj`2DbHF?aE305!;jVPTa>UMO+{SKyHvYGZ~7)WIz;Q zU8I8~!9kDgogQ}3!wqU~zk5InQUUNlh3JZa*9>4~%TS8~j8&vea)GfT{t9Xk4*^*h z48)*1pMbr2I9wWvYXgN?9T8b_Tr~t^^+C}9ifN_*0ST5#Ogi=elcg)&2ZSy|f!;Z` zelj5=vO@XcR$_&ncVq($0&w`W{*0T$O6(13L%e~1*NHR2Gi@HVx(-|ynVo3nL~=87 zMA=}AWJUw@0PyY;KA&9HPFh@;n_h5Q^dN0@7M-}SBSo}?H>OUS;-KV!`PLw5+-`n; zl+3#uQsdw1USSQ!5x`|?-$rSIrtmK9Q1E^%>hh7!x%`)=JsJZ1v~+Z<;`d)R%g@GY zohnTuiLvONGxlU6cpW^-*2${E6-OLDa_|bMh9@lI$#oUHb{9oYx+BAm6D|^Flxy!v zbHr>|K5sA;G44ivgePAU?oFFvT?$j&5KKR&NeN^C*eDa+tq)Z1@g6wz8Uz~4XgM4J zbkLhJalCZNfZ17D5w#0IO6z{2juZs+XOzqW(Da-8UU@2)Q5Q7;*9yZWYpzn!e`d$x z7;`@hG~u|Q4wTn)=*4gv%(|3w7=GH9-04?&?%>qM$luqH@fNaVPczqjR=CWtNMyYi zzU<9KY0sVC#@!S}Lw>b~n$1C2Et=(i!kEYaHCI*wxrhTy`30s#XepZAOr*2NrvzG| z>y~T-6a6dW!+s_Hp3XtiM30bS%u!5}fkJBdTQjn6P=B3|<$}C1U4^~`KV>ExOnQ+! zfw%6QCgwv?8R6z{e?Jf!li-LUC@?z3{cyM!_e|gZxh1beH>cygr3xZZ#ZkcWQUC`Z zF5iJfEe4Inu&q$rK4ot6c#@Q4U}NJ_a$op>sX03;d8?I;(iytLCSWopw@b8!nO$>@B$ksr zdwfuXdibsaBU7cNbUF4Sh8fkt;oYT)3${2S4 zO|`VR6tNXZ&k)5B(G9zQfybTaF;5wHJ&#wR!*^ z2v0N}G_xyiu{(Zp;K=YcD)M?^6s-7;V|^D-yf9~%;=>I~-BBL|*|M~Irty92xBDwb z0ThRP0dkLxZtMBJcEUO(JLN4r>W46P)e_gQ{K&mAAUwb@@K}aSMq8$K)UC>?3SD(+ zJb1ii{Qj!XD(C9*ILY5TPbW`0Z(Ge%ZP%ZsQMJ*mF|u*OfAEjiSI1@463zCPZN{aa z1cPnQt>SI2KcrC-LGY5iGPP$KURmt__6sr_<#uc$dcH4wqtrVe$C} ziM40WvnoMcT25Fb|9!0TuZNTF8V>he6(>qMN;>CSF7~IoXFD|#>c0B*_4P`>LwQwBRYyRM=M?)4d*a36i`%!o#uZkMR%lnUS14Dn>^SU*?|AME z3iR=_3XH1zsfYOZ`S%5QcsDJVOe?onbX2r2Svd1Kzx2)9RN*SUnS^J}2*}{N?O7I6 z=2Z}kPn+jmYaD+6b-Os{Q_f`756^Eu`!qX4D-VrjbNG5~+BHd6x7K$pXCC#<=9T4? zwQVLX%Gn0kTG<{ppEG%vE0I4c@7XiaVNGntKekuX(tLO@utcWSr3EbrE_l{b+9EQg z*&>P_MQ5R@j`9!H5Aer{d#%%`znmMlDC{AhA@h*taNh8DWbR~w&p1cFyY1xjA7Yu_ErH`h?pDp8#j9 zn+M#(aV4h#)9|_>Jm}e;{ze9?ADbA>>hrmdu@24Wv%b(pk8Gvfx$HaXevZ}ilSLo7 z7M2F^`GFc%DppA$mm@P-Gu~>?M+oVf%5j^_mw6cru>F0S6KSH~QWRfgR$Je2L*vCl z9wKe$@=x_py#tphlk5InN;D>LDO57gi;tq4#)xa9zp#Tp9{rHHlA4>ETMTD#O|O&s zE?n-8s>H-^~dQk4PgzaUHzcl#$a&u3Rd}n%g?40oDw= z`%P)e>EzG8DBTmzkmjTs(}tRNV+}!88$^*-{ZE{tvA4MbWfg4TjSqrc*M~##F8H_U z$EGuuaPz-zsL8(x@QC48uk@szSSY7er1s*ys<-ZbbmVYIdtgp-%NVgngh_Ix*~?izC~BRdifF<{V?UU{OQ(0m4+tkZ2 zl+>_Vt3Otz*t1acWi#n_TydU&t$;yG{VAHHFze{wt&(VwUzm46b7Oz*Ny=>5gR=a* zTiTl6vL;cxMn_rhHfA=>&U%CS+FX8XM)h{Py_>%l6K&R;ythPl?@x%=->lNC)-*tS zA5X*HSR<8Pem`IE?&+<=FPrp8!9yaJR z7!kcL8lRXaD9Fda+x+*zK+1I4+cLJnFKEOmYT37Paq4*H@aCZ9(bziOe(YdtHL7CM zhg4bdMy*@4Td-*WrMXdhR5dUWN@^fAPIWg6W?eYaIWgTN95{BD4Vmm}Ery&N$?ZPf zJQN=;P&%77g&bjUV*rB1&!*4_0QOJMa0vi^c>w;{1E7`(02lIwUFUTGC{GNpUA+@D zzLIC`!C}tc9VRg0TpLnRp`y^0jkuS@{@`mSv5ojdNGh5I5dhh%EfRj&)8=O$&LAei z%fT8)$Lv7$)VP?AMxo2ic9{FswW0X;X8Rrl5&uVnHxJesvX(w6`I7QBZ~iI@J%fR~ z(<{3Jea(S)7Zw&wzuYV_E`*xi0Wq{XW{?Y#K%b(p9I$g>ivCydDXel(`-EWerfh%j zKJg(@-(F>1xyI<%C(0xG5T+1FF2qYh<*3{Fra55zN=FZ|4o}D&)R1_CCi)XOz3Io8 zj9j>g=T~uB_WWZ31rbxxjQax((SqN68xMW41ORlE0MWD%LwUY$h+?0rUVwp)u1>on~Vp#Z%luxY| zVu!3i#(lQFOK6=HQ$y~Xd>;8B8p)ya*+b~3{yA&Ef7e*43M2=v$qdC4S_u~NAgP3U zS{=)~@Tq^^0C+c-w3vgoS1%3_5bBYCeX;m<6_k14{=)ivf88De!rsR~41%B&pCdUi zWGiG&zFU`Kv!q{_g(t{E`1=S`!o(t4oJ^E2Z<+;x=jts*G7rj9#VrMKtx|Ka7C^Ba z-b?Rc60=%}pp6WYv!}Oo|EOLb(_cHpEA=hsDqE&MnkrjEJ(Gj)n7r}2{M@JTdWD+L@#0$Fo{12&)mJG z?6BJrDydgbixb%CdJy)m-gDMViRv~*kH=-a#a+7jw_`3HI@IPuv>Jy~@9o3H zN@?pNO({hBPkb!GVeeWe&4q?n5ajzM zF$aqSd_6RglHMO+`Z2tMYq7zKLXJ$)!s>-?k zitcwhnW>?vPXRzv++EwBROy|x!%WE^9)4paMr7t`3wHN$u9a@6)?AuX`byJS!Z9~);zU$mM1H>L@#xy6a1sWIc@r)dK1K4iv43pD z!Tm8%x-bGa7lC8KT$0Y+t?wbOUL+b49s1z4cOUNay(4@xC&uvC^rq^@f0A8ykfG$F z3a_Rknq0AbF86^QHp%nZ4xYRvZ4a4@?>$M5FCE;0F+*0PfauBOvL0CWz z{qz5?A5$_o_t-~7J$a;fq9LjCCbg?dEUfXnOdkS!XjpT}#H@JvX`0B_y_|SW{8f8( zC(oakYvTP91D2CWaW_Tl9%pXYb`+$6U<_T+e^p@qYw_LY=h}1-EM(xOwsY)Aru(|P z#^pWRPNX$x#$73tiilceoshMFl4j~JV)Su_g-Y#|Yvi|{%Y9#0MCU-cOF#B<8ZNc> z|7>iIn@R`4dQ=>NoUIqeh<`Il`4THrQZScHVcU(= z1AK7Xxf=avd$PQ5{^9*8R8Q2X$cg?(s^mi!_GDXEguuT zo_^`;%qN$ogsCXtW!jh0kno&Tw4sK!E(?Fegy@NJ5+rxvJ1bcnLqoJrVDP4H_?-mK zuCxAkPDsEd6F zX^-98v^sqz0{geLy&x4qf literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendConstraints Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendConstraints Icon.png.meta new file mode 100644 index 00000000..0fd78b8c --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendConstraints Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: f9aac3aba3ca7456d807e7fab120eb8a +timeCreated: 1448835892 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendTwistConstraints Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendTwistConstraints Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..63cbd0049a7f23a3fc761c9d3ec6ae0c2b8a51d1 GIT binary patch literal 4670 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendTwistConstraints Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendTwistConstraints Icon.png.meta new file mode 100644 index 00000000..a3012cd3 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBendTwistConstraints Icon.png.meta @@ -0,0 +1,95 @@ +fileFormatVersion: 2 +guid: 91de8d14a7b7a42d88d336323c428b20 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBone Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBone Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6ddf89c7dca2475014e32305edbf9fd131e14d2b GIT binary patch literal 4151 zcmcgv4Omm<9)C9n4iP~#5Gg$l6->9Cv$K!0lN*Bpf{Ko>#4_Wsoxv{K&ODnkuyB~S zOhKg&!7}8Qb@NdZHBBRR+6R?Ll=P5@SJWQ#Rw!zj<=1@=jA^CebGy&ovz_yv_x#`A z@BjV2d)_c>TF8*mLjV9FX{kw>@b2M$!a#WaP)i+#w;)IATqgj*Be)+Ays~~207Fcc z>|9rF`b^Tu*d&yR$)_c5n*&M%Fg4!opo~Sd3(2PoEOw3PLc;+OVlin%a}?=lxwa8RA2?1=hi$dHstKCVuHKJZz5{|iPsR-#6aTRGq2^=Ak zn{Gh#3`-*liBfFDl2oV=-$w-5Sd*E|OiJ-_ z!6%KV(B*QFQfYBPoQ>!6{Oe&L!p@i63Vs}w)vE3QdkB~$=jjYAtvM_dp zL!|PVg)WTX)lADZD+DhAKyUPh> zF~6*%ka022LgpUO{@1@DfUZqX_jBA;7n{vb;dCW0f@b&}a#v|*c8P6Fo8=NvGJqw}qx zlPDLh5y6-%#Hdn?VcD3Pl&MG*pNz^#6zvmDXG|7zNx!HJgK}aN&&F^PRg*X|nah)Y zQJ8Qh%0&$*Y%-E&hP6@9T^1WvKuaC=0uka50;y-L3=4^&cKDt1X?neZWy}^UeBsQT zmWZS!>y?;VsT9j3Sg*S2>13MS>7wjLIxR^fg0@O5785Bq5~xf;DGF)rj1h+E%ROD4t$F>b4;&R0^nlFk>?W}{k6spN98TB%Tr zWhxV`G?|T*TGi(fsLgEF0?V1Q-igX-WrB#Pj6g9=B}Y{NiH|djUf^d(dP{($j9h7JL`E(xX_Lq|ZMjQa2K0b$ZE+zD0skaZ`g`v3%|`nBKGgS| z)aT0-t~`4;Q}S*d=YI1L?ye;4`~IE4-&hCg**q?Durm2bUC1TMQk7G5d_r4` zVMknXNL%Icl}^cLha`&&nwwt3&;I;O$@azTcH-A=b?hxLH*2!q&VD%V)LU;aDF<=< zI-y4dR)DzjH|57xemJ?St*GG@Pn0gEC%R|#^an1EJ$CHu$HVJ{TX>`=%R9G|K!p`R z<248C)4mt3$$STB1KKCL_kj*`^*_sVyrB<2q5Tyc^)#ogh}Ry`MWTPz&`wEb`>5}?<@|Czuzq~kubZ>A2Y4N$oj1%218)R6 zc0Qww*tD#SUnsCUTAHW6+%g-e9uq7$`g-`UL3LkeJo4Qj!LYiy6Mh`w)vRjY8(3(F zy1_SmGEcx(g*$eAelF6}_~3z}uS0u;URUSbMq6`6)D2$GMD*~2S5=!T%7A-V?gm{$ zaP}wGL52L?yzZb~OJdEfYhJ*>ocvEN{xm2$T)Vk2XVM!RQue0CbX_{1_;`h~bJfT% zz8uRd&1rUlk=<1Bq^`B+=QUNnW?9&=y0KjBEqPh42Gt|kwC+=0 zgD2|61H#MV6A{;(c-P_4m9^t?16{#7ThxvjjeAb2@&YU01#QP^Nmq0NJ?_&`&-0fq zBokLE7I#N9joKgUS(n&3d#pF7v^=u>dr$S0h@XP^e8UlSldgGiIWV^*97^d4sDEJ3Ja8z<@X<`?t>B(9J;2O1w`RVbJ+U^x?*91t z)WpI;``^9bonjt}8dd;*8Q`UpVpeCz0 zes0_~&okb_*7#?`+%JZkBi0_flKSWobzQK#di2~Z&Ff;pDN#+pQ_D(Ps)1ld9=v&Z<(|2f*~k<%wX- zS%8M`tQ^DZQN2;~S?y^TXbA9L_+YH@ghW*F?QoBkj{H)3X8-&zLLxzNNjQ;phGcjr zgLGP%u%of{eAp`9w!ALkmLmE1CfhLTt>VQab1Q!-yE(HCtlvTG=V?J%^P#}mWX8r9 qZk>zKfss6eKsOvDbAzRyFX>UIuIx5M@8tg4rzOuydM7b&>3;x}GQ-;d literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBone Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBone Icon.png.meta new file mode 100644 index 00000000..9ec7609e --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiBone Icon.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: 0a18e0376cc184a9b96ebb3bf0175cc2 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiChainConstraints Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiChainConstraints Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a07d2cd33b637093b277015a6d2b5911f6e4d157 GIT binary patch literal 4135 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiChainConstraints Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiChainConstraints Icon.png.meta new file mode 100644 index 00000000..1596bcb0 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiChainConstraints Icon.png.meta @@ -0,0 +1,95 @@ +fileFormatVersion: 2 +guid: 1a42905220c3544c99b3ec98f88b080b +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCloth Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCloth Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5c4c59c8a8c8ee7610b922c093498057c93a04f8 GIT binary patch literal 3713 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 G2mc3qcD&~R literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCloth Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCloth Icon.png.meta new file mode 100644 index 00000000..c6f8494a --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCloth Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 3970b32a4b80e4a9290b7ac8a8cf2619 +timeCreated: 1502052646 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: 1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiClothRenderer Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiClothRenderer Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce6b6bd9ae20d862dce8bd4a903b20f8baf21cf5 GIT binary patch literal 5229 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 H*@XWOo<_Kj literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiClothRenderer Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiClothRenderer Icon.png.meta new file mode 100644 index 00000000..b6a8abd8 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiClothRenderer Icon.png.meta @@ -0,0 +1,103 @@ +fileFormatVersion: 2 +guid: 503f012f470234e44952b01da62590d2 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollider Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollider Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d769edbd9490217cfc1bfce1edfac62204514ab0 GIT binary patch literal 4533 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 BdvpK* literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollider Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollider Icon.png.meta new file mode 100644 index 00000000..dbadf1f9 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollider Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 6da22d6bce08a4f3d86542bb903de689 +timeCreated: 1502054757 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollider2D Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCollider2D Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e08dcb4f90e9df92d29b9baaa1cdee271315d639 GIT binary patch literal 3043 zcmcImXHXMr7X3oe(2*93bio2h_aRCb2^w1H0@9>c>7f}wiXsrCNtLD)0|KH%B!F}X zMNkka(m@OmdZaJ!$Ii~%{k?bQ+%sp+xpVK&`$S(?i-DG#768DY4ZnpvW%S>Go;mHU z%C>}4qVa~C`vO46`ZpjTD~A&RS{)Y+4SjuQFF!9|XD@F7Z4C_pZyzs57k38$g2r+U z1I<#%9LiH<2PPBs(e>&K_Xr>)jD>bFn-?-a2eyxySybDj<7iFT*w5v_joTuJY2mqX zv-y{BPHIo%?!_BhDy;EOl)MiMCata>d_QPd%2_(>M-4Ec&#{OmFBZCj>&WPvilh8V zdhoVxJeqs8K`H?5s8DqwP|g5WwzZY1!Dv~^1PqK8o-c!f1PI8y zq;-Kp^%Jl$jzEf2G`E0!tg6ses^&@v+Wdoz76lql4FVF)Fifg80G+8W-U|d2D1ZhZ zYagWmf-+xfsA;;)+B+Hthk#~6T3^Q9Az3zD+86G?&GqS7!Pyq~YIR%KWoAd3d7+$) zY++XT5+$Oa9susW!OzDEDww6k`I$w>C3n(xd*QL$x|fi$;KtN(!!rshz^pq!8na$l z7@_p;gjD%Axs_RfF%#fCwPz(ePLqF+_Dk?yJWAnEl`pSAzw0LNd0INURS~-aywqI0 z@`>z>*K~aN?x}k`9=r}7W~pXYG#5o3J+$=;u+0` z0)T4xmc%n|x@5rYBqxI+1CY|Rm!v8N0eu<8a{x5_;KGjBsPjKcQJEmisp%{Q6V&&;FG(-v^1t8p1MD~?jVucGA6KbJMbT>DvCfnjNy z#WI5E4Lf7Qnb*SE5JN+y)&*s?6;zBnXO}oC)DMMaCQ=F6!sVW$iv^bB*bIc)yL^f% z%G6zxt>D6&5kVGEWbmHfTwwM${NkexvYL{aDJ+{j?+BchFCc$qJob z=r+h*%cq3?P*^f}_m{sP2z#1nj~t$~!c3!7WJS1^r5$2`6b*mLa&dAYJ4-J6)zeHy@o8p!$ry6` zb#{4aIchtQo*{-IsuON^iOY>EgsX(Jj!QBV@tXQ;MrN0h)OQ)4Os5x2FT9M+uIye3 zWl!#5NmEQSNefR~DmOCrHC7o$mD3r$F=l#m-z4nyZR2go0CKXUH$3-&Yghe%LLs7O?gxK=n;gjf7E z7ChECX1D6I%CSluBl&yhs^*I4?kIXFlKpAwuhkpWN7s-05BygCYEMKh)9m!@FfLCH zYVCMz7wy1)lSW8`{C`QwL9b!B+@%%l*LyMczuaE9;0D(p&y=1cIM*k)ITsCT7hS}O zuEjdd$p^ud9kE{L?XYq`9VXmv+S<9uj2E{Rx6e0T?n`yca;zV${p#1-+a*4M9mRI9 zBwioRam%x9{LwIem=OI+GpGGd{I&Sb^s)3%0(H7hIvM-IMA-yovSacct36^#6eoI& zn7Zrpm}b*wD`pculvZR{v;|~)OtH=N|w=TZX{xr>?HaRwQscj&iAqx9{s=l4nRYKCp{?AgmsIEiNsviCr9+3)e}OZAE(_(skp#tcBGn8UqZ?;)0Z zKS1NAwcO)y{4QLXu)Q$0%U5K|ul_cuHS~MvM;0H!&YK@N;S)EK%AS3^G4A@oC%_5o z>W*}`U&+Ryapky(px8f}8yPHqtQTljpUk(7wkbWC^QBmF&yvlV&oWB)v#(s3DEtUp zT<$021>Q85H^+o3M89Cks8Lyn5>VHdfI zYlbx5bVW^UCL*JTUcJ%~i!_x>D@*Mrcvf!T`)JQ@oA$t%^Z?)>yC z2zK2`?5pkT>7$glm0z{!{eT_cEVx#*8=U*diePe7@usfvhv?Wy(_~=C7Go4I`;DKZ z)Rl(!VnL>Ec+IdK&!M%*$s}$&p8BT6@JXCjpk8}kQpl^2v%8ukqN|^m`^4L(rWzU# zuUmHDV{2TFva#D)}` z{IL>69{EZIc+#(DMY+89d9@nrPQppjbN2q7@=2z7`MH;rHumNtQ|3w@l;q{=swjQS zoIsHghna3x23B|{je$HBnBN+r&YIl4^>Zo7YQ4dGTZn8oE>d^5La9#|lrKr|9H)oJjr7pMc#}SRm~h zV!|poDd_EC01KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(`>RI+y?e7jKeZ#YO-C z3_VFiK~#9!?45g%6vZ9KKfAYkcpfTv0YsyK0VN2CNTe7IQAsKiiIy6P7=)mJ3W|at z8u7s^LG)006Ns9`1jQ(7Fk;2WRW#tMP9Z>uU~tfAEW|qTV1V7*$sgSp_jcx<3l@_X0ch5D-m{0OkQ(fw2vAz8j_TJ6oj) zj?e;#7T*Fk$|t`#kLwfzx5{gE*8+$J{ei#Bao#KX0k6wzYXK-e-meEb`Ecz{^4i_C z0Mw)e_!H2<$2vLyPszHp02JdM;Pe3M=_~8f0#IzyH#xxiCVMp$XaRV`Z9p=>`jWCv zEdT{L3Ss04nk!`8S^y#QBbsOA@rqJecU}Z;3hq*}p`d!-w2UDkRzC!IB2og#q73*c zV9OuzMMO2wH_CN~C4lxoC2&&KB&t8KH=-+m$krX!9AHFN=Oh0YOmt1DyftfQP{(|t~3z`G6?nn#325yo6 z&E`0SE0pqdDcSH9@OTJSuLiyEc@w9^OQkus*=MIQIk|0&XUP zn3mBN7)IUj@OJW_tEd|uzK&KN9{vyDVT6xBHWPrQ!21!@KsCZ*__#_prLtG>T{umh zNjWB}Oqmqw1mIZJRjIN7{)@Z0^J3s!g*(3zSR(&aBK#k<09wcbV7E(oxuW+zkGj5& zT?i*=q+kSK0e85R_XkEPcCTj%Xr$fjAu>DIH`$sUXF0+aI*#M z)&dBg893we+R#AMjA#CAzA=gd;;9( zQhu4+63w)XJ_xh&623mIqqcMB1C^#_oLx^{cOdp3a+!?NLa7B1Aol_PaVcMbFxFsN zMu}+|bAWe%K@D815Ad3487oc8$aX;OfqN?0XAsA`pal>f2jozY%XfgEnU--Lut`3_ zO^GdtAx`VqZd%4@(=uu;er<9-cM$hoN-cm8_#G}m6UW+B%Ma4#W%&d*mu~=%K3R0( z7T|~Vym@wM0jNO+k!PR|U&Pv#u1t)Gwe+HgDCVK$7`M!2yKvtE)&dBTilgl6mvRf2 zB}cL+*0Ok#CCO2I6mxYqn1YYN8d?C&#I%frX&KX=J2dv}1nD~ewx1&@PmF8!H9v|S z&+^1bNBQ8)TbPz{m1!9#Y5}Ox`2*zae*Ve!?vhdIryZYJlNiSKc=NKV&Q4C^P|lpO zm=v=PmxG8_-ey|Hltyd^S^z$Fd|T5p9t7SX>!_AV=|?!mt{YEML!3Fu8=HLXSBnPm zV$onn`PlU1bhAIowjGoM@0gY`NDCm?&L4&dBfp6phm7|2mrP1O;`q*M@w2EXYP_Eg zlVoP{W=HvP_8x9XJ?i$A(}CAb%UEGrMtdy)e>=XjX&GyPKhr=0snO}D=xTrLD4&zO zfpjA|C|4z}U{}m}={r*kDaC529mh-C!6<1v&;szV<71{}jF(US<&AwlNs8N3OC9Aq zV%=DsxVYZ$eG==$;^faA<%2Sn46A8UPR5Ri4XRg6%jl^E;7#ZE0{#Z9pc#Ap7t~ZR zF!P?H{DH(+s_Qx7Wlr)&_U9bQm!O83sRhlw?Q?-mre(}EEu%yWpk*E3#gsPnIo4Kx6MQ1%6Mk)uy8D}C)xC;pA)Xm}Pb@a?Me!@zbUF9kkAL#`A9(c*Cd5_8hC^aqPe%bkF23c_t z8D^vwHTt<*)5~dZe;LMeF$9qjbS6+zhyoZYU-!3!H4FZ3<}J>x+1TK+ad>)Nm_u?g zB0Jh<+`W(@DS%GEALUxOYuJ;{8L7o2T*CI_WSEsIC+>(f35D*!dPI7e&QTRW47f%v z?Uc!s)x+M!i1f3rbA&T8TUE2u443UU37<|<^Gg7yBI4v$p~*f3_M5M)!dp^ zHk->ah!nYR;=|z?UJIZY5u3LO_@1gQT4q;qW9sXuvZ?7`Q)XA8IA=-`EcViN;H3c0 zL2TU2!s$b=9AnaJ_@@0Sy)ru(>EcGFC~-vW<2J8`RWD}a?SNka*W#fG*KgWznA=lJ z>1cmWks1@f=FnMAtglAoB;FC00J{9|AuHHlPWE zoxqhX?R>B10JRPqR}#?}`3O>lNJw!SuvUdhppDqg>xDS}&C-433u(lG89fj#>4#NY z2JS~h>h{DvwX3G(tVg(@PXs0C)pb%uPSmMku+~dJyGN~#F249n@}x8 zvgklIY_tFxXRTZ<%)no>a;@i6PsGV(RZ(xaLP{2GNxQ)*z+KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(`>RI+y?e7jKeZ#YO-C z3KU61K~#9!?45s*l~ozXKi7q2QAVYiG9j2i9AS09NXL{Ab@5j;lp@NMMlqx)_=9O` zkqnec5Oqk@-5l`;sf;OU=17qNQ-($%jp?tRbqea`coAJ55TvssMNx0nS8fO6nrpbnS~i~#!R-w3@{2Rs7w z?GY9rkAjWD8h;fq-s6S60T>2+4QMX90Ibowgr9jdetW8bCBUriasp2UUH}dNSykdb zU<2@L;9g)VFbXKkQGWoi9QYV$0@ec;#rXdIYA*Kyhk;GNRWa&U0E>VyNwxIHxZe*lR*b3o^hHs^ogETKG6nV1-t?r0yYAJI+SYx zCaZv=I1YFN7@6bVOrX}I@qVvwQAh64hIH{1a9xh;&*Zu8di!rHu>BqYW+!n13lYEz zz?BI^*8rTH=iXjmFwh!N|A%T}a?uD3RLhi)DZsON?zI5J^^MNQdBE!t_s<9Z9OHSs ztKV4&+kp|qjsnIfv^pn8+#9GKudDxyvJPKKP`?Zq=cs>ig3r&z&;-wNXu`HANC250 z?ogFdXxrQ!4{J>q{-A#Y?>Wk>i@4XQ{y`LLBkr{Ve@al_=YB_aC3s$YxzfbVJ99a?{2F=C(a;g~dA91cQR=HSb=H>_ z(*ks)uR2n5fZm>U>VXRrhEBne*7X2Qz&zkwkJ!JB!5aE}!J55u=n11{n}BnG-+GoG zf=uRo)|xL20iYiKMDkDabfi-KiE?YgFa*%%Bvu30d&d12s7GuBB7ioQ0pIo%!FPb0 ztr^1-0Kjv|!U`V|+z*VgrVL8}Ad5D9-tKbs2R?7j8I}M5evVAqxEO#e$I4ifh9v-y zS+-|A%2ffkT9bw+fGo08<{gi+ivU}<9+&_C{)@~XxMl<^ki{A{J`k7yK-S=YS1m#m zX97RArVUR3051U#dX%fiy}H;SohxYPkYk5z2l@byT2v6G01hF8M6M;#UqyzMjlcu| zvIum6N4a~jS;HU&0I=92G&~VlXw4j^0FDCR$30&#O(O#%Fadz>1XL(VXa;sX6M0hkpq0ffj~z;7I7&L`fHwkCj- zG2g=qEF|EKrKK)_&B!6xQJjOU8886^> zqs$Eil#$#7@c-=BkS~f}_~k1$0i={#;C)A#3z78oCV&7rjC)HN$YE9eOaNi>9PX@R zgFU(n6F^Gw%{n%Vl=Q0!gL6)*YGfkO8ibaH36iMcaalHT-*YD!vqi}cWY!2MF#i< zFw6uH9?i(AphJ#wCjh?!jx_;<#}@pCiAU-9K*j_R9uEL(J<5HH6r5OQ0w^phxDIIW zC_4wZ(F7144Zzj7PcH>oWi-VE5FYD+A9<83Lk5YiF#&|fQs8M%5v%~Fn*hRNI_|Xt zZ6a8Pj24!e0Kys{n1uU$f;Os=UCAey0K(xTB*olr&+-$HR5f2V0ffT`KowB$S$;V1 z7bFQqMMwgu1ePEZD2McKn_jC7Tm-w2v@*Vypf|FXpiaAyOqvByj-2FOhwPynj-1uo z2NVQWGaFb;_-bb>HZjMoB7&3qGCbHbTENucP2UY8YB_#j!lV9i$mt_9^|Q*=Y_D`!z?H}p@tQ8M zGN&N3j?24C0GAc9?m}`O|6YMi)4G_8Bznjt#)mwf$4%rvX6|0c;7&d8L>G29*8*d^ zLjXgISa*EHy|ZzTu0_=!sL@IkRSxUmI&q|{a}HLeZ6K&QX8BCQ`)M3k>GA*Yt^{@W z#4I1xhi>$6w4&! zMDC;ITkzWqT7wK`<)T_66CBRqx(FZQOkjxqFROu1VmzA__{~aox&R*ccyQ!-=#Ry$ zvt9ey7xm#ZsRus>c-^D^KHyy7DI^ulVXb$mex{2?9pI_eSo{c*b9l0f!{;|oK&FK2 zHB8*5A@S{6X16+|mutv58kh#$hs+{wRH3ycx7?{O#?-V81l4LdWppClF%X2B-#F%c z9RcRtOCz1Nuf17K+Y)3IY(8PNBCBF%w~qkgs@CY4VM{YIwm%YCEBBuEk&Vb0_EKat zYzFRxj7E`2VFEBr0EP*`Faa1Q03%iWZveOw9HW!nLL>kH002ovPDHLk FV1kX5>tz4{ literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCurve Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCurve Icon.png.meta new file mode 100644 index 00000000..c0a6c7cb --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiCurve Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: ed34a2f317b874412ad24d7bab730ad5 +timeCreated: 1466751256 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceConstraints Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceConstraints Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2ab4ac8bc2f96ea3d43ceb604ad32128ec9d2fe9 GIT binary patch literal 4087 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 OKub;Md5wzQoBsniZ67cI literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceField Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceField Icon.png.meta new file mode 100644 index 00000000..fb4c6b08 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceField Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: a83ed40096e3a40efa85f35b091e6298 +timeCreated: 1516041722 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceFieldRenderer Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiDistanceFieldRenderer Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d5c420dbda7b0bcadf8e0b02aa0587b9a29815ec GIT binary patch literal 6596 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 eCV-JL{|*2%qv4>FV(udV0000w literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterMaterialFluid Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterMaterialFluid Icon.png.meta new file mode 100644 index 00000000..81bcc569 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterMaterialFluid Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: ea94643102f314a62a9fab85aaf9c559 +timeCreated: 1487699460 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterMaterialGranular Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterMaterialGranular Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..38f11f203ac9776c4ce25f74e1d2a1a09f842316 GIT binary patch literal 5931 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 N002ovPDHLkV1oJRF0cRq literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterMaterialGranular Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterMaterialGranular Icon.png.meta new file mode 100644 index 00000000..6a243bbe --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterMaterialGranular Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 7cf34d3db0e2e4a009f29fe06a4240d4 +timeCreated: 1487699330 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeCube Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeCube Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0f82ff7b2858762f9b5e2a426bb4a15de4f14354 GIT binary patch literal 3467 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeCube Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeCube Icon.png.meta new file mode 100644 index 00000000..4b084eff --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeCube Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 8723f934b6ce94aa698b20cae91c61bd +timeCreated: 1465712532 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeDisk Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeDisk Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4ab4dbc1085196fa41d43849a09db93ac46b1f69 GIT binary patch literal 5263 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeDisk Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeDisk Icon.png.meta new file mode 100644 index 00000000..e9789518 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeDisk Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 84f2a1eb2e3bf40edbbfa365ba480de5 +timeCreated: 1465712532 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeEdge Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeEdge Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..520c263c59485006dcaaf6643524f652634ddcb6 GIT binary patch literal 3304 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeEdge Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeEdge Icon.png.meta new file mode 100644 index 00000000..382e0513 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeEdge Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 42373f4f9c4d04bc18125f69cf225dc0 +timeCreated: 1465712532 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeMesh Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeMesh Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bb1366c01c052ca91e69685d8b48ccdef1d10275 GIT binary patch literal 4371 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 AO#lD@ literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeSphere Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeSphere Icon.png.meta new file mode 100644 index 00000000..28402b89 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeSphere Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 882466012f5c44b69b035a407aa63e16 +timeCreated: 1465712839 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeSquare Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiEmitterShapeSquare Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6f60ed85a0ec1ef470b95e2e8aef3baff302e020 GIT binary patch literal 3056 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 WuNTy-JLSj#0000i9-mLyrfj* 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 VC8uOeX`=uD002ovPDHLkV1n53qW1s* literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiForceZone Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiForceZone Icon.png.meta new file mode 100644 index 00000000..0790eb99 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiForceZone Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: d7b67d3b64785476bb7520aa3190fee3 +timeCreated: 1482503923 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiMeshTopology Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiMeshTopology Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7926bff2158e06fd891321fa8b72191c356b74d0 GIT binary patch literal 6506 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 Q4gdfE07*qoM6N<$f>v^EtN;K2 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiMeshTopology Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiMeshTopology Icon.png.meta new file mode 100644 index 00000000..95d97f43 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiMeshTopology Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 8e5266f7a0df04a17a5505a19aa2d4d1 +timeCreated: 1452221150 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleHandle Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleHandle Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e50bb19e5f868aa8d403a591e82b795567e5070d GIT binary patch literal 5115 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleHandle Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleHandle Icon.png.meta new file mode 100644 index 00000000..f6ce7de1 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleHandle Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 528d201bc10084452b24974deb16a423 +timeCreated: 1464049002 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticlePicker Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticlePicker Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..75f706cfd080c8a1eb81383d6776a7b6b3fd0ece GIT binary patch literal 4182 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 MYu>t6s%{njKQ05aGXMYp literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticlePicker Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticlePicker Icon.png.meta new file mode 100644 index 00000000..0c23c24f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticlePicker Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 0f9d020f7c659443a93327a34ede18b4 +timeCreated: 1484584318 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleRenderer Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleRenderer Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b234cb105b3d898d703c743c17afa86c9f9f3602 GIT binary patch literal 3943 zcmb7{X*d+#+sDrgV#b<%$-cD6zWk7#n54)qWSJtnvagL@DKoM)wuE9dgp|q8Fo}>s z6vE3kYMYLytN# zrelZgJ6-plLk9~&I0gg2%yncCkYC6T0Q{1-k&&h4&A^br;G2O#Vi$~z#DZ=IdV2fa z03c$t$U591Yl~NRYU>8Oo#DtzU7lY&kdVYPb#XYBay$g?NgSN|9m#2MJ8quig$UdB zgdsShC~dan6v4~jUfR`kTW5`*qT>~>Vxwrw%e!B8n->Zf_WC0G*-^(iWilzHK0wnd zSzBvF6m5ZM?_n{B++StzLul;HIx* z8c<*)!qrPBW=>b4IM_Oka}7!+ARvI$lhd1baZrVukn>S6d~IcVR(!V2ug=h&?=*)e zY)+yuuRxLuu|Q|u#{z)h_Q2Z%4L!^PWp0Mzx!_0p)lqujyAmj&E515)(0m_C4>&IO z(?(tA=ZEQnIw7^8t-d%XFlq;GPHnrWjKNB-!aqiBr$=h+>5CLUvFy?oJ^^QDUY7QF zLR9>guKP!2CU81EZu5{Hj76=0TlxCfYEoI^{w?=_uo|n3g&ulCrGTvk$%D@1JNp@@ z2WD04oX_&yTXncgu#~ve8TrO4(^$MaXO?sEj`FH#?mjFloE6|xEJ&AMGrsEaBgOrM zK-1YA2E%}U+`8O-LFP=r;iak^xdlL0>o!_n76N+n%D(~7{GH#qGMmr*Jre-NCGlr! z4H#M8a^p#Cg>QwMNqkWEW5)U{QY38-!((%(6YwYexds9@B&`wpSG9D4CCBq;I2zt6 zX|OI#b2`UUgZPfQ@fWx8H>bep4Z4`P+{Lxhj(cQ`Nc1uBVKe9@+!3k|QRQNbY1~&N zI=XI`Lve;anJx&)HM!f|nh%`ycQ9jJV#@dS?lqe#WyjZFq5BLC)qhhdDtPaGN$^03 zD!U6Rx72q)ut7uz^}4iT;Ntht5DUp=j4uUeByvTV6H9NE# zQrO|2FdiXNu{(`P3Yw1MT4K7E#L?!LfWeqLm^&C%N-s$^a5gd7!xEE}+D=MjRa!Ji zM{#bqM|fz}VH`~GGC##d#EYe`on+&3%|b}Abw8ZD3>TNiC|_W{;ENbT$dy}{>ke{w z7n;jZG5+0?b4>LpyjWglBZeJg@o=~M-CQHLR!7>bIjmI5syv(1Ozno=JpI$h%7)mI zsw=&?;?GP~XI=1cb$@EY}$%asj%%=h;4-nyx<7}5lrNEA7r z_c3qK_dDa_!eZjDa2D1S*2GSP$0-3{foOpW{zd@>tobvBPkGob8^tfmLRhay?2iI% z9nNf?iQ&ooz?q|!W0w<`vruJY8*HmL6j{Y=^W2vG`8B)PXC}5UEx+MlpLw4T;e>7f z#i`fyS%q7nE&H#ymbJLr;|VN>UJIHps^J0uRJ_-z(o(bub*hZAV8v>-*@E zhg1Fbl6e@zu27glw7IoWaFr+CGt;w(a;q1@_P%a|J~4D!40BX7dMO43Z_@t&Jane8{r z1}>DHB*^?s_4=k3!Kdqq4?N+4SDm~u?yK$Y;jKJY-d^4@*K)cy+c)2{X`ta#2$|e< zb{s!~?_SE#94hoJc5nIGJht~B`RVz>4zqOi^v>MT+?XDQ+)KGz_(yiSc9C`)c3LeTQquy<4>R67qTyT(qvn_v|93hchoM zkI&k_;$B6-CIVIy8e{D_ah; zx5(d$Dhevv)-ekT*TSwjUfU&#SiCHhDIQkz?;2}&nkM!{yJ_j_+}P<`q|<$`3w<2* zIJM|51~WNPfhbSFbmpC}wD>z;7{M5pYSEYb~iD+2VXl>4VZM zb&Uiw?T3^iyPQppiF2_=J2z7-OhVtQz$~m}BQpgazL8wNWM@1)iSPe<>#Lk*c42m5 znH8&dZiDO>#l};O7M`-QS*&xB6#oxGS*ahk<|Ma+*T;DLlFbLo8mww8*?7$rDrF;_ z_?;pM2qNO@XO$_>gCEbc@eNi`Le9n7@_!0}+H)(0l%EPCbi>{$~08N#DEicfC{C zJB=GmR79lgpjK-rUari)MCS>S_WgcYk?=KP)0W0RaWtiG$k0wTw0&_&(J7tP?YV@k zZxz=oii3qhHM{b$#VSQb$xDdUJ`iu4WLVlVzx^8u^PcEQcR+@u;No;wHNjF}s z)~V4kjSJeJLA-DZq~6%-S+>`%3Hf!2dTxOB>CTQ1X(;&1?=SK$k0Xh+_e(;J0WuRO z2+~a(zr!|{`NH8p&BtA$&=D{8T1NMOFz&GbxYKY@cZ1|V{o9S?*8k3toyG=BEk4Np z^C@*^(3EUCBxxe~09_<1D#R*CT)W3stxm~K(dNELoz-W1)qP{JGy<(@s*@;+J+-HQV7Wf9gY2yMXtAZc z5Oc7nu$8pFD?RvFqJMLFO+Yq0HgvFYU69yk8yeMR{=G2xhMka{1J=y(^_>v;bl4_LXYSI9c zLScX*lnEyG|AQsv{9TmZ>uR%Ab>{d`l8KviEz|*if8X)gZ4pW59r)fg1`uzjE>n?n3fL`hyW~daJLOvH_iyyI9=G#?{8e!UdlFiUUW;{ zgsgc9tZ+O!_MWSSrV(_mc}p3FIr(oqAIUh~*E~sW6M?$FiA1T8SlwV3>|z_Z4N7&yhD+gcj1VZ4nOMDkjo@kJlj$uuwGMOF3YIwrp`jwciG3%J>u> zgewznc~gIiECtbWtDiR_%A}@cahB{853&UM!|NN$5(eosa02WqW~f|^5`leq zEf~2*DjdVf>s>^(;~6PDiVNCR(d<(C9_rkxR1+Ac*fxKt5y-;xL*LLN`Z;@lIHAtx z+b%$okdPK%yD4bQ5Wa;W!u2CwR7yW;l2?@~bU5ZDL+_3aw0uER(TP;}(x#us4As6z z?+JetoI=l@V}|+@{1hdiK-Jcd)&|$Sw5MdN78s@VFS5j2AFeb%ADwv-^(L4(B74Re zjVm@Yfj0DuuW3!}=#Z1>zo%H(^v}S+KC=~tTeKvOM}1u$S= znCAqfZ?ksu>k3gX8|+^Uf{rl8P~C`uq=Q<|)dxmhB> zzWyaqH<6lu4xW!F*n|rcpEhkxNB$;yo2Q$U z7W^YyJ)*nH0>nZ?Oah5IIuBzhmG4M`qUjx*o7tnb*`MrDos-40%8lYj-b1B=mxK(o z7{FS?rt2CzjVYPNLTyfgXe{|O{mRG~QYP3MqP@BK=)<@%KofN+%Kscc%tyZ=hcX;t z!1-!%SuI>c1PXMR65~D>LC<|zuA2!WDh47`GiIO710XD z1Ci)xbFX3lnZCO`NBWEZr9ja-u!oQERjVzrdOD%%1KDd?=i~U3&;ru-1QpIVCemsQs`8cgZ*!)7r?GbqGa00JeS@_)*kp zuwRFPGv)OkTl`@GOO>B1wQDxXIsfMy;Q!nSZTzi_fd0B?2T+F`ery1^aQ?D!jiFn@ F{{TxJarpoM literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleRenderer Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleRenderer Icon.png.meta new file mode 100644 index 00000000..743e09c4 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiParticleRenderer Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: f424a87c9f03240c2870a664731ac9aa +timeCreated: 1447901223 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPathSmoother Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPathSmoother Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..939d320956bd2d49c33a10e83994c3b0927a070d GIT binary patch literal 5994 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPathSmoother Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPathSmoother Icon.png.meta new file mode 100644 index 00000000..61b9afb8 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPathSmoother Icon.png.meta @@ -0,0 +1,122 @@ +fileFormatVersion: 2 +guid: 8791eecf125744cbeadea65319c29d5a +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPinConstraints Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPinConstraints Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..81eb89c68fd3d4b8aaf7132ed96656ce66c77263 GIT binary patch literal 3994 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPlant Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPlant Icon.png.meta new file mode 100644 index 00000000..3522620f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiPlant Icon.png.meta @@ -0,0 +1,117 @@ +fileFormatVersion: 2 +guid: 0edcf127e08404f979b63884bc2c0173 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiProfiler Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiProfiler Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9bc5433f5ebdefd4c90d3007acbfa9163ecdd5fe GIT binary patch literal 3159 zcma)8c{CLK_x{*wkR{t#lHHq-y;nja88x<%L9$L+XAollj6G{YNe!jMB*P>^ zV~HYJvYRwCmYBx+^?rZ<{?7aR-E;1J&OP_u=REhn=Z>wl1s{(j4*-DA5_S%;kNAHQ za$vu{H}<6N19vdYITQe1;eV116cmXAz+>fSW@c;a8-xuC^$iM^wKOx64GszN_CsF- zAabPGKEf%BDP}yuye5D&9bT@@L&pJm1tO$V(78-76L{Vh6f$W~NajI`h#oG2Ikepx z9*d(W{;5@a}hpQccWe!|qEcV5jZMNq@fE@%6o=_C(nA(ePv{iNl zvKe4fUWmraMnHhh6PG$gK&Lo(VgKqX56A`pjf*yw2T%FH;%`f1E-+k`H3kL4Wk;$Y zAe9Z|AG1(oH+c&@9O4ja?37keN;Hu_!AYrM!#me&Td?EFTp&Eni6CI&0r2^zYTZCq zpB#f@4zx^Gxd$hZU~GUw&FRUzIG`g!%K0Q2vAR4tEjQhYt~K?9st9^> z&&n6&6)FhBXdLj~LjXv!`rqy9pCQoZXQ$@9X=ujp_Oji83Qm99u5+fGC2BRsskOG;i3 z$(l1M#(O$bL6a%58~fAU(Wqr`y}%^Dno=IWbKNsAyatg*qjH*R1u|(0yB!HPchXe) zr*&(usEOWPak@jYmAC4^y+LH0lk3Wv7FxKey&{vl!<`ku2Z)I_6zlqfuc>HC>@PO< z6n>|Ha9|REVJY!Mb-^ z`h2uWp(}CpVCVr4@sd{YrbKSevz-uOPdS6+!(M5_^1Tpfej2B|CrmdJUm?4YEMh0$ z-WgKCUS;Z^;R;h&RSyw4m3qZwlQ7yTt9^I-Zj*&pcHB!ljxX$CCU2g|NZ$QW8rqN5 z6>!DpmId@n)*Us%*OyiHU;Gh<1u=KiQ22f=e(!tVJg?kKGWWRSB&pmXhMIHIL#FGY zq@Df_7nP!vcrqZ0>?wHRMTpyN!B+Gw0>Q!w?qv2vX;Gn0s1f4G9e-P^^)LCXCpL9T zQ9`V?NH2q0g421T@-MlgawSS`fAI^uXTcQtyE133dE}G`+LpYQ0kBb+dWC(3@qnOT z5nP#0z;u0|g}lTQW%Du`2m%C~%&o5Xvkf8!?a9+{?lMJ0MYhldy=!OYI3GRGHq9@6 zYS&X$@&)oV+2FxtOH66Ft%iM4m9TDDfl^PQm>IP~y?pRffuD~b(^q2w+sHj0f7Cqh zQ{F(pkAn-eh4|kQhxiit;yYko$0PzIZb(#$H%MsY!yj{f&dcw-r1@1_D&Ob6!2KWx zr{f#PqeU}53gsB&Aai1KXiqOWggTrV#69J`^vprvnHw_Z@p*?=wlh`SU&NjbR!KX& ztvXrLi-!O=&`=V55^njZA=MFLeQFFX%w zkEy&{8TcTInlmT)t8w7<=k@Z!w}oTX-!NasyN%joo^4s3D3t1QeQ(4#`+J$`G=05$ zrns`OvUQC>({KxSb9UPzAGLW^q+BwjiRm0|bD1PlZ+I9O8(rJ%UEnbOV9fp?>OoTT z<7W8@qh^KJq1gP`gWDxrr#GoP>3>?LaI0b~)?6NJ@7U(p$Z?W!uQ&oYWH|FVA05== zO67WcK;w|HsOceYK4+PbtRM<>Rf>hu8S_yq=okG6DHgpfwW-;y3_m(_I4!XcG9efn z^q2)-=&pw(Pgs#51y<* z7rtX3M)|L&_0;uz?BUS!)LU}tt|yMJK0H~z5mkKCm5SV{e%8?ZO?hOfWjx}>8h^aB z=;`l_?8THyz=2=4#?vLeq#9f1W5-Dr5jO25={FwTIJjZXp!;Kk&|}YA zT3&Kv5GPZQ!VH4v3h_ZBg-ZnyuY)fi=Wjhb_wKKW$I&-tY=1oLeLwcTXCnV*!#acx z!>JA!w1g4W%Q2-!56O%l_sWZ<-J~s=8}?!uS~IAy4!v~8lG5U1Mk}n@TUj%eS1U`3 ztVzp6?kwt9q z&J^sqOA!4Ule*++ScCm-ML*ro_RTWtJ zZqb3(C3Qoskw*8~*<=AH9*95i`+8?5y54&AvVJ{N@hvUgrUhXREWcYPz0Fbr|Fa|r z*i8WB-x|$h_V&RpTP(ET%#RV23O?3Q*;&MG@9(Y)Agm-)jrV!W0uMz8pJc*`2md$Q zzB0=A8#+18YywB;|CEl&L}JnEZ2zj@zu)}7sQ)(wMPUnrwS|f|6HuqGu--5fHOx_C yJ2P*iMSJILzTUA6=$W7h{c|@H$_c>U9tU`2W0Y2{*Lx1^ho!moxf)ZCTmJ#EoVf`A literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiProfiler Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiProfiler Icon.png.meta new file mode 100644 index 00000000..f4157015 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiProfiler Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 1c322d61eeb3640408ee1119729d5c21 +timeCreated: 1482252070 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRigidbody Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRigidbody Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..174c50672ae4892bfe759fe7059161a4995204d9 GIT binary patch literal 6044 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 Wscp?%5NCD(00008D literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRigidbody Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRigidbody Icon.png.meta new file mode 100644 index 00000000..8d93fea4 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRigidbody Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 1788ce7c914374d949486d9789c9f306 +timeCreated: 1502137043 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRigidbody2D Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRigidbody2D Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..58f8861d41f6dc94b4edac5207f5edd402a9295d GIT binary patch literal 5340 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRod Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRod Icon.png.meta new file mode 100644 index 00000000..edf46095 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRod Icon.png.meta @@ -0,0 +1,95 @@ +fileFormatVersion: 2 +guid: 7125c3eebd3cc4f86aac51cca3ee1592 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRope Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRope Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d8490871c89f300ca6383c861feae6c43a32966a GIT binary patch literal 4225 zcmV-{5Pt88P)KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(`>RI+y?e7jKeZ#YO-C z1+Ga%K~#9!?44VPRaF?re`m5GX9jdK%V^3e3d+k+lp1!S3&Idx=z`fqSwun*6a|un zFJTuVC_*Sg%^tegMd(QAbTRCq=>j67rIw{ulVf9n<|q?$oF3LLj5(Km=3Mq(>-+y; z-p<}<@Ads=o%OBt?X@!_BO?gAG^hzAfRF$}0tg8pB!Do+I5k1C9KLbJSPyLnt_5ZT z7XW7h6M)v1?6!;q2$N>uPT(%!G9aTKz|K$gJ-{;Hbo~U_VhZpUaFxaY_P7XG2b`fn zpgm>)-N0m}f%Z5JSYPYlOMrBe0agQT^%`A@ba5NdS1CU+AM+QFwgxf`zn3eWiVff3E0CR!m7@4(;$?q1jfDEu0*rec(VsGd@ zKqK%vut2fS%XcC702yGFf?t%cLl)q%m?L?sLop^e;<*XJedWs^U&R zum*S;*jeq9S6hHaU=i+#+6$|2zBYpa9{{!hJ-{cx7h}oqlMrA5@HB9C70=o1c`)Pt zMz034z@AD*^hpUYKI)zps<$4+p)$Jp{v_0naG5B^ioRx!?qN0=H|XC{8zUG&BJw z0{1Jnv2%Mu6X0&#KKP;XPhsO<`{4EJokFetz`cv77!0jkdtTorRpVYVkg4!A?9 zpG^V&#%)%SRe0?Qupd{L`JO^+Pk^JB2x2>H1^HWYW*8+0D2e@rgHQF~M zzz?|Dy_M(@?4Si0#;xP;#qEi=8MmL#_i9Fe$&8HXp;-+Ag#-{1Ku7=~0fYn)cKBxi XaqZr`+E5(?00000NkvXXu0mjfw$J4R literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRope Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRope Icon.png.meta new file mode 100644 index 00000000..a4b2cf13 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRope Icon.png.meta @@ -0,0 +1,123 @@ +fileFormatVersion: 2 +guid: 7a860725829a34375a627c13703f0798 +labels: +- ObiRope +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeChainRenderer Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeChainRenderer Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ddd935d586b079caaaf0ee83dc6acec2d7e04921 GIT binary patch literal 6023 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 BPqY94 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeChainRenderer Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeChainRenderer Icon.png.meta new file mode 100644 index 00000000..976d10a0 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeChainRenderer Icon.png.meta @@ -0,0 +1,95 @@ +fileFormatVersion: 2 +guid: 1289c40ad0e7c4fb3bd738f8a3f3e068 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeCursor Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeCursor Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..58f15b5ec0a251cd0165cf8385827b4aca5d3253 GIT binary patch literal 3120 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 WO_9ph8+C)_fQG8hlNx2~*Z%`FjjKWc literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeLineRenderer Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeLineRenderer Icon.png.meta new file mode 100644 index 00000000..1345c291 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeLineRenderer Icon.png.meta @@ -0,0 +1,95 @@ +fileFormatVersion: 2 +guid: 905a18c273af443d6bc588b59ebd56f6 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeMeshRenderer Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeMeshRenderer Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1e644b1b80b0c3a285dccdef4e6446bb898b906f GIT binary patch literal 3884 zcmW+&cRbYpAAjHZ&>i8t-i{Q`PFBj+$yUZ8*<9H(MWK#V$|d7uXR9P5 zG7~zNUFfIZkg{rP%5o(ZNG4cJ*RtN;LZL%c5GKuQ0AU^(Cxb?5E_LHgot z{Q+R({s$PyD-ZyH^@4|vj;X0TF@WgrPV~hZ>gZs7{fMp}-q!#K87(vqwn^XOQ=i|6MSn|0}0NH zpMtQc`R;da%xwUyGKGdj1XOG6!k!TU9Qb~cJ<8Sb?Qcw-siZZ)-UU-Qt_3z2nE*Ov zEjoEXrvRune|eP^WB}kD8m5f{PuRiox}iEV7^z4f=LaJXk5nK)3Jl~PH#iE{d<&c` zqX^P)+B;B8(ZtC@v?>_M_O*fmoYcS!f>LeBoSII6l&dY>1F&b|Ku3hTmkDdkR4hN# zG*#i~8%xE*0IfT-H~ak1X&!3k04Dg?>eRH@^gHk8+RpqZP_D>XTtRleI5&QQ$++(@ z0GOS@=KZr87>)`qqN@en)KNUh0X#X~pN4rFjz>HVITy z+=Y(NH-x*oVqKZjT#Jzk4AHDTWO^_=pxiN`U3`7$Rkt@S;wKEA#9=cO1T-VoWRfv# zcLB;xQ6Y2-fb^!FG)*ZO=*=#j0igc7z~%A`e&coo0J_CdC#$s%9d72K&^QX3h3jej zaAy`>&BI4&swi!iS<(^K2Lf4If)+I85$IJl6Q&rQ_YGCkeCjOw!W7r#s3l*17AJwC zcLMcykdRg z=UmEV&EMp)POL)WZeqQ`sf?%>W=tR9ftqj1MKOu(#r}fLl^((8w1 zgXg~o27vIyR2S0VDGt}*t~F2Xkd1@Q{eik#_)qwpjW z_cFraHtL;sG?{E*V{D^SF0m|L!&Qf{M#kJe_3juhz1*Zm;wINlYseMl=VTjwisVl* z5wRi(hhrSvj_LTL99{QjFS3eBkQEHs488DUc$rf3QuQH}M}e{A64|Hg>n!30iGt0( zTTA97o80@;)iPVlqudrhZH#<)lu(+%Wu$aXV-9+BUqL&!_=#C>MbSsZlX&I(mkfQ1 zgG}Yj<0`ln1M?($^Z9hTOJzzv4di*ad2G4MEe6yfCt^hOvInw{;nr8BzJ)=*`i_(JL!{ zD|{4~4PP*3!1w#uL36UU{x{gEb!ldU`sg$0;L}uI1Eop9;K+ zoEyK?kL{+!KGG{_GfFy>)R8rs71qt1bs=kul4GTA6>7C%^_gNge0fQF$!FNw+f>Lp z|8Tx?e)sG0%KXaKpnRW6o@t)66GJC9%&(80THak|UCvu(Svj}qyeYBiv)M1)bA(HH zSS3Iu%r79YC&=5keyQ}EVoOD9Ma!bKn~>WB|H3sT{>SIZ-CWs0+5F}{Wr=0i@89gs zoWuOA8+!F&qa^=r{&?jVpN|tgYHi_9|6GvG7wWQaQKM_EuWs2)-{_esEXyx@w?hSwF@5ePhZp2NhHHt?J zN90Bv+AaE{^1FL4ZM*4P=r2CTMP?^hGi(ml5QT|)$>hZ(3gtqN4kZ6%x0t$H?Xi;6936NtkUNX;n*@@rN&X=bbK?&9le~aH*ObfB1%fezC8+ zC|K22$(9^;Ha3SV`-R3_3|8AzPQYZY?D_>^?q9d_V@>oLAErDsdtOU5QoT1{XqCBn zc0wgw=ePSE6aB#U(?}D7ROns7dvC-GRD1*e(#O-2 zuKPcB#Mz?x!Wzicrqt?}Bh(OE#uTne?=7Erk~x2{>?wOf-PI6})uHfi_wE;2d#2Mi z1j}EZq2s?&2{A*D9_dI$TPtQ(WOQ|3uUfzK#)a28^QtA?Gy9XBRpd$jOh<|@rMzmp zTAw;UZGF-4Q`knR&*Pz1?Yph^DxcOievupnRb#`ODxzLxQp-pSm^+6}}KK2&N* zxhaq$Q{q#s_Mn0OJ-MV%*g@E!vG#8S{nU(0V24tgby0EQaW%%yY;^ie+10Y5!iySe zA9Ke;w~Tjlz3k2G8{BmIi!}HHej3+0Zgs7FT}ZQEt@mBWZCx3Ys6Ah)R;6YT;k)+@ z|ICiKbZx79#agv0VEw|9${_tiPjadhv;q2HW8B5U@aU!(a9rraUkAzI%Ts>XP{TiG`jPN&lACOaBLbC2(8?whU+{&wjo8!*{YUkKaZmD{?# z_D5pq{^^6XiFLsfE&y;-;vj{_0I>7-KoARgT4)KhGu$LnCT-l^GKbHjbSY=rPTF`}bD5Fx_QJ?DUy`t-VLcy|H=nQGV1n8Ac-&8ocj@{@>0ql zEUBt7+H)&S&WFQQA^C;H_u)t^ybl&nO4r0q*#mTrh&4?0kgw72Gh~E!dnD3{WlE1d zdMFU!s`>ve?>9aBj4iiC;NZ6yW=X|C5@f`3+cRx>*AqDhMkCot2LsR}$(%q1h4v_5{GB(n4E;QJa(0q z7&7qcMC{eDr+^}c5Sml~QV8viT8`rXqE{Je;Cn1qFH8>9pi2|zND^PP1)~8*)+ft0 z8UO-<(7wf5tQ1|tP-AkB#Ri7aK|2mFssSfmg3<&vI7k?1OHhOFKo)11{%-#macK_) zgH8VGdb{rTL9)renrYX6ybbxTPc#<*zch=t*=S8a2qGV8Hfm|wxE9H>_vXX%%S@|> zXbNP+9Jff z*5qn70k!)v#eutuh)Z(NhGsR8=Z?P*k7_k4mW+W2haq9wJ?UI4t&k!vUZL zvmjK2VLi{+=Sbk5IF>YvKw!_o;rP^lZO-8qnt6K2 kD);}dJqDchOVwZkdXx4qunL4P2M-At>Rr^W(sqjeA1W^gZ2$lO literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeMeshRenderer Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeMeshRenderer Icon.png.meta new file mode 100644 index 00000000..1cae38b7 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeMeshRenderer Icon.png.meta @@ -0,0 +1,95 @@ +fileFormatVersion: 2 +guid: c5afdc6c291b44a68be8bf66702358a5 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeSection Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeSection Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..60ff7fb41ca2233f2508e9ecd553fe324a8a312c GIT binary patch literal 3980 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeSection Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeSection Icon.png.meta new file mode 100644 index 00000000..4f157733 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiRopeSection Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: fdb742a900c8d453ea5ce5027e80ad00 +timeCreated: 1464327508 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiShapeMatchingConstraints Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiShapeMatchingConstraints Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8960a702fcb68932b2e9dac361ebf4a36311c7c2 GIT binary patch literal 4677 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiShapeMatchingConstraints Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiShapeMatchingConstraints Icon.png.meta new file mode 100644 index 00000000..51d75f59 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiShapeMatchingConstraints Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: a2686776a1c104bfd8868f056a5cd335 +timeCreated: 1530703943 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinConstraints Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinConstraints Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..20c05c30f9f085a243fbc576e477a02dc45df9bd GIT binary patch literal 5754 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 R{r5ltbyaPZS|#g<{{zqejO+ja literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinnedCloth Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinnedCloth Icon.png.meta new file mode 100644 index 00000000..fc0c584f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinnedCloth Icon.png.meta @@ -0,0 +1,103 @@ +fileFormatVersion: 2 +guid: 630a97028bd4d4777b63c4f8d7091317 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinnedClothRenderer Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSkinnedClothRenderer Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..65edf3629b539e6dbe8351cecb3f822b9d228c2e GIT binary patch literal 5830 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSoftbody Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSoftbody Icon.png.meta new file mode 100644 index 00000000..776e7944 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSoftbody Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 61d065505e09e47bc9f211c93b8d8941 +timeCreated: 1530704861 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSoftbodySkinner Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSoftbodySkinner Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2ff31e9647fb01c27cd747418cbd94b2fbcfb2e1 GIT binary patch literal 4719 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSoftbodySkinner Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSoftbodySkinner Icon.png.meta new file mode 100644 index 00000000..dd71bd93 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSoftbodySkinner Icon.png.meta @@ -0,0 +1,117 @@ +fileFormatVersion: 2 +guid: 654315230d2e241c3a9995c1e60507d0 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSolver Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiSolver Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8c681727a727ae6d7578b3a8a7a5e8433d75c1bb GIT binary patch literal 5347 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 BpADS&pi(;%#64=L^uEdT*l}NRt$~%PY|q( zwN2NxhoRX0(e{A=aPt2rFpys;3;>7e9YaG43r|cCCeRb(FKKLODCr-7alhkp8-TFU zqN|~HS-V2IQ@gi$Yz#&ybvZt(aCH7ls6N&Ch+p1z9in~un`bET!^-AkNd%a zF1kNks?g}6|M33xWNXK>>k{J?@1i5fYis*I_nQ|B7isVzJaRe3+l4ghJLAd~2o`F&?kUR?q zhT{BvOp+!{rK&@%)0NKtiH&F&AogVUbm@S_)*O!^N2AVMAdL_e#CUtE}*S#V$UA#Z(oO82H6ohK+SJ=QHI`;h&@Or$ad*(#5_iXQae26jYFnBVz z-B1WX#cZBT5#h`LydIkB;ky82wNlejiZIZZQ~n!(<|Sdr7mtu8Ul9OYD2+W)tIu}m zlRy=byYQ1(GZ6`QWxaqpBuhNcYrr~(JIe7y__6+xYecOP=6AJBBBh7(XL##Bsh#Co zoaS?kUGYbX8g zP!6v&@XByP%WRws5IC3Wh}y%CbxNu~q&;jlQhOBp#**nfJQ(%ig@nk%ucd*5L7F^H zxW`Yu2Sw_|b#U*WRt#QQ3JwC%57XRmgKFIFDZgADQ<5&aJg^gy?+|jEw>xE%e#%YE z?o5cFD6!a;jF5#Vw*HxhV1`^4e#Ms_B4hA-q+W$O8w5Vq{`32L8@NoTz{}XQp>j2;l3z18U#_n}$grpUWZ4f={vD4yyPhh`K~3xv@!}VA zNI65^OKi)F%kf*Ghq&%>#dn}@Dje}X5_zOTxZ#LOp2>5TZ#j9L*HnM1i{^Rc^5kNy z?N02Rh!V``=F8T~w#kmkUVM4YI?!70NBB$5Yp<+%Ufr;XetyaNt;O$3_U}TkepHHC zf2=%R({B}Om2NR$>0H+0d=R(i#`Wf2;-%7i=(1~W4PTF>N(p^czx~(FU^u{rX+_C9 z*Yu{t8|tb_2+O``h)Sf%Rl~rS?p5v??nMiC`(WH(>!vB^eidHsm+I&0k37kAQtxEl zuvfKvbxie{(TLHO(VJ@lYeH))qvT-!B2sgqatIdpw&m z+C9q#jmwTT%C9GR{5}0*)N-Ms@wmuf3wgra@vCxJzqr;yLD z;CuLTLUNE-eJdVT_?1NTWY3GNHx0e}wp~{6v0%LVm+$w9UY#$|ul7xq3q-q|+H}bJ zTa;b9*}J{Jiz*5#K5ya|Rc?gbu)ncS5I28YC|^9R>f1Ti?l4X0iFDD@)w#Xbzs#ij zRTo|oQIgd1yhVCSr$r`aI3_QKjaIy`z1MS){;zc=d_(B38H)?-6Kozvh!u%_%jC@@ z!JNnZjO`RlD$7S!l|#CM28Y?H!SFht~rDAi44+(RjUP_P?OBzRqPPqkOxM11&g z+Pwk96mJaXIn`vj_dVkNw2{yKMu|H|@{rVMf#WCCUn>8xtiKv`H)vOBxN6RR--D3$ zH@!0DgZ7x$`+yLSDlZ=^AGg(lMqJ~|#@Mi=e;5De@CEV9vadauYaeOXdGI?BzUY&$ zQ8<@>?QxJ>&HVV&56Fe({+{B{^Y*9g@lj_JbNO=K=*`DV8d#_Zo6lGHnTqjmBori? zUu=1r`qZ+nq4Dzh%!MMG?47d{+R=u4p7+cz1%K6GH@8v@&p49#L1xp`=ECq~)xfX2 zzfPWeRQRZ{%!=#I<9fxPstpPa=I)A$SzL4B3%=c=SxMcyb28Mx%`rirM3cd?daD`> zZXpwu7m8sH!VY1LXaf5Bca14``X8zcXPi(J0bgs;So?OQG0gt&v~=smk3urZSCOI0 zYED*7x5DmFhN62sd)_=gu$Z;8vfl6tAKyr`iXVFR%uq4TRx`WuQCE*&&DQk~Zi24a zx2(xtIX@h1uqTk&&Q<nmm;C5(>qKbeCU?A;p!OvB(Q5NM#V}iM!o}!qzoGTGiFA>hqD`#}F%ykOq2^zT z(<7fnvh7?XuXqJve8yk5w!UHawK|O-}zrZ!Tni({?oCk=TVWr zEta12w~e>;P32)5wh=4naK$05*5Im>Wxl04PYC3tl(HhR8)8N+4NweO?YCQS$EkGN z;?g1ooxjw%xUAn5w->FAtL`6*CO49sraA}`c?vWX-C}ca z&#j|^WWKAr7)7V4>?UmP%MF!iFs4mOH?);001Yk)cTxss-7pay%rKMoW%*=vs(9&J+8Utt4eRhiTBKxT&k^N-b ze%W5t0gZv?i9Dy5FFC5mPp-)0K|V7{7H2b8Q=l_5OW#ilm@p!~CB_rS41N&`(n>_4 zV3&xnX}4*(|Dh47dT~xXMJHNtgl+tMAiYU-;TQ_J*SiZdFvRQ>Y?P#dy3&T-O42V57nl?EjF2Sj z7RNuHkxE*H6iR7niiv+ZaGKfw;|As!%4cbX_+fe3JeX)pmqAciDP|Xz)>5}ur*7Z| z&U0A6jyaG9{5CP6Krvzmqe5h*Xi!khOKUn$Xce2X{^}JV*}#_0FEm|^AdOM6`c!ix zoVU)Qe+jw;(AXoWev-{ooYg>|0YOglPfy`U*-$&nS*~W}jFtj)@5)RqMQRRP!K|PH zMdA#(u?LR7|Xb?|>M5G`GeGFM~8pH0A1wA;tb+Z_E zor6~!+C*VO^7e#T*i}h16*wW6=D@+L4n;pfZqwtlLCYqYKSGV#AV4&t8=_QBKsNBL zF0AL$#rdhrxbRI0{s>EI10PWif-G9OMEN7`QX6;~R;Zvf-?d zQa4umzhnOoec_L3;unSVB2vayIwtnzy#Fej^6}b@W-U-U=R``(ExmJ!^#}m|& z#7S1Vl)p86E(cmGZ8%fc6dQmfN<%fIf+Dt-4A9mOHIv4)y|STk7DN%GOUmlRuEP^L zTUC~f=k!8hQS(!0wr*{dyameC5@CIFdFUMHbSC6>iImla?T0rm=$+mw-za&-2WCo%mFl@lGY*BB!)Cc$)9{GSax;n(%K9`90fT*>o_1KkALq5|#; z-B2I1L#hW|i+V;d#|;U1M5I$v@v$uED2ts&oNhYkn$tVO;DJ57)F&=(MGxdJHK*^R zFt1lAyNt{Q!21%3tpF-y_V2?Ymg4)cW^kVz2v1@wV)%0VpuA1oxSHl@$)RQwS-JP+41)DhWN=z9>?G2kTGs%eo8PR(kK9XBsY?djGfHGvg1P- zEJM3nnb9gxOR4s}GrT+l;w2SrsK8b?B>0*F>2j#n;OJeK(@{eyhR3Z-+8nYSMXKPP7`-LkujQaehL-Jobt>aTOLZ@63Y8!IqF( zpVRN}D^M1Pqi;f+GBt+}Li7P>TE_Jky1aVD>j~K1^9n<#p z-sFv+pN<7Gm^YH0rZZ>e({a%)n>>4}oxwRNDtc(T9MOL`8_G(abA}&sQ>HrqBL%YK z>2Zuo2oz)4Ey5Ug&oDA3GH&=k9r*R8G@Y$XMk)R1CFvRednA7hOtR4tMGSWhNWy8y zb~NBWt)!b>#s%5Jj=jgbPAn!WSzA9VXqv7Be5fpNy>1^1=F!{MHsCblBLKkoqS=KS I1DCk}0hUZtxBvhE literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiStitcher Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiStitcher Icon.png.meta new file mode 100644 index 00000000..68420da7 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiStitcher Icon.png.meta @@ -0,0 +1,100 @@ +fileFormatVersion: 2 +guid: ec05a2c75bb4a4ce5a3a1baa76b4c8d5 +timeCreated: 1489589286 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: WebGL + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiStretchShearConstraints Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiStretchShearConstraints Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5ddb1731d38d38b12a6188d1034f7485ecfa6386 GIT binary patch literal 3999 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiStretchShearConstraints Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiStretchShearConstraints Icon.png.meta new file mode 100644 index 00000000..6b1bb22f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiStretchShearConstraints Icon.png.meta @@ -0,0 +1,95 @@ +fileFormatVersion: 2 +guid: b3583331769a946aab1e4c59859547b2 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiTearableCloth Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiTearableCloth Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6e4149573007115a2674deff564fd0575967dfe7 GIT binary patch literal 4277 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 Si20ZQfTp^xTD1x~^1lE&<>I&i literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiTetherConstraints Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiTetherConstraints Icon.png.meta new file mode 100644 index 00000000..689fd5a3 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiTetherConstraints Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 45a4a839cd07d49f698be261ce71ee3c +timeCreated: 1448331895 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVoidZone Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVoidZone Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..595b09c887cb9b689e17cd16b89bbd0d5b45c454 GIT binary patch literal 5518 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVoidZone Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVoidZone Icon.png.meta new file mode 100644 index 00000000..083fee0f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVoidZone Icon.png.meta @@ -0,0 +1,122 @@ +fileFormatVersion: 2 +guid: eac6271e2e50d4b2dbf2dfeff9b65604 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVolumeConstraints Icon.png b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVolumeConstraints Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..eefc8ae99848b962829fad7bf0bc484c323f4cde GIT binary patch literal 5631 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 Z-vFJ!Ae@^ayjlPN002ovPDHLkV1imDjS2t& literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVolumeConstraints Icon.png.meta b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVolumeConstraints Icon.png.meta new file mode 100644 index 00000000..3fbf880e --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/Icons/ObiVolumeConstraints Icon.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: d9d3ddf824bd449e5b405439ee034b12 +timeCreated: 1448433293 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/InvertButton.psd b/xiaofang/Assets/Obi/Editor/Resources/InvertButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..599534295f39ff711d492842e16c4032684469af GIT binary patch literal 28744 zcmeHv34Bw<_W#^0-S?J#3uP$~y3=%_K=%cjwzQ>C79ma2HZ)B_mbMf@K*T5VtSnYG zl_G)&51yc)DEp?uLqKE^(E=h02!(Xt?*Gi(Buzt&@Bj4o`7NK^aPOV7%$YOaGt2EA z=0?P2W+MtQ2N!NUaylS3!^*uM5tl0Da0oTEKQ$e(`wdI}%kC_M;2$Do3?pTDEc$S} z$C>$6uJdLWHC#FFvWLiqVp-J6=n3U2k+@i@<>gBYWr}gWk3T!&%acjQ`A!WJ1_@R1 z(jr+(g<6_jk)9*2C>BRbd?$=|iY|{TFHx09wIW`5iCm$HDj(-7k|^_~QIN*$KwlnF z(H4*Mjl}}qG+`z$Ua6My!U975#X-TrJb@q}cubf;5ImX}5)>Q~7zF3BdW%pb!OmJ=+93Js153*iTaLIWok%*%Tlt!6=a!x4ZFTJT^!r z(ScpKoo-oXlXVlcKSY9SoWG{n)ja!fFLR;)Ho>rcLkuc<%)|$ibAPme4w$>8X5nq zWA@BQ_aDUU_a@T+^)X|5U)K@PIA~jpn19*CZkmU?pX^NHXP>!DqNsSKT&Wf+CDQRQ z$8^W;Y_idv;?(%~OtrE=CYO%aWF^P(QWN6^!I1)ie@H;ExfwG(gPrax&v4;U6`qm< zO^?aXjAW*v{;y1QR`9R1YGKP(hy@_lNgG_&@v)HF;IaV3I%$K;IzARs8(bEESSM|8 zS;xmhYJ6M{0d-4Z#I%5Ez%(sHiev2CT*aInK-#tVerT$Uni4m zWeQ>vr;UYIwD*`+%cn_&6FrL)FfW;MUx}wTZ|o)Cf&P zyjl_8Nhq|PL|VRFW0Is7YD-N-Vu?J#L;#MRrsKrLg$5uPlo0HdhzD=TrsgaOk0(*; z@?(@W*h6w8s};}i;^fcj#i=DZQxw{yAz5-9ThkFIm+-pdXKCbG!p|(1$7Gq*ol2!* z*vkj|Q(-r+p;crSW@?PB0;jPu+_BpzOLLnqE zCqgLV;{bydMkSZ(-1KnD}=}w35afAOtNwPnVMq~ zA)evHX(P@!Z9L3*JYeFp%VDly6c`-Bq(UdhBQvg+9qh{z5!SH#L?g~plD zovD0^kqtGsmq-glIx-bFmP*yyZq##)?5^t0`GsT$pc%NHjQzM|lK`@ybfp4g?Wk3% z;E_TjH6Lr8f!=I;o-4jQ^htWgQGlkkHHf=!7$ygQMxM6S@88m=(?@EiY> zOdiin_U|M;#VR#SxKt)6hf3g!7?55DX?dAeh56WPpZsE+X5o>+M-2`_x;IW2GU?Go zhe^law4_7<4V;C2R!K@EIDHb*e=F7DhR;re^zu@fv<%XhAw5*CE0IAOkEuQ-QW11U z4#sS#Rw^!nbP%Ln)Hzu&V{@Vra&Rd$OXr)Vwa@}V7sV@8^GQs2Bg7+l@HvnOUW&9# zF4b!NGvO;IBDDm*K~ka;DPaC$>Wp(CuV;3C5;k+ODm2rxmc+4Tn8}oxIMR zojm0h7@J}KV!z(W%U_SsftL{K{aq(-=w^7tU53#9ug&Vy6So($&!fns;s6Y&>G(qh zljiRy%*qSE<(YQP@)DRX%)_l(44ZOwY92gih^0J#%SQYkXEbxm%#YDo(gG=do{{o$ zp_Reo7=&9Pk&!RG$P``n_L^Dv53`wBz)7ZEL&AG&2lAO6fIPnTLG0hoA&$2*V$XaV zB$O#`X^y$@_XI*y2i;@ZJ)}WSu3avyN+4Mp8JQMPd{z!mtW%dVDja;{!c&hs@6I&4~fv2}J^gLREmZMkE>*x)%0lkB^q8(^A z+KUdL&(Se-8l6QK(6{IYszGMWSZ7(^vT9flSoLhgc4qfv4`%zbBiQlm z4EA((0b9*p#9qO!VsByZW*=mqVSmG}VLxOybL=?Y93ID?GnSLWnZgls=5ZErR&q9Q z-skM+oaB7Nxy7mFbZ}j{{keQ@6gQPSja$eq<1Xh`akp_l=APny%e~8Ou(Px4Y3FAb zZkJ-0XE)bwf!#{Gx9s-V9ksh?cgL>Y-rl~CJ>PzueTKcrUTeSHe!cxJ`y=+3?C;t) zIXF8EatLuqa+vO*a9HY49or*Td>PIH}>IIVNq?R3iNdndiKv$L;rr1NBFne$@jb+<2v0{>-w7O4%ZW|Ke#rzdAkL;rMgMnUU1v!w%_fN z+aq^J_hIg_?$5bbxL3LFbN|}?p@*Z#aF2Kok;fvBjUJzRT=l5;^!5z)%M^EAZjbUF8+#n;QPY#%b9m3xp7NfRJ@@v!(zB)4fL^h^q`hA0wY%4)UX8u` z^^WN+?Y*M+p5EW~Zt278lh~)Y&#FEL`rPcx={u_Lt8=$;DF=-ssZZQ_EMi#Eus4UD8P+)5Z}`;VFAqO3{1?C8eyM&HemniXAK^M; z!iaezwv4zu(r#qL$l{T2jl3|5H7aaW(Ws51zUH&|0=|s@7XRXC?&!$TiqTs}U-ftK zkM%G0-|2rVpl3i@z|w#N0gnQQ22KxL6?i7FBPc9L9<(*+MzB}##NegD2ZNu6j0zEl zYz(;^>Kd99`aogbXHso)Sn`78qbb~!NhzyRuBHx16{qekb=pB8OE^)uM)-aDuyjTGfee(9nz1J1W~N`}yv)xg+fB}#ym9i+S;1M) zXPwFR&Yqq9L3Tq7kp z?WgBX-!{E|M&gV&X55__HgoyRE3^D&mCyR}xxUZIpF1?$eYR-!zB$}EQ|Ejzr%jY0 z+9ImYPtD(yUn`CmzbSqoiIJ?8{3;zMT`j#=Fs@*A!7qj53fC0=S~Q`ks_3CCUbaE@ zWNymbcjh)0XB2NQrsY%RdrBNi=9GM@@KO{jPAUf~%as>ZeARMQ&Ah02Z_KMzPf~Bw zP?}kqPqaSpFm+BhLidvHR_XZCjipUxxn=vxJx$Q}teUXu{nehUD^}lGBV4n8EpP3LwRLaIe&frkF;(xp>GY=V z&6;&->podObp7k=+cp$!_;zF5#yy+*Z+c}@<6DxqF1;P|_U?BEyz}ZiEt_SVuT>{k z@82?fOVzt}@0Py%^VZz0XWol=Z^yR2+g{z)zFo1s=KZYqPwoicvEzgOA5`vS?bPl3 zb=S;Y7ygm(k56{{@2=j{bI+^)ME}(N^Zti(KD@Gb(%$3yBKGb6XxK-aKKA~2#eQo4 z{Qb2DiVoC#lK08QPbYqQ{NUJwAAc6`+4j!|f4=chk3*G*oenQMOdqK@Qh!u+^x?6> zV|R|vK7QlGv=f(4PCj}5)TC2ioK8A@;!NzBBVUaB;`1+~zWns7h_4Qu6`b9FF6`XL z{|fup$L9s-_kSJ!^(Pl1FC4rWeev+6373w2lkm;y%c+;oew+U7#Vb>;T)R5+YRxst zwO_8wuRr;&^t;v@i@)c7zv8CH&8i>z|FGr9kw5OK5!4*Im2m6a?d;n(?uhR^_(}6q z+udb9yZ&5tZ_vFRzl8kq`L9X8UbsKw{@n+v2dxj6|K|DIrbiig)o*Nv$=UY}Y2LqkbJYvYQhK27g8M>L;lnc8x%wXDs)ZC(4w_JbXhI=-h% zXqx=3;X|GV@Wa3iLgOcB#6AEQ{5-)koO75zN7x%tZ$#18=--eF`8?h1cp=b_kQ1+peB9jJeDKB1hsomk?--zuB2NdX0FO=iB9qD$9Il>JQ_F4DFG1EI)LNdg;Y@`(dlIYi~UfYr=YN+56(~gf%&m#N+R31-&j!xh;LV zZ`p}&ba(VgervbB^wAq9FaK2c-p8lDy<4AKP`bQo+y2v6er^a)o?2M;@|)WaoVj|h z(G#&);4O#vWN*g}BQ6XM_TqpC^L)LzAxl>IU=NOEU91fqntw~Zbai}o53y#lg z&l}kLj4*taydpSm=*f(sXL{}Y>5S{UzgGS$GUD<5Sz?aze#FXs{TGh?Fm-J56Yxtq3m{)<^BBSaN< zsy?3_((%#2$+{ON*S?@qEV1= zK=zaud6|#jBO|IWS!BUoE1&9TO3$T67<5>m6HH#!@jypSg^)BJiB`WXBd_Ri-uL0W zjGWpQBLr_~4fj9zC?a=BAh$~J%Bgp$;$if&&+8gmgFphaFmhWczz#8$va_b)Gv zxyYY}Nt!NiDWPn&`9cIr(j=*kW#bo|M(b(u3Ns&Zy|R?#)vN<98y^INYLe_%bhfe00sMLaAD>- ztZ%fz_%ni8Wx)2VpN@%gxlE;z!ZHV`LAEkp3AS+eG4tFIErL6&A@aJs9PWPEOEHI9 z3`X!_TK3A08NHZr5Hc-$B`%(eS-5WUf^t}KV3D_0z;Vx%{c?9EO*n5*rrpU==OvD8q!Su24=^&IssoQK6hH!Nn>H zW1chVpahLpVO;q$zEs81_~H`NieRTUj9hY^x;y=JrAEr|)naq~ScNv$1Z9p|k=+%_ z>>^b>sKdwyuaHZ4Jj1JPdz6M`uqGxYt7F7oytC97fneP z!zEX(6`S+^ICqS)#$>>l+l=Qb7tNQd;U$<@Dq>cB0bAr6B=DjZg~G`q9TdyT;UrOVUdIf{Vn=xhP*||6`95}l%O&GXr zoE_op#sf2zg>qavo}5^nS@6Qz;X_QR@DXPPf?Vc28Iz0uN4cO1=GpS4rE$qkTKn2S%G#+ulJ&PHSI1ce3_twtMfG^5zlY3Oj|N2WW4 zW^GACTV{QR7DEPn;xy(_UG#81oFChvkYuPmNntKNF&B6^Vsf1VW8WK2M|c}5ho1~a zdkuMrGRy(+@p3iDIhrDoisYFulVBQ7vTiDt=i`>a!C+#!Oi_T_2bL4MSW%4U5ECue zs0zB!VmY>NiWRn@DJsEbq`*nm!Nod_aUK{0yw1760e?yzf4m!O!s$qQbB?S;iU*0< zt25$WKYaU5rkyE5GC>3TL2MS3tMORw5fjL?%cFgl&R^g5IGCwpDXBBa@yyF2KX+KI z>IHMG7nF}rPdK~&7>+CGxga+<-I<)X5dJkF$G|0ruh%vGbZD`E18RaMe6o?Ij*e|Y zEy&YpBTYYClQw|E9hm+0Bf6u?p#`-fuJ;#o{Zfx+#C2WNNS|oh$dGumi$xE*yMb`br* zxegdDG#b(Y4AzVE8ca9SNI~c$^dwkYdAW&39~1f>J)i;TMjF)+x|!xS0^LBPCq}vn z=z1E}68a~4Kr_&FM*Tx{S_{y6qrJs+RV&a>4dt=@=|?W@z<5F&0*{Z;3*j*b(+6=4 zxZ^q+12IXphqvQ8SJ8LY)Y9lR3;^YD>M>0nvTFm#DEAYfbl9yGP-Qu+?Wm_&?XTIl zV7wy^0p14%O*j-I7wo_Mp!Uc86~h}ybZ+7H!^HVNzTVRRx!+&lf$-L!`uznS@NfO8 zpUDGTZ~MR9+hAzLBWmo9mdVh89xN`RoWsA@Vk!uZYmM5@&9Ivmy0x5 zj>mro%uR!j)*GHKJ9{;5Pd#At#v?W!r;Vex8;sPg)7%4bANhbQ4XrH8kp}hPEcUnRai| z>+70YJ7~J2wW&_8Z)&DnX>Lb@Ufx?wmf(a75 zH`s!*T7iCQD2q7L4vZ(n8OGZVh6ZojX)dk~-CRp5Luy;s1O!wS%rra(vltYrqu~i4 z2>?OifCK{g%<(lsUsq3{XX0Us$`9{V6ivyRvtU~diOQwYMjOouE{Zp&*gy~hyEjTVuHNu>&br6?^?b*VzdK?E%lSU}5si!$N#X?O>8;;CsVZkGa z%sQcP9f`~(Va_dxM0JOdO20-zqZ97Lj5Z;vAfdS_oY4rOsBRIWdj$He!gZK#7NWg` zt`MGu&{Q`G(Go&GCwu_GsBRP@F`*|5+aMg(4MH^4NW=3-b-j_EBYXe|Ro5By7YM(C z@Ko!K_O=PD0N3iLhVs}o!n{TZPxTYx5QL{(_&$UO(+f#>E~jVzKm$poUvI~Ct`dsY z)e6xj3;@-vdn}|DwBlG%^<|(`0Z_F-gIkwgFJz@}YH7hyy0!rDUUTlnZUL3uU*B}_N-(N;pw;U9x2RW|XFjL;MK z_aI7@jeL|y=pcS8M5(fYkHU>KM5(ggNXPQ;L6j=%jQaWfqY$M^z0uwq{G|}3%BP0% z*x&IZ>mf>&Pl!VhrP=&9AxfB*kSLuS9deBZlJdVuqO_DB_fjn%y+WeYG~+R!%7-Qk zQPR%>B@sXcQEFN?x}MMSe+8O6MCn34;4QgCqI7e8QATulQqhJVO;NHvpR@kwKcCZr z0b?_=b27#X1Tone8QC!c0nph78n}ZZCgvuFho?-N7$FcOCWZ?bIx&~faCO3|aG*i2 zUEo0k;f$I9D-U8!!xaq2Kp})S6oiW#LZy26oU*EjKJmv7Ek~v zxt0!2oMi4GpwP97xP<7gSab!c8!QHyp=`neiY8bZJ9+HrEi56}b;n+i_j%I;3xPs%I6AKYyP%^d< zTr?9YQ^Oc!G=;%{%45@{Km$FAnwH!uU;z>x0?%Zo#e&EXwmcmEE`etnLA!vU$p6$&EH7|XN+Ll+=To@w~T0;aLCe;tC}3`k~uz!*GSLsC^z^=_bGFzTic7@;t> k15@0Mrj1ZIF?}Ef_W|gR(EOQBU~CqK4*zT~F!qT52SJ%7Q~&?~ literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/InvertButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/InvertButton.psd.meta new file mode 100644 index 00000000..766dfafc --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/InvertButton.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: d105dc041854c4b22b26600e565e6dc8 +timeCreated: 1478799531 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/LeafButton.png b/xiaofang/Assets/Obi/Editor/Resources/LeafButton.png new file mode 100644 index 0000000000000000000000000000000000000000..c097c800b375d81f02bede44903bb2bed24c4fd9 GIT binary patch literal 5109 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 XKGluhSd%B|00000NkvXXu0mjfAR1k^ literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/LeafButton.png.meta b/xiaofang/Assets/Obi/Editor/Resources/LeafButton.png.meta new file mode 100644 index 00000000..dafc45a7 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/LeafButton.png.meta @@ -0,0 +1,117 @@ +fileFormatVersion: 2 +guid: fc6329308ec7e4fa0a7134b8c1294dfd +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/MaskButton.psd b/xiaofang/Assets/Obi/Editor/Resources/MaskButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..5e3c792e835513b9a27c33dd509d154f8edd19d2 GIT binary patch literal 31899 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 Z4(E3?05>FEI9q{|D5>iJAZa literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/MaskButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/MaskButton.psd.meta new file mode 100644 index 00000000..b2c8c9f9 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/MaskButton.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 79009ead5070b47429cdb81d702888c1 +timeCreated: 1478802054 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/OpenCloseCurve.psd b/xiaofang/Assets/Obi/Editor/Resources/OpenCloseCurve.psd new file mode 100644 index 0000000000000000000000000000000000000000..b315d257d5db85f630e5bc9cbe7abbd04f364246 GIT binary patch literal 28549 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 J1= 0) + return sample; + + fixed4 minSample = sample; + float minDist = 99999999; + + for (int k = 1; k < _Padding; ++k) + { + for (int j = 0; j < 8; ++j) + { + float2 offsetUV = i.uv + offsets[j] * _MainTex_TexelSize.xy * k; + fixed4 offsetSample = tex2Dlod(_MainTex, float4(offsetUV.xy,0,0)); + + if (offsetSample.a > 0) + { + float dist = length(i.uv - offsetUV); + if (dist < minDist) + { + minDist = dist; + minSample = offsetSample; + } + } + } + } + + return minSample; + } + ENDCG + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Resources/PaddingShader.shader.meta b/xiaofang/Assets/Obi/Editor/Resources/PaddingShader.shader.meta new file mode 100644 index 00000000..88728fde --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/PaddingShader.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a915cd5b44e5b45509750bc8e231c325 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/PauseButton.psd b/xiaofang/Assets/Obi/Editor/Resources/PauseButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..c22cc9cd7e3f9e4176d2aaf096733574ca8a5ce9 GIT binary patch literal 33636 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 A2mk;8 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/PauseButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/PauseButton.psd.meta new file mode 100644 index 00000000..6e24ea62 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/PauseButton.psd.meta @@ -0,0 +1,57 @@ +fileFormatVersion: 2 +guid: 280ec959fe3324151be804cf285fe931 +timeCreated: 1458681991 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/PencilButton.psd b/xiaofang/Assets/Obi/Editor/Resources/PencilButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..b6705e585c7f87f9b32180ac2da9a9799b16ad51 GIT binary patch literal 29168 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 k2ljfmnYKaU%eH}H+yG$b(zht_JfYHPKZZ9VI4 zJ!-41ty+D(wc5j4wO*}v6;Duiw!iE1VZ-ju^E@-pJoA0#nVsw~ ziHyt0LIh$DF5CpnX@@A5HHM6gOHJc&7^=jF7>}r~y^{ai?j%C+hZq}rF*dl}ncB3n zr0bd?$sE-Jw{b_E8JQ5vq83FDE!9Y*Q{;L zfg)wPR-QF|WVUqr6zM>j-_Rir(WOzPg_=USULq(hRH}4QrGxz>GIg#z3euPz>?dHd z=%)VO*TSD@ExqJo1|sTdh_OVOyS2pw_E(1!|2TK1(bJNRvnvD$M8;9c*2o z#ex=H@&t)qJ_Ha755(|tw$|WWB`;Fk8UR_!J{%#s4dJ$fRa(Xo|E-#_2L? zuv{rGl&kbQ@QA3jM`Y5dJhiq^q8}pBXp{=61Uo&rSS2&MQe*N>bZ|@7f7)vBa$1_% z@E3NY!ouJebw8axu^4)$v8TVVq%M1!Mjo6g*QtxNQh8!A;Ly_Djh!+rEh<%|(@RuR zd1}HCFegZ%kVS<=hDVA+MF}BEp&{Z(kti}WG&WY8C<+e^j|&NljAwdQ>!Pju1jrK9 z(jpAKQLPNC6-7dHM+^vwFscoS42u&*ibYA0VWIH@!%S)|indXku2sNbBvD%A!B+qO zsDFWqHr1pkbP%f3OudnfeWp)l$)~pFnmVge!Sqp$M5~iytJ|XJpX)CvkgIHsEUYRf*PkoVsq^$D60JNo zANs*x4|%N4)`hHi@|^O9TH&tya3)E3pE^HrWoBZG5bx?QmHEVw-G-%Qik% z(ssD40I^NB!(|&ED``7iR)E+h+u^c}kCn6?E-OH6lkITX#>Yz94wn@mw#jz5Y~y1k zZHLPW5Zh!sT(6Ha=F; zcDSqnu}!waWg8zWX**n2fY>J6;j)d7m9!l$D?n_M?Qq$~$4c4`mlYtk$#%GG<6|Xl zhsz2O+hjXjw(+r&w!>uwh;6bRF5CE6N!#JF0>n1i4wr3wtfcL5Spj03Y=_G>K339p zxU2xNO}4{j8y_oaJ6u+P*d}el<^@sZjTW{{ zrWffoMS5W3O}8jRr_aiTO_ofKRFz&XR}~dv0Z!w4yi$v4SEg*1q7>(dQ|NISEM|4e zwId~k^6bR1*}!5eV++8Z0CirLTwkO~&z&pMM#5HAqR~) zH&Be4IHg`?w8$y9NTJj#RE$cH+cUZ2)5Z;Fcj*qoD#$>%w6xg6qQ&XVPE{SqJK~)2 z8okQY2xw%k)=XsP>(b0byjB(8La6jD#E4v_&MX<3uP-(eiG|7pGXXfZsE(6P$u|PQ zqJ&_tL_Ao-YarLdO|_NT&bUSqGw$j{K3dIe77%y7qMqY?5vR*hA)*|1Ib zMb&0Wl`KC)D~%b4H86*pRIApEfo*gdxQ8lK`6l>Wupkp`ic{O!Sjm2WKKWRhSL zEcnhQex@S7z*6975`b;y{5V#q3f2ac0(SzoeH-sg9Q9^oF2+jXHuQCNS2*>U;dOAz z)=E@5*vKeXNvH8+m6`&HK*aXQ4or?vxH_Y3==Bn$LOST{5=hG-Ek)Cq9Cj!cDS=-A z5&;q!cb$hbvhHw&u0qocg^k*-UrGG*!jW_RJM7 z1Y@y3jvR5<+pw?@+3-qwj{q*E*Gg>smzv_>Qi+o z*=Zw8L$95Q-72$vfm%B~R;kE0JsDlu#;2Ir&~m;^o+l|{9tHNra;^Ra*>gy*n3;%)ej;PwLR>`Vj& z;EG_*0Nr_LC6i`HR#%1%bLiaC(=PcfMICk840sk~~e|v~J=;#uuPLr0E zgeN8lHYE!1?nG7-bA@24y~xJluYoBU0)d6>-$}YlHClM!5*d&=Oa{M*0qMDrR+i{B zn2)XY%AJDKBpw;Ov|u2lJK=Obo9@r#Vbd`Plw@u?Az zo?onxmq7YFq=m|&LItGpnCew1mq0LbFlIu%Tv`C>5J)>|voqm|&51_H&MDs_ookWS zLl1m%ALHJ@XLi^m_|WxE7|k za}nD8i$#09aeuM+c@%|Q8iWBgAAgy_ob%5U7WD<;`pmm#1qo~j3vjQN!lv9JtpMg3 zQn?_|x)cA$1ue|7u%mybJWr12Gjc%=^fH)^fxA^Q1@lWU3RSDUy%rk&!(tX1aFXrU zknr4SKwhr|A-7+=5LIysaXcLn_0npP5N5xPu+M?-69|p*y~p-@NQ0cYwz`n-0ZHl< z%wqw?XJ!keMcQIE3kTo0FzazeUZ^wbj(Va1n6HGQ2s8-AphPqbrNjJf9GVC-wgOZL zv$qm71IUd5(H^uP9YH71Pv{J~fUcmMs0=+qm8cdq5(L2~ zoC!~&GvQ10BKi?9eItetiNpvZlNd)#BJv3pQAErj-XIndi-{G)I$|sF6|t8%Li|9S zC4M7r5f6xGL<32YPNWyvjqFVZlaXXBIh@QUUncX(spNEWF8MCGj9gECPVOd;kUxLyiAJ?HQ^o*V%u zkTZyr!Wqqxa;9=-au#t`aJF!EbB=R<<=o;_atvH&t`D~#H;S9e9m~z2DmvA?6 zcX7YtUf`B-Yk54LH_x9J!As$d<4xwh%3H)+#oNI<%sb1w&8y+_`JMUw_=EZBd;|D1n_e~w?queWow^R)}LOR^hpr?Q)4x5Vx)Q3*8sFf9C#!`+X0-M{kcr51GeYj}0EjJZ^hZo;^L|J*A#+cy9Fk&a=#m z=jHE}>NVMGq1P8)r@bmWcyt)hA*VxWhm{=;bhznFdH42C^;UYn=e^VWqIW~bZXIJg z$~!LTxV_`Kj&+^7c8cjF@AP)39i1+8YUnKJoY;9v=MOsX>3ppVr%T^1qq>xIS>5Hk zF6CXlx(@0p?fQ1ton3$TA$|J#Wcs}7v%%+-PffS(-IBX$x-IW^tXp|^@9r_(CwKp- z`@!xHd_8@K_$quq@;&7HP|!gTD^LoS362XYd-(K7=~2{UU60c}8vXqJM*Ge2+u?Vu zr$f)ko_Re#>Up$hrO;QHCY&MMCj7mZeXqz~1-+K`I@znPw}0<3z2EG;r}usTPX4L> z)BU&kUkz{$7#c7&V12;(KD<7WeWvtT)#prKvTu0bg1#&J{?d=^C+?@{x2oUS{@nfp z`>Xn|?|&)KDKIv$IB;9wtsw895kYf;_5?i+76y+G{vh~dupuNoL>aO%hCLn7Z-9Kj>H(L-J;T$&-wZz*-Ykv~YsK5e4GVbCLd1WrVLN{AmvhOw^V8B*3`;j z5yM^^c6_+g@T}o0hW|05?+ERPeQ9Lcu(S`;u8!_&3P$jYfjymgfWZ9+#DM` z_O-D;jq5T_G49*({P8*CH;u2EkT~Jv31u&Zzcl})i!b}XT>A146T3`QPCW36>noC1 zzMjOLG-lFglbR&ylJ%0B+|=Apax10r(xuWzvKZM%vIp|P^2PFdd4uy7=iSdAod03| zgMy(2OA5*r@ro6Sr;}4AubEsoC4I`~DYSBoaz~+E;iSU7Di75Z)p2!qb*cKSrk`fM z=H}F>sUJ_R)DG8f(h<6sb>Hf}U@~>8D4=Lw(XHYk#Vd>JOL9uSE_E+em7bc`ciMt! z_ogRJ|MXSPtI}7G&gd~?_KaJv#lE&~CNVR2=FwR_XU&~e_ImQ`TV^}Vo-+IAIU#cv zW6%p3dWcANY9+}rb#=WUzsGG9CY(wl?cT=N#^EyY`>7lbWXzQFLd?Cl>HhAdpN zuxXKW(U0$l-dXkz{chg7r{5F5xB7kF`>OXZelYZdEsNb3PhWid!?X`~ez8ccZ7AMwcVo`Rlb=R@x^+{RO$#?QZ&q!-xg~SU@vRYC zw|?gH*?Zf_ZAIH2eE!nsXTC`I;@j?i;jk*S~`PwRwM!{VNZ2IPl&D{r(@Ke%SkC z$Ldv?q4E)`S#4fGyBd)pFMbP=(!`mCj5HheCqk1E{wcz z_TuP^moL3^>E>nG<@>)We|!3S@$ZdSUcbt{`t~)qYfG;CTwi~q&y5{7#WxS!O1O3E zkE}ng+?L*cbVqlmsci0D=etYp`QF=lKlJ|o2T2dkJe=^b?2+bCWBL3F_li#*2R#1f zNz9W|m18T*o@$@c&lXj6uG(BZp!#S{M$Prw!rI2Vx9dCCZ+Ra1{A9zJhI@@AP5h>1 z&3&5p8HO9K(uFk5eAn<|W&?OKkjv0`292m4aKZBlf$^NgejTAcM4b>pU#2UN6Z7+Q zuf(ST{TR706q3CT`3d?8nv0z5?Ck9Aob2tL+#MYp-8;BCIk|S|}|TwJ{H#l?#);{NX_pbsN=J7|D_BK#2PPEhUyeGR_u?P$Y-s@_BY#$|($l?i8nohlm?H zO5*7^b#^Gv>w|S)#q|_+$UKr8Hb6V)Y&^f$;;hPBPo=tW@AW(1=$-Ikwk+}J2EDlB zxzT^fpM5>|*sn#mtCIXb+Bol5hh?n$fFj-iW%s=Ik@= zecgnj!tTpwBrNWFDU9ub>E=N{?~RH?x|{nJRkX9jDB~| ztFkU%O)*SfzUtM>G`c>0VNk(w_lA*6j~(p1H2Ucs5ygGlxl8oKtGnLh*Q{Foo*_gn zo%iy%)!SU_ryq9lz4XPGCud2DmyNr;{QSbFfrS@VS42;XoH=Fbq8%{}@0_U$S*CkD zW6a_syVunZ{9#$>$fS4I78N$-FD?r?E_?Igvk?tblb`Rs^t0h-`b>5Css1lL?DpQr zV|VY-{`!2(lA>~_=!swDxuyl}`l81NzZ|OCmj6UKafhPxi?TTry9`fW@J>hHnh6h= zj2xnP*ln2O<@8P0Q>WfN8L;!%qT@NMWcQnfu5A2VC%YY;-E*Pq{dD1>A4kmER=OtT z?E4qxqEo-$dKmJSKK)ntHQRpv7-0m{)VS>=roBBZsEf z5rQ|f#`|CV7$$;WxP+gi6v3as^xKr622pE?7W>wc<~jsxsg^X(2nUaVuM2P|@O#Ua zwh(?TZ6W$vwuK~2I*3rRMK_}iF7TcPqr%?t*y_3#D1_<@B`QT~W)fb0D98L*RRVsI zcnVH8IB^*`j4w2?MJP5Y%kn)FO46pPUikXaREp67xtLdvVP2aPu@+GB;+K}DQp{Jv zBweewlTf$TasdJ*>5{ajy77xmllBquDhnHNyE4_xD_J{SH$E5))-g$+!aOa!yJ7rq z(PmTIT@v8M=VkUixG|S6+`A(#UJ)QZV|2`6a?fFO%%KgKk84oDFLu%>60+Fshl>~1 z0(axfDutdbu`fY*vXv zFD)>=X+;Uztb*3&Vh*Th7E}Ravc} z%qq~tLw4Nr(8xl8!1y|wk47K`tb@s!6){F%ytY_ij486Uj(BYb_Bf*>MLS)E7fP8T z#!HS?FSX?Tb?F%OO|t@1X$zjSQZh}hg%@8^xrANm1&Epc2fYVkY!MXZV_I6M%ED=^ z%$P-{lflbb6b2`03T0Hv%3;lXF<0nxhE-Nrq!bXuq1H@=WpOSP!v`*IN;3>xH!hBF zanpgB>U<@x9Y2`JmLfR(4<2A^g&%HKAt+_ZQ?RA_{Z%PwqGhpMd9f0TjAV+LYy>;8 zA-Ec|mB!UP$Y(ytLx&i2us&vNGE11!@N5N)wz(7Nz?dYo`sGjC+zGVVcP1*a zU)knPpbKf4Xu^;2ZSDjr-@Xb(&*ika6X?WiB`9`rbelVYmZfh%FP;6c&7DAVI$lBH zuPtbEC(!gAk5PbRew#aibSVVtnm7kZZ_ANz{2G)!^9K~D-VYc|xVsxgEj--jP9W*X z4Jdi@@iuo@%NF{gX`KeQxf7_@{!lcfX&~|*vji2n=OEs*1~jv`9_n!!e-AB;E3v-g zey%K1;ePG~Cm$x6_`d)&%tY1rp8)W~@LG^@bny6P@=sI9FbyZOCM{Lw;t1s6PK)IV zRUVE*ENAE`swwzcZKjnvOJ%uF~P)MK_RXq1y1IF45URmJo@5e0Gut)Ts!IiGguJGR80VvGJr!&~*fjR)1Fk^;~ zJzz?f!AtluRD(Dj_Ev7}UJEI-#z2#`bDipO`g#*h-pwT&aC%__O`MKt#L2vRn%FLE zhFAB*$fi1)^L&vLLUo9UtF5NV-7tMcL||nVO+H2FIU3#JF3vGH2{se0Qvb7NO7WRdZ!0YQ7<=4B_89M#G zKVX5d>~DR{7PQC9|Mqx+;SG;=84^7+y5e+F8lJ_#Sk^MT3B`Pkz5stWZawRlW!6fdp{kk1wQ5X_nub?%qb;;}(63 zuA+HOPs;C>)fj3ajVcWloCm*`)f?(DRo+xVmHqap@i`{$HB?YHuU0lSV&Z;%1$FgC zjiH%_k-V<9g7@&ZJM{*duA$NMstV4f3pF$i{j}j(1?TSC+cXUWd(+bj&Q}Yr&~y{c zZK|tlY!N2+QSDFoFG~G;d>&q+dUwc$l!QYTSchiMh%&Vy2moEMJUM(nwQN8?0 z1$9AvsHO=B;`W2e3ToZ_i_Ms#Dh{43e^xjU& zHRD%ek8hn1&o}RP*0IFVp4C2_xbuu>i3s^E*hO%d2vf1Zb>_yFwV^~_z(eopxL4mRjhNr1bBQ$O_%sL`jE0;8Rrr;;RYXGczvf^y_9J2F4T89NXR(7H{P5xAl6BWv z2j4UJP<7R@aKH=ljXWX)DtsMNRV3_RVGpvJGFMW5@Wut?ioj+xAaFvCF z%O?iQPuH@6t2GEY0aLFU9XzB-NQEpiI(T}6kQ(xtF>sgG3#qJQY~T`m{p*B0|0&Qd zaO4ul`&A1$DLC|MY2so?m5}4l#x8L~{7lFZ8-w?c<4+sQW2=Syfc_D3WAGm7BaB#_ zR3+pOESR^M4PKP`Sjf*_cG?ua;wM6?ujWuK6TT|~DuvV_WB8I4n-iW2$()wxofTd! zr20)gRLe$h?Tx*P{RhpHPHqkFM7s-vtLc>(<~$>>|?`skwNIvSGE<0?}m}Rg<*OezSzNm zAV@Jq@KUuog6|uIlt^ug;4?q}!A9`+LZN7)RRnMG&rmEsTgyc7x|NH!{#I*>;L|1t zSJ&bQMz>HE;(70Xwll(ksD(7z0F&N^^}YE-J*I9o(NyJ}j-2P1SOJlLW0D)yh>4PV znmQ5hNHn8rM2vzdKCfx3Kc7G_`6m+Us%g%-{toc(frtoxS_K+q@PF1Y{qObg8O^yp zqc?(iFV`=@jpKc-n&v-$`o~5|SA?1oH|05ff5xRMntyH0?3er7V;(yHnC9;-9MIVw zv;+C@2~E{3jdy4Qg3vWo($tk%{YXrao|7&-rO7>#&W%8EI2{Ksx?fFG)l1?X@b>{O z;ovuHQ&lZZ{XVlV*$7j74&~Z+-0eD=+%>6F1AHeTIfEOaU51mHZVg~AIs#MsN9EA$ zvS=rm*w-U87T{_8=B=$y8fkJ%Ag>93pK!cwpm~?yP72A|S>H^P-=sQYHkxOkU1~N? z=*;y9l78Pz-&-8#h`&}4L^TLb&IpD#EL`sh%_j>d`BBXGjjjfodax|by%`n}?0iDQ zeeJM~{1}>kxJ}U$V5bNU7rtpVAfBx8*lJ~n!xNlVs&x|r90;7|IQJjm!>xc6#c^_= z$`LK@HYhzSJAIH?9Fvuvo)se&1D$20f$JMNEGID{B4zBbNU=CEF+$AJi8%}nR|lMm z02=Z&i`^JO1e;BaGyAft;R=dlpb~~QR)nkbWdx951mlugXN2sY*aED|SkrJ!8^m^O zRdDq%*}~eEI&N%oM3b1GJT_S@jz}I$iz!@fv$z9pYDP4+gK4hOvexppQ1}`f7>U)3 zt)Ku{##+ zi;}5_;Hp_qnLCEBNfibI8jn>o6&mT`#MtCUF$qW*#O}##j|Gv@ZR4=}TREQX1kGYD z3k5Cqgvyybt)XD#>4VsQUyNwo{_EZhgy0`hy1G!h+CG-=UO3_Q zi>F6K0oLqol2a5-fN4R?f(K`1h{RK*8h)}gRi+r|{Pw4F&U~3 zdZtR6ICDgjc;*ywe~I(pK^DPTL0Rb;=~9h|pOr3GsDrWwI*TOAWN8qjG1|+SPqApG z40H~~1pe6Acz(E2CFT2j`gw@GeSG*rp{Gwjf1%K)FW=YO$Jfgn{)HYs{et|3LB0We z{pCE!0#d;$NlH*cM5MkrfCf6JX*3x@US89uPxqYe=c!bsdinJ4-ye(d_4NP_5A_U% zMwI2DQ1_&T8017q)nb(_LnBiv_*kweS(&LB=0Vi) z3@;x~Z!e={$QTSZ2?|$9MH;0lNvV_%qH7+Xrqn3aY03BeZen(-O|ivH@PF4F60xy0GBQ&pM&>}v~TSOubN>QrPMVdjPj10LCRQi!E75raS-Pnk>-q>nCOlZ{{~Ph| z5z(TUXqg&Zb%vog(!Nji$wcYY=2$~#mCL9;njuoDrP%TVoeidMIug*5a2~1!gG6H7 z?*@tS*dUbzdo{y0s%4r@_757Zg>`A!O|t&A{OM^@MQbAqEsEm$Yawc7ie|bW;VH0|GP0ACZY`A;{1Fv#1_Fev~3YJkR`D^3$BQl*kX zUWQIV+2v%ekb{spJ`t3dj{zRhUwYd!)R25plO^FJ2YjdA$>!Olo-Ip;Exg2I(@ zr7Bh_kq&|w^FDNAmkn+t$ApK+tCT4+xpa^^Au5a?GbCK-(_bj`@b&a*Dy9jaUe5a~ zPh(-K3bSM{<21R&NM;=B|C5Qv3jQahn#gJ^#Ka)2gKg$&-99GNHglO6q;;^(T&>&3 zgxY2<6N9u4wwbGS`a4z`)Ab^Dl5+stKRkk-LAbG2?C6Kb2eObpUG*k-QQ?PEf1Gna`$ zS_j+A)w+F5sBPvlF-YrRo4H!Ij|sKSTqXu-9c(jK>-I6BwwcSsAgzOK=4#zOCe$`_ znHZ#Xu+3bp+sB03W-b$hv<|kJt9ARBP}|I9VvyFsR?TJ6c<@xJfYYYa;aDkkE;Wcc zvziM}Te#`-xRx0zI5HWRsmaLH01_Y0Me%A)Vlo`Eq&Q*}8mUx~nT`oKjo;yN6^7eU zc@t$>m?KQ4!Fe#5mMK+@5T#3#hKx-D6kQmd0nP*{Qxc_`%#66?$zmW{p?IW1O885G zlfj8diZmz_WnfXrBE!fH5G5u|u2JYUvP#aB$u%+sB@*c76nA*+xMB1u-2qqx!vh|T zHE!Re#&Oh1RW;B%V$Sdkjlxg~sARIr2qdJcV~s$#N)g@&C^U`0@MO8#NEwl;nPvor zq{}0W0NAlnbeMQbs@@Q^l@Oej2nTJb!_f&6K3}5DOb$^##~M;sluFS87bb7X7p9UV zjZ$bLdnU+n+ZwMhxrF~de1cl8q44op@{j~0yTvrA7|!y+`BXT~tM3)@sqtzTJdPe~k zI48dJGOZ~rK6{@<%DY53ovQMSOM@u7d( zrugtbLe#GmP*iUUW)L(L>y0(XPMk*3%_xk1Ah`8b$8FeDRu>F1u?6V5V-P{h za`8fs^_QiP~f&5^JFA(N)IoYxEI7n)nzB zYxG4vkWoUTt6|kRYB(bG9 zP)nPR!4`5DtXp8MlBvPH1>O>xJc@I}a|Q()5VijzYuuZ52ISrcg4V z`=>+v#Rn3{jvLSCUWe{)4qgWxT_jd##3n}K2@8V5ihO)(k(NX~!P_eDQT~nYctpqZ z`Aum5BxxtkP(dIj;(^&u0>6|2>4lJ%PuFB%Jl5JFc?wQ5@F?S;0tF%638z!(bYF^x zPKV&MBwYa=oPl-Dkfcj+`ZAB9#Pwnf-%2r#3gS)==dUpIz4Q}3AV!2cOgQ@ZZxTnBknIvel|rW6?gcVHPNGQf;2^n=Q&dT zXy|1yO@roENMzJ6z{nKM&ipo!@GoX-A^|7qehmrxojT+&(G%I;a6nA$HN>*FM9dGr z0SaMkx8dfa;d2H;W1RBneh+D&Q_p4(#tHx#Y8e$4PJ8P6F-j0z@VS~4A(J(wQMKxQ~I zjyay0!c;NmFh6ImWo~C4V4h-LW!_;vXBIPSSR9r;i_h|44PZsHMzO@KsjNAyWvq>? zJ*;D_%d9)B999WS$F^qk*zW8gb_{zgJC!}1y_mh0y^DR6{WCk8oy)G|a5#<}S55#Y znlp|wnKO&CjI)_@kaM1Mi}R9G!R2y0bKSWExp7<(SHoS*-N5~hdyadXo6D^>vov!u z^EHb!8*ipCTVS@1^5Ga-^lqa-QXS%O5O%vCOfov1)JC$12?FL#s@y z?qwZfJ>FVlz1(`Q^(E`4*3~xlHl8*yHWHh;Hk)jY+1$2y)6Tq| zOS{l^6WYyex3=Apb~oA;+nU?*ylcFQZr!^@b<60sq1&Zy#oZmdhjgFZeNFeX-3y%Tod!9{oYpvgC#NOs^%qj`zxU?c^HcI@5K(>ti=-x4~{x-L|{k?ak>O z*n3Lv&Ao5-Vf69ulh$WbpBwHBccHt?eY5+mzU;pJ`zrcw?|a|F$|KZcn#X>R98X8j z;hqaTk9)rH5_paGTIqGwOXuzHE%)B({m7@i&rqKQKBs)%`S$S@`)=~R>u2p3={MK! zgkNbt_kPlT-}L*_-`+pge~JG^{{~@zP$fJdEC>(;ObYlq;C`S(V0_@Rz+d{a`-k

!5R$i^X0 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 kF_;Q7S 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/RadiusIndicator.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/RadiusIndicator.psd.meta new file mode 100644 index 00000000..7f9e818b --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/RadiusIndicator.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: fe4fd4da6245f48c1bcd64c8422b7b4c +timeCreated: 1471035768 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/RecButton.psd b/xiaofang/Assets/Obi/Editor/Resources/RecButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..d9cefe3daf49617e3be6643850693042e97c6ce1 GIT binary patch literal 27590 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/RecButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/RecButton.psd.meta new file mode 100644 index 00000000..bbb80a95 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/RecButton.psd.meta @@ -0,0 +1,57 @@ +fileFormatVersion: 2 +guid: d5d19ff51922e4539a782a48d6adf4e1 +timeCreated: 1458681621 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/RemoveButton.psd b/xiaofang/Assets/Obi/Editor/Resources/RemoveButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..d422e962a45311a3b735b2c2927e8a71426b5e12 GIT binary patch literal 29664 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 DL3h&1 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/RemoveButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/RemoveButton.psd.meta new file mode 100644 index 00000000..d561f91f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/RemoveButton.psd.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 8b56a65aecb4c42dea430c75690b8a4b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/RemoveControlPoint.psd b/xiaofang/Assets/Obi/Editor/Resources/RemoveControlPoint.psd new file mode 100644 index 0000000000000000000000000000000000000000..acf904406a7bd7917022f650af090d173da9f6ee GIT binary patch literal 32178 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 J3XCn{{{Y#|MHc`7 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/RemoveControlPoint.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/RemoveControlPoint.psd.meta new file mode 100644 index 00000000..da5349a3 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/RemoveControlPoint.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 7d2ee37b895e649c186b4de7004bd444 +timeCreated: 1478799645 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/RemoveIcon.psd b/xiaofang/Assets/Obi/Editor/Resources/RemoveIcon.psd new file mode 100644 index 0000000000000000000000000000000000000000..48f6bb12c7335e036e47d18eb9bf74b715f38ce4 GIT binary patch literal 26154 zcmeHP34Bw<)}NcbZMwHm)}|X}>ynnHrL?7OxRP#wji>JsK66J ztO728C?Y;^V-Xh?QCyHs1QqZV5dlF&5mdH(XXa+71mDy5`@Zk@%MJJ5Im?_m^Pe+w zZ)cdBRajk%D8wFoxJk$e^$l|dqdqK|dc7sCMLYpOxv|7XD#{Ts7wpfWql^Z)YqcXM9 zAg7x(WmAoG?bK0q%Bd~Np{m&7dHy-=+3h-mjy5YK?K&-E%5Kk%RjBlhbT*_hJ0(^^ zRLm{8u?1KlX{fB0$n{2Al98OAq)e4cB{EsEbV!CwCLJtEOO>Xjq{2U0l5|LRhAcZR zQ(`+}^ZX%|V^lR|*A$i5iUTS)w%KepWT&LGwY4R;r6=o+>J;hFp+m8mw6rA9NHR@f z%!>9T#uUdIvD+!4O-iH2VAkjv3AU?f)LYECv9Y)y$6>3N&fqABF(s2aCM)&2ly-$7 zMVg$N;;;-Ea{!ZUxsg_w^~O5AUYp0(yt-L$)|;C328p~@Ch1?PP-+;=7?6|VnZfCS z(-vK%Fw=Q}P(~7lC!*rfJHbvf|XV*~m%3FuTA`+7u(^!M{^;sFaS@Fj$OQ(&#E> z3azDeG-EbFi%8vDM5WAb(i?RObDqLr&}x(l+~_H-jLO!O27BA&q&QXoZm*%0D=Qt2 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 G7V$q4_bxyH literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/RestoreButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/RestoreButton.psd.meta new file mode 100644 index 00000000..6086b836 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/RestoreButton.psd.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 3b85a7a10acb94ba093952ee1cb68420 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/RewindButton.psd b/xiaofang/Assets/Obi/Editor/Resources/RewindButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..73b9694e23c2f4a80bfc8b7b439984ec51f029ea GIT binary patch literal 30935 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/RotateControlPoint.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/RotateControlPoint.psd.meta new file mode 100644 index 00000000..dc569cf0 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/RotateControlPoint.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: f33b6dcf4f7f946909841f077b4f1aa3 +timeCreated: 1478799645 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/ScaleControlPoint.psd b/xiaofang/Assets/Obi/Editor/Resources/ScaleControlPoint.psd new file mode 100644 index 0000000000000000000000000000000000000000..cb52d7268a3994aeb2374d77aed2544cfc4a5896 GIT binary patch literal 41233 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 U2=32T0?sXL75?U0z}1NV0}Bk~VgLXD literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/ScaleControlPoint.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/ScaleControlPoint.psd.meta new file mode 100644 index 00000000..2f4c39cc --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/ScaleControlPoint.psd.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: d13fb15ff13b2475b8585a693545eb0c +timeCreated: 1442227197 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/SelectIcon.psd b/xiaofang/Assets/Obi/Editor/Resources/SelectIcon.psd new file mode 100644 index 0000000000000000000000000000000000000000..719afb5ce9b9448602c73fd42199c37675cd271f GIT binary patch literal 25951 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/SelectedWorld_bck.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/SelectedWorld_bck.psd.meta new file mode 100644 index 00000000..71638193 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/SelectedWorld_bck.psd.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 01844e929694344c79f595973dd49a4a +timeCreated: 1440124004 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/SeparatorLine.psd b/xiaofang/Assets/Obi/Editor/Resources/SeparatorLine.psd new file mode 100644 index 0000000000000000000000000000000000000000..b3234dc52c6ab72e3ce38f9800106a9ee9fe2451 GIT binary patch literal 25656 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 F@jv?ZpWpxh literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/ShowTangentHandles.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/ShowTangentHandles.psd.meta new file mode 100644 index 00000000..91403965 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/ShowTangentHandles.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 913a0a12dbef54c7ca939f3dc86dc19f +timeCreated: 1478799645 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/ShowThicknessHandles.psd b/xiaofang/Assets/Obi/Editor/Resources/ShowThicknessHandles.psd new file mode 100644 index 0000000000000000000000000000000000000000..717c329e36b05e307cdff4497c6d18e619b50054 GIT binary patch literal 31848 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/ShowThicknessHandles.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/ShowThicknessHandles.psd.meta new file mode 100644 index 00000000..bb3842d3 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/ShowThicknessHandles.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 71c2b8c0a1d5b4908a4764a8beed8da6 +timeCreated: 1478799645 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/SmoothButton.psd b/xiaofang/Assets/Obi/Editor/Resources/SmoothButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..bce383f6243939027bf405a0f61a838d4ed7107f GIT binary patch literal 29579 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 B1d9Lw literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/SmoothButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/SmoothButton.psd.meta new file mode 100644 index 00000000..66ef2bac --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/SmoothButton.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 51e011fff1bad43078a63a1c71b11965 +timeCreated: 1478802054 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/StepButton.psd b/xiaofang/Assets/Obi/Editor/Resources/StepButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..049bfe911ae2d42aa056189f8ae8ec79ab980166 GIT binary patch literal 30792 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/StepButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/StepButton.psd.meta new file mode 100644 index 00000000..b6b08a1a --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/StepButton.psd.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 3a4a9652d5a3546a494c48ad14e4b492 +timeCreated: 1435831067 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/StopButton.psd b/xiaofang/Assets/Obi/Editor/Resources/StopButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..d601f8691546e368821894b106aa65dd32c18a33 GIT binary patch literal 26662 zcmeHP33yY*_Me-zOS-r0&`?^+)+H@X+t8M_=}KE#no<@KNR!((G`R^`+5#$zhzbab zifqaviii)~Sj2@@(I<~h!40&C2q;1kS(GLJGjp?3gU{#teE;vu4fozT%bYp$n=^B# zbD5iwU!_14Vh=vt#N_ltT$WWkC?mhLg2y9NaSv)N;&zYw^LGwH@DCB2al~fm_Ya(3 zCX2r|f7BW4s-HV=ZzQrvs49yA1YL&I>3_9AZ6u0WMj7ip-9ivq1>u4FIF*_+nOjOKG z*)e%oARb*&C6?=rv^Xs>H9?guk%*p0OKMdbk|c@A zNe;`9F$*w}$&IwqtT)!^_1YY^=2eY)v)%Vqf+8VPikh=wx%@L+a@c?srpxY4Xs>J;c&deFw*IgIto9N zxv&``(-!F+<}}qzG0;iXv`KF7dc>iY{y0 zCF}3oZ)v0%ZzBt9ifH}55tF{&+@dtnc?}Q;cOUXto9>xBjkDv0R`XwI0+X`&KWu=M zyM_0E*Z@*lvSU#GyBfe5xvEAb(?F|plI%fiXZ*ivv%8LTf3D3se31UXZ!@;{xsQPM zLEB@*{L3Efj^}X44?BnW&N-JuB$Mm4dSiuNP3OQfrX#j9WV4*&Qn|d!sIS*(=^Rsa zalW{;P%f2ZN~H-Yi4s>cE_yaQ9ao;^!c-Mz$w`iB@*N|YW2pZt6V3|$l~z4$`3ms> z#5?JO%R4?EQXgC%fOsc;aCyhaL+XRe0}$_|4=(Tccu0M4c>v;_^ugsF9}lSyE)PJw zlRmh-4VEV zJ|0pZTpoaUCw*{v$HznJgUbUD@1zed@A!B~eQ#!Sr zDiDp#$bt;m6bdjnw1FaK^0j8h=8>q*qS2Z)3^56Ef1)j~7*odX(j9_La1!9+tZ}$Y zjVsAcRTIcNV@&5i0TGYg@ceA8M%{S%ub@bPHS>VhBug-9Ymo{Ti_r7 zN2lq0Ra1iv2o@y-dnM%H4cWw8trm;bdP`ldz72awj$$Ko2QOcHr(V8MT{Ds~7xk&u z;YbN}vR&8#zLp`9GR>59A*q;i!d2LZq)lg-!M+Ht}Ww>LvQ8``D zn(-*M2Da&TRIEa!W%*S`RqhyUfgGVKquwwIw$WAL2-PqRcKCv^pc;J2*PG3HomS5@ z*s_T166}HtKgiCn)-*J_3Igo{@Xeu*`wI6b)(2DqcM7(B+wPf*QKA~7k}<(XMw(Gg5$0(PjY_eEjmRjXkpkBsR0C13L<}-PtScc+Lt2HV5Dh<+ zhqSCu-^zO&DXL5!-MT?*3z6YK@2O|{x`JSb3Z zV)uR?}dAGKR2~FR`Uf`;oEjJ3a6Z-6Op zf=!8HygQM#M6S@8t{!9i;U@_tRbsJ=?2jbFR0bnFaH%R#PF2GfF(5q~(%KfY0rRof zk#$Wt&A}r>q!Ap1bQhd%VAF$$4x7%!X|;}l0Ow$z4Qiblr}skok!A}Hd~P|U=QL~R z7D#^z=~%5rr-3vcQzLb>5;`LfV-{jSUKT=rq6U|AolDvb5eT|S zt~X2}Z6fZc>Mw@Rfn5MLJx%e@tny#nue1;a+LX^RD44Ru!Ysi;gG>qHcUKb00GMkG9oMht~5)o@}qsR$~ zDD+??;{LQB@gf2dcieLzp&ad2?q3UkParfZ`V1TQkOn!qx?MO6f#jGpC_p z95s-F=^K?p6;kC?H8qBsNHtIlWufk)9;D_`i>PJPYHB_88ub>ni~5K+x#GY5B@;Dj9$oP<{A&W!a2ss#XKGZ+7Z>T&}8Tvrz^3b1s|?eH%@2Dy?4z)=;ll8~;f3Mq@Y&(dhwlkL6~T?@6CsaKMLZa>Hsbw=(~*M6 z_{h@8Ns;p+{}Fj0vOOw1YH(C-RBP1osCT2YiKuxnG-C%SI!dZHVz+kkE(y0vtBuG{RH^=&~s_eJw4C&>eMT@*Q8!g z^?I+@x#)=KoM=t-Q_(x3e-KBB^Tb;567gPfd+#2-OL|*+ukL-I_l=nNn2|BFVm8H` z=o8QI-?1tDc}wQ(}4Iti-K}7m{L=#wIA}wp{yZ%rts?E=wB2d9r0G(lbfffK zdTjc{^cCr!WkhCFWz5g`Fq5B|pE*7Aoy=clQkhxyy6obRgdt5sULJBbD?W?PTAOt$ zJ0@G1y*j%sN1QV;XH`zy(B4CpL)Q%bHn&f%I`_rgGkN{Us6``M9F8RJxf)k>r2~* zr4PG**xoWxnWAi2*|+5b%8ljQD>xOyDxR!3K0IzXGkj|$sw}O1vhqY#eAVQtw?_y@ zRE=0Z;`?ez^?lX*6cLIEikB5vYw~Lr)_gUx-$={I-L)aL<7(H}UK>>~YSE~+(MhB4 zAN}!|ZeuiKwv82ztsVQ~*emxG-t+W5r^ls@n=|g%z47<9-uuz`ZsWD%-<=RLK{?@# ziTsJ9CcZrJrm|AGMtP;Kv~ERRyGpKlM)jjQSN)Xw9Gy)sqR-T4*DtC++mPMxWW%|} zp^b|h&uiqGWtvNqN+zwGbgikfXKg zsV_|9O;b(VeP8eUX5M%5{=EBFKR`WD_rUJyeWuTzetJgnjF)Bx%xs$ZuUW~n7R~zQ z!BG!xpWSozjM=9iDt>6goZvaeIiEc|5mo=C>tF2l;=C7ctz*`;y;S|u-u3D0 z*T3B3<%JtK8!Q{ny)y2VL;ooF$F_|L8&_}Yv}xX}=vB+BKfE^awPUZBy}tX6j5jvE z8TaOj%@LdDZlShJ+0wqXackSQG20HmHSDe3+lOr5{C48o>)z@8&hmGo-d*@!z{GW5uiq0MS;hrB(|7iH}#`!rvh5fYR zLca@dUd+9?zkPK3=}X2-)}QBJ?s|FMFN1&CeWmKk*H?8{Z(N&uz3cUte$DuG-*2OS zJ9DGurts#HTm5fszg>3wxK(GhlD{<~$!q{m2H3y!@eCSq1K@(^6Jpyr(e~%a1=Iym z*3Yd!ArbjJ-2{0B&=*iJp^$n8=u_6O&}<~~^Yiof6Z!j#!U6*V!=ge&qL8RA5fM=l z5naMW*9P3_cD0s<-i3uFwFh015;_&zap`U+1Amu59)iJJJ7>Xz!#pUoge4)UP&lRPD zFpSIV9WLSLjZj9!OrDt{htYd}QRe^v`e1-t&p&)a9c1r`A67=F@vW{qC0+Hot%L^p)EB<~fUB-15P( z@2{p8k7{Un_?dNE_kDKeS{UMRz*`>iNhsi_5f^$(!g=7qu|v1-+HdN0Fl61lxxcmF-1OGkcO=u23SPVV z%lxuIlT9ZSWhm9W)*P_ExWewv)Ht+%aX`4#~yIQ(Ie`Hg(=_Mb<-C zMxLB^{AhPse97huukRnW;#ybJJWJg8?=r1u`;C4o$6b8i>!v7)*9@5-(U3$19IW%{zHAAY3Eb(S~N9t%CT0F|vgbNk9q zw>N!t_4UEU z8&nF%X`2{>3#@=(RMWKb)a(;yiHJmI|>) zD6dH2x`Km>jHOJ63w!ol#0F@QMZMI>b%odp80mO9(4LF@u~lSpTla&qjjl`ksK``g zw3m&S4DHs-<&2AuxL(zIve@Z|%f<)6U^Pkh(A67ZRfM#^OP%d?_lMy0=aF@FA!y;V zD>?auHy6?f{_?}M97b#mv)+dETwDSJ-@>$_3?K!E;DV#e-3IGVKX%<7+w*=36^%** zEl$C<6?(ZI?16V3v=qS{-pGmFmRdW0i3BV0L2Y0K4#!KRkuy-hM8ZOjmq?5lQ9D`W zwDql!i$m6cK+6R+*GT!DcR0a1rO8Yii$*J2G-g$!eGL;87!{4~?qUv@C$A`IMp@@j zt$-I`_BT!WTBZVfTA?*#Ebx2CKT_-X;AP)T#QH9^j-0u%`zpe6*1G?kpMxf{yh?-0 z_9_hCNmcJ;nQ*l9)fvO2NYwooiYm}v5@ ziP)1Ho5i+1#c{VGH&)>mCpJoqQyKgUl4P-6YK>-cc$jw%8op<>l?JVbo^j)mX2=fuT9$y1>sWRlgJE$v@1`;<{EgnTu?>V zY;|b1Vb{Rr)boehLikVpwiai zR^j1_V7Z2=$8AHNYnX0gn(+ATptUALy&J94V*3u9a2`{m4wq2^CwZf*vY6~+@L=FM z$6-JGQE>bjYOD#TKj}#|8Xb*0Xx>pe|N9BypRj?*q*Q?h_Ji20Z#Cj^G<0VzT;a%# z8c7bej?JXbz@7zmInch|f1Hb;dI<;0f9(n-U{CJ)yBL1=-ygJ8d-1NnKWORF#k>Cg zhj4~g#8FVCG?S>q>7okK<3;Su1-COIvlD~45ziytqcYf_1UCLZBXX_MgylFk{V=y2 zJ`HVq>U7ke{_vL0+fM}V{=7wix4c;Pzm~r@>W##3;$JkR>}i(oPWQS)-utB0{r9W& zQaE+umm5}+SbD;iXgU11C8!fiFSk&vC)6(|E*~cDxqIzSf$O!@@yo>HT59oeTf%hc zZ%a_e7hg8nJfSWhzkGGt~-Msg}vbOVt@ zQ>-nqF!^swP_a#y7gDSzlqmLcGI7t6EG6&8;!mP*r$M_Z*_T<&0bqqXVcRO7Pq7*J;+usTb*x7gWSQeN&|u6Xn33435G2W9GKq$2J0bd za<|sPagmNaWb5eC@HSU)d)MSa3$ZBKBLo-Cwv;04au z;;?87@qe@i+(`fc literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/StopButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/StopButton.psd.meta new file mode 100644 index 00000000..e0723097 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/StopButton.psd.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: d7f73785945ac441d9d2c7e6aea7c600 +timeCreated: 1435831194 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/StopRecButton.psd b/xiaofang/Assets/Obi/Editor/Resources/StopRecButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..2c3b631627b37aa539cbbe693f6871fb33a5f57d GIT binary patch literal 32128 zcmeHw2Ygf2`}euo-EBIctcJ3|(nZr!R`&o(OGhX}Ax+XYkR~BX2M97PDlU+X$`BPq z0a2!ih#(4O6$BLrs8B}>ZKZAKNZ#k1o1{so;ivxo@B98gpCsho^NjPH=lMS8oO^F` zPKZg!%0U#OUu-xD$cKlRG)tn4Nl4FNu?Usfi<*X*JqM)z>oWr(_=kw?0mQbqvF6bG zJDFRTESq(F=d(cz)I`=F%VM7&J+4A6mdugq1O>7pxpGYKy^lT#7RaSzf~Q1fgk`7` zWySKe`5IZy{7Jcz`Ew*ArNQIIx{j`htte5K$aG>sMTtVGjjb3HES9PYWU)}j?9gBV zQPIsA6C95Pg8YmuL83|{6GRP<43UI|hYN(l;o&2qgu?L01QB835usu5PZ$zDA~s4G z8xbuqy@JQOLTR){S{R$1lwxWQs4>CCI-NQ;G_<_De0X`}aFwPgG<@X9k=RT`LGj@-oF$qP8@o)D9;x4wtA( zLMz1T(D315p%%+faWr5Oo2ZeAbt+A+N~IV}N1j!z(y6q?DzzXnM<^JaA(qIMm@#B@ zsC|V_4?1nhlEgaMSU@N$1j7@R8!n8E43CY97#0>08y03|gx0jPkpbC|igjYM6=6tN zWJpA0Zg^O1#E95P;jr*XixnGPdpjzryl~!sWTjKnWMgzFhS>^sl2eSB9sg13kV-7s zP?u^HBJ1LY1aOtQ#vVj;W5JSl$gkf#F3F^vsP6fGMlN9!(=2@ zSm|J||Bm@COgz*~np_J*b)LC5(qo_W$sE~STdujYD&(Y(s>K?u3?n}#*bKe(Oh8-0 zbw~zd#S+}_#!B$qAd`*`wc&QUWnWGHaMB))E^XVY>R;P0FP14C%`CJjqV?BCw5mc~ zxmY8MFM@vX=qZo3X;uW|5XAyd#Ha~^{^~;dzdmR5=(C*x&6Bp>jQL-?uv@OfU0>`h;)n0K zETY&%l|rS-P)TKD;TqEwyR*xV?i8mdCT3|=g>r>#tTsC}L6DxDC=4Gd6oy0$54SdB zrDw9!b?`J7ZdKtfIn;8S{LoBhnd<+Wh0Xx~n^x^?IUBJ9#4+iF%P~H7QYTz?fH)?d za5=`uPU?iq4iLwr6E4U2*h!sm*#Y91bi(BrA3LcNE;~RRlTNrC<6|dv!es}DW6}wi zV|?tSPPps`ugv&8Lc2Xx?c7Ql0op3qE z$4=^m%MK97q!TX3_}EFEaM=Okm~_JB7#};S6D~VI9FtDC9OGjrb;4x_h-14eKMK6X+kTy}ssCY^9O#>Y5jrC7$I=zjF@i~aVFWRss(vBteL3R zDa}DZkOdkGkzJ(Cun>tFWnw3x)O8XQ3lv(5WKxl?%t9oWD3UA$;Mi$8K{BVv1O$x| zg1r)n;0@W#oGldyq^i<_IMq$;A$g^0ln?O|6c6hqXr#G$N?l67Yz5A(<&~h23cBKF zYZW@e&#F+wWn0u;%VZMR%Ln^YVK=X-S7a4sY0bR?m$5ROvD;{(tdKTi*K96q)9tF+ z9EpPFXK5sHQ?Ui|@|I{+>M5{|E(`Zixw6O%pC=Y%gHH)6olaGvP$`Q{Rou-I?1B~F z!_3c?7ZqCz+{^;-&7zOT3bT&(0j0s2f^FZXGZ{w%iOkc~D4fPErgw!i?-HKBd#*;T z)WSwanNl*38?R6oiv{6ykMt)R5peWCxzOvyNQt!2*TqnlL0N+45e*)SM+)E3<_5SYXp+(?6l`=KoGAj8GJf2Mc?R{l-Ih2GQmb zj%nUu#6d;)m@vl~M2P%80nzP&NhXe;jvSK+@=kwn8QZmgS@Q%S#2=fNwSrk-atM>k zQU#u`aabJKr>~T1?dBng4muv~CLX+&5duuR5rz^vN1_14D7$l@VVa|b9pW;rNHGyl z6_iaoY$5|TA3j_{q$gRm#VyjPO4T+jj*9GJHeUsjbFg)KTQb=25SQvysWPQZgSP|& z1L5t&CS_Mz8FR2Cy`)G0r~m2rnXska=2A$&x8-DLi)=5K9I--|D=xCp@|4IFid3XeSucs`q1_hQY`|gf+ney7;6`uN)0y}TAB3>?5cpN`XR1+0h!t#;=4iGi|y6P z2pWtVf;$Q5&g1GynVxUG2peW^_q2&}rHTRFzXYzncspYL)M*0l1?c`RFzTSAizQlh zMotR8T|ux_QGoX>(w4{(22=AjdK_K}Ny`!ltYrU5(MO`zz-5@q0_8|4{7wdxmqS@m zu2W+^_S&yt4lXnB%;2X12cg^@my77~V?>88$KkTHLOQg7b3d+xvmEw-i zoCxL0GP$fA%2%P>Ur|~jhccd1{YqqF7>q28S$~~OQViuVD7$NNv*9|<8jTRoy~wIu zU{%&Z4+LG5s8Y`(IS~w&3=zPOgv1EaWaSE(P8X5|zkMRsNa2@BO4MQ{T-E59aV^Au zXg?@n(+7t_D?LX=oLgG{=VX#IDxj*9*IBcZr`is4GhDxzFL&|^HX?NBX@t6e+sW&{ z6>fZ&BXsbhRXhQ>zgYcfid-fcjsdm29;sl_{Of{Md&6;imc6usBzg!7aIcoYR^3vK z0Pa2{GC_!aC;rD3t=zKmz<3Er zhE`543n(!=S0E|Xl+h|Id}700j~DVofv6AahX%v_N(72Vqfi`5M&nT?+|^A*Pr!X# zF)D$3x^lDtEkTuNC3+dHMVrtTv;*xzd(eJ#2pvP8qR-JebP0WhZlIg!Hu?kAqh{1b zQ52W*pnR!7Du^0D4WrIn5I z^(A$g`i8ni{YEuXtqdl^o#Dsm%^1iCWyCPz850<}jK>*8jJb^YjOC0M85N9$@qiO#6(OtW&pD$1ED38a>nYartWB()tb?pmtShWrta_G#?ZNKF9>$Jkr?d0f zMeK5RC3_wFE%pKSY4%s_+w5izhZDdV#EIslai(%+bDrcp&v}irmve%1ne#KJiOb~% za))upa5K4Lu8v#D-N=2H`w6$2dz-80x$%N{5xf-MG@g>Tl(&xe4(~XxnpeYXbMbZ= z;1cVS=^}NR=kk)v4ws`Y7hP_J<)xJd#U@2?r*!FaR0{rPY(}|fgW)l(>!z@FM90q z_{`%6551?a=Wx$-PpRi3&&{3(J*z$MdbxNF@QU|(!fU?QID$jY(O2TT z%y)3*~QR{Fi?cfqgTpYK1yU*uomzuEs||C<5KfPn$&0g8Z^0`>=7 z3ux`uyIXuWS+{4q?dewCt)+X= zdzANhy~pVuwLSfMj_N7t`CQNaJ-_Y6=ry!gcCROUz0s?xS5xmky;FOudvEOhS?}6D z0e#~7%FQ~Ck|ga{Lt{bq5VUrg{}%c6KV*H z3R8sb2)hx^4<8@CH2i3IW5m!1NyO%etC1d&DUpjJ4@WkP7&byS;`I?9v&L>6dvjdhapG~?$Nd!7FHRcwR$NW|koej0 z@5bLv2usi;97t$Mj7?macp{0Jl$!Kh(uHJxa$fSLIs2PXi?V~SoW`mK0e@w(z#d7^xiykU0Q>@Blf=48%!dyY{tMX|SpS2C;Qh?1|I zqdcYRqpDC{Ru5BGs&CGXox65!y=H>uEiI*eTzgpO2RBnyrGrbKF1=MYwrq2mzFbuP zL4{9+vZ89<(0R|!tC^oN|IH^^PfDIVxuEZYB@1pXj9<9zDe9?$r%o>Fw`lpI+lx~d z?_A=#WX_WFOT(6~UV4Aolx0Vk_g=nu`Oi(|>-w;kL*aQnJ9IB%4_ac75U$C)={-rV(8kGEF7 z)$z9S?VCHZcb?i6y=&Jyz213gH)D6{?%&>>@$RMflHNPKCuGmIy#aey?nC=Z_x=9< ztoN_&pRoVr2QeS)`EbC8uO9F{@Z3S_;JkzNhl&r~JUsRAdktEVQPx^Q~J=`TJ{`TVmp z@n=5yV$2uEzKs3y$k~{)ht3Jl9juC~I&ePf{DBL?3kNSoUp#zi0QGCKK=LG zf2jXxtF5f_seASA;JY8*i@R4Srh6#r6j3q`RdDieFcLVrlfPT`)chJZi{{;ZwPY6t( zS@h$Gw-4%$DC5`0pWO4|hfZc@WoM?OPfSMehl79rOae_gpGnNmD$ZvT=Q9Zmh=2HS z@eiv(gVrzSGl}z=#Q99(d?s-|lQ^GAoX;fAXOjOL&m_h=HF$eqXIx$xXwT-<%!T-|*9z1-cs{JZ=5`uqBJ_i-mL(}^bRkCca-n}?@| zx2LDKpQop%A3k{c(N%o@69dK*$cG1yMgk@kj2J!?(}yyC58o^@jHjq^;3XUWKTi<+-@JQT9UkHlAq~dLxQOF&Qido6F&`neLGw^kK64^26Ejlf}NlbC*PL z{8nvyKcQcL|Lji-B1dSJUQXl=Se;XUt3jfT3fR7X*}$Y%a;3>9-_QxWRpoqMt zh`|7FS;QwUhaE*+=o`*wfd_Mgec2I9R{3EMKFz*dAKAa)mS*Yd#2kN#c0|Jf4t9V$ zFzRGAIPpd|X>y)WC;Q3b!e4tZsM7`Gx5%AI+Vnx=P*dK<6-_I56cyfB_Cm$N`x_c{ z3q#X?yd`|IX{A^6s2ww3SSEj~<;8E6L9dDKop0*4+Hhdm+6Pyqm+mdwbo0Y`eNuW= zMFeSA^nWU?%y7(z-nn*X6EKCcBvPtsPo#1OI;fl7`Cmys(F0vM)ASx@wj~_O!Imlr&A-_e1T{ zl%7r74{5w=Mt*YidcO+`#`ZeMOZ(;6j@E5$KYnNUX`hz+*e|SwOoo z-F5Z5ORYb+&A9Hu@;?i9R@TNI-SvgG<<_#JN4*4wKVExqes;Bf(a2@%Dia6$uD?H^ z?Z>NzH>Pj+bo5(-@!PI0`hINrUCEMX)XR1nntl(;F}xqWyI_7myf5GI8U`6aV;@hYDJo)-(Rkv1b|KNp- zcNhIQw;#vlr&m9ox!Z_#Kv>_<-%j==9X=0_Q{4BxV9|#ZmO&N3QV;=rT~Q2W9elK; zqy`P&M`#F8A}pX1VuN%G!B9k0L`DW03I!hGQhc(o2!<8#dyoZRxak6_r=>ib8f?;G zfKE7BARqu84HZGk`0pR9SIEi209z5Ts)^26sNl|6sG-)eFetMPDuU5zn;3%w zd`pZ`q0jg)JziUZLP%dCR?5?}Q?j94i}~@&B)p8F3O?TO!FAweT26sILh&g%*57iY z6ivFa%f%1oTEqruk%bSDes3pZD`2GSB@^aa)$Q#9tb@v;iD z^@)i}D<5%O*($OigooS4FM`1~QtVYysDW>eN&c;3HplLM4E~yxMOGx?`0)p?KQ zJ4cnM0(*GqSb1&A6u}(UG74;#qjbIe4pu99+ypD|vMj<Z~+15f-v6zf%ejb%I7t zQCI=B8033$(0aIi(o_Co^_ypjSgVt1Qu1@k=}Lc+N-LxJ8i}=jyiyl$UPg#=HOd@YD07O{iJ%U%9xPfZ5eQ6+X}D-2lEd0O z8Cj)A>?LZ-1g0^?u(gq>$-)^YHqtcnm3Z+csbV^aG&+ej@6om6R5vXK%(bm}9t!b1 znFhXgm&nBQ>QjIi_k9KQ9vEZKLuD?eB_+xnT*k&sDpIW!mWH56_%O^v8CB47SjW4X z-QWEZZLFkJA)u&FY?*TF>TIZnU%0xtOc=OrTpi)+<`-tFiWInYd|_gAR>4d6j(<$I z3jdjm5`}EKMC)n=vN8o!nMA6YeFQ(TBe)rhm!`FZpl5k8KKX>8gYA(y z&LSbT;U~_45ey%)3KGv}^c;oNV7emn6)w}Qm6d4cKn7k0lFR`3>h%{ddgkj|=ngKC z!DJ_VCW_Gb!xyL3LOV}GXWU`x1;^_i}Nxwww? znXY5c#Wd}ky(LW3@z}Rc*TGR@9s4s~$399-Q(Yp1F`>sysS@WBUxT=CBZXJrs>#im zX$3C)hfErfv9xfB!MRt=lS?rTAM#z0L{Wfy84D){%jL>K+}E(2&~ub?@b$<-E41oD z8(N~k_APlQ{j0bHw~+=PvbI-Jsx@CzMgXt#y28W%Jrw>AiLfSoT*%CjD=(4Z2`B!m zV@h`P^<=uoDv=%5G<{6LyxQE*@7fPuu?MCJyz{ZHVtwvT$8cJy1n(;zrV18fkN+nftih0nP!x8JF8pD?*E!jc8FD z=B5&EDs~vkSUZ)tN?S=K4yLt$b#R3=+5(M28Qj?i?&ud=+#wEw4{6xp!#qo5dK_6A zjtrOtg~Jb_fYCZ^gO)9tH8|fmFMso0!~gs5f7p_!=5N3MVM`4)fBWt1)&HONYM65H z43s6-kr@w{Q!?v!dUU(^=~;Dg^mP%@WkzAfG7A$i|hM)O+_)AF>v4Q((zADMEy+0bTuVC1x9^SixR z)7Ea}90}x)scJH`8(U#6%{K6v0hKjvFyS2ugtG8llcB@d29n9`d=8cvKMHK8`357t z3`}n2vw(j%u$9lo+D71_d_A8LP|#h^XT?@GV-B^q+g(1}Z}Og6Ofec>@UQ1{{NkQG z-hgRlTTNv^BcJORSNl)vQ;&U@8#k@CDL?+=z4M9lp4 zcW~aTrbD?9dIUl0!P0gS2TP0>rnl34g4u(mts)li&rNR?v9UJE`wG2?k-v1RUc@TC zOy~V%{#_9}ui)K3NZ#vTpHeU4c8;o1wu0F#W%&aUJG;;nLG$@S00bP~cX3@ll(J{6 zq9cW@R}~sWJQ9l@d^U)<*)v|gXvun2p@@#k*alJ&Ei+}kN?uS-;^l#CR^ckBWy<>H zcaM>5wcR=P?qy5X{~%dytN)|RtQ#8ZNUzX0)S0qwXl%H9p7b7leZvn|n(5JQXf!l1 z>rRu=uCIsk_3CCi>xRbm1`d`OAJn(gd;*!Fv9*B({O0=B1~%3vS#Q)gFzTxB=^I#A zO{2Z;-rWXv-752FKUY@|<`#91_S1EZ4cyvAR-^rN-Tel3?INque!8yN%rTAj>gER4 zHm!NIH{WY+VAj5E8to72??Wu7Oru?2-w4#_rqQmiuO}3pc6~ke4aWv)ZvoG@)`I6% zrmirwZ4a$9i-1bwdM>#Gz0u4|xWbk>`zudcF;_0v`AwNQ)Bdb7<~$JzRev5sz;-g?Ax*)Q^9 z!QK0W13g`+HuL~-T#g!B=LNFb5odzlcuD9=;ah3S<){HB(ZtbqQ;TW4X6o92hIxd9cHqtU2BM)TNhgXt_c_6#7MGduZ ztQ^WUG%tzdixrrZ7mD)*d8J(ZNM2c9emJi<<3?fcQJFcpnWKclxSY()oH(Hn=o}Lb z+@P58qU7l4wEXcgLSb@pw2-EgMTCZhpWzS$SrxAdv`snP91Zfbt2P#B$>Zxk|d zvmHWz9BS5R><0&b|@sJ@JC36qKP1BjObc`UgDGUY#k4=*XP4omRKebKB z03-}TpH#ZXg2T%eGpgpY_XiYd~H z=^91eBpqEgX=u50Qmr&e7M_;sF}NYQL8VpE28p0SrBv&a8&bk0GEEho3~9`c4i^v= zLv2cU1{Me^i%JAyjgA(?N5w@-V`5_kB2iTAz<7};c7Q+_6Dy34fj?1X?7-xBQL->W zU_QcAJs>q$C#y~_&B`$s2UJRUjlrNzj*hOcuaByai_+-i(XmNMN!W}~7zrAY`iW|T zq#;tR@4*xQk_C;P-xTwY*$jHF&a|B!*M~@!(1@ESA4TdICDo{+8zkE3 z*r=Fjt7XVI7%)i|>u8BVqbt{Fl&MV3OKLO*jlM>s6^P43f<8qOsX~nzeFsN7W@z)E z%@&;{G0>@iP<$kYC%!yZlpGhE953u2BTSBou`$AEI@lZXpva^7LiGlt2H{6#E>e{YLyD91UGtgomysYO0A`B21mE4K5DO_m5Yk3j<*{| zDphoQ;iorb*Fj{OBfZ_6`tpfdI=YnBYm7Q6om~eww1vAlD2s}c^VNETL@lNBvr@sG zD1}0n921)e-7sNbOoA{*lo%VEC=_O7W+Y^Yl41wO#K$L+$gl82;Nt8A^*z3Pyz8w<}6qBdWLsy+>iAJXH zlb9@{C)jf>!Kze{7}ZL2dKx325^jOsb|hdd;XI@TlO<9dcd1f5Hqf%c(RSQ6w;Z!6 z{zRiafG%U(ChH&Dudkui&PEo-6w&%)BYI7>pY| zfnHMg4;w(}&}$xb1Bh$}<^NX=&=$GU8i`s?%Tl8)L2F_BPqo=YN4me!Y5wRz`aj=h zOz*QF0WE{J!-)CF9_-fVaQhECtN6ipE~_Y6tWj!oMH(5M3eTAK*li&@xJ{fd7MJKW z)e0q@sxQsW6y#@%MX^aDQKT>`*4B)Tp4m?Om1nr{stRw((bm`G2SzgMQ2!_sZ54c! zRvm1)3UL6$Iq8DSIX(_j7hDd2I450jImgFA>VnGw5a*-|F6a0-NL_F_0OFio`MxEug+PP*W7j*o-X1(yRL&Pf+s&hc@O zy5MpE#5w7L%Q-#{QWsnffH)^za5=}vLF$6b0TAb;3ohsQI7nS^IRN6Ebiw5u9|x%m zE(buIlP3aZbA6a*mIK)CHFVAkIk_T+Z=vkhtS0d*_WD3_N-ojs~?=qeq2wj4z^4d8x2~c0hoAmE-KL*%BoRAB*5 za0YzN||LP0LM1dnbKOh83+a?1bZdK;0@UvT`Cg@WEx{ty5=nQkQ})>^#i<2<%4>e zI$8N}wIQcRsS>xX^~hAp1nu!l^-2TbmozBTORef2b+i=r^1=R8*v)H>iV}H=-Vzl! zjg{e!-A09UHDku1*mBsW+g`C{QYFJL(Mi)sVhiN(lj=0u5wMM}1V^YsEw{kug9WAF zQ>MmX(5RFewcMP=%Ob%p*zmnA{8ELy##Z2I5rA)2ecV^rKQlg{Jh)TvGv7%+>P=)m z=0f3?HkH{G&b~%?!CvJ$iCPaE8ELh2B0oc^t&s>~nTQM~8bY{wqjHFP2~s0H#JU91 zG^C|yBGGU|8Au8I8juK3ta;aYJdt&WD};*4L@0!0wuF!(K6W!(VN@zeoo*1q1Lwqt z*`_z);=T6`Bxffp-JRsRNoaR+g$qUM5rO*?^iJ#tIaoyZ7D?x!=;~^aDB;Q@9LmgD zxp;|{gE64cD7ad5aP26Bd#jm4Z2k^3!lMD>wd0k235y-M4E;}J1Pg4MZ2Bh@-u&N2 z#Sn^O@ZeytvELXEBhhvv9P_xtN{5VanlZ;Mh!FYS0nzP@Nj9!OQ*%rrBru;iZNV9* zEr%^n08D(^9kvPJqy`8)#!cLLtvv*o4m}KIw)I2- zh*4=D#Gm@Q9%>@sYf z*_I48yd_41CYM&zI=m$q7zl4CHY=q6<-6>`h-(wC`xo`nrH=ga77 ziIF@Y-0Ntap&j)K3)^1Zvr10(1=@h?&)Cn*wF)2$8mduatlbS7Exc&xY1=Gv4|VHjLh0d4&qKh6UlTf~POuj#xQz zlz@K#!rvWw9R#{Ws@E2k<>1#91X~pac+VnZiCm#G-9F0n!*3$5e!pXVL?R4wFvDX_-n50nWlc zYh@}KPVa&Avvo!s`0PSR&#Y6>^^pD+(mj<%l>*XuObt@e66lN^j9E_uEv`jo)%;K?Ot^yre;Mt7QuE{TGGW zZpW{Ug}<52#sW?yA`@uz<(JCjR?KS z#66@zPOf$r);u6tdIfnbAaQBAKx)+0F)AE<PhM;YBsfi zT0*U))>7|NA5ouDUr~pt|*vPb~Rhap2D8RUdUd> zUeDgf-pl@meU^QdeV4=I1abtNNX{Tm9%nd5%9+5K!kNQa!g-6cg|mnA4d)!^I;WNE z&F#wV&rRm$b1S)WZasGXbE@Ye&-XmP^gQQz*DJuQpO@Hcw3pFquGbo`U0%n%ZhCur z_x4Wr9_4NDp6k8V`!nw!ynpuz^ojDx_mTND`YiR?;&a63nyXut_`mJ{mH(vxen9Vl>;PH7jDXhz zJ_|S>$PVlgC=QecJ{7n+@bkb6LA;=dp!}fmL9>J24LT5XJvbnEU~olnL-5kzPlC^e zutR!>)xS`{B9h*A|I%RjN z?KHpB)=sB8b2|6yJgjql=hr%a-uY^mpe}>DNW0AHva!pFuB@*8x|Vi*qU-Bj_jkS3 zt$VlJZrW~(yM5N}YWI-t>D|Y7f2sS9?oFYAp{b#Y(3e7YhF%r~3o-;s!6LyP!S%4N zVR>Q3u$5s4!tRAfgbxp&9=;*`bPtani9M=&ywqcNkLx`{dlvP4vgf*y=)6d)?_B(R)PiXL@h#eJP@2M1I7ih;ocLxsy^TL<@HVMTif^5zK8m; z`o;IF>9@4s!TzlNqW+5hul7GYfIA>*fO^2H0mmY}A~PcEBG*NpiwcP&Z^rnHcQUSJ#$@U;H)q}vCyOVGcV)4&a!xYcVR$FMhH3bV)?Xgp%#Uc*9DDEgkk#X>93}rF+W)%f^Dv5 z8;9?%@U0kKv9{vQh^!F{Mx3pTuAE%CZ)E3@ijg0V;*Y8r_2#Hsk7Ymh@?#f9$B&*l z`sm{kk2gI2)tJs>lw&>_>pNC5cGEcSxDn&t9(P|-ELkPFRh3`0tm?W{EPX|KMV2mm zN!CQC&$N04ITwQA2 z(z@U4E9y5j_&2B<_D}3L@wtf?C*@3f;|b0a(kFI58TRC~C(ljJn7ncdHKl6G?#3RC zGa4^U&7JzzG>>Vu)4rY_GkwAI-<}%r)V3MjW=x%N{^{JO*Uj{qshfH1nL*Dif0pyC z;@Jbw#XYz9xz<^-S^t?GGkf9e`*Wmo{_}k7^NXH0&8?n$V4i5+YcKF#P`_|=e%k!E z7WgliwBY=UMK5l7N$}FFmwtPB?8{#*9Jp}#D;}>HUpc#|aM6d0doF%q@%<$=OTJs0 zxpc#_uFIZVcIQ>ut4Cf-e{KEpZp&vcZ(gBT@%_r&m0MQzUbXOb-s^R*|FpVd_1-rU z-&p%*=Qn4+*|J8x=ImRgZ|zx|uy*a+UEiL!j)j96N3LJFA!Nhs z_t1OB_b$Ib?){@13pVcFl(=dA2faR6wmER~tS!`*iCeC3t=W3^!;v2z{%FWYySEM6 zwt0Kh_B9`eeZ2IO;7{i5@Ype9hiT`eows&rcU}Ed{^|MMV|SnYtn#yO_YB)};PZmd zzx*QSi_i9E?A`fg%9kI1mHgF5|4IDM)_tOVTlUBA-~4s_*P9QB4s1D?aPY%JNr$!_ z9(;Jmk+dV9ev|dh7vJW8yYIW9-yJ?W{OI?`Mjt!-z3lr-$Cbx_JyCb!-pQ$_xTj{F z_B*}shps=YI@9;ehO?rxpPb7&xBthoA5Wf_p1<;6{eSOYnDLYMPYW-GUR--gc_viuTIAt22N0|9RQ9KG#0@CHBgL!oo=rAZQyUaZfZ2DSI_yzg+_ypmLPY{#E z|IZjO?Lz);Pyqp(3P&t|itSICPQ(BIEYlt;4ZP&SiwPXyFh1CbVsW@UzMH#;Crpvq z3n|26TZDdy;!tcBhsEXd+_-G7I1u`?Ibi{@+>Bw8!0-vvguI~nE8oxT(KER8)2g_E zy6K0-{9X&nuAlo=s*ev@wehLmSud8$vUk635Op{*{73r6rWv1oV?2K|C*q~mPk-?8 zo^SvA+Z&rd|L(%Ait4(V3*X%G#nGQ`C*+Qh*FW>hnyq_}UA*IuSS;|CLww@%xbeh= zu-E_&crYP6kSm-vKL~s9Y3bqXaXqWf>839bmjz4p1Apzs!w&F!$L~G@PQ2bhmOWf# zpntTw@W&oRw7Fn9fxOtHOn;Pyerdilre)rxDNh}{b*FX8m&Z5V4QX7R(UevxY~H%= zwsOevOFy5!JUaKt>8%CEQ+4AO?O8mx-?E+W zb{+e5_MyvXps?aMZZ8{h=8F1c)2ZUaC%4z#uba}Gka6YAmXyXrle*75c<{`iJ0=vq z^S9av6AB5vlY2Go*6G#_E$?rVulOK!!*9!vCrxblVZ*ySwkc0<)kK6Xt-IEEt(W_S zg(Vpu3%_q}tiRv*>c|PYLl@p~-y>c&l{bthpLsF#N* zDF-hcYki)-x@GLXrqm6`H(qIccWeFH{IuM<)7yoe?p=Q8+`^H0;n(*~Xlgn0YioT$ z$e2-GKajh->0jXFWEEaNb)jWsRqObn?EqLadFXILF*!PyHXPepcg;t9M}6Yp znSynb$L_oQ!z(9rSLCm6*R078El~e_@7n~LY((4IKM?6_opHRGsNcm zLq64s;QO0N$uaOJ6j;8T31$#`1=Z%?3YN7D!3uU;8Y{xVqu}2bxKnukw5={wcw1el zeztXCQ5GANkkw|J7=sJU7hzPGJ09bGR{(|3?<$E}kzblq3hAqupP|me6Po+s^n(-U zfx|qpiakOZIc2uxy8THngA8sB2Gus76mSe4W%*KSOQEu;Np$QQDEMIL3gD4`15pn{*c>4Fn3k&4WjGBd?yi_6)5~Bg8O6cLvUGUVz{p|U ze*w3r*C9qzWmF0fwbP!du+7eeZ1}+0Eos8Q1zEEb4qPx(BUj?m@#BltmIW{M?f8Vz zfR9hB5fp06Q!u&uKP(qi(KcHZU56WDD9L8=5&XoC;9{&^l3ZkL16Af=?c7Pw!S?JW zBsY8#5%j|0B&())>_h1Oy}9$lw}B79wxpTTltwky$D^nxDuv!4g;xQ*ZY+ltV*Gjl zqaC&j9}Cxk4o6=j(Gq&1LWXHL$%>>@S%quF!C{K!3UxKE7l}(u*Q#qZwzN{Ot+u13 zN^IZmnV_#x;WF~zB$SSo-&=N8>d{z=DV64!9H%T#5jff1E-^fD4?6So-&=yN|?cjDQ6X z%N=m(PjKlExcuW3>JPZUiHN0tpSt@qHcqV%gT!fiA3pT#l>amA`#GKW*WGmi9;%~6B6<&ha`$b+1UvqhR&`a zG+aG!DgkKFYZ3VoK?0*D!pfnHX}E&nbSQ+-=7Ml>p+o=)A{d!tuL$aa*aK|JTv7q1 zTSab6QE&~g_`>*>Ke946;l7BUTbU~oCFE9`L~LAaizpaZwPY~%gH+e-nZ5i$C_>E@ zOvL6z4p0Cn6^;%LDX?`AP_VBeE@7}e7WN>ugGHzf%2q6(Xo3aQGP|>-wzkeDBoHiG zL@2@ATrYE-TSVUWV36VQIS#CtKL7^fA!%~E*1~a-fIVdDXw&d!S8#im zXFv-vC|M!|7tOSkH84UgrZ5;#d2E^#Xr>FO%G`S*79i0o^3P==7DVP|8;P6WuHl&= zXc2K4C`_V2D4ginLqX)lgP1rlcL5UeOyFAzsAOaRT16chkZk&ZrSWhLNmWVJ+kt|? rsGUAwfx;38)^@j;wm{**^npCw2cSDb_%ofr5*FqT|6nh$^oaih4;~)X literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/TextureIcon.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/TextureIcon.psd.meta new file mode 100644 index 00000000..0821ef67 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/TextureIcon.psd.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: 931c48569a82e4dae84d4702bf6da199 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 1 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 1 + pSDShowRemoveMatteOption: 1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/ToggleableGroupBg.psd b/xiaofang/Assets/Obi/Editor/Resources/ToggleableGroupBg.psd new file mode 100644 index 0000000000000000000000000000000000000000..5a186cebac762f54d2d221d96f984e3a9ee8dabf GIT binary patch literal 24638 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 Bnpyw= literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/TrunkButton.png.meta b/xiaofang/Assets/Obi/Editor/Resources/TrunkButton.png.meta new file mode 100644 index 00000000..abc62b32 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/TrunkButton.png.meta @@ -0,0 +1,117 @@ +fileFormatVersion: 2 +guid: ca503dc9534e0488b98fc100f4fd1d5d +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 5 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/UVSpaceColor.shader b/xiaofang/Assets/Obi/Editor/Resources/UVSpaceColor.shader new file mode 100644 index 00000000..c8b2ac3e --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/UVSpaceColor.shader @@ -0,0 +1,47 @@ +Shader "Obi/UVSpaceColor" +{ + SubShader + { + Tags { "RenderType"="Opaque" } + LOD 100 + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + struct appdata + { + float4 vertex : POSITION; + fixed4 color : COLOR; + float2 uv : TEXCOORD0; + }; + + struct v2f + { + float2 uv : TEXCOORD0; + fixed4 color : COLOR; + float4 vertex : SV_POSITION; + }; + + v2f vert (appdata v) + { + v2f o; + o.uv = v.uv; + o.vertex = float4(v.uv.xy,0,1); + o.vertex = UnityObjectToClipPos(float4(v.uv,0,1)); + o.color = v.color; + return o; + } + + fixed4 frag (v2f i) : SV_Target + { + return i.color; + } + ENDCG + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/Resources/UVSpaceColor.shader.meta b/xiaofang/Assets/Obi/Editor/Resources/UVSpaceColor.shader.meta new file mode 100644 index 00000000..367df23a --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/UVSpaceColor.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 459ae7c4c81724f20b6810647d2dbd3d +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/UVSpaceColorMaterial.mat b/xiaofang/Assets/Obi/Editor/Resources/UVSpaceColorMaterial.mat new file mode 100644 index 00000000..9bbe0d27 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/UVSpaceColorMaterial.mat @@ -0,0 +1,76 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: UVSpaceColorMaterial + m_Shader: {fileID: 4800000, guid: 459ae7c4c81724f20b6810647d2dbd3d, type: 3} + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 7e271617753294f4aaf5d79862c5d182, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _Glossiness: 0.5 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/xiaofang/Assets/Obi/Editor/Resources/UVSpaceColorMaterial.mat.meta b/xiaofang/Assets/Obi/Editor/Resources/UVSpaceColorMaterial.mat.meta new file mode 100644 index 00000000..66a8487b --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/UVSpaceColorMaterial.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8d64d32033a9145218d8c42c02e53b63 +timeCreated: 1445287098 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/UnpinButton.psd b/xiaofang/Assets/Obi/Editor/Resources/UnpinButton.psd new file mode 100644 index 0000000000000000000000000000000000000000..46e280c5a0e334e4578b9183eb71ccf04d050f7e GIT binary patch literal 31753 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 W0EQ#DKRpP{Zebemtw(`*MEno##B*i< literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/UnpinButton.psd.meta b/xiaofang/Assets/Obi/Editor/Resources/UnpinButton.psd.meta new file mode 100644 index 00000000..a96c6e38 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/UnpinButton.psd.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 546d0fbcbc7794babadce998d53cc471 +timeCreated: 1478802054 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.mat b/xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.mat new file mode 100644 index 00000000..0662b1c7 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.mat @@ -0,0 +1,79 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: VoxelMaterial + m_Shader: {fileID: 4800000, guid: a5455d2f5ab50497d8642726d64b9cd5, type: 3} + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 7e271617753294f4aaf5d79862c5d182, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _Glossiness: 0.5 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _Size: 0.95 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _InsideColor: {r: 0.8627451, g: 0.8627451, b: 0.8627451, a: 1} + - _OutsideColor: {r: 0.3529412, g: 0.3529412, b: 0.3529412, a: 1} + m_BuildTextureStacks: [] diff --git a/xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.mat.meta b/xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.mat.meta new file mode 100644 index 00000000..344e7c4d --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 130b71128e55b4a3f9a4dceca6667bf9 +timeCreated: 1445287098 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.shader b/xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.shader new file mode 100644 index 00000000..55d1a82b --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.shader @@ -0,0 +1,63 @@ +Shader "Obi/VoxelMaterial" { + + Properties { + _MainTex ("Base (RGB)", 2D) = "white" {} + _Size("Square size",Float) = 0.95 + _InsideColor("Inside color",Color) = (1,1,1,1) + _OutsideColor("Outside color",Color) = (0,0,0,1) + } + + SubShader { + + Pass { + + Cull Back + Fog { Mode Off } + + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + struct vin{ + float4 vertex : POSITION; + fixed4 color : COLOR; + float2 texcoord : TEXCOORD0; + }; + + struct v2f { + float4 pos: POSITION; + fixed4 color : COLOR; + float2 texcoord : TEXCOORD0; + }; + + sampler2D _MainTex; + float _Size; + fixed4 _InsideColor; + fixed4 _OutsideColor; + + v2f vert(vin v) { + v2f o; + o.pos = UnityObjectToClipPos (v.vertex); + o.texcoord = v.texcoord; + o.color = v.color; + return o; + } + + fixed4 frag(v2f i) : SV_Target { + + float2 centered = i.texcoord * 2 - 1; + float square = max(abs(centered.x), abs(centered.y)) - 0.05f/(2.0*1.4142); + float width = fwidth(square); + float alpha = smoothstep(_Size - width, _Size, square); + + return lerp(_InsideColor,_OutsideColor,alpha); + } + + ENDCG + } + + } +} + diff --git a/xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.shader.meta b/xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.shader.meta new file mode 100644 index 00000000..d5800a63 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/VoxelMaterial.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a5455d2f5ab50497d8642726d64b9cd5 +timeCreated: 1445287084 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/Resources/obi_editor_logo.png b/xiaofang/Assets/Obi/Editor/Resources/obi_editor_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..51c3c88b6930b4c5e4100957abd33d22004f7291 GIT binary patch literal 14374 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Editor/Resources/obi_editor_logo.png.meta b/xiaofang/Assets/Obi/Editor/Resources/obi_editor_logo.png.meta new file mode 100644 index 00000000..464725b2 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/Resources/obi_editor_logo.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 8eeefc8d5c2ab4e0582a93f719bcd31a +timeCreated: 1471538194 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -3 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod.meta new file mode 100644 index 00000000..2f90f428 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 00c9b99ffa90a4646b360dcad1ea0b84 +labels: +- ObiRope +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/Blueprints.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/Blueprints.meta new file mode 100644 index 00000000..2d99c230 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/Blueprints.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 16f13a837c41b437a87aa83162abd677 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/Blueprints/ObiRopeBaseBlueprintEditor.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/Blueprints/ObiRopeBaseBlueprintEditor.cs new file mode 100644 index 00000000..ff5c98e1 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/Blueprints/ObiRopeBaseBlueprintEditor.cs @@ -0,0 +1,58 @@ +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.Collections; +using System; + +namespace Obi +{ + [CustomEditor(typeof(ObiRopeBlueprintBase), true)] + public class ObiRopeBaseBlueprintEditor : ObiActorBlueprintEditor + { + + public override void OnEnable() + { + base.OnEnable(); + Undo.undoRedoPerformed += UndoRedoPerformed; + } + + public override void OnDisable() + { + base.OnDisable(); + Undo.undoRedoPerformed -= UndoRedoPerformed; + } + + void UndoRedoPerformed() + { + // Re-generate the blueprint after undo/redo. + if (blueprint != null) + blueprint.GenerateImmediate(); + } + + public override void OnInspectorGUI() + { + + serializedObject.UpdateIfRequiredOrScript(); + + EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins); + Editor.DrawPropertiesExcluding(serializedObject, "m_Script"); + + EditorGUILayout.EndVertical(); + + if (GUI.changed) + { + serializedObject.ApplyModifiedProperties(); + + // Re-generate the blueprint if any element has been changed. + if (blueprint != null) + blueprint.GenerateImmediate(); + + // There might be blueprint editing operations that have no undo entry, so do this to + // ensure changes are serialized to disk by Unity. + EditorUtility.SetDirty(this); + } + } + } + + +} diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/Blueprints/ObiRopeBaseBlueprintEditor.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/Blueprints/ObiRopeBaseBlueprintEditor.cs.meta new file mode 100644 index 00000000..c5925c27 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/Blueprints/ObiRopeBaseBlueprintEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87efff4816bdd4fa4bda69ca33516658 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/BonePropertyCurveDrawer.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/BonePropertyCurveDrawer.cs new file mode 100644 index 00000000..8d240cde --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/BonePropertyCurveDrawer.cs @@ -0,0 +1,29 @@ +using UnityEngine; +using UnityEditor; + +namespace Obi +{ + [CustomPropertyDrawer(typeof(ObiBone.BonePropertyCurve))] + public class BonePropertyCurveDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + EditorGUI.BeginProperty(position, label, property); + + float curveFieldWidth = (position.width - EditorGUIUtility.labelWidth) * 0.5f; + + var multRect = new Rect(position.x, position.y, position.width - curveFieldWidth, position.height); + EditorGUI.PropertyField(multRect, property.FindPropertyRelative("multiplier"), label); + + var indent = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + + var curveRect = new Rect(position.x + position.width - curveFieldWidth + 3, position.y, curveFieldWidth - 3, position.height); + EditorGUI.CurveField(curveRect, property.FindPropertyRelative("curve"), Color.green, new Rect(0, 0, 1, 1), GUIContent.none); + + EditorGUI.indentLevel = indent; + + EditorGUI.EndProperty(); + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/BonePropertyCurveDrawer.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/BonePropertyCurveDrawer.cs.meta new file mode 100644 index 00000000..3fb84d07 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/BonePropertyCurveDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b78a1342294ee4644a9a0d6a247d3604 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/IgnoredBoneDrawer.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/IgnoredBoneDrawer.cs new file mode 100644 index 00000000..2ba8fccf --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/IgnoredBoneDrawer.cs @@ -0,0 +1,30 @@ +using UnityEngine; +using UnityEditor; + +namespace Obi +{ + [CustomPropertyDrawer(typeof(ObiBone.IgnoredBone))] + public class IgnoredBoneDrawer : PropertyDrawer + { + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + EditorGUI.BeginProperty(position, label, property); + + GUI.Box(EditorGUI.IndentedRect(position), GUIContent.none, ObiEditorUtils.GetToggleablePropertyGroupStyle()); + + var rect = new Rect(position.x + 4, position.y + EditorGUIUtility.standardVerticalSpacing, position.width - 8, EditorGUIUtility.singleLineHeight); + EditorGUI.PropertyField(rect, property.FindPropertyRelative("bone"), label); + + rect.position = new Vector2(rect.position.x, rect.position.y + EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + EditorGUI.PropertyField(rect, property.FindPropertyRelative("ignoreChildren")); + + EditorGUI.EndProperty(); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + int lineCount = 2; + return EditorGUIUtility.singleLineHeight * lineCount + EditorGUIUtility.standardVerticalSpacing * (lineCount + 1); + } + } +} diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/IgnoredBoneDrawer.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/IgnoredBoneDrawer.cs.meta new file mode 100644 index 00000000..f1da0074 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/IgnoredBoneDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f9e4bd0b2f9544e039fef4cd5d95232f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiBoneEditor.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiBoneEditor.cs new file mode 100644 index 00000000..0aedd61e --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiBoneEditor.cs @@ -0,0 +1,225 @@ +using UnityEditor; +using UnityEngine; + +namespace Obi +{ + + [CustomEditor(typeof(ObiBone))] + public class ObiBoneEditor : Editor + { + ObiBone bone; + + SerializedProperty collisionMaterial; + SerializedProperty selfCollisions; + SerializedProperty surfaceCollisions; + + SerializedProperty mass; + SerializedProperty rotationalMass; + SerializedProperty radius; + + SerializedProperty skinConstraintsEnabled; + SerializedProperty skinCompliance; + SerializedProperty skinRadius; + + SerializedProperty stretchShearConstraintsEnabled; + SerializedProperty stretchCompliance; + SerializedProperty shear1Compliance; + SerializedProperty shear2Compliance; + + SerializedProperty bendTwistConstraintsEnabled; + SerializedProperty torsionCompliance; + SerializedProperty bend1Compliance; + SerializedProperty bend2Compliance; + SerializedProperty plasticYield; + SerializedProperty plasticCreep; + + SerializedProperty aerodynamicsEnabled; + SerializedProperty drag; + SerializedProperty lift; + + SerializedProperty fixRoot; + SerializedProperty stretchBones; + SerializedProperty ignored; + + public void OnEnable() + { + bone = (ObiBone)target; + + fixRoot = serializedObject.FindProperty("fixRoot"); + stretchBones = serializedObject.FindProperty("stretchBones"); + ignored = serializedObject.FindProperty("ignored"); + + collisionMaterial = serializedObject.FindProperty("m_CollisionMaterial"); + selfCollisions = serializedObject.FindProperty("m_SelfCollisions"); + surfaceCollisions = serializedObject.FindProperty("m_SurfaceCollisions"); + + mass = serializedObject.FindProperty("_mass"); + rotationalMass = serializedObject.FindProperty("_rotationalMass"); + radius = serializedObject.FindProperty("_radius"); + + skinConstraintsEnabled = serializedObject.FindProperty("_skinConstraintsEnabled"); + skinRadius = serializedObject.FindProperty("_skinRadius"); + skinCompliance = serializedObject.FindProperty("_skinCompliance"); + + stretchShearConstraintsEnabled = serializedObject.FindProperty("_stretchShearConstraintsEnabled"); + stretchCompliance = serializedObject.FindProperty("_stretchCompliance"); + shear1Compliance = serializedObject.FindProperty("_shear1Compliance"); + shear2Compliance = serializedObject.FindProperty("_shear2Compliance"); + + bendTwistConstraintsEnabled = serializedObject.FindProperty("_bendTwistConstraintsEnabled"); + torsionCompliance = serializedObject.FindProperty("_torsionCompliance"); + bend1Compliance = serializedObject.FindProperty("_bend1Compliance"); + bend2Compliance = serializedObject.FindProperty("_bend2Compliance"); + plasticYield = serializedObject.FindProperty("_plasticYield"); + plasticCreep = serializedObject.FindProperty("_plasticCreep"); + + aerodynamicsEnabled = serializedObject.FindProperty("_aerodynamicsEnabled"); + drag = serializedObject.FindProperty("_drag"); + lift = serializedObject.FindProperty("_lift"); + } + + public void OnDisable() + { + Tools.hidden = false; + } + + public override void OnInspectorGUI() + { + serializedObject.UpdateIfRequiredOrScript(); + + EditorGUILayout.LabelField("Bones", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(fixRoot); + EditorGUILayout.PropertyField(stretchBones); + EditorGUILayout.PropertyField(ignored); + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Collisions", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(collisionMaterial, new GUIContent("Collision material")); + EditorGUI.BeginChangeCheck(); + var newCategory = EditorGUILayout.Popup("Collision category", ObiUtils.GetCategoryFromFilter(bone.Filter), ObiUtils.categoryNames); + if (EditorGUI.EndChangeCheck()) + { + foreach (ObiBone t in targets) + { + Undo.RecordObject(t, "Set collision category"); + t.Filter = ObiUtils.MakeFilter(ObiUtils.GetMaskFromFilter(t.Filter), newCategory); + PrefabUtility.RecordPrefabInstancePropertyModifications(t); + } + } + + EditorGUI.BeginChangeCheck(); + var newMask = EditorGUILayout.MaskField("Collides with", ObiUtils.GetMaskFromFilter(bone.Filter), ObiUtils.categoryNames); + if (EditorGUI.EndChangeCheck()) + { + foreach (ObiBone t in targets) + { + Undo.RecordObject(t, "Set collision mask"); + t.Filter = ObiUtils.MakeFilter(newMask, ObiUtils.GetCategoryFromFilter(t.Filter)); + PrefabUtility.RecordPrefabInstancePropertyModifications(t); + } + } + EditorGUILayout.PropertyField(selfCollisions, new GUIContent("Self collisions")); + EditorGUILayout.PropertyField(surfaceCollisions, new GUIContent("Surface-based collisions")); + EditorGUILayout.Space(); + + ObiEditorUtils.DoPropertyGroup(new GUIContent("Particles"), + () => { + EditorGUILayout.PropertyField(mass); + EditorGUILayout.PropertyField(rotationalMass); + EditorGUILayout.PropertyField(radius); + }); + + ObiEditorUtils.DoToggleablePropertyGroup(skinConstraintsEnabled, new GUIContent("Skin Constraints", Resources.Load("Icons/ObiSkinConstraints Icon")), + () => { + EditorGUILayout.PropertyField(skinRadius, new GUIContent("Skin radius")); + EditorGUILayout.PropertyField(skinCompliance, new GUIContent("Skin compliance")); + }); + + ObiEditorUtils.DoToggleablePropertyGroup(stretchShearConstraintsEnabled, new GUIContent("Stretch & Shear Constraints", Resources.Load("Icons/ObiStretchShearConstraints Icon")), + () => { + EditorGUILayout.PropertyField(stretchCompliance, new GUIContent("Stretch compliance")); + EditorGUILayout.PropertyField(shear1Compliance, new GUIContent("Shear compliance X")); + EditorGUILayout.PropertyField(shear2Compliance, new GUIContent("Shear compliance Y")); + }); + + ObiEditorUtils.DoToggleablePropertyGroup(bendTwistConstraintsEnabled, new GUIContent("Bend & Twist Constraints", Resources.Load("Icons/ObiBendTwistConstraints Icon")), + () => { + EditorGUILayout.PropertyField(torsionCompliance, new GUIContent("Torsion compliance")); + EditorGUILayout.PropertyField(bend1Compliance, new GUIContent("Bend compliance X")); + EditorGUILayout.PropertyField(bend2Compliance, new GUIContent("Bend compliance Y")); + EditorGUILayout.PropertyField(plasticYield, new GUIContent("Plastic yield")); + EditorGUILayout.PropertyField(plasticCreep, new GUIContent("Plastic creep")); + }); + + ObiEditorUtils.DoToggleablePropertyGroup(aerodynamicsEnabled, new GUIContent("Aerodynamics", Resources.Load("Icons/ObiAerodynamicConstraints Icon")), + () => { + EditorGUILayout.PropertyField(drag, new GUIContent("Drag")); + EditorGUILayout.PropertyField(lift, new GUIContent("Lift")); + }); + + if (GUI.changed) + serializedObject.ApplyModifiedProperties(); + + } + + + [DrawGizmo(GizmoType.Selected)] + private static void DrawGizmos(ObiBone actor, GizmoType gizmoType) + { + if (actor.boneBlueprint != null && actor.isLoaded) + { + var color = new Color(1, 1, 1, 0.5f); + var upColor = new Color(0, 1, 0, 1); + + for (int i = 0; i < actor.boneBlueprint.parentIndices.Count; ++i) + { + int parent = actor.boneBlueprint.parentIndices[i]; + if (parent >= 0) + { + var index = actor.solverIndices[parent]; + var nextIndex = actor.solverIndices[i]; + + var pos = actor.GetParticlePosition(index); + var npos = actor.GetParticlePosition(nextIndex); + var or = actor.GetParticleOrientation(index); + var nor = actor.GetParticleOrientation(nextIndex); + var rad = actor.GetParticleMaxRadius(index); + var nrad = actor.GetParticleMaxRadius(nextIndex); + + var up = pos + or * Vector3.up * rad; + var down = pos + or * Vector3.down * rad; + var left = pos + or * Vector3.left * rad; + var right = pos + or * Vector3.right * rad; + + var nup = npos + nor * Vector3.up * nrad; + var ndown = npos + nor * Vector3.down * nrad; + var nleft = npos + nor * Vector3.left * nrad; + var nright = npos + nor * Vector3.right * nrad; + + Handles.color = upColor; + Handles.DrawLine(up, nup); + + Handles.color = color; + Handles.DrawLine(down, ndown); + Handles.DrawLine(left, nleft); + Handles.DrawLine(right, nright); + Handles.DrawWireDisc(npos, nor * Vector3.forward, nrad); + } + } + if (actor.particleCount > 0) + { + var index = actor.solverIndices[0]; + var pos = actor.GetParticlePosition(index); + var or = actor.GetParticleOrientation(index); + var rad = actor.GetParticleMaxRadius(index); + + Handles.DrawWireDisc(pos, or * Vector3.forward, rad); + } + } + } + + } + +} + + diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiBoneEditor.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiBoneEditor.cs.meta new file mode 100644 index 00000000..2f33c8d3 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiBoneEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f25827f322514e1bb93fd309cd801bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiDraggableIcon.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiDraggableIcon.cs new file mode 100644 index 00000000..1d41c3b9 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiDraggableIcon.cs @@ -0,0 +1,73 @@ +using UnityEngine; +using UnityEditor; +using System.Collections; + +namespace Obi{ +public class ObiDraggableIcon { + + public static bool Draw(bool selected, int id, ref Vector2 position, Color color){ + + Texture texture = Resources.Load("Dot"); + + int controlID = GUIUtility.GetControlID(id,FocusType.Passive); + + // select vertex on mouse click: + switch (Event.current.GetTypeForControl(controlID)){ + + case EventType.MouseDown: + + Rect area = new Rect (position.x-5, position.y-5, 10, 10); + + if (area.Contains(Event.current.mousePosition)) + { + selected = true; + GUIUtility.hotControl = controlID; + Event.current.Use(); + }else if ((Event.current.modifiers & EventModifiers.Shift) == 0 && (Event.current.modifiers & EventModifiers.Command) == 0){ + + selected = false; + + } + + break; + + case EventType.MouseDrag: + + if (GUIUtility.hotControl == controlID){ + + position = Event.current.mousePosition; + GUI.changed = true; + + Event.current.Use(); + + } + + break; + + case EventType.MouseUp: + + if (GUIUtility.hotControl == controlID){ + + GUIUtility.hotControl = 0; + Event.current.Use(); + + } + + break; + + case EventType.Repaint: + + Color oldColor = GUI.color; + GUI.color = selected ? ObiEditorSettings.GetOrCreateSettings().selectedParticleColor : ObiEditorSettings.GetOrCreateSettings().particleColor; + Rect rect = new Rect (position.x-2, position.y-2, 4, 4); + GUI.Box(rect,EditorGUIUtility.whiteTexture); + GUI.color = oldColor; + + break; + + } + + return selected; + } +} +} diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiDraggableIcon.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiDraggableIcon.cs.meta new file mode 100644 index 00000000..d2449d02 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiDraggableIcon.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c736a38cd50af4bccbd08b83993abbdb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathEditor.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathEditor.cs new file mode 100644 index 00000000..7056a44e --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathEditor.cs @@ -0,0 +1,1241 @@ +using UnityEngine; +using UnityEditor; +using UnityEditor.EditorTools; +using System; +using UnityEditor.Overlays; +using UnityEngine.UIElements; + +namespace Obi +{ + [EditorTool("Obi Path Editor Tool",typeof(ObiRopeBase))] + public class ObiPathEditor : EditorTool + { + + [Overlay(typeof(SceneView), "Obi Path Editor", "Obi Path Editor", "Obi Path Editor", true)] + [Icon("Assets/Obi/Editor/Resources/EditCurves.psd")] + class PathEditorOverlay : Overlay, ITransientOverlay + { + public static ObiPathEditor editor; + + public override VisualElement CreatePanelContent() + { + var root = new VisualElement(); + root.Add(new IMGUIContainer(editor.DrawToolPanel)); + return root; + } + + // Use the visible property to hide or show this instance from within the class. + public bool visible + { + get + { + return ToolManager.activeToolType == typeof(ObiPathEditor); + } + } + } + + enum PathEditorTool + { + TranslatePoints, + RotatePoints, + ScalePoints, + OrientPoints, + InsertPoints, + RemovePoints + } + + ObiPath path; + + Quaternion prevRot = Quaternion.identity; + Vector3 prevScale = Vector3.one; + + PathEditorTool currentTool = PathEditorTool.TranslatePoints; + bool showTangentHandles = true; + bool showThicknessHandles = true; + + public bool needsRepaint = false; + + protected bool[] selectedStatus; + protected int lastSelected = 0; + protected int selectedCount = 0; + protected Vector3 selectionAverage; + protected bool useOrientation = false; + + protected static Color handleColor = new Color(1, 0.55f, 0.1f); + protected GUIContent m_IconContent; + + public override GUIContent toolbarIcon + { + get + { + if (m_IconContent == null) + { + m_IconContent = new GUIContent() + { + image = Resources.Load("EditCurves"), + text = "Obi Path Editor Tool", + tooltip = "Obi Path Editor Tool" + }; + } + return m_IconContent; + } + } + + ObiRopeBlueprintBase blueprint + { + get { return (target as ObiRopeBase).sharedBlueprint as ObiRopeBlueprintBase; } + } + + public void OnEnable() + { + this.useOrientation = target is ObiRod; + selectedStatus = new bool[0]; + PathEditorOverlay.editor = this; + } + + public void ResizeCPArrays() + { + Array.Resize(ref selectedStatus, path.ControlPointCount); + } + + public override void OnToolGUI(EditorWindow window) + { + needsRepaint = false; + + float thicknessScale = blueprint.thickness; + this.path = (target as ObiRopeBase).path; + var matrix = (target as ObiRopeBase).transform.localToWorldMatrix; + + ResizeCPArrays(); + + HandleUtility.AddDefaultControl(GUIUtility.GetControlID("PathEditor".GetHashCode(), FocusType.Passive)); + + Matrix4x4 prevMatrix = Handles.matrix; + Handles.matrix = matrix; + + // Draw control points: + Handles.color = handleColor; + for (int i = 0; i < path.ControlPointCount; ++i) + { + needsRepaint |= DrawControlPoint(i); + } + + // Count selected and calculate average position: + selectionAverage = GetControlPointAverage(out lastSelected, out selectedCount); + + // Draw cp tool handles: + needsRepaint |= SplineCPTools(matrix); + + if (showThicknessHandles) + needsRepaint |= DoThicknessHandles(thicknessScale); + + // Control point selection handle: + needsRepaint |= ObiPathHandles.SplineCPSelector(path, selectedStatus); + + Handles.matrix = prevMatrix; + + // During edit mode, allow to add/remove control points. + if (currentTool == PathEditorTool.InsertPoints) + AddControlPointsMode(matrix); + + if (currentTool == PathEditorTool.RemovePoints) + RemoveControlPointsMode(matrix); + + if (needsRepaint) + window.Repaint(); + + } + + private void AddControlPointsMode(Matrix4x4 matrix) + { + + float mu = ScreenPointToCurveMu(path, Event.current.mousePosition, matrix); + + Vector3 pointOnSpline = matrix.MultiplyPoint3x4(path.points.GetPositionAtMu(path.Closed, mu)); + + float size = HandleUtility.GetHandleSize(pointOnSpline) * 0.12f; + + Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); + Handles.color = Color.green; + Handles.DrawDottedLine(pointOnSpline, ray.origin, 4); + Handles.SphereHandleCap(0, pointOnSpline, Quaternion.identity, size, Event.current.type); + + + if (Event.current.type == EventType.MouseDown && Event.current.modifiers == EventModifiers.None) + { + Undo.RecordObject(blueprint, "Add"); + + int newIndex = path.InsertControlPoint(mu); + if (newIndex >= 0) + { + ResizeCPArrays(); + for (int i = 0; i < selectedStatus.Length; ++i) + selectedStatus[i] = false; + selectedStatus[newIndex] = true; + } + + path.FlushEvents(); + Event.current.Use(); + } + + // Repaint the scene, so that the add control point helpers are updated every frame. + SceneView.RepaintAll(); + + } + + private void RemoveControlPointsMode(Matrix4x4 matrix) + { + + float mu = ScreenPointToCurveMu(path, Event.current.mousePosition, matrix); + + Vector3 pointOnSpline = matrix.MultiplyPoint3x4(path.points.GetPositionAtMu(path.Closed, mu)); + + float size = HandleUtility.GetHandleSize(pointOnSpline) * 0.12f; + + Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); + + Handles.color = Color.red; + Handles.DrawDottedLine(pointOnSpline, ray.origin, 4); + + int index = path.GetClosestControlPointIndex(mu); + Handles.SphereHandleCap(0, matrix.MultiplyPoint3x4(path.points[index].position), Quaternion.identity, size, Event.current.type); + + if (Event.current.type == EventType.MouseDown && Event.current.modifiers == EventModifiers.None && index >= 0 && path.ControlPointCount > 2) + { + Undo.RecordObject(blueprint, "Remove"); + + path.RemoveControlPoint(index); + ResizeCPArrays(); + for (int i = 0; i < selectedStatus.Length; ++i) + selectedStatus[i] = false; + + path.FlushEvents(); + Event.current.Use(); + } + + // Repaint the scene, so that the add control point helpers are updated every frame. + SceneView.RepaintAll(); + + } + + protected bool DrawControlPoint(int i) + { + bool repaint = false; + var wp = path.points[i]; + float size = HandleUtility.GetHandleSize(wp.position) * 0.04f; + + if (selectedStatus[i] && showTangentHandles) + { + + Handles.color = handleColor; + + if (!(i == 0 && !path.Closed)) + { + Vector3 tangentPosition = wp.inTangentEndpoint; + + if (Event.current.type == EventType.Repaint) + Handles.DrawDottedLine(tangentPosition, wp.position, 2); + + EditorGUI.BeginChangeCheck(); + Handles.DotHandleCap(0, tangentPosition, Quaternion.identity, size, Event.current.type); + Vector3 newTangent = Handles.PositionHandle(tangentPosition, Quaternion.identity); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(blueprint, "Modify tangent"); + wp.SetInTangentEndpoint(newTangent); + path.points[i] = wp; + path.FlushEvents(); + repaint = true; + } + } + + if (!(i == path.ControlPointCount - 1 && !path.Closed)) + { + Vector3 tangentPosition = wp.outTangentEndpoint; + + if (Event.current.type == EventType.Repaint) + Handles.DrawDottedLine(tangentPosition, wp.position, 2); + + EditorGUI.BeginChangeCheck(); + Handles.DotHandleCap(0, tangentPosition, Quaternion.identity, size, Event.current.type); + Vector3 newTangent = Handles.PositionHandle(tangentPosition, Quaternion.identity); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(blueprint, "Modify tangent"); + wp.SetOutTangentEndpoint(newTangent); + path.points[i] = wp; + path.FlushEvents(); + repaint = true; + } + } + } + + if (Event.current.type == EventType.Repaint) + { + + Handles.color = selectedStatus[i] ? handleColor : Color.white; + Vector3 pos = wp.position; + + if (currentTool == PathEditorTool.OrientPoints) + { + Handles.ArrowHandleCap(0, pos, Quaternion.LookRotation(path.normals[i]), HandleUtility.GetHandleSize(pos), EventType.Repaint); + } + + Handles.SphereHandleCap(0, pos, Quaternion.identity, size * 3, EventType.Repaint); + + } + return repaint; + } + + protected Vector3 GetControlPointAverage(out int lastSelected, out int selectedCount) + { + + lastSelected = -1; + selectedCount = 0; + Vector3 averagePos = Vector3.zero; + + // Find center of all selected control points: + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + + averagePos += path.points[i].position; + selectedCount++; + lastSelected = i; + + } + } + if (selectedCount > 0) + averagePos /= selectedCount; + return averagePos; + + } + + protected bool SplineCPTools(Matrix4x4 matrix) + { + bool repaint = false; + + // Calculate handle rotation, for local or world pivot modes. + Quaternion handleRotation = Tools.pivotRotation == PivotRotation.Local ? Quaternion.identity : Quaternion.Inverse(matrix.rotation); + + // Reset initial handle rotation/orientation after using a tool: + if (GUIUtility.hotControl == 0) + { + + prevRot = handleRotation; + prevScale = Vector3.one; + + if (selectedCount == 1 && Tools.pivotRotation == PivotRotation.Local && currentTool == PathEditorTool.OrientPoints) + { + //prevRot = Quaternion.LookRotation(GetNormal(lastSelected)); + } + } + + // Transform handles: + if (selectedCount > 0) + { + + if (useOrientation && currentTool == PathEditorTool.OrientPoints) + { + repaint |= OrientTool(selectionAverage, handleRotation); + } + else + { + switch (currentTool) + { + case PathEditorTool.TranslatePoints: + { + repaint |= MoveTool(selectionAverage, handleRotation); + } + break; + + case PathEditorTool.ScalePoints: + { + repaint |= ScaleTool(selectionAverage, handleRotation); + } + break; + + case PathEditorTool.RotatePoints: + { + repaint |= RotateTool(selectionAverage, handleRotation); + } + break; + } + } + } + return repaint; + } + + protected bool MoveTool(Vector3 handlePosition, Quaternion handleRotation) + { + + EditorGUI.BeginChangeCheck(); + Vector3 newPos = Handles.PositionHandle(handlePosition, handleRotation); + if (EditorGUI.EndChangeCheck()) + { + + Undo.RecordObject(blueprint, "Move control point"); + + Vector3 delta = newPos - handlePosition; + + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + var wp = path.points[i]; + wp.Transform(delta, Quaternion.identity, Vector3.one); + path.points[i] = wp; + } + } + + path.FlushEvents(); + return true; + } + return false; + } + + protected bool ScaleTool(Vector3 handlePosition, Quaternion handleRotation) + { + + EditorGUI.BeginChangeCheck(); + Vector3 scale = Handles.ScaleHandle(prevScale, handlePosition, handleRotation, HandleUtility.GetHandleSize(handlePosition)); + + if (EditorGUI.EndChangeCheck()) + { + + Vector3 deltaScale = new Vector3(scale.x / prevScale.x, scale.y / prevScale.y, scale.z / prevScale.z); + prevScale = scale; + + Undo.RecordObject(blueprint, "Scale control point"); + + if (Tools.pivotMode == PivotMode.Center && selectedCount > 1) + { + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + var wp = path.points[i]; + Vector3 newPos = handlePosition + Vector3.Scale(wp.position - handlePosition, deltaScale); + wp.Transform(newPos - wp.position, Quaternion.identity, Vector3.one); + path.points[i] = wp; + } + } + } + else + { + // Scale all handles of selected control points relative to their control point: + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + var wp = path.points[i]; + wp.Transform(Vector3.zero, Quaternion.identity, deltaScale); + path.points[i] = wp; + } + } + } + + path.FlushEvents(); + return true; + } + return false; + } + + protected bool RotateTool(Vector3 handlePosition, Quaternion handleRotation) + { + + EditorGUI.BeginChangeCheck(); + + // TODO: investigate weird rotation gizmo: + Quaternion newRotation = Handles.RotationHandle(prevRot, handlePosition); + + if (EditorGUI.EndChangeCheck()) + { + + Quaternion delta = newRotation * Quaternion.Inverse(prevRot); + prevRot = newRotation; + + Undo.RecordObject(blueprint, "Rotate control point"); + + if (Tools.pivotMode == PivotMode.Center && selectedCount > 1) + { + + // Rotate all selected control points around their average: + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + var wp = path.points[i]; + Vector3 newPos = handlePosition + delta * (wp.position - handlePosition); + wp.Transform(newPos - wp.position, Quaternion.identity, Vector3.one); + path.points[i] = wp; + } + } + + } + else + { + + // Rotate all handles of selected control points around their control point: + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + var wp = path.points[i]; + wp.Transform(Vector3.zero, delta, Vector3.one); + path.points[i] = wp; + } + } + } + + path.FlushEvents(); + return true; + } + return false; + } + + protected bool OrientTool(Vector3 averagePos, Quaternion pivotRotation) + { + + EditorGUI.BeginChangeCheck(); + Quaternion newRotation = Handles.RotationHandle(prevRot, averagePos); + + if (EditorGUI.EndChangeCheck()) + { + + Quaternion delta = newRotation * Quaternion.Inverse(prevRot); + prevRot = newRotation; + + Undo.RecordObject(blueprint, "Orient control point"); + + // Rotate all selected control points around their average: + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + path.normals[i] = delta * path.normals[i]; + } + } + + path.FlushEvents(); + return true; + } + return false; + } + + + protected bool DoThicknessHandles(float scale) + { + Color oldColor = Handles.color; + Handles.color = handleColor; + + EditorGUI.BeginChangeCheck(); + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + Vector3 position = path.points[i].position; + + var tangent = path.points.GetTangent(i); + if (!tangent.Equals(Vector3.zero)) + { + Quaternion orientation = Quaternion.LookRotation(tangent); + + float offset = 0.05f; + float thickness = (path.thicknesses[i] * scale) + offset; + + EditorGUI.BeginChangeCheck(); + thickness = DoRadiusHandle(orientation, position, thickness); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(blueprint, "Change control point thickness"); + path.thicknesses[i] = Mathf.Max(0, (thickness - offset) / scale); + path.FlushEvents(); + return true; + } + } + } + } + Handles.color = oldColor; + + return false; + } + + public void DrawToolPanel() + { + + DrawToolButtons(); + + DrawControlPointInspector(); + + } + + private void DrawToolButtons() + { + GUILayout.BeginHorizontal(); + + EditorGUI.BeginChangeCheck(); + GUILayout.Toggle(currentTool == PathEditorTool.TranslatePoints, new GUIContent(Resources.Load("TranslateControlPoint"), "Translate CPs"), "Button", GUILayout.MaxHeight(24), GUILayout.Width(38)); + if (EditorGUI.EndChangeCheck()) + { + currentTool = PathEditorTool.TranslatePoints; + } + + EditorGUI.BeginChangeCheck(); + GUILayout.Toggle(currentTool == PathEditorTool.RotatePoints, new GUIContent(Resources.Load("RotateControlPoint"), "Rotate CPs"), "Button", GUILayout.MaxHeight(24), GUILayout.Width(38)); + if (EditorGUI.EndChangeCheck()) + { + currentTool = PathEditorTool.RotatePoints; + } + + EditorGUI.BeginChangeCheck(); + GUILayout.Toggle(currentTool == PathEditorTool.ScalePoints, new GUIContent(Resources.Load("ScaleControlPoint"), "Scale CPs"), "Button", GUILayout.MaxHeight(24), GUILayout.Width(38)); + if (EditorGUI.EndChangeCheck()) + { + currentTool = PathEditorTool.ScalePoints; + } + + EditorGUI.BeginChangeCheck(); + GUILayout.Toggle(currentTool == PathEditorTool.InsertPoints, new GUIContent(Resources.Load("AddControlPoint"), "Add CPs"), "Button", GUILayout.MaxHeight(24), GUILayout.Width(38)); + if (EditorGUI.EndChangeCheck()) + { + currentTool = PathEditorTool.InsertPoints; + } + + EditorGUI.BeginChangeCheck(); + GUILayout.Toggle(currentTool == PathEditorTool.RemovePoints, new GUIContent(Resources.Load("RemoveControlPoint"), "Remove CPs"), "Button", GUILayout.MaxHeight(24), GUILayout.Width(38)); + if (EditorGUI.EndChangeCheck()) + { + currentTool = PathEditorTool.RemovePoints; + } + + EditorGUI.BeginChangeCheck(); + bool closed = GUILayout.Toggle(path.Closed, new GUIContent(Resources.Load("OpenCloseCurve"), "Open/Close the path"), "Button", GUILayout.MaxHeight(24), GUILayout.Width(38)); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(blueprint, "Open/close path"); + path.Closed = closed; + path.FlushEvents(); + needsRepaint = true; + } + + if (useOrientation) + { + EditorGUI.BeginChangeCheck(); + GUILayout.Toggle(currentTool == PathEditorTool.OrientPoints, new GUIContent(Resources.Load("OrientControlPoint"), "Orientation tool"), "Button", GUILayout.MaxHeight(24), GUILayout.Width(38)); + if (EditorGUI.EndChangeCheck()) + { + currentTool = PathEditorTool.OrientPoints; + } + } + + showTangentHandles = GUILayout.Toggle(showTangentHandles, new GUIContent(Resources.Load("ShowTangentHandles"), "Show tangent handles"), "Button", GUILayout.MaxHeight(24), GUILayout.Width(38)); + showThicknessHandles = GUILayout.Toggle(showThicknessHandles, new GUIContent(Resources.Load("ShowThicknessHandles"), "Show thickness handles"), "Button", GUILayout.MaxHeight(24), GUILayout.Width(38)); + + GUILayout.EndHorizontal(); + } + + private void DrawPositionField(Rect rect, string label, int index) + { + EditorGUI.showMixedValue = false; + float pos = 0; + bool firstSelected = true; + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + if (firstSelected) + { + pos = path.points[i].position[index]; + firstSelected = false; + } + else if (!Mathf.Approximately(pos,path.points[i].position[index])) + { + EditorGUI.showMixedValue = true; + break; + } + } + } + + EditorGUI.BeginChangeCheck(); + float oldLabelWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 10; + pos = EditorGUI.FloatField(rect, label, pos); + EditorGUIUtility.labelWidth = oldLabelWidth; + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) + { + + Undo.RecordObject(blueprint, "Change control points position"); + + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + var wp = path.points[i]; + wp.position[index] = pos; + path.points[i] = wp; + } + } + path.FlushEvents(); + needsRepaint = true; + } + } + + private void DrawInTangentField(Rect rect, string label, int index) + { + EditorGUI.showMixedValue = false; + float pos = 0; + bool firstSelected = true; + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + if (firstSelected) + { + pos = path.points[i].inTangent[index]; + firstSelected = false; + } + else if (!Mathf.Approximately(pos, path.points[i].inTangent[index])) + { + EditorGUI.showMixedValue = true; + break; + } + } + } + + EditorGUI.BeginChangeCheck(); + float oldLabelWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 10; + pos = EditorGUI.FloatField(rect, label, pos); + EditorGUIUtility.labelWidth = oldLabelWidth; + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) + { + + Undo.RecordObject(blueprint, "Change control points tangent"); + + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + var wp = path.points[i]; + var newInTangent = wp.inTangent; + newInTangent[index] = pos; + wp.SetInTangent(newInTangent); + path.points[i] = wp; + } + } + path.FlushEvents(); + needsRepaint = true; + } + } + + private void DrawOutTangentField(Rect rect, string label, int index) + { + EditorGUI.showMixedValue = false; + float pos = 0; + bool firstSelected = true; + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + if (firstSelected) + { + pos = path.points[i].outTangent[index]; + firstSelected = false; + } + else if (!Mathf.Approximately(pos, path.points[i].outTangent[index])) + { + EditorGUI.showMixedValue = true; + break; + } + } + } + + EditorGUI.BeginChangeCheck(); + float oldLabelWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 10; + pos = EditorGUI.FloatField(rect, label, pos); + EditorGUIUtility.labelWidth = oldLabelWidth; + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) + { + + Undo.RecordObject(blueprint, "Change control points tangent"); + + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + var wp = path.points[i]; + var newOutTangent = wp.outTangent; + newOutTangent[index] = pos; + wp.SetOutTangent(newOutTangent); + path.points[i] = wp; + } + } + path.FlushEvents(); + needsRepaint = true; + } + } + + private void DrawControlPointInspector() + { + + GUI.enabled = selectedCount > 0; + + bool wideMode = EditorGUIUtility.wideMode; + EditorGUIUtility.wideMode = true; + EditorGUIUtility.labelWidth = 100; + + EditorGUILayout.BeginVertical(); + + GUILayout.Box("", ObiEditorUtils.GetSeparatorLineStyle()); + + // position: + var rect = EditorGUILayout.GetControlRect(); + rect = EditorGUI.PrefixLabel(rect, GUIUtility.GetControlID(FocusType.Passive), new GUIContent("Position")); + rect.width /= 3.0f; + DrawPositionField(rect,"X",0); rect.x += rect.width; + DrawPositionField(rect,"Y",1); rect.x += rect.width; + DrawPositionField(rect,"Z",2); rect.x += rect.width; + + // in tangent: + rect = EditorGUILayout.GetControlRect(); + rect = EditorGUI.PrefixLabel(rect, GUIUtility.GetControlID(FocusType.Passive), new GUIContent("In Tangent")); + rect.width /= 3.0f; + DrawInTangentField(rect, "X", 0); rect.x += rect.width; + DrawInTangentField(rect, "Y", 1); rect.x += rect.width; + DrawInTangentField(rect, "Z", 2); rect.x += rect.width; + + // out tangent: + rect = EditorGUILayout.GetControlRect(); + rect = EditorGUI.PrefixLabel(rect, GUIUtility.GetControlID(FocusType.Passive), new GUIContent("Out Tangent")); + rect.width /= 3.0f; + DrawOutTangentField(rect, "X", 0); rect.x += rect.width; + DrawOutTangentField(rect, "Y", 1); rect.x += rect.width; + DrawOutTangentField(rect, "Z", 2); rect.x += rect.width; + + // tangent mode: + EditorGUI.showMixedValue = false; + var mode = ObiWingedPoint.TangentMode.Free; + bool firstSelected = true; + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + if (firstSelected) + { + mode = path.points[i].tangentMode; + firstSelected = false; + } + else if (mode != path.points[i].tangentMode) + { + EditorGUI.showMixedValue = true; + break; + } + } + } + + EditorGUI.BeginChangeCheck(); + var newMode = (ObiWingedPoint.TangentMode)EditorGUILayout.EnumPopup("Tangent mode", mode, GUILayout.MinWidth(94)); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) + { + + Undo.RecordObject(blueprint, "Change control points mode"); + + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + var wp = path.points[i]; + wp.tangentMode = newMode; + path.points[i] = wp; + } + } + path.FlushEvents(); + needsRepaint = true; + } + + // thickness: + EditorGUI.showMixedValue = false; + float thickness = 0; + firstSelected = true; + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + if (firstSelected) + { + thickness = path.thicknesses[i]; + firstSelected = false; + } + else if (!Mathf.Approximately(thickness, path.thicknesses[i])) + { + EditorGUI.showMixedValue = true; + break; + } + } + } + + EditorGUI.BeginChangeCheck(); + thickness = EditorGUILayout.FloatField("Thickness", thickness, GUILayout.MinWidth(94)); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) + { + + Undo.RecordObject(blueprint, "Change control point thickness"); + + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + path.thicknesses[i] = Mathf.Max(0, thickness); + } + path.FlushEvents(); + needsRepaint = true; + } + + // mass: + EditorGUI.showMixedValue = false; + float mass = 0; + firstSelected = true; + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + if (firstSelected) + { + mass = path.masses[i]; + firstSelected = false; + } + else if (!Mathf.Approximately(mass, path.masses[i])) + { + EditorGUI.showMixedValue = true; + break; + } + } + } + + EditorGUI.BeginChangeCheck(); + mass = EditorGUILayout.FloatField("Mass", mass, GUILayout.MinWidth(94)); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) + { + + Undo.RecordObject(blueprint, "Change control point mass"); + + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + path.masses[i] = mass; + } + path.FlushEvents(); + needsRepaint = true; + } + + if (useOrientation) + { + // rotational mass: + EditorGUI.showMixedValue = false; + float rotationalMass = 0; + firstSelected = true; + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + if (firstSelected) + { + rotationalMass = path.rotationalMasses[i]; + firstSelected = false; + } + else if (!Mathf.Approximately(rotationalMass, path.rotationalMasses[i])) + { + EditorGUI.showMixedValue = true; + break; + } + } + } + + EditorGUI.BeginChangeCheck(); + rotationalMass = EditorGUILayout.FloatField("Rotational mass", rotationalMass, GUILayout.MinWidth(94)); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) + { + + Undo.RecordObject(blueprint, "Change control point rotational mass"); + + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + path.rotationalMasses[i] = rotationalMass; + } + path.FlushEvents(); + needsRepaint = true; + } + } + + // category: + EditorGUI.showMixedValue = false; + int category = 0; + firstSelected = true; + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + if (firstSelected) + { + category = ObiUtils.GetCategoryFromFilter(path.filters[i]); + firstSelected = false; + } + else if (!Mathf.Approximately(category, ObiUtils.GetCategoryFromFilter(path.filters[i]))) + { + EditorGUI.showMixedValue = true; + break; + } + } + } + + EditorGUI.BeginChangeCheck(); + category = EditorGUILayout.Popup("Category", category, ObiUtils.categoryNames, GUILayout.MinWidth(94)); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(blueprint, "Change control point category"); + + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + path.filters[i] = ObiUtils.MakeFilter(ObiUtils.GetMaskFromFilter(path.filters[i]),category); + } + path.FlushEvents(); + needsRepaint = true; + } + + // mask: + EditorGUI.showMixedValue = false; + int mask = 0; + firstSelected = true; + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + if (firstSelected) + { + mask = ObiUtils.GetMaskFromFilter(path.filters[i]); + firstSelected = false; + } + else if (!Mathf.Approximately(mask, ObiUtils.GetMaskFromFilter(path.filters[i]))) + { + EditorGUI.showMixedValue = true; + break; + } + } + } + + EditorGUI.BeginChangeCheck(); + mask = EditorGUILayout.MaskField("Collides with", mask, ObiUtils.categoryNames, GUILayout.MinWidth(94)); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(blueprint, "Change control point mask"); + + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + path.filters[i] = ObiUtils.MakeFilter(mask,ObiUtils.GetCategoryFromFilter(path.filters[i])); + } + path.FlushEvents(); + needsRepaint = true; + } + + // color: + EditorGUI.showMixedValue = false; + Color color = Color.white; + firstSelected = true; + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + if (firstSelected) + { + color = path.colors[i]; + firstSelected = false; + } + else if (color != path.colors[i]) + { + EditorGUI.showMixedValue = true; + break; + } + } + } + + EditorGUI.BeginChangeCheck(); + color = EditorGUILayout.ColorField(new GUIContent("Color"), color, true, true, true, GUILayout.MinWidth(94)); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) + { + + Undo.RecordObject(blueprint, "Change control point color"); + + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + path.colors[i] = color; + } + path.FlushEvents(); + needsRepaint = true; + } + + // name: + EditorGUI.showMixedValue = false; + string cpname = ""; + firstSelected = true; + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + { + if (firstSelected) + { + cpname = path.GetName(i); + firstSelected = false; + } + else if (cpname != path.GetName(i)) + { + EditorGUI.showMixedValue = true; + break; + } + } + } + + EditorGUI.BeginChangeCheck(); + cpname = EditorGUILayout.DelayedTextField("Name", cpname, GUILayout.MinWidth(94)); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) + { + + Undo.RecordObject(blueprint, "Change control point name"); + + for (int i = 0; i < path.ControlPointCount; ++i) + { + if (selectedStatus[i]) + path.SetName(i, cpname); + } + path.FlushEvents(); + needsRepaint = true; + } + + + EditorGUILayout.EndVertical(); + + EditorGUIUtility.wideMode = wideMode; + + GUI.enabled = true; + } + + internal static float DoRadiusHandle(Quaternion rotation, Vector3 position, float radius) + { + Vector3[] vector3Array; + + Vector3 camToPosition; + if (Camera.current.orthographic) + { + camToPosition = Camera.current.transform.forward; + Handles.DrawWireDisc(position, camToPosition, radius); + + vector3Array = new Vector3[4] + { + Camera.current.transform.right, + Camera.current.transform.up, + -Camera.current.transform.right, + -Camera.current.transform.up, + }; + + } + else + { + camToPosition = position - Camera.current.transform.position; + Handles.DrawWireDisc(position, rotation * Vector3.forward, radius); + + vector3Array = new Vector3[4] + { + rotation * Vector3.right, + rotation * Vector3.up, + rotation * -Vector3.right, + rotation * -Vector3.up, + }; + } + + for (int index = 0; index < 4; ++index) + { + int controlId = GUIUtility.GetControlID("ObiPathThicknessHandle".GetHashCode(), FocusType.Passive); + Vector3 position1 = position + radius * vector3Array[index]; + bool changed = GUI.changed; + GUI.changed = false; + Vector3 a = Handles.Slider(controlId, position1, vector3Array[index], HandleUtility.GetHandleSize(position1) * 0.03f, Handles.DotHandleCap, 0.0f); + if (GUI.changed) + radius = Vector3.Distance(a, position); + GUI.changed |= changed; + } + + return radius; + } + + public static float ScreenPointToCurveMu(ObiPath path, Vector2 screenPoint, Matrix4x4 referenceFrame, int samples = 30) + { + + if (path.ControlPointCount >= 2) + { + + samples = Mathf.Max(1, samples); + float step = 1 / (float)samples; + + float closestMu = 0; + float minDistance = float.MaxValue; + + for (int k = 0; k < path.GetSpanCount(); ++k) + { + int nextCP = (k + 1) % path.ControlPointCount; + + var wp1 = path.points[k]; + var wp2 = path.points[nextCP]; + + Vector3 _p = referenceFrame.MultiplyPoint3x4(wp1.position); + Vector3 p = referenceFrame.MultiplyPoint3x4(wp1.outTangentEndpoint); + Vector3 p_ = referenceFrame.MultiplyPoint3x4(wp2.inTangentEndpoint); + Vector3 p__ = referenceFrame.MultiplyPoint3x4(wp2.position); + + Vector2 lastPoint = HandleUtility.WorldToGUIPoint(path.m_Points.Evaluate(_p, p, p_, p__, 0)); + for (int i = 1; i <= samples; ++i) + { + + Vector2 currentPoint = HandleUtility.WorldToGUIPoint(path.m_Points.Evaluate(_p, p, p_, p__, i * step)); + + float mu; + float distance = Vector2.SqrMagnitude((Vector2)ObiUtils.ProjectPointLine(lastPoint, currentPoint, screenPoint, out mu) - screenPoint); + + if (distance < minDistance) + { + minDistance = distance; + closestMu = (k + (i - 1) * step + mu / samples) / (float)path.GetSpanCount(); + } + lastPoint = currentPoint; + } + + } + + return closestMu; + + } + else + { + Debug.LogWarning("Curve needs at least 2 control points to be defined."); + } + return 0; + + } + + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathEditor.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathEditor.cs.meta new file mode 100644 index 00000000..32c490bc --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0cb694bcadb6a4909b593111507e1eb3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathHandles.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathHandles.cs new file mode 100644 index 00000000..2a0bc1b6 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathHandles.cs @@ -0,0 +1,271 @@ +using UnityEngine; +using UnityEditor; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Obi +{ + + public class ObiPathHandles + { + + static int splineSelectorHash = "ObiPathSelectorHash".GetHashCode(); + const int minSelectionDistance = 5; + + static Vector2 startPos; + static Vector2 currentPos; + static bool dragging = false; + static Rect marquee; + + public static bool SplineCPSelector(ObiPath path, bool[] selectionStatus) + { + + int controlID = GUIUtility.GetControlID(splineSelectorHash, FocusType.Passive); + int selectedCPIndex = -1; + bool selectionStatusChanged = false; + + // select vertex on mouse click: + switch (Event.current.GetTypeForControl(controlID)) + { + case EventType.Layout: + case EventType.MouseMove: + + float minSqrDistance = System.Single.MaxValue; + float sqrMinSelectionDistance = minSelectionDistance * minSelectionDistance; + + for (int i = 0; i < path.ControlPointCount; i++) + { + + // get particle position in gui space: + Vector2 pos = HandleUtility.WorldToGUIPoint(path.points[i].position); + + // get distance from mouse position to particle position: + float sqrDistance = Vector2.SqrMagnitude(Event.current.mousePosition - pos); + + // check if this control point is closer to the cursor that any previously considered point. + if (sqrDistance < sqrMinSelectionDistance && sqrDistance < minSqrDistance) + { + minSqrDistance = sqrDistance; + } + + } + HandleUtility.AddControl(controlID, Mathf.Sqrt(minSqrDistance)); + + break; + + case EventType.MouseDown: + + marquee.Set(0, 0, 0, 0); + startPos = Event.current.mousePosition; + + if (Event.current.button == 0) + { + + if (HandleUtility.nearestControl == controlID) + { + GUIUtility.hotControl = controlID; + + // If the user is pressing shift or ctrl, accumulate selection. + if ((Event.current.modifiers & (EventModifiers.Shift | EventModifiers.Control)) == 0 && (Event.current.modifiers & EventModifiers.Alt) == 0) + { + for (int i = 0; i < selectionStatus.Length; i++) + selectionStatus[i] = false; + + selectionStatusChanged = true; + } + + minSqrDistance = System.Single.MaxValue; + sqrMinSelectionDistance = minSelectionDistance * minSelectionDistance; + + for (int i = 0; i < path.ControlPointCount; i++) + { + + // get particle position in gui space: + Vector2 pos = HandleUtility.WorldToGUIPoint(path.points[i].position); + + // get distance from mouse position to particle position: + float sqrDistance = Vector2.SqrMagnitude(startPos - pos); + + // check if this control point is closer to the cursor that any previously considered point. + if (sqrDistance < sqrMinSelectionDistance && sqrDistance < minSqrDistance) + { + minSqrDistance = sqrDistance; + selectedCPIndex = i; + } + + } + + if (selectedCPIndex >= 0) + { // toggle particle selection status. + + selectionStatus[selectedCPIndex] = !selectionStatus[selectedCPIndex]; + selectionStatusChanged = true; + + // Prevent spline deselection if we have selected a particle: + Event.current.Use(); + + } + } + else if ((Event.current.modifiers & (EventModifiers.Shift | EventModifiers.Control)) == 0 && (Event.current.modifiers & EventModifiers.Alt) == 0) + { + for (int i = 0; i < selectionStatus.Length; i++) + selectionStatus[i] = false; + + selectionStatusChanged = true; + } + } + + break; + + case EventType.MouseDrag: + + if (Event.current.button == 0 && (Event.current.modifiers & EventModifiers.Alt) == 0) + { + currentPos = Event.current.mousePosition; + if (!dragging && Vector2.Distance(startPos, currentPos) > 5) + { + dragging = true; + } + + if (dragging) + { + GUIUtility.hotControl = controlID; + Event.current.Use(); + } + + //update marquee rect: + float left = Mathf.Min(startPos.x, currentPos.x); + float right = Mathf.Max(startPos.x, currentPos.x); + float bottom = Mathf.Min(startPos.y, currentPos.y); + float top = Mathf.Max(startPos.y, currentPos.y); + + marquee = new Rect(left, bottom, right - left, top - bottom); + + } + + break; + + case EventType.MouseUp: + + if (GUIUtility.hotControl == controlID) + { + + dragging = false; + + for (int i = 0; i < path.ControlPointCount; i++) + { + + // get particle position in gui space: + Vector2 pos = HandleUtility.WorldToGUIPoint(path.points[i].position); + + if (pos.x > marquee.xMin && pos.x < marquee.xMax && pos.y > marquee.yMin && pos.y < marquee.yMax) + { + selectionStatus[i] = true; + selectionStatusChanged = true; + } + + } + + GUIUtility.hotControl = 0; + Event.current.Use(); + } + + break; + + case EventType.Repaint: + + if (dragging) + { + GUISkin oldSkin = GUI.skin; + GUI.skin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Scene); + Handles.BeginGUI(); + GUI.Box(new Rect(marquee.xMin, marquee.yMin, marquee.width, marquee.height), ""); + Handles.EndGUI(); + GUI.skin = oldSkin; + } + + break; + + } + + return selectionStatusChanged; + } + + private static void DrawControlPointArcs(ObiPath path, float thicknessScale) + { + for (int i = 0; i < path.ControlPointCount; ++i) + { + Vector3 position = path.points[i].position; + Vector3 tangent = path.points.GetTangent(i); + Vector3 right = Vector3.Cross(tangent, path.normals[i]).normalized; + float thickness = path.thicknesses[i] * thicknessScale + 0.05f; + + Handles.DrawWireArc(position, tangent, right, -180, thickness); + } + } + + private static void DrawPathPolylines(Vector3[] samples, Vector3[] leftSamples, Vector3[] rightSamples, Vector3[] upSamples, bool drawOrientation) + { + Handles.DrawPolyLine(samples); + if (drawOrientation) + { + Handles.DrawPolyLine(leftSamples); + Handles.DrawPolyLine(upSamples); + Handles.DrawPolyLine(rightSamples); + } + } + + public static void DrawPathHandle(ObiPath path, Matrix4x4 referenceFrame, float thicknessScale, int resolution, bool drawOrientation = true) + { + + if (path == null || path.GetSpanCount() == 0) return; + + Matrix4x4 prevMatrix = Handles.matrix; + Handles.matrix = referenceFrame; + + // Draw the curve: + int curveSegments = path.GetSpanCount() * resolution; + Vector3[] samples = new Vector3[curveSegments + 1]; + Vector3[] leftSamples = new Vector3[curveSegments + 1]; + Vector3[] rightSamples = new Vector3[curveSegments + 1]; + Vector3[] upSamples = new Vector3[curveSegments + 1]; + + for (int i = 0; i <= curveSegments; ++i) + { + + float mu = i / (float)curveSegments; + samples[i] = path.points.GetPositionAtMu(path.Closed,mu); + + if (drawOrientation) + { + Vector3 tangent = path.points.GetTangentAtMu(path.Closed,mu); + Vector3 right = Vector3.Cross(tangent, path.normals.GetAtMu(path.Closed,mu)).normalized; + Vector3 up = Vector3.Cross(right, tangent).normalized; + float thickness = path.thicknesses.GetAtMu(path.Closed,mu) * thicknessScale + 0.05f; + + leftSamples[i] = samples[i] - right * thickness; + rightSamples[i] = samples[i] + right * thickness; + upSamples[i] = samples[i] + up * thickness; + + if (i % 5 == 0) + { + Handles.DrawLine(leftSamples[i], rightSamples[i]); + Handles.DrawLine(samples[i], samples[i] + up * thickness); + } + } + } + + if (drawOrientation) + DrawControlPointArcs(path, thicknessScale); + + DrawPathPolylines(samples, leftSamples, rightSamples, upSamples, drawOrientation); + DrawPathPolylines(samples, leftSamples, rightSamples, upSamples, drawOrientation); + + Handles.matrix = prevMatrix; + } + + + } +} + diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathHandles.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathHandles.cs.meta new file mode 100644 index 00000000..8df16e49 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathHandles.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3c12ceb831344c47af02f0d6bf73de7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathSmootherEditor.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathSmootherEditor.cs new file mode 100644 index 00000000..068bc64a --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathSmootherEditor.cs @@ -0,0 +1,37 @@ +using UnityEditor; +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Obi +{ + + [CustomEditor(typeof(ObiPathSmoother), true), CanEditMultipleObjects] + public class ObiPathSmootherEditor : Editor + { + + ObiPathSmoother shape; + + public void OnEnable() + { + shape = (ObiPathSmoother)target; + } + + public override void OnInspectorGUI() + { + + serializedObject.UpdateIfRequiredOrScript(); + + Editor.DrawPropertiesExcluding(serializedObject, "m_Script"); + + // Apply changes to the serializedProperty + if (GUI.changed) + serializedObject.ApplyModifiedProperties(); + + } + + } + +} + diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathSmootherEditor.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathSmootherEditor.cs.meta new file mode 100644 index 00000000..4b3fca50 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiPathSmootherEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a01b6dc95e7284e2583513863858d670 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRodEditor.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRodEditor.cs new file mode 100644 index 00000000..f8e0ad88 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRodEditor.cs @@ -0,0 +1,216 @@ +using UnityEditor; +using UnityEditor.EditorTools; +using UnityEditorInternal; +using UnityEngine; +using System; +using System.Collections.Generic; +using System.Linq; + + +namespace Obi +{ + + [CustomEditor(typeof(ObiRod))] + public class ObiRodEditor : Editor + { + [MenuItem("GameObject/3D Object/Obi/Obi Rod", false, 301)] + static void CreateObiRod(MenuCommand menuCommand) + { + GameObject go = new GameObject("Obi Rod", typeof(ObiRod), typeof(ObiRopeExtrudedRenderer)); + var renderer = go.GetComponent(); + renderer.material = ObiEditorUtils.GetDefaultMaterial(); + ObiEditorUtils.PlaceActorRoot(go, menuCommand); + } + + ObiRod actor; + + SerializedProperty rodBlueprint; + + SerializedProperty collisionMaterial; + SerializedProperty selfCollisions; + SerializedProperty surfaceCollisions; + + SerializedProperty stretchShearConstraintsEnabled; + SerializedProperty stretchCompliance; + SerializedProperty shear1Compliance; + SerializedProperty shear2Compliance; + + SerializedProperty bendTwistConstraintsEnabled; + SerializedProperty torsionCompliance; + SerializedProperty bend1Compliance; + SerializedProperty bend2Compliance; + SerializedProperty plasticYield; + SerializedProperty plasticCreep; + + SerializedProperty aerodynamicsEnabled; + SerializedProperty drag; + SerializedProperty lift; + + SerializedProperty chainConstraintsEnabled; + SerializedProperty tightness; + + GUIStyle editLabelStyle; + + public void OnEnable() + { + actor = (ObiRod)target; + + rodBlueprint = serializedObject.FindProperty("m_RodBlueprint"); + + collisionMaterial = serializedObject.FindProperty("m_CollisionMaterial"); + selfCollisions = serializedObject.FindProperty("m_SelfCollisions"); + surfaceCollisions = serializedObject.FindProperty("m_SurfaceCollisions"); + + stretchShearConstraintsEnabled = serializedObject.FindProperty("_stretchShearConstraintsEnabled"); + stretchCompliance = serializedObject.FindProperty("_stretchCompliance"); + shear1Compliance = serializedObject.FindProperty("_shear1Compliance"); + shear2Compliance = serializedObject.FindProperty("_shear2Compliance"); + + bendTwistConstraintsEnabled = serializedObject.FindProperty("_bendTwistConstraintsEnabled"); + torsionCompliance = serializedObject.FindProperty("_torsionCompliance"); + bend1Compliance = serializedObject.FindProperty("_bend1Compliance"); + bend2Compliance = serializedObject.FindProperty("_bend2Compliance"); + plasticYield = serializedObject.FindProperty("_plasticYield"); + plasticCreep = serializedObject.FindProperty("_plasticCreep"); + + aerodynamicsEnabled = serializedObject.FindProperty("_aerodynamicsEnabled"); + drag = serializedObject.FindProperty("_drag"); + lift = serializedObject.FindProperty("_lift"); + + chainConstraintsEnabled = serializedObject.FindProperty("_chainConstraintsEnabled"); + tightness = serializedObject.FindProperty("_tightness"); + } + + private void DoEditButton() + { + using (new EditorGUI.DisabledScope(actor.rodBlueprint == null)) + { + EditorGUILayout.BeginHorizontal(); + GUILayout.Space(EditorGUIUtility.labelWidth); + EditorGUI.BeginChangeCheck(); + bool edit = GUILayout.Toggle(ToolManager.activeToolType == typeof(ObiPathEditor), new GUIContent(Resources.Load("EditCurves")), "Button", GUILayout.MaxWidth(36), GUILayout.MaxHeight(24)); + EditorGUILayout.LabelField("Edit path", editLabelStyle, GUILayout.ExpandHeight(true), GUILayout.MaxHeight(24)); + if (EditorGUI.EndChangeCheck()) + { + if (edit) + ToolManager.SetActiveTool(); + else + ToolManager.RestorePreviousPersistentTool(); + + SceneView.RepaintAll(); + } + EditorGUILayout.EndHorizontal(); + } + } + + public override void OnInspectorGUI() + { + if (editLabelStyle == null) + { + editLabelStyle = new GUIStyle(GUI.skin.label); + editLabelStyle.alignment = TextAnchor.MiddleLeft; + } + + serializedObject.UpdateIfRequiredOrScript(); + + if (actor.rodBlueprint != null && actor.rodBlueprint.path.ControlPointCount < 2) + { + actor.rodBlueprint.GenerateImmediate(); + } + + using (new EditorGUI.DisabledScope(ToolManager.activeToolType == typeof(ObiPathEditor))) + { + GUILayout.BeginHorizontal(); + + EditorGUI.BeginChangeCheck(); + + EditorGUILayout.PropertyField(rodBlueprint, new GUIContent("Blueprint")); + + if (actor.rodBlueprint == null) + { + if (GUILayout.Button("Create", EditorStyles.miniButton, GUILayout.MaxWidth(80))) + { + string path = EditorUtility.SaveFilePanel("Save blueprint", "Assets/", "RodBlueprint", "asset"); + if (!string.IsNullOrEmpty(path)) + { + path = FileUtil.GetProjectRelativePath(path); + ObiRodBlueprint asset = ScriptableObject.CreateInstance(); + + AssetDatabase.CreateAsset(asset, path); + AssetDatabase.SaveAssets(); + + actor.rodBlueprint = asset; + } + } + } + + if (EditorGUI.EndChangeCheck()) + { + foreach (var t in targets) + { + (t as ObiRod).RemoveFromSolver(); + (t as ObiRod).ClearState(); + } + serializedObject.ApplyModifiedProperties(); + foreach (var t in targets) + (t as ObiRod).AddToSolver(); + } + + GUILayout.EndHorizontal(); + } + + DoEditButton(); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Collisions", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(collisionMaterial, new GUIContent("Collision material")); + EditorGUILayout.PropertyField(selfCollisions, new GUIContent("Self collisions")); + EditorGUILayout.PropertyField(surfaceCollisions, new GUIContent("Surface-based collisions")); + + EditorGUILayout.Space(); + ObiEditorUtils.DoToggleablePropertyGroup(stretchShearConstraintsEnabled, new GUIContent("Stretch & Shear Constraints", Resources.Load("Icons/ObiStretchShearConstraints Icon")), + () => { + EditorGUILayout.PropertyField(stretchCompliance, new GUIContent("Stretch compliance")); + EditorGUILayout.PropertyField(shear1Compliance, new GUIContent("Shear compliance X")); + EditorGUILayout.PropertyField(shear2Compliance, new GUIContent("Shear compliance Y")); + }); + + ObiEditorUtils.DoToggleablePropertyGroup(bendTwistConstraintsEnabled, new GUIContent("Bend & Twist Constraints", Resources.Load("Icons/ObiBendTwistConstraints Icon")), + () => { + EditorGUILayout.PropertyField(torsionCompliance, new GUIContent("Torsion compliance")); + EditorGUILayout.PropertyField(bend1Compliance, new GUIContent("Bend compliance X")); + EditorGUILayout.PropertyField(bend2Compliance, new GUIContent("Bend compliance Y")); + EditorGUILayout.PropertyField(plasticYield, new GUIContent("Plastic yield")); + EditorGUILayout.PropertyField(plasticCreep, new GUIContent("Plastic creep")); + }); + + ObiEditorUtils.DoToggleablePropertyGroup(aerodynamicsEnabled, new GUIContent("Aerodynamics", Resources.Load("Icons/ObiAerodynamicConstraints Icon")), + () => { + EditorGUILayout.PropertyField(drag, new GUIContent("Drag")); + EditorGUILayout.PropertyField(lift, new GUIContent("Lift")); + }); + + ObiEditorUtils.DoToggleablePropertyGroup(chainConstraintsEnabled, new GUIContent("Chain Constraints", Resources.Load("Icons/ObiChainConstraints Icon")), + () => { + EditorGUILayout.PropertyField(tightness, new GUIContent("Tightness")); + }); + + + if (GUI.changed) + serializedObject.ApplyModifiedProperties(); + + } + + [DrawGizmo(GizmoType.Selected)] + private static void DrawGizmos(ObiRod actor, GizmoType gizmoType) + { + Handles.color = Color.white; + if (actor.rodBlueprint != null) + ObiPathHandles.DrawPathHandle(actor.rodBlueprint.path, actor.transform.localToWorldMatrix, actor.rodBlueprint.thickness ,20); + } + + } + +} + + diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRodEditor.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRodEditor.cs.meta new file mode 100644 index 00000000..43404e2f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRodEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d55c0f03ad50c414cacd39520aef2087 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeChainRendererEditor.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeChainRendererEditor.cs new file mode 100644 index 00000000..76570ef5 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeChainRendererEditor.cs @@ -0,0 +1,54 @@ +using UnityEditor; +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Obi{ + + [CustomEditor(typeof(ObiRopeChainRenderer)), CanEditMultipleObjects] + public class ObiRopeChainRendererEditor : Editor + { + + ObiRopeChainRenderer renderer; + + public void OnEnable(){ + renderer = (ObiRopeChainRenderer)target; + } + + [MenuItem("CONTEXT/ObiRopeChainRenderer/Bake mesh")] + static void Bake(MenuCommand command) + { + ObiRopeChainRenderer renderer = (ObiRopeChainRenderer)command.context; + + if (renderer.actor.isLoaded) + { + var system = renderer.actor.solver.GetRenderSystem() as ObiChainRopeRenderSystem; + + if (system != null) + { + var mesh = new Mesh(); + system.BakeMesh(renderer, ref mesh, true); + ObiEditorUtils.SaveMesh(mesh, "Save chain mesh", "chain mesh"); + GameObject.DestroyImmediate(mesh); + } + } + } + + public override void OnInspectorGUI() { + + serializedObject.UpdateIfRequiredOrScript(); + + Editor.DrawPropertiesExcluding(serializedObject,"m_Script"); + + // Apply changes to the serializedProperty + if (GUI.changed){ + + serializedObject.ApplyModifiedProperties(); + } + + } + + } +} + diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeChainRendererEditor.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeChainRendererEditor.cs.meta new file mode 100644 index 00000000..f9953042 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeChainRendererEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 0efaf4d397fcc4b87842866f9a69f07b +labels: +- ObiRope +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeCursorEditor.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeCursorEditor.cs new file mode 100644 index 00000000..18d81009 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeCursorEditor.cs @@ -0,0 +1,98 @@ +using UnityEditor; +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Obi +{ + + [CustomEditor(typeof(ObiRopeCursor)), CanEditMultipleObjects] + public class ObiRopeCursorEditor : Editor + { + SerializedProperty cursorMu; + SerializedProperty sourceMu; + SerializedProperty direction; + + public void OnEnable() + { + cursorMu = serializedObject.FindProperty("m_CursorMu"); + sourceMu = serializedObject.FindProperty("m_SourceMu"); + direction = serializedObject.FindProperty("direction"); + } + + public override void OnInspectorGUI() + { + serializedObject.UpdateIfRequiredOrScript(); + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(cursorMu); + if (EditorGUI.EndChangeCheck()) + { + foreach (var t in targets) + (t as ObiRopeCursor).UpdateCursor(); + } + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(sourceMu); + if (EditorGUI.EndChangeCheck()) + { + foreach (var t in targets) + (t as ObiRopeCursor).UpdateSource(); + } + + EditorGUILayout.PropertyField(direction); + + // Apply changes to the serializedProperty + if (GUI.changed) + serializedObject.ApplyModifiedProperties(); + + } + + private static void DrawArrow() + { + Gizmos.DrawLine(Vector3.left, Vector3.up); + Gizmos.DrawLine(Vector3.right, Vector3.up); + Gizmos.DrawLine(Vector3.left, Vector3.down); + Gizmos.DrawLine(Vector3.right, Vector3.down); + Gizmos.DrawLine(Vector3.left, Vector3.forward); + Gizmos.DrawLine(Vector3.right, Vector3.forward); + Gizmos.DrawLine(Vector3.up, Vector3.forward); + Gizmos.DrawLine(Vector3.down, Vector3.forward); + } + + [DrawGizmo(GizmoType.Selected)] + private static void DrawGizmos(ObiRopeCursor cursor, GizmoType gizmoType) + { + var rope = cursor.GetComponent(); + if (rope.solver != null) + { + Gizmos.color = new Color(1, 0.5f, 0, 0.75f); + + // draw source particle: + int sourceIndex = cursor.sourceParticleIndex; + + if (sourceIndex >= 0 && rope.IsParticleActive(rope.solver.particleToActor[sourceIndex].indexInActor)) + { + Vector3 pos = rope.GetParticlePosition(sourceIndex); + Gizmos.DrawWireSphere(pos, HandleUtility.GetHandleSize(pos) * 0.4f); + } + + // draw cursor: + var element = cursor.cursorElement; + + if (element != null && element.particle1 != element.particle2) + { + Vector3 pos = rope.GetParticlePosition(cursor.direction ? element.particle1 : element.particle2); + Vector3 pos2 = rope.GetParticlePosition(cursor.direction ? element.particle2 : element.particle1); + Vector3 direction = pos2 - pos; + + float size = HandleUtility.GetHandleSize(pos) * 0.4f; + Gizmos.matrix = Matrix4x4.TRS(pos, Quaternion.LookRotation(direction), Vector3.one * size); + DrawArrow(); + } + } + } + } +} + diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeCursorEditor.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeCursorEditor.cs.meta new file mode 100644 index 00000000..f740a0b2 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeCursorEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e3ec1bf77ba7a47b596abdc62069c72b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeEditor.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeEditor.cs new file mode 100644 index 00000000..9fe40c8f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeEditor.cs @@ -0,0 +1,213 @@ +using UnityEditor; +using UnityEditor.EditorTools; +using UnityEngine; + +namespace Obi +{ + + [CustomEditor(typeof(ObiRope))] + public class ObiRopeEditor : Editor + { + + [MenuItem("GameObject/3D Object/Obi/Obi Rope", false, 300)] + static void CreateObiRope(MenuCommand menuCommand) + { + GameObject go = new GameObject("Obi Rope", typeof(ObiRope), typeof(ObiRopeExtrudedRenderer)); + var renderer = go.GetComponent(); + renderer.material = ObiEditorUtils.GetDefaultMaterial(); + ObiEditorUtils.PlaceActorRoot(go, menuCommand); + } + + ObiRope actor; + + SerializedProperty ropeBlueprint; + + SerializedProperty collisionMaterial; + SerializedProperty selfCollisions; + SerializedProperty surfaceCollisions; + + SerializedProperty distanceConstraintsEnabled; + SerializedProperty stretchingScale; + SerializedProperty stretchCompliance; + SerializedProperty maxCompression; + + SerializedProperty bendConstraintsEnabled; + SerializedProperty bendCompliance; + SerializedProperty maxBending; + SerializedProperty plasticYield; + SerializedProperty plasticCreep; + + SerializedProperty aerodynamicsEnabled; + SerializedProperty drag; + SerializedProperty lift; + + SerializedProperty tearingEnabled; + SerializedProperty tearResistanceMultiplier; + SerializedProperty tearRate; + + GUIStyle editLabelStyle; + + public void OnEnable() + { + actor = (ObiRope)target; + + ropeBlueprint = serializedObject.FindProperty("m_RopeBlueprint"); + + collisionMaterial = serializedObject.FindProperty("m_CollisionMaterial"); + selfCollisions = serializedObject.FindProperty("m_SelfCollisions"); + surfaceCollisions = serializedObject.FindProperty("m_SurfaceCollisions"); + + distanceConstraintsEnabled = serializedObject.FindProperty("_distanceConstraintsEnabled"); + stretchingScale = serializedObject.FindProperty("_stretchingScale"); + stretchCompliance = serializedObject.FindProperty("_stretchCompliance"); + maxCompression = serializedObject.FindProperty("_maxCompression"); + + bendConstraintsEnabled = serializedObject.FindProperty("_bendConstraintsEnabled"); + bendCompliance = serializedObject.FindProperty("_bendCompliance"); + maxBending = serializedObject.FindProperty("_maxBending"); + plasticYield = serializedObject.FindProperty("_plasticYield"); + plasticCreep = serializedObject.FindProperty("_plasticCreep"); + + aerodynamicsEnabled = serializedObject.FindProperty("_aerodynamicsEnabled"); + drag = serializedObject.FindProperty("_drag"); + lift = serializedObject.FindProperty("_lift"); + + tearingEnabled = serializedObject.FindProperty("tearingEnabled"); + tearResistanceMultiplier = serializedObject.FindProperty("tearResistanceMultiplier"); + tearRate = serializedObject.FindProperty("tearRate"); + + } + + private void DoEditButton() + { + using (new EditorGUI.DisabledScope(actor.ropeBlueprint == null)) + { + EditorGUILayout.BeginHorizontal(); + GUILayout.Space(EditorGUIUtility.labelWidth); + EditorGUI.BeginChangeCheck(); + bool edit = GUILayout.Toggle(ToolManager.activeToolType == typeof(ObiPathEditor), new GUIContent(Resources.Load("EditCurves")), "Button", GUILayout.MaxWidth(36), GUILayout.MaxHeight(24)); + EditorGUILayout.LabelField("Edit path", editLabelStyle, GUILayout.ExpandHeight(true), GUILayout.MaxHeight(24)); + if (EditorGUI.EndChangeCheck()) + { + if (edit) + ToolManager.SetActiveTool(); + else + ToolManager.RestorePreviousPersistentTool(); + + SceneView.RepaintAll(); + } + EditorGUILayout.EndHorizontal(); + } + } + + public override void OnInspectorGUI() + { + if (editLabelStyle == null) + { + editLabelStyle = new GUIStyle(GUI.skin.label); + editLabelStyle.alignment = TextAnchor.MiddleLeft; + } + + serializedObject.UpdateIfRequiredOrScript(); + + if (actor.sourceBlueprint != null && actor.ropeBlueprint.path.ControlPointCount < 2) + { + actor.ropeBlueprint.GenerateImmediate(); + } + + using (new EditorGUI.DisabledScope(ToolManager.activeToolType == typeof(ObiPathEditor))) + { + GUILayout.BeginHorizontal(); + EditorGUI.BeginChangeCheck(); + + EditorGUILayout.PropertyField(ropeBlueprint, new GUIContent("Blueprint")); + + if (actor.ropeBlueprint == null) + { + if (GUILayout.Button("Create", EditorStyles.miniButton, GUILayout.MaxWidth(80))) + { + string path = EditorUtility.SaveFilePanel("Save blueprint", "Assets/", "RopeBlueprint", "asset"); + if (!string.IsNullOrEmpty(path)) + { + path = FileUtil.GetProjectRelativePath(path); + ObiRopeBlueprint asset = ScriptableObject.CreateInstance(); + + AssetDatabase.CreateAsset(asset, path); + AssetDatabase.SaveAssets(); + + actor.ropeBlueprint = asset; + } + } + } + + if (EditorGUI.EndChangeCheck()) + { + foreach (var t in targets) + { + (t as ObiRope).RemoveFromSolver(); + (t as ObiRope).ClearState(); + } + serializedObject.ApplyModifiedProperties(); + foreach (var t in targets) + (t as ObiRope).AddToSolver(); + } + + GUILayout.EndHorizontal(); + } + + DoEditButton(); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Collisions", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(collisionMaterial, new GUIContent("Collision material")); + EditorGUILayout.PropertyField(selfCollisions, new GUIContent("Self collisions")); + EditorGUILayout.PropertyField(surfaceCollisions, new GUIContent("Surface-based collisions")); + + EditorGUILayout.Space(); + ObiEditorUtils.DoToggleablePropertyGroup(tearingEnabled, new GUIContent("Tearing"), + () => + { + EditorGUILayout.PropertyField(tearResistanceMultiplier, new GUIContent("Tear resistance")); + EditorGUILayout.PropertyField(tearRate, new GUIContent("Tear rate")); + }); + ObiEditorUtils.DoToggleablePropertyGroup(distanceConstraintsEnabled, new GUIContent("Distance Constraints", Resources.Load("Icons/ObiDistanceConstraints Icon")), + () => + { + EditorGUILayout.PropertyField(stretchingScale, new GUIContent("Stretching scale")); + EditorGUILayout.PropertyField(stretchCompliance, new GUIContent("Stretch compliance")); + EditorGUILayout.PropertyField(maxCompression, new GUIContent("Max compression")); + }); + + ObiEditorUtils.DoToggleablePropertyGroup(bendConstraintsEnabled, new GUIContent("Bend Constraints", Resources.Load("Icons/ObiBendConstraints Icon")), + () => + { + EditorGUILayout.PropertyField(bendCompliance, new GUIContent("Bend compliance")); + EditorGUILayout.PropertyField(maxBending, new GUIContent("Max bending")); + EditorGUILayout.PropertyField(plasticYield, new GUIContent("Plastic yield")); + EditorGUILayout.PropertyField(plasticCreep, new GUIContent("Plastic creep")); + }); + + ObiEditorUtils.DoToggleablePropertyGroup(aerodynamicsEnabled, new GUIContent("Aerodynamics", Resources.Load("Icons/ObiAerodynamicConstraints Icon")), + () => { + EditorGUILayout.PropertyField(drag, new GUIContent("Drag")); + EditorGUILayout.PropertyField(lift, new GUIContent("Lift")); + }); + + if (GUI.changed) + serializedObject.ApplyModifiedProperties(); + + } + + [DrawGizmo(GizmoType.Selected)] + private static void DrawGizmos(ObiRope actor, GizmoType gizmoType) + { + Handles.color = Color.white; + if (actor.ropeBlueprint != null) + ObiPathHandles.DrawPathHandle(actor.ropeBlueprint.path, actor.transform.localToWorldMatrix, actor.ropeBlueprint.thickness, 20, false); + } + + } + +} + + diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeEditor.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeEditor.cs.meta new file mode 100644 index 00000000..78df88c8 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7e5f7e0daf504c86885734478e9c965 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeExtrudedRendererEditor.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeExtrudedRendererEditor.cs new file mode 100644 index 00000000..02a4983f --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeExtrudedRendererEditor.cs @@ -0,0 +1,55 @@ +using UnityEditor; +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Obi{ + + [CustomEditor(typeof(ObiRopeExtrudedRenderer)), CanEditMultipleObjects] + public class ObiRopeExtrudedRendererEditor : Editor + { + + ObiRopeExtrudedRenderer renderer; + + public void OnEnable(){ + renderer = (ObiRopeExtrudedRenderer)target; + } + + [MenuItem("CONTEXT/ObiRopeExtrudedRenderer/Bake mesh")] + static void Bake(MenuCommand command) + { + ObiRopeExtrudedRenderer renderer = (ObiRopeExtrudedRenderer)command.context; + + if (renderer.actor.isLoaded) + { + var system = renderer.actor.solver.GetRenderSystem() as ObiExtrudedRopeRenderSystem; + + if (system != null) + { + var mesh = new Mesh(); + system.BakeMesh(renderer, ref mesh, true); + ObiEditorUtils.SaveMesh(mesh, "Save rope mesh", "rope mesh"); + GameObject.DestroyImmediate(mesh); + } + } + } + + public override void OnInspectorGUI() { + + serializedObject.UpdateIfRequiredOrScript(); + + Editor.DrawPropertiesExcluding(serializedObject,"m_Script"); + + // Apply changes to the serializedProperty + if (GUI.changed){ + + serializedObject.ApplyModifiedProperties(); + + } + + } + + } +} + diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeExtrudedRendererEditor.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeExtrudedRendererEditor.cs.meta new file mode 100644 index 00000000..50deeab9 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeExtrudedRendererEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 0d0e145ce66cd47e798bf4b926eddfc2 +labels: +- ObiRope +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeLineRendererEditor.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeLineRendererEditor.cs new file mode 100644 index 00000000..586d69b1 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeLineRendererEditor.cs @@ -0,0 +1,38 @@ +using UnityEditor; +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Obi{ + + [CustomEditor(typeof(ObiRopeLineRenderer)), CanEditMultipleObjects] + public class ObiRopeLineRendererEditor : Editor + { + + ObiRopeLineRenderer renderer; + + public void OnEnable(){ + renderer = (ObiRopeLineRenderer)target; + } + + public override void OnInspectorGUI() { + + serializedObject.UpdateIfRequiredOrScript(); + + Editor.DrawPropertiesExcluding(serializedObject,"m_Script"); + + // Apply changes to the serializedProperty + if (GUI.changed){ + + serializedObject.ApplyModifiedProperties(); + + //renderer.UpdateRenderer(null); + + } + + } + + } +} + diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeLineRendererEditor.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeLineRendererEditor.cs.meta new file mode 100644 index 00000000..5accc43c --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeLineRendererEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: c0a72c38772bb454dabc7efc5b8f03be +labels: +- ObiRope +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeMeshRendererEditor.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeMeshRendererEditor.cs new file mode 100644 index 00000000..2d110592 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeMeshRendererEditor.cs @@ -0,0 +1,52 @@ +using UnityEditor; +using UnityEngine; + +namespace Obi{ + + [CustomEditor(typeof(ObiRopeMeshRenderer)), CanEditMultipleObjects] + public class ObiRopeMeshRendererEditor : Editor + { + + ObiRopeMeshRenderer renderer; + + [MenuItem("CONTEXT/ObiRopeMeshRenderer/Bake mesh")] + static void Bake(MenuCommand command) + { + ObiRopeMeshRenderer renderer = (ObiRopeMeshRenderer)command.context; + + if (renderer.actor.isLoaded) + { + var system = renderer.actor.solver.GetRenderSystem() as ObiMeshRopeRenderSystem; + + if (system != null) + { + var mesh = new Mesh(); + system.BakeMesh(renderer, ref mesh, true); + ObiEditorUtils.SaveMesh(mesh, "Save rope mesh", "rope mesh"); + GameObject.DestroyImmediate(mesh); + } + } + } + + public void OnEnable(){ + renderer = (ObiRopeMeshRenderer)target; + } + + public override void OnInspectorGUI() { + + serializedObject.UpdateIfRequiredOrScript(); + + Editor.DrawPropertiesExcluding(serializedObject,"m_Script"); + + // Apply changes to the serializedProperty + if (GUI.changed){ + + serializedObject.ApplyModifiedProperties(); + + } + + } + + } +} + diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeMeshRendererEditor.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeMeshRendererEditor.cs.meta new file mode 100644 index 00000000..6a6c6a27 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeMeshRendererEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 297abfc8979aa46329f3a7e914866adc +labels: +- ObiRope +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeSectionEditor.cs b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeSectionEditor.cs new file mode 100644 index 00000000..b5c6fe48 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeSectionEditor.cs @@ -0,0 +1,213 @@ +using UnityEditor; +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Obi{ + + /** + * Custom inspector for ObiParticleRenderer component. + */ + + [CustomEditor(typeof(ObiRopeSection))] + public class ObiRopeSectionEditor : Editor + { + + ObiRopeSection section; + bool[] selected = new bool[0]; + + Color previewBck = new Color(0.2f,0.2f,0.2f,1); + Color previewLines = new Color(0.15f,0.15f,0.15f,1); + + public void OnEnable(){ + section = (ObiRopeSection)target; + } + + public override bool HasPreviewGUI(){ + return true; + } + + private void ResetSelection(){ + selected = new bool[section.Segments]; + } + + public override void OnInspectorGUI() { + + serializedObject.UpdateIfRequiredOrScript(); + + Editor.DrawPropertiesExcluding(serializedObject,"m_Script"); + + GUI.enabled = !EditorApplication.isPlaying; + GUILayout.Label("Presets"); + + GUILayout.BeginHorizontal(); + if (GUILayout.Button("4-segment circle")){ + Undo.RecordObject(section, "Set rope section preset"); + section.CirclePreset(4); + ResetSelection(); + } + + if (GUILayout.Button("8-segment circle")){ + Undo.RecordObject(section, "Set rope section preset"); + section.CirclePreset(8); + ResetSelection(); + } + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + if (GUILayout.Button("12-segment circle")){ + Undo.RecordObject(section, "Set rope section preset"); + section.CirclePreset(12); + ResetSelection(); + } + + if (GUILayout.Button("16-segment circle")){ + Undo.RecordObject(section, "Set rope section preset"); + section.CirclePreset(16); + ResetSelection(); + } + GUILayout.EndHorizontal(); + + GUILayout.Label("Tools"); + if (GUILayout.Button("Add vertex")){ + Undo.RecordObject(section, "Add rope vertex"); + section.vertices.Add(Vector2.zero); + } + + if (GUILayout.Button("Remove selected vertices")){ + Undo.RecordObject(section, "Remove rope vertices"); + for (int i = selected.Length-1; i > 0; --i){ + if (selected[i] && section.vertices.Count > 3) + section.vertices.RemoveAt(i); + } + // special cases: first vertex: + if (selected[0] && section.vertices.Count > 3){ + section.vertices.RemoveAt(0); + section.vertices[section.vertices.Count-1] = section.vertices[0]; + } + + ResetSelection(); + } + GUI.enabled = true; + + // Apply changes to the serializedProperty + if (GUI.changed){ + serializedObject.ApplyModifiedProperties(); + EditorUtility.SetDirty(target); + } + + } + + private void DrawSectionOutline(Rect region, Color color){ + // Draw segment lines: + Handles.BeginGUI( ); + Color oldColor = Handles.color; + Handles.color = color; + Vector3[] points = new Vector3[section.vertices.Count]; + for (int i = 0; i < section.vertices.Count; i++){ + points[i] = new Vector3(region.center.x + section.vertices[i].x * region.width * 0.5f, + region.center.y + section.vertices[i].y * region.height * 0.5f,0); + } + Handles.DrawAAPolyLine(points); + Handles.EndGUI(); + Handles.color = oldColor; + } + + private void DrawDrawingArea(Rect region){ + // Draw drawing area grid: + Handles.BeginGUI(); + Handles.DrawSolidRectangleWithOutline(region,previewBck,previewLines); + + Color oldColor = Handles.color; + Handles.color = previewLines; + + if (section.snapX > 5){ + float x = region.center.x; + while (x < region.xMax){ + Handles.DrawLine(new Vector3(x,region.yMin,0),new Vector3(x,region.yMax,0)); + x += section.snapX; + } + x = region.center.x - section.snapX; + while (x > region.xMin){ + Handles.DrawLine(new Vector3(x,region.yMin,0),new Vector3(x,region.yMax,0)); + x -= section.snapX; + } + } + + if (section.snapY > 5){ + float y = region.center.y; + while (y < region.yMax){ + Handles.DrawLine(new Vector3(region.xMin,y,0),new Vector3(region.xMax,y,0)); + y += section.snapY; + } + y = region.center.y - section.snapY; + while (y > region.yMin){ + Handles.DrawLine(new Vector3(region.xMin,y,0),new Vector3(region.xMax,y,0)); + y -= section.snapY; + } + } + + Handles.color = oldColor; + Handles.EndGUI(); + } + + public override void OnPreviewGUI(Rect region, GUIStyle background) + { + DrawSectionOutline(region, Color.red); + } + + public override void OnInteractivePreviewGUI(Rect region, GUIStyle background) + { + Array.Resize(ref selected,section.Segments); + + // Calculate drawing area rect: + Vector2 oldCenter = region.center; + if (region.width > region.height) + region.width = region.height; + if (region.height > region.width) + region.height = region.width; + + region.width -= 10; + region.height -= 15; + + region.center = oldCenter; + + // Draw background and lines: + DrawDrawingArea(region); + + // Draw the section outline: + DrawSectionOutline(region, Color.white); + + // Draw all draggable vertices: + for (int i = 0; i < section.Segments; i++){ + + float x = region.center.x + section.vertices[i].x * region.width * 0.5f; + float y = region.center.y + section.vertices[i].y * region.height * 0.5f; + Vector2 pos = new Vector2(x,y); + + bool oldSelection = selected[i]; + Vector2 olsPos = pos; + selected[i] = ObiDraggableIcon.Draw(selected[i],i,ref pos,Color.red); + + if (selected[i] != oldSelection) + this.Repaint(); + + if (pos != olsPos){ + + pos.x = Mathf.Clamp(ObiRopeSection.SnapTo(pos.x - region.center.x,section.snapX,5) / (region.width * 0.5f),-1,1); + pos.y = Mathf.Clamp(ObiRopeSection.SnapTo(pos.y - region.center.y,section.snapY,5) / (region.height * 0.5f),-1,1); + section.vertices[i] = pos; + if (i == 0) + section.vertices[section.Segments] = pos; + + EditorUtility.SetDirty(target); + } + } + + } + + } + +} + diff --git a/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeSectionEditor.cs.meta b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeSectionEditor.cs.meta new file mode 100644 index 00000000..c12c5c62 --- /dev/null +++ b/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeSectionEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 1539d8c58261942e28859228dfa310fb +labels: +- ObiRope +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/QuickstartGuide_rope.pdf b/xiaofang/Assets/Obi/QuickstartGuide_rope.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d2071e966bf1d11475aea3d15659954c691acee3 GIT binary patch literal 53087 zcmcG#by$_%*DflE5-J@c-Lfd@E-9r!)}lqayQD*q?rubS(Ops^-6bx%J48}yPu}-; zzHjey_I36j=Q{kcE?7Lzobwsam}A`IzQ?3fmXu~;XXV16`=0x~<$K-tEDR3HSCqB} z78pW8Z1To7rcP#*oZuT(HfeJ!Cu0XTX)ApvV@YE}TO(r;5e!Es2V;F}jF0IVy20jfPwt0mFQzp1sUt{g^*d1o*fpvzex?sHNr&(4%`jKSM01(jP1EJYyFV?BpU!zH7DR-7 zE>Hd%Ket(+SRf}VLmm?T{>1V{yk}9BbQ_~HORINOO}ZfA+EVD zE&Q_F-{QAif%|Qhdj0D3Q~ODzEV3R^a_?Vr!d3@K>{|gyuX=pKyHIDuj^@iE#A@^@ zU1>DM_ZvAM%!LI&t7Q}+v2wN&onv_>e*4; z?;&KdT4kQ$7B=AIQav}+DV0FkZ+LbAS=#YB7Wu8 z^^6>c#?TaPr9kj@jHrfTiQz=w38Snp&6KE1_r(l}XyxlJbT{W3?JC!t@?dI(5O2j6 z?Ep3x=u(HJ|A(dbuc+Qwb7rtb(63M~aA;;_@nEd|{hD)9pT%4J%VPBOondWI$I0s9 z#&<2{898xr_+%!##S47tC|ta3;uUl>N_JeNz}qFSp6~7^q3G?E-J=>h?KGw^*m0l+ z)n3HQOi#+3R;g}flR922QiNqXZ4X#T3)@M)VauEGC>-nij2elpnld# zr;v!0jE$i`EFP!kN?-HsVaJO{nB$2$1D;t(@qpH^%QYja25&Tcq#8i&hhDWsvJ4`uWi-V!CY2$Nu@A+ zGX6k2;VjylK-%p&{7U|ucW`|31A5~G{;3(P-`HXO6`oDd%FRnLj6Kfdn(b#4UZ<^J zjzZTTQJku7uQx?=o`kbd$*L(&I!WCmIR6MsHRw<+RJAxupnn?}t;IS<&N@~$tNE)t zPptF_W$L(_fU$vB-(Lo3il>$1deZyui=oUFvBJK{F>bU{qUmDNq>SGN-i#;ZPb)j%cTp$iKX5Nv1Qb8CE{-D9{X=0EzU?{ zMpR;Jzp8!RVMQc^Cu-M{XU4HsENer8$46S5r<>)IsM6GOo(n&5m>=W5-pQ%#T;O&{ zzC4BS&y=OaJ1=k5=!IfGUzb`E*8a!u*iXcNQJ;5N zi7;YYV@Tk9McWsfBL2Y4O5-3B5RySXn1@1TY5c1fw>Cd2W#or@KN^daA8mI@=EEUG zN9@+!OYoX_6{Lg11 z8z)pXmnXiUWnq`owBQoW7W{G2f@d3Ptw`;%s}(W!u2b$e#=7J@h&n&U>=0myjpfR0 zV&>LqR85>yqSsOG{~EyH-YUyjU8-9UpS_{Z$^Y1zRn6f;xob4y6jL>d-=Z&`yGVFC zPb6B`yc8dI=aJ8|{c|KE{LS8Rn>NI~ zt&G$dC}x)T&*^R7|KQbXNj_kt^)v|+k6xtb9Vrr78DWozB@m)M3mRW9HtTN1*FnD zA^8&;6mNT6;NBts_K%8wcG3PM4)vYYVv9#rKL71R1&)sOO*!#9G#-i3ZiyFm0UZKC zPd+MpN&8_DKWee#66yWuw_Fxzzj%#G9}u{LVQgdcpM(Z}yU&3b_o?sx7j|AwuKR!g z`z67em>U|a%Dl$- zpR@0NMu;OJwDla$>}(O9*ZvZMOv8%yiR4vbw!Z)*SsaDn@h>8r*l27tY-C#6=&k_n z0lMf2mM?E!Bhw}b=i;KF_p;LDEFc-D6UEmb%v~|G=w&Sqxy>FF2;S^zwr0uZWp18q zPZW$y%x{8Eey<&TssQZQX#cy9ZN#-O)rwwR(CUcdT7G{1&DFUn_;Gsxlc9do|Fc>8 zpS!NV*AJKmt0F38KYp;WDPs^Rdh}L>8U231CRAC*eGOwn!_^oXnbfp2+r`!!Tdek- zHz;qZ#6|aL{+aYQV^V#0qfr7B3RM=zN>B}8GyiGYT867Z3#&Dk>_=>5^YUb4sIM*o@7r9n1C_J0Kd_u*tILFuXYHEC7fZtnYmT=+s8I#OC z$?xi*8SDH}(`*)7>&5Ftk<-a{F1UBse@5tT=Uo@Ar#Ii_ZO3Yf<=3DK2SjtZJ`LeZ} z?3Q2CC2H5(B#3>5CMG0&33!5mkzPz=lOHKif$fp7K@%mEqg~_n$0Px@V5B2PgzGtn zj;gA`pfAE*K_Mbwi5#_2*l8;|@ay!?pNGGyQOy$*6H|ZOd$H%U9d2DcSv40lQSWQM z6AoJ1+_JKR`0sQz_7$N)pIimfpnp@lySu00>a!}cl7IT~BX^wne{QxhQ2ABKma48) zyTr)BLTLVEdK}>B&(@g7P4LYGNPfIrPok5wOsK7`{VEd$n?9d0j3N#?3J47B8~^#< zV~Cl75QhGtrAjU7V)=W}qT6N$a3>|>Y`r#bz8^JBg>{k1!J<|(uLv$f7&6}|D)J=u z%>oa#Pp`{WvbEbnEL<%Ymy~4M z1Np{5yJIC@hx?;lD=$#B$s%DOkp<6wXR)nKlXOZA%?*$Lr&b<}k>Cj-^JxB3BUI$} zVztU?su&8v-VAehDK{KUX5S%Ku)Zm+UvU4sUEs`4HMKik`p$e~V#d39*r^bT#@J7{KLt>7QE#DnB#{diKy>q zi^6wJu9Ab9m&TWA8Qa-ayqxej{ANm6@a2nmt?9<*X4d#~%Fe^qtAq1JAD@YQ1+Zg@ zIgEk>7Qtn>?~X-&5DeqRuqnH#tScL_7TEZw_=|_s#6G5vTtLVmqiuz6Nmwf`|gZgyOguB)$z7ol>$;M0_JQJ+?+njUfw`5Zbrx{UGX zONZX)g7aM4vV#?&7*2hVp$6cvwHYLO?%Q4etxS+;DXxK`NrIx@ zvk5AnMf@Vkv1f26f(&S;h!?^viYH+l3MUnGDfx(h-A|qBj>3$Uoq+Vh!|>o&wG81r za0rXu@J-mSdRsl~Lz$yqnyB8Kni?)$)z$8ZIH@N@tdllgYrQc|$$WUmW4=fak50#A zC=$v?g#HXhFXqTD9W8$+d?W=D!AGKMhNUlGz7&vJGnyc_PZ^fHJr=CHY?ayrOSS7? zB&ZGrtU|O@YHSnqY&CWkHo}$KoiWYz7(w6!**T0^Q)rfjkx|8kVPfy)Ls9{!Le^v8 z3uHq%ofZ{GdNaN#s(p`Luq~TbqcJhDL%=U*aNE zK|8s0DTvDX-YYw;YKGVP;+EC3y#E$WUi)^)vLAOKK6*greZ9a}E7J%afflJOW#ZGfm#%_sS1k8R1FT;~DVIbl2wQbTrpo zwDVkQhR5^d=#KnQ$w&9&E#PXauJ|U_3ElP4JwJZ*<@h~BwV3Go9cSiWhsAIod@RE` zpZx0D9isHBl@+b_IJYT zYSf2oT?t=^1+W4Q{n@jG@=>{cp`C<;gc0HMxvjCU`d{9s&(>Nd z*%!Gk&b*`o*3)aN978LSC{cw|lo|9u?poQ$1#proGRrv@{1oz>zC${a*$v}ePY>ov z4$cpn4?Dk3GRL?sdezrmD$c^(lD@VXSXnWL-V_yN#vU!+9JnHo3^Fz7_6|}^Gh?L6 zTaH69e!gIyB;sgv-ksL0HYqya8%*JpsXz4~l~3g||Ni+I_M55PUj<4OI2*uGxe+(O z{PObhbJeCwIy&j9mSNX;VAHmK=Nl!Niev6Xou`&OlOnH4JCgcKxV7=IM_tqk|8Z4^ z-;b*d!LCTCJ7e2jn8zW~c@C6^hvzlTA;)qDD#fJ2XztUaK%)1fFNzGta-}6S5%(-_GBYzJd&82)Y)(Wp-|Vt;?bT*3iWyW)*Hg zywhG7pQ#c32&tz39|#p$e*4QN<)M=5)+mH6kM1K)!CjWGcHV==7d%$U7FjI=V>bNy zodG#H)VlJePyhp>$OK`fr@-@iy1KSjJZ`(CxdqpwsU&KayU%^k4;L5rgqLOnWTojI zWqSYJ9!lfgt%K_5Tu*D;nok6%E2Z;QR#lBFvg6*zGHN!q5pxPTq%dG;3r=LdYGpA5 z+oQWhyO*bo5LC!#4gA_42`>&-6v{!x!|XP1Ak_JB#F zgpv{yU)YX@D~6f%mY&X|jtki>iAhU$1Nb}n#0!L{=yrd1p8q>mZY}eF$oJ%Lk=P0R z1VaFBWo@zdk!+-}xY!?cq19{FF;9~E4F>vOfe~FaL6$raPSB{{%a|s3&lngQ(x_E5 zHvW>R?79c{+Z!X>%cGF{8UPo&2If{rIg6!jWo}+nSje|R7abqfwC$o|mT*4;I@&&r ze`S#U?%Qu-@|l^LmrFqC&-kwIcrQTc;$VBxj`S{ z`$XNWiWWq6tKT}ewcTBvy`xU7k-cB~MKHx|X>99Q#B#a({qpoA7Pruk)ak)}!R23U zPf#wH?)OI5&rx1?+G6!bXqn6dw)O0)Dnac9H zy~L!V74zJbD+3_$&xS(!2H!6!=6`O>i4XSN9?v7;wYh%N#C&mi%e~2FkWjxsCVxLo zaB(q2MHWni)KdT}nme8@)uv87emPeJg{iBDsg5%=qqZ@pA1&JQl^kbuL_G39*4hVF zWEoe!pIA)2AOPD(BQKav(QQg+dlHiO$TbRKpvL9 z?y|ghI&WXt+c%pXwlH+F1Yr#DYPzt%*V{rf_??zN%LoVvN_CrE4(1x)kuE)KrN$0x z%7Z4x#|M1=tmstnp~F8tJso6Mkpu<`)yMvU}BWg)0 zsY}r;)|i9@09V>XZ?=`Drl#)QG{c|VAfeErGR?G2h-51~njCefM=FePYI+(GV%77Q z%ENJE@Dh%$ak9G>Fy9MN$`rcX6usl`ZKt@qkeS@}8=6(u^9tk$P(k4#aY1YN2Ss;N z;0PVHKg6S#FDxn=lU}H|r63gk-Gz5MQXn^&$}M+h&=W~!Q}P}PO#t;sR@UKZI1cX1 z!4eLBez$!@t+lna$<(6g?H`I@Yzm4)Z|7YZk?W)H3*S7l_#L|&3R_w{e^nU=zXFwX z;1itj*^R6c^e(@sl;QbaWuvi2Lpzsy|@g5T&BhKR=jP zFVkU{zCD|@#i8Qnp1QkqLQiYUkeh3;H*EJsV*7S7&enE4u5VJfSD9x=BD3F{d<1BV1!0kPQo7=kowZt)e&? zo`Rrj$ZJ2b_8+r2EVcXbAyfz!nw$sBPhHOjs)LV4C9vGIw*Qi=$@lK0^E)~%&jhM` zl_oySuxDgqX6DMLF&@|d#6SuiXJlfk4yG?6-kyU0l%eoilY;-oF}d^sAiqE{10!Kv zTEy*`mQeWSWWuk%RKe=j#bilcf@NZIGWSVTWTbSecAeGst4Eet_<8AE=C}u5>9RD) zm1sDU%*{|Gl06pMZH+x=Ix!_<{5HP{oA@(iH?C5)Kv?1tRaIcBDy~ zCMn$?5a9sW+a`)>7<%XT?-?*3-Cl^E&yBNDZC;)fiN?EkH0q5Y;16es`dppugA@@O z8tQ);{30(mcWb=TJORA76b@tAH*bPZJr!aRoq3NQo^wq?D zNW2sA`b&A8;kqy;eE@-(|EcGESb*z-*OSId>JmU>u{HXIEdK+QpPi6OKR`W}x{@e3 za=S9i8H*5mr!PV(HYU0+3zV{0QPVIQy>I@eaGFkXrGf3@=H>=m6H$BQs0M=>91dp) znr0yBa4AayZ@$`rmpg?;(^;WW2RvQcI0^p*S1;em`L&o>zFh-Dw;R{TDfVnchP$~0008|5ZPlMWc*Cn;yZ+>B6VNubx*4709`W4ULKZt^` zD0nvdlj-X+GcvrcFYK-TFG8g%D=Wv{-))HfeC8Wn_9h4xg1}}7W`C_-DXX({54MTk ze-tOV_>Lti1Q?p$I}+O#KZJNQngGs=7ZAa+-6y6K5NqlpGJXe1qDYKNpSxR)$vzLF zCAXC-}FK-Rq zO=DkQTU#^Dbd#P%#&Q+*`dbs~t3yn(BYL&RNzidycP(LBC%c^y?14gHP$L^QJphWb zr(v?PvNe8SNAo>$Ki$de_vs48;pgW^@WpO8jtB>Rf82KX5KD-XU8UR$RO}HE5#7mw zfq~;!$R!$;oy=LmA&W1PkS9fO8v(Hgh#3f?&U!YyXJqmAjF$)_K3XxP7TS8bk#-RU zXX274>Ht+P#koPlTUW%u!P)*S+8u})>r5hF>jFDdgsp$(ha>~{t#zI%F$P(v*VM=; zm&dLzmJaQDBJ0*@nw-z$%*y=L3KyT!>FfH&1vKSUHG=V)J!Fz`x%yT;3figQFw9GP;uCB_$LinOlE?U^t zd7_}CZ!~Hwf3jXK=azr1BWeHqjHJSBV=$%L%95S49YDTqxnKIWZ;{4wqv&9JIWWf1 z$nQ@@n{H~mASwmG&efp6a9dAMU+_2-Za^XIK$pU&g1^g`_v3j=!XuxHKRZtEpA)C$ zJz1#IfG?lMqd?we=$u#n?AbF4pX=WZ_N&+;AKHDR$c#)(`ck)Dn&WgRc!2`%CI&tO7QQs#)~4$yeBtMfyjyPNY$^uDz#%$3#E zc{aV*0;tn4O&IL+0Efs@abXw$6w1h}WKCru(xir<_$@@(^~0MRWysx(Kvmp5sMGB7 ztiBS#)e}zqY3F;BKVbzym&|ujd+#|{@q`qi}nYD5lFVvW z)A0es;HUD|zq0kNWOW0Y8k&G)n=ELuOX??t1Ty6|U3F(TXlNvl&CauGhg}0sj>?yGm(Hy3Ted7j_79swLl6|_n7Aw;`!Hvbk;C~C{Xx)>l8Ro$caCr_N+n)G z)LMQC{`Kn@LhSkQ#!%Yb2H=LF&G<2u822wSWJM}OA)Rk554_2aKO>@1i;B%#fTnuQ zhxv4`8AFnVV(qzN8F|%eqIi?#J#dhc_|++l&B@NLl9sR8CYv^U%#bkw85kJQcM^~E z#>93eIQRlxS@FfrEm3d;6^eMI_Jh+`TI2DdPetoP(bwbP*kvS5$-N8~ahQJ?*;V{x zKLCy#kgV%Je{Q7TK;E8zM?jXJM!$5+4vCW@=_rC`iu$~_>9>bDihn9j?d)8mqrGzigZM?U^}~}~tD$3%SghxA4OQITn^@ItwDX2M5sR)NA;?_` zZAw`pAftDS2h+^`^HNw?Sd<0r(T!B)m9CoG&DWJ{$b*bcd}nZ88aO&u^I&WL9A*qC zN8|;EinfETqnuGJ6uElz^zfdlW!6RQt>`fIk*FbIQxd5f@kaI-nC#E7-dO@M&5!3F5$4M8&UNo@0!N80{|4D<5p^BAN36FyB zgd`CsV5EBOEz83~uw0JOqn}w1_V>#+j(~MS{c2>#Z$Jh3o1dE-Y9xJSG+G3e-K;!c z@KCzy(m{~^J=^!#9;dTbV6n+3U(G=f#C#GopYYtwaK*j=M1VLB^n<*7c>2J!gjPDw z-@f$~kT+^HaI6+v$;SLYeR4LYCZZ$wxZ3?}o8f`S*g*yZjPZ0^@AjC;IvZ{r=7FTs zqb6^LB`L5~KhG`9s9kW`=Cc1n^@)QM`Dp(37bs$|;KoaxJ!ZslbJ#gqDXphis!f(M zN;2bi1%vZp0D}Zh43afv7t}K0qF6Vy7p*H)cM@_RpeSX+>g6m$psznTEst*--~2u8 zhOUWq4*5Ix11dIdLg(I;!i$M)z?9}F^;#n$S5^)VRXkM;Fn-4kc~9LYry_QGOa^99 z?8ovbEIBbp=>!{bybTF?w!MF9f`=KN579 zB^36oyW8vqFiKoc(x^b+?SB6531ZLqm-XZI0bEse^`LS&F+Hr;*494!XqC_q+~@e-S}uviIBedj zNd^#Mxt^yLR&;j~L6~H}Fh$OHrk+UQ5D?^9leVs=KoKMV*zk9UqR2ie+*P1THYJP_ z)Zg2xez2nG?c|Dgtfh1?^x2<*O3AONdf5dI4IkQdQuZjM^N1*N?THK?O(=5}gmOyw;cfbTA9iO%M!f*U_MiX*0xi_4HN+|vJ* zI;0+gKnkq$x%0L*QYsnuz7MorU7wxo2anA+HNH*6KxKQ10hKAB3rQyafaQtI`pHNo znYGl|BmwMu7xxB;T~H1+107x85h+qV))A8ZQ$g7Fc-^%$;4cac+t*2Zrj&REx`pBK zttW)x&)Hw6(MJ*%5GP`0H8fYw2$aTRlkt=uM}B?A()-&=<*_(PDF+`P-&Q?~RVa{f z-lBfoo-xtKAJ;3(&zEk^(R%9eRO&7bsj+uATqQ_|a$0!reVeyebi`N#09aM#x+#S% z=6-)rYL#jZVxcd#f0i!-2;xkWt;?dVW0GN`hDZmcj7QIERl+q9KECJTaINJ})qR`9fJ=%mdr9H3Y1n~0;Mp? zzU<8pAX5PP{F}uTWPb3qG#p<-Y?(JTd!r`a?^--^feoluN2J^2jbIN`dce$mv~P1c zwdoE{yPn$fLZ~t|@|*~@Dh;Ik&;eYX&JU3tGXHGci!}>Dw@1H%p)0%fMev|>n{0=m}~jsEdo!dGL{>)rI`CPI4F-2NhUaLAmzIQ%xC>sl^$X9 z5yKpxz{|N0Qg1V_wHV3wDpXA{M@Jj;Y`~>Ano7}7wm?Q>mn>>vI!CW?uQyx#)8xmO z|M3D3u@Y4y3BlmL;1r~@_LM+xD~j1Ft6v<|XbmH=Gzx*qntAet5p3Y;f6>a$VGiG(}U#Nx5C|W}r zw&r}bY1G7Z@_HQXtves9=6VDP?^@AfDz{}g>=G1%s44XY%U!NtOI6)p=H=(trDRJN z@kt>_?01WwwSfAm#!n-vJK==_t)wNCBhD5?rD#L9~zx@6~O;d`33&$Qa5YW zHJk~|7e4ifITOGdnC^rCD9d6}xL~>#Tl#kY>%WeF|H$rsJAWT&zA{(cjOUfeW9rBggoQCvYmq3IbNJ^hMSX?GeEJe}R} zGi$z(_jm--c@tE&xkrxen^Cy@8=@a{@RrrBAE-ec1Y)cgTJZSWPz3*9e2%Hd#Shdi zcYwl!$}jy+ORbBr7hl+-86zct69VbC`T>O5WsJ`|@|KyZ^i3gA0iZllUZ02?6Ho=2 z%f6uGnQN`pCvU+}N#EMgy|*jmiKT&1$o?jc6FWP`lTXA;$Y&jgS)IONF7mJy}CplEHEg36QX zau}!Ew91xi=M_t5V7_L^Wm+kQE|^pBQ!Am?z!=>>72~PDnuh=gUI`1``#D)5*cd+7 z>ZMJD#~{KgLpFTNFcjOg{QdaVBPhYJ@v0W6nqx5Jcm<^UQO*;ZEw7k*g=!g_JFtf1Q>RKvhET?9jhk}yP-y2{x?w-aKY{-!65vd4;r@2Pae z3p#G^XhRHtPSatt)illZs7TG1#!oR1*p}`|CSss*p`o`HoApFdBux;{rV6?qfI7%% z=@m6eDQ++GUyVoVpL26*lj^|641uoHlVpp3Q$&7|pV2*6l-4KL<4+oQ(mA^JN~7X~ zpFQCT=wIkpAYEx^QQ5fH0p^I7;Py;tUFDo6gU`D>S0i}WlKj`T!pS+Fxb{JmYTz7^ z6r{F0LxKTLx^oq>&r{ty%51Dk!ZXDp^1WopEqEsj8ot(WDm9el->xU={yO2v&FvTS?%sfw2*4N|7qg}BHSyjQ{pMz8XNO?#3XpNG z)InD^w4CJ5cPNtjVcswHEnSa5I~Hu{*L@yar;uWK_biHpSMiYm3tmyAO!#vug|J?% zvig}Cd9AXu-hVP%R7q74Xw4dPF!ubC%VlW6Q0x#|i~9P76mwn_UHFUI%oZ|SP%`{g z4OMlSc~~u{kr$nq$m4locWUsJvggkb6b>WSQ#I62SOOS%^fPe2LZ>Bf0IDXw;p2Me z&^IN0HwPJ7QD)b-u8!wp@EQvr-^`TtWrU(Zf>yR$l*r$g7IApaT!# zu=^Vn5Rm@L4eMg;tITpJqTXKrM@7Xex==*vQn4U_RQn$7D&mFeM;dEAj_@vL@}x)n z-V5%#EF_QKzA5N_21nszU$^4+sKe(-?jz8r9iDaE90MYN*J15Vqd>^c^TjF_}#!5U@z&^{9m%`ypozyc0!D;XU3PV z0VeVG6QUzf?S&idLxlNYMq*#4um>&2@#o{De&pg0>5t}3?r}y`32v~8C?F{>oNF@Z z5?Qnf*PcH#&@G-Oe<^mB8>6IbF4Jw^Sg5-eYcCxS%NDY?v$z=zZ)$3~zP>&=aVjwgFXt2s zerd3=zOK)5Xo`phJvQkk0zYsc}-tyO$lJ<8UO&!rSbmpeW2Z-&3;vSJBy}%wxgp1;m4AxO-Cy$ z`I3g_y9OrDz*#|-x4&m`v#rtd^V9B-E>PyK4!*&@XUQU7a6{VqC+@S*>Onv$yHenJnnxJ+@l5` z71irySJ3DCAm0L|nyIO}ga=E;CG6A}Mn{!ZRP?QWJCf);2f8Yy%I0v!guhCA#ot>7B{>;OoLqfz7K$z=VoUwRRXr__Hy%K z2F~jyth~IuLe2D6-bO(cZS7{WG3o-mWLHjs0?o^y;l@Ki+=smzG*Lpod$|rEoP9ry zI>%wwJ2*2F(0 z2V0M?4k+?koOcNo-O?}kZj_QWK-&~|3GUd8&M)CnEn~xuOkbE_K=eU4mwL|M2KQ6Q zd~EcC70WCTtLYUTRb)>O3=3dxIo}#N1O=}^jOF87rhzez1zP?u>B^eaRr2< zU{`Z1EBs2@fD>%H{?)D|Cf^h&^=lIo6O3&_o!ecxyHkYNb-(D{*}dSTrwoNk)zjwA zewxrB_hbUS9_pX>U>7e$KXFgSWuPh?P-AMfBx#is=hncTg~*Z_wF4a^ID$xThaWP2^0ezNxEsaIijC5Zu$NwfMMEvm^0_J z?79BALwjs)?kU}qn&E7!i--79j~qBPGE?sXb7x)aP993J(15jNn0f;e;H*$c>{ zy3qw~#%R?16-P1u)li`7?BSYKqKRT1x5%kWM_;LeIWH z|1${hKk`cmC#*zc41w68QLn)QZhSBB-Tf@)8{#{a>jt zIx~D0)=1?o;pKG$L<|xV64$*MaiGE7KT03C>-X>9M}2j5bwI2E%_&zfx8=@2ApHQn z5KtH;9tU&$t~X=+{|<(Iw^|1+)2=Ve%>a=bRF=P2q#De;y}g~BPWls=I5|1taQH}; z=%Js~&VQ}Gz7+KSIcW;&%YC=fqN_{D%p}Lb!C9dc67mG(GiU`Q*T{`i_|Jn}hiCQp zZmzFO$;g!JHrI`cdwP1Rso~?6l$4xI>m;4sw^lL@rGusi*W}m0`whUd`+ov?2iUAL zMes7LcXwwedLP8BM*=keJfld1eu7;=dOGP#O~6pkj8_~T9RU_JeJ=gm)tQ!4Y|F>r zDCI#eX;t;tfhevV3JVwSZ*Mu@+Z8 z^F;G}^os;U(aTFX2k`Y>-za(|(rs=)(?IVUAk`nn(%rj(liZxQ;p#88k;J4V2{f8S zskO~b*O~E;x7Ti43i9%UfKfc(pJnjtZ3n^y4K+2T2?#4d=5V255YVaZ2VA_oDd6y( zlKqDvmKGK(D=U<f>11b>s&nVHEz6>z8 zzbEE6Kc12Bw3jm*yl=1rEl5-r#`ySLG&J9UEW~1AVF8x@GnP({GBGF=6Kt6hj}(=Q zNr5TC@t@5RiE(Psr}X-Do$Vqfog*7328HH*(_7Bhuh8-Vw?7-}8yh<%s-~8J z(d2UZ84x6>pf@e0s@yy?qe0*UD!QVgB4tV4>-lC^i677!kO#^%tMi+hw4^F#n)(@N z9RbH>vAy@Jy58znj+dv>{i+P`luB?NG@#H&k1(D*`Bat;Z1C%kWw0y=mmfb~>}*X{ zkj;;So*m+gRi`5OMJHsSzkg#SE2=k)kmbJm061MjLgF{{^JcOpog|lt2>En`m=)6k zlF-~XeLS@L#}9FwN|=EGwWR%Yi6&Z)dg&e=149@pt6r-RBO@af)iNNNd(=PXBV5Bu z;hxl98kX|%PtRUbQ@<*xjiQGyoPLzLxvxcWPKM=L#3=bF%vF~7jrcoicU93DAd&LRIw>pEzJLlO~<>pET zN??AeLL2Gr9qkUV2Cca2SAwj%P58@Am;TIup~xlvSI7jcu|lT9>53wpxc6aC;GT$h zFss?>>87SO2|PXHEHuEg-|TmEbo9x|39yl2I>>mStCglRUm*>&WDE60!C@hT<@TR< zR$fNMir!s2&KsHq)1i#-!a&y$Y(57dt2d9;-T)aL*?CO)HaIaldUSbust%Jvq-2(c z5pRF+&3zD{aygoV$jQm^+RTBMMkruy5@6A(imeX>As|sH6BXD~N-0llZEb-jVWs2M z(n|=GCR519<*&|1ARvNnK<*itFfMg1C3p01GU>_5$(Z%5v#Fe>k?b)5tn0`8GIamP zM>&P+`$4s}KU@F(Ih8sHZPJxiR#x#U3)zK*z1!MtIB0?(GVOz2g?Fl|(ZRFto;F$} z04X7FSeYfRmmtTSf|m&}Nt?Rx`)0?9JkVU)p=zZ_65KgBI5<~hj_3J4VorPzv)+ci zI(m<}YeAs?pT`pb^WN``#Wo6qhg1RYJE@#;Kmg~lT_DB9MXoO@DRD{-cK@TOp`igN zYX&yE6Zf|M!oru5f*+5v?Qxh9&9D$vhbAsoRz(zz)`Nv_+MhSkKrQ$bw2hfa|C@P{ z{WoE5zu2FnilA2lW!JBAON-{-q*gNzbU~-8wV7GP8yRwc3FY&>UxvSrWh`545~#Hl zDKHM_n}0UL_-z-23gnDcY0TmAk5wxGECqlWgd%fT!r;HL9~ZmDAYt4Q7uIOh7YocJ z?l74H5^#sVw^ya1WY>b1N9~_162GMmQ7Uub`8I9e#&%(hhTpz)bxVQ3{l~pcc0WBX z6eNOT?*wY^nHp9_8ynVt6Qy4#6AazCq^Ri9`5=3A6v#&7~;JBe**fYH(g!pHni<$Nc66)zou4 ze9YDtJ-!UIw1BFz+5I<7ek3c`ST_z5CL|)d`+JrijAllwns@}dZQ>{6d)H$CFNGKaz{{t2e9R{s&X>$5-U%gNt` zej)XHeqOy1l!iMsIsfZFEs^yl$5mhRDsys>S@8i&0S?VDG%1RuA zA|4cyfDgO$AJ|w~2}_|vX@Cv=U+oeGV+0dgBWf6hgoIE6J}*gVX=w$eDZ_{f3F}J8 zh;LT~;ZC1YQ(rvKaN&`=nw*+SNJ`ojFoihf2R-{j3nKR5$^ZlvlavoM>}TB6E(qMm zv*4hQ^AG@b^q|mMu=${vx2vMJU-RoWK;oaaWQ5DVeamQW3P|#dA&6Iy)D_kJO>Z`P zcJH^*n6jfI=Ui1)F)qd4pit3$H^wt~O>HeV4^MYb&%{6NZm*kAS}SCEm0^vBJ(w43 z0KM(*?(%loX8(%|ozTHS0D4+l044y*ytc6}EhBSI3TI|x(*vp6CK&sl`P9EuYvzge z_}=$}1z_9$2l-KDPP{Eq-Dncp0i~-zQf$tDpk@}J5I~*t4~|&z0U>1R1EKA=ZLJS7 z6@oKG|Ak+3^79|RZ~@&eerMu`zGNK-9}19l%l-*P!eO63KQ_~Fbado3E9+wYUvG?( zNM!;o<659pD%7T)?GQ>XJB9oMeNS`%Cir3mkcuCn zgsWIxjN9JpY`K_wZ~teq|Ij)ReE6)G7BV2s{Uyg8HI^r9X2i>7!3Y_o^5mQK<|& z*G^U)%}nY2#C58-P-#SdiSaT1WoIYsOI34xC^*}Nf;&v0nJ&ngvb{jA#}m>wdgF3_ zF6{pIkJ?@GNz0$%KZ8yqC;F)m{+~Y$(%|?~+@H;~?V26G2b5`hu8UG0C&5lT@t!N_ zoM}*D(g$lX@S>2!c#Y#~x<;cA^XJ8=k9?mxoSu$(-)OCw%I#ckLZhBMSY8{>ih4#o zuIOFI_3gH4XAFrFd-ZsIrcmY4x~ZJ|sl}8biWr(SEiMITxAg7xc%!5HyucLABj4vV zDdABRhm@k)O-_AQv-$2V4@P4Y8S)iYW3yOvn|TfqdG4bRMx&ECdjhYmwx?MlzVrb5!JT-r-yP*(yAQU>k|-MI5k&y;1y<+NYgGNmx1U};{QvXc zU%P$2zbezAa(_&jt8-nha^`T|)tH`@@bXABNv>1_hlIPo!KrVgcj`E(wkTCvj}zerxp$=hOb#Vs?2wh@%I%Pd8P&5^@~;+bF^ zBw5N|MjEzP)~4R83*kHBfx-UA^|W?#UdXZ6N(Fe;rh2y4mnf_{c7hIcYGrTh(p+|{ z9|$5lRKzSgB6D0T<>7Lg%#^>vMz>l>V&vQZT0ujZ`9z&`?L5)f>@LEHgWVZ2B4GGE zXg9sRk|*tkEGcwq1_v9h;F=s4d#4R2s%N18Lfw)sTF_^qM<|4POuxEqwF*fP*}#sj zZ5E~L(pHlCH#**2ndS(JfX$h!PKi>`&f`5a>{W5^x)ZIg1hEMc+Xk4^)~JreryGk1 zxcaJLk9!ysNK7zvtG^!0L%05d$iMMjPy1OO!W{$6lhhTE$Km1=UbpXBg9{MNlba0aisr4(_mp}5q><8zHPV-+^A zK8tcd>>W0gEXKhE_o&-reHv^p=jkfEJaR471uuIds_QKF)D3i+jJ(7ylG>alr&o>bywv`M9|Jb{mM;L@eJQt_)u|zfgej$=!x1N*VB*Ayy2Q?Y4>io+M9FxZ6SA}wgK@9ddn(*Gn#d z|Lw-*@>ovs!R?bDu|6{#+{agMDLsxp%(4Yf(!Mf_4giDm#SbjTwzKo18)1?@(?{Qo8n{O4`Tp+3ZgM}$V@&+i2iHVMU#=q=j7RCC-T#{7+TvB4sCe1O zD=nRviu?=w7GvZBMSF!rmZL>1 z*)>ya`Xx_$IVQi&OeSU@sYl=vPvmdz+i?%B&%<9|5?A4YQz%)-oM?E#XS+#)ZsVt2 zwMe%f-(!6WRWFIl)!aNUTWCL|77^*4FpARnC`OQjNwKi|^|mGMCxw;v59n!bYkEIk zHa8w?^%7=ya5qn_>76NnhPTw%YHZSjxoPY1f&|al_$;VwT`@gdKD%t#Enncloi3H; zZ5)w99+P3vPWqxb9m5BuTUkbl&yswYABGu53!*wvmPAEO*#;8Z4p*+789fH0j%kl} zOjvNuV(t+2TpV~?6Ft_*M_G8UFS9%cKp?Ngy*LkfKs&1Fy@0Z_^AeBG-ruMFC=0dr z7?sY?|G4>0wyoYJSiTJHfSzls?{zUQAENz=E-K<019xjajT7m@HcI3eF6+D5KOTAf zhu-d())=`bN-&c2c2?}=-8);nUN%v`5co=Dz2I{Eoffj<=AR8b%BE>*CFD~g#~Y?^ zEnSg+D4dutgP6w@Zxc~&opnAUuN^bJ$yP7du`a!Nca-S6x`z59V?8OZotFK6ikZFM=n+JbIICu)mqI;>1@w-$Ue(e@rWasti|p6w<~`nXv(n{o9B zHFn)K=E2xd@K@Kl<>dD5*T6ER!}#?ez*dNdTwCB?{Fb>Y+Di7#3W3T=psj&5zrJ+C zGc!|8_N~{1MjBm4!Q&Q{ko&0dd)EjQp}Cf{krXe}&i6u`cBPMle}e;TW$$Z!8aVIJ*RI-#r%~qmN0c*tU;Gco z-T_FLr^^#=+qP}nw$0mi_ifv{ZQHhO+qV0*ZTHvzcV@nKc6VZ9E1q~FGb{5{);U>~ zS$Xh#^?e=s+DrY&0&4x7A&~KNq!+LOvUT;@$Y%fqz1#8S@A>F^+);`1>%acyotROG z2dMeb_ZFq}9TYrm*7pHh_hrV}0e$^>gK+-TkHI}x`^tT{L-Pd6yeoO_9*#}^so&u$ zZrdIv_63f2L*R?}VuyA;V~}~*)7)fnCw*JEaGL`I33)UA{WoR&FFoA%l%b5@y4>!VX{b#3yDTFLC+?Kv0LiCxqX3=sDk}u`{4Y{Cjggyz$5i1m7>WBzNdV z-=+-6H!f4)|1|!7J;oZ>ul&jol=f5eX}-xsnYqdI19~NwVaQi}4|VK3lE?U94|EhI zK)jQd@KgVq;agDq+JD-C5dzvjL{I-=s1aN!bw^Uq$tU|`HyX%eYLnH7-3A-Vidb9ufw{jb;;yR#I(KiGP!G?~x7#;YW`Vqb2Xw}|%N;^GgI z0^J|t)2-YA?Z1HN4zJgf#J(gG+z#3I`0?-T!c}g*uG1%G%u{~YjPFaM?}Pm1Snw1b zD;SqE7w>nl~=?c3~~`i^_?d?hsS%@z2z7)1H#1ZqA-?oL-j+fD_;^w=`X)q z?3nK*t?PsN45V?h-HPB(m)`~4fr9ST**SQ;o_;hTEnCaeU8`HJo)UgaUzExpqjvqi zz7#S7#UE4Pa3XeXMY;aA$fI5lh-n}2{1?jq5D@!^^iB`|dRIqOXkEwEz6`Pmj$Tn;{j(zekA=f7q-Ka0n@plw(NGs-|U0DnQ+n zCKcvZx7z~&f!uoj%yPaLw?owBVpHg7_B}id21kfd*EMwZR4bC^ z_I!|ipoft`w#Mhg`5fcoB8^V$ERvio8T9(*QONfOendWWT$jrd{Fu_1zskPQXWyS8 z-O%t8e{Or0BgGQ`+(=O_3E@#^RsO63rtK zB<95F_2|g~#s6jB>(RM`q(ROAX#0qq41vu@9-YXMONiOTd!fh7gM^6BA!P9%tkk^w zrzR8#DS?WQnCXESB4la&PSAHafqZX#k6P_d(_-01NRl5P>7<{_s)HK<%^#W_BDd~= zVZEBos8RF`Y3CI4%DhZD?(qYv0S%$gM9QcpegDh_c8Kzr1#0a+kjvghZmXh! zGa!khGo$3Y2N3eOhh{i7qb@ne`$x)u?dEer5KMWP1SREYSM+OfBag@9WFK+r&(%#)6M{@0&ueX^#vPS?&)<10X>peC}6p z{pWYCAbvII^Iam<9v=6=*J!QlUeeP0k`;I;T$y(eE7W0Sd|K8bVcc2)0mlD4=K>C2 zAH8EUrRynuracaoAY@hH;L<;=-)KGz00m6SxqaACidL5d{XajR|F0zqgCFp4i-Gt5 z)6T>{n+5;uOt3Jp{X4b{3&Vew{yY2{3*$e#3jb4FnE!~+#z?@(#KG{RQTTT>wo5Hv zFO{Vv{^#vyQ!>Z|m_2oZ-cDmCgi(1Qh@i5xkJKCD4+sQ?fp)S4<9Hadv{V@Z9h6E@ z3x&Gm{TQlTv?kCA<9xPU+A{49D;rR4tEHv@YTJq`+NQH+ROa_CS2BN%Gh6u$%S>-%yEMBi z!V?9@j}>E#jg%f@k%6~H_5=>|d|U#WPSI0&X6CWU3j-=rON}YXvyxm=V~t6?@>rau z0eGb34ag-@>4Q$~p?XEsWf9xO%!#t94`9;4`0&p2B3dZk;H}{%yzBoZjN-x5x!PqyUk8Y<24X+fXyS&~iXUEZLI=E>d^A9$Fi^1(cU zY>ciIz?K$lZL*iKyVB7XkRKe?Ky68Fmh>gv0@fMM2-(75#pK0(MRyi3UiVHT8lf@8 z&0~)v96kv!SpvHSDn`LC`R6LEaWaTE=hEitPk3Ybgs$&#zJv|L@HiVI&raAp0G8a+ zrsqRx!lulg8wSkj>vv9T2wJGl^3H$TY{i`M3W=X!WDFeLNO~cavxb?@d7M1W5)NLM zC|8ENuMxa=a}=V(C5eoPlZ*JGM$KE7i-v%oy#Kicqz-~5`XhrlUu;F#b&`P1I6&4O zBR3Z@dH}olDg1_<5%omY<8K$Ehv?1n#^z8Ln}s%ywJssJE~9-SSb4_$0Q?60o=V<( zSNK%vljTF_L2k(%I3D|MsZkSny`@nE0h`+usTpkoW?C0pWoV@dy)p1q2lzzgnUvuM z))Uf0-M{aC+wPK9EgrFFK_n}#1FkDrrQwgQaLLWMBYvvs5iR?RSp(1Xfoa%x5d9vi zG4w_9D`b`O$^7^+BXk<()AZ!PoIb5?A~_e1_kmVr@7bEjA$5qY&h`n7sV9)1EH$}&j(0?BizCmg+z?y~kNy<6t_G<2#vFFFssKy{8jjt5m{)QaryJdc*&=R)L` z6YJf%$a%hv6Y=Bx{@5_{T>Yy_XHd$$)ONpX{^j42mx+%R!*X+!jUl+k&wa_;aw6`~z`rBMJMYF%$`J>j;0Y(>B1#tXcRJ)rA5!98yf z)>~?ka|-eIFTR4uAH9duqH%MEaaLj5G@6i_gJ^}d$Ch)e#5)3PMDFXrmcyH~E`RA8 zv)9qrZLF@SbYMGj4|b1bi@d{eM?X2bqr`L#D z?Flx@Z4a><1>@~~eqi`&Mk33_k$df9*~h#zyNPv@d{x@hs#DMEtb?6=AEKtp z)!TY^y3q1RofFAAowd|HmZpZS{9&{2cq!YSoQ4eS8ukzs(82YVP`Tp|BiQJbuaz-a zi4bMpl2UX@?HS|W?U^U5#rlGqSnlrc9th0O%vfxDW3~x!N%*oN`huo9T4@mcs%(|q zMERscJ%3-b@aFf8gSmvk7ca3_-RZyX&qa6hyDrwU$^K#lRd}{LTgl%}x!1LBc9YzY zw}S@%CgvV_+FN{q)UGzUt#~1F!63gPx8~{^sm_yoVs&UJS*2eCV0E zHG%%!@E$h$i#|-`ZX9O~hR^@-uU_%6y2D0QY$ze0@b3_;qvY7#H{uku&cg*iI^}3xoG}GO2tU_y9 zOWP$LjE0-&cc$hbbj4au^tuIS=8pCvy`w(?o(p`9I_z!fi&lQ)acW|9MLgLY z`nG+cJX-eju4y85vA#K``*|4W3&FNVWEZ)-;hr_Cz|3#vsdmz9QF7Uba>-id$B10g z#Ay}SaJc6b3!CDa&A_Esh5bV%z7Z7VVPYED>@-mSs+@e4TI4wxzXpTe zcIN;aGXU{j*lz$+8)aqLx1+XqgSGdJ(xY_iO0f;aM+^)MBd=u@jA;58Lax)+*0iFm z59sPG8TL2Y!Piia?va$tUls^G`|#w#D1pu_d@q4#$UBopjRZA&zw{=EoSVuR%wX@~ zCB1*i%90oL6ccm1bCZGE&WR;xOc70POp#2bx<5$vuR#Np5y+vndCOc1_p0Z)Uli7v z<1h`O)l z#SbACm&=i(iIi7HbIdG5Mi0x2Tul9>r*JhjhL$^SXSy9tzV#caJX#4U8)n$p)K>Zq zQkj@WU8%P*CnzP8r0PvBh1D{qhZ-T52y9re#!BbCnP^gn`Vw7H&;}tfDF!O7kmraH z*0hgW48ud7LFKQ_(;n;x7&8&(q8sqV;1kRB-E~Bqhf(Rsqn{#L1r__*n>LJ zsG`v+6<o0u%>TMaaAX;XzFC}Z_5qGVK0qcFU(oaV3B`)!$^r)tg zk`_L_jq-HGu2i4BKXlV|sX(CcR&pwqX~5ccm&00=y*XEvPHsSt()MM9BR8#gT5;1| zjL{{~f1%!=#}Q}hmAS><<}=BfzB9lk(X4-w8i<*!s`aphbcJDJeh&x&&pA3I5}}6- z9iz}qV{Ym5l=D+{F?In#S~0t+P7QBw4=T1x;iz?WCBYTcw{)+tBW%s>GFV4%8|AAl zKDl_Dg{JrtczC&bwBD)Flg*8X*EMk_J^n=FWc9Xfw%QtAH)87yzbY?_`aL{xKGEqA z(%D)3w9l%5y^%qF-JB^q^t15N?H*0HFu^yIzrEgbU!0T|kyrtHdB#IeG*6yHjwI8T zd4oLRgk+0AT3x!JlA5UVK71Q&8h`S)`b$nn1!%_&&r-r*WIe1wj*wA4=PnGB?Rx&e zm@NcWm(`8LI}y;DK&BY&N!2DR*`Kvbmz}dqm!_Z63rB(@y9>!ZV%;w1(Nj!Ke#}ed zZYP)5V7?!8OD294`Fc-hq_RslHA7G9Ew=Xo)Z#H33oq;iKOw)Rk+T0b%e0n{M}_BQ zwa$!=H;p!3P7&H5ceaJo9bw$@+Z`ZiQGy@ym{p2VbH5YL zM=6tiPGjMRNHN+%0Eb;3%fc5&j=o>@+gtE}Eq96x4dnWvcDML)dV3 zYWL86+VCF1Tgdv5LdOmSFbvSIf{214rTf)L2}eICoy8@GQ-eXx!d2ZG@L zDR`0jr(h@MzSLm8DO^6$oveh4Px2_4NB7n!kw^b_ESz4gQ}!qsC*zvqrfiHg9KXgo z9hG13^;GFYg!DUqpS+^3?zNaY;~j-xb`3|dQ}-4)d`9VsU*W@gXyhoh_L{N4Q=nW9YH<=Y-u-Y4Za=e`W)8}!DeWqEHSZQ1ys)v z{}9k54qldW+h9XrMQAzTmheoCm%kK$Im18WmnN`xM?6*|lv6}Kl+aNixy4R^>m}Pm z`xlkZtuOQX%i@cnP9BqsE028O5%EvVUSPRya*$HQb%F=M&fuV%p!c<}@8lM*bm$_Z2aZO9ecmgXIEr0r~0>|4yOt zW&D^;Knwr7Ulco4mcw9YC?cxdDtdq>S>LW^cPlQe#5%$CoB0klg1)Rr>y^vmmiJ;z zm%Za}j8te%(yB5ZQ^Cf8_3%Rt`gvz$)D#VDwNeqaQlf6$Nz9BYxp9L*g`2 z#w!kLyuN2DoccT$M!8(ex==P$qlmfx&NuYb#)uy`z2sw!rVSn;Dcy!V=RV+PSRs>W zFHQ!YL3KRH{5Xe2m6!ATsCvDv$Ew2iRf|U@uG!+PwK4L~EBOpOr&&G77L?ZBFclOp z*;T^0fCy`Ie~P)+Rxq#rg$514eHF9N&ZuLXoyR(3TYl^K)Xn&meP#7`@olLa?-|m- z{`q#Td~A7Wd~FXILHCui8GIbV{?OgJv6!5p&onZwfnjk0?FgL8)6A*wS*7v4YLbF3 znpdsS*1WfP_P6b<2yOS0{c_P?SrV&#wVNJ>aKa!wS#|{x`XV#Z9Yqfy*B4h7tet=m zS}WkJf63%4= zd8YQ#mHmp2Wi*@HB(kd=F@LsU^=SVb1%G7+&%1TT&ibl;5|B7ru2nTT)9lGdS*Ke% zy?|nSWC=N>X>J6=(x%6P#yT;#KDX$fRhTu0a&m1Z1Sk$s1jJzJhuXV`HR5oqEwHJG z!%a1L*}y(5h3@7GsiIGdXR?cTyt;EOP>HIiKo3@DjeggvWEzDdkQ&{gqh3W7SS;R6 zj&9Dq-p`d-N0&y8V5rCH%T_RxA2q+TOCAcAt>~$`S7z?#r7fKX$Z2o?{m4x1@=SJd z?YcO|Uy02(kzr`o*sA^zb{&rFXSCnSare3~dMrt zA3;-dQSDiH4rcev&2NA7hqN3c6=I(adeaSQDe^xJD)ifV!232_u(P9JVX!)oxyW89 zx#HkM8J~Faah?DyTd zzT@2BisA>dBQ!?P`u2MMTq{tm4JGV{wH}3i9oC7etkc>Oiv{+U0GI(B17Lv;5jW!2 zg8xRzRfMX=RRGYSCEc&(h~$AEyUz841`zDU^9w=pfxfFCMT-fSO$@7R3GZS7bZU7i z&))&a0(v7jToA+;(4Pms{aO($`r2;&zZo$!dH~BsAn3gWZ9y;EpmqgeKxPkPLoI`EglOayQ>;EG#)NAUTX~jG*KtB1 z?ZPYS!At7+`DL?|Hp6aMN30!&+0?FqW&Hewl%s^(4xT6POag2GfC=PYZIyN;hWdj8 zmLz^i_qqbWjc2b0a7_!T>7!*3t+`m&Cx3}v<;RzZFiTycO?@VmpkB7kN=qbSBeHPH zDHm4hTYP>(8Wk??@SA8w_Me^28_!96gY2^WcwI8UD*(=l7?D);`sh^VyFj-kTyDI& z)ahP23!`>HT8<&{;hDj5LdE4*_Z^CtSzBD!Kot+mu8C+>(Dj1mra0t7tSvPYemrZ zPX&OpMif`#KGi5>>TCm`oIgKsc|i(L2g+)ZKst~G)END$a$+%-0{ls&l`L`k9^?F1 z<|2TpPzFrdhuSU74d)nOa)FuXOn5e`TFHyMu{kgsz!E^7u^GTBYwtjNe``11FQqrf zaZ`=sWTRL27Q3Te8no;oxM@SzNkdz8NsBmcWC~W+rfJ3F%86?3LQq^mGX`!q3GGXb zOP#E)w^+4(3j1W^6r6b|9MI{2ivZ#DEd$r}hRe`KUh3#-j=KFrs4830-$PHRhJeY{ z{PD^fh33V|^W;PcB`CBKl)95KhFs3Q-~c6n0T;cXenoh^0l-^7;+p_kK?tghHWf+XfpZk^ zmh9gHrEJ0R@Q8o++Ng|dis|@Z+rQWqatV+NlqBp!ZQ@kNX8T|I$@MDwk+J3L5?1fV z&NB24AbaOhBbjWd4=Yv;8!0d-R;BVyADJ z1{r9upJ=G>g8B(_E>#tiqNSdqWtOD1XMq96Uoe^%eGCo3`Ny4~Ma^n#EL*-%_f4xe5wF>%TS&4dM1|e%4CA<1} z`{2drh%%KD#UAAoUv^_vrl?NC1#l*c!Q7t;6l02gEucHe!6y7edc+m=OZf(VW@l+5 ze9`*pb!qZi_*Ev^r*DiB-(M3a3@4nkXtSYXLz%fde_Cx5pWqEXx=#2d($Flv0aPpO z!B?3`d-(aTx+QFZ^M7=D9jJ=eMLMXD)e={l51!ahq(hyoe<-zm*4BH}trY zn-tJenxhU6nG#TM|48q(!8%D=*OJFmi>rJAxl@}^S%z`g2B9w;OgB7zJMof|%i-52j{3Z7%NzM%&wjc#(>Sbt z?K5gt|M@h&0&wKB@a?-z{9LO9Y$i0spTw;duqSf$YaqYyrf|S$&g8Y=Pv0=~oy=` zgLa6~u=3Zj&1t;thI_`!M0tN;l*-btA3v#3carKgjAdLC3l@7vNiE5{S+lb8Lhgl57DJ1iiIZQ>ECiOlh%|dAg8KxdoZ%oWaVl%ZS^AH=ym?n!z_esGB zH>$LdlP^x=O5OD@P8K1b2#(1Pbq$PzN{J1LjD?x9Nn+k|npim2lNqb9aJ#9yN9Jqv5VG^OHT^K=T2l0LsRx zr>K*tbh4C^XnZeG)Qh%iIfy?wJXxyi1$mYg#W;UVMN}d`oLyZ*Ngf^!0YW|I6KR4X z*o<^lTa~`p22fqx`>)=h=o2R9kiQdG+HJ^n$aQ&6*00tNxOTbD<~=<+5lXU0dD6zt znF7-`n4gXDMtRaL;=`$}a-2HgjKBDlAAYgdA@F5Gp*Db{_|{{eohIW8`PmB4=*Y>- zx!YKfvF=->?2Yln3XJ2!UMh)i5!OU$ZO>ai9H;R z3X{vCJfct2YjFUaSw+t|V;e0tP>JaliCW~w#kYkOQM%ojI^n#C`>g<61API_ipEhW zO?w)4EN{qeal)J;a}kEMI||W&!zBELb3Q(d1!?Q617esmD0t?ryTTKqtR)~|P@1>p ztQ4Q$i&5F7_@Zy4(0cqI)MNkBdi|pwW8?U5&H;g8wUX` zGXom|69WSS0V4wgyDq(?lYzB`k)W-awFv3;x{i*1)l~fJ~u?a)DP2T~E6I5*t!yclk(PP&iW=do@3tUJL5F6tF{z}{*+@LEoU0}Nc?oQ5l4g41nso5z zt-#AWFJ*BS)j4#apH2AxGy?v2n2mq<`Tt{Vs5m&A{L6A%$iUI$UuXU=BDZjGbP_f< zaQH`(G6w&d{*mOrAUYhi+1c3%m{=JIbpJzU{~k{S{~B*Upd2c8sZFOu)*_^xtKEnXIa!)7PGBze3Qr^{)fVru}xe z+Mhr$prZrK6%qsjjigojw=2eU+cVyD*FBTf)JEmnXMIo4SgQGoCqoZ9@;)BCoZ_mHSCim|<9pizOea1N7 zbx_oM0c zF{Awcfssp}`n{6Fme2INL`F>?=)V){xIUoWMm2Q5K|75rZNGu|nAGll0r@d2CVKp` zE@{WcHj!@d-0x$(OV|-BTs@dyTe9t_?B4IE?bzf1(7A7VNIN;#JUG{Y1g`VgnbTZ7 zl!1E|GO%yF;kP&Wx)w50F1fqhIsZva{Uo|(Ms7__ZsqKRmaiX<^55j_=#qaCyzDsa zcI?vkP%-rg;1)zo|K=}2khozHw4NK?3 z*8IJEM`rzL=lpDH1?%FQa^Qiy>`T7=jWhCi2?nqe+_oLG6OL#8)h(}Mx4eB#`e9o2 zA!oOoe*Iud`z`ma@JasJ;%RnzwSVWL{Ox|aL-*IWu4yX+6kr#!RzwN{Q5+}#44Da} zQPQM!F(g$E6);)=(ZME7U$_Rf6~RWhZKgj}O?1&wXe;w1RP~~WhWYgaJwLF>!bt6! zVU3~b&JiXKHLU?}10+JVXP?JQgrMN0VZ#z|>|l(f3$Gf1_7GXd#M!2Rhco#mt|J^H z3N6Z~&?#{QTgIgQLnRgeo`!3w&}Tsn9f19_?LfI(aUT?o%E0Azu=lmL0$8CNxu$t3 z)Zjpx4kfdzYsjD#c~EEC8E}(82v!l}8^cZVP9CM%=acOlb|@H6DPaeJ9VhLP8u_EB z)Q^Eudf-sW^iOw+3?vwy>H+c}=>f{jbrl}g3VD3@2Yt_IW$d8aSb8+noyWJV$YDQ1C7FEI2VlYcDGQ#}h2~h~3cBSj{3Ms3 zRqK^Qy55c3*i^2v042glHhkae-UMAJs3e1cmlkjo5ZE2eb@F7wog5$@Z%V{VD_vNq zgt$imKn><~lW^6`PIte`m2(Ot*<}}V=+1~>yisipv4ct;R(_?xUL`IC`lZ^#gzf4I zDj)aO5$Y@Vl%pLBX`7ISN!97P&3NXYK3${sEU*?sbXG__2eLLA+M)fEzX8Zvq1RC= zqS&aL9#kH#rA#;H68*DXy$|cL(U;NfAw!Xk7M@S_rnpd@vlAp7q=_P$+6FN@D;QI^ z>Bk(XNgT2IRs5mK`+qEI-3HO<%QaiJ(h>^!RySvIq;eqSh{i}IAh28&(+Z-m^y=QQ z2iPb*dpSnMhzMXFj#Ke;0Eo?bxHMPrRY!2%N3bd>ej#e;VCBa~7H&L6#aH9j(G#dE(f6#e#%)hjz( z#Lr<>NE|!YtO}Jnnx}YFtQrzG#06O{uomKCyI?##0vS0wr__Ua@KjkYHR*&nJ=w(o zgk#=iz9El6+7Glt5Vz{#yZV3$*Wzf3V7a@qbKOXV9T%|H=Q}@7o=sI%khcN~@9jN1 zJ814&j%-};;DRYzfo~koFzr`!!t2ACguZ3{jXW>G!K;!~CnvDv)i`dRf*w4%K62d< z+w9j+_zP!|*dHJ#BDGN|umy3p9HLAJG}@4<;jEzjjto!1^$8~+oI)j_`_xg_OFPUs zH_r=z9b}nzhlEnrazFvX3wmVjWnYzVf~Hk&k+r2R2#wpNvwoJ!Z9UU}M?QkGWy~6VHte9>KM0eYgSjdh**}3-9PQh{n=K!7; zMeoROaw>bJG?RIR`vo~)YQ7Mjc95ORLE+b+q7hzz`b_7OB(V(bKdo6F`TO`OKFHij z%I-3yXeKGpd5rVT_Up0BD2*blchfd zN9Km>Ga zEnk|73+ZKVbtc(J6ynyV8-av}C&AmR(QtTsTQpoC4Y-gd`Agv5VoqVw^TK8rublIf zq18UbdC4_o4S2j)QfRZm{)|Sv^|})R?@A$7rk8YDsl236r=jK6=~|02B-1wzzQ6gp zJ=mqb1SIt^(VfW;CP-ajBCvg@H)(T>dXYZ25IB(v`Q4S=naDiM_MqKj2h>YaYHQkV zDscQnnVMJ!vzsA>Tm;IXst?df#vQ!kxt?=qh6OZk>ST)A%oWSI_NJeao@)8{0*O%-?hZ&L*At@WKK9HGixfCOE z<{gAtBL;y{r+0MM%gdDfIDA~ws!<2`EO#HIOK@zR6G_fS9`00wgm#>Tr6pZ$j+iu=P|jaOT|>e-$v%JaY0Ng@iYdh!Zz`y?Sl5yc(KS& zxKbJ|su$`RvUX=p1rGT9qH=CHUQHQOa1)h8?kO1Bwj3p+FRz9RMXo`_GS_oltRhud zJSd{6Z+jrxe08d7?Y&f~DNHmtVdX7RythvA4Ty3wdcxJkkZwEusL`JUHb!~(_8R+S z3#qXPX31%rlUf`l;UL7QV~!wsW6gO}L?Q;<ED2|8v%mO9F6(Y+3x zBD_YZWb8$UtURPImiwqQT2@doz1qT$o*JhRY`Hp-lCZZ;J%pKjnCdyzTMn@3d5 zhYtNVgzRYYCWWNDX|GzMj@<+JyBi0`lNFPEkpkzK7I4D5_tj6}qer5YFmm$EC^?OK z9I^z7=2~VKVCRV1^Y*~ejk9mHx2j8nZ`I*g4fFP9YnmuN6BDjIjW|=z@hW!pR|^dK zDRk8wh+6#Zd;y4ZJq4#K$$VO8jX0+Doo`djrk-R5XMbaVP9=_5m#4}OzVm_tJdL^s zsOEJY`T^rRcG-D+crN#L@_b}&R3wIkNt{{!`ZRkP<0v`w;`azv{KWLv+n?W9QK+21 zLWU*qt!h{pVDIOCW-nlM+;FG@ijBm0;|O#({`y6ngi32Cj%=q(Jm@*YD0R=d$2zyO zadu&+V=OjgHwZ8QsLkPW*Ppd>dKG3*JRkP8sCYeBkmMaS_w^<)cnL_rEdf@4StBjv zB};NoHr;-AZzkKw8VP~IXoeBG&;;fPXPMQIZ%uY?U2+yQInUO{g^VlTupzFOsS&Y= z4WCGK0R4BRoOIrmMlR5*E0sKKD+&|VcK~;dE&(fj8b)C_ls;2I=T{!#rc%<~fJ+j$y>K~(mn+V%?<0bv3}-lL*oRiVr=%;X3F z*IEI6tJGi44Bk|M{g<~p2S8Mz+WVLc*BZ#7i@)-&IR{e@)CbwfF<~F;cPMc$#G_OD zctkxD^M^y0Gvyu?M}dJg=1O44z5aHI{usQz;0xA*m5oP4jvrEDHgTlmdOxB_~C&|_^D zb)B%|FZ^NjTA~N#7-(f0St#o;Q zGPr3yB8I-yE{LGrYxaNW-6D5r32Lq8Nh&c)jqhbM1-S_Msy3YLM|IXy4Bpp~XOeVEr@3^2u&(wL z0@UdZRU-^+DFLr~z!7K27c{LQ%H;TaApnMGP}P8Z0m$)LqjC6Al%IFumOoIsut`b+ zTN9_D+$Lw~FELiiOFpaCfVoEKxM&It?Hi@44*zmloDC67(D;!Up%vqx<9Yy4W~*h3 z=)ki&EEO?eJ@Hs$IV+i5Y?M!vmR?y82!Ss`(_8A*9r`Jsbdr&PcZft42RZQ|YC;Bc zK&fWKIz>hmVKF8;{#!rX=-K1al|-QS3lN>M}t;Jvc~7 z7Uk$$^I%Me9t#XT8plVTMijSpf~gn;=KS>rE?vPiX1s${xmHGlRBmHY4Y|H5uM5DY ziCd=X(Z?;M?1d{MK}pQ|(voOYN{*iB-$zXxyJU}km|fru(gzo0Xfe&ccK87=6;;;0 zH1r}RXT@bD)Qzwtzp0P%A2FUq^-~La@~;AF2axPLOU7%R$5@T^O)Vo)`|~w!DX05<#XXwWOAGxio44}$<#hKH=~Y$${_@!l#dw5+P+EK_HE`gY|uc^&1Z zv;u8og%8q;`{aJi1z%dloBYPfqHnrCSBFPr#a+JS>}lwe{DGYsNL9$<U)3WEbfk9-c9T0L9*#%o3Rq>Z&{Q+@Q2Hj?s)fsb;Un<>O{8RU z=_bj%mFkv-%Vt4ZnXFFx9Y*LuxBq)bP43(zOoDQ60h)T_x0A|`hsc@2sFV7BUi@Rx zUx-6_h4K5Y6X4A8+*WYKub|HvWOS3R>)dkwM@liCDo6_IcCIUi`4XBuk)pPe_>WSs zJcD3<5$+8rDV@LVx~|aQXQY4gl_6fWJVP3NyOl;4dyAy40}iw{ehpx(N4PMX-A2eplD^tjIyyz_(66LuER!{z_*LydO}*^d5EyBs!Z$e)>`kLrJ%CnZ5n zmwFW|WTI-6PaE$fkjG?P2SeAgF=P6(9ygwbpu9|T=AML&c;J~OY#5%*k&|l4DXPgt zRV*q|gK+_hl#8C>-@kA+fD z(ImoYr5NST<=cH$e%R2#6D>tEaJ(SjnfOyX^>y@}?k4oY#?=G>PrFI5>LO69%CDX6QSRyOAm> z;kyBH5(6r|x@v#1R$>m5$Q{(|)V1}VjZeP|(N(aZ0)z%`@Gzy=0s2-v$+Gjg=obb&8}`d(8E>kbFElN~6`YQGCl9z+Z5Z9}e4^&wx|k7&DnYH9`m>_1>dO$jzCz@zfYbiP-3902@L|D6oW@OGLD-zIpCT7&7C>$ zF7l%)7J}4J{Nr#J1n9SQE2OWh_(7w?DSL0+Nx`_cL+>$EMi#YPsUy$gI|&1{y5h;6 zr$tzsbOciXvm_FOljD)LMZs!9yA3hz4+-{lI9TIX^e^0(&#boNS*IlTKi0J3jL}H( zGZSY@YOfix(!8=w72+0pN|k+L*DujNA#=e_UYr%`SSHm)WOV%x0sg(V2lo9D_UKc6aK^_y+jnIP8Xpf~b{$TlNhqISQ z;&Lg|@)$5VL|$g(&rYpLXA>LGp&-7jE1!)!yUN3rqCs932^SZ~hP@TlJiD(3XoB3M z&x2XvVvf-Q<4VMrV$ECsB8-_|<@~cO|H|3%n$$Y}^Xk#c$>krsqR`?vKR%aPYRjsUBt~KbNHlDC zlk9an=|-^va3va#fZv`g(irBH;UwayT9gYMU*||23=7OQtXF#NoEbi&)390@@rN!k z*gB^OV|uWDTN3kx2yilEAjr^zHc0&xv%n_``@u-t*YlT= z9rABXj>$Y##+YXxtbNcebt-W_4&}erWXDc(!AJw><1plNLRsCZp8_dm!6EfIA4pT! z>|GQ{Os+gbfYKNrvHN;ulL$#^BVQc62J|dh{(}4wJU$`<7ZZ;0d9YA8rm@k>2O?&A zKoM8iBC8E+D)Ra~0(`@iS7YVKaVw}%2FEYpF#9_TbCr}+j93_#ySmXsNT%N)P3RGZ z>bA?Vi-^`9f6z%nWyZo-sW@M4_#K~);UaUJn?!Li&vocf)(c`maJ&l5oV)%?b#sCPV^^}XyR@`-*;4nf0z@pB@u`S^4-%Us!OwF-JkQ%3M-L2e1*9`8; z3%eCc@HUW(Xz+-c8*;T2V8M$Uf%6x0m(v~w@^!SqA;>0+FOCGr%=KXX!z`Lr@08X` zat6M>oFa;TKtkINvN`Zyf9@Bb(LJ0ExmUUEeoU-lubbkhKZcCaPrfZ1*wxn6>FHjR zmr-edAe4Al4kj2@W_9*JnHw~;@c2LNU)~4AiTkOJI`C<2pbb5HnltWSa8czL4<`ow zZM4H`^z-J&W-8>l6WE66-r(^~YvaALaf@V?3S1{k3l6Vz5`cJPeWP7J%qOpReH$Ma zf6%91h>K{+(v|ROfVDjy80J>J%8NJ%sfXWQX z#4+P9a8Bw(WKc|u&yW@J3^?q^!GWDmtL;3s+xKCscehi{C5*)m9P$017ojPXXPEG} z75yPycJS0fWz)Y;pd%e*-2PnsF?ao(HMLzwPoUl&c!dG`jtURoU*%vTPO4ZaF~ zH{Mi|EJ0*DZrP-C91JC(7Z4~Omg!?xF8AkX2bKp$wbO_Iz!D0!eX38SN2h~31Yo~H z!{~Tp>m*@nbOyJ?*Aa~{<_{=K@UH`x`@xEECYk_btE4QL)ui6*oOw800?F6~8jQyx(5Ou&wgs)MO)qGis1 zKgyukL_c;6PFf7cpXvjjSxS060RGyMnUJf z!l%TB^K2=RdcYy|a8v6LRT8HpR9mTV3;as|y>e~t%u5&KcaAp^2C~zvzjj`UFh4#U z3TdHWtJnG{#$!2nj(mnse+HD9rJc=Lp2>#}$|3Ol1l_}0D{lrK>h{Jn69T&gB_GJT zdXYY}9_ng`X~(qlZYdB?xXhDUIBB@uChBVFR)KPhoS4yG&h>_4SAWWW&1ex`enw4W zOtudQ7Ou46m~)nXhOW^)bje#p=?*bF2-8M2g>us`I3Lo#w%-KE>oj(bEzV>eYP{$H z!K78OT9Enm72(vYMmtJdf3Rm>9K5&*m}m0< zJB-Ye=$G@zr+jW=7 z0`*@3c;0}I^Ikbk>#k-JP2H1Q!V3$L+KoHXTG05sDd}GM#bG@g=61~y_T1r1*X2Yp zOP;N2 zX1vC|AbWNr;Z=2*G@jmudm`12QE|WU$Uk;OBBdAlWII6y_^oQXD-L?I+SEf}yt(qk zbmei#(WeUR z$nJUyvDGxOdKO2$5E&2zP z30AAS)p_HK=g({5&C@aOSagl^f&@G!Pmr8LUd0~5{dpkw-+XZU#15N48S0%f*ZCq$ zLH=@xU?OwHwA}3(*(96$cmMydy(^E0^85ZttL)h&Lny-R8&US9>^q6UV6u$N*jtn( zq7+doN}(NDSZkNvW0&4nUTim`~80M{r&#>eZ0!dbD#6vd+xdCo_p?d z-sd_E52G5NTE5}ys*lcJHtx4CKE`8~H-NLdSeG|=EnR1k)t<9HKLoa=RBubDPp&Qx zpLn}a2)9Qf=HTlU4OOL@0^%A=?=-lxRv$3|amQ3>b{smc~ z@5H~tD)=ziV7Yr?BH>0U(hm#M6_?`E9I*Cze2I8v;+e&NNl+Z%6`S`qE*8`oIV@Rq zYXe`0N+NICst=J#qEEfwuXu>GE#?8q=aS9k(u2$NC50<{7tsxhAJ%(z-&FVKckMW+ zA(N!P`(e$du6ECpFX0`^K@M>zC*rkMtvW=>5f>3K3sv^|7Wzpm@x3JOM0Q>e=cy~M zXiq1Lt7Df^)MOSu>3S?-d83UKb$ckm;<f|}03;*Vukp5!8?8}EAY9fUkS0CgkYKj`KS-NwnM72Ym^}>){ zs-^sz3YS2-Q)KCtMoIa%>qU3n5~>-KySyoB;8T|!{lWHp3B@~c304Mfb#11~aB1O5 z%NKSn@jGKn-!9*M$8p7jY-e$V*LmC5MH^N8X-!+Z?oT8OKgrptsGX+pY(oR-=9tjw z=p6i5fy<97nY;Mh4un9(-q;*Rtdwrutl0@ioV%-yfq5pAK<` z2Mw&sUGidOHte($%H8I`cp*JyO^HWcOMPR{t*~)I(HZ-uV7InUepOrtj4BJ&T)ytL zlaRZ|w|3db(r$N~P};=a`RDkQE}T47j;afLJ~5x~VJ)e#-f#;|%6)u4hXqN5xN!7T zgiGrSr@gIu5wx%*}SX}6E z4Kk3pn{i>I@@RD4jjtsG8;=CWzF8V-`9>M3w^{$P@v+!skv?bt<{`2EW*vw358rjK zl+z#DX8%xicalUDO!WP=O8CHgZ{Mr09N=ZwJ$7VCtLBf<{du1kCT$6Nc4MBhvI_ZQ zdd5n_RhQ>cp0_{sCoc-@EjmX3dgR>4!~>NW5f_V+wk;`E1N=^H!*?UvuVMFUX^dNr zACX2JL2x+~?{K}~ymm5f!4B6vCznopX}*VBWxmozFS%Wc?3tGekKoFZT2QR1V{mqL zG^O5MiA!}8kEc41-dTY}@1+8@$ZxLk@`sf=`$!oV?e->q=Rni4lodLM>y!NGx1|xp z)%};Q_W$M3-XEHR;#HH`2se{@W|QV+%c+?;{s`d=r{Wf(uaUMIPx#<9NL-D9_JF^pF)^|7UHhgS^F6Nt*$a-O!dk(qoy4Xl8N8hvds+Pka138~x zX%hAgmy62)$5drNKlsX)25@yj= zmA1n2d&Ai?t+Ef3&aG*V^J`evydhu7PA8k+YD>9){x*fNXDx?LH)O7<{3?Hiu8?}_ zb&o(_Vp-T)2ltc*%l)2bMLa#*y30~&Rh#$FLhky#Hav=F z0mmxbeJ_tjGLbxHdgoQzh{2%y&b2{JM-mTt!xnvT#(!|x+{w@1ZnQI!r_Y=F$3&FG z74wM`oj%(#KlgiW^;FzPtiRmebzRD!q_~Z@^v%*SGqDMWWdoug)MWGx1s6VOyA*R- zvGKqi;;zH56S%JxIJG%>y-94<%(nd|khK3{+q$~WWRFW*wqrS5?FFt&8}rJkS~ZKo zbL#Za*5SM2^R18Hyvn1oru1k(X1C%DlF&*+`U`r<-Rxz9r0(UZc10>|20{z zA@V#{D@$Xu#IyMo+7#{L&|{mEUcMR{%zgKmOUzKGceQ>sPwF+F9-J{buz^fk`SiGT z#|<8GfNT7g_il$DNIfY&pmnyuQb3KXv{Dk^*u6uIN8*jox8ijXft}o2g`6)7F7Ofv zB9qX?-8T-GdIHCW-o2 z(2U|fi$~q5o#Fux+MAbm?5bHA>YRMz2x+UL`Z1pVtq0x}ZwWN|LKf({bl|0WvFx|o zhi|m+3zCUCXO<;jfGUtYy10NM{-97Rq981Pf98efdJ7)J#O$~u8l1Go<&;C=xa2_K z4Ub*ld#rN`jbk3QW;SO$h?8I4+Or`T-M>UvKK~O*wnv`l+mdeKE%C8pG&3q;=abbj zwY6!wVe;EG^HwVTP!;UFYWH<5;cThPfjjq{KbCvvZ-0AB#pHeCr4RRx!)|CxG&$X< zYRZoGHbfU*>KCA1MXm0XLz}MJCVJcX;oMCq}Bgr<(={QE6l z)I4(aoL@+>J1aU!3frYTTHCX1t}l4f zsY<|QQK#( zv8UD^HL*41%#~Vcr_9|+GTFX4L+6Y8pZnY|akt?AvS(4q=%|vsE$4myO{v4np}LPKhIX#D`Le z?UDwU@^62|qMWX~?~Kwrm5^pGf5XmJ1WDc&kmuQ9A9Q*s-G197OhZi`r$Mr+o> znC$S7V~^L{lm~5{c!N3qiaWmNNB`&#&hav2q&&atmv@VTF(KPVTnyijIsXnF3PCIx z2m2zh2=p&p?a%Xm0j`z-4~3wizW|-T0K(c#fUpTb^-}%GR%AblHr3Yy06=HMgK>D6 z3Iq>DqwwG>5s&;==wKoq;7fm@gR$W17dn`6b2c~_hJoOtGXbSPPX_vh4aQ*c{|OtM zVnRKG;E(Mc=aO#LSy(jcowGzyX8++zf4k!?(i`p?9g^6w7Apr?$Jnp?MLAOR9oj;?_=YD$s=e_>%Ye#!kdroA_3%F)TNrMbI`ISqa++Vq3V>(gI9xDQPBH4eh%6~<~E z2I1}bpImAj8eJZpE_06hMD;j1nR@R@S@gB6GCh;!-;+Y{gZKbkqcoOhLS;Mmgi5&o zUne)JPAofb^kcJ|+mEkOJmV(0Ig_!f!7zYN3}_ci z1bl#N=o5v+aG{Za9)X1sL4Axq5DAR7e}n0UOvFq~H}l+X7I;4BIMccSnd>8ApwEmW zxB!wL0;SKGtyt)IF31o;q`=q!E*K@ljXIdAAb+Dkq+FB!B2QBse;vEUs{)w<3&|wxo7Zq-)YO(mrLIXj=C6O-lD4 z-y`bzABm26cSQilu_0^q_VR5m1wyrlzR%yIH-FQK_@x%<_Hjn$6xrDD+<}E79Z8wu z-UNk*LOJmk>T4zKFnE*L+l-2Lz{C)sgz%al$1)(CEp+Ix#RGMKJS<3Jmb83ykfw9 z?3IWe$A&Joc~8IWEE0dtajH-xGOhJ-(MOVW*P?erp8EtfUzg}qHo)H%ROoE@k;w6_ z{N3nPAw?xV(}QWr3Mr@3Lv4{y1t%gbCfmj;`10N)>7K{5RJ~SHS8q0sUV7<$)lmLt z+LplDi0H^cL74-q&X@3vo)T$2z7=g&5Z4m^(Gnb_DgNnX8ehuYekFTeG2 zc%2t^9SWS+?}LXGe3}=3zAEC>diSNd`twI09%$Gx@=1Az(BQC5yJgs_gGN_1OP9ar z5h#l}Ja6$iPAS)Un|8|=R8r;a-g0a&U%@}WVuO(V`~@(9?D&A-lOIq%w%dC1Z|7uid zgYN@Tu2}7?HETqSBkvvLcI3Srvo8yEj_WlKc0-#^^(l0N-Z{Qo3wg9U8hRTf#dd!} zEPfulpX76NaYThyfLMu`X(amXx|{P_m)KPV^=aK)sLAOPOT8P_=N>A^5jVd=Z;*du z^xn`_GKLtzB*TNLh60wmpURjRsyD@K)>(9D^#h;z@plzYE!enctxRM=91P~cZ!2iL z#3p(oT10zwy96l?p%rT8!GAqYL|4=ehD<)Xp-w?WaBW;fyg~fOIDFiydy0bb_vF(L zo-pLdUSlap5kDVY81;0Mn#t!?JShqfJ+7*~+S9GiD>LxWGEgQ=eH1n-G^!L9J-+Ys zhQ^$i7UOFgg^=t>c>ded;H~hWXf+e7-1LSw z-lRgg*AkBMm*ayE1RojN44g2RatG4xJ%*&~+Bp?6G0V7gxbi$)iD{euLlP42=xWMMe(ZeWg$-Cn0*(8E($vd|Cw4%L7D+r`XIo^$Yhh}mYN2^*yG2-{o~QV=?GDwycHcrp1guz?r*V*AV-*S%S9@{ICYn%Q2Qm{_Xezglno4lxbCV#yKH`$>=;pa>$<}Apu&mk zPp;qaIr(ho>B?tc8;qJ1Ul7lu^J<@GTwdFx@5YI;mRlF~z#7`IdPF!BX5B(VxPVseH zK`ME4^I2$}ZoOQC+~e%V_j!tyPg^jRg^vbri9byAO7ktM?A}N8{oUN%;Fj-twxp{98uM}_Z zii{QV2TTrhn8uo3F~yp4uH&U@=0}H=r~lRcp`>Q?=75i=f#~^K(vh~!D$Xg+d^Zo& zqtavQFPy}7=l0$YY3{)hBr~McBVKfCg=mD_iOBfQ$;Zi;RlOz2!VLXb?r~J6S*dS{ z+!lkd&zK}kb&RuGeV*Ek{L|2%( zx;g(#egd+Z@@OA1Lu>F#4SM%yj@JxdyzH|79^szQ{Xsa+;l#C(cY^!n6*rnH z+c?&^gv+IgNeV>3hE&!^yHuY{T$Xq-{y2Z=vZAFcmuWIC*~Z)|4#@d*ymJP979I)O5nwXupYuf@ge6RR%?kLZs~Y zB=RZdQxD#4IPAj=I-MsT%9ZqrakI~O*={0xKc*ymSE<6fPmCD>9XFxPK@g&11 z^R`R~<}tjtnH){tLzb%jmX`0JSy(}<`jXmEb2C-yBDbyZB?*U~vhW`guaCXQuK&>d z{>Xu#Gm2iy)AKV4hpekAmWBV2up|EJ); zG{;gZ%~UiFXsDE$mipP9$S)kO|EwPNY~pjekLHUdtEpN};&IXT&Pyqemw{Lu1MU`}d| zZ|UDWF?vUI2(G5^(X92PamKNo4ui%M&n91#yl|$h#n9`H)43Xa4WchwUrC-$hDAg<_+Ng zdQj*Ts=tv3aDyqH6msAinx%m@%t%iMha}=~DkxQ?BDD9XGamqcy(dWhg@IiS)6@T% z_zSj0)7u4x`))#}lRQXt()5nb-el8HHyUh`SkCobw>~t0JAO|9L-ecXv2vgV!3I2*69D#zP zP%3~zg%;*dCxwED)GDY7W*tA@wE$VcpgKuz)F8TstSq<>{V-Vw@bDx-e6zGbqEP%8 zZ9weuD3~zdoPw9| zz9e_DA8_p9+P+kGAJ&)c?A|)_&A6T~*$=!W2k*&A{vM=25H>W2F#`i|b1xX)&9>Y=g-*BpS3?buE7#Z`djU@$cwRC`Lp&J(FoT5gW%2d?&n{( z&j^HQ`BJ?6;W}Vc$bqa?ut@OFIbyUAVm})}AY?{R1;-LqnImH?qMZX{Or>Fotbq8} zpNYyihz541VXU%3vWR;QJTdmJto7lbu+CJh>u*WvcRaC3dJa4>0!z>UBH0FT){b7= z*b)vxa4=?ci&e5LlloULpx_%6qY5NJ`+NpxHvS&uKwpYKnN|jvsj5ai;G1Y=D^x4i;QQPP5*`` z#-VZmBSBCFhYbEa8W4$4C2+wR#|y0Qd(Cj;IRI3K*m+X2xQK{`V$EpW+o1 zNM;xr=8(=XG7K&mA_cQ{MzsK)@!t@cgf2k4joT4pE~U7iC^Q;Wt%CoJ1=vRH#Ti;G32=fE0sfnZr$0ib7E zT#Wk6rdMGGEh{O@?EJ<4-(7`KEV}X=#(%EDs40bG^~&*6CYo&(22dl$dcr1T7JdK4 z<)5v>3?`<$rr+@TA68-f)EwXF1b|fx{e%%_@r>fVf`-{W)#bGnuD~a4Kvs>%vdxC zEEDZ-iR*VpnPn2qfwx&k8Nd&xt<2xzX|{5qS?0_fSemxUNVaVVSk?ayYfK*jg(Ii} z1m;g4fynR}7(N0PrwVoj1e_}PDh7rpU{%pG1_sSC!+z6)Urqv3d^3Cm2A519 z0X1{DSw{OemFiO6gP`{$knaI7n2g=QFVhOGP@o9LxB+7tQ--aDF-#aZSebDfhzz1) zZjfL|2753h^HBikWZYvu44|BhE9T>jrQH&MJ)uG_6k`^_mZJ@0K$z)3^73wVmT?t*o2#mV9;FeThvI!{w0(~;vv8fNR zxdR(O#xDp)$$UKoHwUorDbY=TfxHZ0otWL9F|v#%rr0qJ@&f=(1k4E-eTFQigvXe# z(^8x2FZ13{kuYoidBq&9DUr;S#k4O5l#OWzP*W=nmov+P&A^tjN(lm<(tsq`z@}XA zX|yR|8SxWt3iJ%Vk>WvfV!j`PE_J9u0JDl@Z37xd);1UrRk%J3GaVjh$XA;h2)5=7 zG%LaxaNtgN0)q%}!m0qRj7O^i%rF+KN&pbopD)g|+@WnfcxPv0X$1XWGZlNLx=~bv zDS`ALk}n8`ds97V^dJukl@ZmY2Z3NIh2%?v)5!Fo099|gpRXb`Y)pGUg}I%Ic$d z@cPOV#wm#5cW6M^CgE9@+%J4*BRM^Uh zP?EvSG9m(GJg}FcpsB(}hnYQ=L?|U-CLI!sL(HlVkA>Fo8TBEMgjqTS60)GhdIlZH z&45Ia&LoYgKG{GnKO8Gt++!YthYe=>rd zKMV>5Wtz;80R~jZ&NGHcguJDhbXe4EUBhB#+Y&64t;7B-4%!8>)klDQ3$`*Mw49C-Py*@00h+wIY9!LTZ%0MWw%8C+B21_IGx~X&+ z!&w2l7syqBL6ZWCvl!_DA9)>07mLOLGoXvs(Z%8Q2|(BM(OM{iK2i&b(j(#k{OmuH zK%Ob^)^)te?mo02KNwsGk3#Dawe$!WT~G~>AxN?#;PeQ(D1<(SsEvj^c^Vy{6B$c5 QFp&f_m%O~5nLgM50IZaR!vFvP literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/QuickstartGuide_rope.pdf.meta b/xiaofang/Assets/Obi/QuickstartGuide_rope.pdf.meta new file mode 100644 index 00000000..0218f7a9 --- /dev/null +++ b/xiaofang/Assets/Obi/QuickstartGuide_rope.pdf.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: dd3977598aee74c5eaa2111f3d999165 +labels: +- ObiRope +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/README.rtf b/xiaofang/Assets/Obi/README.rtf new file mode 100644 index 00000000..d6d71741 --- /dev/null +++ b/xiaofang/Assets/Obi/README.rtf @@ -0,0 +1,38 @@ +{\rtf1\ansi\ansicpg1252\cocoartf2512 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fmodern\fcharset0 Courier-Bold;\f1\fmodern\fcharset0 Courier;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +\paperw11900\paperh16840\margl1440\margr1440\vieww23180\viewh10900\viewkind0 +\deftab720 +\pard\pardeftab720\partightenfactor0 + +\f0\b\fs26 \cf0 \expnd0\expndtw0\kerning0 +OFFICIAL OBI WEBPAGE:\ +{\field{\*\fldinst{HYPERLINK "http://obi.virtualmethodstudio.com"}}{\fldrslt +\f1\b0 http://obi.virtualmethodstudio.com}}\ +\ +OFFICIAL FORUM:\ +{\field{\*\fldinst{HYPERLINK "http://obi.virtualmethodstudio.com/forum"}}{\fldrslt +\f1\b0 http://obi.virtualmethodstudio.com/forum}}\ +\ +CREDITS: +\f1\b0 \ +\ +\ul Programming, design:\ulnone \ +Jos\'e9 Mar\'eda \'93ArK\'94 M\'e9ndez Gonz\'e1lez\ +\ +\ul Support, Community management and Web/Forum maintenance:\ulnone \ +Lidia Mart\'ednez Prado \ +\ +\ul Special thanks to:\ulnone \ +VargaPD (testing and debugging)\ +theANMATOR2b (testing)\ +Hanging Cui (testing, help with vectorization issues)\ +Janne Ramstedt (debugging and suggestions)\ +Tigrero Tiger (debugging)\ +Hatchling (feedback regarding collision filtering and spatial query API)\ +\ +all the folks at the Unity forums and of course, all Obi users.\ +\ +\ +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/README.rtf.meta b/xiaofang/Assets/Obi/README.rtf.meta new file mode 100644 index 00000000..de9ed91b --- /dev/null +++ b/xiaofang/Assets/Obi/README.rtf.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 133c58a050c6b404cb14cc72f0a1676c +timeCreated: 1443155832 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources.meta b/xiaofang/Assets/Obi/Resources.meta new file mode 100644 index 00000000..0cc732a6 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6217e7f6fe8104bbca06fe7ac150a57d +folderAsset: yes +timeCreated: 1435572248 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute.meta b/xiaofang/Assets/Obi/Resources/Compute.meta new file mode 100644 index 00000000..054ac134 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 55c2294f77a2c4783b788be18cc01798 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/AerodynamicConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/AerodynamicConstraints.compute new file mode 100644 index 00000000..d51c3c4b --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/AerodynamicConstraints.compute @@ -0,0 +1,61 @@ +#pragma kernel Project + +#include "MathUtils.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer particleIndices; +StructuredBuffer aerodynamicCoeffs; + +StructuredBuffer positions; +StructuredBuffer normals; +StructuredBuffer wind; +StructuredBuffer invMasses; + +RWStructuredBuffer velocities; + +// Variables set from the CPU +uint activeConstraintCount; +float deltaTime; + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p = particleIndices[i]; + + float area = aerodynamicCoeffs[i * 3]; + float dragCoeff = aerodynamicCoeffs[i * 3 + 1]; + float liftCoeff = aerodynamicCoeffs[i * 3 + 2]; + + if (invMasses[p] > 0) + { + float4 relVelocity = velocities[p] - wind[p]; + float rvSqrMag = dot(relVelocity, relVelocity); + + if (rvSqrMag < EPSILON) + return; + + float4 rvNorm = relVelocity / sqrt(rvSqrMag); + + // calculate surface normal (always facing wind) + float4 surfNormal = asfloat(normals[p]) * sign(dot(asfloat(normals[p]), rvNorm)); + + // aerodynamic_factor was originally multiplied by air_density. The density is now premultiplied in lift and drag. + float aerodynamicFactor = 0.5f * rvSqrMag * area; + float attackAngle = dot(surfNormal,rvNorm); + + float3 liftDirection = normalizesafe(cross(cross(surfNormal.xyz, rvNorm.xyz), rvNorm.xyz)); + + //drag: + velocities[p] += (-dragCoeff * rvNorm + + + // lift: + liftCoeff * float4(liftDirection.xyz,0)) * + + // scale + attackAngle * min(aerodynamicFactor * invMasses[p] * deltaTime, 1000); + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/AerodynamicConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/AerodynamicConstraints.compute.meta new file mode 100644 index 00000000..229e5ddc --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/AerodynamicConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a819ec002d4434b5da29879a26e3211a +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/AtomicDeltas.cginc b/xiaofang/Assets/Obi/Resources/Compute/AtomicDeltas.cginc new file mode 100644 index 00000000..78305076 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/AtomicDeltas.cginc @@ -0,0 +1,75 @@ +#ifndef ATOMICDELTAS_INCLUDE +#define ATOMICDELTAS_INCLUDE + +#include "InterlockedUtils.cginc" + +RWStructuredBuffer deltasAsInt; +RWStructuredBuffer positionConstraintCounts; + +RWStructuredBuffer orientationDeltasAsInt; +RWStructuredBuffer orientationConstraintCounts; + +// atomic delta add: +void AtomicAddPositionDelta(in int index, in float4 delta) +{ + InterlockedAddFloat(deltasAsInt, index, 0, delta.x); + InterlockedAddFloat(deltasAsInt, index, 1, delta.y); + InterlockedAddFloat(deltasAsInt, index, 2, delta.z); + InterlockedAdd(positionConstraintCounts[index], 1); +} + +void AtomicAddOrientationDelta(in int index, in quaternion delta) +{ + InterlockedAddFloat(orientationDeltasAsInt, index, 0, delta.x); + InterlockedAddFloat(orientationDeltasAsInt, index, 1, delta.y); + InterlockedAddFloat(orientationDeltasAsInt, index, 2, delta.z); + InterlockedAddFloat(orientationDeltasAsInt, index, 3, delta.w); + InterlockedAdd(orientationConstraintCounts[index], 1); +} + +// non-atomic versions: +void AddPositionDelta(in int index, in float4 delta) +{ + deltasAsInt[index] = asuint(delta + asfloat(deltasAsInt[index])); + positionConstraintCounts[index]++; +} + +void AddOrientationDelta(in int index, in quaternion delta) +{ + orientationDeltasAsInt[index] = asuint(delta + asfloat(orientationDeltasAsInt[index])); + orientationConstraintCounts[index]++; +} + +// applying deltas: +void ApplyPositionDelta(RWStructuredBuffer positions, in int index, in float SOR) +{ + int count = positionConstraintCounts[index]; + if (count > 0) + { + positions[index].xyz += float3(asfloat(deltasAsInt[index].x), + asfloat(deltasAsInt[index].y), + asfloat(deltasAsInt[index].z)) * SOR / count; + + deltasAsInt[index] = uint4(0, 0, 0, 0); + positionConstraintCounts[index] = 0; + } +} + +void ApplyOrientationDelta(RWStructuredBuffer orientations, in int index, in float SOR) +{ + int count = orientationConstraintCounts[index]; + if (count > 0) + { + orientations[index] += quaternion(asfloat(orientationDeltasAsInt[index].x), + asfloat(orientationDeltasAsInt[index].y), + asfloat(orientationDeltasAsInt[index].z), + asfloat(orientationDeltasAsInt[index].w)) * SOR / count; + + orientations[index] = normalize(orientations[index]); + + orientationDeltasAsInt[index] = uint4(0, 0, 0, 0); + orientationConstraintCounts[index] = 0; + } +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/AtomicDeltas.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/AtomicDeltas.cginc.meta new file mode 100644 index 00000000..8f9c197c --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/AtomicDeltas.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1a767b30eef4240859cf6158473bd06a +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/BendConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/BendConstraints.compute new file mode 100644 index 00000000..5652e39c --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/BendConstraints.compute @@ -0,0 +1,83 @@ +#pragma kernel Project +#pragma kernel Apply + +#include "MathUtils.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer particleIndices; +StructuredBuffer restBends; +StructuredBuffer stiffnesses; +RWStructuredBuffer lambdas; + +RWStructuredBuffer positions; +StructuredBuffer invMasses; + +// Variables set from the CPU +uint activeConstraintCount; +float deltaTime; +float sorFactor; + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p1 = particleIndices[i * 3]; + int p2 = particleIndices[i * 3 + 1]; + int p3 = particleIndices[i * 3 + 2]; + + float w1 = invMasses[p1]; + float w2 = invMasses[p2]; + float w3 = invMasses[p3]; + + float wsum = w1 + w2 + 2 * w3; + if (wsum > 0) + { + float4 bendVector = positions[p3] - (positions[p1] + positions[p2] + positions[p3]) / 3.0f; + float bend = length(bendVector); + + if (bend > 0) + { + float constraint = 1.0f - (stiffnesses[i].x + restBends[i]) / bend; + + // remove this to force a certain curvature. + if (constraint >= 0) + { + // calculate time adjusted compliance + float compliance = stiffnesses[i].y / (deltaTime * deltaTime); + + // since the third particle moves twice the amount of the other 2, the modulus of its gradient is 2: + float dlambda = (-constraint - compliance * lambdas[i]) / (wsum + compliance + EPSILON); + float4 correction = dlambda * bendVector; + + lambdas[i] += dlambda; + + float4 delta1 = -correction * 2 * w1; + float4 delta2 = -correction * 2 * w2; + float4 delta3 = correction * 4 * w3; + + AddPositionDelta(p1, delta1); + AddPositionDelta(p2, delta2); + AddPositionDelta(p3, delta3); + } + } + } +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p1 = particleIndices[i * 3]; + int p2 = particleIndices[i * 3 + 1]; + int p3 = particleIndices[i * 3 + 2]; + + ApplyPositionDelta(positions, p1, sorFactor); + ApplyPositionDelta(positions, p2, sorFactor); + ApplyPositionDelta(positions, p3, sorFactor); +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/BendConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/BendConstraints.compute.meta new file mode 100644 index 00000000..c253612b --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/BendConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 92b982b3ba8824f1cb17f9313e0b11ac +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/BendTwistConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/BendTwistConstraints.compute new file mode 100644 index 00000000..81969677 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/BendTwistConstraints.compute @@ -0,0 +1,78 @@ +#pragma kernel Project +#pragma kernel Apply + +#include "MathUtils.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer orientationIndices; +StructuredBuffer stiffnesses; +StructuredBuffer plasticity; +RWStructuredBuffer restDarboux; +RWStructuredBuffer lambdas; + +RWStructuredBuffer orientations; +StructuredBuffer invRotationalMasses; + +// Variables set from the CPU +uint activeConstraintCount; +float deltaTime; +float sorFactor; + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int q1 = orientationIndices[i * 2]; + int q2 = orientationIndices[i * 2 + 1]; + + float w1 = invRotationalMasses[q1]; + float w2 = invRotationalMasses[q2]; + + // calculate time adjusted compliance + float3 compliances = stiffnesses[i] / (deltaTime * deltaTime); + + // rest and current darboux vectors + quaternion rest = restDarboux[i]; + quaternion omega = qmul(q_conj(orientations[q1]), orientations[q2]); + + quaternion omega_plus; + omega_plus = omega + rest; //delta Omega with - omega_0 + omega -= rest; //delta Omega with + omega_0 + + if (dot(omega.xyz,omega.xyz) > dot(omega_plus.xyz,omega_plus.xyz)) + omega = omega_plus; + + // plasticity + if (dot(omega.xyz, omega.xyz) > plasticity[i].x * plasticity[i].x) + { + rest += omega * plasticity[i].y * deltaTime; + restDarboux[i] = rest; + } + + float3 dlambda = (omega.xyz - compliances * lambdas[i]) / (compliances + w1 + w2 + EPSILON); + + //discrete Darboux vector does not have vanishing scalar part + quaternion dlambdaQ = quaternion(dlambda[0], dlambda[1], dlambda[2],0); + + AddOrientationDelta(q1, qmul(orientations[q2], dlambdaQ) * w1); + AddOrientationDelta(q2,-qmul(orientations[q1], dlambdaQ) * w2); + + lambdas[i] += dlambda; +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int q1 = orientationIndices[i * 2]; + int q2 = orientationIndices[i * 2 + 1]; + + ApplyOrientationDelta(orientations, q1, sorFactor); + ApplyOrientationDelta(orientations, q2, sorFactor); +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/BendTwistConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/BendTwistConstraints.compute.meta new file mode 100644 index 00000000..ab675e5e --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/BendTwistConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e5ad8a2b8563941539b7551b0a93b911 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/BitonicSort.compute b/xiaofang/Assets/Obi/Resources/Compute/BitonicSort.compute new file mode 100644 index 00000000..1929395f --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/BitonicSort.compute @@ -0,0 +1,39 @@ +#pragma kernel BitonicSort + +const uint numEntries; +const uint groupWidth; +const uint groupHeight; +const uint stepIndex; + +RWStructuredBuffer Keys; +RWStructuredBuffer Values; + +[numthreads(128,1,1)] +void BitonicSort(uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + uint hIndex = i & (groupWidth - 1); + uint indexLeft = hIndex + (groupHeight + 1) * (i / groupWidth); + uint rightStepSize = stepIndex == 0 ? groupHeight - 2 * hIndex : (groupHeight + 1) / 2; + uint indexRight = indexLeft + rightStepSize; + + // Exit if out of bounds (for non-power of 2 input sizes) + if (indexRight >= numEntries) return; + + float keyLeft = Keys[indexLeft]; + float keyRight = Keys[indexRight]; + + float valueLeft = Values[indexLeft]; + float valueRight = Values[indexRight]; + + // Swap entries if value is descending + if (valueLeft > valueRight) + { + Keys[indexLeft] = keyRight; + Keys[indexRight] = keyLeft; + + Values[indexLeft] = valueRight; + Values[indexRight] = valueLeft; + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/BitonicSort.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/BitonicSort.compute.meta new file mode 100644 index 00000000..16cb0e09 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/BitonicSort.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ceefe1197724d4a408783ad72b2c56ab +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/Bounds.cginc b/xiaofang/Assets/Obi/Resources/Compute/Bounds.cginc new file mode 100644 index 00000000..2549b518 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Bounds.cginc @@ -0,0 +1,127 @@ +#ifndef BOUNDS_INCLUDE +#define BOUNDS_INCLUDE + +#include "Transform.cginc" +#include "Matrix.cginc" + +struct aabb +{ + float4 min_; + float4 max_; + + void FromTriangle(float4 v1, float4 v2, float4 v3, float4 margin) + { + min_ = min(min(v1, v2), v3) - margin; + max_ = max(max(v1, v2), v3) + margin; + } + + void FromEdge(float4 v1, float4 v2, float4 radius) + { + min_ = min(v2 - radius, v1 - radius); + max_ = max(v2 + radius, v1 + radius); + } + + void FromParticle(float4 v1, float radius) + { + min_ = v1 - radius; + max_ = v1 + radius; + } + + bool IntersectsAabb(in aabb b, bool in2D = false) + { + if (in2D) + { + return (min_[0] <= b.max_[0] && max_[0] >= b.min_[0]) && + (min_[1] <= b.max_[1] && max_[1] >= b.min_[1]); + } + else + { + return (min_[0] <= b.max_[0] && max_[0] >= b.min_[0]) && + (min_[1] <= b.max_[1] && max_[1] >= b.min_[1]) && + (min_[2] <= b.max_[2] && max_[2] >= b.min_[2]); + } + } + + float AverageAxisLength() + { + float4 d = max_ - min_; + return (d.x + d.y + d.z) * 0.33f; + } + + float MaxAxisLength() + { + float4 d = max_ - min_; + return max(max(d.x,d.y),d.z); + } + + void EncapsulateParticle(in float4 position, float radius) + { + min_ = min(min(min_, position - radius), position - radius); + max_ = max(max(max_, position + radius), position + radius); + } + + void EncapsulateParticle(in float4 previousPosition, in float4 position, float radius) + { + min_ = min(min(min_, position - radius), previousPosition - radius); + max_ = max(max(max_, position + radius), previousPosition + radius); + } + + void EncapsulateBounds(in aabb bounds) + { + min_ = min(min_,bounds.min_); + max_ = max(max_,bounds.max_); + } + + void Expand(float4 amount) + { + min_ -= amount; + max_ += amount; + } + + void Sweep(float4 velocity) + { + min_ = min(min_, min_ + velocity); + max_ = max(max_, max_ + velocity); + } + + float4 Center() + { + return (min_ + (max_ - min_) * 0.5f); + } + + void Transform(in float4x4 transform) + { + float3 xa = transform._m00_m10_m20 * min_.x; + float3 xb = transform._m00_m10_m20 * max_.x; + + float3 ya = transform._m01_m11_m21 * min_.y; + float3 yb = transform._m01_m11_m21 * max_.y; + + float3 za = transform._m02_m12_m22 * min_.z; + float3 zb = transform._m02_m12_m22 * max_.z; + + min_ = float4(min(xa, xb) + min(ya, yb) + min(za, zb) + transform._m03_m13_m23, 0); + max_ = float4(max(xa, xb) + max(ya, yb) + max(za, zb) + transform._m03_m13_m23, 0); + } + + void Transform(in transform transform) + { + Transform(TRS(transform.translation.xyz, transform.rotation, transform.scale.xyz)); + } + + aabb Transformed(in float4x4 trfm) + { + aabb cpy = this; + cpy.Transform(trfm); + return cpy; + } + + aabb Transformed(in transform trfm) + { + aabb cpy = this; + cpy.Transform(trfm); + return cpy; + } +}; + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/Bounds.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/Bounds.cginc.meta new file mode 100644 index 00000000..f3c0a8e7 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Bounds.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 52c09ed0a553243328693072f77d1465 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/BoundsReduction.compute b/xiaofang/Assets/Obi/Resources/Compute/BoundsReduction.compute new file mode 100644 index 00000000..91dabe39 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/BoundsReduction.compute @@ -0,0 +1,93 @@ +#pragma kernel RuntimeSimplexBounds SIMPLEX_BOUNDS=RuntimeSimplexBounds USE_COLLISION_MAT +#pragma kernel EditSimplexBounds SIMPLEX_BOUNDS=EditSimplexBounds +#pragma kernel Reduce + +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "CollisionMaterial.cginc" +#include "MathUtils.cginc" +#include "Integration.cginc" +#include "SolverParameters.cginc" + +StructuredBuffer simplices; +StructuredBuffer positions; +StructuredBuffer velocities; +StructuredBuffer principalRadii; +StructuredBuffer fluidMaterials; + +RWStructuredBuffer simplexBounds; +RWStructuredBuffer reducedBounds; + +float deltaTime; + +groupshared aabb sdata[128]; + +[numthreads(256, 1, 1)] +void SIMPLEX_BOUNDS (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= pointCount + edgeCount + triangleCount) + { + reducedBounds[i].min_ = float4(FLT_MAX,FLT_MAX,FLT_MAX,0); + reducedBounds[i].max_ = -float4(FLT_MAX,FLT_MAX,FLT_MAX,0); + return; + } + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(i, simplexSize); + + aabb sxBounds, soBounds; + sxBounds.min_ = soBounds.min_ = float4(FLT_MAX,FLT_MAX,FLT_MAX,0); + sxBounds.max_ = soBounds.max_ = float4(-FLT_MAX,-FLT_MAX,-FLT_MAX,0); + + for (int j = 0; j < simplexSize; ++j) + { + int p = simplices[simplexStart + j]; + + #if USE_COLLISION_MAT + int m = collisionMaterialIndices[p]; + float solidRadius = principalRadii[p].x + collisionMargin + (m >= 0 ? collisionMaterials[m].stickDistance : 0); + #else + float solidRadius = principalRadii[p].x + collisionMargin; + #endif + + // Expand simplex bounds, using both the particle's original position and its velocity: + sxBounds.EncapsulateParticle(positions[p], + IntegrateLinear(positions[p], velocities[p], deltaTime * particleCCD), + max(solidRadius, fluidMaterials[p].x * 0.5f)); + + soBounds.EncapsulateParticle(positions[p], + IntegrateLinear(positions[p], velocities[p], deltaTime), + solidRadius); + + } + + simplexBounds[i] = sxBounds; + reducedBounds[i] = soBounds; +} + +[numthreads( 256, 1, 1)] +void Reduce( uint3 threadIdx : SV_GroupThreadID, uint3 groupIdx : SV_GroupID) +{ + // each thread loads two elements from global to shared mem and combines them: + unsigned int tid = threadIdx.x; + unsigned int i = groupIdx.x * 256 + tid; + sdata[tid] = reducedBounds[i]; + sdata[tid].EncapsulateBounds(reducedBounds[i + 128]); + + GroupMemoryBarrierWithGroupSync(); + + // do reduction in shared mem + for (unsigned int s = 64; s > 0; s >>= 1) + { + if (tid < s) + { + sdata[tid].EncapsulateBounds(sdata[tid + s]); + } + GroupMemoryBarrierWithGroupSync(); + } + + // write result for this group to global mem + if (tid == 0) + reducedBounds[groupIdx.x] = sdata[0]; +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/BoundsReduction.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/BoundsReduction.compute.meta new file mode 100644 index 00000000..5959ca43 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/BoundsReduction.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4eaa80a9c435f42fa9837a3594766a1f +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/BoxShape.compute b/xiaofang/Assets/Obi/Resources/Compute/BoxShape.compute new file mode 100644 index 00000000..d965346e --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/BoxShape.compute @@ -0,0 +1,125 @@ +#include "ColliderDefinitions.cginc" +#include "ContactHandling.cginc" +#include "Transform.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "Optimization.cginc" + +#pragma kernel GenerateContacts + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer principalRadii; +StructuredBuffer velocities; + +StructuredBuffer simplices; + +StructuredBuffer transforms; +StructuredBuffer shapes; + +StructuredBuffer contactPairs; +StructuredBuffer contactOffsetsPerType; + +RWStructuredBuffer contacts; +RWStructuredBuffer dispatchBuffer; + +StructuredBuffer worldToSolver; + +uint maxContacts; + +struct Box : IDistanceFunction +{ + shape s; + transform colliderToSolver; + + void Evaluate(in float4 pos, in float4 radii, in quaternion orientation, inout SurfacePoint projectedPoint) + { + float4 center = s.center * colliderToSolver.scale; + float4 size = s.size * colliderToSolver.scale * 0.5f; + + // clamp the point to the surface of the box: + float4 pnt = colliderToSolver.InverseTransformPointUnscaled(pos) - center; + + if (s.is2D()) + pnt[2] = 0; + + // get minimum distance for each axis: + float4 distances = size - abs(pnt); + + if (distances.x >= 0 && distances.y >= 0 && distances.z >= 0) + { + projectedPoint.normal = float4(0,0,0,0); + projectedPoint.pos = pnt; + + // find minimum distance in all three axes and the axis index: + if (distances.y < distances.x && distances.y < distances.z) + { + projectedPoint.normal[1] = sign(pnt[1]); + projectedPoint.pos[1] = size[1] * projectedPoint.normal[1]; + } + else if (distances.z < distances.x && distances.z < distances.y) + { + projectedPoint.normal[2] = sign(pnt[2]); + projectedPoint.pos[2] = size[2] * projectedPoint.normal[2]; + } + else + { + projectedPoint.normal[0] = sign(pnt[0]); + projectedPoint.pos[0] = size[0] * projectedPoint.normal[0]; + } + } + else + { + projectedPoint.pos = clamp(pnt, -size, size); + projectedPoint.normal = normalizesafe(pnt - projectedPoint.pos); + } + + projectedPoint.pos = colliderToSolver.TransformPointUnscaled(projectedPoint.pos + center + projectedPoint.normal * s.contactOffset); + projectedPoint.normal = colliderToSolver.TransformDirection(projectedPoint.normal); + projectedPoint.bary = float4(1,0,0,0); + } +}; + +[numthreads(128, 1, 1)] +void GenerateContacts (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + // entry #11 in the dispatch buffer is the amount of pairs for the first shape type. + if (i >= dispatchBuffer[11 + 4*BOX_SHAPE]) return; + + uint count = contacts.IncrementCounter(); + if (count < maxContacts) + { + int firstPair = contactOffsetsPerType[BOX_SHAPE]; + int simplexIndex = contactPairs[firstPair + i].x; + int colliderIndex = contactPairs[firstPair + i].y; + + contact c = (contact)0; + + Box boxShape; + boxShape.colliderToSolver = worldToSolver[0].Multiply(transforms[colliderIndex]); + boxShape.s = shapes[colliderIndex]; + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(simplexIndex, simplexSize); + + float4 simplexBary = BarycenterForSimplexOfSize(simplexSize); + float4 simplexPoint; + + SurfacePoint surfacePoint = Optimize(boxShape, positions, orientations, principalRadii, + simplices, simplexStart, simplexSize, simplexBary, simplexPoint, surfaceCollisionIterations, surfaceCollisionTolerance); + + c.pointB = surfacePoint.pos; + c.normal = surfacePoint.normal * boxShape.s.isInverted(); + c.pointA = simplexBary; + c.bodyA = simplexIndex; + c.bodyB = colliderIndex; + + contacts[count] = c; + + InterlockedMax(dispatchBuffer[0],(count + 1) / 128 + 1); + InterlockedMax(dispatchBuffer[3], count + 1); + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/BoxShape.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/BoxShape.compute.meta new file mode 100644 index 00000000..6928e9b1 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/BoxShape.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9df6755bffe0b4dc5a30f4715e8a503c +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/BoxShapeQuery.compute b/xiaofang/Assets/Obi/Resources/Compute/BoxShapeQuery.compute new file mode 100644 index 00000000..034373c3 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/BoxShapeQuery.compute @@ -0,0 +1,136 @@ +#include "ColliderDefinitions.cginc" +#include "QueryDefinitions.cginc" +#include "ContactHandling.cginc" +#include "Transform.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "Optimization.cginc" + +#pragma kernel GenerateResults + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer principalRadii; +StructuredBuffer simplices; + +StructuredBuffer transforms; +StructuredBuffer shapes; + +StructuredBuffer contactPairs; +StructuredBuffer contactOffsetsPerType; + +RWStructuredBuffer results; +RWStructuredBuffer dispatchBuffer; + +StructuredBuffer worldToSolver; + +uint maxContacts; + +struct Box : IDistanceFunction +{ + queryShape s; + transform colliderToSolver; + + void Evaluate(in float4 pos, in float4 radii, in quaternion orientation, inout SurfacePoint projectedPoint) + { + float4 center = s.center * colliderToSolver.scale; + float4 size = s.size * colliderToSolver.scale * 0.5f; + + // clamp the point to the surface of the box: + float4 pnt = colliderToSolver.InverseTransformPointUnscaled(pos) - center; + + // get minimum distance for each axis: + float4 distances = size - abs(pnt); + + if (distances.x >= 0 && distances.y >= 0 && distances.z >= 0) + { + projectedPoint.normal = float4(0,0,0,0); + projectedPoint.pos = pnt; + + // find minimum distance in all three axes and the axis index: + if (distances.y < distances.x && distances.y < distances.z) + { + projectedPoint.normal[1] = sign(pnt[1]); + projectedPoint.pos[1] = size[1] * projectedPoint.normal[1]; + } + else if (distances.z < distances.x && distances.z < distances.y) + { + projectedPoint.normal[2] = sign(pnt[2]); + projectedPoint.pos[2] = size[2] * projectedPoint.normal[2]; + } + else + { + projectedPoint.normal[0] = sign(pnt[0]); + projectedPoint.pos[0] = size[0] * projectedPoint.normal[0]; + } + } + else + { + projectedPoint.pos = clamp(pnt, -size, size); + projectedPoint.normal = normalizesafe(pnt - projectedPoint.pos); + } + + projectedPoint.pos = colliderToSolver.TransformPointUnscaled(projectedPoint.pos + center + projectedPoint.normal * s.contactOffset); + projectedPoint.normal = colliderToSolver.TransformDirection(projectedPoint.normal); + projectedPoint.bary = float4(1,0,0,0); + } +}; + +[numthreads(128, 1, 1)] +void GenerateResults (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + // entry #11 in the dispatch buffer is the amount of pairs for the first shape type. + if (i >= dispatchBuffer[11 + 4*BOX_QUERY]) return; + + int firstPair = contactOffsetsPerType[BOX_QUERY]; + int simplexIndex = contactPairs[firstPair + i].x; + int queryIndex = contactPairs[firstPair + i].y; + + queryResult c = (queryResult)0; + + Box boxShape; + boxShape.colliderToSolver = worldToSolver[0].Multiply(transforms[queryIndex]); + boxShape.s = shapes[queryIndex]; + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(simplexIndex, simplexSize); + + float4 simplexBary = BarycenterForSimplexOfSize(simplexSize); + float4 simplexPoint; + + SurfacePoint surfacePoint = Optimize(boxShape, positions, orientations, principalRadii, + simplices, simplexStart, simplexSize, simplexBary, simplexPoint, surfaceCollisionIterations, surfaceCollisionTolerance); + + + float4 simplexPrevPosition = FLOAT4_ZERO; + float simplexRadius = 0; + for (int j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + simplexPrevPosition += positions[particleIndex] * simplexBary[j]; + simplexRadius += EllipsoidRadius(surfacePoint.normal, orientations[particleIndex], principalRadii[particleIndex].xyz) * simplexBary[j]; + } + + c.queryPoint = surfacePoint.pos; + c.normal = surfacePoint.normal; + c.simplexBary = simplexBary; + c.simplexIndex = simplexIndex; + c.queryIndex = queryIndex; + c.dist = dot(simplexPrevPosition - surfacePoint.pos,surfacePoint.normal) - simplexRadius; + + if (c.dist <= boxShape.s.maxDistance) + { + uint count = results.IncrementCounter(); + if (count < maxContacts) + { + results[count] = c; + + InterlockedMax(dispatchBuffer[0],(count + 1) / 128 + 1); + InterlockedMax(dispatchBuffer[3], count + 1); + } + } + +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/BoxShapeQuery.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/BoxShapeQuery.compute.meta new file mode 100644 index 00000000..4b6e8ed4 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/BoxShapeQuery.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 409c5f7d65dd84df9853de82bd3fbf46 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/CapsuleShape.compute b/xiaofang/Assets/Obi/Resources/Compute/CapsuleShape.compute new file mode 100644 index 00000000..1b99c0e6 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/CapsuleShape.compute @@ -0,0 +1,122 @@ +#include "ColliderDefinitions.cginc" +#include "ContactHandling.cginc" +#include "Transform.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "Optimization.cginc" + +#pragma kernel GenerateContacts + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer principalRadii; +StructuredBuffer velocities; + +StructuredBuffer simplices; + +StructuredBuffer transforms; +StructuredBuffer shapes; + +StructuredBuffer contactPairs; +StructuredBuffer contactOffsetsPerType; + +RWStructuredBuffer contacts; +RWStructuredBuffer dispatchBuffer; + +StructuredBuffer worldToSolver; + +uint maxContacts; + +struct Capsule : IDistanceFunction +{ + shape s; + transform colliderToSolver; + + void Evaluate(in float4 pos, in float4 radii, in quaternion orientation, inout SurfacePoint projectedPoint) + { + float4 center = s.center * colliderToSolver.scale; + float4 pnt = colliderToSolver.InverseTransformPointUnscaled(pos) - center; + + if (s.is2D()) + pnt[2] = 0; + + int direction = (int)s.size.z; + float height; + float radius; + float4 halfVector = float4(0,0,0,0); + + if (direction == 0) + { + radius = s.size.x * max(colliderToSolver.scale[1], colliderToSolver.scale[2]); + height = max(radius, s.size.y * 0.5f * colliderToSolver.scale[0]); + halfVector[0] = height - radius; + } + else if (direction == 1) + { + radius = s.size.x * max(colliderToSolver.scale[2], colliderToSolver.scale[0]); + height = max(radius, s.size.y * 0.5f * colliderToSolver.scale[1]); + halfVector[1] = height - radius; + } + else + { + radius = s.size.x * max(colliderToSolver.scale[0], colliderToSolver.scale[1]); + height = max(radius, s.size.y * 0.5f * colliderToSolver.scale[2]); + halfVector[2] = height - radius; + } + + float mu; + float4 centerLine = NearestPointOnEdge(-halfVector, halfVector, pnt, mu); + float4 centerToPoint = pnt - centerLine; + float distanceToCenter = length(centerToPoint); + + float4 normal = centerToPoint / (distanceToCenter + EPSILON); + + projectedPoint.pos = colliderToSolver.TransformPointUnscaled(center + centerLine + normal * (radius + s.contactOffset)); + projectedPoint.normal = colliderToSolver.TransformDirection(normal); + projectedPoint.bary = float4(1,0,0,0); + } +}; + +[numthreads(128, 1, 1)] +void GenerateContacts (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + // entry #11 in the dispatch buffer is the amount of pairs for the first shape type. + if (i >= dispatchBuffer[11 + 4*CAPSULE_SHAPE]) return; + + uint count = contacts.IncrementCounter(); + if (count < maxContacts) + { + int firstPair = contactOffsetsPerType[CAPSULE_SHAPE]; + int simplexIndex = contactPairs[firstPair + i].x; + int colliderIndex = contactPairs[firstPair + i].y; + + contact c = (contact)0; + + Capsule capsuleShape; + capsuleShape.colliderToSolver = worldToSolver[0].Multiply(transforms[colliderIndex]); + capsuleShape.s = shapes[colliderIndex]; + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(simplexIndex, simplexSize); + + float4 simplexBary = BarycenterForSimplexOfSize(simplexSize); + float4 simplexPoint; + + SurfacePoint surfacePoint = Optimize(capsuleShape, positions, orientations, principalRadii, + simplices, simplexStart, simplexSize, simplexBary, simplexPoint, surfaceCollisionIterations, surfaceCollisionTolerance); + + c.pointB = surfacePoint.pos; + c.normal = surfacePoint.normal * capsuleShape.s.isInverted(); + c.pointA = simplexBary; + c.bodyA = simplexIndex; + c.bodyB = colliderIndex; + + contacts[count] = c; + + InterlockedMax(dispatchBuffer[0],(count + 1) / 128 + 1); + InterlockedMax(dispatchBuffer[3], count + 1); + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/CapsuleShape.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/CapsuleShape.compute.meta new file mode 100644 index 00000000..0295bcb2 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/CapsuleShape.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bd92ed8a5b1bc404c9b114747495f080 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/ChainConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/ChainConstraints.compute new file mode 100644 index 00000000..62c8c1a4 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ChainConstraints.compute @@ -0,0 +1,159 @@ +#pragma kernel Project +#pragma kernel Apply + +#include "MathUtils.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer particleIndices; +StructuredBuffer firstIndex; +StructuredBuffer numIndices; +StructuredBuffer restLengths; + +RWStructuredBuffer ni; // (ni:constraint gradient, di:desired lenght) +RWStructuredBuffer diagonals; // (subdiagonals), bi (diagonals) and ci (superdiagonals): + +RWStructuredBuffer positions; +StructuredBuffer invMasses; + +// Variables set from the CPU +uint activeConstraintCount; +float deltaTime; +float sorFactor; + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int c = id.x; + + if (c >= activeConstraintCount) return; + + int numEdges = numIndices[c] - 1; + int first = firstIndex[c]; + float minLength = restLengths[c].x; + float maxLength = restLengths[c].y; + + int i; + for (i = 0; i < numEdges; ++i) + { + int edge = first + i; + + float4 p1 = positions[particleIndices[edge]]; + float4 p2 = positions[particleIndices[edge+1]]; + float4 diff = p1 - p2; + + float dist = length(diff); + ni[edge] = float4(diff/(dist + EPSILON)); + } + + // calculate ai, bi and ci + for (i = 0; i < numEdges; ++i) + { + int edge = first + i; + + float w_i_ = invMasses[particleIndices[edge]]; + float w__i = invMasses[particleIndices[edge+1]]; + + float4 ni__ = FLOAT4_ZERO; + if (i > 0) ni__ = ni[edge - 1]; + + float4 n__i = FLOAT4_ZERO; + if (i < numEdges - 1) n__i = ni[edge + 1]; + + diagonals[edge] = float3(-w_i_ * dot(ni[edge], ni__), // ai + w_i_ + w__i, // bi + -w__i * dot(ni[edge], n__i));// ci + } + + // solve step #1, forward sweep: + // reuse diagonals.xy to store sweep results ci_ and di_: + for (i = 0; i < numEdges; ++i) + { + int edge = first + i; + float4 p1 = positions[particleIndices[edge]]; + float4 p2 = positions[particleIndices[edge + 1]]; + + float cip_ = 0; + float dip_ = 0; + + if (i > 0) + { + cip_ = diagonals[edge - 1].x; + dip_ = diagonals[edge - 1].y; + } + + float3 d = diagonals[edge]; + float den = d.y - cip_ * d.x; + + if (abs(den) > EPSILON) + { + float dist = distance(p1, p2); + float correction = 0; + + if (dist >= maxLength) + correction = dist - maxLength; + else if (dist <= minLength) + correction = dist - minLength; + + d.xy = float2(d.z / den, (correction - dip_ * d.x) / den); + + } + else + d.xy = float2(0,0); + + diagonals[edge] = d; + } + + // solve step #2, backward sweep. reuse diagonals.z to store solution xi: + for (i = numEdges - 1; i >= 0; --i) + { + int edge = first + i; + + float xi_ = (i < numEdges - 1) ? diagonals[edge + 1].z : 0; + + float3 d = diagonals[edge]; + d.z = d.y - d.x * xi_; + diagonals[edge] = d; + } + + // calculate deltas: + for (i = 0; i < numIndices[c]; ++i) + { + int index = first + i; + + float4 ni__ = FLOAT4_ZERO; + float xi_ = 0; + + if (i > 0) + { + ni__ = ni[index - 1]; + xi_ = diagonals[index - 1].z; + } + + float4 n_i_ = FLOAT4_ZERO; + float nxi = 0; + + if (i < numIndices[c] - 1) + { + n_i_ = ni[index]; + nxi = diagonals[index].z; + } + + int p = particleIndices[index]; + + AddPositionDelta(p, invMasses[p] * (ni__ * xi_ - n_i_ * nxi)); + } +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int first = firstIndex[i]; + int last = first + numIndices[i]; + + for (int k = first; k < last; ++k) + ApplyPositionDelta(positions, particleIndices[k], sorFactor); +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/ChainConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/ChainConstraints.compute.meta new file mode 100644 index 00000000..561afa19 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ChainConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2a5f3e8f1330846819f1abe7a6181c51 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/ClothRendering.compute b/xiaofang/Assets/Obi/Resources/Compute/ClothRendering.compute new file mode 100644 index 00000000..069c5990 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ClothRendering.compute @@ -0,0 +1,180 @@ +#pragma kernel UpdateSkinConstraints +#pragma kernel UpdateClothMesh + +#include "MathUtils.cginc" + +struct Influence +{ + int index; + float weight; +}; + +struct SkinmapData +{ + int firstInfluence; + int firstInfNumber; + int firstParticleBindPose; + + int firstSkinWeight; + int firstSkinWeightNumber; + int firstBoneBindPose; + + int bindPoseCount; +}; + +struct SkeletonData +{ + int firstBone; + int boneCount; +}; + +struct MeshData +{ + int firstVertex; + int vertexCount; + + int firstTriangle; + int triangleCount; +}; + +StructuredBuffer particleIndices; +StructuredBuffer rendererIndices; // for each vertex/particle, index of its renderer. + +StructuredBuffer renderablePositions; +StructuredBuffer renderableOrientations; +StructuredBuffer colors; + +StructuredBuffer restPositions; +StructuredBuffer restOrientations; + +StructuredBuffer skinConstraintOffsets; + +StructuredBuffer skinmapIndices; // for each renderer, index of its skinmap. +StructuredBuffer meshIndices; // for each renderer, index of its mesh. +StructuredBuffer skeletonIndices; // for each renderer, index of its skeleton. + +StructuredBuffer particleOffsets; // for each renderer, index of its first particle in the batch. +StructuredBuffer vertexOffsets; // for each renderer, index of its first vertex in the batch. + +StructuredBuffer skinData; +StructuredBuffer influences; +StructuredBuffer influenceOffsets; +StructuredBuffer particleBindMatrices; +StructuredBuffer boneBindMatrices; + +StructuredBuffer skeletonData; +StructuredBuffer bonePos; +StructuredBuffer boneRot; +StructuredBuffer boneScl; + +StructuredBuffer meshData; +StructuredBuffer positions; +StructuredBuffer normals; +StructuredBuffer tangents; + +RWStructuredBuffer skinConstraintPoints; +RWStructuredBuffer skinConstraintNormals; +RWByteAddressBuffer vertices; + +// Variables set from the CPU +uint vertexCount; +uint constraintCount; +float4x4 world2Solver; + +[numthreads(128, 1, 1)] +void UpdateSkinConstraints (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= constraintCount) return; + + int rendererIndex = rendererIndices[i]; + + // get skin map and mesh data: + SkinmapData skin = skinData[skinmapIndices[rendererIndex]]; + SkeletonData skel = skeletonData[skeletonIndices[rendererIndex]]; + + // invalid skeleton: + if (skel.boneCount <= 0) + return; + + // get index of this particle in its original actor: + int originalParticleIndex = i - particleOffsets[rendererIndex]; + + // get first influence and amount of influences for this particle: + int influenceStart = influenceOffsets[skin.firstSkinWeightNumber + originalParticleIndex]; + int influenceCount = influenceOffsets[skin.firstSkinWeightNumber + originalParticleIndex + 1] - influenceStart; + + float4 pos = FLOAT4_ZERO; + float4 norm = FLOAT4_ZERO; + + for (int k = influenceStart; k < influenceStart + influenceCount; ++k) + { + Influence inf = influences[skin.firstSkinWeight + k]; + + float4x4 bind = boneBindMatrices[skin.firstBoneBindPose + inf.index]; + + int boneIndex = skel.firstBone + inf.index; + float4x4 deform = TRS(bonePos[boneIndex], boneRot[boneIndex], boneScl[boneIndex]); + float4x4 trfm = mul(world2Solver, mul(deform, bind)); + + pos.xyz += mul(trfm, float4(restPositions[particleIndices[i]].xyz, 1)).xyz * inf.weight; + norm.xyz += mul(trfm, float4(rotate_vector(restOrientations[particleIndices[i]], float3(0, 0, 1)), 0)).xyz * inf.weight; + } + + int constraintIndex = skinConstraintOffsets[rendererIndex] + originalParticleIndex; + skinConstraintPoints[constraintIndex] = pos; + skinConstraintNormals[constraintIndex] = norm; + +} + +[numthreads(128, 1, 1)] +void UpdateClothMesh (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= vertexCount) return; + + int rendererIndex = rendererIndices[i]; + + // get skin map and mesh data: + SkinmapData skin = skinData[skinmapIndices[rendererIndex]]; + MeshData mesh = meshData[meshIndices[rendererIndex]]; + + // get index of this vertex in its original mesh: + int originalVertexIndex = i - vertexOffsets[rendererIndex]; + + // get index of the vertex in the mesh batch: + int batchedVertexIndex = mesh.firstVertex + originalVertexIndex; + + // get first influence and amount of influences for this vertex: + int influenceStart = influenceOffsets[skin.firstInfNumber + originalVertexIndex]; + int influenceCount = influenceOffsets[skin.firstInfNumber + originalVertexIndex + 1] - influenceStart; + + float3 position = float3(0,0,0); + float3 normal = float3(0,0,0); + float4 tangent = FLOAT4_ZERO; + float4 color = FLOAT4_ZERO; + + for (int k = influenceStart; k < influenceStart + influenceCount; ++k) + { + Influence inf = influences[skin.firstInfluence + k]; + + int p = particleIndices[particleOffsets[rendererIndex] + inf.index]; + + float4x4 deform = mul(m_translate(FLOAT4X4_IDENTITY,renderablePositions[p].xyz), q_toMatrix(renderableOrientations[p])); + float4x4 trfm = mul(deform, particleBindMatrices[skin.firstParticleBindPose + inf.index]); + + // update vertex/normal/tangent: + position += mul(trfm, float4(positions[batchedVertexIndex], 1)).xyz * inf.weight; + normal += mul(trfm, float4(normals[batchedVertexIndex], 0)).xyz * inf.weight; + tangent += float4(mul(trfm, float4(tangents[batchedVertexIndex].xyz, 0)).xyz, tangents[batchedVertexIndex].w) * inf.weight; + color += colors[p] * inf.weight; + } + + int base = i * 14; + vertices.Store3( base<<2, asuint(position)); + vertices.Store3((base + 3)<<2, asuint(normal)); + vertices.Store4((base + 6)<<2, asuint(tangent)); + vertices.Store4((base + 10)<<2, asuint(color)); +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/ClothRendering.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/ClothRendering.compute.meta new file mode 100644 index 00000000..5b2b24c9 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ClothRendering.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7620e03e082f448828570f6659b73301 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/ColliderCollisionConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/ColliderCollisionConstraints.compute new file mode 100644 index 00000000..d4f22386 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ColliderCollisionConstraints.compute @@ -0,0 +1,219 @@ +#include "ContactHandling.cginc" +#include "ColliderDefinitions.cginc" +#include "Rigidbody.cginc" +#include "Simplex.cginc" +#include "CollisionMaterial.cginc" +#include "AtomicDeltas.cginc" + +#pragma kernel Clear +#pragma kernel Initialize +#pragma kernel Project +#pragma kernel Apply + +StructuredBuffer particleIndices; + +StructuredBuffer simplices; +StructuredBuffer invMasses; +StructuredBuffer invRotationalMasses; +StructuredBuffer prevPositions; +StructuredBuffer prevOrientations; +StructuredBuffer principalRadii; +StructuredBuffer velocities; + +StructuredBuffer transforms; +StructuredBuffer shapes; +RWStructuredBuffer RW_rigidbodies; + +RWStructuredBuffer positions; +RWStructuredBuffer orientations; +RWStructuredBuffer deltas; + +RWStructuredBuffer contacts; +RWStructuredBuffer effectiveMasses; +StructuredBuffer dispatchBuffer; + +StructuredBuffer inertialSolverFrame; + +// Variables set from the CPU +uint particleCount; +float maxDepenetration; +float substepTime; +float stepTime; +int steps; +float timeLeft; +float sorFactor; + +[numthreads(128, 1, 1)] +void Clear (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= dispatchBuffer[3]) return; + + int rigidbodyIndex = shapes[contacts[i].bodyB].rigidbodyIndex; + if (rigidbodyIndex >= 0) + { + int orig; + InterlockedExchange(RW_rigidbodies[rigidbodyIndex].constraintCount, 0, orig); + } +} + +[numthreads(128, 1, 1)] +void Initialize (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= dispatchBuffer[3]) return; + + int simplexSizeA; + int simplexStartA = GetSimplexStartAndSize(contacts[i].bodyA, simplexSizeA); + + // get the material from the first particle in the simplex: + int aMaterialIndex = collisionMaterialIndices[simplices[simplexStartA]]; + bool rollingContacts = aMaterialIndex >= 0 ? collisionMaterials[aMaterialIndex].rollingContacts > 0 : false; + + float4 relativeVelocity = FLOAT4_ZERO; + float4 simplexPrevPosition = FLOAT4_ZERO; + quaternion simplexPrevOrientation = quaternion(0, 0, 0, 0); + float simplexRadius = 0; + float simplexInvMass = 0; + float simplexInvRotationalMass = 0; + + for (int j = 0; j < simplexSizeA; ++j) + { + int particleIndex = simplices[simplexStartA + j]; + relativeVelocity += velocities[particleIndex] * contacts[i].pointA[j]; + simplexPrevPosition += prevPositions[particleIndex] * contacts[i].pointA[j]; + simplexPrevOrientation += prevOrientations[particleIndex] * contacts[i].pointA[j]; + simplexInvMass += invMasses[particleIndex] * contacts[i].pointA[j]; + simplexInvRotationalMass += invRotationalMasses[particleIndex] * contacts[i].pointA[j]; + simplexRadius += EllipsoidRadius(contacts[i].normal, prevOrientations[particleIndex], principalRadii[particleIndex].xyz) * contacts[i].pointA[j]; + } + + // if there's a rigidbody present, subtract its velocity from the relative velocity: + int rigidbodyIndex = shapes[contacts[i].bodyB].rigidbodyIndex; + if (rigidbodyIndex >= 0) + { + // Note: unlike rA, that is expressed in solver space, rB is expressed in world space. + relativeVelocity -= GetRigidbodyVelocityAtPoint(RW_rigidbodies[rigidbodyIndex], contacts[i].pointB, + asfloat(linearDeltasAsInt[rigidbodyIndex]), + asfloat(angularDeltasAsInt[rigidbodyIndex]), inertialSolverFrame[0]); + + int bMaterialIndex = shapes[contacts[i].bodyB].materialIndex; + rollingContacts = rollingContacts | (bMaterialIndex >= 0 ? collisionMaterials[bMaterialIndex].rollingContacts > 0 : false); + } + + // update contact distance + contacts[i].dist = dot(simplexPrevPosition - contacts[i].pointB, contacts[i].normal) - simplexRadius; + + // calculate contact point in A's surface: + float4 contactPoint = contacts[i].pointB + contacts[i].normal * contacts[i].dist; + + // update contact basis: + CalculateBasis(relativeVelocity, contacts[i].normal, contacts[i].tangent); + + // calculate A's contact mass. + float4 invInertiaTensor = 1.0/(GetParticleInertiaTensor(simplexRadius, simplexInvRotationalMass) + FLOAT4_EPSILON); + CalculateContactMassesA(simplexInvMass, invInertiaTensor, simplexPrevPosition, simplexPrevOrientation, contactPoint, rollingContacts, contacts[i].normal, contacts[i].tangent, GetBitangent(contacts[i]), effectiveMasses[i].normalInvMassA, effectiveMasses[i].tangentInvMassA, effectiveMasses[i].bitangentInvMassA); + + // clear B's contact mass. + if (rigidbodyIndex >= 0) + { + CalculateContactMassesB(RW_rigidbodies[rigidbodyIndex], inertialSolverFrame[0].frame, contacts[i].pointB, contacts[i].normal, contacts[i].tangent, GetBitangent(contacts[i]), effectiveMasses[i].normalInvMassB, effectiveMasses[i].tangentInvMassB, effectiveMasses[i].bitangentInvMassB); + InterlockedAdd(RW_rigidbodies[rigidbodyIndex].constraintCount, 1); + } + else + { + ClearContactMasses(effectiveMasses[i].normalInvMassB, effectiveMasses[i].tangentInvMassB, effectiveMasses[i].bitangentInvMassB); + } +} + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= dispatchBuffer[3]) return; + + // Skip contacts involving triggers: + if (shapes[contacts[i].bodyB].isTrigger()) + return; + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(contacts[i].bodyA, simplexSize); + int colliderIndex = contacts[i].bodyB; + + // Get the rigidbody index (might be < 0, in that case there's no rigidbody present) + int rigidbodyIndex = shapes[colliderIndex].rigidbodyIndex; + + float frameEnd = stepTime * steps; + float substepsToEnd = timeLeft / substepTime; + + // Combine collision materials (use material from first particle in simplex) + collisionMaterial material = CombineCollisionMaterials(collisionMaterialIndices[simplices[simplexStart]], shapes[colliderIndex].materialIndex); + + // Get relative velocity at contact point. + // As we do not consider true ellipses for collision detection, particle contact points are never off-axis. + // So particle angular velocity does not contribute to normal impulses, and we can skip it. + float4 simplexPosition = FLOAT4_ZERO; + float4 simplexPrevPosition = FLOAT4_ZERO; + float simplexRadius = 0; + + for (int j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + simplexPosition += positions[particleIndex] * contacts[i].pointA[j]; + simplexPrevPosition += prevPositions[particleIndex] * contacts[i].pointA[j]; + simplexRadius += EllipsoidRadius(contacts[i].normal, orientations[particleIndex], principalRadii[particleIndex].xyz) * contacts[i].pointA[j]; + } + + // project position to the end of the full step: + float4 posA = lerp(simplexPrevPosition, simplexPosition, substepsToEnd); + posA += -contacts[i].normal * simplexRadius; + + float4 posB = contacts[i].pointB; + int rbContacts = 1; + if (rigidbodyIndex >= 0) + { + posB += GetRigidbodyVelocityAtPoint(rigidbodies[rigidbodyIndex], contacts[i].pointB, + asfloat(linearDeltasAsInt[rigidbodyIndex]), + asfloat(angularDeltasAsInt[rigidbodyIndex]), inertialSolverFrame[0]) * frameEnd; + rbContacts = rigidbodies[rigidbodyIndex].constraintCount; + } + + float normalInvMass = effectiveMasses[i].normalInvMassA + effectiveMasses[i].normalInvMassB * rbContacts; + float lambda = SolveAdhesion(contacts[i], normalInvMass, posA, posB, material.stickDistance, material.stickiness, stepTime); + + lambda += SolvePenetration(contacts[i], normalInvMass, posA, posB, maxDepenetration * stepTime); + + if (abs(lambda) > EPSILON) + { + float4 delta = lambda * contacts[i].normal * BaryScale(contacts[i].pointA) / substepsToEnd; + for (int j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + float4 delta1 = delta * invMasses[particleIndex] * contacts[i].pointA[j]; + + AtomicAddPositionDelta(particleIndex, delta1); + } + + if (rigidbodyIndex >= 0) + { + ApplyImpulse(rigidbodyIndex, -lambda / frameEnd * contacts[i].normal, contacts[i].pointB, inertialSolverFrame[0].frame); + } + } +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int threadIndex = id.x; + + if (threadIndex >= particleCount) return; + + int p = particleIndices[threadIndex]; + + ApplyPositionDelta(positions, p, sorFactor); +} + + diff --git a/xiaofang/Assets/Obi/Resources/Compute/ColliderCollisionConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/ColliderCollisionConstraints.compute.meta new file mode 100644 index 00000000..c8cd8057 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ColliderCollisionConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ff4c3e041ffef4a5c91cf275735a7ecc +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/ColliderDefinitions.cginc b/xiaofang/Assets/Obi/Resources/Compute/ColliderDefinitions.cginc new file mode 100644 index 00000000..f5317ee4 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ColliderDefinitions.cginc @@ -0,0 +1,80 @@ +#ifndef COLLIDERDEFS_INCLUDE +#define COLLIDERDEFS_INCLUDE + +#define SPHERE_SHAPE 0 +#define BOX_SHAPE 1 +#define CAPSULE_SHAPE 2 +#define HEIGHTMAP_SHAPE 3 +#define TRIANGLE_MESH_SHAPE 4 +#define EDGE_MESH_SHAPE 5 +#define SDF_SHAPE 6 + +#define FORCEMODE_FORCE 0 +#define FORCEMODE_ACCEL 1 +#define FORCEMODE_WIND 2 + +#define DAMPDIR_ALL 0 +#define DAMPDIR_FORCE 1 +#define DAMPDIR_SURFACE 2 + +#define ZONETYPE_DIRECTIONAL 0 +#define ZONETYPE_RADIAL 1 +#define ZONETYPE_VORTEX 2 +#define ZONETYPE_VOID 3 + +struct shape +{ + float4 center; + float4 size; /**< box: size of the box in each axis. + sphere: radius of sphere (x,y,z), + capsule: radius (x), height(y), direction (z, can be 0, 1 or 2). + heightmap: width (x axis), height (y axis) and depth (z axis) in world units.*/ + uint type; /**< Sphere = 0, + Box = 1, + Capsule = 2, + Heightmap = 3, + TriangleMesh = 4, + EdgeMesh = 5, + SignedDistanceField = 6*/ + + float contactOffset; + int dataIndex; + int rigidbodyIndex; // index of the associated rigidbody in the collision world. + int materialIndex; // index of the associated material in the collision world. + int forceZoneIndex; // index of the associated force zone in the collision world. + int phase; + int flags; // first bit whether the collider is 2D (1) or 3D (0), second bit whether it's a trigger (1) or regular collider (0). + // third bit determines whether shape is inverted or not. + + bool is2D() + { + return (flags & 1) != 0; + } + + bool isTrigger() + { + // TODO: using bools doesn't work... why? + int a = (flags & 1 << 1) != 0; + int b = forceZoneIndex >= 0; + return a || b; + } + + float isInverted() + { + return (flags & 1 << 2) != 0 ? -1 : 1; + } +}; + +struct forceZone +{ + uint type; + uint mode; + uint dampingDir; + float intensity; + float minDistance; + float maxDistance; + float falloffPower; + float damping; +}; + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/ColliderDefinitions.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/ColliderDefinitions.cginc.meta new file mode 100644 index 00000000..46948415 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ColliderDefinitions.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fe486a46344cd4c299b4475a4e046796 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/ColliderFrictionConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/ColliderFrictionConstraints.compute new file mode 100644 index 00000000..175d3320 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ColliderFrictionConstraints.compute @@ -0,0 +1,192 @@ +#include "ContactHandling.cginc" +#include "ColliderDefinitions.cginc" +#include "Rigidbody.cginc" +#include "Simplex.cginc" +#include "CollisionMaterial.cginc" +#include "Integration.cginc" +#include "AtomicDeltas.cginc" + +#pragma kernel Project +#pragma kernel Apply + +StructuredBuffer particleIndices; +StructuredBuffer simplices; +StructuredBuffer invMasses; +StructuredBuffer invRotationalMasses; +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer prevPositions; +StructuredBuffer prevOrientations; +StructuredBuffer principalRadii; + +StructuredBuffer transforms; +StructuredBuffer shapes; + +RWStructuredBuffer RW_positions; +RWStructuredBuffer RW_orientations; + +RWStructuredBuffer contacts; +RWStructuredBuffer effectiveMasses; +StructuredBuffer dispatchBuffer; + +StructuredBuffer solverToWorld; +StructuredBuffer inertialSolverFrame; + +// Variables set from the CPU +uint particleCount; +float substepTime; +float stepTime; +float sorFactor; + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= dispatchBuffer[3]) return; + + // Skip contacts involving triggers: + if (shapes[contacts[i].bodyB].isTrigger()) + return; + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(contacts[i].bodyA, simplexSize); + int colliderIndex = contacts[i].bodyB; + + int rigidbodyIndex = shapes[colliderIndex].rigidbodyIndex; + + // Combine collision materials (use material from first particle in simplex) + collisionMaterial material = CombineCollisionMaterials(collisionMaterialIndices[simplices[simplexStart]], shapes[colliderIndex].materialIndex); + + // Calculate relative velocity: + float4 rA = float4(0,0,0,0), rB = float4(0,0,0,0); + + float4 prevPositionA = float4(0,0,0,0); + float4 linearVelocityA = float4(0,0,0,0); + float4 angularVelocityA = float4(0,0,0,0); + float invRotationalMassA = 0; + quaternion orientationA = quaternion(0, 0, 0, 0); + float simplexRadiusA = 0; + + int j = 0; + for (j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + prevPositionA += prevPositions[particleIndex] * contacts[i].pointA[j]; + linearVelocityA += DifferentiateLinear(positions[particleIndex], prevPositions[particleIndex], substepTime) * contacts[i].pointA[j]; + angularVelocityA += DifferentiateAngular(orientations[particleIndex], prevOrientations[particleIndex], substepTime) * contacts[i].pointA[j]; + invRotationalMassA += invRotationalMasses[particleIndex] * contacts[i].pointA[j]; + orientationA += orientations[particleIndex] * contacts[i].pointA[j]; + simplexRadiusA += EllipsoidRadius(contacts[i].normal, prevOrientations[particleIndex], principalRadii[particleIndex].xyz) * contacts[i].pointA[j]; + } + + float4 relativeVelocity = linearVelocityA; + + // Add particle angular velocity if rolling contacts are enabled: + if (material.rollingContacts > 0) + { + rA = -contacts[i].normal * simplexRadiusA; + relativeVelocity += float4(cross(angularVelocityA.xyz, rA.xyz), 0); + } + + // Subtract rigidbody velocity: + int rbContacts = 1; + if (rigidbodyIndex >= 0) + { + // Note: unlike rA, that is expressed in solver space, rB is expressed in world space. + rB = solverToWorld[0].TransformPoint(contacts[i].pointB) - rigidbodies[rigidbodyIndex].com; + + relativeVelocity -= GetRigidbodyVelocityAtPoint(rigidbodies[rigidbodyIndex], contacts[i].pointB, + asfloat(linearDeltasAsInt[rigidbodyIndex]), + asfloat(angularDeltasAsInt[rigidbodyIndex]), inertialSolverFrame[0]); + + rbContacts = rigidbodies[rigidbodyIndex].constraintCount; + } + + // Determine impulse magnitude: + float tangentMass = effectiveMasses[i].tangentInvMassA + effectiveMasses[i].tangentInvMassB * rbContacts; + float bitangentMass = effectiveMasses[i].bitangentInvMassA + effectiveMasses[i].bitangentInvMassB * rbContacts; + float2 impulses = SolveFriction(contacts[i], tangentMass, bitangentMass, relativeVelocity, material.staticFriction, material.dynamicFriction, stepTime); + + if (abs(impulses.x) > EPSILON || abs(impulses.y) > EPSILON) + { + float4 tangentImpulse = impulses.x * contacts[i].tangent; + float4 bitangentImpulse = impulses.y * GetBitangent(contacts[i]); + float4 totalImpulse = tangentImpulse + bitangentImpulse; + + float baryScale = BaryScale(contacts[i].pointA); + for (j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + float4 delta1 = (tangentImpulse * effectiveMasses[i].tangentInvMassA + bitangentImpulse * effectiveMasses[i].bitangentInvMassA) * substepTime * contacts[i].pointA[j] * baryScale; + AtomicAddPositionDelta(particleIndex, delta1); + } + + if (rigidbodyIndex >= 0) + { + ApplyImpulse(rigidbodyIndex, -totalImpulse, contacts[i].pointB, inertialSolverFrame[0].frame); + } + + // Rolling contacts: + if (material.rollingContacts > 0) + { + // Calculate angular velocity deltas due to friction impulse: + float4 invInertiaTensor = 1.0/(GetParticleInertiaTensor(simplexRadiusA, invRotationalMassA) + FLOAT4_EPSILON); + float4x4 solverInertiaA = TransformInertiaTensor(invInertiaTensor, orientationA); + + float4 angVelDeltaA = mul(solverInertiaA, float4(cross(rA.xyz, totalImpulse.xyz), 0)); + float4 angVelDeltaB = FLOAT4_ZERO; + + // Final angular velocities, after adding the deltas: + angularVelocityA += angVelDeltaA; + float4 angularVelocityB = FLOAT4_ZERO; + + // Calculate weights (inverse masses): + float invMassA = length(mul(solverInertiaA, normalizesafe(angularVelocityA))); + float invMassB = 0; + + if (rigidbodyIndex >= 0) + { + angVelDeltaB = mul(-rigidbodies[rigidbodyIndex].inverseInertiaTensor, float4(cross(rB.xyz, totalImpulse.xyz), 0)); + angularVelocityB = rigidbodies[rigidbodyIndex].angularVelocity + angVelDeltaB; + invMassB = length(mul(rigidbodies[rigidbodyIndex].inverseInertiaTensor, normalizesafe(angularVelocityB))) * rbContacts; + } + + // Calculate rolling axis and angular velocity deltas: + float4 rollAxis = FLOAT4_ZERO; + float rollingImpulse = SolveRollingFriction(contacts[i], angularVelocityA, angularVelocityB, material.rollingFriction, invMassA, invMassB, rollAxis); + angVelDeltaA += rollAxis * rollingImpulse * invMassA; + angVelDeltaB -= rollAxis * rollingImpulse * invMassB; + + // Apply orientation delta to particles: + quaternion orientationDelta = AngularVelocityToSpinQuaternion(orientationA, angVelDeltaA, substepTime); + + for (j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + AtomicAddOrientationDelta(particleIndex, orientationDelta); + } + + // Apply angular velocity delta to rigidbody: + if (rigidbodyIndex >= 0) + { + AtomicAddAngularDelta(rigidbodyIndex, angVelDeltaB); + } + } + } +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int threadIndex = id.x; + + if (threadIndex >= particleCount) return; + + int p = particleIndices[threadIndex]; + + ApplyPositionDelta(RW_positions, p, sorFactor); + ApplyOrientationDelta(RW_orientations, p, sorFactor); +} + + diff --git a/xiaofang/Assets/Obi/Resources/Compute/ColliderFrictionConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/ColliderFrictionConstraints.compute.meta new file mode 100644 index 00000000..e3e3d701 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ColliderFrictionConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ec52fd9d30c594294a7c2f0f50cc6096 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/ColliderGrid.compute b/xiaofang/Assets/Obi/Resources/Compute/ColliderGrid.compute new file mode 100644 index 00000000..c699fbf0 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ColliderGrid.compute @@ -0,0 +1,473 @@ +#include "GridUtils.cginc" +#include "CollisionMaterial.cginc" +#include "ContactHandling.cginc" +#include "ColliderDefinitions.cginc" +#include "Rigidbody.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "AtomicDeltas.cginc" +#include "Phases.cginc" + +#define MAX_CONTACTS_PER_SIMPLEX 32 + +#pragma kernel Clear +#pragma kernel BuildUnsortedList +#pragma kernel FindPopulatedLevels +#pragma kernel SortList +#pragma kernel BuildContactList +#pragma kernel PrefixSumColliderCounts +#pragma kernel SortContactPairs +#pragma kernel ApplyForceZones +#pragma kernel WriteForceZoneResults + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer principalRadii; +StructuredBuffer invMasses; +StructuredBuffer velocities; +RWStructuredBuffer externalForces; +RWStructuredBuffer wind; +RWStructuredBuffer life; + +StructuredBuffer activeParticles; +StructuredBuffer simplices; +StructuredBuffer filters; +RWStructuredBuffer simplexBounds; // bounding box of each simplex. + +StructuredBuffer aabbs; +StructuredBuffer transforms; +StructuredBuffer shapes; +StructuredBuffer forceZones; +RWStructuredBuffer sortedColliderIndices; + +RWStructuredBuffer colliderTypeCounts; +RWStructuredBuffer contactOffsetsPerType; +RWStructuredBuffer unsortedContactPairs; + +RWStructuredBuffer cellIndices; +RWStructuredBuffer cellOffsets; + +RWStructuredBuffer cellCounts; +RWStructuredBuffer offsetInCells; + +RWStructuredBuffer contacts; +RWStructuredBuffer contactPairs; +RWStructuredBuffer dispatchBuffer; + +StructuredBuffer solverToWorld; +StructuredBuffer worldToSolver; + +uint maxContacts; +uint colliderCount; // amount of colliders in the grid. +uint cellsPerCollider; // max amount of cells a collider can be inserted into. Typically this is 8. +int shapeTypeCount; // number of different collider shapes, ie: box, sphere, sdf, etc. +uint particleCount; +float deltaTime; + +[numthreads(128, 1, 1)] +void Clear (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i == 0) + { + for (int l = 0; l <= GRID_LEVELS; ++l) + levelPopulation[l] = 0; + } + + // clear all cell offsets to invalid, so that we can later use atomic minimum to calculate the offset. + if (i < maxCells) + { + cellOffsets[i] = INVALID; + cellCounts[i] = 0; + } + + // clear all cell indices to invalid. + if (i < colliderCount) + { + for (uint j = 0; j < cellsPerCollider; ++j) + cellIndices[i*cellsPerCollider+j] = INVALID; + } +} + +[numthreads(128, 1, 1)] +void BuildUnsortedList (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= colliderCount) return; + + aabb bounds = aabbs[i]; + int rb = shapes[i].rigidbodyIndex; + + // Expand bounds by rigidbody's linear velocity + // (check against out of bounds rigidbody access, can happen when a destroyed collider references a rigidbody that has just been destroyed too) + if (rb >= 0)// && rb < rigidbodies.Length) + bounds.Sweep(rigidbodies[rb].velocity * deltaTime); + + // Expand bounds by collision material's stick distance: + if (shapes[i].materialIndex >= 0) + bounds.Expand(collisionMaterials[shapes[i].materialIndex].stickDistance); + + // calculate bounds size, grid level and cell size: + float4 size = bounds.max_ - bounds.min_; + float maxSize = max(max (size.x, size.y), size.z); + int level = GridLevelForSize(maxSize); + float cellSize = CellSizeOfLevel(level); + + // calculate max and min cell coordinates (force 4th component to zero, might not be after expanding) + int4 minCell = floor(bounds.min_ / cellSize); + int4 maxCell = floor(bounds.max_ / cellSize); + minCell[3] = 0; + maxCell[3] = 0; + + // if the collider is 2D, project it to the z = 0 cells. + if (shapes[i].is2D()) + { + minCell[2] = 0; + maxCell[2] = 0; + } + + int4 cellSpan = maxCell - minCell; + + // insert collider in cells: + for (int x = 0; x <= cellSpan[0]; ++x) + { + for (int y = 0; y <= cellSpan[1]; ++y) + { + for (int z = 0; z <= cellSpan[2]; ++z) + { + int cellIndex = GridHash(minCell + int4(x, y, z, level)); + + // calculate flat index of this cell into arrays: + int k = x + y*2 + z*4 + i*cellsPerCollider; + + cellIndices[k] = cellIndex; + InterlockedAdd(cellCounts[cellIndex],1,offsetInCells[k]); + } + } + } + + // atomically increase this level's population by one: + InterlockedAdd(levelPopulation[1 + level],1); +} + +[numthreads(128, 1, 1)] +void SortList (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + if (i >= colliderCount * cellsPerCollider) return; + + uint cellIndex = cellIndices[i]; + + if (cellIndex != INVALID) + { + // write collider to its sorted index: + uint sortedIndex = cellOffsets[cellIndex] + offsetInCells[i]; + sortedColliderIndices[sortedIndex] = i; + } +} + +[numthreads(128, 1, 1)] +void BuildContactList (uint3 id : SV_DispatchThreadID) +{ + unsigned int threadIndex = id.x; + + if (threadIndex >= pointCount + edgeCount + triangleCount) return; + + uint cellCount = colliderCount * cellsPerCollider; + int candidateCount = 0; + uint candidates[MAX_CONTACTS_PER_SIMPLEX]; + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(threadIndex, simplexSize); + + aabb b = simplexBounds[threadIndex].Transformed(solverToWorld[0]); + + // max size of the particle bounds in cells: + int4 maxSize = int4(10,10,10,10); + + // build a list of candidate colliders: + for (uint m = 1; m <= levelPopulation[0]; ++m) + { + uint l = levelPopulation[m]; + float cellSize = CellSizeOfLevel(l); + + int4 minCell = floor(b.min_ / cellSize); + int4 maxCell = floor(b.max_ / cellSize); + maxCell = minCell + min(maxCell - minCell, maxSize); + + for (int x = minCell[0]; x <= maxCell[0]; ++x) + { + for (int y = minCell[1]; y <= maxCell[1]; ++y) + { + // for 2D mode, project each cell at z == 0 and check them too. This way we ensure 2D colliders + // (which are inserted in cells with z == 0) are accounted for in the broadphase. + if (mode == 1) + { + uint flatCellIndex = GridHash(int4(x,y,0,l)); + uint cellStart = cellOffsets[flatCellIndex]; + uint cellCount = cellCounts[flatCellIndex]; + + // iterate through colliders in the neighbour cell + for (uint n = cellStart; n < cellStart + cellCount; ++n) + { + // sorted insert into the candidates list: + if (candidateCount < MAX_CONTACTS_PER_SIMPLEX) + candidates[candidateCount++] = sortedColliderIndices[n] / cellsPerCollider; + } + } + + for (int z = minCell[2]; z <= maxCell[2]; ++z) + { + uint flatCellIndex = GridHash(int4(x,y,z,l)); + uint cellStart = cellOffsets[flatCellIndex]; + uint cellCount = cellCounts[flatCellIndex]; + + // iterate through colliders in the neighbour cell + for (uint n = cellStart; n < cellStart + cellCount; ++n) + { + if (candidateCount < MAX_CONTACTS_PER_SIMPLEX) + candidates[candidateCount++] = sortedColliderIndices[n] / cellsPerCollider; + } + + } + } + } + } + + //evaluate candidates and create contacts: + if (candidateCount > 0) + { + // insert sort: + for (int k = 1; k < candidateCount; ++k) + { + uint key = candidates[k]; + int j = k - 1; + + while (j >= 0 && candidates[j] > key) + candidates[j + 1] = candidates[j--]; + + candidates[j + 1] = key; + } + + // make sure each candidate only shows up once in the list: + int first = 0, contactCount = 0; + while(++first != candidateCount) + { + if (candidates[contactCount] != candidates[first]) + candidates[++contactCount] = candidates[first]; + } + contactCount++; + + // append contacts: + for (int i = 0; i < contactCount; i++) + { + int c = candidates[i]; + + aabb colliderBoundsWS = aabbs[c]; + int rb = shapes[c].rigidbodyIndex; + + // Expand bounds by rigidbody's linear velocity: + if (rb >= 0) + colliderBoundsWS.Sweep(rigidbodies[rb].velocity * deltaTime); + + // Expand bounds by collision material's stick distance: + if (shapes[c].materialIndex >= 0) + colliderBoundsWS.Expand(collisionMaterials[shapes[c].materialIndex].stickDistance); + + // check if any simplex particle and the collider should collide: + bool shouldCollide = false; + int colliderCategory = shapes[c].phase & CategoryMask; + int colliderMask = (shapes[c].phase & MaskMask) >> 16; + for (int j = 0; j < simplexSize; ++j) + { + int simplexCategory = filters[simplices[simplexStart + j]] & CategoryMask; + int simplexMask = (filters[simplices[simplexStart + j]] & MaskMask) >> 16; + shouldCollide = shouldCollide || ((simplexCategory & colliderMask) != 0 && (simplexMask & colliderCategory) != 0); + } + + if (shouldCollide && b.IntersectsAabb(colliderBoundsWS, mode == 1)) + { + uint count; + InterlockedAdd(dispatchBuffer[7], 1, count); + + // technically incorrect, as number of pairs != number of contacts but + // we will ignore either excess pairs or contacts. + if (count < maxContacts) + { + // increment the amount of contacts for this shape type: + InterlockedAdd(colliderTypeCounts[shapes[c].type],1); + + // enqueue a new contact pair: + unsortedContactPairs[count] = uint2(threadIndex,c); + + InterlockedMax(dispatchBuffer[4],(count + 1) / 128 + 1); + } + } + } + } +} + +[numthreads(1, 1, 1)] +void PrefixSumColliderCounts (uint3 id : SV_DispatchThreadID) +{ + contactOffsetsPerType[0] = 0; + int i; + + for (i = 0; i < shapeTypeCount; ++i) + { + contactOffsetsPerType[i+1] = contactOffsetsPerType[i] + colliderTypeCounts[i]; + + // write amount of pairs per collider type in the dispatch buffer: + dispatchBuffer[8 + i*4] = colliderTypeCounts[i] / 128 + 1; + dispatchBuffer[8 + i*4 + 3] = colliderTypeCounts[i]; + } +} + +[numthreads(128, 1, 1)] +void SortContactPairs (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + if (i >= dispatchBuffer[7] || i >= maxContacts) return; + + uint2 pair = unsortedContactPairs[i]; + int shapeType = (int)shapes[pair.y].type; + + // decrement amount of pairs for the given collider type: + uint count; + InterlockedAdd(colliderTypeCounts[shapeType],-1, count); + + // write the pair directly at its position in the sorted array: + contactPairs[contactOffsetsPerType[shapeType] + count - 1] = pair; +} + +void AtomicAddExternalForceDelta(in int index, in float4 delta) +{ + InterlockedAddFloat(deltasAsInt, index, 0, delta.x); + InterlockedAddFloat(deltasAsInt, index, 1, delta.y); + InterlockedAddFloat(deltasAsInt, index, 2, delta.z); +} + +void AtomicAddWindDelta(in int index, in float4 delta) +{ + InterlockedAddFloat(orientationDeltasAsInt, index, 0, delta.x); + InterlockedAddFloat(orientationDeltasAsInt, index, 1, delta.y); + InterlockedAddFloat(orientationDeltasAsInt, index, 2, delta.z); +} + +void AtomicAddLifeDelta(in int index, in float delta) +{ + InterlockedAddFloat(deltasAsInt, index, 3, delta); +} + +[numthreads(128, 1, 1)] +void ApplyForceZones (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatchBuffer[3]) return; + + int forceZoneIndex = shapes[contacts[i].bodyB].forceZoneIndex; + + if (forceZoneIndex >= 0) + { + int simplexSize; + int simplexStart = GetSimplexStartAndSize(contacts[i].bodyA, simplexSize); + + for (int j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + + if (invMasses[particleIndex] > 0) + { + float dist = -dot(positions[particleIndex] - contacts[i].pointB, contacts[i].normal); + if (dist < 0) continue; + + float4 axis = worldToSolver[0].Multiply(transforms[contacts[i].bodyB]).TransformDirection(float4(0, 0, 1, 0)); + + // calculate falloff region based on min/max distances: + float falloff = 1; + float range = forceZones[forceZoneIndex].maxDistance - forceZones[forceZoneIndex].minDistance; + if (abs(range) > EPSILON) + falloff = pow(saturate((dist - forceZones[forceZoneIndex].minDistance) / range), forceZones[forceZoneIndex].falloffPower); + + float forceIntensity = forceZones[forceZoneIndex].intensity * falloff; + float dampIntensity = forceZones[forceZoneIndex].damping * falloff; + + // calculate force direction, depending on the type of the force field: + float4 result = FLOAT4_ZERO; + switch (forceZones[forceZoneIndex].type) + { + case ZONETYPE_RADIAL: + result = contacts[i].normal * forceIntensity; + break; + case ZONETYPE_VORTEX: + result = float4(cross(axis.xyz * forceIntensity, contacts[i].normal.xyz),0); + break; + case ZONETYPE_DIRECTIONAL: + result = axis * forceIntensity; + break; + default: + AtomicAddLifeDelta(particleIndex, -forceIntensity * deltaTime); + return; + } + + // calculate damping along force direction: + float4 dampingDir; + switch (forceZones[forceZoneIndex].dampingDir) + { + case DAMPDIR_FORCE: + { + float4 forceDir = normalizesafe(result); + result -= forceDir * dot(velocities[particleIndex], forceDir) * dampIntensity; + } + break; + case DAMPDIR_SURFACE: + result -= contacts[i].normal * dot(velocities[particleIndex], contacts[i].normal) * dampIntensity; + break; + default: + result -= velocities[particleIndex] * dampIntensity; + break; + } + + // here we reuse position and orientation delta buffers as velocity and wind buffers for atomic writes: + switch (forceZones[forceZoneIndex].mode) + { + case FORCEMODE_ACCEL: + AtomicAddExternalForceDelta(particleIndex, result / simplexSize / invMasses[particleIndex]); + break; + case FORCEMODE_FORCE: + AtomicAddExternalForceDelta(particleIndex, result / simplexSize); + break; + case FORCEMODE_WIND: + AtomicAddWindDelta(particleIndex, result / simplexSize); + break; + } + } + } + } +} + +[numthreads(128, 1, 1)] +void WriteForceZoneResults (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= particleCount) return; + + int p = activeParticles[i]; + + externalForces[p].xyz += float3(asfloat(deltasAsInt[p].x), + asfloat(deltasAsInt[p].y), + asfloat(deltasAsInt[p].z)); + + wind[p].xyz += float3(asfloat(orientationDeltasAsInt[p].x), + asfloat(orientationDeltasAsInt[p].y), + asfloat(orientationDeltasAsInt[p].z)); + + life[p] += asfloat(deltasAsInt[p].w); + + deltasAsInt[p] = uint4(0, 0, 0, 0); + orientationDeltasAsInt[p] = uint4(0, 0, 0, 0); +} + + diff --git a/xiaofang/Assets/Obi/Resources/Compute/ColliderGrid.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/ColliderGrid.compute.meta new file mode 100644 index 00000000..6dbc2185 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ColliderGrid.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: df152b65921c34856a1ea566d782acc1 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/CollisionMaterial.cginc b/xiaofang/Assets/Obi/Resources/Compute/CollisionMaterial.cginc new file mode 100644 index 00000000..5bfaa856 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/CollisionMaterial.cginc @@ -0,0 +1,109 @@ +#ifndef COLLISIONMATERIAL_INCLUDE +#define COLLISIONMATERIAL_INCLUDE + +struct collisionMaterial +{ + float dynamicFriction; + float staticFriction; + float rollingFriction; + float stickiness; + float stickDistance; + int frictionCombine; + int stickinessCombine; + int rollingContacts; +}; + +StructuredBuffer collisionMaterialIndices; +StructuredBuffer collisionMaterials; + +collisionMaterial EmptyCollisionMaterial() +{ + collisionMaterial m; + m.dynamicFriction = 0; + m.staticFriction = 0; + m.rollingFriction = 0; + m.stickiness = 0; + m.stickDistance = 0; + m.frictionCombine = 0; + m.stickinessCombine = 0; + m.rollingContacts = 0; + return m; +} + +collisionMaterial CombineWith(collisionMaterial a, collisionMaterial b) +{ + collisionMaterial result; + int frictionCombineMode = max(a.frictionCombine, b.frictionCombine); + int stickCombineMode = max(a.stickinessCombine, b.stickinessCombine); + + switch (frictionCombineMode) + { + case 0: + default: + result.dynamicFriction = (a.dynamicFriction + b.dynamicFriction) * 0.5f; + result.staticFriction = (a.staticFriction + b.staticFriction) * 0.5f; + result.rollingFriction = (a.rollingFriction + b.rollingFriction) * 0.5f; + break; + + case 1: + result.dynamicFriction = min(a.dynamicFriction, b.dynamicFriction); + result.staticFriction = min(a.staticFriction, b.staticFriction); + result.rollingFriction = min(a.rollingFriction, b.rollingFriction); + break; + + case 2: + result.dynamicFriction = a.dynamicFriction * b.dynamicFriction; + result.staticFriction = a.staticFriction * b.staticFriction; + result.rollingFriction = a.rollingFriction * b.rollingFriction; + break; + + case 3: + result.dynamicFriction = max(a.dynamicFriction, b.dynamicFriction); + result.staticFriction = max(a.staticFriction, b.staticFriction); + result.rollingFriction = max(a.rollingFriction, b.rollingFriction); + break; + } + + switch (stickCombineMode) + { + case 0: + default: + result.stickiness = (a.stickiness + b.stickiness) * 0.5f; + break; + + case 1: + result.stickiness = min(a.stickiness, b.stickiness); + break; + + case 2: + result.stickiness = a.stickiness * b.stickiness; + break; + + case 3: + result.stickiness = max(a.stickiness, b.stickiness); + break; + } + + result.stickDistance = max(a.stickDistance, b.stickDistance); + result.rollingContacts = a.rollingContacts | b.rollingContacts; + return result; +} + +collisionMaterial CombineCollisionMaterials(int materialA, int materialB) +{ + // Combine collision materials: + collisionMaterial combined; + + if (materialA >= 0 && materialB >= 0) + combined = CombineWith(collisionMaterials[materialA], collisionMaterials[materialB]); + else if (materialA >= 0) + combined = collisionMaterials[materialA]; + else if (materialB >= 0) + combined = collisionMaterials[materialB]; + else + combined = EmptyCollisionMaterial(); + + return combined; +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/CollisionMaterial.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/CollisionMaterial.cginc.meta new file mode 100644 index 00000000..adab542a --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/CollisionMaterial.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 034a508161c9948969266fd0cbf21988 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/ContactHandling.cginc b/xiaofang/Assets/Obi/Resources/Compute/ContactHandling.cginc new file mode 100644 index 00000000..1ffbd7fb --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ContactHandling.cginc @@ -0,0 +1,228 @@ +#ifndef CONTACTHANDLING_INCLUDE +#define CONTACTHANDLING_INCLUDE + +#include "MathUtils.cginc" +#include "Transform.cginc" + +struct contact // 96 bytes +{ + float4 pointA; // point A, expressed as simplex barycentric coords for simplices, as a solver-space position for colliders. + float4 pointB; // point B, expressed as simplex barycentric coords for simplices, as a solver-space position for colliders. + float4 normal; /**< Normal direction. */ + float4 tangent; /**< Tangent direction. */ + + float dist; /** distance between both colliding entities at the beginning of the timestep.*/ + + float normalLambda; + float tangentLambda; + float bitangentLambda; + float stickLambda; + float rollingFrictionImpulse; + + int bodyA; + int bodyB; +}; + +// 24 bytes +struct contactMasses +{ + float normalInvMassA; + float tangentInvMassA; + float bitangentInvMassA; + + float normalInvMassB; + float tangentInvMassB; + float bitangentInvMassB; +}; + +float4 GetBitangent(in contact c) +{ + return normalizesafe(float4(cross(c.normal.xyz,c.tangent.xyz),0)); +} + +void CalculateBasis(in float4 relativeVelocity, in float4 normal, out float4 tangent) +{ + tangent = normalizesafe(relativeVelocity - dot(relativeVelocity, normal) * normal); +} + +void CalculateContactMassesA(float invMass, + float4 inverseInertiaTensor, + float4 position, + quaternion orientation, + float4 contactPoint, + bool rollingContacts, + float4 normal, + float4 bitangent, + float4 tangent, + out float normalInvMassA, + out float tangentInvMassA, + out float bitangentInvMassA) +{ + // initialize inverse linear masses: + normalInvMassA = tangentInvMassA = bitangentInvMassA = invMass; + + if (rollingContacts) + { + float4 rA = contactPoint - position; + float4x4 solverInertiaA = TransformInertiaTensor(inverseInertiaTensor, orientation); + + normalInvMassA += RotationalInvMass(solverInertiaA, rA, normal); + tangentInvMassA += RotationalInvMass(solverInertiaA, rA, tangent); + bitangentInvMassA += RotationalInvMass(solverInertiaA, rA, bitangent); + } +} + +void CalculateContactMassesB(float invMass, + float4 inverseInertiaTensor, + float4 position, + quaternion orientation, + float4 contactPoint, + bool rollingContacts, + float4 normal, + float4 bitangent, + float4 tangent, + out float normalInvMassB, + out float tangentInvMassB, + out float bitangentInvMassB) +{ + // initialize inverse linear masses: + normalInvMassB = tangentInvMassB = bitangentInvMassB = invMass; + + if (rollingContacts) + { + float4 rB = contactPoint - position; + float4x4 solverInertiaB = TransformInertiaTensor(inverseInertiaTensor, orientation); + + normalInvMassB += RotationalInvMass(solverInertiaB, rB, normal); + tangentInvMassB += RotationalInvMass(solverInertiaB, rB, tangent); + bitangentInvMassB += RotationalInvMass(solverInertiaB, rB, bitangent); + } +} + +void ClearContactMasses(out float normalInvMass, + out float tangentInvMass, + out float bitangentInvMass) +{ + normalInvMass = tangentInvMass = bitangentInvMass = 0; +} + +float SolveAdhesion(inout contact c, float normalMass, float4 posA, float4 posB, float stickDistance, float stickiness, float dt) +{ + float lambdaChange = 0; + + if (normalMass > 0 && stickDistance > 0 && stickiness > 0 && dt > 0) + { + c.dist = dot(posA - posB, c.normal); + + // calculate stickiness position correction: + float constraint = stickiness * (1 - max(c.dist / stickDistance, 0)) * dt; + + // calculate lambda multiplier: + float dlambda = -constraint / normalMass; + + // accumulate lambda: + float newStickinessLambda = min(c.stickLambda + dlambda, 0); + + // calculate lambda change and update accumulated lambda: + lambdaChange = newStickinessLambda - c.stickLambda; + c.stickLambda = newStickinessLambda; + } + + return lambdaChange; +} + +float SolvePenetration(inout contact c, float normalMass, float4 posA, float4 posB, float maxDepenetrationDelta) +{ + float lambdaChange = 0; + + if (normalMass > 0) + { + //project position delta to normal vector: + c.dist = dot(posA - posB, c.normal); + + // calculate max projection distance based on depenetration velocity: + float maxProjection = max(-c.dist - maxDepenetrationDelta, 0); + + // calculate lambda multiplier: + float dlambda = -(c.dist + maxProjection) / normalMass; + + // accumulate lambda: + float newLambda = max(c.normalLambda + dlambda, 0); + + // calculate lambda change and update accumulated lambda: + lambdaChange = newLambda - c.normalLambda; + c.normalLambda = newLambda; + } + + return lambdaChange; +} + +float2 SolveFriction(inout contact c, float tangentMass, float bitangentMass, float4 relativeVelocity, float staticFriction, float dynamicFriction, float dt) +{ + float2 lambdaChange = float2(0,0); + + if (tangentMass > 0 && bitangentMass > 0 && + (dynamicFriction > 0 || staticFriction > 0) && (c.normalLambda > 0 /*|| stickLambda > 0*/)) + { + // calculate delta projection on both friction axis: + float tangentPosDelta = dot(relativeVelocity, c.tangent); + float bitangentPosDelta = dot(relativeVelocity, GetBitangent(c)); + + // calculate friction pyramid limit: + float dynamicFrictionCone = c.normalLambda / dt * dynamicFriction; + float staticFrictionCone = c.normalLambda / dt * staticFriction; + + // tangent impulse: + float tangentLambdaDelta = -tangentPosDelta / tangentMass; + float newTangentLambda = c.tangentLambda + tangentLambdaDelta; + + if (abs(newTangentLambda) > staticFrictionCone) + newTangentLambda = clamp(newTangentLambda, -dynamicFrictionCone, dynamicFrictionCone); + + lambdaChange[0] = newTangentLambda - c.tangentLambda; + c.tangentLambda = newTangentLambda; + + // bitangent impulse: + float bitangentLambdaDelta = -bitangentPosDelta / bitangentMass; + float newBitangentLambda = c.bitangentLambda + bitangentLambdaDelta; + + if (abs(newBitangentLambda) > staticFrictionCone) + newBitangentLambda = clamp(newBitangentLambda, -dynamicFrictionCone, dynamicFrictionCone); + + lambdaChange[1] = newBitangentLambda - c.bitangentLambda; + c.bitangentLambda = newBitangentLambda; + } + + return lambdaChange; +} + +float SolveRollingFriction(inout contact c, + float4 angularVelocityA, + float4 angularVelocityB, + float rollingFriction, + float invMassA, + float invMassB, + inout float4 rolling_axis) +{ + float rolling_impulse_change = 0; + float totalInvMass = invMassA + invMassB; + + if (totalInvMass > 0) + { + rolling_axis = normalizesafe(angularVelocityA - angularVelocityB); + + float vel1 = dot(angularVelocityA,rolling_axis); + float vel2 = dot(angularVelocityB,rolling_axis); + + float relativeVelocity = vel1 - vel2; + + float maxImpulse = c.normalLambda * rollingFriction; + float newRollingImpulse = clamp(c.rollingFrictionImpulse - relativeVelocity / totalInvMass, -maxImpulse, maxImpulse); + rolling_impulse_change = newRollingImpulse - c.rollingFrictionImpulse; + c.rollingFrictionImpulse = newRollingImpulse; + } + + return rolling_impulse_change; +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/ContactHandling.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/ContactHandling.cginc.meta new file mode 100644 index 00000000..0cf2726c --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ContactHandling.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 28492658e279e4adaab298f430af09a2 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/DeformableTriangles.compute b/xiaofang/Assets/Obi/Resources/Compute/DeformableTriangles.compute new file mode 100644 index 00000000..636b7a71 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/DeformableTriangles.compute @@ -0,0 +1,139 @@ +#pragma kernel ResetNormals +#pragma kernel UpdateNormals +#pragma kernel UpdateEdgeNormals +#pragma kernel OrientationFromNormals + +#include "InterlockedUtils.cginc" +#include "MathUtils.cginc" + +StructuredBuffer deformableTriangles; +StructuredBuffer deformableTriangleUVs; + +StructuredBuffer deformableEdges; + +StructuredBuffer renderablePositions; +StructuredBuffer wind; +StructuredBuffer phases; + +RWStructuredBuffer normals; +RWStructuredBuffer tangents; +RWStructuredBuffer renderableOrientations; + +// Variables set from the CPU +uint normalsCount; +uint triangleCount; +uint edgeCount; + +void AccumulateNormal(in int index, in float4 delta) +{ + InterlockedAddFloat(normals, index, 0, delta.x); + InterlockedAddFloat(normals, index, 1, delta.y); + InterlockedAddFloat(normals, index, 2, delta.z); +} + +void AccumulateTangent(in int index, in float4 delta) +{ + InterlockedAddFloat(tangents, index, 0, delta.x); + InterlockedAddFloat(tangents, index, 1, delta.y); + InterlockedAddFloat(tangents, index, 2, delta.z); + InterlockedAddFloat(tangents, index, 3, delta.w); +} + +[numthreads(128, 1, 1)] +void ResetNormals (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + if (i >= normalsCount) return; + + if ((phases[i] & (int)PHASE_FLUID) == 0) + { + normals[i] = asuint(FLOAT4_ZERO); + tangents[i] = asuint(FLOAT4_ZERO); + } +} + +[numthreads(128, 1, 1)] +void UpdateNormals (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + if (i >= triangleCount) return; + + int p1 = deformableTriangles[i*3]; + int p2 = deformableTriangles[i*3 + 1]; + int p3 = deformableTriangles[i*3 + 2]; + + float2 w1 = deformableTriangleUVs[i*3]; + float2 w2 = deformableTriangleUVs[i*3 + 1]; + float2 w3 = deformableTriangleUVs[i*3 + 2]; + + float4 v1 = renderablePositions[p1]; + float4 v2 = renderablePositions[p2]; + float4 v3 = renderablePositions[p3]; + + float3 m1 = (v2 - v1).xyz; + float3 m2 = (v3 - v1).xyz; + + float2 s = w2 - w1; + float2 t = w3 - w1; + + float4 normal = float4(cross(m1, m2), 0); + float4 tangent = FLOAT4_ZERO; + + float area = s.x * t.y - t.x * s.y; + + if (abs(area) > EPSILON) + { + tangent = float4(t.y * m1.x - s.y * m2.x, + t.y * m1.y - s.y * m2.y, + t.y * m1.z - s.y * m2.z, 0) / area; + } + + AccumulateNormal(p1,normal); + AccumulateNormal(p2,normal); + AccumulateNormal(p3,normal); + + AccumulateTangent(p1,tangent); + AccumulateTangent(p2,tangent); + AccumulateTangent(p3,tangent); +} + +[numthreads(128, 1, 1)] +void UpdateEdgeNormals (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + if (i >= edgeCount) return; + + int p1 = deformableEdges[i * 2]; + int p2 = deformableEdges[i * 2 + 1]; + + float4 edge = renderablePositions[p2] - renderablePositions[p1]; + float4 avgWind = (wind[p1] + wind[p2]) * 0.5f; + float denom = dot(edge, edge); + float4 normal = avgWind - (denom < EPSILON ? FLOAT4_ZERO : edge * dot(avgWind, edge) / denom); + + AccumulateNormal(p1,normal); + AccumulateNormal(p2,normal); +} + +[numthreads(128, 1, 1)] +void OrientationFromNormals (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + if (i >= normalsCount) return; + + if ((phases[i] & (int)PHASE_FLUID) == 0) + { + float4 normal = asfloat(normals[i]); + float4 tangent = asfloat(tangents[i]); + + if (dot(normal, normal) > EPSILON && + dot(tangent, tangent) > EPSILON) + { + normals[i] = asuint(normalizesafe(normal)); + tangents[i] = asuint(normalizesafe(tangent)); + + // particle orientation from normal/tangent: + renderableOrientations[i] = q_look_at(asfloat(normals[i]).xyz, asfloat(tangents[i]).xyz); + } + } +} diff --git a/xiaofang/Assets/Obi/Resources/Compute/DeformableTriangles.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/DeformableTriangles.compute.meta new file mode 100644 index 00000000..6175b9da --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/DeformableTriangles.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2444094f2fb2c43cfb9c90b5949f39ec +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/DensityConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/DensityConstraints.compute new file mode 100644 index 00000000..f373013c --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/DensityConstraints.compute @@ -0,0 +1,326 @@ +#pragma kernel UpdateDensities +#pragma kernel Apply +#pragma kernel ApplyPositionDeltas +#pragma kernel ApplyAtmosphere +#pragma kernel AccumulateSmoothPositions +#pragma kernel AccumulateAnisotropy +#pragma kernel AverageAnisotropy + +#include "MathUtils.cginc" +#include "Quaternion.cginc" +#include "AtomicDeltas.cginc" +#include "FluidKernels.cginc" + +StructuredBuffer neighbors; +StructuredBuffer neighborCounts; + +StructuredBuffer sortedToOriginal; + +StructuredBuffer sortedPositions; +StructuredBuffer sortedPrevPositions; +StructuredBuffer sortedFluidMaterials; +StructuredBuffer sortedFluidInterface; +StructuredBuffer sortedPrincipalRadii; +StructuredBuffer sortedUserData; +RWStructuredBuffer sortedFluidData; + +StructuredBuffer prevOrientations; + +StructuredBuffer wind; + +RWStructuredBuffer fluidData; +RWStructuredBuffer positions; +RWStructuredBuffer orientations; +RWStructuredBuffer velocities; +RWStructuredBuffer userData; +RWStructuredBuffer normals; + +RWStructuredBuffer massCenters; +RWStructuredBuffer prevMassCenters; + +RWStructuredBuffer renderablePositions; +RWStructuredBuffer renderableOrientations; +RWStructuredBuffer renderableRadii; + +RWStructuredBuffer anisotropies; +StructuredBuffer dispatchBuffer; + +// Variables set from the CPU +uint maxNeighbors; +float deltaTime; + +[numthreads(128, 1, 1)] +void UpdateDensities (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatchBuffer[3]) return; + + float4 positionA = sortedPositions[i]; + float4 fluidMaterialA = sortedFluidMaterials[i]; + + // self-contribution: + float avgKernel = Poly6(0,fluidMaterialA.x); + float restVolumeA = pow(abs(sortedPrincipalRadii[i].x * 2),3-mode); // in 2D, mode == 1 so amount of dimensions is 2. + float grad = restVolumeA * Spiky(0,fluidMaterialA.x); + + float4 fluidDataA = float4(avgKernel,0,grad,grad*grad); + float4 massCenterA = avgKernel * float4(positionA.xyz, 1) / positionA.w; + float4 prevMassCenterA = avgKernel * float4(sortedPrevPositions[i].xyz, 1) / positionA.w; + float4x4 anisotropyA = avgKernel * (multrnsp4(positionA, sortedPrevPositions[i]) + FLOAT4X4_IDENTITY * 0.2 * sortedPrincipalRadii[i].x * sortedPrincipalRadii[i].x) / positionA.w; + + float4 fluidMaterialB; + float4 positionB; + + // iterate over neighborhood, calculate density and gradient. + uint count = min(maxNeighbors, neighborCounts[i]); + for (uint j = 0; j < count; ++j) + { + int n = neighbors[maxNeighbors * i + j]; + + fluidMaterialB = sortedFluidMaterials[n]; + positionB = sortedPositions[n]; + float dist = length((positionA - positionB).xyz); + + float avgKernel = (Poly6(dist,fluidMaterialA.x) + Poly6(dist,fluidMaterialB.x)) * 0.5f; + + float restVolumeB = pow(abs(sortedPrincipalRadii[n].x * 2),3-mode); + float grad = restVolumeB * Spiky(dist,fluidMaterialA.x); + fluidDataA += float4(restVolumeB / restVolumeA * avgKernel,0,grad,grad*grad); + + // accumulate masses for COMs and moment matrices: + massCenterA += avgKernel * float4(positionB.xyz, 1) / positionB.w; + prevMassCenterA += avgKernel * float4(sortedPrevPositions[n].xyz, 1) / positionB.w; + anisotropyA += avgKernel * (multrnsp4(positionB, sortedPrevPositions[n]) + FLOAT4X4_IDENTITY * 0.2 * sortedPrincipalRadii[n].x * sortedPrincipalRadii[n].x) / positionB.w; + } + + // self particle contribution to density and gradient: + fluidDataA[3] += fluidDataA[2] * fluidDataA[2]; + + // usually, we'd weight density by mass (density contrast formulation) by dividing by invMass. Then, multiply by invMass when + // calculating the state equation (density / restDensity - 1, restDensity = mass / volume, so density * invMass * restVolume - 1 + // We end up with density / invMass * invMass * restVolume - 1, invMass cancels out. + float constraint = max(0, fluidDataA[0] * restVolumeA - 1); + + // calculate lambda: + fluidDataA[1] = -constraint / (positionA.w * fluidDataA[3] + EPSILON); + + // get total neighborhood mass: + float M = massCenterA[3]; + massCenterA /= massCenterA[3]; + prevMassCenterA /= prevMassCenterA[3]; + + // update moment: + anisotropyA -= M * multrnsp4(massCenterA, prevMassCenterA); + + // extract neighborhood orientation delta: + renderableOrientations[i] = ExtractRotation(anisotropyA, QUATERNION_IDENTITY, 2); + + sortedFluidData[i] = fluidDataA; + massCenters[i] = massCenterA; + prevMassCenters[i] = prevMassCenterA; +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatchBuffer[3]) return; + + float restVolumeA = pow(abs(sortedPrincipalRadii[i].x * 2),3-mode); + float4 fluidMaterialA = sortedFluidMaterials[i]; + float4 positionA = sortedPositions[i]; + float4 prevPositionA = sortedPrevPositions[i]; + float4 massCenterA = massCenters[i]; + float lambdaA = sortedFluidData[i][1]; + + float4 fluidMaterialB; + float4 fluidInterfaceB; + float4 massCenterB; + float4 positionB; + + float4 pressureDelta = FLOAT4_ZERO; + float4 viscVortDelta = FLOAT4_ZERO; + + uint count = min(maxNeighbors, neighborCounts[i]); + for (uint j = 0; j < count; ++j) + { + int n = neighbors[maxNeighbors * i + j]; + + fluidMaterialB = sortedFluidMaterials[n]; + massCenterB = massCenters[n]; + positionB = sortedPositions[n]; + + float4 normal = float4((positionA - positionB).xyz,0); + float dist = length(normal); + + float restVolumeB = pow(abs(sortedPrincipalRadii[n].x * 2),3-mode); + + // calculate lambda correction due to polarity (cohesion): + float cAvg = (Cohesion(dist,fluidMaterialA.x * 1.4) + Cohesion(dist,fluidMaterialB.x * 1.4)) * 0.5; + float st = 0.2 * cAvg * (1 - saturate(abs(fluidMaterialA.y - fluidMaterialB.y))) * (fluidMaterialA.y + fluidMaterialB.y) * 0.5; + float scorrA = -st / (positionA.w * sortedFluidData[i][3] + EPSILON); + float scorrB = -st / (positionB.w * sortedFluidData[n][3] + EPSILON); + + float avgGradient = (Spiky(dist,fluidMaterialA.x) + Spiky(dist,fluidMaterialB.x)) * 0.5; + pressureDelta += normal / (dist + EPSILON) * avgGradient * ((lambdaA + scorrA) * restVolumeB + (sortedFluidData[n][1] + scorrB) * restVolumeA); + + // viscosity and vorticity: + float4 viscGoal = float4(massCenterB.xyz + rotate_vector(renderableOrientations[n], (prevPositionA - prevMassCenters[n]).xyz), 0); + float4 vortGoal = float4(massCenterB.xyz + rotate_vector(renderableOrientations[n], (positionA - massCenterB).xyz), 0); + viscVortDelta += (viscGoal - positionA) * fluidMaterialB.z + (vortGoal - positionA) * fluidMaterialB.w * 0.1; + } + + // viscosity and vorticity: + float4 viscGoal = float4(massCenterA.xyz + rotate_vector(renderableOrientations[i], (prevPositionA - prevMassCenters[i]).xyz), 0); + float4 vortGoal = float4(massCenterA.xyz + rotate_vector(renderableOrientations[i], (positionA - massCenterA).xyz), 0); + viscVortDelta += (viscGoal - positionA) * fluidMaterialA.z + (vortGoal - positionA) * fluidMaterialA.w * 0.1; + + AddPositionDelta(sortedToOriginal[i], pressureDelta * positionA.w + viscVortDelta / (neighborCounts[i] + 1)); +} + +[numthreads(128, 1, 1)] +void ApplyPositionDeltas (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatchBuffer[3]) return; + + int p = sortedToOriginal[i]; + ApplyPositionDelta(positions, p, 1); + + orientations[p] = qmul(renderableOrientations[i], prevOrientations[p]); + fluidData[p] = sortedFluidData[i]; +} + +[numthreads(128, 1, 1)] +void ApplyAtmosphere (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatchBuffer[3]) return; + + int originalIndex = sortedToOriginal[i]; + + float4 normal = FLOAT4_ZERO; + float restVolumeA = pow(abs(sortedPrincipalRadii[i].x * 2),3 - mode); + float4 positionA = sortedPositions[i]; + float radiiA = sortedFluidMaterials[i].x; + float4 userDataA = sortedUserData[i]; + + uint count = min(maxNeighbors, neighborCounts[i]); + for (uint j = 0; j < count; ++j) + { + int n = neighbors[maxNeighbors * i + j]; + + float restVolumeB = pow(abs(sortedPrincipalRadii[n].x * 2),3 - mode); + float radiiB = sortedFluidMaterials[n].x; + + float4 dir = positionA - sortedPositions[n]; + float dist = length(dir); + + float avgKernel = (Poly6(dist,radiiA) + Poly6(dist,radiiB)) * 0.5f; + float avgGradient = (Spiky(dist,radiiA) + Spiky(dist,radiiB)) * 0.5; + + // property diffusion: + float diffusionSpeed = (sortedFluidInterface[i].w + sortedFluidInterface[n].w) * avgKernel * deltaTime; + float4 userDelta = (sortedUserData[n] - userDataA) * diffusionSpeed; + userDataA += restVolumeB / restVolumeA * userDelta; + + // calculate color field normal: + float radius = (radiiA + radiiB) * 0.5f; + float4 vgrad = dir / (dist + EPSILON) * avgGradient; + normal += vgrad * radius * restVolumeB; + } + + // particles near the surface should experience drag: + float4 velocityDiff = velocities[originalIndex] - wind[originalIndex]; + velocities[originalIndex] -= sortedFluidInterface[i].x * velocityDiff * max(0, 1 - fluidData[i][0] * restVolumeA) * deltaTime; + + // ambient pressure: + velocities[originalIndex] += sortedFluidInterface[i].y * normal * deltaTime; + + normals[originalIndex] = normal; + userData[originalIndex] = userDataA; +} + +[numthreads(128, 1, 1)] +void AccumulateSmoothPositions (uint3 id : SV_DispatchThreadID) +{ + unsigned int p1 = id.x; + if (p1 >= dispatchBuffer[3]) return; + + anisotropies[p1] = FLOAT4X4_ZERO; + float4 renderablePositionA = renderablePositions[p1]; + float radiiA = sortedFluidMaterials[p1].x; + float4 avgPosition = float4(renderablePositionA.xyz, 1);//FLOAT4_ZERO; + + uint count = min(maxNeighbors, neighborCounts[p1]); + for (uint j = 0; j < count; ++j) + { + int p2 = neighbors[maxNeighbors * p1 + j]; + float4 renderablePositionB = renderablePositions[p2]; + + float dist = length((renderablePositionA - renderablePositionB).xyz); + + float avgKernel = (Poly6(dist,radiiA) + Poly6(dist,sortedFluidMaterials[p2].x)) * 0.5; + avgPosition += float4(renderablePositionB.xyz,1) * avgKernel; + } + + anisotropies[p1]._m03_m13_m23_m33 = avgPosition / avgPosition.w; +} + +[numthreads(128, 1, 1)] +void AccumulateAnisotropy (uint3 id : SV_DispatchThreadID) +{ + unsigned int p1 = id.x; + if (p1 >= dispatchBuffer[3]) return; + + float4x4 anisotropyA = anisotropies[p1]; + float4 renderablePositionA = renderablePositions[p1]; + float radiiA = sortedFluidMaterials[p1].x; + + uint count = min(maxNeighbors, neighborCounts[p1]); + for (uint j = 0; j < count; ++j) + { + int p2 = neighbors[maxNeighbors * p1 + j]; + float4 renderablePositionB = renderablePositions[p2]; + + float dist = length((renderablePositionA - renderablePositionB).xyz); + + float avgKernel = (Poly6(dist,radiiA) + Poly6(dist,sortedFluidMaterials[p2].x)) * 0.5; + + float4 r = (renderablePositionB - anisotropyA._m03_m13_m23_m33) * avgKernel; + anisotropyA += multrnsp4(r, r); + } + + anisotropies[p1] = anisotropyA; +} + +[numthreads(128, 1, 1)] +void AverageAnisotropy (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatchBuffer[3]) return; + + int o = sortedToOriginal[i]; + + if (anisotropies[i]._m00 + anisotropies[i]._m11 + anisotropies[i]._m22 > 0.01f) + { + float3 singularValues; + float3x3 u; + EigenSolve((float3x3)anisotropies[i], singularValues, u); + + float maxVal = singularValues[0]; + float3 s = max(singularValues, maxVal / maxAnisotropy) / maxVal * sortedPrincipalRadii[i].x; + + renderableOrientations[o] = q_look_at(u._m02_m12_m22,u._m01_m11_m21); + renderableRadii[o] = float4(s.xyz,1); + } + else + { + float radius = sortedPrincipalRadii[i].x / maxAnisotropy; + renderableOrientations[o] = QUATERNION_IDENTITY; + renderableRadii[o] = float4(radius,radius,radius,1); + fluidData[o].x = 1 / pow(abs(radius * 2),3-mode); // normal volume of an isolated particle. + } + + renderablePositions[o] = lerp(renderablePositions[o],anisotropies[i]._m03_m13_m23_m33,min((maxAnisotropy - 1)/3.0f,1)); +} diff --git a/xiaofang/Assets/Obi/Resources/Compute/DensityConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/DensityConstraints.compute.meta new file mode 100644 index 00000000..d170b648 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/DensityConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 80856d7c741a940a7bbf0d7d4f472e1d +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/DistanceConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/DistanceConstraints.compute new file mode 100644 index 00000000..bf507f61 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/DistanceConstraints.compute @@ -0,0 +1,69 @@ +#pragma kernel Project +#pragma kernel Apply + +#include "MathUtils.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer particleIndices; +StructuredBuffer restLengths; +StructuredBuffer stiffnesses; +RWStructuredBuffer lambdas; + +RWStructuredBuffer positions; +StructuredBuffer invMasses; + +// Variables set from the CPU +uint activeConstraintCount; +float deltaTime; +float sorFactor; + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p1 = particleIndices[i * 2]; + int p2 = particleIndices[i * 2 + 1]; + + float w1 = invMasses[p1]; + float w2 = invMasses[p2]; + + // calculate time adjusted compliance + float compliance = stiffnesses[i].x / (deltaTime * deltaTime); + + // calculate position and lambda deltas: + float4 dist = positions[p1] - positions[p2]; + float d = length(dist); + + // calculate constraint value: + float constraint = d - restLengths[i]; + constraint -= max(min(constraint, 0), -stiffnesses[i].y); + + // calculate lambda and position deltas: + float dlambda = (-constraint - compliance * lambdas[i]) / (w1 + w2 + compliance + EPSILON); + float4 delta = dlambda * dist / (d + EPSILON); + + lambdas[i] += dlambda; + + float4 delta1 = delta * w1; + float4 delta2 = -delta * w2; + + AddPositionDelta(p1, delta1); + AddPositionDelta(p2, delta2); +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p1 = particleIndices[i * 2]; + int p2 = particleIndices[i * 2 + 1]; + + ApplyPositionDelta(positions, p1, sorFactor); + ApplyPositionDelta(positions, p2, sorFactor); +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/DistanceConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/DistanceConstraints.compute.meta new file mode 100644 index 00000000..8d55c47c --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/DistanceConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4883886c2cc7740e18f906dcf663c1f1 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/DistanceFieldShape.compute b/xiaofang/Assets/Obi/Resources/Compute/DistanceFieldShape.compute new file mode 100644 index 00000000..c28cc0ca --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/DistanceFieldShape.compute @@ -0,0 +1,212 @@ +#include "ColliderDefinitions.cginc" +#include "ContactHandling.cginc" +#include "Transform.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "Optimization.cginc" + +#pragma kernel GenerateContacts + +struct DistanceFieldHeader +{ + int firstNode; + int nodeCount; +}; + +struct DFNode +{ + float4 distancesA; + float4 distancesB; + float4 center; + int firstChild; + + // add 12 bytes of padding to ensure correct memory alignment: + int pad0; + int pad1; + int pad2; + + float4 GetNormalizedPos(float4 position) + { + float4 corner = center - float4(center[3],center[3],center[3],center[3]); + return (position - corner) / (center[3] * 2); + } + + float4 SampleWithGradient(float4 position) + { + float4 nPos = GetNormalizedPos(position); + + // trilinear interpolation of distance: + float4 x = distancesA + (distancesB - distancesA) * nPos[0]; + float2 y = x.xy + (x.zw - x.xy) * nPos[1]; + float dist = y[0] + (y[1] - y[0]) * nPos[2]; + + // gradient estimation: + // x == 0 + float2 a = distancesA.xy + (distancesA.zw - distancesA.xy) * nPos[1]; + float x0 = a[0] + (a[1] - a[0]) * nPos[2]; + + // x == 1 + a = distancesB.xy + (distancesB.zw - distancesB.xy) * nPos[1]; + float x1 = a[0] + (a[1] - a[0]) * nPos[2]; + + // y == 0 + float y0 = x[0] + (x[1] - x[0]) * nPos[2]; + + // y == 1 + float y1 = x[2] + (x[3] - x[2]) * nPos[2]; + + return float4(x1 - x0, y1 - y0, y[1] - y[0], dist); + + } + + int GetOctant(float4 position) + { + int index = 0; + if (position[0] > center[0]) index |= 4; + if (position[1] > center[1]) index |= 2; + if (position[2] > center[2]) index |= 1; + return index; + } +}; + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer principalRadii; +StructuredBuffer velocities; + +StructuredBuffer simplices; + +StructuredBuffer transforms; +StructuredBuffer shapes; + +// distance field data: +StructuredBuffer distanceFieldHeaders; +StructuredBuffer dfNodes; + +StructuredBuffer contactPairs; +StructuredBuffer contactOffsetsPerType; + +RWStructuredBuffer contacts; +RWStructuredBuffer dispatchBuffer; + +StructuredBuffer worldToSolver; + +uint maxContacts; +float deltaTime; + +struct DistanceField : IDistanceFunction +{ + shape s; + transform colliderToSolver; + + StructuredBuffer distanceFieldHeaders; + StructuredBuffer dfNodes; + + float4 DFTraverse(float4 particlePosition, + in DistanceFieldHeader header) + { + int stack[12]; + int stackTop = 0; + + stack[stackTop++] = 0; + + while (stackTop > 0) + { + // pop node index from the stack: + int nodeIndex = stack[--stackTop]; + DFNode node = dfNodes[header.firstNode + nodeIndex]; + + // if the child node exists, recurse down the df octree: + if (node.firstChild >= 0) + stack[stackTop++] = node.firstChild + node.GetOctant(particlePosition); + else + return node.SampleWithGradient(particlePosition); + } + return FLOAT4_ZERO; + } + + void Evaluate(in float4 pos, in float4 radii, in quaternion orientation, inout SurfacePoint projectedPoint) + { + float4 pnt = colliderToSolver.InverseTransformPoint(pos); + + if (s.is2D()) + pnt[2] = 0; + + float4 sample = DFTraverse(pnt, distanceFieldHeaders[s.dataIndex]); + float4 normal = float4(normalize(sample.xyz), 0); + + projectedPoint.pos = colliderToSolver.TransformPoint(pnt - normal * (sample[3] - s.contactOffset)); + projectedPoint.normal = colliderToSolver.TransformDirection(normal); + projectedPoint.bary = float4(1,0,0,0); + } +}; + +[numthreads(128, 1, 1)] +void GenerateContacts (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + // entry #11 in the dispatch buffer is the amount of pairs for the first shape type. + if (i >= dispatchBuffer[11 + 4 * SDF_SHAPE]) return; + + int firstPair = contactOffsetsPerType[SDF_SHAPE]; + int simplexIndex = contactPairs[firstPair + i].x; + int colliderIndex = contactPairs[firstPair + i].y; + shape s = shapes[colliderIndex]; + + if (s.dataIndex < 0) return; + + DistanceFieldHeader header = distanceFieldHeaders[s.dataIndex]; + + DistanceField dfShape; + dfShape.colliderToSolver = worldToSolver[0].Multiply(transforms[colliderIndex]); + dfShape.s = s; + dfShape.distanceFieldHeaders = distanceFieldHeaders; + dfShape.dfNodes = dfNodes; + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(simplexIndex, simplexSize); + + float4 simplexBary = BarycenterForSimplexOfSize(simplexSize); + float4 simplexPoint; + + SurfacePoint colliderPoint = Optimize(dfShape, positions, orientations, principalRadii, + simplices, simplexStart, simplexSize, simplexBary, simplexPoint, surfaceCollisionIterations, surfaceCollisionTolerance); + + float4 velocity = FLOAT4_ZERO; + float simplexRadius = 0; + for (int j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + simplexRadius += principalRadii[particleIndex].x * simplexBary[j]; + velocity += velocities[particleIndex] * simplexBary[j]; + } + + /*float4 rbVelocity = float4.zero; + if (rigidbodyIndex >= 0) + rbVelocity = BurstMath.GetRigidbodyVelocityAtPoint(rigidbodyIndex, colliderPoint.point, rigidbodies, solverToWorld);*/ + + float dAB = dot(simplexPoint - colliderPoint.pos, colliderPoint.normal); + float vel = dot(velocity /*- rbVelocity*/, colliderPoint.normal); + + //if (vel * deltaTime + dAB <= simplexRadius + s.contactOffset + collisionMargin) + { + uint count = contacts.IncrementCounter(); + if (count < maxContacts) + { + contact c = (contact)0; + + c.pointB = colliderPoint.pos; + c.normal = colliderPoint.normal * dfShape.s.isInverted(); + c.pointA = simplexBary; + c.bodyA = simplexIndex; + c.bodyB = colliderIndex; + + contacts[count] = c; + + InterlockedMax(dispatchBuffer[0],(count + 1) / 128 + 1); + InterlockedMax(dispatchBuffer[3], count + 1); + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/DistanceFieldShape.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/DistanceFieldShape.compute.meta new file mode 100644 index 00000000..0f2a1664 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/DistanceFieldShape.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2391a8c719b4c4193a8be38dcf83e8fd +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/EdgeMeshShape.compute b/xiaofang/Assets/Obi/Resources/Compute/EdgeMeshShape.compute new file mode 100644 index 00000000..3a9a6fb7 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/EdgeMeshShape.compute @@ -0,0 +1,208 @@ +#include "ColliderDefinitions.cginc" +#include "ContactHandling.cginc" +#include "Transform.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "Optimization.cginc" + +#pragma kernel GenerateContacts + +struct BIHNode +{ + int firstChild; /**< index of the first child node. The second one is right after the first.*/ + int start; /**< index of the first element in this node.*/ + int count; /**< amount of elements in this node.*/ + + int axis; /**< axis of the split plane (0,1,2 = x,y,z)*/ + float min_; /**< minimum split plane*/ + float max_; /**< maximum split plane*/ +}; + +struct EdgeMeshHeader +{ + int firstNode; + int nodeCount; + int firstEdge; + int edgeCount; + int firstVertex; + int vertexCount; +}; + +struct Edge +{ + int i1; + int i2; + aabb b; +}; + + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer principalRadii; +StructuredBuffer velocities; + +StructuredBuffer simplices; +StructuredBuffer simplexBounds; // bounding box of each simplex. + +StructuredBuffer transforms; +StructuredBuffer shapes; + +// triangle mesh data: +StructuredBuffer edgeMeshHeaders; +StructuredBuffer edgeBihNodes; +StructuredBuffer edges; +StructuredBuffer edgeVertices; + +StructuredBuffer contactPairs; +StructuredBuffer contactOffsetsPerType; + +RWStructuredBuffer contacts; +RWStructuredBuffer dispatchBuffer; + +StructuredBuffer worldToSolver; + +uint maxContacts; +float deltaTime; + +struct EdgeMesh : IDistanceFunction +{ + shape s; + transform colliderToSolver; + int dataOffset; + + EdgeMeshHeader header; + + void Evaluate(in float4 pos, in float4 radii, in quaternion orientation, inout SurfacePoint projectedPoint) + { + float4 pnt = colliderToSolver.InverseTransformPointUnscaled(pos); + + if (s.is2D()) + pnt[2] = 0; + + Edge t = edges[header.firstEdge + dataOffset]; + float4 v1 = (float4(edgeVertices[header.firstVertex + t.i1],0,0) + s.center) * colliderToSolver.scale; + float4 v2 = (float4(edgeVertices[header.firstVertex + t.i2],0,0) + s.center) * colliderToSolver.scale; + + float mu = 0; + float4 nearestPoint = NearestPointOnEdge(v1, v2, pnt, mu); + float4 normal = normalizesafe(pnt - nearestPoint); + + projectedPoint.pos = colliderToSolver.TransformPointUnscaled(nearestPoint + normal * s.contactOffset); + projectedPoint.normal = colliderToSolver.TransformDirection(normal); + projectedPoint.bary = float4(1,0,0,0); + } + +}; + +[numthreads(128, 1, 1)] +void GenerateContacts (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + // entry #11 in the dispatch buffer is the amount of pairs for the first shape type. + if (i >= dispatchBuffer[11 + 4 * EDGE_MESH_SHAPE]) return; + + int firstPair = contactOffsetsPerType[EDGE_MESH_SHAPE]; + int simplexIndex = contactPairs[firstPair + i].x; + int colliderIndex = contactPairs[firstPair + i].y; + shape s = shapes[colliderIndex]; + + if (s.dataIndex < 0) return; + + EdgeMeshHeader header = edgeMeshHeaders[s.dataIndex]; + + EdgeMesh meshShape; + meshShape.colliderToSolver = worldToSolver[0].Multiply(transforms[colliderIndex]); + meshShape.s = s; + meshShape.header = header; + + // invert a full matrix here to accurately represent collider bounds scale. + float4x4 solverToCollider = Inverse(TRS(meshShape.colliderToSolver.translation.xyz, meshShape.colliderToSolver.rotation, meshShape.colliderToSolver.scale.xyz)); + aabb simplexBound = simplexBounds[simplexIndex].Transformed(solverToCollider); + + float4 marginCS = float4((s.contactOffset + collisionMargin) / meshShape.colliderToSolver.scale.xyz, 0); + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(simplexIndex, simplexSize); + + int stack[12]; + int stackTop = 0; + + stack[stackTop++] = 0; + + while (stackTop > 0) + { + // pop node index from the stack: + int nodeIndex = stack[--stackTop]; + + BIHNode node = edgeBihNodes[header.firstNode + nodeIndex]; + + // leaf node: + if (node.firstChild < 0) + { + // check for contact against all triangles: + for (int dataOffset = node.start; dataOffset < node.start + node.count; ++dataOffset) + { + Edge t = edges[header.firstEdge + dataOffset]; + float4 v1 = float4(edgeVertices[header.firstVertex + t.i1],0,0) + s.center; + float4 v2 = float4(edgeVertices[header.firstVertex + t.i2],0,0) + s.center; + aabb edgeBounds; + edgeBounds.FromEdge(v1, v2, marginCS); + + if (edgeBounds.IntersectsAabb(simplexBound, s.is2D())) + { + float4 simplexBary = BarycenterForSimplexOfSize(simplexSize); + float4 simplexPoint; + + meshShape.dataOffset = dataOffset; + + SurfacePoint surfacePoint = Optimize(meshShape, positions, orientations, principalRadii, + simplices, simplexStart, simplexSize, simplexBary, simplexPoint, surfaceCollisionIterations, surfaceCollisionTolerance); + + float4 velocity = FLOAT4_ZERO; + float simplexRadius = 0; + for (int j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + simplexRadius += principalRadii[particleIndex].x * simplexBary[j]; + velocity += velocities[particleIndex] * simplexBary[j]; + } + + float dAB = dot(simplexPoint - surfacePoint.pos, surfacePoint.normal); + float vel = dot(velocity, surfacePoint.normal); + + if (vel * deltaTime + dAB <= simplexRadius + s.contactOffset + collisionMargin) + { + uint count = contacts.IncrementCounter(); + if (count < maxContacts) + { + contact c = (contact)0; + + c.pointB = surfacePoint.pos; + c.normal = surfacePoint.normal * meshShape.s.isInverted(); + c.pointA = simplexBary; + c.bodyA = simplexIndex; + c.bodyB = colliderIndex; + + contacts[count] = c; + + InterlockedMax(dispatchBuffer[0],(count + 1) / 128 + 1); + InterlockedMax(dispatchBuffer[3], count + 1); + } + } + } + } + } + else // check min and/or max children: + { + // visit min node: + if (simplexBound.min_[node.axis] <= node.min_) + stack[stackTop++] = node.firstChild; + + // visit max node: + if (simplexBound.max_[node.axis] >= node.max_) + stack[stackTop++] = node.firstChild + 1; + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/EdgeMeshShape.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/EdgeMeshShape.compute.meta new file mode 100644 index 00000000..3f9c16b5 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/EdgeMeshShape.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 229868ae412914f11bbfa8c3ab9474c8 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/FluidChunkDefs.cginc b/xiaofang/Assets/Obi/Resources/Compute/FluidChunkDefs.cginc new file mode 100644 index 00000000..24d1528e --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/FluidChunkDefs.cginc @@ -0,0 +1,33 @@ +#ifndef FLUIDCHUNKDEFS_INCLUDE +#define FLUIDCHUNKDEFS_INCLUDE + +#define chunkResolution 4u // amount of voxels in width/height/depth + +struct keyvalue +{ + uint key; + uint handle; +}; + +uint3 chunkGridResolution; // height/width/depth of chunk grid +float3 chunkGridOrigin; +float voxelSize; + +uint maxChunks; + +uint VoxelID(uint3 coords) +{ + return coords.x + coords.y * chunkGridResolution.x + coords.z * chunkGridResolution.x * chunkGridResolution.y; +} + +uint hash(uint k) +{ + k ^= k >> 16; + k *= 0x85ebca6b; + k ^= k >> 13; + k *= 0xc2b2ae35; + k ^= k >> 16; + return k % maxChunks; +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/FluidChunkDefs.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/FluidChunkDefs.cginc.meta new file mode 100644 index 00000000..2f088fd3 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/FluidChunkDefs.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: bc0e240276e8a42a2ac5a11368e4f7fa +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/FluidFoam.compute b/xiaofang/Assets/Obi/Resources/Compute/FluidFoam.compute new file mode 100644 index 00000000..0eedd8e0 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/FluidFoam.compute @@ -0,0 +1,432 @@ +#pragma kernel SortFluidData + +#pragma kernel Emit +#pragma kernel CopyAliveCount +#pragma kernel Update +#pragma kernel Copy + +#pragma kernel Sort +#pragma kernel ClearMesh +#pragma kernel BuildMesh + +#include "InterlockedUtils.cginc" +#include "MathUtils.cginc" +#include "GridUtils.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "FluidKernels.cginc" + +StructuredBuffer sortedToOriginal; +RWStructuredBuffer sortedPositions; +RWStructuredBuffer sortedVelocities; +RWStructuredBuffer sortedOrientations; +RWStructuredBuffer sortedRadii; + +StructuredBuffer cellOffsets; // start of each cell in the sorted item array. +StructuredBuffer cellCounts; // number of item in each cell. +StructuredBuffer gridHashToSortedIndex; +StructuredBuffer solverBounds; + +StructuredBuffer fluidSimplices; +StructuredBuffer activeParticles; +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer velocities; +RWStructuredBuffer angularVelocities; +StructuredBuffer principalRadii; +StructuredBuffer fluidMaterial; +StructuredBuffer fluidData; + +StructuredBuffer inputPositions; // w component is distance to camera +StructuredBuffer inputVelocities; // w component is buoyancy +StructuredBuffer inputColors; // rgba diffuse color +StructuredBuffer inputAttributes; // currentlifetime, maxlifetime, size, drag + +RWStructuredBuffer outputPositions; +RWStructuredBuffer outputVelocities; +RWStructuredBuffer outputColors; +RWStructuredBuffer outputAttributes; + +RWStructuredBuffer dispatch; +RWByteAddressBuffer vertices; +RWByteAddressBuffer indices; + +// Variables set from the CPU +uint activeParticleCount; +uint maxFoamParticles; + +float2 vorticityRange; +float2 velocityRange; +float foamGenerationRate; +float potentialIncrease; +float potentialDiffusion; + +float advectionRadius; +float lifetime; +float lifetimeRandom; +float particleSize; +float buoyancy; +float drag; +float airDrag; +float sizeRandom; +float isosurface; +float airAging; +float3 agingOverPopulation; +float4 foamColor; +float4 sortAxis; + +const uint groupWidth; +const uint groupHeight; +const uint stepIndex; + +float deltaTime; + +static const int4 quadrantOffsets[] = +{ + int4(0, 0, 0, 1), + int4(1, 0, 0, 1), + int4(0, 1, 0, 1), + int4(1, 1, 0, 1), + int4(0, 0, 1, 1), + int4(1, 0, 1, 1), + int4(0, 1, 1, 1), + int4(1, 1, 1, 1) +}; + +//https://www.shadertoy.com/view/4djSRW +float3 hash33(float3 p3) +{ + p3 = frac(p3 * float3(.1031, .1030, .0973)); + p3 += dot(p3, p3.yxz+33.33); + return frac((p3.xxy + p3.yxx)*p3.zyx); +} + +float hash13(float3 p3) +{ + p3 = frac(p3 * .1031); + p3 += dot(p3, p3.zyx + 31.32); + return frac((p3.x + p3.y) * p3.z); +} + +void RandomInCylinder(float seed, float4 pos1, float4 pos2, float radius, out float4 position, out float3 velocity) +{ + float3 rand = hash33(lerp(pos1.xyz, pos2.xyz, seed)); + + float3 v = pos2.xyz - pos1.xyz; + float d = length(v); + float3 b1 = d > EPSILON ? v / d : v; + float3 b2 = normalizesafe(cross(b1, float3(1,0,0))); + float3 b3 = cross(b2, b1); + + float theta = rand.y * 2 * PI; + float2 disc = radius * sqrt(rand.x) * float2(cos(theta),sin(theta)); + + velocity = b2 * disc.x + b3 * disc.y; + position = float4(pos1.xyz + b1 * d * rand.z + velocity,0); +} + +[numthreads(128, 1, 1)] +void SortFluidData (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatch[3]) return; + + int original = sortedToOriginal[i]; + sortedPositions[i] = float4(positions[original].xyz, 1 / fluidData[original].x); + sortedVelocities[i] = velocities[original]; + sortedOrientations[i] = orientations[original]; + sortedRadii[i] = fluidMaterial[original].x * (principalRadii[original] / principalRadii[original].x); +} + +[numthreads(128, 1, 1)] +void Emit (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + if (i >= activeParticleCount) return; + + int p = activeParticles[i]; + + float4 angVel = angularVelocities[p]; + float2 potential = UnpackFloatRG(angVel.w); + + // calculate fluid potential for foam generation: + float vorticityPotential = Remap01(length(angularVelocities[p]), vorticityRange.x, vorticityRange.y); + float velocityPotential = Remap01(length(velocities[p]), velocityRange.x, velocityRange.y); + float potentialDelta = velocityPotential * vorticityPotential * deltaTime * potentialIncrease; + + // update foam potential: + potential.y = saturate(potential.y * potentialDiffusion + potentialDelta); + + // calculate amount of emitted particles + potential.x += foamGenerationRate * potential.y * deltaTime; + int emitCount = (int)potential.x; + potential.x -= emitCount; + + for (int j = 0; j < emitCount; ++j) + { + // atomically increment alive particle counter: + uint count; + InterlockedAdd(dispatch[3], 1, count); + + if (count < maxFoamParticles) + { + // initialize foam particle in a random position inside the cylinder spawned by fluid particle: + float3 radialVelocity; + RandomInCylinder(j, positions[p], positions[p] + velocities[p] * deltaTime, principalRadii[p].x, outputPositions[count], radialVelocity); + + // calculate initial life/size/color: + float initialLife = potential.y * (lifetime - hash13(positions[p].xyz) * lifetime * lifetimeRandom); + float initialSize = particleSize - hash13(positions[p].xyz + float3(0.51,0.23,0.1)) * particleSize * sizeRandom; + + outputVelocities[count] = velocities[p] + float4(radialVelocity, buoyancy); + outputColors[count] = foamColor; + outputAttributes[count] = float4(1, 1/initialLife,initialSize,PackFloatRGBA(float4(airAging / 50.0, airDrag, drag, isosurface))); + } + } + + angVel.w = PackFloatRG(potential); + angularVelocities[p] = angVel; +} + +[numthreads(1, 1, 1)] +void CopyAliveCount (uint3 id : SV_DispatchThreadID) +{ + dispatch[0] = dispatch[3] / 128 + 1; + dispatch[8] = dispatch[3]; + dispatch[4] = dispatch[7] = 0; +} + +[numthreads(128, 1, 1)] +void Update (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + if (i >= dispatch[8]) return; + + uint count; + InterlockedAdd(dispatch[3], -1, count); + count--; + + if (count < maxFoamParticles && inputAttributes[count].x > 0) + { + uint aliveCount; + InterlockedAdd(dispatch[7], 1, aliveCount); + InterlockedMax(dispatch[4],(aliveCount + 1) / 128 + 1); + + float4 attributes = inputAttributes[count]; + float4 packedData = UnpackFloatRGBA(attributes.w); + + int offsetCount = (mode == 1) ? 4 : 8; + float4 advectedVelocity = FLOAT4_ZERO; + float kernelSum = -packedData.w; + int neighbourCount = 0; + + float4 diffusePos = inputPositions[count]; + + for (uint m = 1; m <= levelPopulation[0]; ++m) + { + uint l = levelPopulation[m]; + float radius = CellSizeOfLevel(l); + float interactionDist = radius * 0.5; + + float4 cellCoords = floor((diffusePos - solverBounds[0].min_) / radius); + + cellCoords[3] = 0; + if (mode == 1) + cellCoords[2] = 0; + + float4 posInCell = diffusePos - (solverBounds[0].min_ + cellCoords * radius + float4(interactionDist,interactionDist,interactionDist,interactionDist)); + int4 quadrant = (int4)sign(posInCell); + quadrant[3] = l; + + for (int j = 0; j < offsetCount; ++j) + { + int4 neighborCoord = (int4)cellCoords + quadrantOffsets[j] * quadrant; + int cellIndex = gridHashToSortedIndex[GridHash(neighborCoord)]; + uint n = cellOffsets[cellIndex]; + uint end = n + cellCounts[cellIndex]; + + for (;n < end; ++n) + { + uint p = fluidSimplices[n]; + + int4 particleCoord = int4(floor((positions[p].xyz - solverBounds[0].min_.xyz)/ radius).xyz,l); + if (any (particleCoord - neighborCoord)) + continue; + + float4 normal = diffusePos - positions[p]; + normal[3] = 0; + if (mode == 1) + normal[2] = 0; + + float d = length(normal); + if (d <= interactionDist) + { + float3 radii = principalRadii[p].xyz; + + normal.xyz = rotate_vector(q_conj(orientations[p]), normal.xyz) / radii; + d = length(normal.xyz) * radii.x; + + // velocities.w is volume (1/normalized density): + float w = positions[p].w * Poly6(d, radii.x); + + kernelSum += w; + advectedVelocity += velocities[p] * w; + neighbourCount++; + } + } + } + } + + float4 forces = FLOAT4_ZERO; + float velocityScale = 1; + float agingScale = 1 + Remap01(dispatch[8] / (float)maxFoamParticles,agingOverPopulation.x,agingOverPopulation.y) * (agingOverPopulation.z - 1); + + // foam/bubble particle: + if (kernelSum > EPSILON && neighbourCount > 3) + { + // advection: + forces = packedData.z / deltaTime * (advectedVelocity / (kernelSum + packedData.w) - inputVelocities[count]); + + // buoyancy: + forces -= float4(gravity,0) * inputVelocities[count].w * saturate(kernelSum); + + } + else // spray: + { + // gravity: + forces += float4(gravity,0); + + // atmospheric drag/aging: + velocityScale = packedData.y; + agingScale *= packedData.x * 50; + } + + // don't change 4th component, as its used to store buoyancy control parameter. + forces[3] = 0; + + // update particle data: + attributes.x -= attributes.y * deltaTime * agingScale; + outputAttributes[aliveCount] = attributes; + outputColors[aliveCount] = inputColors[count]; + + // integrate: + outputVelocities[aliveCount] = (inputVelocities[count] + forces * deltaTime) * velocityScale; + outputPositions[aliveCount] = float4((inputPositions[count] + outputVelocities[aliveCount] * deltaTime).xyz, neighbourCount); + } +} + +[numthreads(128, 1, 1)] +void Copy (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + if (i == 0) + { + dispatch[0] = dispatch[4]; + dispatch[3] = dispatch[7]; + } + + if (i >= dispatch[7]) return; + + outputPositions[i] = inputPositions[i]; + outputVelocities[i] = inputVelocities[i]; + outputColors[i] = inputColors[i]; + outputAttributes[i] = inputAttributes[i]; +} + +[numthreads(128,1,1)] +void Sort(uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + uint hIndex = i & (groupWidth - 1); + uint indexLeft = hIndex + (groupHeight + 1) * (i / groupWidth); + uint rightStepSize = stepIndex == 0 ? groupHeight - 2 * hIndex : (groupHeight + 1) / 2; + uint indexRight = indexLeft + rightStepSize; + + // Exit if out of bounds + if (indexRight >= dispatch[3]) return; + + float4 posLeft = inputPositions[indexLeft]; + float4 posRight = inputPositions[indexRight]; + float4 velLeft = inputVelocities[indexLeft]; + float4 velRight = inputVelocities[indexRight]; + float4 colorLeft = inputColors[indexLeft]; + float4 colorRight = inputColors[indexRight]; + float4 attrLeft = inputAttributes[indexLeft]; + float4 attrRight = inputAttributes[indexRight]; + + // calculate distance to camera: + float distLeft = dot(posLeft.xyz, sortAxis.xyz); + float distRight = dot(posRight.xyz, sortAxis.xyz); + + // Swap entries if order is incorrect + if (distLeft < distRight) + { + outputPositions[indexLeft] = posRight; + outputPositions[indexRight] = posLeft; + outputVelocities[indexLeft] = velRight; + outputVelocities[indexRight] = velLeft; + outputColors[indexLeft] = colorRight; + outputColors[indexRight] = colorLeft; + outputAttributes[indexLeft] = attrRight; + outputAttributes[indexRight] = attrLeft; + } +} + +[numthreads(128, 1, 1)] +void ClearMesh (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= maxFoamParticles) return; + + indices.Store((i*6)<<2, 0); + indices.Store((i*6+1)<<2, 0); + indices.Store((i*6+2)<<2, 0); + + indices.Store((i*6+3)<<2, 0); + indices.Store((i*6+4)<<2, 0); + indices.Store((i*6+5)<<2, 0); +} + +[numthreads(128, 1, 1)] +void BuildMesh (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatch[3]) return; + + // <<2 = multiply by 4 to get byte address, since a float/int is 4 bytes in size. + + // particle data is the same for all 4 vertices: + for (uint v = i*4; v < i*4 + 4; ++v) + { + int base = v*19; + + // pos + vertices.Store4(base<<2, asuint(float4(inputPositions[i].xyz, 1))); + + // color: + vertices.Store4((base+7)<<2, asuint( inputColors[i] )); + + // velocity and attributes + vertices.Store4((base+11)<<2, asuint( inputVelocities[i] )); + vertices.Store4((base+15)<<2, asuint( inputAttributes[i] )); + } + + //different offset for each vertex: + int base = i*4; + vertices.Store3((base*19 + 4)<<2, asuint(float3(1,1,0))); + vertices.Store3(((base+1)*19 + 4)<<2, asuint(float3(-1,1,0))); + vertices.Store3(((base+2)*19 + 4)<<2, asuint(float3(-1,-1,0))); + vertices.Store3(((base+3)*19 + 4)<<2, asuint(float3(1,-1,0))); + + // indices: + indices.Store((i*6)<<2, asuint(i*4+2)); + indices.Store((i*6+1)<<2, asuint(i*4+1)); + indices.Store((i*6+2)<<2, asuint(i*4)); + + indices.Store((i*6+3)<<2, asuint(i*4+3)); + indices.Store((i*6+4)<<2, asuint(i*4+2)); + indices.Store((i*6+5)<<2, asuint(i*4)); +} diff --git a/xiaofang/Assets/Obi/Resources/Compute/FluidFoam.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/FluidFoam.compute.meta new file mode 100644 index 00000000..2fcb5eaf --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/FluidFoam.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a8c6735ba651f4c808f068c3b99bca04 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/FluidFoamDensity.compute b/xiaofang/Assets/Obi/Resources/Compute/FluidFoamDensity.compute new file mode 100644 index 00000000..7a2a0a65 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/FluidFoamDensity.compute @@ -0,0 +1,172 @@ +#pragma kernel Clear +#pragma kernel InsertInGrid +#pragma kernel SortByGrid +#pragma kernel ComputeDensity +#pragma kernel ApplyDensity + +#include "InterlockedUtils.cginc" +#include "MathUtils.cginc" +#include "GridUtils.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "FluidKernels.cginc" + +RWStructuredBuffer sortedToOriginal; + +RWStructuredBuffer offsetInCell; +RWStructuredBuffer cellStart; // start of each cell in the sorted item array. +RWStructuredBuffer cellCounts; // number of item in each cell. +StructuredBuffer solverBounds; + +RWStructuredBuffer inputPositions; +RWStructuredBuffer sortedPositions; +RWStructuredBuffer fluidData; + +StructuredBuffer dispatch; + +// each emitter has its own global radius, not possible to have foam emitters interact with each other. +float particleRadius; +float smoothingRadius; +float surfaceTension; +float pressure; +float invMass; + +float deltaTime; + +[numthreads(128, 1, 1)] +void Clear (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= maxCells) return; + + // clear all cell counts to zero, and cell offsets to invalid. + cellStart[i] = INVALID; + cellCounts[i] = 0; +} + +[numthreads(128, 1, 1)] +void InsertInGrid (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatch[3]) return; + + uint cellIndex = GridHash(floor(inputPositions[i] / smoothingRadius).xyz); + InterlockedAdd(cellCounts[cellIndex],1,offsetInCell[i]); +} + +[numthreads(128, 1, 1)] +void SortByGrid (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatch[3]) return; + + uint cellIndex = GridHash(floor(inputPositions[i] / smoothingRadius).xyz); + + uint sortedIndex = cellStart[cellIndex] + offsetInCell[i]; + sortedPositions[sortedIndex] = inputPositions[i]; + sortedToOriginal[sortedIndex] = i; +} + +[numthreads(128, 1, 1)] +void ComputeDensity (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatch[3]) return; + + float4 positionA = inputPositions[i]; + + int3 cellCoords = floor(inputPositions[i] / smoothingRadius).xyz; + + // self-contribution: + float avgKernel = Poly6(0,smoothingRadius); + float restVolume = pow(abs(particleRadius * 2),3-mode); + float grad = restVolume * Spiky(0,smoothingRadius); + + float4 fluidDataA = float4(avgKernel,0,grad,grad*grad); + + float4 positionB; + + // iterate over neighborhood, calculate density and gradient. + for (int k = 0; k < 27; ++k) + { + uint cellIndex = GridHash(cellCoords + cellNeighborhood[k].xyz); + uint start = cellStart[cellIndex]; + + for (uint j = 0; j < cellCounts[cellIndex]; ++j) + { + positionB = sortedPositions[start + j]; + float3 r = (positionA - positionB).xyz; + + if (mode == 1) + r[2] = 0; + + float dist = length(r); + + if (dist > smoothingRadius) continue; + + float grad = restVolume * Spiky(dist,smoothingRadius); + fluidDataA += float4(Poly6(dist,smoothingRadius),0,grad,grad*grad); + } + } + + // self particle contribution to density and gradient: + fluidDataA[3] += fluidDataA[2] * fluidDataA[2]; + + // usually, we'd weight density by mass (density contrast formulation) by dividing by invMass. Then, multiply by invMass when + // calculating the state equation (density / restDensity - 1, restDensity = mass / volume, so density * invMass * restVolume - 1 + // We end up with density / invMass * invMass * restVolume - 1, invMass cancels out. + float constraint = max(-0.5f * surfaceTension, fluidDataA[0] * restVolume - 1); + + // calculate lambda: + fluidDataA[1] = -constraint / (invMass * fluidDataA[3] + EPSILON); + + fluidData[i] = fluidDataA; +} + +[numthreads(128, 1, 1)] +void ApplyDensity (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatch[3]) return; + + int3 cellCoords = floor(inputPositions[i] / smoothingRadius).xyz; + + float restVolume = pow(abs(particleRadius * 2),3-mode); + float4 positionA = inputPositions[i]; + float4 fluidDataA = fluidData[i]; + + float4 fluidDataB; + float4 positionB; + + float4 pressureDelta = FLOAT4_ZERO; + + for (int k = 0; k < 27; ++k) + { + uint cellIndex = GridHash(cellCoords + cellNeighborhood[k].xyz); + uint start = cellStart[cellIndex]; + + for (uint j = 0; j < cellCounts[cellIndex]; ++j) + { + positionB = sortedPositions[start + j]; + fluidDataB = fluidData[sortedToOriginal[start + j]]; + + float4 r = float4((positionA - positionB).xyz,0); + + if (mode == 1) + r[2] = 0; + + float dist = length(r); + + if (dist > smoothingRadius) continue; + + float wAvg = (0.001f + 0.2f * surfaceTension) * Poly6(dist,smoothingRadius) / Poly6(0,smoothingRadius); + float scorrA = - wAvg / (invMass * fluidDataA[3] + EPSILON); + float scorrB = - wAvg / (invMass * fluidDataB[3] + EPSILON); + pressureDelta += r / (dist + EPSILON) * Spiky(dist,smoothingRadius) * ((fluidDataA[1] + scorrA) + (fluidDataB[1] + scorrB)) * restVolume; + } + } + + // write to output positions. + inputPositions[i] = positionA + pressure * pressureDelta * invMass; +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/FluidFoamDensity.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/FluidFoamDensity.compute.meta new file mode 100644 index 00000000..247a584a --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/FluidFoamDensity.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2332ee3ce70e9447d8d13b5b67ac8e6c +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/FluidKernels.cginc b/xiaofang/Assets/Obi/Resources/Compute/FluidKernels.cginc new file mode 100644 index 00000000..deac8042 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/FluidKernels.cginc @@ -0,0 +1,40 @@ +#ifndef FLUIDKERNELS_INCLUDE +#define FLUIDKERNELS_INCLUDE + +#include "SolverParameters.cginc" + +float Poly6(float r, float h) +{ + float h2 = h * h; + float h4 = h2 * h2; + float h8 = h4 * h4; + + float rl = min(r, h); + float hr = h2 - rl * rl; + + if (mode) + return 4.0f / PI / h8 * hr * hr * hr; + else + return 315.0f / (64.0 * PI) / (h8 * h) * hr * hr * hr; +} + +float Spiky(float r, float h) +{ + float h2 = h * h; + float h4 = h2 * h2; + + float rl = min(r, h); + float hr = h - rl; + + if (mode) + return -30.0f / PI / (h4 * h) * hr * hr; + else + return -45.0f / PI / (h4 * h2) * hr * hr; +} + +float Cohesion(float r, float h) +{ + return cos(min(r, h) * 3 * PI / (2 * h)); +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/FluidKernels.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/FluidKernels.cginc.meta new file mode 100644 index 00000000..5915645b --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/FluidKernels.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 53c4eeee7bd2141deb8d1179555a1920 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/FluidMeshChunks.compute b/xiaofang/Assets/Obi/Resources/Compute/FluidMeshChunks.compute new file mode 100644 index 00000000..da444b47 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/FluidMeshChunks.compute @@ -0,0 +1,205 @@ +#pragma kernel ClearChunks +#pragma kernel ClearGrid +#pragma kernel InsertChunks +#pragma kernel SortParticles +#pragma kernel FindPopulatedLevels + +#include "MathUtils.cginc" +#include "Bounds.cginc" +#include "GridUtils.cginc" +#include "FluidChunkDefs.cginc" +#include "SolverParameters.cginc" + +// particle data: +StructuredBuffer particleIndices; +StructuredBuffer positions; +StructuredBuffer velocities; +StructuredBuffer angularVelocities; +StructuredBuffer principalRadii; +StructuredBuffer fluidMaterial; +StructuredBuffer fluidData; +StructuredBuffer orientations; +StructuredBuffer colors; +StructuredBuffer normals; + +RWStructuredBuffer sortedPositions; +RWStructuredBuffer sortedPrincipalRadii; +RWStructuredBuffer sortedVelocities; +RWStructuredBuffer sortedOrientations; +RWStructuredBuffer sortedColors; + +// particle grid data: +StructuredBuffer solverBounds; +StructuredBuffer gridHashToSortedIndex; +RWStructuredBuffer cellOffsets; // start of each cell in the sorted item array. +RWStructuredBuffer cellCounts; // number of item in each cell. +RWStructuredBuffer offsetInCell; // for each item, offset within its the cell. + +// voxel data: +RWStructuredBuffer chunkCoords; // for each chunk, spatial coordinates. +RWStructuredBuffer hashtable; // size: maxChunks entries. + +RWStructuredBuffer dispatchBuffer; + +uint firstParticle; +uint particleCount; +float isosurface; +float smoothing; + +uint AllocateChunk(uint3 coords) +{ + uint key = VoxelID(coords); + uint slot = hash(key); + + [allow_uav_condition] + for (uint i = 0; i < maxChunks; ++i) // at most, check the entire table. + { + uint prev; + InterlockedCompareExchange(hashtable[slot].key, INVALID, key, prev); + + // allocate new chunk: + if (prev == INVALID) + { + InterlockedAdd(dispatchBuffer[4],1,hashtable[slot].handle); + chunkCoords[hashtable[slot].handle] = coords; + return hashtable[slot].handle; + } + // could not allocate chunk, since it already exists. + else if (prev == key) + { + return INVALID; + } + // collision, try next slot. + else + slot = (slot + 1) % maxChunks; + } + return INVALID; // could not allocate chunk, not enough space. +} + +[numthreads(128, 1, 1)] +void ClearChunks (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= maxChunks) + return; + + // clear all chunks: + keyvalue k; + k.key = 0xffffffff; + k.handle = 0xffffffff; + hashtable[i] = k; +} + +[numthreads(128, 1, 1)] +void ClearGrid (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= maxCells) + return; + + if (i == 0) + { + for (int l = 0; l <= GRID_LEVELS; ++l) + levelPopulation[l] = 0; + } + + // clear all cell counts to zero, and cell offsets to invalid. + cellOffsets[i] = INVALID; + cellCounts[i] = 0; +} + +[numthreads(128, 1, 1)] +void InsertChunks (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= particleCount) return; + + int p = particleIndices[firstParticle + i]; + + // ignore inactive particles: + if (principalRadii[p].w <= 0.5f) + return; + + // calculate particle cell index: + int level = GridLevelForSize(fluidMaterial[p].x); + float cellSize = CellSizeOfLevel(level); + int4 cellCoord = int4(floor((positions[p].xyz - solverBounds[0].min_.xyz) / cellSize),level); + + // if the solver is 2D, project to the z = 0 cell. + if (mode == 1) cellCoord[2] = 0; + + // since cell hashes are morton-sorted during collision detection, here we also get sorted cells + // as long as particle cellCoords are reasonably similar + // (won't be the exact same since we use renderable positions instead of positions) + uint cellIndex = gridHashToSortedIndex[GridHash(cellCoord)]; + + // insert simplex in cell: + InterlockedAdd(cellCounts[cellIndex],1, offsetInCell[p]); + + // atomically increase this level's population by one: + InterlockedAdd(levelPopulation[1 + level],1); + + //in 3D, only particles near the surface should spawn chunks: + //if (mode == 0 && dot(normals[p],normals[p]) < 0.0001f) + //return; + + // expand aabb by voxel size, since boundary voxels (at a chunks' 0 X/Y/Z) can't be triangulated. + float radius = fluidMaterial[p].x + voxelSize; + + // calculate particle chunk span. + float chunkSize = chunkResolution * voxelSize; + uint3 minCell = floor((positions[p].xyz - radius - chunkGridOrigin) / chunkSize); + uint3 maxCell = floor((positions[p].xyz + radius - chunkGridOrigin) / chunkSize); + + if (mode == 1) + minCell[2] = maxCell[2] = 0; + + for (uint x = minCell[0]; x <= maxCell[0]; ++x) + { + for (uint y = minCell[1]; y <= maxCell[1]; ++y) + { + for (uint z = minCell[2]; z <= maxCell[2]; ++z) + { + AllocateChunk(uint3(x, y, z)); + } + } + } +} + +[numthreads(128, 1, 1)] +void SortParticles (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + if (i >= particleCount) return; + + int p = particleIndices[firstParticle + i]; + + // ignore inactive particles: + if (principalRadii[p].w <= 0.5f) + return; + + // calculate particle cell index: + int level = GridLevelForSize(fluidMaterial[p].x); + float cellSize = CellSizeOfLevel(level); + int4 cellCoord = int4(floor((positions[p].xyz - solverBounds[0].min_.xyz) / cellSize),level); + + // if the solver is 2D, project to the z = 0 cell. + if (mode == 1) cellCoord[2] = 0; + + uint cellIndex = gridHashToSortedIndex[GridHash(cellCoord)]; + + // find final sorted index: + uint gridIndex = cellOffsets[cellIndex] + offsetInCell[p]; + + // write particle data in sorted order: + sortedPositions[gridIndex] = float4(positions[p].xyz, 1 / fluidData[p].x); + sortedPrincipalRadii[gridIndex] = fluidMaterial[p].x * (principalRadii[p] / principalRadii[p].x); + sortedVelocities[gridIndex] = float4(velocities[p].xyz, (asuint(angularVelocities[p].w) & 0x0000ffff) / 65535.0); + sortedOrientations[gridIndex] = orientations[p]; + sortedColors[gridIndex] = colors[p]; +} + + + diff --git a/xiaofang/Assets/Obi/Resources/Compute/FluidMeshChunks.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/FluidMeshChunks.compute.meta new file mode 100644 index 00000000..e70344d3 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/FluidMeshChunks.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 745eb95f8ca884ea6830b3ca14ee05a0 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/FluidSurfaceMeshBuilding.compute b/xiaofang/Assets/Obi/Resources/Compute/FluidSurfaceMeshBuilding.compute new file mode 100644 index 00000000..d4e04809 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/FluidSurfaceMeshBuilding.compute @@ -0,0 +1,604 @@ +#pragma kernel SampleSDF +#pragma kernel CalculateSurface +#pragma kernel Triangulate +#pragma kernel Smoothing + +#pragma kernel FixArgsBuffer +#pragma kernel FillIndirectDrawBuffer + +#include "MathUtils.cginc" +#include "Bounds.cginc" +#include "GridUtils.cginc" +#include "FluidChunkDefs.cginc" +#include "FluidKernels.cginc" +#include "SolverParameters.cginc" +#include "NormalCompression.cginc" + +/* + * y z + * ^ / + * | + * 6----7 + * /| /| + * 2----3 | + * | 4--|-5 + * |/ |/ + * 0----1 --> x + * + */ + + /* + * static Vector2Int[] cubeEdges = + * { + * new Vector2Int(7,3), 0 + * new Vector2Int(7,5), 1 + * new Vector2Int(7,6), 2 + * + * new Vector2Int(6,4), 3 // x + * new Vector2Int(4,5), 4 + * new Vector2Int(5,1), 5 + * + * new Vector2Int(1,3), 6 // y + * new Vector2Int(3,2), 7 + * new Vector2Int(2,6), 8 + * + * new Vector2Int(4,0), 9 // z + * new Vector2Int(2,0), 10 + * new Vector2Int(1,0) 11 + * }; + */ + +static const int4 faceNeighborEdges[] = +{ + int4(0,1,5,6), + int4(0,2,7,8), + int4(4,5,9,11), + int4(3,8,9,10), + int4(6,7,10,11), + int4(1,2,3,4) +}; + +static const float3 corners[] = +{ + float3(0, 0, 0), // 0 + float3(1, 0, 0), // 1 + float3(0, 1, 0), // 2 + float3(1, 1, 0), // 3 + float3(0, 0, 1), // 4 + float3(1, 0, 1), // 5 + float3(0, 1, 1), // 6 + float3(1, 1, 1) // 7 +}; + +static const int3 quadNeighborIndices[] = +{ + int3(1, 3, 2), // x + int3(4, 5, 1), // y + int3(2, 6, 4), // z +}; + +static const int oppositeFaces[] = +{ + 7, //0 + 6, //1 + 5, //2 + 4, //3 + 3, //4 + 2, //5 + 1 //6 +}; + +static const int3 quadWindingOrder[] = { + int3(0, 1 ,2), + int3(2, 1 ,0) +}; + +struct indirectDrawIndexedArgs +{ + uint indexCountPerInstance; + uint instanceCount; + uint startIndex; + uint baseVertexIndex; + uint startInstance; +}; + +// particle grid data: +StructuredBuffer solverBounds; +StructuredBuffer cellOffsets; // start of each cell in the sorted item array. +StructuredBuffer cellCounts; // number of item in each cell. +StructuredBuffer gridHashToSortedIndex; + +StructuredBuffer sortedPositions; +StructuredBuffer sortedVelocities; +StructuredBuffer sortedPrincipalRadii; +StructuredBuffer sortedColors; +StructuredBuffer sortedOrientations; + +// voxel data: +StructuredBuffer chunkCoords; // for each chunk, spatial coordinates. +StructuredBuffer hashtable; // size: maxChunks entries. +RWStructuredBuffer voxelToVertex; // for each voxel, index into the vertices array in case the voxel spawns a vertex, INVALID otherwise. +RWStructuredBuffer vertexAdjacency; // indices of adjacent face voxels for each voxel. +RWStructuredBuffer voxelVelocities; // for each voxel, fluid velocity value. We are reusing the same ComputeBuffer used for vertexAdjacency. + +// edge LUTs +StructuredBuffer edges; +StructuredBuffer edgeTable; + +// mesh data: +RWStructuredBuffer verts; +RWStructuredBuffer outputVerts; +RWStructuredBuffer colors; +RWStructuredBuffer velocities; +RWStructuredBuffer quads; + +RWStructuredBuffer dispatchBuffer; +RWStructuredBuffer dispatchBuffer2; +RWStructuredBuffer indirectBuffer; + +uint currentBatch; + +float isosurface; +uint descentIterations; +float descentIsosurface; +float descentSpeed; +float smoothing; +float bevel; +uint dispatchMultiplier; +uint countMultiplier; +uint instanceCount; + +uint voxelCoordToOffset(int3 coord) +{ + if (mode == 1) + return (int)EncodeMorton2((uint2)coord.xy); + else return (int)EncodeMorton3((uint3)coord.xyz); +} + +uint LookupChunk(int3 coords) +{ + uint key = VoxelID(coords); + uint slot = hash(key); + + for (uint i = 0; i < maxChunks; ++i) // at most, check the entire table. + { + if (hashtable[slot].key == key) + { + return hashtable[slot].handle; + } + if (hashtable[slot].key == INVALID) + { + return INVALID; + } + + slot = (slot + 1) % maxChunks; + } + return INVALID; +} + +uint GetVoxelIndex(int3 chunkCoords, int3 voxelCoords, int voxelsInChunk) +{ + int3 mask = voxelCoords < 0 ? -1 : voxelCoords / chunkResolution; + uint chunk = LookupChunk(chunkCoords + mask); + + return chunk == INVALID ? INVALID : chunk * voxelsInChunk + voxelCoordToOffset(nfmod(voxelCoords, chunkResolution)); +} + +[numthreads(128, 1, 1)] +void SampleSDF (uint3 id : SV_DispatchThreadID) // one thread per voxel, +{ + uint i = id.x; + if (i >= dispatchBuffer[3]) return; + + int voxelsInChunk = (int)pow(chunkResolution, 3 - mode); // 64 voxels in 3D, 16 in 2D. + + // calculate chunk index: + int chunkIndex = i / voxelsInChunk; + + // get offset of voxel within chunk: + int cornerOffset = i - chunkIndex * voxelsInChunk; + int3 voxelCoords; + + if (mode == 1) + voxelCoords = (int3)DecodeMorton2((uint)cornerOffset); + else + voxelCoords = (int3)DecodeMorton3((uint)cornerOffset); + + int3 cornerCoords= chunkCoords[chunkIndex] * chunkResolution + voxelCoords; + + // calculate sampling position: + float3 samplePos = chunkGridOrigin + cornerCoords * voxelSize; + + float dist = isosurface; + float4 color = FLOAT4_ZERO; + float4 velocity = FLOAT4_ZERO; + + for (uint m = 1; m <= levelPopulation[0]; ++m) + { + uint l = levelPopulation[m]; + float cellSize = CellSizeOfLevel(l); + + int3 cell = floor((samplePos - solverBounds[0].min_.xyz) / cellSize); // TODO: not necessary to subtract solverBounds? + int3 minCell = cell - 1; + int3 maxCell = cell + 1; + + if (mode == 1) + minCell[2] = maxCell[2] = 0; + + for (int x = minCell[0]; x <= maxCell[0]; ++x) + { + for (int y = minCell[1]; y <= maxCell[1]; ++y) + { + for (int z = minCell[2]; z <= maxCell[2]; ++z) + { + int4 neighborCoord = int4(x, y, z, l); + int cellIndex = gridHashToSortedIndex[GridHash(neighborCoord)]; + uint n = cellOffsets[cellIndex]; + uint end = n + cellCounts[cellIndex]; + + for (;n < end; ++n) + { + float3 radii = sortedPrincipalRadii[n].xyz; + + // due to hash collisions, two neighboring cells might map to the same + // hash bucket, and we'll add the same set of particles twice to the neighbors list. + // So we only consider particles that have the same spatial coordinates as the cell. + uint level = GridLevelForSize(radii.x); + float cellSize = CellSizeOfLevel(level); + int4 particleCoord = int4(floor((sortedPositions[n].xyz - solverBounds[0].min_.xyz)/ cellSize).xyz,level); + + if (any (particleCoord - neighborCoord)) + continue; + + float3 normal = samplePos - sortedPositions[n].xyz; + if (mode == 1) + normal[2] = 0; + + // only update distance if within anisotropic kernel radius: + float maxDistance = radii.x + voxelSize * 1.42f; + float r = dot(normal, normal); + if (r <= maxDistance * maxDistance) + { + normal = rotate_vector(q_conj(sortedOrientations[n]), normal.xyz) / radii; + float d = length(normal) * radii.x; + + // sortedPositions.w is volume (1/normalized density): + float w = sortedPositions[n].w * Poly6(d,radii.x); + + dist -= w; + + // tigther smoothing kernel for color and velocities: + float w2 = 1-saturate(r / (radii.x * radii.x)); + color += float4(sortedColors[n].xyz * w2, w2); + velocity += sortedVelocities[n] * w2; // 4th component is length(angularVel), vorticity intensity. + } + + } + } + } + } + } + + verts[i].x = dist; + verts[i].y = PackFloatRGBA(color/color.w); + + voxelVelocities[i] = velocity / color.w; +} + +float EvaluateSDF (float4 distancesA, float4 distancesB, in float3 nPos, out float3 normal) +{ + // trilinear interpolation of distance: + float4 x = distancesA + (distancesB - distancesA) * nPos[0]; + float2 y = x.xy + (x.zw - x.xy) * nPos[1]; + + // gradient estimation: + // x == 0 + float2 a = distancesA.xy + (distancesA.zw - distancesA.xy) * nPos[1]; + float x0 = a[0] + (a[1] - a[0]) * nPos[2]; + + // x == 1 + a = distancesB.xy + (distancesB.zw - distancesB.xy) * nPos[1]; + float x1 = a[0] + (a[1] - a[0]) * nPos[2]; + + // y == 0 + float y0 = x[0] + (x[1] - x[0]) * nPos[2]; + + // y == 1 + float y1 = x[2] + (x[3] - x[2]) * nPos[2]; + + normal = normalize(float3(x1 - x0, y1 - y0, y[1] - y[0])); + return y[0] + (y[1] - y[0]) * nPos[2]; +} + +[numthreads(128, 1, 1)] +void CalculateSurface (uint3 id : SV_DispatchThreadID) // once per voxel. +{ + uint i = id.x; + if (i >= dispatchBuffer[3]) return; + + int voxelsInChunk = (int)pow(chunkResolution, 3 - mode); // 64 voxels in 3D, 16 in 2D. + int verticesPerVoxel = mode == 1 ? 4 : 8; // 8 vertices in 3D, 4 in 2D. + float3 dimensionMask = mode == 1 ? float3(1, 1, 0) : float3(1, 1, 1); + int edgeCount = mode == 1 ? 4 : 12; + + // initialize voxel with invalid vertex: + voxelToVertex[i] = INVALID; + + // calculate chunk index: + int chunkIndex = i / voxelsInChunk; + + // get offset of voxel within chunk: + int voxelOffset = i - chunkIndex * voxelsInChunk; + int3 voxelCoords; + + if (mode == 1) + voxelCoords = (int3)DecodeMorton2((uint)voxelOffset); + else + voxelCoords = (int3)DecodeMorton3((uint)voxelOffset); + + // get samples at voxel corners: + float samples[8]; + float4 vcolor[8]; + float4 vvelo[8]; + uint cornerMask = 0; + + // initialize all samples to zero (last 4 samples aren't written to in 2D). + int j = 0; + for (j = 0; j < 8; ++j) + samples[j] = 0; + + for (j = 0; j < verticesPerVoxel; ++j) + { + uint v = GetVoxelIndex(chunkCoords[chunkIndex], voxelCoords + corners[j], voxelsInChunk); + + if (v == INVALID) + return; + else + { + samples[j] = verts[v].x; + vcolor[j] = UnpackFloatRGBA(verts[v].y); + vvelo[j] = voxelVelocities[v]; + cornerMask |= samples[j] >= 0 ? (1 << j) : 0; + } + } + + // store cornerMask: + verts[i].z = asfloat(cornerMask); + + int edgeMask = edgeTable[cornerMask]; + + // if the voxel does not intersect the surface, return: + if ((mode == 1 && cornerMask == 0xf) || + (mode == 0 && edgeMask == 0)) + return; + + // calculate vertex position using edge crossings: + float3 normalizedPos = float3(0,0,0); + float4 velocity = FLOAT4_ZERO; + float4 color = FLOAT4_ZERO; + int intersections = 0; + + for (j = 0; j < edgeCount; ++j) + { + if((edgeMask & (1 << j)) == 0) + continue; + + int2 e = edges[j]; + float t = -samples[e.x] / (samples[e.y] - samples[e.x]); + + normalizedPos += lerp(corners[e.x],corners[e.y],t); + color += lerp(vcolor[e.x], vcolor[e.y], t); + velocity += lerp(vvelo[e.x], vvelo[e.y], t); + intersections++; + } + + // intersections will always be > 0 in 3D: + if (intersections > 0) + { + normalizedPos /= intersections; + color /= intersections; + velocity /= intersections; + } + else + { + normalizedPos = float3(0.5f, 0.5f, -bevel); + color = (vcolor[0] + vcolor[1] + vcolor[2] + vcolor[3]) * 0.25f; + velocity = (vvelo[0] + vvelo[1] + vvelo[2] + vvelo[3]) * 0.25f; + } + + float4 distancesA = float4(samples[0], samples[4], samples[2], samples[6]); + float4 distancesB = float4(samples[1], samples[5], samples[3], samples[7]); + + // gradient descent: + float3 normal; + for(uint k = 0; k < descentIterations; ++k) + { + float d = EvaluateSDF(distancesA, distancesB, normalizedPos, normal); + normalizedPos -= descentSpeed * normal * (d + isosurface + descentIsosurface); + } + + // final normal evaluation: + EvaluateSDF(distancesA, distancesB, normalizedPos, normal); + + // modify normal in 2D mode: + if (mode) + normal = lerp(float3(0,0,-1),float3(normal.xy,-normal.z),bevel); // no bevel, flat normals + + // Append vertex: + InterlockedAdd(dispatchBuffer[4],1,voxelToVertex[i]); + verts[voxelToVertex[i]].w = i; + + float3 voxelCorner = chunkGridOrigin + (float3)(chunkCoords[chunkIndex] * chunkResolution + voxelCoords) * voxelSize; + outputVerts[voxelToVertex[i]] = float4(voxelCorner * dimensionMask + normalizedPos * voxelSize, encode(normal)); + colors[voxelToVertex[i]] = color; + velocities[voxelToVertex[i]] = velocity; +} + +[numthreads(128, 1, 1)] +void Triangulate (uint3 id : SV_DispatchThreadID) +{ + uint v0 = id.x; + if (v0 >= dispatchBuffer[3]) return; + + int voxelsInChunk = (int)pow(chunkResolution, 3 - mode); // 64 voxels in 3D, 16 in 2D. + int quadCount = 3 - mode * 2; // 3 quads in 3D, 1 in 2D. + int adjacentCount = 6 - mode * 2; // 6 adjacent voxels in 3D, 4 in 2D. + + // get index of the voxel that spawned this vertex: + uint i = verts[v0].w; + + // calculate chunk index and look up coordinates: + int chunkIndex = i / voxelsInChunk; + + // get offset of voxel within chunk: + int voxelOffset = i - chunkIndex * voxelsInChunk; + int3 voxelCoords; + + if (mode == 1) + voxelCoords = (int3)DecodeMorton2((uint)voxelOffset); + else + voxelCoords = (int3)DecodeMorton3((uint)voxelOffset); + + uint cornerMask = asuint(verts[i].z); + int edgeMask = edgeTable[cornerMask]; + + // get winding order using last bit of cornermask, which indicates corner sign: + // in 2D, cornerMask >> 7 is always 0, so we get the second winding order. + int3 windingOrder = (cornerMask >> 7) ? quadWindingOrder[0] : quadWindingOrder[1]; + + // Retrieve adjacent voxels: + int j; + uint adjacent[6]; + for (j = 0; j < adjacentCount; ++j) + adjacent[j] = GetVoxelIndex(chunkCoords[chunkIndex], voxelCoords + corners[j + 1], voxelsInChunk); + + // Iterate over all potential quads, append those needed: + for (j = 0; j < quadCount; ++j) + { + // if the edge is not crossing the surface, skip it (3D only) + if (mode == 0 && (edgeMask & (1 << j)) == 0) + continue; + + // calculate final neighbor indices: + uint3 neighbors = uint3(quadNeighborIndices[j][windingOrder[0]]-1, + quadNeighborIndices[j][windingOrder[1]]-1, + quadNeighborIndices[j][windingOrder[2]]-1); + + // get vertex indices for all voxels involved: + uint v1 = voxelToVertex[adjacent[neighbors[0]]]; + uint v2 = voxelToVertex[adjacent[neighbors[1]]]; + uint v3 = voxelToVertex[adjacent[neighbors[2]]]; + + // if any of the vertices is invalid, skip the quad: + if (v1 == INVALID || v2 == INVALID || v3 == INVALID) + continue; + + // append a new quad: + uint baseIndex; + InterlockedAdd(dispatchBuffer2[4],1,baseIndex); + baseIndex *= 6; + + // flip edge if necessary, to always use the shortest diagonal: + float3 diag1 = outputVerts[v0].xyz - outputVerts[v2].xyz; + float3 diag2 = outputVerts[v1].xyz - outputVerts[v3].xyz; + if (dot(diag1,diag1) > dot(diag2,diag2) * 1.1) + { + quads[baseIndex] = v1; + quads[baseIndex+1] = v2; + quads[baseIndex+2] = v3; + + quads[baseIndex+3] = v0; + quads[baseIndex+4] = v1; + quads[baseIndex+5] = v3; + } + else + { + quads[baseIndex] = v0; + quads[baseIndex+1] = v1; + quads[baseIndex+2] = v2; + + quads[baseIndex+3] = v3; + quads[baseIndex+4] = v0; + quads[baseIndex+5] = v2; + } + } + + // Move adjacent voxel in Z axis to last position, so that 2D adjacent voxels are the first 4. + adjacent[5] = adjacent[3]; + adjacent[2] = GetVoxelIndex(chunkCoords[chunkIndex], voxelCoords + int3(0, -1, 0), voxelsInChunk); + adjacent[3] = GetVoxelIndex(chunkCoords[chunkIndex], voxelCoords + int3(-1, 0, 0), voxelsInChunk); + adjacent[4] = GetVoxelIndex(chunkCoords[chunkIndex], voxelCoords + int3(0, 0, -1), voxelsInChunk); + + // initialize vertex adjacency to INVALID. + for (j = 0; j < 6; ++j) + vertexAdjacency[v0*6 + j] = INVALID; + + // Determine adjacent surface voxels for smoothing: + bool isAdjacent; + for (j = 0; j < adjacentCount; ++j) + { + if (adjacent[j] != INVALID) + { + // adjacent if this does not intersect the surface or both intersect the surface. + isAdjacent = (edgeMask == 0 || edgeTable[asuint(verts[adjacent[j]].z)] != 0) && + + // in 3D mode, it should also intersect any of the face edges to be considered adjacent: + (mode == 1 || any(edgeMask & (1 << faceNeighborEdges[j]))); + + vertexAdjacency[v0 * 6 + j] = isAdjacent ? voxelToVertex[adjacent[j]] : INVALID; + } + } +} + +[numthreads(128, 1, 1)] +void Smoothing (uint3 id : SV_DispatchThreadID) +{ + uint thread = id.x; + if (thread >= dispatchBuffer[3]) return; + + float3 n = decode(verts[thread].w); + + float4 coord = float4(verts[thread].xyz,1); + float4 norm = float4(n,1); + + for (int j = 0; j < 6; ++j) + { + uint v = vertexAdjacency[thread*6 + j]; + if (v != INVALID) + { + coord += float4(verts[v].xyz,1); + norm += float4(decode(verts[v].w),1); + } + } + + coord.xyz /= coord.w; + norm.xyz /= norm.w; + + float3 v = lerp(verts[thread].xyz, coord.xyz, smoothing); + n = normalize(lerp(n,norm.xyz, smoothing)); + + outputVerts[thread] = float4(v, encode(n)); + +} + +[numthreads(1, 1, 1)] +void FixArgsBuffer (uint3 id : SV_DispatchThreadID) +{ + dispatchBuffer[3] = dispatchBuffer[4] * dispatchMultiplier; + dispatchBuffer[0] = dispatchBuffer[3] / 128 + 1; + dispatchBuffer[4] *= countMultiplier; // used to zero out fourth component if needed. +} + +[numthreads(1, 1, 1)] +void FillIndirectDrawBuffer (uint3 id : SV_DispatchThreadID) +{ + indirectDrawIndexedArgs a; + + a.indexCountPerInstance = dispatchBuffer[3] * 6; // number of quads * 6 + a.instanceCount = instanceCount; + a.startIndex = 0; + a.baseVertexIndex = 0; + a.startInstance = 0; + indirectBuffer[0] = a; +} + diff --git a/xiaofang/Assets/Obi/Resources/Compute/FluidSurfaceMeshBuilding.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/FluidSurfaceMeshBuilding.compute.meta new file mode 100644 index 00000000..67121ca8 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/FluidSurfaceMeshBuilding.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 676e30b71ac3147969895b3f0ad6d2ec +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/GridUtils.cginc b/xiaofang/Assets/Obi/Resources/Compute/GridUtils.cginc new file mode 100644 index 00000000..c17c5ac6 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/GridUtils.cginc @@ -0,0 +1,166 @@ +#ifndef GRIDUTILS_INCLUDE +#define GRIDUTILS_INCLUDE + +#define INVALID 0xFFFFFFFF +#define MIN_GRID_LEVEL -6 // minimum cell size is 0.01 meters, enough for very small colliders / particles (log(0.01) / log(2)) +#define MAX_GRID_LEVEL 17 // maximum cell size is 131072 meters, enough for gargantuan objects. +#define GRID_LEVELS (MAX_GRID_LEVEL - MIN_GRID_LEVEL + 1) + +RWStructuredBuffer levelPopulation; +uint maxCells; // maximum number of unique cells in the grid. + +static const float4 cellNeighborhood[27] = { +float4(-1,-1,-1, 0), +float4(-1,-1, 0, 0), +float4(-1,-1, 1, 0), +float4(-1, 0,-1, 0), +float4(-1, 0, 0, 0), +float4(-1, 0, 1, 0), +float4(-1, 1,-1, 0), +float4(-1, 1, 0, 0), +float4(-1, 1, 1, 0), +float4( 0,-1,-1, 0), +float4( 0,-1, 0, 0), +float4( 0,-1, 1, 0), +float4( 0, 0,-1, 0), +float4( 0, 0, 0, 0), +float4( 0, 0, 1, 0), +float4( 0, 1,-1, 0), +float4( 0, 1, 0, 0), +float4( 0, 1, 1, 0), +float4( 1,-1,-1, 0), +float4( 1,-1, 0, 0), +float4( 1,-1, 1, 0), +float4( 1, 0,-1, 0), +float4( 1, 0, 0, 0), +float4( 1, 0, 1, 0), +float4( 1, 1,-1, 0), +float4( 1, 1, 0, 0), +float4( 1, 1, 1, 0), +}; + +static const float4 aheadCellNeighborhood[13] = { +float4(1,0,0,0), // + , 0 , 0 ( 1) +float4(0,1,0,0), // 0 , + , 0 ( 3) +float4(1,1,0,0), // + , + , 0 ( 4) +float4(0,0,1,0), // 0 , 0 , + ( 9) +float4(1,0,1,0), // + , 0 , + (10) +float4(0,1,1,0), // 0 , + , + (12) +float4(1,1,1,0), // + , + , + (13) + +float4(-1,1,0,0), // - , + , 0 ( 2) +float4(-1,-1,1,0), // - , - , + ( 5) +float4(0,-1,1,0), // 0 , - , + ( 6) +float4(1,-1,1,0), // + , - , + ( 7) +float4(-1,0,1,0), // - , 0 , + ( 8) +float4(-1,1,1,0), // - , + , + (11) +}; + +[numthreads(1,1,1)] +void FindPopulatedLevels (uint3 id : SV_DispatchThreadID) +{ + for (int l = 1; l <= GRID_LEVELS; ++l) + { + if (levelPopulation[l] > 0) + levelPopulation[1 + levelPopulation[0]++] = l - 1; + } +} + +inline int GridLevelForSize(float size) +{ + // the magic number is 1/log(2), used because log_a(x) = log_b(x) / log_b(a) + // level is clamped between MIN_LEVEL and MAX_LEVEL, then remapped to (0, MAX_LEVEL - MIN_LEVEL) + // this allows us to avoid InterlockedMax issues on GPU, since it doesn't work on negative numbers on some APIs. + return clamp((int)ceil(log(size) * 1.44269504089), MIN_GRID_LEVEL, MAX_GRID_LEVEL) - MIN_GRID_LEVEL; +} + +inline float CellSizeOfLevel(int level) +{ + return exp2(level + MIN_GRID_LEVEL); +} + +inline int4 GetParentCellCoords(int4 cellCoords, uint level) +{ + float decimation = exp2(level - cellCoords[3]); + int4 cell = (int4)floor((float4)cellCoords / decimation); + cell[3] = level; + return cell; +} + +uint Part1By1(uint x) +{ + x &= 0x0000ffff; // x = ---- ---- ---- ---- fedc ba98 7654 3210 + x = (x ^ (x << 8)) & 0x00ff00ff; // x = ---- ---- fedc ba98 ---- ---- 7654 3210 + x = (x ^ (x << 4)) & 0x0f0f0f0f; // x = ---- fedc ---- ba98 ---- 7654 ---- 3210 + x = (x ^ (x << 2)) & 0x33333333; // x = --fe --dc --ba --98 --76 --54 --32 --10 + x = (x ^ (x << 1)) & 0x55555555; // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0 + return x; +} + +// "Insert" two 0 bits after each of the 10 low bits of x +uint Part1By2(uint x) +{ + x &= 0x000003ff; // x = ---- ---- ---- ---- ---- --98 7654 3210 + x = (x ^ (x << 16)) & 0xff0000ff; // x = ---- --98 ---- ---- ---- ---- 7654 3210 + x = (x ^ (x << 8)) & 0x0300f00f; // x = ---- --98 ---- ---- 7654 ---- ---- 3210 + x = (x ^ (x << 4)) & 0x030c30c3; // x = ---- --98 ---- 76-- --54 ---- 32-- --10 + x = (x ^ (x << 2)) & 0x09249249; // x = ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0 + return x; +} + +uint Compact1By1(uint x) +{ + x &= 0x55555555; // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0 + x = (x ^ (x >> 1)) & 0x33333333; // x = --fe --dc --ba --98 --76 --54 --32 --10 + x = (x ^ (x >> 2)) & 0x0f0f0f0f; // x = ---- fedc ---- ba98 ---- 7654 ---- 3210 + x = (x ^ (x >> 4)) & 0x00ff00ff; // x = ---- ---- fedc ba98 ---- ---- 7654 3210 + x = (x ^ (x >> 8)) & 0x0000ffff; // x = ---- ---- ---- ---- fedc ba98 7654 3210 + return x; +} + +uint Compact1By2(uint x) +{ + x &= 0x09249249; // x = ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0 + x = (x ^ (x >> 2)) & 0x030c30c3; // x = ---- --98 ---- 76-- --54 ---- 32-- --10 + x = (x ^ (x >> 4)) & 0x0300f00f; // x = ---- --98 ---- ---- 7654 ---- ---- 3210 + x = (x ^ (x >> 8)) & 0xff0000ff; // x = ---- --98 ---- ---- ---- ---- 7654 3210 + x = (x ^ (x >> 16)) & 0x000003ff; // x = ---- ---- ---- ---- ---- --98 7654 3210 + return x; +} + +inline uint EncodeMorton2(uint2 coords) +{ + return (Part1By1(coords.y) << 1) + Part1By1(coords.x); +} + +inline uint EncodeMorton3(uint3 coords) +{ + return (Part1By2(coords.z) << 2) + (Part1By2(coords.y) << 1) + Part1By2(coords.x); +} + +inline uint3 DecodeMorton2(uint code) +{ + return uint3(Compact1By1(code >> 0), Compact1By1(code >> 1), 0); +} + +inline uint3 DecodeMorton3(uint code) +{ + return uint3(Compact1By2(code >> 0), Compact1By2(code >> 1), Compact1By2(code >> 2)); +} + +inline uint GridHash(in int4 cellIndex) +{ + return (73856093*cellIndex.x ^ + 19349663*cellIndex.y ^ + 83492791*cellIndex.z ^ + 10380569*cellIndex.w) % maxCells; +} + +inline uint GridHash(in int3 cellIndex) +{ + return (73856093*cellIndex.x ^ + 19349663*cellIndex.y ^ + 83492791*cellIndex.z) % maxCells; +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/GridUtils.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/GridUtils.cginc.meta new file mode 100644 index 00000000..be067e28 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/GridUtils.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b4dbf43981a3b419fbc2eaf5f2c05a6c +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/HeightfieldShape.compute b/xiaofang/Assets/Obi/Resources/Compute/HeightfieldShape.compute new file mode 100644 index 00000000..e286ce6f --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/HeightfieldShape.compute @@ -0,0 +1,230 @@ +#include "ColliderDefinitions.cginc" +#include "ContactHandling.cginc" +#include "Transform.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "Optimization.cginc" + +#pragma kernel GenerateContacts + +struct HeightFieldHeader +{ + int firstSample; + int sampleCount; +}; + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer principalRadii; +StructuredBuffer velocities; + +StructuredBuffer simplices; +StructuredBuffer simplexBounds; // bounding box of each simplex. + +StructuredBuffer transforms; +StructuredBuffer shapes; + +// heightfield data: +StructuredBuffer heightFieldHeaders; +StructuredBuffer heightFieldSamples; + +StructuredBuffer contactPairs; +StructuredBuffer contactOffsetsPerType; + +RWStructuredBuffer contacts; +RWStructuredBuffer dispatchBuffer; + +StructuredBuffer worldToSolver; + +uint maxContacts; +float deltaTime; + +struct Heightfield : IDistanceFunction +{ + shape s; + transform colliderToSolver; + + CachedTri tri; + float4 triNormal; + + void Evaluate(in float4 pos, in float4 radii, in quaternion orientation, inout SurfacePoint projectedPoint) + { + float4 pnt = colliderToSolver.InverseTransformPoint(pos); + + float4 bary; + float4 nearestPoint = NearestPointOnTri(tri, pnt, bary); + float4 normal = normalizesafe(pnt - nearestPoint); + + // flip the contact normal if it points below ground: (doesn't work with holes) + //OneSidedNormal(triNormal, normal); + + projectedPoint.pos = colliderToSolver.TransformPoint(nearestPoint + normal * s.contactOffset); + projectedPoint.normal = colliderToSolver.TransformDirection(normal); + projectedPoint.bary = float4(1,0,0,0); + } + +}; + +[numthreads(128, 1, 1)] +void GenerateContacts (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + // entry #11 in the dispatch buffer is the amount of pairs for the first shape type. + if (i >= dispatchBuffer[11 + 4 * HEIGHTMAP_SHAPE]) return; + + int firstPair = contactOffsetsPerType[HEIGHTMAP_SHAPE]; + int simplexIndex = contactPairs[firstPair + i].x; + int colliderIndex = contactPairs[firstPair + i].y; + shape s = shapes[colliderIndex]; + + if (s.dataIndex < 0) return; + + HeightFieldHeader header = heightFieldHeaders[s.dataIndex]; + + Heightfield fieldShape; + fieldShape.colliderToSolver = worldToSolver[0].Multiply(transforms[colliderIndex]); + fieldShape.s = s; + + // invert a full matrix here to accurately represent collider bounds scale. + float4x4 solverToCollider = Inverse(TRS(fieldShape.colliderToSolver.translation.xyz, fieldShape.colliderToSolver.rotation, fieldShape.colliderToSolver.scale.xyz)); + aabb simplexBound = simplexBounds[simplexIndex].Transformed(solverToCollider); + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(simplexIndex, simplexSize); + + int resolutionU = (int)s.center.x; + int resolutionV = (int)s.center.y; + + // calculate terrain cell size: + float cellWidth = s.size.x / (resolutionU - 1); + float cellHeight = s.size.z / (resolutionV - 1); + + // calculate particle bounds min/max cells: + int2 min_ = int2((int)floor(simplexBound.min_[0] / cellWidth), (int)floor(simplexBound.min_[2] / cellHeight)); + int2 max_ = int2((int)floor(simplexBound.max_[0] / cellWidth), (int)floor(simplexBound.max_[2] / cellHeight)); + + for (int su = min_[0]; su <= max_[0]; ++su) + { + if (su >= 0 && su < resolutionU - 1) + { + for (int sv = min_[1]; sv <= max_[1]; ++sv) + { + if (sv >= 0 && sv < resolutionV - 1) + { + // calculate neighbor sample indices: + int csu1 = clamp(su + 1, 0, resolutionU - 1); + int csv1 = clamp(sv + 1, 0, resolutionV - 1); + + // sample heights: + float h1 = heightFieldSamples[header.firstSample + sv * resolutionU + su] * s.size.y; + float h2 = heightFieldSamples[header.firstSample + sv * resolutionU + csu1] * s.size.y; + float h3 = heightFieldSamples[header.firstSample + csv1 * resolutionU + su] * s.size.y; + float h4 = heightFieldSamples[header.firstSample + csv1 * resolutionU + csu1] * s.size.y; + + if (h1 < 0) continue; + h1 = abs(h1); + h2 = abs(h2); + h3 = abs(h3); + h4 = abs(h4); + + float min_x = su * s.size.x / (resolutionU - 1); + float max_x = csu1 * s.size.x / (resolutionU - 1); + float min_z = sv * s.size.z / (resolutionV - 1); + float max_z = csv1 * s.size.z / (resolutionV - 1); + + float4 convexPoint; + float4 simplexBary = BarycenterForSimplexOfSize(simplexSize); + + // ------contact against the first triangle------: + float4 v1 = float4(min_x, h3, max_z, 0); + float4 v2 = float4(max_x, h4, max_z, 0); + float4 v3 = float4(min_x, h1, min_z, 0); + + fieldShape.tri.Cache(v1, v2, v3); + fieldShape.triNormal.xyz = normalizesafe(cross((v2 - v1).xyz, (v3 - v1).xyz)); + + SurfacePoint colliderPoint = Optimize(fieldShape, positions, orientations, principalRadii, + simplices, simplexStart, simplexSize, simplexBary, convexPoint, surfaceCollisionIterations, surfaceCollisionTolerance); + + float4 velocity = FLOAT4_ZERO; + float simplexRadius = 0; + int j; + for (j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + simplexRadius += principalRadii[particleIndex].x * simplexBary[j]; + velocity += velocities[particleIndex] * simplexBary[j]; + } + + float dAB = dot(convexPoint - colliderPoint.pos, colliderPoint.normal); + float vel = dot(velocity, colliderPoint.normal); + + if (vel * deltaTime + dAB <= simplexRadius + s.contactOffset + collisionMargin) + { + uint count = contacts.IncrementCounter(); + if (count < maxContacts) + { + contact c = (contact)0; + + c.pointB = colliderPoint.pos; + c.normal = colliderPoint.normal * fieldShape.s.isInverted(); + c.pointA = simplexBary; + c.bodyA = simplexIndex; + c.bodyB = colliderIndex; + + contacts[count] = c; + + InterlockedMax(dispatchBuffer[0],(count + 1) / 128 + 1); + InterlockedMax(dispatchBuffer[3], count + 1); + } + } + + // ------contact against the second triangle------: + v1 = float4(min_x, h1, min_z, 0); + v2 = float4(max_x, h4, max_z, 0); + v3 = float4(max_x, h2, min_z, 0); + + fieldShape.tri.Cache(v1, v2, v3); + fieldShape.triNormal.xyz = normalizesafe(cross((v2 - v1).xyz, (v3 - v1).xyz)); + + colliderPoint = Optimize(fieldShape, positions, orientations, principalRadii, + simplices, simplexStart, simplexSize, simplexBary, convexPoint, surfaceCollisionIterations, surfaceCollisionTolerance); + + velocity = FLOAT4_ZERO; + simplexRadius = 0; + for (j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + simplexRadius += principalRadii[particleIndex].x * simplexBary[j]; + velocity += velocities[particleIndex] * simplexBary[j]; + } + + dAB = dot(convexPoint - colliderPoint.pos, colliderPoint.normal); + vel = dot(velocity, colliderPoint.normal); + + if (vel * deltaTime + dAB <= simplexRadius + s.contactOffset + collisionMargin) + { + uint count = contacts.IncrementCounter(); + if (count < maxContacts) + { + contact c = (contact)0; + + c.pointB = colliderPoint.pos; + c.normal = colliderPoint.normal * fieldShape.s.isInverted(); + c.pointA = simplexBary; + c.bodyA = simplexIndex; + c.bodyB = colliderIndex; + + contacts[count] = c; + + InterlockedMax(dispatchBuffer[0],(count + 1) / 128 + 1); + InterlockedMax(dispatchBuffer[3], count + 1); + } + } + } + } + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/HeightfieldShape.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/HeightfieldShape.compute.meta new file mode 100644 index 00000000..a04ea626 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/HeightfieldShape.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d9efd384bb82b4ec0b0adf1fc349a89b +ComputeShaderImporter: + externalObjects: {} + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/InertialFrame.cginc b/xiaofang/Assets/Obi/Resources/Compute/InertialFrame.cginc new file mode 100644 index 00000000..3a30c9c6 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/InertialFrame.cginc @@ -0,0 +1,18 @@ +#ifndef INERTIALFRAME_INCLUDE +#define INERTIALFRAME_INCLUDE + +#include "Transform.cginc" + +struct inertialFrame +{ + transform frame; + transform prevFrame; + + float4 velocity; + float4 angularVelocity; + + float4 acceleration; + float4 angularAcceleration; +}; + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/InertialFrame.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/InertialFrame.cginc.meta new file mode 100644 index 00000000..ed4916d3 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/InertialFrame.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2d21eb1b3353a439eb5f6f6df05dd6d0 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/InstancedParticleRendering.compute b/xiaofang/Assets/Obi/Resources/Compute/InstancedParticleRendering.compute new file mode 100644 index 00000000..b07c7bc8 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/InstancedParticleRendering.compute @@ -0,0 +1,44 @@ +#pragma kernel UpdateParticleInstances + +#include "PathFrame.cginc" + +struct RendererData +{ + float4 color; + float radiusScale; +}; + +StructuredBuffer activeParticles; +StructuredBuffer rendererData; +StructuredBuffer rendererIndex; + +StructuredBuffer renderablePositions; +StructuredBuffer renderableOrientations; +StructuredBuffer renderableRadii; +StructuredBuffer colors; +float4x4 solverToWorld; + +RWStructuredBuffer instanceTransforms; +RWStructuredBuffer invInstanceTransforms; +RWStructuredBuffer instanceColors; + +uint particleCount; + +[numthreads(128, 1, 1)] +void UpdateParticleInstances (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= particleCount) return; + + int p = activeParticles[i]; + + float4x4 tfrm = TRS(renderablePositions[p].xyz, + renderableOrientations[p], + renderableRadii[p].xyz * renderableRadii[p][3] * rendererData[rendererIndex[i]].radiusScale); + + instanceTransforms[i] = mul(solverToWorld, tfrm); + + instanceColors[i] = colors[p] * rendererData[rendererIndex[i]].color; + + invInstanceTransforms[i] = Inverse(instanceTransforms[i]); +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/InstancedParticleRendering.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/InstancedParticleRendering.compute.meta new file mode 100644 index 00000000..a82b45e1 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/InstancedParticleRendering.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d2b27c5c6c8154b6694d7e017468ccc0 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/Integration.cginc b/xiaofang/Assets/Obi/Resources/Compute/Integration.cginc new file mode 100644 index 00000000..fc9edd61 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Integration.cginc @@ -0,0 +1,38 @@ +#ifndef INTEGRATION_INCLUDE +#define INTEGRATION_INCLUDE + +#include "Quaternion.cginc" + +float4 IntegrateLinear(float4 position, float4 velocity, float dt) +{ + return position + velocity * dt; +} + +float4 DifferentiateLinear(float4 position, float4 prevPosition, float dt) +{ + return (position - prevPosition) / dt; +} + +quaternion AngularVelocityToSpinQuaternion(quaternion rotation, float4 angularVelocity, float dt) +{ + quaternion delta = quaternion(angularVelocity.x, + angularVelocity.y, + angularVelocity.z, 0); + + return quaternion(0.5f * qmul(delta,rotation) * dt); +} + +quaternion IntegrateAngular(quaternion rotation, float4 angularVelocity, float dt) +{ + rotation += AngularVelocityToSpinQuaternion(rotation,angularVelocity, dt); + return normalize(rotation); +} + +float4 DifferentiateAngular(quaternion rotation, quaternion prevRotation, float dt) +{ + quaternion deltaq = qmul(rotation, q_conj(prevRotation)); + float s = deltaq.w >= 0 ? 1 : -1; + return float4(s * deltaq.xyz * 2.0f / dt, 0); +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/Integration.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/Integration.cginc.meta new file mode 100644 index 00000000..7940d015 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Integration.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d436b0155e8f943d59a26290140664cd +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/InterlockedUtils.cginc b/xiaofang/Assets/Obi/Resources/Compute/InterlockedUtils.cginc new file mode 100644 index 00000000..06f22729 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/InterlockedUtils.cginc @@ -0,0 +1,46 @@ +#ifndef INTERLOCKEDUTILS_INCLUDE +#define INTERLOCKEDUTILS_INCLUDE + +void InterlockedAddFloat(RWStructuredBuffer buffer, int index, int axis, float value) +{ + uint i_val = asuint(value); + uint tmp0 = 0; + uint tmp1; + + [allow_uav_condition] + while (true) + { + InterlockedCompareExchange(buffer[index][axis], tmp0, i_val, tmp1); + + if (tmp1 == tmp0) + break; + + tmp0 = tmp1; + i_val = asuint(value + asfloat(tmp1)); + } + + return; +} + +void InterlockedAddFloat(RWStructuredBuffer buffer, int index, float value) +{ + uint i_val = asuint(value); + uint tmp0 = 0; + uint tmp1; + + [allow_uav_condition] + while (true) + { + InterlockedCompareExchange(buffer[index], tmp0, i_val, tmp1); + + if (tmp1 == tmp0) + break; + + tmp0 = tmp1; + i_val = asuint(value + asfloat(tmp1)); + } + + return; +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/InterlockedUtils.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/InterlockedUtils.cginc.meta new file mode 100644 index 00000000..c09fa844 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/InterlockedUtils.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: bb532ce1395da4d13b47a4da3e1b4033 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/MathUtils.cginc b/xiaofang/Assets/Obi/Resources/Compute/MathUtils.cginc new file mode 100644 index 00000000..5df9be82 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/MathUtils.cginc @@ -0,0 +1,557 @@ +#ifndef MATHUTILS_INCLUDE +#define MATHUTILS_INCLUDE + +#define PI 3.14159265359f +#define SQRT2 1.41421356237f +#define SQRT3 1.73205080757f +#define EPSILON 0.0000001f +#define FLT_MAX 3.402823466e+38 +#define FLT_MIN 1.175494351e-38 + +#define FLOAT4_ZERO float4(0, 0, 0, 0) +#define FLOAT4_EPSILON float4(EPSILON, EPSILON, EPSILON, EPSILON) + +#define zero 0 +#define one 1 + +#define PHASE_SELFCOLLIDE (1 << 24) +#define PHASE_FLUID (1 << 25) +#define PHASE_ONESIDED (1 << 26) + +#include "Quaternion.cginc" +#include "Matrix.cginc" + +float4 normalizesafe(in float4 v, float4 def = float4(0,0,0,0)) +{ + float len = length(v); + return (len < EPSILON) ? def : v/len; +} + +float3 normalizesafe(in float3 v, float3 def = float3(0,0,0)) +{ + float len = length(v); + return (len < EPSILON) ? def : v/len; +} + +inline float cmax( in float3 v) +{ + return max(max(v.x,v.y),v.z); +} + +inline float3 nfmod(float3 a, float3 b) +{ + return a - b * floor(a / b); +} + +inline float BaryScale(float4 coords) +{ + return 1.0 / dot(coords, coords); +} + +float Remap01(float value, float min_, float max_) +{ + return (min(value, max_) - min(value, min_)) / (max_ - min_); +} + +float EllipsoidRadius(float4 normSolverDirection, quaternion orientation, float3 radii) +{ + float3 localDir = rotate_vector(q_conj(orientation), normSolverDirection.xyz) / radii; + float sqrNorm = dot(localDir, localDir); + return sqrNorm > EPSILON ? sqrt(1 / sqrNorm) : radii.x; +} + +float4 Project(float4 v, float4 onto) +{ + float len = dot(onto,onto); + if (len < EPSILON) + return FLOAT4_ZERO; + return dot(onto, v) * onto / len; +} + +float3 Project(float3 v, float3 onto) +{ + float len = dot(onto,onto); + if (len < EPSILON) + return float3(0,0,0); + return dot(onto, v) * onto / len; +} + +inline void OneSidedNormal(float4 forward, inout float4 normal) +{ + float d = dot(normal.xyz, forward.xyz); + if (d < 0) normal -= 2 * d * forward; +} + +quaternion ExtractRotation(float3x3 m, quaternion rotation, int iterations) +{ + float4x4 R; + for (int i = 0; i < iterations; ++i) + { + R = q_toMatrix(rotation); + float3 omega = (cross(R._m00_m10_m20, m._m00_m10_m20) + cross(R._m01_m11_m21, m._m01_m11_m21) + cross(R._m02_m12_m22, m._m02_m12_m22)) / + (abs(dot(R._m00_m10_m20, m._m00_m10_m20) + dot(R._m01_m11_m21, m._m01_m11_m21) + dot(R._m02_m12_m22, m._m02_m12_m22)) + EPSILON); + + float w = length(omega); + if (w < EPSILON) + break; + + rotation = normalize(qmul(axis_angle((1.0f / w) * omega, w), rotation)); + } + return rotation; +} + +quaternion ExtractRotation(float4x4 m, quaternion rotation, int iterations) +{ + return ExtractRotation((float3x3) m, rotation, iterations); +} + +float4 GetParticleInertiaTensor(in float4 principalRadii, in float invRotationalMass) +{ + float4 sqrRadii = principalRadii * principalRadii; + return 0.2f / (invRotationalMass + EPSILON) * float4(sqrRadii[1] + sqrRadii[2], + sqrRadii[0] + sqrRadii[2], + sqrRadii[0] + sqrRadii[1], 0); +} + +float4x4 TransformInertiaTensor(float4 tensor, quaternion rotation) +{ + float4x4 rotMatrix = q_toMatrix(rotation); + return mul(rotMatrix, mul(AsDiagonal(tensor), transpose(rotMatrix))); +} + +float RotationalInvMass(float4x4 inverseInertiaTensor, float4 pos, float4 direction) +{ + float4 cr = mul(inverseInertiaTensor, float4(cross(pos.xyz, direction.xyz), 0)); + return dot(cross(cr.xyz, pos.xyz), direction.xyz); +} + +float4 NearestPointOnEdge(float4 a, float4 b, float4 p, out float mu, bool clampToSegment = true) +{ + float4 ap = p - a; + float4 ab = b - a; + ap.w = 0; + ab.w = 0; + + mu = dot(ap, ab) / dot(ab, ab); + + if (clampToSegment) + mu = saturate(mu); + + float4 result = a + ab * mu; + result.w = 0; + return result; +} + +float3 NearestPointOnEdge(float3 a, float3 b, float3 p, out float mu, bool clampToSegment = true) +{ + float3 ap = p - a; + float3 ab = b - a; + + mu = dot(ap, ab) / dot(ab, ab); + + if (clampToSegment) + mu = saturate(mu); + + float3 result = a + ab * mu; + return result; +} + +float RaySphereIntersection(float3 rayOrigin, float3 rayDirection, float3 center, float radius) +{ + float3 oc = rayOrigin - center; + + float a = dot(rayDirection, rayDirection); + float b = 2.0 * dot(oc, rayDirection); + float c = dot(oc, oc) - radius * radius; + float discriminant = b * b - 4 * a * c; + if (discriminant < 0){ + return -1.0f; + } + else{ + return (-b - sqrt(discriminant)) / (2.0f * a); + } +} + +struct CachedTri +{ + float4 vertex; + float4 edge0; + float4 edge1; + float4 data; + + void Cache(in float4 v1, + in float4 v2, + in float4 v3) + { + vertex = v1; + edge0 = v2 - v1; + edge1 = v3 - v1; + data = float4(0,0,0,0); + data[0] = dot(edge0, edge0); + data[1] = dot(edge0, edge1); + data[2] = dot(edge1, edge1); + data[3] = data[0] * data[2] - data[1] * data[1]; + } +}; + +float4 NearestPointOnTri(in CachedTri tri, + in float4 p, + out float4 bary) +{ + float4 v0 = tri.vertex - p; + float b0 = dot(tri.edge0, v0); + float b1 = dot(tri.edge1, v0); + float t0 = tri.data[1] * b1 - tri.data[2] * b0; + float t1 = tri.data[1] * b0 - tri.data[0] * b1; + + if (t0 + t1 <= tri.data[3]) + { + if (t0 < zero) + { + if (t1 < zero) // region 4 + { + if (b0 < zero) + { + t1 = zero; + if (-b0 >= tri.data[0]) // V0 + t0 = one; + else // E01 + t0 = -b0 / tri.data[0]; + } + else + { + t0 = zero; + if (b1 >= zero) // V0 + t1 = zero; + else if (-b1 >= tri.data[2]) // V2 + t1 = one; + else // E20 + t1 = -b1 / tri.data[2]; + } + } + else // region 3 + { + t0 = zero; + if (b1 >= zero) // V0 + t1 = zero; + else if (-b1 >= tri.data[2]) // V2 + t1 = one; + else // E20 + t1 = -b1 / tri.data[2]; + } + } + else if (t1 < zero) // region 5 + { + t1 = zero; + if (b0 >= zero) // V0 + t0 = zero; + else if (-b0 >= tri.data[0]) // V1 + t0 = one; + else // E01 + t0 = -b0 / tri.data[0]; + } + else // region 0, interior + { + float invDet = one / tri.data[3]; + t0 *= invDet; + t1 *= invDet; + } + } + else + { + float tmp0, tmp1, numer, denom; + + if (t0 < zero) // region 2 + { + tmp0 = tri.data[1] + b0; + tmp1 = tri.data[2] + b1; + if (tmp1 > tmp0) + { + numer = tmp1 - tmp0; + denom = tri.data[0] - 2 * tri.data[1] + tri.data[2]; + if (numer >= denom) // V1 + { + t0 = one; + t1 = zero; + } + else // E12 + { + t0 = numer / denom; + t1 = one - t0; + } + } + else + { + t0 = zero; + if (tmp1 <= zero) // V2 + t1 = one; + else if (b1 >= zero) // V0 + t1 = zero; + else // E20 + t1 = -b1 / tri.data[2]; + } + } + else if (t1 < zero) // region 6 + { + tmp0 = tri.data[1] + b1; + tmp1 = tri.data[0] + b0; + if (tmp1 > tmp0) + { + numer = tmp1 - tmp0; + denom = tri.data[0] - 2 * tri.data[1] + tri.data[2]; + if (numer >= denom) // V2 + { + t1 = one; + t0 = zero; + } + else // E12 + { + t1 = numer / denom; + t0 = one - t1; + } + } + else + { + t1 = zero; + if (tmp1 <= zero) // V1 + t0 = one; + else if (b0 >= zero) // V0 + t0 = zero; + else // E01 + t0 = -b0 / tri.data[0]; + } + } + else // region 1 + { + numer = tri.data[2] + b1 - tri.data[1] - b0; + if (numer <= zero) // V2 + { + t0 = zero; + t1 = one; + } + else + { + denom = tri.data[0] - 2 * tri.data[1] + tri.data[2]; + if (numer >= denom) // V1 + { + t0 = one; + t1 = zero; + } + else // 12 + { + t0 = numer / denom; + t1 = one - t0; + } + } + } + } + + bary = float4(1 - (t0 + t1), t0, t1,0); + return tri.vertex + t0 * tri.edge0 + t1 * tri.edge1; +} + +float3 unitOrthogonal(float3 input) +{ + // Find a vector to cross() the input with. + if (!(input.x < input.z * EPSILON) + || !(input.y < input.z * EPSILON)) + { + float invnm = 1 / length(input.xy); + return float3(-input.y * invnm, input.x * invnm, 0); + } + else + { + float invnm = 1 / length(input.yz); + return float3(0, -input.z * invnm, input.y * invnm); + } +} + +// D is symmetric, S is an eigen value +float3 EigenVector(float3x3 D, float S) +{ + // Compute a cofactor matrix of D - sI. + float3 c0 = D._m00_m10_m20; c0[0] -= S; + float3 c1 = D._m01_m11_m21; c1[1] -= S; + float3 c2 = D._m02_m12_m22; c2[2] -= S; + + // Upper triangular matrix + float3 c0p = float3(c1[1] * c2[2] - c2[1] * c2[1], 0, 0); + float3 c1p = float3(c2[1] * c2[0] - c1[0] * c2[2], c0[0] * c2[2] - c2[0] * c2[0], 0); + float3 c2p = float3(c1[0] * c2[1] - c1[1] * c2[0], c1[0] * c2[0] - c0[0] * c2[1], c0[0] * c1[1] - c1[0] * c1[0]); + + // Get a column vector with a largest norm (non-zero). + float C01s = c1p[0] * c1p[0]; + float C02s = c2p[0] * c2p[0]; + float C12s = c2p[1] * c2p[1]; + float3 norm = float3(c0p[0] * c0p[0] + C01s + C02s, + C01s + c1p[1] * c1p[1] + C12s, + C02s + C12s + c2p[2] * c2p[2]); + + // index of largest: + int index = 0; + if (norm[0] > norm[1] && norm[0] > norm[2]) + index = 0; + else if (norm[1] > norm[0] && norm[1] > norm[2]) + index = 1; + else + index = 2; + + float3 V = float3(0,0,0); + + // special case + if (norm[index] < EPSILON) + { + V[0] = 1; return V; + } + else if (index == 0) + { + V[0] = c0p[0]; V[1] = c1p[0]; V[2] = c2p[0]; + return normalize(V); + } + else if (index == 1) + { + V[0] = c1p[0]; V[1] = c1p[1]; V[2] = c2p[1]; + return normalize(V); + } + else + { + V = c2p; + return normalize(V); + } +} + +static float3 EigenValues(float3x3 D) +{ + float one_third = 1 / 3.0f; + float one_sixth = 1 / 6.0f; + float three_sqrt = sqrt(3.0f); + + float3 c0 = D._m00_m10_m20; + float3 c1 = D._m01_m11_m21; + float3 c2 = D._m02_m12_m22; + + float m = one_third * (c0[0] + c1[1] + c2[2]); + + // K is D - I*diag(S) + float K00 = c0[0] - m; + float K11 = c1[1] - m; + float K22 = c2[2] - m; + + float K01s = c1[0] * c1[0]; + float K02s = c2[0] * c2[0]; + float K12s = c2[1] * c2[1]; + + float q = 0.5f * (K00 * (K11 * K22 - K12s) - K22 * K01s - K11 * K02s) + c1[0] * c2[1] * c0[2]; + float p = one_sixth * (K00 * K00 + K11 * K11 + K22 * K22 + 2 * (K01s + K02s + K12s)); + + float p_sqrt = sqrt(p); + + float tmp = p * p * p - q * q; + float phi = one_third * atan2(sqrt(max(0, tmp)), q); + float phi_c = cos(phi); + float phi_s = sin(phi); + float sqrt_p_c_phi = p_sqrt * phi_c; + float sqrt_p_3_s_phi = p_sqrt * three_sqrt * phi_s; + + float e0 = m + 2 * sqrt_p_c_phi; + float e1 = m - sqrt_p_c_phi - sqrt_p_3_s_phi; + float e2 = m - sqrt_p_c_phi + sqrt_p_3_s_phi; + + float aux; + if (e0 > e1) + { + aux = e0; + e0 = e1; + e1 = aux; + } + if (e0 > e2) + { + aux = e0; + e0 = e2; + e2 = aux; + } + if (e1 > e2) + { + aux = e1; + e1 = e2; + e2 = aux; + } + + return float3(e2, e1, e0); +} + +void EigenSolve(float3x3 D, out float3 S, out float3x3 V) +{ + // D is symmetric + // S is a vector whose elements are eigenvalues + // V is a matrix whose columns are eigenvectors + S = EigenValues(D); + float3 V0, V1, V2; + + if (S[0] - S[1] > S[1] - S[2]) + { + V0 = EigenVector(D, S[0]); + if (S[1] - S[2] < EPSILON) + { + V2 = unitOrthogonal(V0); + } + else + { + V2 = EigenVector(D, S[2]); V2 -= V0 * dot(V0, V2); V2 = normalize(V2); + } + V1 = cross(V2, V0); + } + else + { + V2 = EigenVector(D, S[2]); + if (S[0] - S[1] < EPSILON) + { + V1 = unitOrthogonal(V2); + } + else + { + V1 = EigenVector(D, S[1]); V1 -= V2 * dot(V2, V1); V1 = normalize(V1); + } + V0 = cross(V1, V2); + } + + V._m00_m10_m20 = V0; + V._m01_m11_m21 = V1; + V._m02_m12_m22 = V2; +} + +float4 UnpackFloatRGBA(float v) +{ + uint rgba = asuint(v); + float r = ((rgba & 0xff000000) >> 24) / 255.0; + float g = ((rgba & 0x00ff0000) >> 16) / 255.0; + float b = ((rgba & 0x0000ff00) >> 8) / 255.0; + float a = (rgba & 0x000000ff) / 255.0; + return float4(r, g, b, a); +} + +float PackFloatRGBA(float4 enc) +{ + uint rgba = ((uint)(enc.x * 255.0) << 24) + + ((uint)(enc.y * 255.0) << 16) + + ((uint)(enc.z * 255.0) << 8) + + (uint)(enc.w * 255.0); + return asfloat(rgba); +} + +float2 UnpackFloatRG(float v) +{ + uint rgba = asuint(v); + float r = ((rgba & 0xffff0000) >> 16) / 65535.0; + float g = (rgba & 0x0000ffff) / 65535.0; + return float2(r, g); +} + +float PackFloatRG(float2 enc) +{ + uint rgba = ((uint)(enc.x * 65535.0) << 16) + + (uint)(enc.y * 65535.0); + return asfloat(rgba); +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/MathUtils.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/MathUtils.cginc.meta new file mode 100644 index 00000000..43b30e62 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/MathUtils.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 729e4f240dd344abfa1b0972b2ceb0ea +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/Matrix.cginc b/xiaofang/Assets/Obi/Resources/Compute/Matrix.cginc new file mode 100644 index 00000000..5a1bf98e --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Matrix.cginc @@ -0,0 +1,108 @@ +#ifndef MATRIX_INCLUDE +#define MATRIX_INCLUDE + +#define FLOAT4X4_IDENTITY float4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) +#define FLOAT3X3_IDENTITY float3x3(1, 0, 0, 0, 1, 0, 0, 0, 1) +#define FLOAT4X4_ZERO float4x4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) +#define FLOAT3X3_ZERO float3x3(0, 0, 0, 0, 0, 0, 0, 0, 0) + +#include "Quaternion.cginc" + +float4x4 Inverse(float4x4 m) +{ + float n11 = m[0][0], n12 = m[1][0], n13 = m[2][0], n14 = m[3][0]; + float n21 = m[0][1], n22 = m[1][1], n23 = m[2][1], n24 = m[3][1]; + float n31 = m[0][2], n32 = m[1][2], n33 = m[2][2], n34 = m[3][2]; + float n41 = m[0][3], n42 = m[1][3], n43 = m[2][3], n44 = m[3][3]; + + float t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44; + float t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44; + float t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44; + float t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; + + float det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; + float idet = 1.0f / det; + + float4x4 ret; + + ret[0][0] = t11 * idet; + ret[0][1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * idet; + ret[0][2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * idet; + ret[0][3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * idet; + + ret[1][0] = t12 * idet; + ret[1][1] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * idet; + ret[1][2] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * idet; + ret[1][3] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * idet; + + ret[2][0] = t13 * idet; + ret[2][1] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * idet; + ret[2][2] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * idet; + ret[2][3] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * idet; + + ret[3][0] = t14 * idet; + ret[3][1] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * idet; + ret[3][2] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * idet; + ret[3][3] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * idet; + + return ret; +} + +float4x4 m_scale(float4x4 m, float3 v) +{ + float x = v.x, y = v.y, z = v.z; + + m[0][0] *= x; m[1][0] *= y; m[2][0] *= z; + m[0][1] *= x; m[1][1] *= y; m[2][1] *= z; + m[0][2] *= x; m[1][2] *= y; m[2][2] *= z; + m[0][3] *= x; m[1][3] *= y; m[2][3] *= z; + + return m; +} + +float4x4 m_translate(float4x4 m, float3 v) +{ + float x = v.x, y = v.y, z = v.z; + m[0][3] = x; + m[1][3] = y; + m[2][3] = z; + return m; +} + +float4x4 TRS(float3 position, float4 quat, float3 scale) +{ + float4x4 m = q_toMatrix(quat); + return float4x4(m[0][0] * scale.x, m[0][1] * scale.y, m[0][2] * scale.z, position.x, + m[1][0] * scale.x, m[1][1] * scale.y, m[1][2] * scale.z, position.y, + m[2][0] * scale.x, m[2][1] * scale.y, m[2][2] * scale.z, position.z, + 0, 0, 0, 1); +} + +float4x4 AsDiagonal(in float4 v) +{ + return float4x4(v.x, 0, 0, 0, + 0, v.y, 0, 0, + 0, 0, v.z, 0, + 0, 0, 0, v.w); +} + +float3x3 multrnsp(in float4 column, in float4 row) +{ + return float3x3(row.xyz * column[0],row.xyz * column[1],row.xyz * column[2]); +} + +float4x4 multrnsp4(in float4 column, float4 row) +{ + row[3] = 0; + return float4x4(row * column[0],row * column[1],row * column[2], float4(0,0,0,0)); +} + +float FrobeniusNorm(in float4x4 m) +{ + return sqrt(dot(m._m00_m10_m20_m30,m._m00_m10_m20_m30) + + dot(m._m01_m11_m21_m31,m._m01_m11_m21_m31) + + dot(m._m02_m12_m22_m32,m._m02_m12_m22_m32) + + dot(m._m03_m13_m23_m33,m._m03_m13_m23_m33)); +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/Matrix.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/Matrix.cginc.meta new file mode 100644 index 00000000..d6fefdd9 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Matrix.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 80cddbfae548f433a93a4e6e7a10b089 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/NormalCompression.cginc b/xiaofang/Assets/Obi/Resources/Compute/NormalCompression.cginc new file mode 100644 index 00000000..4fcc93d0 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/NormalCompression.cginc @@ -0,0 +1,32 @@ +#ifndef NORMALCOMPRESSION_INCLUDE +#define NORMALCOMPRESSION_INCLUDE + +float2 octWrap( float2 v ) +{ + return ( 1.0 - abs( v.yx ) ) * ( v.xy >= 0.0 ? 1.0 : -1.0 ); +} + +// use octahedral encoding to reduce to 2 coords, then pack them as two 16 bit values in a 32 bit float. +float encode( float3 n ) +{ + n /= ( abs( n.x ) + abs( n.y ) + abs( n.z ) ); + n.xy = n.z >= 0.0 ? n.xy : octWrap( n.xy ); + n.xy = n.xy * 0.5 + 0.5; + uint nx = (uint)(n.x * 0xffff); + uint ny = (uint)(n.y * 0xffff); + return asfloat((nx << 16) | (ny & 0xffff)); +} + +// unpack 32 bit float into two 16 bit ones, then use octahedral decoding. +float3 decode( float k ) +{ + uint d = asuint(k); + float2 f = float2((d >> 16) / 65535.0, (d & 0xffff) / 65535.0) * 2.0 - 1.0; + + float3 n = float3( f.x, f.y, 1.0 - abs( f.x ) - abs( f.y ) ); + float t = saturate( -n.z ); + n.xy += n.xy >= 0.0 ? -t : t; + return normalize( n ); +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/NormalCompression.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/NormalCompression.cginc.meta new file mode 100644 index 00000000..d98da818 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/NormalCompression.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d05e07f20b7784bac93ad5818826c787 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/Optimization.cginc b/xiaofang/Assets/Obi/Resources/Compute/Optimization.cginc new file mode 100644 index 00000000..dbc54cd9 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Optimization.cginc @@ -0,0 +1,126 @@ +#ifndef OPTIMIZATION_INCLUDE +#define OPTIMIZATION_INCLUDE + +#include "MathUtils.cginc" +#include "SurfacePoint.cginc" + +void GetInterpolatedSimplexData(in int simplexStart, + in int simplexSize, + StructuredBuffer simplices, + StructuredBuffer positions, + StructuredBuffer orientations, + StructuredBuffer radii, + float4 convexBary, + inout float4 convexPoint, + inout float4 convexRadii, + inout float4 convexOrientation) +{ + convexPoint = FLOAT4_ZERO; + convexRadii = FLOAT4_ZERO; + convexOrientation = quaternion(0, 0, 0, 0); + for (int j = 0; j < simplexSize; ++j) + { + int particle = simplices[simplexStart + j]; + convexPoint += positions[particle] * convexBary[j]; + convexRadii += radii[particle] * convexBary[j]; + convexOrientation += orientations[particle] * convexBary[j]; + } + convexPoint.w = 0; +} + +// Frank-Wolfe convex optimization algorithm. Returns closest point to a simplex in a signed distance function. +void FrankWolfe(in IDistanceFunction f, + in int simplexStart, + in int simplexSize, + StructuredBuffer positions, + StructuredBuffer orientations, + StructuredBuffer radii, + StructuredBuffer simplices, + inout float4 convexPoint, + inout float4 convexThickness, + inout quaternion convexOrientation, + inout float4 convexBary, + inout SurfacePoint pointInFunction, + int maxIterations, + float tolerance) +{ + for (int i = 0; i < maxIterations; ++i) + { + // sample target function: + f.Evaluate(convexPoint, convexThickness, convexOrientation, pointInFunction); + + // find descent direction: + int descent = 0; + float gap = FLT_MIN; + for (int j = 0; j < simplexSize; ++j) + { + int particle = simplices[simplexStart + j]; + float4 candidate = positions[particle] - convexPoint; + candidate.w = 0; + + // here, we adjust the candidate by projecting it to the engrosed simplex's surface: + candidate -= pointInFunction.normal * (radii[particle].x - convexThickness.x); + + float corr = dot(-pointInFunction.normal, candidate); + if (corr > gap) + { + descent = j; + gap = corr; + } + } + + // if the duality gap is below tolerance threshold, stop iterating. + if (gap < tolerance) + break; + + // update the barycentric coords using 2/(i+2) as the step factor + float stp = 0.3f * 2.0f / (i + 2); + convexBary *= 1 - stp; + switch(descent) + { + case 0: convexBary[0] += stp;break; + case 1: convexBary[1] += stp;break; + case 2: convexBary[2] += stp;break; + case 3: convexBary[3] += stp;break; + } + + // get cartesian coordinates of current solution: + GetInterpolatedSimplexData(simplexStart, simplexSize, simplices, positions, orientations, radii, convexBary, convexPoint, convexThickness, convexOrientation); + } +} + +SurfacePoint Optimize(in IDistanceFunction f, + StructuredBuffer positions, + StructuredBuffer orientations, + StructuredBuffer radii, + StructuredBuffer simplices, + in int simplexStart, + in int simplexSize, + inout float4 convexBary, + out float4 convexPoint, + in int maxIterations = 16, + in float tolerance = 0.004f) +{ + SurfacePoint pointInFunction; + + // get cartesian coordinates of the initial guess: + float4 convexThickness; + quaternion convexOrientation; + GetInterpolatedSimplexData(simplexStart, simplexSize, simplices, positions, orientations, radii, convexBary, convexPoint, convexThickness, convexOrientation); + + // for a 0-simplex (point), perform a single evaluation: + if (simplexSize == 1 || maxIterations < 1) + f.Evaluate(convexPoint, convexThickness, convexOrientation, pointInFunction); + + // for a 1-simplex (edge), perform golden ratio search: + //else if (simplexSize == 2) + // GoldenSearch(ref function, simplexStart, simplexSize, positions, orientations, radii, simplices, ref convexPoint, ref convexThickness, ref convexOrientation, ref convexBary, ref pointInFunction, maxIterations, tolerance * 10); + + // for higher-order simplices, use general Frank-Wolfe convex optimization: + else + FrankWolfe(f, simplexStart, simplexSize, positions, orientations, radii, simplices, convexPoint, convexThickness, convexOrientation, convexBary, pointInFunction, maxIterations, tolerance); + + return pointInFunction; +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/Optimization.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/Optimization.cginc.meta new file mode 100644 index 00000000..fe513de1 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Optimization.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e10fb000e4ce24365adc488a45bbe664 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/ParticleCollisionConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/ParticleCollisionConstraints.compute new file mode 100644 index 00000000..66fd25b6 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ParticleCollisionConstraints.compute @@ -0,0 +1,189 @@ +#pragma kernel Initialize +#pragma kernel Project +#pragma kernel Apply + +#include "ContactHandling.cginc" +#include "ColliderDefinitions.cginc" +#include "CollisionMaterial.cginc" +#include "Simplex.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer particleIndices; + +StructuredBuffer simplices; +StructuredBuffer invMasses; +StructuredBuffer invRotationalMasses; +StructuredBuffer principalRadii; +StructuredBuffer velocities; +StructuredBuffer prevPositions; +StructuredBuffer prevOrientations; +StructuredBuffer orientations; + +RWStructuredBuffer positions; +RWStructuredBuffer deltas; + +// Vulkan workaround: don't declare a RW array after a counter/append one (particleContacts) since the counter overlaps the first entry in the next array. +RWStructuredBuffer effectiveMasses; +RWStructuredBuffer particleContacts; +StructuredBuffer dispatchBuffer; + +// Variables set from the CPU +uint particleCount; +float deltaTime; +float shockPropagation; +float4 gravity; +float sorFactor; + +[numthreads(128, 1, 1)] +void Initialize (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= dispatchBuffer[3]) return; + + int simplexSizeA; + int simplexSizeB; + int simplexStartA = GetSimplexStartAndSize(particleContacts[i].bodyA, simplexSizeA); + int simplexStartB = GetSimplexStartAndSize(particleContacts[i].bodyB, simplexSizeB); + + float4 simplexVelocityA = float4(0,0,0,0); + float4 simplexPrevPositionA = float4(0,0,0,0); + quaternion simplexPrevOrientationA = quaternion(0, 0, 0, 0); + float simplexRadiusA = 0; + float simplexInvMassA = 0; + float simplexInvRotationalMassA = 0; + + float4 simplexVelocityB = float4(0,0,0,0); + float4 simplexPrevPositionB = float4(0,0,0,0); + quaternion simplexPrevOrientationB = quaternion(0, 0, 0, 0); + float simplexRadiusB = 0; + float simplexInvMassB = 0; + float simplexInvRotationalMassB = 0; + + int j = 0; + for (j = 0; j < simplexSizeA; ++j) + { + int particleIndex = simplices[simplexStartA + j]; + simplexVelocityA += velocities[particleIndex] * particleContacts[i].pointA[j]; + simplexPrevPositionA += prevPositions[particleIndex] * particleContacts[i].pointA[j]; + simplexPrevOrientationA += prevOrientations[particleIndex] * particleContacts[i].pointA[j]; + simplexInvMassA += invMasses[particleIndex] * particleContacts[i].pointA[j]; + simplexInvRotationalMassA += invRotationalMasses[particleIndex] * particleContacts[i].pointA[j]; + simplexRadiusA += EllipsoidRadius(particleContacts[i].normal, prevOrientations[particleIndex], principalRadii[particleIndex].xyz) * particleContacts[i].pointA[j]; + } + + for (j = 0; j < simplexSizeB; ++j) + { + int particleIndex = simplices[simplexStartB + j]; + simplexVelocityB += velocities[particleIndex] * particleContacts[i].pointB[j]; + simplexPrevPositionB += prevPositions[particleIndex] * particleContacts[i].pointB[j]; + simplexPrevOrientationB += prevOrientations[particleIndex] * particleContacts[i].pointB[j]; + simplexInvMassB += invMasses[particleIndex] * particleContacts[i].pointB[j]; + simplexInvRotationalMassB += invRotationalMasses[particleIndex] * particleContacts[i].pointB[j]; + simplexRadiusB += EllipsoidRadius(particleContacts[i].normal, prevOrientations[particleIndex], principalRadii[particleIndex].xyz) * particleContacts[i].pointB[j]; + } + + simplexPrevPositionA.w = 0; + simplexPrevPositionB.w = 0; + + // update contact distance + float dAB = dot(simplexPrevPositionA - simplexPrevPositionB, particleContacts[i].normal); + particleContacts[i].dist = dAB - (simplexRadiusA + simplexRadiusB); + + // calculate contact points: + float4 contactPointA = simplexPrevPositionB + particleContacts[i].normal * (particleContacts[i].dist + simplexRadiusB); + float4 contactPointB = simplexPrevPositionA - particleContacts[i].normal * (particleContacts[i].dist + simplexRadiusA); + + // update contact basis: + CalculateBasis(simplexVelocityA - simplexVelocityB, particleContacts[i].normal,particleContacts[i].tangent); + + // update contact masses: + int aMaterialIndex = collisionMaterialIndices[simplices[simplexStartA]]; + int bMaterialIndex = collisionMaterialIndices[simplices[simplexStartB]]; + bool rollingContacts = (aMaterialIndex >= 0 ? collisionMaterials[aMaterialIndex].rollingContacts > 0 : false) | + (bMaterialIndex >= 0 ? collisionMaterials[bMaterialIndex].rollingContacts > 0 : false); + + float4 invInertiaTensorA = 1.0/(GetParticleInertiaTensor(simplexRadiusA, simplexInvRotationalMassA) + FLOAT4_EPSILON); + float4 invInertiaTensorB = 1.0/(GetParticleInertiaTensor(simplexRadiusB, simplexInvRotationalMassB) + FLOAT4_EPSILON); + + float4 bitangent = GetBitangent(particleContacts[i]); + CalculateContactMassesA(simplexInvMassA, invInertiaTensorA, simplexPrevPositionA, simplexPrevOrientationA, contactPointA, rollingContacts, particleContacts[i].normal,particleContacts[i].tangent,bitangent, effectiveMasses[i].normalInvMassA, effectiveMasses[i].tangentInvMassA, effectiveMasses[i].bitangentInvMassA); + CalculateContactMassesB(simplexInvMassB, invInertiaTensorB, simplexPrevPositionB, simplexPrevOrientationB, contactPointB, rollingContacts, particleContacts[i].normal,particleContacts[i].tangent,bitangent, effectiveMasses[i].normalInvMassB, effectiveMasses[i].tangentInvMassB, effectiveMasses[i].bitangentInvMassB); +} + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= dispatchBuffer[3]) return; + + int simplexSizeA; + int simplexSizeB; + int simplexStartA = GetSimplexStartAndSize(particleContacts[i].bodyA, simplexSizeA); + int simplexStartB = GetSimplexStartAndSize(particleContacts[i].bodyB, simplexSizeB); + + float4 simplexPositionA = float4(0,0,0,0), simplexPositionB = float4(0,0,0,0); + float simplexRadiusA = 0, simplexRadiusB = 0; + + int j = 0; + for (j = 0; j < simplexSizeA; ++j) + { + int particleIndex = simplices[simplexStartA + j]; + simplexPositionA += positions[particleIndex] * particleContacts[i].pointA[j]; + simplexRadiusA += EllipsoidRadius(particleContacts[i].normal, orientations[particleIndex], principalRadii[particleIndex].xyz) * particleContacts[i].pointA[j]; + } + for (j = 0; j < simplexSizeB; ++j) + { + int particleIndex = simplices[simplexStartB + j]; + simplexPositionB += positions[particleIndex] * particleContacts[i].pointB[j]; + simplexRadiusB += EllipsoidRadius(particleContacts[i].normal, orientations[particleIndex], principalRadii[particleIndex].xyz) * particleContacts[i].pointA[j]; + } + + simplexPositionA.w = 0; + simplexPositionB.w = 0; + + float4 posA = simplexPositionA - particleContacts[i].normal * simplexRadiusA; + float4 posB = simplexPositionB + particleContacts[i].normal * simplexRadiusB; + + float normalInvMass = effectiveMasses[i].normalInvMassA + effectiveMasses[i].normalInvMassB; + + float lambda = SolvePenetration(particleContacts[i], normalInvMass, posA, posB, 10); + + if (abs(lambda) > EPSILON) + { + float shock = shockPropagation * dot(particleContacts[i].normal, normalizesafe(gravity)); + float4 delta = lambda * particleContacts[i].normal; + + float baryScale = BaryScale(particleContacts[i].pointA); + for (j = 0; j < simplexSizeA; ++j) + { + int particleIndex = simplices[simplexStartA + j]; + float4 delta1 = delta * invMasses[particleIndex] * particleContacts[i].pointA[j] * baryScale * (1 - shock); + AtomicAddPositionDelta(particleIndex, delta1); + } + + baryScale = BaryScale(particleContacts[i].pointB); + for (j = 0; j < simplexSizeB; ++j) + { + int particleIndex = simplices[simplexStartB + j]; + float4 delta2 = -delta * invMasses[particleIndex] * particleContacts[i].pointB[j] * baryScale * (1 + shock); + AtomicAddPositionDelta(particleIndex, delta2); + } + } +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int threadIndex = id.x; + + if (threadIndex >= particleCount) return; + + int p = particleIndices[threadIndex]; + + ApplyPositionDelta(positions, p, sorFactor); + +} + + diff --git a/xiaofang/Assets/Obi/Resources/Compute/ParticleCollisionConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/ParticleCollisionConstraints.compute.meta new file mode 100644 index 00000000..e53cfc74 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ParticleCollisionConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 770004596b21f49118a60c5ad181940c +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/ParticleFrictionConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/ParticleFrictionConstraints.compute new file mode 100644 index 00000000..13c92607 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ParticleFrictionConstraints.compute @@ -0,0 +1,187 @@ +#pragma kernel Project +#pragma kernel Apply + +#include "ContactHandling.cginc" +#include "Integration.cginc" +#include "CollisionMaterial.cginc" +#include "Simplex.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer particleIndices; +StructuredBuffer simplices; +StructuredBuffer prevPositions; +StructuredBuffer prevOrientations; +StructuredBuffer invMasses; +StructuredBuffer invRotationalMasses; +StructuredBuffer principalRadii; + +RWStructuredBuffer positions; +RWStructuredBuffer orientations; +RWStructuredBuffer deltas; + +RWStructuredBuffer particleContacts; +RWStructuredBuffer effectiveMasses; +StructuredBuffer dispatchBuffer; + +// Variables set from the CPU +uint particleCount; +float substepTime; +float stepTime; +float sorFactor; + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= dispatchBuffer[3]) return; + + int simplexSizeA; + int simplexSizeB; + int simplexStartA = GetSimplexStartAndSize(particleContacts[i].bodyA, simplexSizeA); + int simplexStartB = GetSimplexStartAndSize(particleContacts[i].bodyB, simplexSizeB); + + // Combine collision materials (use material from first particle in simplex) + collisionMaterial material = CombineCollisionMaterials(collisionMaterialIndices[simplices[simplexStartA]], + collisionMaterialIndices[simplices[simplexStartB]]); + + float4 prevPositionA = float4(0,0,0,0); + float4 linearVelocityA = float4(0,0,0,0); + float4 angularVelocityA = float4(0,0,0,0); + float invRotationalMassA = 0; + quaternion orientationA = quaternion(0, 0, 0, 0); + float simplexRadiusA = 0; + + float4 prevPositionB = float4(0,0,0,0); + float4 linearVelocityB = float4(0,0,0,0); + float4 angularVelocityB = float4(0,0,0,0); + float invRotationalMassB = 0; + quaternion orientationB = quaternion(0, 0, 0, 0); + float simplexRadiusB = 0; + + int j = 0; + for (j = 0; j < simplexSizeA; ++j) + { + int particleIndex = simplices[simplexStartA + j]; + prevPositionA += prevPositions[particleIndex] * particleContacts[i].pointA[j]; + linearVelocityA += DifferentiateLinear(positions[particleIndex], prevPositions[particleIndex], substepTime) * particleContacts[i].pointA[j]; + angularVelocityA += DifferentiateAngular(orientations[particleIndex], prevOrientations[particleIndex], substepTime) * particleContacts[i].pointA[j]; + invRotationalMassA += invRotationalMasses[particleIndex] * particleContacts[i].pointA[j]; + orientationA += orientations[particleIndex] * particleContacts[i].pointA[j]; + simplexRadiusA += EllipsoidRadius(particleContacts[i].normal, prevOrientations[particleIndex], principalRadii[particleIndex].xyz) * particleContacts[i].pointA[j]; + } + + for (j = 0; j < simplexSizeB; ++j) + { + int particleIndex = simplices[simplexStartB + j]; + prevPositionB += prevPositions[particleIndex] * particleContacts[i].pointB[j]; + linearVelocityB += DifferentiateLinear(positions[particleIndex], prevPositions[particleIndex], substepTime) * particleContacts[i].pointB[j]; + angularVelocityB += DifferentiateAngular(orientations[particleIndex], prevOrientations[particleIndex], substepTime) * particleContacts[i].pointB[j]; + invRotationalMassB += invRotationalMasses[particleIndex] * particleContacts[i].pointB[j]; + orientationB += orientations[particleIndex] * particleContacts[i].pointB[j]; + simplexRadiusB += EllipsoidRadius(particleContacts[i].normal, prevOrientations[particleIndex], principalRadii[particleIndex].xyz) * particleContacts[i].pointB[j]; + } + + float4 rA = FLOAT4_ZERO; + float4 rB = FLOAT4_ZERO; + + // Consider angular velocities if rolling contacts are enabled: + if (material.rollingContacts > 0) + { + rA = -particleContacts[i].normal * simplexRadiusA; + rB = particleContacts[i].normal * simplexRadiusB; + + linearVelocityA += float4(cross(angularVelocityA.xyz, rA.xyz), 0); + linearVelocityB += float4(cross(angularVelocityB.xyz, rB.xyz), 0); + } + + // Calculate relative velocity: + float4 relativeVelocity = linearVelocityA - linearVelocityB; + + // Determine impulse magnitude: + float tangentMass = effectiveMasses[i].tangentInvMassA + effectiveMasses[i].tangentInvMassB; + float bitangentMass = effectiveMasses[i].bitangentInvMassA + effectiveMasses[i].bitangentInvMassB; + float2 impulses = SolveFriction(particleContacts[i],tangentMass,bitangentMass,relativeVelocity, material.staticFriction, material.dynamicFriction, stepTime); + + if (abs(impulses.x) > EPSILON || abs(impulses.y) > EPSILON) + { + float4 tangentImpulse = impulses.x * particleContacts[i].tangent; + float4 bitangentImpulse = impulses.y * GetBitangent(particleContacts[i]); + float4 totalImpulse = tangentImpulse + bitangentImpulse; + + float baryScale = BaryScale(particleContacts[i].pointA); + for (j = 0; j < simplexSizeA; ++j) + { + int particleIndex = simplices[simplexStartA + j]; + float4 delta1 = (tangentImpulse * effectiveMasses[i].tangentInvMassA + bitangentImpulse * effectiveMasses[i].bitangentInvMassA) * substepTime * particleContacts[i].pointA[j] * baryScale; + AtomicAddPositionDelta(particleIndex, delta1); + } + + baryScale = BaryScale(particleContacts[i].pointB); + for (j = 0; j < simplexSizeB; ++j) + { + int particleIndex = simplices[simplexStartB + j]; + float4 delta2 = -(tangentImpulse * effectiveMasses[i].tangentInvMassB + bitangentImpulse * effectiveMasses[i].bitangentInvMassB) * substepTime * particleContacts[i].pointB[j] * baryScale; + AtomicAddPositionDelta(particleIndex, delta2); + } + + // Rolling contacts: + if (material.rollingContacts > 0) + { + float4 invInertiaTensorA = 1.0/(GetParticleInertiaTensor(simplexRadiusA, invRotationalMassA) + FLOAT4_EPSILON); + float4 invInertiaTensorB = 1.0/(GetParticleInertiaTensor(simplexRadiusB, invRotationalMassB) + FLOAT4_EPSILON); + + // Calculate angular velocity deltas due to friction impulse: + float4x4 solverInertiaA = TransformInertiaTensor(invInertiaTensorA, orientationA); + float4x4 solverInertiaB = TransformInertiaTensor(invInertiaTensorB, orientationB); + + float4 angVelDeltaA = mul(solverInertiaA, float4(cross(rA.xyz, totalImpulse.xyz), 0)); + float4 angVelDeltaB = -mul(solverInertiaB, float4(cross(rB.xyz, totalImpulse.xyz), 0)); + + // Final angular velocities, after adding the deltas: + angularVelocityA += angVelDeltaA; + angularVelocityB += angVelDeltaB; + + // Calculate weights (inverse masses): + float invMassA = length(mul(solverInertiaA, normalizesafe(angularVelocityA))); + float invMassB = length(mul(solverInertiaB, normalizesafe(angularVelocityB))); + + // Calculate rolling axis and angular velocity deltas: + float4 rollAxis = FLOAT4_ZERO; + float rollingImpulse = SolveRollingFriction(particleContacts[i],angularVelocityA, angularVelocityB, material.rollingFriction, invMassA, invMassB, rollAxis); + angVelDeltaA += rollAxis * rollingImpulse * invMassA; + angVelDeltaB -= rollAxis * rollingImpulse * invMassB; + + // Apply orientation deltas to particles: + quaternion orientationDeltaA = AngularVelocityToSpinQuaternion(orientationA, angVelDeltaA, substepTime); + quaternion orientationDeltaB = AngularVelocityToSpinQuaternion(orientationB, angVelDeltaB, substepTime); + + for (j = 0; j < simplexSizeA; ++j) + { + int particleIndex = simplices[simplexStartA + j]; + AtomicAddOrientationDelta(particleIndex, orientationDeltaA); + } + + for (j = 0; j < simplexSizeB; ++j) + { + int particleIndex = simplices[simplexStartB + j]; + AtomicAddOrientationDelta(particleIndex, orientationDeltaB); + } + } + } +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int threadIndex = id.x; + + if (threadIndex >= particleCount) return; + + int p = particleIndices[threadIndex]; + + ApplyPositionDelta(positions, p, sorFactor); + ApplyOrientationDelta(orientations, p, sorFactor); +} + + diff --git a/xiaofang/Assets/Obi/Resources/Compute/ParticleFrictionConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/ParticleFrictionConstraints.compute.meta new file mode 100644 index 00000000..48a2a4d3 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ParticleFrictionConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bd14011b19e9c47d1964f351a7ed4df7 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/ParticleGrid.compute b/xiaofang/Assets/Obi/Resources/Compute/ParticleGrid.compute new file mode 100644 index 00000000..bc640844 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ParticleGrid.compute @@ -0,0 +1,600 @@ +#include "GridUtils.cginc" +#include "CollisionMaterial.cginc" +#include "ColliderDefinitions.cginc" +#include "ContactHandling.cginc" +#include "SolverParameters.cginc" +#include "Simplex.cginc" +#include "Phases.cginc" +#include "Bounds.cginc" +#include "Simplex.cginc" + +#pragma kernel Clear +#pragma kernel InsertSimplices +#pragma kernel FindPopulatedLevels +#pragma kernel SortSimplices +#pragma kernel BuildFluidDispatch +#pragma kernel SortFluidSimplices +#pragma kernel BuildMortonIndices +#pragma kernel MortonSort +#pragma kernel FindFluidNeighborsInSameLevel +#pragma kernel FindFluidNeighborsInUpperLevels +#pragma kernel BuildContactList + +StructuredBuffer solverBounds; +StructuredBuffer simplexBounds; +StructuredBuffer simplices; // particle indices in each simplex. + +StructuredBuffer positions; +StructuredBuffer restPositions; +StructuredBuffer principalRadii; +StructuredBuffer fluidMaterials; +StructuredBuffer fluidInterface; +StructuredBuffer normals; + +StructuredBuffer orientations; +StructuredBuffer restOrientations; + +StructuredBuffer velocities; +StructuredBuffer invMasses; +StructuredBuffer phases; +StructuredBuffer filters; + +StructuredBuffer R_cellCoords; // for each item, its cell coordinates. +StructuredBuffer R_offsetInCell; // for each item, its offset within the cell. +StructuredBuffer R_cellOffsets; // start of each cell in the sorted item array. +StructuredBuffer R_cellCounts; // number of item in each cell. +StructuredBuffer R_levelPopulation; + +RWStructuredBuffer cellCoords; // for each item, its cell coordinates. +RWStructuredBuffer offsetInCell; // for each item, its offset within the cell. +RWStructuredBuffer cellOffsets; // start of each cell in the sorted item array. +RWStructuredBuffer cellCounts; // number of item in each cell. + +RWStructuredBuffer cellHashToMortonIndex; + +RWStructuredBuffer mortonSortedCellHashes; +RWStructuredBuffer sortedSimplexToFluid; // fluidSimplices +RWStructuredBuffer sortedFluidIndices; +RWStructuredBuffer sortedSimplexIndices; + +RWStructuredBuffer sortedPositions; +RWStructuredBuffer sortedFluidMaterials; +RWStructuredBuffer sortedFluidInterface; +RWStructuredBuffer sortedPrincipalRadii; + +RWStructuredBuffer neighbors; +RWStructuredBuffer neighborCounts; + +RWStructuredBuffer particleContacts; +RWStructuredBuffer contactPairs; + +RWStructuredBuffer fluidDispatchBuffer; +RWStructuredBuffer dispatchBuffer; + +RWStructuredBuffer colors; + +uint maxContacts; +uint maxNeighbors; +uint fluidParticleCount; +float deltaTime; + +const uint groupWidth; +const uint groupHeight; +const uint stepIndex; + +/** +For each cell, calculate coords and morton. This only works if there’s no collisions, so use the coord of one random particle that maps to that cell: + +For each simplex: +Determine cell coords (any particle in it will do) and hash, store in array per cell. Sort array by morton(coords), create array that maps from cell hash to morton index, then use as cellCounts[mortonIndex]. + +This way we have sorted particles and cells, and can use for fluid surface. Win win!! +*/ + +[numthreads(128, 1, 1)] +void Clear (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= maxCells) + return; + + if (i == 0) + { + for (int l = 0; l <= GRID_LEVELS; ++l) + levelPopulation[l] = 0; + } + + // clear all cell counts to zero, and cell offsets to invalid. + cellOffsets[i] = INVALID; + cellCounts[i] = 0; + mortonSortedCellHashes[i] = i; +} + +[numthreads(128, 1, 1)] +void InsertSimplices (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= pointCount + edgeCount + triangleCount) return; + + // calculate simplex cell index: + int level = GridLevelForSize(simplexBounds[i].MaxAxisLength()); + float cellSize = CellSizeOfLevel(level); + int4 cellCoord = int4(floor((simplexBounds[i].Center() - solverBounds[0].min_)/ cellSize).xyz,level); + + // if the solver is 2D, project to the z = 0 cell. + if (mode == 1) cellCoord[2] = 0; + + // insert simplex in cell: + uint cellIndex = GridHash(cellCoord); + cellCoords[i] = cellCoord; + InterlockedAdd(cellCounts[cellIndex],1,offsetInCell[i]); + + // assign minimum morton code to cell + // (there may be hash collisions mapping two coordinates to the same cell, that's why we use atomic minimum) + float mortonCellSize = solverBounds[0].MaxAxisLength() / 1024.0; + uint morton = EncodeMorton3(floor((simplexBounds[i].Center() - solverBounds[0].min_).xyz / mortonCellSize)); + InterlockedMin(cellOffsets[cellIndex], morton); + + // clear neighbor count: + neighborCounts[i] = 0; + + // atomically increase this level's population by one: + InterlockedAdd(levelPopulation[1 + level],1); +} + +[numthreads(128,1,1)] +void MortonSort(uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + uint hIndex = i & (groupWidth - 1); + uint indexLeft = hIndex + (groupHeight + 1) * (i / groupWidth); + uint rightStepSize = stepIndex == 0 ? groupHeight - 2 * hIndex : (groupHeight + 1) / 2; + uint indexRight = indexLeft + rightStepSize; + + // Exit if out of bounds + if (indexRight >= maxCells) return; + + // get morton index for both cells: + uint mortonL = cellOffsets[indexLeft]; + uint mortonR = cellOffsets[indexRight]; + + // get cell counts: + uint simplexIndexL = cellCounts[indexLeft]; + uint simplexIndexR = cellCounts[indexRight]; + + uint orderL = mortonSortedCellHashes[indexLeft]; + uint orderR = mortonSortedCellHashes[indexRight]; + + // Swap entries if order is incorrect + if (mortonL > mortonR) + { + cellCounts[indexLeft] = simplexIndexR; + cellCounts[indexRight] = simplexIndexL; + + cellOffsets[indexLeft] = mortonR; + cellOffsets[indexRight] = mortonL; + + mortonSortedCellHashes[indexLeft] = orderR; + mortonSortedCellHashes[indexRight] = orderL; + } +} + +[numthreads(128,1,1)] +void BuildMortonIndices(uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= maxCells) return; + + // build map from cell hash to index in morton-sorted cell data. + int index = mortonSortedCellHashes[i]; + cellHashToMortonIndex[index] = i; +} + +[numthreads(128, 1, 1)] +void SortSimplices (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + if (i >= pointCount + edgeCount + triangleCount) return; + + // write simplex index to its index in the grid: + uint cellIndex = cellHashToMortonIndex[GridHash(R_cellCoords[i])]; + uint gridIndex = R_cellOffsets[cellIndex] + R_offsetInCell[i]; + sortedSimplexIndices[gridIndex] = i; // maps from index in grid to simplex index. + + // flag fluid simplices with 1. we'll later do a prefix sum of this array + // to get a compact list of grid-sorted fluid indices. + int size; + int p = simplices[GetSimplexStartAndSize(i, size)]; + sortedFluidIndices[gridIndex] = ((phases[p] & Fluid) != 0) ? 1:0; +} + +[numthreads(1, 1, 1)] +void BuildFluidDispatch (uint3 id : SV_DispatchThreadID) +{ + // since we are using *exclusive* prefix sum, + // we must add the last entries of both buffers together to get total count of fluid simplices. + + int lastEntry = pointCount + edgeCount + triangleCount - 1; + fluidDispatchBuffer[3] = sortedSimplexToFluid[lastEntry] + sortedFluidIndices[lastEntry]; + fluidDispatchBuffer[0] = fluidDispatchBuffer[3] / 128 + 1; +} + +[numthreads(128, 1, 1)] +void SortFluidSimplices (uint3 id : SV_DispatchThreadID) //rename to sort fluid data. +{ + // check all simplices. + uint i = id.x; + if (i >= pointCount + edgeCount + triangleCount) return; + + uint cellIndex = cellHashToMortonIndex[GridHash(R_cellCoords[i])]; + uint gridIndex = R_cellOffsets[cellIndex] + R_offsetInCell[i]; + + // copy the data of first particle in each fluid simplex to sorted arrays + // using prefix sum results: same as grid order, but contiguous. + int size; + int p = simplices[GetSimplexStartAndSize(i, size)]; + + if ((phases[p] & Fluid) != 0) + { + int fluidIndex = sortedSimplexToFluid[gridIndex]; + sortedFluidIndices[fluidIndex] = i; + + sortedPositions[fluidIndex] = positions[p]; + sortedFluidMaterials[fluidIndex] = fluidMaterials[p]; + sortedFluidInterface[fluidIndex] = fluidInterface[p]; + sortedPrincipalRadii[fluidIndex] = principalRadii[p]; + } + else + sortedSimplexToFluid[gridIndex] = -1; +} + +int GetSimplexGroup(in int simplexStart,in int simplexSize, out int flags, out int category, out int mask, out bool restPositionsEnabled) +{ + flags = 0; + int group = 0; + category = 0; + mask = 0; + restPositionsEnabled = false; + + for (int j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + group = max(group, phases[particleIndex] & GroupMask); + flags |= phases[particleIndex] & ~GroupMask; // get flags from phase + category |= filters[particleIndex] & CategoryMask; // get category from filter + mask |= (filters[particleIndex] & MaskMask) >> 16; // get mask from filter + restPositionsEnabled = restPositionsEnabled || (restPositions[particleIndex].w > 0.5f); + } + + return group; +} + +struct simplexData +{ + int index; + int start; + int size; + int category; + int mask; + int flags; + int group; + bool restPosEnabled; +}; + +simplexData GetSimplexData(int indexInGrid) +{ + simplexData s; + s.index = sortedSimplexIndices[indexInGrid]; + s.start = GetSimplexStartAndSize(s.index, s.size); + s.group = GetSimplexGroup(s.start, s.size, s.flags, s.category, s.mask, s.restPosEnabled); + return s; +} + +void InteractionTest(simplexData a, simplexData b) +{ + if ((a.flags & Fluid) == 0 || (b.flags & Fluid) == 0) + { + // immediately reject simplex pairs that share particles: + int j = 0; + for (int i = 0; i < a.size; ++i) + for (j = 0; j < b.size; ++j) + if (simplices[a.start + i] == simplices[b.start + j]) + return; + + // if all particles are in the same group: + if (a.group == b.group) + { + // if none are self-colliding, reject the pair. + if ((a.flags & b.flags & SelfCollide) == 0) + return; + } + // category-based filtering: + else if ((a.mask & b.category) == 0 || (b.mask & a.category) == 0) + return; + + // swap simplices (except for category) so that B is always the one-sided one. + int categoryA = a.category; + int categoryB = b.category; + if ((a.flags & OneSided) != 0 && categoryA < categoryB) + { + simplexData t = a; + a = b; + b = t; + } + + float4 simplexBary = BarycenterForSimplexOfSize(a.size); + float4 simplexPoint; + + Simplex simplexShape; + simplexShape.simplexStart = b.start; + simplexShape.simplexSize = b.size; + simplexShape.simplices = simplices; + simplexShape.positions = restPositions; + float simplexRadiusA = 0; float simplexRadiusB = 0; + + // skip the contact if there's self-intersection at rest: + if (a.group == b.group && (a.restPosEnabled || b.restPosEnabled)) + { + SurfacePoint restPoint = Optimize(simplexShape, restPositions, restOrientations, principalRadii, + simplices, a.start, a.size, simplexBary, simplexPoint, 4, 0); + + for (j = 0; j < a.size; ++j) + simplexRadiusA += principalRadii[simplices[a.start + j]].x * simplexBary[j]; + + for (j = 0; j < b.size; ++j) + simplexRadiusB += principalRadii[simplices[b.start + j]].x * restPoint.bary[j]; + + // compare distance along contact normal with radius. + if (dot(simplexPoint - restPoint.pos, restPoint.normal) < simplexRadiusA + simplexRadiusB) + return; + } + + simplexBary = BarycenterForSimplexOfSize(a.size); + simplexShape.positions = positions; + + SurfacePoint surfacePoint = Optimize(simplexShape, positions, orientations, principalRadii, + simplices, a.start, a.size, simplexBary, simplexPoint); + + simplexRadiusA = 0; simplexRadiusB = 0; + float4 velocityA = FLOAT4_ZERO, velocityB = FLOAT4_ZERO, normalB = FLOAT4_ZERO; + + for (j = 0; j < a.size; ++j) + { + int particleIndex = simplices[a.start + j]; + simplexRadiusA += principalRadii[particleIndex].x * simplexBary[j]; + velocityA += velocities[particleIndex] * simplexBary[j]; + } + + for (j = 0; j < b.size; ++j) + { + int particleIndex = simplices[b.start + j]; + simplexRadiusB += principalRadii[particleIndex].x * surfacePoint.bary[j]; + velocityB += velocities[particleIndex] * surfacePoint.bary[j]; + normalB += asfloat(normals[particleIndex]) * surfacePoint.bary[j]; + } + + float dAB = dot(simplexPoint - surfacePoint.pos, surfacePoint.normal); + float vel = dot(velocityA - velocityB, surfacePoint.normal); + + // check if the projected velocity along the contact normal will get us within collision distance. + if (vel * deltaTime + dAB <= simplexRadiusA + simplexRadiusB + collisionMargin) + { + // adapt collision normal for one-sided simplices: + if ((b.flags & OneSided) != 0 && categoryA < categoryB) + OneSidedNormal(normalB, surfacePoint.normal); + + uint count = particleContacts.IncrementCounter(); + if (count < maxContacts) + { + contact c = (contact)0; + + c.normal = surfacePoint.normal; + c.pointA = simplexBary; + c.pointB = surfacePoint.bary; + c.bodyA = a.index; + c.bodyB = b.index; + + particleContacts[count] = c; + contactPairs[count] = uint2(c.bodyA,c.bodyB); + + InterlockedMax(dispatchBuffer[0],(count + 1) / 128 + 1); + InterlockedMax(dispatchBuffer[3], count + 1); + } + } + } +} + +[numthreads(128, 1, 1)] +void BuildContactList (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= pointCount + edgeCount + triangleCount) return; + + // current cell: + int4 cellCoord = R_cellCoords[i]; + uint cellIndex = cellHashToMortonIndex[GridHash(cellCoord)]; + uint n = R_cellOffsets[cellIndex]; + uint end = n + R_cellCounts[cellIndex]; + uint indexInGrid = n + R_offsetInCell[i]; + + simplexData data1 = GetSimplexData(indexInGrid); + + // in current cell, only consider simplices that appear after this one: + for (++indexInGrid; indexInGrid < end; ++indexInGrid) + InteractionTest(data1,GetSimplexData(indexInGrid)); + + // neighbour cells ahead of the current one in the same level: + for(int j = 0; j < 13; ++j) + { + // get first simplex in neighbor cell: + cellIndex = cellHashToMortonIndex[GridHash(cellCoord + aheadCellNeighborhood[j])]; + n = R_cellOffsets[cellIndex]; + end = n + R_cellCounts[cellIndex]; + + // iterate through all simplices in neighbor cell: + for (; n < end; ++n) + InteractionTest(data1,GetSimplexData(n)); + } + + // higher grid levels: + for (uint m = 1; m <= R_levelPopulation[0]; ++m) + { + uint l = R_levelPopulation[m]; + if (l <= (uint)cellCoord.w) continue; + + int4 parentCellCoords = GetParentCellCoords(cellCoord, l); + + for (int j = 0; j < 27; ++j) + { + // get first simplex in neighbor cell: + cellIndex = cellHashToMortonIndex[GridHash(parentCellCoords + cellNeighborhood[j])]; + n = R_cellOffsets[cellIndex]; + end = n + R_cellCounts[cellIndex]; + + // iterate through all simplices in neighbor cell: + for (; n < end; ++n) + InteractionTest(data1,GetSimplexData(n)); + } + } +} + +[numthreads(128, 1, 1)] +void FindFluidNeighborsInSameLevel (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatchBuffer[3]) return; + + // current cell: + int4 cellCoord = R_cellCoords[sortedFluidIndices[i]]; + int4 neighborCoord, particleCoord; + uint cellIndex, n, end; + + float4 d; + float interactionRadius, cellSize; + int fluidB, level; + + float4 posA = sortedPositions[i]; + float radA = sortedFluidMaterials[i].x; + + uint count = 0; + + // neighbour cells in same level. We don't need atomics for this, + // and we can guarantee that the neighbors for each particle will + // appear in sorted order. + for(int j = 0; j < 27; ++j) + { + // get cell start/end + neighborCoord = cellCoord + cellNeighborhood[j]; + cellIndex = cellHashToMortonIndex[GridHash(neighborCoord)]; + n = R_cellOffsets[cellIndex]; + end = n + R_cellCounts[cellIndex]; + + // iterate through all simplices in neighbor cell: + for (; n < end; ++n) + { + fluidB = sortedSimplexToFluid[n]; + if (fluidB >= 0 && fluidB != (int)i) + { + // due to hash collisions, two neighboring cells might map to the same + // hash bucket, and we'll add the same set of particles twice to the neighbors list. + // So we only consider particles that have the same spatial coordinates as the cell. + level = GridLevelForSize(sortedFluidMaterials[fluidB].x); + cellSize = CellSizeOfLevel(level); + particleCoord = int4(floor((sortedPositions[fluidB] - solverBounds[0].min_)/ cellSize).xyz,level); + + if (any (particleCoord - neighborCoord)) + continue; + + // calculate particle center distance: + d = posA - sortedPositions[fluidB]; d.w = 0; + interactionRadius = max(radA, sortedFluidMaterials[fluidB].x); + + if (dot(d,d) <= interactionRadius * interactionRadius && count < maxNeighbors) + neighbors[maxNeighbors * i + (count++)] = fluidB; + } + } + } + + neighborCounts[i] = count; +} + +[numthreads(128, 1, 1)] +void FindFluidNeighborsInUpperLevels (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatchBuffer[3]) return; + + int s = sortedFluidIndices[i]; + + int4 cellCoord = R_cellCoords[s]; + int4 parentCellCoords, neighborCoord, particleCoord; + uint cellIndex, n, end; + + float4 d; + float interactionRadius, cellSize; + int fluidB, level; + + float4 posA = sortedPositions[i]; + float radA = sortedFluidMaterials[i].x; + + for (uint m = 1; m <= R_levelPopulation[0]; ++m) + { + uint l = R_levelPopulation[m]; + + // skip levels below this particle's level. + if (l <= (uint)cellCoord.w) continue; + + parentCellCoords = GetParentCellCoords(cellCoord, l); + + for (int j = 0; j < 27; ++j) + { + // get cell start/end + neighborCoord = parentCellCoords + cellNeighborhood[j]; + cellIndex = cellHashToMortonIndex[GridHash(neighborCoord)]; + n = R_cellOffsets[cellIndex]; + end = n + R_cellCounts[cellIndex]; + + // iterate through all simplices in neighbor cell: + for (; n < end; ++n) + { + fluidB = sortedSimplexToFluid[n]; + if (fluidB >= 0) + { + // due to hash collisions, two neighboring cells might map to the same + // hash bucket, and we'll add the same set of particles twice to the neighbors list. + // So we only consider particles that have the same spatial coordinates as the cell. + level = GridLevelForSize(sortedFluidMaterials[fluidB].x); + cellSize = CellSizeOfLevel(level); + particleCoord = int4(floor((sortedPositions[fluidB] - solverBounds[0].min_)/ cellSize).xyz,level); + + if (any (particleCoord - neighborCoord)) + continue; + + // calculate particle center distance: + d = posA - sortedPositions[fluidB]; d.w = 0; + interactionRadius = max(radA, sortedFluidMaterials[fluidB].x); + + if (dot(d,d) <= interactionRadius * interactionRadius) + { + uint entryA, entryB; + InterlockedAdd(neighborCounts[i], 1, entryA); + InterlockedAdd(neighborCounts[fluidB], 1, entryB); + + if (entryA < maxNeighbors && entryB < maxNeighbors) + { + neighbors[maxNeighbors * i + entryA] = fluidB; + neighbors[maxNeighbors * fluidB + entryB] = i; + } + } + } + } + } + } + + // convert simplex index to start in indices array. + int o; + sortedFluidIndices[i] = simplices[GetSimplexStartAndSize(s, o)]; +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/ParticleGrid.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/ParticleGrid.compute.meta new file mode 100644 index 00000000..15d29e6b --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ParticleGrid.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 282fd6222e54d48fea7f2d1a74501fa9 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/ParticleMeshBuilding.compute b/xiaofang/Assets/Obi/Resources/Compute/ParticleMeshBuilding.compute new file mode 100644 index 00000000..e990898d --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ParticleMeshBuilding.compute @@ -0,0 +1,72 @@ +#pragma kernel BuildMesh + +#include "MathUtils.cginc" + +struct RendererData +{ + float4 color; + float radiusScale; +}; + +StructuredBuffer particleIndices; + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer radii; +StructuredBuffer colors; + +StructuredBuffer rendererIndices; +StructuredBuffer rendererData; + +RWByteAddressBuffer vertices; +RWByteAddressBuffer indices; + +uint firstParticle; +uint particleCount; + +[numthreads(128, 1, 1)] +void BuildMesh (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= particleCount) return; + + int p = particleIndices[firstParticle + i]; + int r = rendererIndices[firstParticle + i]; + + // <<2 = multiply by 4 to get byte address, since a float/int is 4 bytes in size. + + // particle data is the same for all 4 vertices: + for (uint v = i*4; v < i*4 + 4; ++v) + { + int base = v*23; + + // pos + vertices.Store4(base<<2, asuint(float4(positions[p].xyz, 1))); + + // color: + vertices.Store4((base+7)<<2, asuint(colors[p] * rendererData[r].color)); + + // b1, b2, b3: + vertices.Store4((base+11)<<2, asuint( float4(rotate_vector(orientations[p],float3(1,0,0)),radii[p].x * radii[p].w * rendererData[r].radiusScale) )); + vertices.Store4((base+15)<<2, asuint( float4(rotate_vector(orientations[p],float3(0,1,0)),radii[p].y * radii[p].w * rendererData[r].radiusScale) )); + vertices.Store4((base+19)<<2, asuint( float4(rotate_vector(orientations[p],float3(0,0,1)),radii[p].z * radii[p].w * rendererData[r].radiusScale) )); + } + + //different offset for each vertex: + int base = i*4; + vertices.Store3((base*23 + 4)<<2, asuint(float3(1,1,0))); + vertices.Store3(((base+1)*23 + 4)<<2, asuint(float3(-1,1,0))); + vertices.Store3(((base+2)*23 + 4)<<2, asuint(float3(-1,-1,0))); + vertices.Store3(((base+3)*23 + 4)<<2, asuint(float3(1,-1,0))); + + // indices: + indices.Store((i*6)<<2, asuint(i*4+2)); + indices.Store((i*6+1)<<2, asuint(i*4+1)); + indices.Store((i*6+2)<<2, asuint(i*4)); + + indices.Store((i*6+3)<<2, asuint(i*4+3)); + indices.Store((i*6+4)<<2, asuint(i*4+2)); + indices.Store((i*6+5)<<2, asuint(i*4)); +} + diff --git a/xiaofang/Assets/Obi/Resources/Compute/ParticleMeshBuilding.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/ParticleMeshBuilding.compute.meta new file mode 100644 index 00000000..c28621d1 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ParticleMeshBuilding.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a5989e4df4ce944ea96d566e7df4d68a +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/PathFrame.cginc b/xiaofang/Assets/Obi/Resources/Compute/PathFrame.cginc new file mode 100644 index 00000000..e9ea2742 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/PathFrame.cginc @@ -0,0 +1,158 @@ +#ifndef PATHFRAME_INCLUDE +#define PATHFRAME_INCLUDE + +#include "MathUtils.cginc" + +struct pathFrame +{ + float3 position; + float3 tangent; + float3 normal; + float3 binormal; + + float4 color; + float thickness; + + + void Initialize(float3 position, float3 tangent, float3 normal, float3 binormal, float4 color, float thickness){ + this.position = position; + this.normal = normal; + this.tangent = tangent; + this.binormal = binormal; + this.color = color; + this.thickness = thickness; + } + + void Reset() + { + position = float3(0,0,0); + tangent = float3(0,0,1); + normal = float3(0,1,0); + binormal = float3(1,0,0); + color = float4(1,1,1,1); + thickness = 0; + } + + void SetTwist(float twist) + { + quaternion twistQ = axis_angle(tangent, radians(twist)); + normal = rotate_vector(twistQ, normal); + binormal = rotate_vector(twistQ, binormal); + } + + void Transport(pathFrame frame, float twist) + { + // Calculate delta rotation: + quaternion rotQ = from_to_rotation(tangent, frame.tangent); + quaternion twistQ = axis_angle(frame.tangent, radians(twist)); + quaternion finalQ = qmul(twistQ , rotQ); + + // Rotate previous frame axes to obtain the new ones: + normal = rotate_vector(finalQ, normal); + binormal = rotate_vector(finalQ, binormal); + tangent = frame.tangent; + position = frame.position; + thickness = frame.thickness; + color = frame.color; + } + + void Transport(float3 newPosition, float3 newTangent, float twist) + { + // Calculate delta rotation: + quaternion rotQ = from_to_rotation(tangent, newTangent); + quaternion twistQ = axis_angle(newTangent, radians(twist)); + quaternion finalQ = qmul(twistQ, rotQ); + + // Rotate previous frame axes to obtain the new ones: + normal = rotate_vector(finalQ, normal); + binormal = rotate_vector(finalQ, binormal); + tangent = newTangent; + position = newPosition; + + } + + // Transport, hinting the normal. + void Transport(float3 newPosition, float3 newTangent, float3 newNormal, float twist) + { + normal = rotate_vector(axis_angle(newTangent,radians(twist)), newNormal); + tangent = newTangent; + binormal = cross(normal, tangent); + position = newPosition; + } + + float3x3 ToMatrix(int mainAxis) + { + float3x3 basis; + + if (mainAxis == 0) + { + basis._m00_m10_m20 = tangent; + basis._m01_m11_m21 = binormal; + basis._m02_m12_m22 = normal; + } + else if (mainAxis == 1) + { + basis._m01_m11_m21 = tangent; + basis._m02_m12_m22 = binormal; + basis._m00_m10_m20 = normal; + } + else + { + basis._m02_m12_m22 = tangent; + basis._m00_m10_m20 = binormal; + basis._m01_m11_m21 = normal; + } + + /*int xo = (mainAxis) % 3; + int yo = (mainAxis + 1) % 3; + int zo = (mainAxis + 2) % 3; + + basis[xo] = tangent; + basis[yo] = binormal; + basis[zo] = normal;*/ + + return basis; + } +}; + +void WeightedSum(float w1, float w2, float w3, in pathFrame c1, in pathFrame c2, in pathFrame c3, out pathFrame sum) +{ + sum.position.x = c1.position.x * w1 + c2.position.x * w2 + c3.position.x * w3; + sum.position.y = c1.position.y * w1 + c2.position.y * w2 + c3.position.y * w3; + sum.position.z = c1.position.z * w1 + c2.position.z * w2 + c3.position.z * w3; + + sum.tangent.x = c1.tangent.x * w1 + c2.tangent.x * w2 + c3.tangent.x * w3; + sum.tangent.y = c1.tangent.y * w1 + c2.tangent.y * w2 + c3.tangent.y * w3; + sum.tangent.z = c1.tangent.z * w1 + c2.tangent.z * w2 + c3.tangent.z * w3; + + sum.normal.x = c1.normal.x * w1 + c2.normal.x * w2 + c3.normal.x * w3; + sum.normal.y = c1.normal.y * w1 + c2.normal.y * w2 + c3.normal.y * w3; + sum.normal.z = c1.normal.z * w1 + c2.normal.z * w2 + c3.normal.z * w3; + + sum.binormal.x = c1.binormal.x * w1 + c2.binormal.x * w2 + c3.binormal.x * w3; + sum.binormal.y = c1.binormal.y * w1 + c2.binormal.y * w2 + c3.binormal.y * w3; + sum.binormal.z = c1.binormal.z * w1 + c2.binormal.z * w2 + c3.binormal.z * w3; + + sum.color.x = c1.color.x * w1 + c2.color.x * w2 + c3.color.x * w3; + sum.color.y = c1.color.y * w1 + c2.color.y * w2 + c3.color.y * w3; + sum.color.z = c1.color.z * w1 + c2.color.z * w2 + c3.color.z * w3; + sum.color.w = c1.color.w * w1 + c2.color.w * w2 + c3.color.w * w3; + + sum.thickness = c1.thickness * w1 + c2.thickness * w2 + c3.thickness * w3; +} + +pathFrame addFrames(pathFrame c1, pathFrame c2) +{ + pathFrame r; + r.Initialize(c1.position + c2.position, c1.tangent + c2.tangent, c1.normal + c2.normal, c1.binormal + c2.binormal, c1.color + c2.color, c1.thickness + c2.thickness); + return r; +} + +pathFrame multiplyFrame(float f, pathFrame c) +{ + pathFrame r; + r.Initialize(c.position * f, c.tangent * f, c.normal * f, c.binormal * f, c.color * f, c.thickness * f); + return r; +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/PathFrame.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/PathFrame.cginc.meta new file mode 100644 index 00000000..fa818faa --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/PathFrame.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 10c2f01e614d74b30b6a489c96e8a0ce +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/PathSmoothing.compute b/xiaofang/Assets/Obi/Resources/Compute/PathSmoothing.compute new file mode 100644 index 00000000..06bf6ae5 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/PathSmoothing.compute @@ -0,0 +1,235 @@ +#pragma kernel ParallelTransport +#pragma kernel Decimate +#pragma kernel ChaikinSmooth + +#include "PathFrame.cginc" + +struct smootherPathData +{ + uint smoothing; + float decimation; + float twist; + float restLength; + float smoothLength; + bool usesOrientedParticles; +}; + +StructuredBuffer renderablePositions; +StructuredBuffer renderableOrientations; +StructuredBuffer principalRadii; +StructuredBuffer colors; + +RWStructuredBuffer pathData; +StructuredBuffer particleIndices; + +RWStructuredBuffer pathFrames; +StructuredBuffer frameOffsets; +RWStructuredBuffer decimatedFrameCounts; + +RWStructuredBuffer smoothFrames; +StructuredBuffer smoothFrameOffsets; +RWStructuredBuffer smoothFrameCounts; + +// Variables set from the CPU +uint chunkCount; + +void PathFrameFromParticle(inout pathFrame frame, int particleIndex, bool useOrientedParticles, bool interpolateOrientation = false) +{ + // Update current frame values from particles: + frame.position = renderablePositions[particleIndex].xyz; + frame.thickness = principalRadii[particleIndex][0]; + frame.color = colors[particleIndex]; + + // Use particle orientation if possible: + if (useOrientedParticles) + { + quaternion current = renderableOrientations[particleIndex]; + quaternion previous = renderableOrientations[max(0, particleIndex - 1)]; + float4x4 average = q_toMatrix(interpolateOrientation ? q_slerp(current, previous, 0.5f) : current); + frame.normal = average._m01_m11_m21; + frame.binormal = average._m00_m10_m20; + frame.tangent = average._m02_m12_m22; + } +} + + +[numthreads(128, 1, 1)] +void ParallelTransport (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= chunkCount) return; + + pathFrame nextFrame; + pathFrame currFrame; + pathFrame prevFrame; + + nextFrame.Reset(); + currFrame.Reset(); + prevFrame.Reset(); + + int firstIndex = i > 0 ? frameOffsets[i - 1] : 0; + int frameCount = frameOffsets[i] - firstIndex; + + // initialize current and previous frame: + PathFrameFromParticle(currFrame, particleIndices[firstIndex], pathData[i].usesOrientedParticles, false); + prevFrame = currFrame; + + // parallel transport: + for (int m = 1; m <= frameCount; ++m) + { + int index = firstIndex + min(m, frameCount - 1); + int pIndex = particleIndices[index]; + + // generate curve frame from particle: + PathFrameFromParticle(nextFrame, pIndex, pathData[i].usesOrientedParticles); + + if (pathData[i].usesOrientedParticles) + { + // copy frame directly. + prevFrame = currFrame; + } + else + { + // perform parallel transport, using forward / backward average to calculate tangent. + // if the average is too small, reuse the previous frame tangent. + currFrame.tangent = normalizesafe((currFrame.position - prevFrame.position) + + (nextFrame.position - currFrame.position), prevFrame.tangent); + prevFrame.Transport(currFrame, pathData[i].twist); + } + + // advance current frame: + currFrame = nextFrame; + pathFrames[firstIndex + m - 1] = prevFrame; + } +} + +[numthreads(128, 1, 1)] +void Decimate (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= chunkCount) return; + + int firstInputIndex = i > 0 ? frameOffsets[i - 1] : 0; + int inputFrameCount = frameOffsets[i] - firstInputIndex; + + // no decimation, no work to do, just return: + if (pathData[i].decimation < 0.00001f || inputFrameCount < 3) + { + decimatedFrameCounts[i] = inputFrameCount; + return; + } + + float scaledThreshold = pathData[i].decimation * pathData[i].decimation * 0.01f; + + int start = 0; + int end = inputFrameCount - 1; + decimatedFrameCounts[i] = 0; + + while (start < end) + { + // add starting point: + pathFrames[firstInputIndex + decimatedFrameCounts[i]++] = pathFrames[firstInputIndex + start]; + + int newEnd = end; + + while (true) + { + int maxDistanceIndex = 0; + float maxDistance = 0; + float mu; + + // find the point that's furthest away from the current segment: + for (int j = start + 1; j < newEnd; j++) + { + float3 nearest = NearestPointOnEdge(pathFrames[firstInputIndex + start].position, + pathFrames[firstInputIndex + newEnd].position, + pathFrames[firstInputIndex + j].position, mu); + + float3 delta = nearest - pathFrames[firstInputIndex + j].position; + float d = dot(delta,delta); + + if (d > maxDistance) + { + maxDistanceIndex = j; + maxDistance = d; + } + } + + if (maxDistance <= scaledThreshold) + break; + + newEnd = maxDistanceIndex; + } + + start = newEnd; + } + + // add the last point: + pathFrames[firstInputIndex + decimatedFrameCounts[i]++] = pathFrames[firstInputIndex + end]; + +} + +[numthreads(128, 1, 1)] +void ChaikinSmooth (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= chunkCount) return; + + int firstInputIndex = i > 0 ? frameOffsets[i - 1] : 0; + int inputFrameCount = decimatedFrameCounts[i]; + + int firstOutputIndex = smoothFrameOffsets[i]; + + int k = (int)pathData[i].smoothing; + + // No work to do. just copy the input to the output: + if (k == 0) + { + smoothFrameCounts[i] = inputFrameCount; + for (int j = 0; j < inputFrameCount; ++j) + smoothFrames[firstOutputIndex + j] = pathFrames[firstInputIndex + j]; + } + else + { + // precalculate some quantities: + int pCount = (int)pow(2, k); + int n0 = inputFrameCount - 1; + float twoRaisedToMinusKPlus1 = pow(2, -(k + 1)); + float twoRaisedToMinusK = pow(2, -k); + float twoRaisedToMinus2K = pow(2, -2 * k); + float twoRaisedToMinus2KMinus1 = pow(2, -2 * k - 1); + + smoothFrameCounts[i] = (inputFrameCount - 2) * pCount + 2; + + // calculate initial curve points: + smoothFrames[firstOutputIndex] = addFrames(multiplyFrame(0.5f + twoRaisedToMinusKPlus1 , pathFrames[firstInputIndex]) , multiplyFrame(0.5f - twoRaisedToMinusKPlus1, pathFrames[firstInputIndex + 1])); + smoothFrames[firstOutputIndex + pCount * n0 - pCount + 1] = addFrames(multiplyFrame(0.5f - twoRaisedToMinusKPlus1, pathFrames[firstInputIndex + n0 - 1]) , multiplyFrame(0.5f + twoRaisedToMinusKPlus1, pathFrames[firstInputIndex + n0])); + + // calculate internal points: + for (int j = 1; j <= pCount; ++j) + { + // precalculate coefficients: + float F = 0.5f - twoRaisedToMinusKPlus1 - (j - 1) * (twoRaisedToMinusK - j * twoRaisedToMinus2KMinus1); + float G = 0.5f + twoRaisedToMinusKPlus1 + (j - 1) * (twoRaisedToMinusK - j * twoRaisedToMinus2K); + float H = (j - 1) * j * twoRaisedToMinus2KMinus1; + + for (int l = 1; l < n0; ++l) + { + WeightedSum(F, G, H, + pathFrames[firstInputIndex + l - 1], + pathFrames[firstInputIndex + l], + pathFrames[firstInputIndex + l + 1], + smoothFrames[firstOutputIndex + (l - 1) * pCount + j]); + } + } + + // make first and last curve points coincide with original points: + smoothFrames[firstOutputIndex] = pathFrames[firstInputIndex]; + smoothFrames[firstOutputIndex + smoothFrameCounts[i] - 1] = pathFrames[firstInputIndex + inputFrameCount - 1]; + } + + // calculate path lengths: + pathData[i].smoothLength = 0; + for (int j = firstOutputIndex + 1; j < firstOutputIndex + smoothFrameCounts[i]; ++j) + pathData[i].smoothLength += distance(smoothFrames[j-1].position, smoothFrames[j].position); +} diff --git a/xiaofang/Assets/Obi/Resources/Compute/PathSmoothing.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/PathSmoothing.compute.meta new file mode 100644 index 00000000..589cc57c --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/PathSmoothing.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 91c36d3d171884541b751112dfac062c +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/Phases.cginc b/xiaofang/Assets/Obi/Resources/Compute/Phases.cginc new file mode 100644 index 00000000..30bfe208 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Phases.cginc @@ -0,0 +1,13 @@ +#ifndef PHASES_INCLUDE +#define PHASES_INCLUDE + + +#define CategoryMask 0x0000ffff +#define MaskMask 0xffff0000 + +#define GroupMask 0x00ffffff +#define SelfCollide 1 << 24 +#define Fluid 1 << 25 +#define OneSided 1 << 26 + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/Phases.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/Phases.cginc.meta new file mode 100644 index 00000000..290fe950 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Phases.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 96d6b61b6caf54444b039bf6f29c9205 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/PinConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/PinConstraints.compute new file mode 100644 index 00000000..151cc86a --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/PinConstraints.compute @@ -0,0 +1,205 @@ +#pragma kernel Clear +#pragma kernel Initialize +#pragma kernel Project +#pragma kernel Apply + +#include "MathUtils.cginc" +#include "AtomicDeltas.cginc" +#include "ColliderDefinitions.cginc" +#include "Rigidbody.cginc" + +StructuredBuffer particleIndices; +StructuredBuffer colliderIndices; +StructuredBuffer offsets; +StructuredBuffer restDarboux; +StructuredBuffer stiffnesses; +RWStructuredBuffer lambdas; + +StructuredBuffer transforms; +StructuredBuffer shapes; +RWStructuredBuffer RW_rigidbodies; + +RWStructuredBuffer RW_positions; +RWStructuredBuffer RW_orientations; + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer prevPositions; +StructuredBuffer invMasses; +StructuredBuffer invRotationalMasses; + +StructuredBuffer inertialSolverFrame; + +// Variables set from the CPU +uint activeConstraintCount; +float stepTime; +float substepTime; +float timeLeft; +int steps; +float sorFactor; + +[numthreads(128, 1, 1)] +void Clear (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int colliderIndex = colliderIndices[i]; + + // no collider to pin to, so ignore the constraint. + if (colliderIndex < 0) + return; + + int rigidbodyIndex = shapes[colliderIndex].rigidbodyIndex; + + if (rigidbodyIndex >= 0) + { + int orig; + InterlockedExchange(RW_rigidbodies[rigidbodyIndex].constraintCount, 0, orig); + } +} + +[numthreads(128, 1, 1)] +void Initialize (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int colliderIndex = colliderIndices[i]; + + // no collider to pin to, so ignore the constraint. + if (colliderIndex < 0) + return; + + int rigidbodyIndex = shapes[colliderIndex].rigidbodyIndex; + + if (rigidbodyIndex >= 0) + { + InterlockedAdd(RW_rigidbodies[rigidbodyIndex].constraintCount, 1); + } +} + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int particleIndex = particleIndices[i]; + int colliderIndex = colliderIndices[i]; + + // no collider to pin to, so ignore the constraint. + if (colliderIndex < 0) + return; + + int rigidbodyIndex = shapes[colliderIndex].rigidbodyIndex; + + float frameEnd = stepTime * steps; + float substepsToEnd = timeLeft / substepTime; + + // calculate time adjusted compliances + float2 compliances = stiffnesses[i].xy / (substepTime * substepTime); + + // project particle position to the end of the full step: + float4 particlePosition = lerp(prevPositions[particleIndex], positions[particleIndex], substepsToEnd); + + // express pin offset in world space: + float4 worldPinOffset = transforms[colliderIndex].TransformPoint(offsets[i]); + float4 predictedPinOffset = worldPinOffset; + quaternion predictedRotation = transforms[colliderIndex].rotation; + + float rigidbodyLinearW = 0; + float rigidbodyAngularW = 0; + + if (rigidbodyIndex >= 0) + { + rigidbody rb = rigidbodies[rigidbodyIndex]; + + // predict rigidbody transform: + transform predictedTrfm = transforms[colliderIndex].Integrate(rb.velocity + asfloat(linearDeltasAsInt[rigidbodyIndex]), + rb.angularVelocity + asfloat(angularDeltasAsInt[rigidbodyIndex]), frameEnd); + + // predict offset point position and rb rotation at the end of the step: + predictedPinOffset = predictedTrfm.TransformPoint(offsets[i]); + predictedRotation = predictedTrfm.rotation; + + // calculate linear and angular rigidbody effective masses (mass splitting: multiply by constraint count) + rigidbodyLinearW = rb.inverseMass * rb.constraintCount; + rigidbodyAngularW = RotationalInvMass(rb.inverseInertiaTensor, + worldPinOffset - rb.com, + normalizesafe(inertialSolverFrame[0].frame.TransformPoint(particlePosition) - predictedPinOffset)) * rb.constraintCount; + + } + + // Transform pin position to solver space for constraint solving: + predictedPinOffset = inertialSolverFrame[0].frame.InverseTransformPoint(predictedPinOffset); + predictedRotation = qmul(q_conj(inertialSolverFrame[0].frame.rotation), predictedRotation); + + float4 gradient = particlePosition - predictedPinOffset; + float constraint = length(gradient); + float4 gradientDir = gradient / (constraint + EPSILON); + + float4 lambda = lambdas[i]; + float linearDLambda = (-constraint - compliances.x * lambda.w) / (invMasses[particleIndex] + rigidbodyLinearW + rigidbodyAngularW + compliances.x + EPSILON); + lambda.w += linearDLambda; + float4 correction = linearDLambda * gradientDir; + + AddPositionDelta(particleIndex, correction * invMasses[particleIndex] / substepsToEnd); + + if (rigidbodyIndex >= 0) + { + ApplyImpulse(rigidbodyIndex, + -correction / frameEnd, + inertialSolverFrame[0].frame.InverseTransformPoint(worldPinOffset), + inertialSolverFrame[0].frame); + } + + if (rigidbodyAngularW > 0 || invRotationalMasses[particleIndex] > 0) + { + // bend/twist constraint: + quaternion omega = qmul(q_conj(orientations[particleIndex]), predictedRotation); //darboux vector + + quaternion omega_plus; + omega_plus = omega + restDarboux[i]; //delta Omega with - omega_0 + omega -= restDarboux[i]; //delta Omega with + omega_0 + if (dot(omega.xyz, omega.xyz) > dot(omega_plus.xyz, omega_plus.xyz)) + omega = omega_plus; + + float3 dlambda = (omega.xyz - compliances.y * lambda.xyz) / (compliances.y + invRotationalMasses[particleIndex] + rigidbodyAngularW + EPSILON); + lambda.xyz += dlambda; + + //discrete Darboux vector does not have vanishing scalar part: + quaternion dlambdaQ = quaternion(dlambda[0], dlambda[1], dlambda[2], 0); + + quaternion orientDelta = asfloat(orientationDeltasAsInt[particleIndex]); + orientDelta += qmul(predictedRotation, dlambdaQ) * invRotationalMasses[particleIndex] / substepsToEnd; + orientationDeltasAsInt[particleIndex] = asuint(orientDelta); + orientationConstraintCounts[particleIndex]++; + + if (rigidbodyIndex >= 0) + { + ApplyDeltaQuaternion(rigidbodyIndex, + predictedRotation, + -qmul(orientations[particleIndex], dlambdaQ) * rigidbodyAngularW, + inertialSolverFrame[0].frame, stepTime); + } + } + + lambdas[i] = lambda; +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p = particleIndices[i]; + + ApplyPositionDelta(RW_positions, p, sorFactor); + ApplyOrientationDelta(RW_orientations, p, sorFactor); +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/PinConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/PinConstraints.compute.meta new file mode 100644 index 00000000..23582462 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/PinConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d65f884fa36104c4493d2bc55441b89d +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/Quaternion.cginc b/xiaofang/Assets/Obi/Resources/Compute/Quaternion.cginc new file mode 100644 index 00000000..9143d27c --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Quaternion.cginc @@ -0,0 +1,230 @@ +#ifndef QUATERNION_INCLUDE +#define QUATERNION_INCLUDE + +#define QUATERNION_IDENTITY float4(0, 0, 0, 1) + +typedef float4 quaternion; + +// Quaternion multiplication +// http://mathworld.wolfram.com/Quaternion.html +quaternion qmul(quaternion q1, quaternion q2) +{ + return quaternion( + q2.xyz * q1.w + q1.xyz * q2.w + cross(q1.xyz, q2.xyz), + q1.w * q2.w - dot(q1.xyz, q2.xyz) + ); +} + +// Vector rotation with a quaternion +// http://mathworld.wolfram.com/Quaternion.html +float3 rotate_vector(quaternion r, float3 v) +{ + float4 r_c = r * float4(-1, -1, -1, 1); + return qmul(r, qmul(float4(v, 0), r_c)).xyz; +} + +// A given angle of rotation about a given axis +quaternion axis_angle(float3 axis, float angle) +{ + float sn = sin(angle * 0.5); + float cs = cos(angle * 0.5); + return quaternion(axis * sn, cs); +} + +// https://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another +quaternion from_to_rotation(float3 v1, float3 v2) +{ + float4 q; + float d = dot(v1, v2); + if (d < -0.999999) + { + float3 right = float3(1, 0, 0); + float3 up = float3(0, 1, 0); + float3 tmp = cross(right, v1); + if (length(tmp) < 0.000001) + { + tmp = cross(up, v1); + } + tmp = normalize(tmp); + q = axis_angle(tmp, 3.14159265359f); + } else if (d > 0.999999) { + q = QUATERNION_IDENTITY; + } else { + q.xyz = cross(v1, v2); + q.w = 1 + d; + q = normalize(q); + } + return q; +} + +float4 q_conj(float4 q) +{ + return float4(-q.x, -q.y, -q.z, q.w); +} + +// https://jp.mathworks.com/help/aeroblks/quaternioninverse.html +quaternion q_inverse(quaternion q) +{ + quaternion conj = q_conj(q); + return conj / (q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w); +} + +quaternion q_diff(quaternion q1, quaternion q2) +{ + return q2 * q_inverse(q1); +} + +quaternion q_look_at(float3 forward, float3 up) +{ + forward = normalize(forward); + float3 right = normalize(cross(up, forward)); + up = cross(forward, right); + + float m00 = right.x; + float m01 = right.y; + float m02 = right.z; + float m10 = up.x; + float m11 = up.y; + float m12 = up.z; + float m20 = forward.x; + float m21 = forward.y; + float m22 = forward.z; + + float num8 = (m00 + m11) + m22; + quaternion q = QUATERNION_IDENTITY; + + if (num8 > 0.0) + { + float num = sqrt(num8 + 1.0); + q.w = num * 0.5; + num = 0.5 / num; + q.x = (m12 - m21) * num; + q.y = (m20 - m02) * num; + q.z = (m01 - m10) * num; + return q; + } + else if ((m00 >= m11) && (m00 >= m22)) + { + float num7 = sqrt(((1.0 + m00) - m11) - m22); + float num4 = 0.5 / num7; + q.x = 0.5 * num7; + q.y = (m01 + m10) * num4; + q.z = (m02 + m20) * num4; + q.w = (m12 - m21) * num4; + return q; + } + else if (m11 > m22) + { + float num6 = sqrt(((1.0 + m11) - m00) - m22); + float num3 = 0.5 / num6; + q.x = (m10 + m01) * num3; + q.y = 0.5 * num6; + q.z = (m21 + m12) * num3; + q.w = (m20 - m02) * num3; + return q; + } + else + { + float num5 = sqrt(((1.0 + m22) - m00) - m11); + float num2 = 0.5 / num5; + q.x = (m20 + m02) * num2; + q.y = (m21 + m12) * num2; + q.z = 0.5 * num5; + q.w = (m01 - m10) * num2; + return q; + } +} + +quaternion q_slerp(in quaternion a, in quaternion b, float t) +{ + // if either input is zero, return the other. + if (length(a) == 0.0) + { + if (length(b) == 0.0) + return QUATERNION_IDENTITY; + else + return b; + } + else if (length(b) == 0.0) + { + return a; + } + else + { + float cosHalfAngle = a.w * b.w + dot(a.xyz, b.xyz); + + if (cosHalfAngle >= 1.0 || cosHalfAngle <= -1.0) + { + return a; + } + else + { + if (cosHalfAngle < 0.0) + { + b.xyz = -b.xyz; + b.w = -b.w; + cosHalfAngle = -cosHalfAngle; + } + + float blendA; + float blendB; + if (cosHalfAngle < 0.99) + { + // do proper slerp for big angles + float halfAngle = acos(cosHalfAngle); + float sinHalfAngle = sin(halfAngle); + float oneOverSinHalfAngle = 1.0 / sinHalfAngle; + blendA = sin(halfAngle * (1.0 - t)) * oneOverSinHalfAngle; + blendB = sin(halfAngle * t) * oneOverSinHalfAngle; + } + else + { + // do lerp if angle is really small. + blendA = 1.0 - t; + blendB = t; + } + + quaternion result = quaternion(blendA * a.xyz + blendB * b.xyz, blendA * a.w + blendB * b.w); + + if (length(result) > 0.0) + return normalize(result); + else + return QUATERNION_IDENTITY; + } + } +} + +quaternion q_eulerXYZ(float3 euler) +{ + float3 s, c; + sincos(0.5f * euler, s, c); + return quaternion( + // s.x * c.y * c.z + s.y * s.z * c.x, + // s.y * c.x * c.z - s.x * s.z * c.y, + // s.z * c.x * c.y - s.x * s.y * c.z, + // c.x * c.y * c.z + s.y * s.z * s.x + float4(s.xyz, c.x) * c.yxxy * c.zzyz + s.yxxy * s.zzyz * float4(c.xyz, s.x) * float4(1.0f, -1.0f, -1.0f, 1.0f) + ); +} + +float4x4 q_toMatrix(quaternion q) +{ + float xx = q.x * q.x; + float xy = q.x * q.y; + float xz = q.x * q.z; + float xw = q.x * q.w; + + float yy = q.y * q.y; + float yz = q.y * q.z; + float yw = q.y * q.w; + + float zz = q.z * q.z; + float zw = q.z * q.w; + + return float4x4(1 - 2 * (yy + zz), 2 * (xy - zw), 2 * (xz + yw), 0, + 2 * (xy + zw), 1 - 2 * (xx + zz), 2 * (yz - xw), 0, + 2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xx + yy), 0, + 0, 0, 0, 1); +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/Quaternion.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/Quaternion.cginc.meta new file mode 100644 index 00000000..ad02e0bf --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Quaternion.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d586fccea37884cd99448480e05b9efc +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/QueryDefinitions.cginc b/xiaofang/Assets/Obi/Resources/Compute/QueryDefinitions.cginc new file mode 100644 index 00000000..ddd2b711 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/QueryDefinitions.cginc @@ -0,0 +1,30 @@ +#ifndef QUERYDEFS_INCLUDE +#define QUERYDEFS_INCLUDE + +#define SPHERE_QUERY 0 +#define BOX_QUERY 1 +#define RAY_QUERY 2 + +struct queryShape +{ + float4 center; + float4 size; + int type; + float contactOffset; + float maxDistance; + int filter; +}; + +struct queryResult +{ + float4 simplexBary; // point A, expressed as simplex barycentric coords for simplices. + float4 queryPoint; // point B, expressed as a solver-space position. + float4 normal; + float dist; + float distAlongRay; + int simplexIndex; + int queryIndex; +}; + + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/QueryDefinitions.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/QueryDefinitions.cginc.meta new file mode 100644 index 00000000..55f203af --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/QueryDefinitions.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: aa793a9f45d044bb9af2361e9c92f11d +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/RayShapeQuery.compute b/xiaofang/Assets/Obi/Resources/Compute/RayShapeQuery.compute new file mode 100644 index 00000000..a02d9f39 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/RayShapeQuery.compute @@ -0,0 +1,132 @@ +#include "ColliderDefinitions.cginc" +#include "QueryDefinitions.cginc" +#include "ContactHandling.cginc" +#include "Transform.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "Optimization.cginc" + +#pragma kernel GenerateResults + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer principalRadii; +StructuredBuffer simplices; + +StructuredBuffer transforms; +StructuredBuffer shapes; + +StructuredBuffer contactPairs; +StructuredBuffer contactOffsetsPerType; + +RWStructuredBuffer results; +RWStructuredBuffer dispatchBuffer; + +StructuredBuffer worldToSolver; + +uint maxContacts; + +struct Ray : IDistanceFunction +{ + queryShape s; + transform colliderToSolver; + + void Evaluate(in float4 pos, in float4 radii, in quaternion orientation, inout SurfacePoint projectedPoint) + { + float4x4 simplexToSolver = TRS(pos.xyz, orientation, radii.xyz); + float4x4 solverToSimplex = Inverse(simplexToSolver); + float4x4 colliderToSimplex = mul(solverToSimplex, TRS(colliderToSolver.translation.xyz, colliderToSolver.rotation, colliderToSolver.scale.xyz)); + + // express ray in simplex space (ellipsoid == scaled sphere) + float4 rayOrigin = mul(colliderToSimplex, float4(s.center.xyz,1)); + float4 rayDirection = normalizesafe(mul(colliderToSimplex, float4(s.size.xyz,0))); + + float rayDistance = RaySphereIntersection(rayOrigin.xyz, rayDirection.xyz, float3(0,0,0), 1); + + if (rayDistance < 0) + { + pos = colliderToSolver.InverseTransformPointUnscaled(pos); + + float mu; + float4 centerLine = NearestPointOnEdge(s.center * colliderToSolver.scale, (s.center + s.size) * colliderToSolver.scale, pos, mu); + float4 centerToPoint = pos - centerLine; + float distanceToCenter = length(centerToPoint); + + float4 normal = centerToPoint / (distanceToCenter + EPSILON); + + projectedPoint.pos = colliderToSolver.TransformPointUnscaled(centerLine + normal * s.contactOffset); + projectedPoint.normal = colliderToSolver.TransformDirection(normal); + } + else + { + float4 rayPoint = mul(simplexToSolver, float4((rayOrigin + rayDirection * rayDistance).xyz,1)); + float4 normal = normalizesafe(float4((pos - rayPoint).xyz,0)); + + projectedPoint.pos = rayPoint + normal * s.contactOffset; + projectedPoint.normal = normal; + } + + projectedPoint.bary = float4(1,0,0,0); + } +}; + +[numthreads(128, 1, 1)] +void GenerateResults (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + // entry #11 in the dispatch buffer is the amount of pairs for the first shape type. + if (i >= dispatchBuffer[11 + 4*RAY_QUERY]) return; + + int firstPair = contactOffsetsPerType[RAY_QUERY]; + int simplexIndex = contactPairs[firstPair + i].x; + int queryIndex = contactPairs[firstPair + i].y; + + queryResult c = (queryResult)0; + + Ray rayShape; + rayShape.colliderToSolver = worldToSolver[0].Multiply(transforms[queryIndex]); + rayShape.s = shapes[queryIndex]; + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(simplexIndex, simplexSize); + + float4 simplexBary = BarycenterForSimplexOfSize(simplexSize); + float4 simplexPoint; + + SurfacePoint surfacePoint = Optimize(rayShape, positions, orientations, principalRadii, + simplices, simplexStart, simplexSize, simplexBary, simplexPoint, surfaceCollisionIterations, surfaceCollisionTolerance); + + + float4 simplexPrevPosition = FLOAT4_ZERO; + float simplexRadius = 0; + for (int j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + simplexPrevPosition += positions[particleIndex] * simplexBary[j]; + simplexRadius += EllipsoidRadius(surfacePoint.normal, orientations[particleIndex], principalRadii[particleIndex].xyz) * simplexBary[j]; + } + + c.queryPoint = surfacePoint.pos; + c.normal = surfacePoint.normal; + c.simplexBary = simplexBary; + c.simplexIndex = simplexIndex; + c.queryIndex = queryIndex; + c.dist = dot(simplexPrevPosition - surfacePoint.pos, surfacePoint.normal) - simplexRadius; + + if (c.dist <= rayShape.s.maxDistance) + { + uint count = results.IncrementCounter(); + if (count < maxContacts) + { + float4 pointOnRay = surfacePoint.pos + surfacePoint.normal * c.dist; + c.distAlongRay = dot(pointOnRay.xyz - rayShape.s.center.xyz, normalizesafe(rayShape.s.size.xyz)); + + results[count] = c; + + InterlockedMax(dispatchBuffer[0],(count + 1) / 128 + 1); + InterlockedMax(dispatchBuffer[3], count + 1); + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/RayShapeQuery.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/RayShapeQuery.compute.meta new file mode 100644 index 00000000..5228b817 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/RayShapeQuery.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cc1e43b48b9764f8585de0bd68298b1c +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/Rigidbody.cginc b/xiaofang/Assets/Obi/Resources/Compute/Rigidbody.cginc new file mode 100644 index 00000000..9038eef5 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Rigidbody.cginc @@ -0,0 +1,108 @@ +#ifndef RIGIDBODY_INCLUDE +#define RIGIDBODY_INCLUDE + +#include "InertialFrame.cginc" +#include "InterlockedUtils.cginc" +#include "Integration.cginc" + +RWStructuredBuffer linearDeltasAsInt; +RWStructuredBuffer angularDeltasAsInt; + +struct rigidbody +{ + float4x4 inverseInertiaTensor; + float4 velocity; + float4 angularVelocity; + float4 com; + float inverseMass; + + int constraintCount; + int pad1; + int pad2; +}; + +StructuredBuffer rigidbodies; + +void CalculateContactMassesB(in rigidbody rb, + in transform t, + float4 pointB, + float4 normal, + float4 bitangent, + float4 tangent, + out float normalInvMassB, + out float tangentInvMassB, + out float bitangentInvMassB) +{ + float4 rB = t.TransformPoint(pointB) - rb.com; + + // initialize inverse linear masses: + normalInvMassB = tangentInvMassB = bitangentInvMassB = rb.inverseMass; + normalInvMassB += RotationalInvMass(rb.inverseInertiaTensor, rB, normal); + tangentInvMassB += RotationalInvMass(rb.inverseInertiaTensor, rB, tangent); + bitangentInvMassB += RotationalInvMass(rb.inverseInertiaTensor, rB, bitangent); +} + +float4 GetRigidbodyVelocityAtPoint(in rigidbody rb, + float4 pnt, + float4 linearDelta, + float4 angularDelta, + in inertialFrame frame) +{ + float4 linearVel = rb.velocity + linearDelta; + float4 angularVel = rb.angularVelocity + angularDelta; + float4 r = frame.frame.TransformPoint(pnt) - rb.com; + + // calculate rigidbody velocity. (point is assumed to be expressed in solver space, convert it to world space): + float4 wsRigidbodyVel = linearVel + float4(cross(angularVel.xyz, r.xyz), 0); + + // calculate solver velocity: + float4 wsSolverVelocity = frame.velocity + float4(cross(frame.angularVelocity.xyz, pnt.xyz), 0); + + // convert the resulting velocity back to solver space: + return frame.frame.InverseTransformVector(wsRigidbodyVel - wsSolverVelocity); +}; + +void AtomicAddLinearDelta(in int rigidbodyIndex, in float4 delta) +{ + InterlockedAddFloat(linearDeltasAsInt, rigidbodyIndex, 0, delta.x); + InterlockedAddFloat(linearDeltasAsInt, rigidbodyIndex, 1, delta.y); + InterlockedAddFloat(linearDeltasAsInt, rigidbodyIndex, 2, delta.z); +} + +void AtomicAddAngularDelta(in int rigidbodyIndex, in float4 delta) +{ + InterlockedAddFloat(angularDeltasAsInt, rigidbodyIndex, 0, delta.x); + InterlockedAddFloat(angularDeltasAsInt, rigidbodyIndex, 1, delta.y); + InterlockedAddFloat(angularDeltasAsInt, rigidbodyIndex, 2, delta.z); +} + +void ApplyImpulse(int rigidbodyIndex, + float4 impulse, + float4 pnt, + in transform frame) +{ + float4 impulseWS = frame.TransformVector(impulse); + float4 r = frame.TransformPoint(pnt) - rigidbodies[rigidbodyIndex].com; + + float4 linearDelta = rigidbodies[rigidbodyIndex].inverseMass * impulseWS; + float4 angularDelta = mul(rigidbodies[rigidbodyIndex].inverseInertiaTensor, float4(cross(r.xyz, impulseWS.xyz), 0)); + + AtomicAddLinearDelta (rigidbodyIndex, linearDelta); + AtomicAddAngularDelta(rigidbodyIndex, angularDelta); +} + +void ApplyDeltaQuaternion(int rigidbodyIndex, + quaternion rotation, + quaternion delta, + in transform frame, + float dt) +{ + quaternion rotationWS = qmul(frame.rotation, rotation); + quaternion deltaWS = qmul(frame.rotation, delta); + + // convert quaternion delta to angular acceleration: + quaternion newRotation = normalize(rotationWS + deltaWS); + AtomicAddAngularDelta(rigidbodyIndex, DifferentiateAngular(newRotation, rotationWS, dt)); +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/Rigidbody.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/Rigidbody.cginc.meta new file mode 100644 index 00000000..68dede37 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Rigidbody.cginc.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 157a770866f4047a5b8a08e6aca2f1bf +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/RopeChainRendering.compute b/xiaofang/Assets/Obi/Resources/Compute/RopeChainRendering.compute new file mode 100644 index 00000000..57ee32be --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/RopeChainRendering.compute @@ -0,0 +1,109 @@ +#pragma kernel UpdateChainMesh + +#include "PathFrame.cginc" + +struct chainRendererData +{ + int modifierOffset; + float twistAnchor; + float twist; + uint usesOrientedParticles; + + float4 scale; +}; + +struct chunkData +{ + int rendererIndex; + int offset; // index of the first element for each chunk. +}; + +struct linkModifier +{ + float3 translation; + float3 scale; + float3 rotation; + + void Clear() + { + translation = float3(0,0,0); + scale = float3(1,1,1); + rotation = float3(0,0,0); + } +}; + +StructuredBuffer rendererData; +StructuredBuffer chunksData; +StructuredBuffer modifiers; +StructuredBuffer elements; + +StructuredBuffer renderablePositions; +StructuredBuffer renderableOrientations; +StructuredBuffer principalRadii; +StructuredBuffer colors; +float4x4 solverToWorld; + +RWStructuredBuffer instanceTransforms; +RWStructuredBuffer invInstanceTransforms; +RWStructuredBuffer instanceColors; + +uint chunkCount; + +[numthreads(32, 1, 1)] +void UpdateChainMesh (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= chunkCount) return; + + int firstIndex = i > 0 ? chunksData[i - 1].offset : 0; + uint elementCount = chunksData[i].offset - firstIndex; + + int rendererIndex = chunksData[i].rendererIndex; + chainRendererData renderer = rendererData[rendererIndex]; + + int firstModifier = rendererIndex > 0 ? rendererData[rendererIndex - 1].modifierOffset : 0; + uint modifierCount = renderer.modifierOffset - firstModifier; + + linkModifier modifier; + modifier.Clear(); + + pathFrame frame; + frame.Reset(); + + float twist = -renderer.twist * elementCount * renderer.twistAnchor; + frame.SetTwist(twist); + + // parallel transport: + for (uint m = 0; m < elementCount; ++m) + { + if (modifierCount > 0) + modifier = modifiers[firstModifier + m % modifierCount]; + + int index = firstIndex + m; + float4 pos = renderablePositions[elements[index].x]; + float4 nextPos = renderablePositions[elements[index].y]; + float4 vect = nextPos - pos; + float3 tangent = normalizesafe(vect.xyz); + + if (renderer.usesOrientedParticles == 1) + { + frame.Transport(nextPos.xyz, tangent, rotate_vector(renderableOrientations[elements[index].x], float3(0, 1, 0)), twist); + twist += renderer.twist; + } + else + frame.Transport(nextPos.xyz, tangent, renderer.twist); + + if (modifierCount > 0) + modifier = modifiers[firstModifier + m % (uint)modifierCount]; + + quaternion rotation = q_look_at(frame.tangent, frame.normal); + float3 position = (pos + vect * 0.5f).xyz + rotate_vector(rotation, modifier.translation); + float3 scale = principalRadii[elements[index].x].x * 2 * renderer.scale.xyz * modifier.scale; + + rotation = qmul(rotation, q_eulerXYZ(radians(modifier.rotation))); + + instanceTransforms[index] = mul(solverToWorld, TRS(position,rotation,scale)); + invInstanceTransforms[index] = Inverse(instanceTransforms[index]); + instanceColors[index] = (colors[elements[index].x] + colors[elements[index].x]) * 0.5; + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/RopeChainRendering.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/RopeChainRendering.compute.meta new file mode 100644 index 00000000..a80ac9cb --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/RopeChainRendering.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 64a1b58e2d7634b3b905947b0c5e78c7 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/RopeExtrudedRendering.compute b/xiaofang/Assets/Obi/Resources/Compute/RopeExtrudedRendering.compute new file mode 100644 index 00000000..cdcb106c --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/RopeExtrudedRendering.compute @@ -0,0 +1,164 @@ +#pragma kernel UpdateRopeMesh + +#include "PathFrame.cginc" + +struct smootherPathData +{ + uint smoothing; + float decimation; + float twist; + float restLength; + float smoothLength; + uint usesOrientedParticles; +}; + +struct extrudedMeshData +{ + int sectionVertexCount; + float thicknessScale; + float uvAnchor; + uint normalizeV; + float2 uvScale; +}; + +StructuredBuffer pathSmootherIndices; +StructuredBuffer chunkOffsets; + +StructuredBuffer frames; +StructuredBuffer frameOffsets; +StructuredBuffer frameCounts; + +StructuredBuffer sectionData; +StructuredBuffer sectionOffsets; +StructuredBuffer sectionIndices; + +StructuredBuffer vertexOffsets; +StructuredBuffer triangleOffsets; +StructuredBuffer triangleCounts; + +StructuredBuffer extrudedData; +StructuredBuffer pathData; + +RWByteAddressBuffer vertices; +RWByteAddressBuffer tris; + +// Variables set from the CPU +uint firstRenderer; +uint rendererCount; + +pathFrame LookAt(pathFrame frame, in pathFrame target, out float dist) +{ + float3 tangent = target.position - frame.position; + dist = length(tangent); + tangent /= dist + EPSILON; + + quaternion rotQ = from_to_rotation(frame.tangent, tangent); + frame.normal = rotate_vector(rotQ, frame.normal); + frame.binormal = rotate_vector(rotQ, frame.binormal); + frame.tangent = tangent; + + return frame; +} + +[numthreads(128, 1, 1)] +void UpdateRopeMesh (uint3 id : SV_DispatchThreadID) +{ + unsigned int u = id.x; + if (u >= rendererCount) return; + + int k = firstRenderer + u; + int s = pathSmootherIndices[k]; + + float3 vertex = float3(0,0,0); + float3 normal = float3(0,0,0); + float4 texTangent = FLOAT4_ZERO; + + int tri = 0; + int sectionIndex = 0; + int sectionStart = sectionOffsets[sectionIndices[k]]; + int sectionSegments = (sectionOffsets[sectionIndices[k] + 1] - sectionStart) - 1; + int verticesPerSection = sectionSegments + 1; // the last vertex in each section must be duplicated, due to uv wraparound. + + float smoothLength = 0; + int i; + for (i = chunkOffsets[s]; i < chunkOffsets[s + 1]; ++i) + smoothLength += pathData[i].smoothLength; + + float vCoord = -extrudedData[k].uvScale.y * pathData[chunkOffsets[s]].restLength * extrudedData[k].uvAnchor; + float actualToRestLengthRatio = smoothLength / pathData[chunkOffsets[s]].restLength; + + int firstVertex = vertexOffsets[k]; + int firstTriangle = triangleOffsets[k]; + + // clear out triangle indices for this rope: + for (i = firstTriangle; i < firstTriangle + triangleCounts[k]; ++i) + { + int offset = i*3; + tris.Store((offset)<<2, 0); + tris.Store((offset+1)<<2,0); + tris.Store((offset+2)<<2,0); + } + + // for each chunk in the rope: + for (i = chunkOffsets[s]; i < chunkOffsets[s+1]; ++i) + { + int firstFrame = frameOffsets[i]; + int frameCount = frameCounts[i]; + + for (int f = 0; f < frameCount; ++f) + { + // Calculate previous and next curve indices: + int prevIndex = firstFrame + max(f - 1, 0); + int index = firstFrame + f; + + // advance v texcoord: + vCoord += extrudedData[k].uvScale.y * (distance(frames[index].position, frames[prevIndex].position) / + (extrudedData[k].normalizeV ? smoothLength : actualToRestLengthRatio)); + + // calculate section thickness and scale the basis vectors by it: + float sectionThickness = frames[index].thickness * extrudedData[k].thicknessScale; + + // Loop around each segment: + int nextSectionIndex = sectionIndex + 1; + for (int j = 0; j <= sectionSegments; ++j) + { + // make just one copy of the section vertex: + float2 sectionVertex = sectionData[sectionStart + j]; + + // calculate normal using section vertex, curve normal and binormal: + normal.x = (sectionVertex.x * frames[index].normal.x + sectionVertex.y * frames[index].binormal.x) * sectionThickness; + normal.y = (sectionVertex.x * frames[index].normal.y + sectionVertex.y * frames[index].binormal.y) * sectionThickness; + normal.z = (sectionVertex.x * frames[index].normal.z + sectionVertex.y * frames[index].binormal.z) * sectionThickness; + + // offset curve position by normal: + vertex.x = frames[index].position.x + normal.x; + vertex.y = frames[index].position.y + normal.y; + vertex.z = frames[index].position.z + normal.z; + + // cross(normal, curve tangent) + texTangent.xyz = cross(normal, frames[index].tangent); + texTangent.w = -1; + + int base = (firstVertex + sectionIndex * verticesPerSection + j) * 16; + vertices.Store3( base<<2, asuint(vertex)); + vertices.Store3((base + 3)<<2, asuint(normal)); + vertices.Store4((base + 6)<<2, asuint(texTangent)); + vertices.Store4((base + 10)<<2, asuint(frames[index].color)); + vertices.Store2((base + 14)<<2, asuint(float2(j / (float)sectionSegments * extrudedData[k].uvScale.x, vCoord))); + + if (j < sectionSegments && f < frameCount - 1) + { + int offset = firstTriangle * 3; + tris.Store((offset + tri++)<<2, asuint(firstVertex + sectionIndex * verticesPerSection + j)); + tris.Store((offset + tri++)<<2, asuint(firstVertex + nextSectionIndex * verticesPerSection + j)); + tris.Store((offset + tri++)<<2, asuint(firstVertex + sectionIndex * verticesPerSection + (j + 1))); + + tris.Store((offset + tri++)<<2, asuint(firstVertex + sectionIndex * verticesPerSection + (j + 1))); + tris.Store((offset + tri++)<<2, asuint(firstVertex + nextSectionIndex * verticesPerSection + j)); + tris.Store((offset + tri++)<<2, asuint(firstVertex + nextSectionIndex * verticesPerSection + (j + 1))); + } + } + sectionIndex++; + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/RopeExtrudedRendering.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/RopeExtrudedRendering.compute.meta new file mode 100644 index 00000000..2861b99f --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/RopeExtrudedRendering.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0d389c799c83d43f38f2486ab16fe902 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/RopeLineRendering.compute b/xiaofang/Assets/Obi/Resources/Compute/RopeLineRendering.compute new file mode 100644 index 00000000..8d3582ae --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/RopeLineRendering.compute @@ -0,0 +1,162 @@ +#pragma kernel UpdateLineMesh + +#include "PathFrame.cginc" + +struct smootherPathData +{ + uint smoothing; + float decimation; + float twist; + float restLength; + float smoothLength; + uint usesOrientedParticles; +}; + +struct lineMeshData +{ + float2 uvScale; + float thicknessScale; + float uvAnchor; + uint normalizeV; +}; + +StructuredBuffer pathSmootherIndices; +StructuredBuffer chunkOffsets; + +StructuredBuffer frames; +StructuredBuffer frameOffsets; +StructuredBuffer frameCounts; + +StructuredBuffer vertexOffsets; +StructuredBuffer triangleOffsets; +StructuredBuffer triangleCounts; + +StructuredBuffer rendererData; +StructuredBuffer pathData; + +RWByteAddressBuffer vertices; +RWByteAddressBuffer tris; + +// Variables set from the CPU +uint firstRenderer; +uint rendererCount; +float3 localSpaceCamera; + +pathFrame LookAt(pathFrame frame, in pathFrame target, out float dist) +{ + float3 tangent = target.position - frame.position; + dist = length(tangent); + tangent /= dist + EPSILON; + + quaternion rotQ = from_to_rotation(frame.tangent, tangent); + frame.normal = rotate_vector(rotQ, frame.normal); + frame.binormal = rotate_vector(rotQ, frame.binormal); + frame.tangent = tangent; + + return frame; +} + +[numthreads(128, 1, 1)] +void UpdateLineMesh (uint3 id : SV_DispatchThreadID) +{ + unsigned int u = id.x; + if (u >= rendererCount) return; + + int k = firstRenderer + u; + int s = pathSmootherIndices[k]; + + float3 vertex = float3(0,0,0); + float3 normal = float3(0,0,0); + float4 bitangent = FLOAT4_ZERO; + + int tri = 0; + int sectionIndex = 0; + int firstVertex = vertexOffsets[k]; + int firstTriangle = triangleOffsets[k]; + + float smoothLength = 0; + int i = 0; + for (i = chunkOffsets[s]; i < chunkOffsets[s + 1]; ++i) + smoothLength += pathData[i].smoothLength; + + float vCoord = -rendererData[k].uvScale.y * pathData[chunkOffsets[s]].restLength * rendererData[k].uvAnchor; + float actualToRestLengthRatio = smoothLength / pathData[chunkOffsets[s]].restLength; + + // clear out triangle indices for this rope: + for (i = firstTriangle; i < firstTriangle + triangleCounts[k]; ++i) + { + int offset = i*3; + tris.Store((offset)<<2, 0); + tris.Store((offset+1)<<2,0); + tris.Store((offset+2)<<2,0); + } + + // for each chunk in the rope: + for (i = chunkOffsets[s]; i < chunkOffsets[s+1]; ++i) + { + int firstFrame = frameOffsets[i]; + int frameCount = frameCounts[i]; + + for (int f = 0; f < frameCount; ++f) + { + // Calculate previous and next curve indices: + int prevIndex = firstFrame + max(f - 1, 0); + int index = firstFrame + f; + + // advance v texcoord: + vCoord += rendererData[k].uvScale.y * (distance(frames[index].position, frames[prevIndex].position) / + (rendererData[k].normalizeV == 1 ? smoothLength : actualToRestLengthRatio)); + + // calculate section thickness and scale the basis vectors by it: + float sectionThickness = frames[index].thickness * rendererData[k].thicknessScale; + + normal.x = frames[index].position.x - localSpaceCamera.x; + normal.y = frames[index].position.y - localSpaceCamera.y; + normal.z = frames[index].position.z - localSpaceCamera.z; + normal = normalize(normal); + + bitangent.x = -(normal.y * frames[index].tangent.z - normal.z * frames[index].tangent.y); + bitangent.y = -(normal.z * frames[index].tangent.x - normal.x * frames[index].tangent.z); + bitangent.z = -(normal.x * frames[index].tangent.y - normal.y * frames[index].tangent.x); + bitangent.xyz = normalize(bitangent.xyz); + bitangent.w = 1; + + vertex.x = frames[index].position.x - bitangent.x * sectionThickness; + vertex.y = frames[index].position.y - bitangent.y * sectionThickness; + vertex.z = frames[index].position.z - bitangent.z * sectionThickness; + + int base = (firstVertex + sectionIndex * 2) * 16; + vertices.Store3( base<<2, asuint(vertex)); + vertices.Store3((base + 3)<<2, asuint(-normal)); + vertices.Store4((base + 6)<<2, asuint(bitangent)); + vertices.Store4((base + 10)<<2, asuint(frames[index].color)); + vertices.Store2((base + 14)<<2, asuint(float2(0, vCoord))); + + vertex.x = frames[index].position.x + bitangent.x * sectionThickness; + vertex.y = frames[index].position.y + bitangent.y * sectionThickness; + vertex.z = frames[index].position.z + bitangent.z * sectionThickness; + + base = (firstVertex + sectionIndex * 2 + 1) * 16; + vertices.Store3( base<<2, asuint(vertex)); + vertices.Store3((base + 3)<<2, asuint(-normal)); + vertices.Store4((base + 6)<<2, asuint(bitangent)); + vertices.Store4((base + 10)<<2, asuint(frames[index].color)); + vertices.Store2((base + 14)<<2, asuint(float2(1, vCoord))); + + if (f < frameCount - 1) + { + + int offset = firstTriangle * 3; + tris.Store((offset + tri++)<<2, asuint(firstVertex + sectionIndex * 2)); + tris.Store((offset + tri++)<<2, asuint(firstVertex + (sectionIndex + 1) * 2)); + tris.Store((offset + tri++)<<2, asuint(firstVertex + sectionIndex * 2 + 1)); + + tris.Store((offset + tri++)<<2, asuint(firstVertex + sectionIndex * 2 + 1)); + tris.Store((offset + tri++)<<2, asuint(firstVertex + (sectionIndex + 1) * 2)); + tris.Store((offset + tri++)<<2, asuint(firstVertex + (sectionIndex + 1) * 2 + 1)); + } + + sectionIndex++; + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/RopeLineRendering.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/RopeLineRendering.compute.meta new file mode 100644 index 00000000..05e0afc7 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/RopeLineRendering.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d9fce691efd9941a78e1e74355ec3d84 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/RopeMeshRendering.compute b/xiaofang/Assets/Obi/Resources/Compute/RopeMeshRendering.compute new file mode 100644 index 00000000..f12fc2dc --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/RopeMeshRendering.compute @@ -0,0 +1,218 @@ +#pragma kernel UpdateRopeMesh + +#include "PathFrame.cginc" + +struct ropeMeshData +{ + uint axis; + float volumeScaling; + uint stretchWithRope; + uint spanEntireLength; + uint instances; + float instanceSpacing; + float offset; + float meshSizeAlongAxis; + float4 scale; +}; + +struct smootherPathData +{ + uint smoothing; + float decimation; + float twist; + float restLength; + float smoothLength; + uint usesOrientedParticles; +}; + +struct MeshData +{ + int firstVertex; + int vertexCount; + + int firstTriangle; + int triangleCount; +}; + +StructuredBuffer pathSmootherIndices; +StructuredBuffer chunkOffsets; + +StructuredBuffer frames; +StructuredBuffer frameOffsets; +StructuredBuffer frameCounts; + +StructuredBuffer vertexOffsets; + +StructuredBuffer meshIndices; +StructuredBuffer meshData; + +StructuredBuffer sortedIndices; +StructuredBuffer sortedOffsets; + +StructuredBuffer rendererData; +StructuredBuffer pathData; + +StructuredBuffer positions; +StructuredBuffer normals; +StructuredBuffer tangents; +StructuredBuffer colors; + +RWByteAddressBuffer vertices; + +// Variables set from the CPU +uint firstRenderer; +uint rendererCount; + +pathFrame InterpolateFrames(pathFrame a, pathFrame b, float3 bOffset, float t) +{ + // this offset is used to displace a copy of the first and last frames of the path, + // to ensure meshes extrude correctly prior to the first or past the last frame. + b.position += bOffset; + pathFrame interp = addFrames(multiplyFrame(1 - t, a) ,multiplyFrame(t , b)); + + // (no need to renormalize tangent, since offsetFromCurve[axis] = 0) + interp.normal = normalize(interp.normal); + interp.binormal = normalize(interp.binormal); + return interp; +} + +[numthreads(16, 1, 1)] +void UpdateRopeMesh (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= rendererCount) return; + + int rendererIndex = firstRenderer + i; + int pathIndex = pathSmootherIndices[rendererIndex]; + ropeMeshData renderer = rendererData[rendererIndex]; + + // get mesh data: + MeshData mesh = meshData[meshIndices[rendererIndex]]; + int sortedOffset = sortedOffsets[rendererIndex]; + + // get index of first output vertex: + int firstOutputVertex = vertexOffsets[rendererIndex]; + + // get index of first chunk, ignore others (no support for tearing): + int chunkIndex = chunkOffsets[pathIndex]; + + // get first frame and frame count: + int firstFrame = frameOffsets[chunkIndex]; + int lastFrame = firstFrame + frameCounts[chunkIndex] - 1; + + // get mesh deform axis: + int axis = renderer.axis; + + // initialize scale vector: + float3 actualScale = renderer.scale.xyz; + + // calculate stretch ratio: + float stretchRatio = renderer.stretchWithRope == 1 ? pathData[chunkIndex].smoothLength / pathData[chunkIndex].restLength : 1; + + // squashing factor, makes mesh thinner when stretched and thicker when compresssed. + float squashing = clamp(1 + renderer.volumeScaling * (1 / max(stretchRatio, 0.01f) - 1), 0.01f, 2); + + // calculate scale along swept axis so that the mesh spans the entire lenght of the rope if required. + if (renderer.spanEntireLength == 1) + { + float totalMeshLength = renderer.meshSizeAlongAxis * renderer.instances; + float totalSpacing = renderer.instanceSpacing * (renderer.instances - 1); + float axisScale = pathData[chunkIndex].restLength / (totalMeshLength + totalSpacing); + + if (axis == 0) actualScale.x = axisScale; + else if (axis == 1) actualScale.y = axisScale; + else actualScale.z = axisScale; + } + + // init loop variables: + float lengthAlongAxis = renderer.offset; + int index = firstFrame; + int nextIndex = firstFrame + 1; + int prevIndex = firstFrame; + float nextMagnitude = distance(frames[index].position, frames[nextIndex].position); + float prevMagnitude = nextMagnitude; + + + for (int j = 0; j < mesh.vertexCount; ++j) + { + int base = (firstOutputVertex + sortedIndices[sortedOffset + j]) * 14; + vertices.Store3(base << 2, asuint(positions[mesh.firstVertex + sortedIndices[sortedOffset + j]] * float3(0.5,1,1))); + } + + for (int k = 0; k < (int)renderer.instances; ++k) + { + for (int j = 0; j < mesh.vertexCount; ++j) + { + int currVIndex = mesh.firstVertex + sortedIndices[sortedOffset + j]; + int prevVIndex = mesh.firstVertex + sortedIndices[sortedOffset + max(0,j - 1)]; + + // calculate how much we've advanced in the sort axis since the last vertex: + lengthAlongAxis += (positions[currVIndex][axis] - positions[prevVIndex][axis]) * actualScale[axis] * stretchRatio; + + // check if we have moved to a new section of the curve: + pathFrame frame; + if (lengthAlongAxis < 0) + { + while (-lengthAlongAxis > prevMagnitude && index > firstFrame) + { + lengthAlongAxis += prevMagnitude; + index = max(index - 1, firstFrame); + nextIndex = min(index + 1, lastFrame); + prevIndex = max(index - 1, firstFrame); + nextMagnitude = distance(frames[index].position, frames[nextIndex].position); + prevMagnitude = distance(frames[index].position, frames[prevIndex].position); + } + + float3 offset = float3(0,0,0); + if (index == prevIndex) + { + offset = frames[index].position - frames[nextIndex].position; + prevMagnitude = length(offset); + } + + frame = InterpolateFrames(frames[index], frames[prevIndex], offset, -lengthAlongAxis / prevMagnitude); + } + else + { + while (lengthAlongAxis > nextMagnitude && index < lastFrame) + { + lengthAlongAxis -= nextMagnitude; + index = min(index + 1, lastFrame); + nextIndex = min(index + 1, lastFrame); + prevIndex = max(index - 1, firstFrame); + nextMagnitude = distance(frames[index].position, frames[nextIndex].position); + prevMagnitude = distance(frames[index].position, frames[prevIndex].position); + } + + float3 offset = float3(0,0,0); + if (index == nextIndex) + { + offset = frames[index].position - frames[prevIndex].position; + nextMagnitude = length(offset); + } + + frame = InterpolateFrames(frames[index], frames[nextIndex], offset, lengthAlongAxis / nextMagnitude); + } + + // update basis matrix: + float3x3 basis = frame.ToMatrix(axis); + + // calculate vertex offset from curve: + float3 offsetFromCurve = positions[currVIndex] * actualScale * frame.thickness * squashing; + if (axis == 0) offsetFromCurve.x = 0; + else if (axis == 1) offsetFromCurve.y = 0; + else offsetFromCurve.z = 0; + + // write modified vertex data: + int base = (firstOutputVertex + sortedIndices[sortedOffset + j]) * 14; + vertices.Store3( base<<2, asuint(frame.position + mul(basis, offsetFromCurve))); + vertices.Store3((base + 3)<<2, asuint(mul(basis, normals[currVIndex]))); + vertices.Store4((base + 6)<<2, asuint(float4(mul(basis, tangents[currVIndex].xyz), tangents[currVIndex].w))); + vertices.Store4((base + 10)<<2, asuint(frames[index].color)); + } + + firstOutputVertex += mesh.vertexCount; + lengthAlongAxis += renderer.instanceSpacing * actualScale[axis] * stretchRatio; + } + +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/RopeMeshRendering.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/RopeMeshRendering.compute.meta new file mode 100644 index 00000000..fbe83db5 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/RopeMeshRendering.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 68510b7d06c3544fba668628be450928 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/Scan.compute b/xiaofang/Assets/Obi/Resources/Compute/Scan.compute new file mode 100644 index 00000000..dc961d99 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Scan.compute @@ -0,0 +1,78 @@ +#pragma kernel ScanInBucketExclusive +#pragma kernel ScanAddBucketResult + +#define THREADS_PER_GROUP 512 // Ensure that this equals the 'threadsPerGroup' const in the host script. Must be an odd power of 2. + +// These must be a multiple of THREADS_PER_GROUP. +StructuredBuffer _Input; +RWStructuredBuffer _Result; +RWStructuredBuffer _BlockSum; +uint count; + +groupshared uint bucket[THREADS_PER_GROUP]; + +// Scan in each bucket. +[numthreads(THREADS_PER_GROUP, 1, 1)] +void ScanInBucketExclusive(uint DTid : SV_DispatchThreadID, uint Gid : SV_GroupID, uint GI : SV_GroupIndex) +{ + if (DTid < count) { + bucket[GI] = _Input[DTid]; + } else { + bucket[GI] = 0; + } + + GroupMemoryBarrierWithGroupSync(); + + uint stride; + + // up-sweep + [unroll] + for (stride = 2; stride <= THREADS_PER_GROUP; stride <<= 1) + { + GroupMemoryBarrierWithGroupSync(); + if (((GI + 1) % stride) == 0) + { + const uint half_stride = (stride >> 1); + bucket[GI] += bucket[GI - half_stride]; + } + } + + // Without this barrier, setting tg_mem[-1] to 0 may not be properly + // propagated across the entire threadgroup. + GroupMemoryBarrierWithGroupSync(); + if (GI == THREADS_PER_GROUP - 1) + { + // clear the last element + _BlockSum[Gid] = bucket[GI]; + bucket[GI] = 0; + } + + // down-sweep + [unroll] + for (stride = THREADS_PER_GROUP; stride > 1; stride >>= 1) + { + GroupMemoryBarrierWithGroupSync(); + + if (((GI + 1) % stride) == 0) + { + const uint half_stride = (stride >> 1); + const uint prev_idx = GI - half_stride; + const int tmp = bucket[prev_idx]; + bucket[prev_idx] = bucket[GI]; + bucket[GI] += tmp; + } + } + + GroupMemoryBarrierWithGroupSync(); + + if (DTid < count) + _Result[DTid] = bucket[GI]; +} + +// Add the bucket scanned result to each bucket to get the final result. +[numthreads(THREADS_PER_GROUP, 1, 1)] +void ScanAddBucketResult(uint DTid : SV_DispatchThreadID, uint Gid : SV_GroupID) +{ + if (DTid < count) + _Result[DTid] += _Input[Gid]; +} diff --git a/xiaofang/Assets/Obi/Resources/Compute/Scan.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/Scan.compute.meta new file mode 100644 index 00000000..4b20551d --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Scan.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7124bb82b9af4476c8de8e82d7f8caba +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/ShapeMatchingConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/ShapeMatchingConstraints.compute new file mode 100644 index 00000000..79d671b3 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ShapeMatchingConstraints.compute @@ -0,0 +1,266 @@ +#pragma kernel CalculateRestShapeMatching +#pragma kernel PlasticDeformation +#pragma kernel Project +#pragma kernel Apply + +#include "MathUtils.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer particleIndices; +StructuredBuffer firstIndex; +StructuredBuffer numIndices; +StructuredBuffer explicitGroup; +StructuredBuffer shapeMaterialParameters; + +RWStructuredBuffer RW_restComs; +RWStructuredBuffer coms; +RWStructuredBuffer constraintOrientations; + +RWStructuredBuffer RW_Aqq; +RWStructuredBuffer RW_linearTransforms; +RWStructuredBuffer RW_deformation; + +RWStructuredBuffer RW_positions; +RWStructuredBuffer orientations; + +StructuredBuffer restComs; +StructuredBuffer Aqq; +StructuredBuffer linearTransforms; +StructuredBuffer deformation; + +StructuredBuffer positions; +StructuredBuffer restPositions; +StructuredBuffer restOrientations; +StructuredBuffer invMasses; +StructuredBuffer invRotationalMasses; +StructuredBuffer principalRadii; + +// Variables set from the CPU +uint activeConstraintCount; +float deltaTime; +float sorFactor; + +void RecalculateRestData(uint i) +{ + int k = 0; + float maximumMass = 10000; + + // initialize rest center of mass and shape matrix: + RW_restComs[i] = FLOAT4_ZERO; + RW_Aqq[i] = FLOAT4X4_ZERO; + + float4 restCom = FLOAT4_ZERO; + float4x4 _Aqq = FLOAT4X4_ZERO, _Rqq = FLOAT4X4_ZERO; + + // calculate rest center of mass, shape mass and RW_Aqq matrix. + for (int j = 0; j < numIndices[i]; ++j) + { + k = particleIndices[firstIndex[i] + j]; + + float mass = maximumMass; + if (invMasses[k] > 1.0f / maximumMass) + mass = 1.0f / invMasses[k]; + + restCom += restPositions[k] * mass; + + float4x4 particleR = q_toMatrix(restOrientations[k]); + particleR[3][3] = 0; + + _Rqq += mul(particleR, + mul(AsDiagonal(GetParticleInertiaTensor(principalRadii[k],invRotationalMasses[k])), + transpose(particleR)) + ); + + float4 restPosition = restPositions[k]; + restPosition[3] = 0; + + _Aqq += mass * multrnsp4(restPosition, restPosition); + } + + if (restCom[3] < EPSILON) + return; + + restCom.xyz /= restCom[3]; + RW_restComs[i] = restCom; + + restCom[3] = 0; + _Aqq -= RW_restComs[i][3] * multrnsp4(restCom, restCom); + _Aqq[3][3] = 1; // so that the determinant is never 0 due to all-zeros row/column. + + RW_Aqq[i] = Inverse(_Rqq + mul(RW_deformation[i], mul(_Aqq, transpose(RW_deformation[i])))); + +} + +[numthreads(128, 1, 1)] +void CalculateRestShapeMatching (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + RecalculateRestData(i); +} + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int k; + float maximumMass = 10000; + + coms[i] = FLOAT4_ZERO; + float4x4 Apq = FLOAT4X4_ZERO, Rpq = FLOAT4X4_ZERO; + + // calculate shape mass, center of mass, and moment matrix: + int j; + for (j = 0; j < numIndices[i]; ++j) + { + k = particleIndices[firstIndex[i] + j]; + + float mass = maximumMass; + if (invMasses[k] > 1.0f / maximumMass) + mass = 1.0f / invMasses[k]; + + coms[i] += positions[k] * mass; + + float4x4 particleR = q_toMatrix(orientations[k]); + float4x4 particleRT = q_toMatrix(restOrientations[k]); + particleR[3][3] = 0; + particleRT[3][3] = 0; + + Rpq += mul(particleR, + mul(AsDiagonal(GetParticleInertiaTensor(principalRadii[k],invRotationalMasses[k])), + transpose(particleRT)) + ); + + float4 restPosition = restPositions[k]; + restPosition[3] = 0; + + Apq += mass * multrnsp4(positions[k], restPosition); + } + + if (restComs[i][3] < EPSILON) + return; + + coms[i] /= restComs[i][3]; + + // subtract global shape moment: + float4 restCom = restComs[i]; + restCom[3] = 0; + + Apq -= restComs[i][3] * multrnsp4(coms[i], restCom); + + // calculate optimal transform including plastic deformation: + float4x4 Apq_def = Rpq + mul(Apq, transpose(deformation[i])); + Apq_def[3][3] = 1; + + // reconstruct full best-matching linear transform: + RW_linearTransforms[i] = mul(Apq_def, Aqq[i]); + + // extract rotation from transform matrix, using warmstarting and few iterations: + constraintOrientations[i] = ExtractRotation(Apq_def, constraintOrientations[i], 5); + + // calculate particle orientations: + if (explicitGroup[i] > 0) + { + // if the group is explicit, set the orientation for all particles: + for (int j = 0; j < numIndices[i]; ++j) + { + k = particleIndices[firstIndex[i] + j]; + orientations[k] = qmul(constraintOrientations[i], restOrientations[k]); + } + } + else + { + // set orientation of center particle only: + int centerIndex = particleIndices[firstIndex[i]]; + orientations[centerIndex] = qmul(constraintOrientations[i], restOrientations[centerIndex]); + } + + // finally, obtain rotation matrix: + float4x4 R = q_toMatrix(constraintOrientations[i]); + R[3][3] = 0; + float4x4 transform = mul(R,deformation[i]); + + // calculate and accumulate particle goal positions: + float4 goal, delta; + for (j = 0; j < numIndices[i]; ++j) + { + k = particleIndices[firstIndex[i] + j]; + goal = coms[i] + mul(transform, restPositions[k] - restComs[i]); + delta = (goal - positions[k]) * shapeMaterialParameters[i * 5]; + + AddPositionDelta(k, delta); + } +} + +[numthreads(128, 1, 1)] +void PlasticDeformation (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= activeConstraintCount) return; + + // get plastic deformation parameters: + float plastic_yield = shapeMaterialParameters[i * 5 + 1]; + float plastic_creep = shapeMaterialParameters[i * 5 + 2]; + float plastic_recovery = shapeMaterialParameters[i * 5 + 3]; + float max_deform = shapeMaterialParameters[i * 5 + 4]; + + // if we are allowed to absorb deformation: + if (plastic_creep > 0) + { + //obtain rotation matrix: + float4x4 R = q_toMatrix(constraintOrientations[i]); + R[3][3] = 1; + + // get scale matrix (A = RS so S = Rt * A) and its deviation from the identity matrix: + float4x4 deform_matrix = mul(transpose(R), linearTransforms[i]) - FLOAT4X4_IDENTITY; + + // if the amount of deformation exceeds the yield threshold: + float norm = FrobeniusNorm(deform_matrix); + if (norm > plastic_yield) + { + // deform the shape permanently: + RW_deformation[i] = mul(FLOAT4X4_IDENTITY + plastic_creep * deform_matrix, RW_deformation[i]); + + // clamp deformation so that it does not exceed a percentage; + deform_matrix = RW_deformation[i] - FLOAT4X4_IDENTITY; + norm = FrobeniusNorm(deform_matrix); + if (norm > max_deform) + { + RW_deformation[i] = FLOAT4X4_IDENTITY + max_deform * deform_matrix / norm; + } + + // if we cannot recover from plastic deformation, recalculate rest shape now: + if (plastic_recovery == 0) + RecalculateRestData(i); + } + } + + // if we can recover from plastic deformation, lerp towards non-deformed shape and recalculate rest shape: + if (plastic_recovery > 0) + { + RW_deformation[i] += (FLOAT4X4_IDENTITY - RW_deformation[i]) * min(plastic_recovery * deltaTime, 1.0f); + RecalculateRestData(i); + } +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int first = firstIndex[i]; + int last = first + numIndices[i]; + + for (int k = first; k < last; ++k) + { + int p = particleIndices[k]; + ApplyPositionDelta(RW_positions, p, sorFactor); + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/ShapeMatchingConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/ShapeMatchingConstraints.compute.meta new file mode 100644 index 00000000..ea486ca8 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/ShapeMatchingConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 18ba9336feedf4902b78736cf9abdaa8 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/Simplex.cginc b/xiaofang/Assets/Obi/Resources/Compute/Simplex.cginc new file mode 100644 index 00000000..9fc762e3 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Simplex.cginc @@ -0,0 +1,89 @@ +#ifndef SIMPLEX_INCLUDE +#define SIMPLEX_INCLUDE + +#include "Optimization.cginc" + +uint pointCount; +uint edgeCount; +uint triangleCount; + +int GetSimplexStartAndSize(in uint index, out uint size) +{ + size = 0; + int start = 0; + + if (index < triangleCount) + { + size = 3; + start = index * 3; + } + else if (index < triangleCount + edgeCount) + { + size = 2; + start = triangleCount * 3 + (index - triangleCount) * 2; + } + else if (index < triangleCount + edgeCount + pointCount) + { + size = 1; + start = triangleCount * 3 + edgeCount * 2 + (index - triangleCount - edgeCount); + } + return start; +} + +float4 BarycenterForSimplexOfSize(in int simplexSize) +{ + switch(simplexSize) + { + case 1: return float4(1,0,0,0); + case 2: return float4(0.5,0.5,0,0); + case 3: return float4(1/3.0,1/3.0,1/3.0,0); + case 4: return float4(0.25,0.25,0.25,0.25); + default: return float4(1,0,0,0); + } +} + +struct Simplex : IDistanceFunction +{ + StructuredBuffer positions; + StructuredBuffer radii; + StructuredBuffer simplices; + + int simplexStart; + int simplexSize; + + void Evaluate(in float4 pos, in float4 radii, in quaternion orientation, inout SurfacePoint projectedPoint) + { + switch (simplexSize) + { + case 1: + default: + { + float4 p1 = positions[simplices[simplexStart]]; p1.w = 0; + projectedPoint.bary = float4(1, 0, 0, 0); + projectedPoint.pos = p1; + } + break; + case 2: + { + float4 p1 = positions[simplices[simplexStart]]; p1.w = 0; + float4 p2 = positions[simplices[simplexStart + 1]]; p2.w = 0; + float mu; + NearestPointOnEdge(p1, p2, pos, mu); + projectedPoint.bary = float4(1 - mu, mu, 0, 0); + projectedPoint.pos = p1 * projectedPoint.bary[0] + p2 * projectedPoint.bary[1]; + + }break; + case 3: + { + CachedTri tri; + tri.Cache(float4(positions[simplices[simplexStart]].xyz,0), + float4(positions[simplices[simplexStart + 1]].xyz,0), + float4(positions[simplices[simplexStart + 2]].xyz,0)); + projectedPoint.pos = NearestPointOnTri(tri, pos, projectedPoint.bary); + }break; + } + projectedPoint.normal = normalizesafe(pos - projectedPoint.pos); + } + +}; +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/Simplex.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/Simplex.cginc.meta new file mode 100644 index 00000000..a695ffd7 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Simplex.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d8eeb7300d95c4653a91d905aaaf5344 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/SkinConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/SkinConstraints.compute new file mode 100644 index 00000000..c3714990 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SkinConstraints.compute @@ -0,0 +1,71 @@ +#pragma kernel Project +#pragma kernel Apply + +#include "MathUtils.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer particleIndices; +StructuredBuffer skinPoints; +StructuredBuffer skinNormals; +StructuredBuffer skinRadiiBackstop; +StructuredBuffer skinCompliance; +RWStructuredBuffer lambdas; + +RWStructuredBuffer positions; +StructuredBuffer invMasses; + +// Variables set from the CPU +uint activeConstraintCount; +float deltaTime; +float sorFactor; + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + float radius = skinRadiiBackstop[i].x; + float collisionRadius = skinRadiiBackstop[i].y; + float backstopDistance = collisionRadius + skinRadiiBackstop[i].z; + + float compliance = skinCompliance[i] / (deltaTime * deltaTime); + int p = particleIndices[i]; + + if (invMasses[p] > 0) + { + float4 toSkin = positions[p] - skinPoints[i]; + float4 toBackstop = positions[p] - (skinPoints[i] - skinNormals[i] * backstopDistance); + + // distance to skin and backstop sphere centers: + float d = length(toSkin); + float b = length(toBackstop); + + // constrain particle within skin radius. + // ignore mass in the equations (use 1), as we don't want particle mass to interfere with skin compliance. + // We should be able to adjust skin properties and particle mass (for collisions) independently. + float constraint = max(0,d - radius); + float dlambda = (-constraint - compliance * lambdas[i]) / (1 + compliance); + lambdas[i] += dlambda; + float4 skinCorrection = dlambda * toSkin / (d + EPSILON); + + // constrain particle outside the backstop sphere (0 compliance): + constraint = min(0, b - collisionRadius); + float4 backstopCorrection = - constraint * toBackstop / (b + EPSILON); + + AddPositionDelta(p, skinCorrection + backstopCorrection); + } +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p1 = particleIndices[i]; + + ApplyPositionDelta(positions, p1, sorFactor); +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/SkinConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/SkinConstraints.compute.meta new file mode 100644 index 00000000..92eeacff --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SkinConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2bec2152263654b08b1639ececa4ced6 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/SoftbodyRendering.compute b/xiaofang/Assets/Obi/Resources/Compute/SoftbodyRendering.compute new file mode 100644 index 00000000..1afb27c9 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SoftbodyRendering.compute @@ -0,0 +1,145 @@ +#pragma kernel UpdateSoftbodyMesh + +#include "MathUtils.cginc" + +struct Influence +{ + int index; + float weight; +}; + +struct SkinmapData +{ + int firstInfluence; + int firstInfNumber; + int firstParticleBindPose; + + int firstSkinWeight; + int firstSkinWeightNumber; + int firstBoneBindPose; + + int bindPoseCount; +}; + +struct SkeletonData +{ + int firstBone; + int boneCount; +}; + +struct MeshData +{ + int firstVertex; + int vertexCount; + + int firstTriangle; + int triangleCount; +}; + +StructuredBuffer particleIndices; +StructuredBuffer rendererIndices; // for each vertex/particle, index of its renderer. + +StructuredBuffer renderablePositions; +StructuredBuffer renderableOrientations; + +StructuredBuffer restPositions; +StructuredBuffer restOrientations; +StructuredBuffer colors; + +StructuredBuffer skinConstraintOffsets; + +StructuredBuffer skinmapIndices; // for each renderer, index of its skinmap. +StructuredBuffer meshIndices; // for each renderer, index of its mesh. +StructuredBuffer skeletonIndices; // for each renderer, index of its skeleton. + +StructuredBuffer particleOffsets; // for each renderer, index of its first particle in the batch. +StructuredBuffer vertexOffsets; // for each renderer, index of its first vertex in the batch. + +StructuredBuffer skinData; +StructuredBuffer influences; +StructuredBuffer influenceOffsets; +StructuredBuffer bindPoses; + +StructuredBuffer skeletonData; +StructuredBuffer bonePos; +StructuredBuffer boneRot; +StructuredBuffer boneScl; + +StructuredBuffer meshData; +StructuredBuffer positions; +StructuredBuffer normals; +StructuredBuffer tangents; + +RWByteAddressBuffer vertices; + +// Variables set from the CPU +uint vertexCount; +float4x4 world2Solver; + +[numthreads(128, 1, 1)] +void UpdateSoftbodyMesh (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= vertexCount) return; + + int rendererIndex = rendererIndices[i]; + + // get skin map and mesh data: + SkinmapData skin = skinData[skinmapIndices[rendererIndex]]; + MeshData mesh = meshData[meshIndices[rendererIndex]]; + SkeletonData skel = skeletonData[skeletonIndices[rendererIndex]]; + + // get index of this vertex in its original mesh: + int originalVertexIndex = i - vertexOffsets[rendererIndex]; + + // get index of the vertex in the mesh batch: + int batchedVertexIndex = mesh.firstVertex + originalVertexIndex; + + // get first influence and amount of influences for this vertex: + int influenceStart = influenceOffsets[skin.firstInfNumber + originalVertexIndex]; + int influenceCount = influenceOffsets[skin.firstInfNumber + originalVertexIndex + 1] - influenceStart; + + float3 position = float3(0,0,0); + float3 normal = float3(0,0,0); + float4 tangent = FLOAT4_ZERO; + float4 color = FLOAT4_ZERO; + + for (int k = influenceStart; k < influenceStart + influenceCount; ++k) + { + Influence inf = influences[skin.firstInfluence + k]; + float4x4 trfm; + + if (inf.index < skin.bindPoseCount) // bone influence: + { + int boneIndex = skel.firstBone + inf.index; + int bindIndex = skin.firstParticleBindPose + inf.index; + + float4x4 bind = bindPoses[bindIndex]; + + float4x4 deform = inf.index < skel.boneCount ? TRS(bonePos[boneIndex], boneRot[boneIndex], boneScl[boneIndex]) : FLOAT4X4_IDENTITY; + + // bone skinning leaves vertices in world space, so convert to solver space afterwards: + trfm = mul(world2Solver, mul(deform, bind)); + } + else // particle influence + { + int p = particleIndices[particleOffsets[rendererIndex] + inf.index - skin.bindPoseCount]; + + float4x4 deform = mul(m_translate(FLOAT4X4_IDENTITY,renderablePositions[p].xyz), q_toMatrix(renderableOrientations[p])); + trfm = mul(deform, bindPoses[skin.firstParticleBindPose + inf.index]); + color += colors[p] * inf.weight; + } + + // update vertex/normal/tangent: + position += mul(trfm, float4(positions[batchedVertexIndex], 1)).xyz * inf.weight; + normal += mul(trfm, float4(normals[batchedVertexIndex], 0)).xyz * inf.weight; + tangent += float4(mul(trfm, float4(tangents[batchedVertexIndex].xyz, 0)).xyz, tangents[batchedVertexIndex].w) * inf.weight; + } + + int base = i * 14; + vertices.Store3( base<<2, asuint(position)); + vertices.Store3((base + 3)<<2, asuint(normal)); + vertices.Store4((base + 6)<<2, asuint(tangent)); + vertices.Store4((base + 10)<<2, asuint(color)); +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/SoftbodyRendering.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/SoftbodyRendering.compute.meta new file mode 100644 index 00000000..4ae05f36 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SoftbodyRendering.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 805ca20f71b034180a1ab0ba707928be +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/Solver.compute b/xiaofang/Assets/Obi/Resources/Compute/Solver.compute new file mode 100644 index 00000000..ad188dc0 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Solver.compute @@ -0,0 +1,240 @@ +#pragma kernel ApplyInertialForces +#pragma kernel ApplyRigidbodyDeltas +#pragma kernel StoreStartState +#pragma kernel PredictPositions +#pragma kernel UpdateVelocities +#pragma kernel UpdatePositions +#pragma kernel Interpolate + +#include "Bounds.cginc" +#include "Integration.cginc" +#include "CollisionMaterial.cginc" +#include "SolverParameters.cginc" +#include "MathUtils.cginc" +#include "Rigidbody.cginc" + +StructuredBuffer simplices; +StructuredBuffer activeParticles; +StructuredBuffer invMasses; +StructuredBuffer invRotationalMasses; +StructuredBuffer phases; +StructuredBuffer buoyancies; +StructuredBuffer fluidRadii; + +StructuredBuffer R_startPositions; +StructuredBuffer R_endPositions; +StructuredBuffer R_startOrientations; +StructuredBuffer R_endOrientations; + +RWStructuredBuffer positions; +RWStructuredBuffer orientations; +RWStructuredBuffer principalRadii; +RWStructuredBuffer startPositions; +RWStructuredBuffer endPositions; +RWStructuredBuffer startOrientations; +RWStructuredBuffer endOrientations; +RWStructuredBuffer renderablePositions; +RWStructuredBuffer renderableOrientations; +RWStructuredBuffer renderableRadii; +RWStructuredBuffer prevPositions; +RWStructuredBuffer prevOrientations; +RWStructuredBuffer velocities; +RWStructuredBuffer angularVelocities; + +RWStructuredBuffer externalForces; +RWStructuredBuffer externalTorques; + +RWStructuredBuffer linearDeltas; +RWStructuredBuffer angularDeltas; + +// Variables set from the CPU +uint particleCount; + +float deltaTime; +float blendFactor; +float velocityScale; + +float4 angularVel; +float4 inertialAccel; +float4 eulerAccel; + +[numthreads(128, 1, 1)] +void ApplyInertialForces(uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= particleCount) return; + + int p = activeParticles[i]; + + if (invMasses[p] > 0) + { + float4 euler = float4(cross(eulerAccel.xyz, positions[p].xyz), 0); + float4 centrifugal = float4(cross(angularVel.xyz, cross(angularVel.xyz, positions[p].xyz)), 0); + float4 coriolis = 2 * float4(cross(angularVel.xyz, velocities[p].xyz), 0); + float4 angularAccel = euler + coriolis + centrifugal; + + velocities[p] -= (inertialAccel * worldLinearInertiaScale + angularAccel * worldAngularInertiaScale) * deltaTime; + } +} + +[numthreads(128, 1, 1)] +void ApplyRigidbodyDeltas (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= particleCount) return; + + linearDeltas[i].xyz = float3(asfloat(linearDeltasAsInt[i].x), + asfloat(linearDeltasAsInt[i].y), + asfloat(linearDeltasAsInt[i].z)); + + angularDeltas[i].xyz = float3(asfloat(angularDeltasAsInt[i].x), + asfloat(angularDeltasAsInt[i].y), + asfloat(angularDeltasAsInt[i].z)); +} + +[numthreads(128, 1, 1)] +void StoreStartState (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= particleCount) return; + + startPositions[i] = endPositions[i]; + startOrientations[i] = endOrientations[i]; + + endPositions[i] = positions[i]; + endOrientations[i] = orientations[i]; +} + +[numthreads(128, 1, 1)] +void PredictPositions (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= particleCount) return; + + int p = activeParticles[i]; + + // the previous position/orientation is the current position/orientation at the start of the step. + prevPositions[p] = positions[p]; + prevOrientations[p] = orientations[p]; + + // predict positions: + if (invMasses[p] > 0) + { + float4 effectiveGravity = float4(gravity,0); + + // Adjust gravity for buoyant fluid particles: + if ((phases[p] & (int)PHASE_FLUID) != 0) + effectiveGravity *= -buoyancies[p].z; + + // apply external forces and gravity: + float4 vel = velocities[p] + (invMasses[p] * externalForces[p] + effectiveGravity) * deltaTime; + + // project velocity to 2D plane if needed: + if (mode == 1) + vel[3] = 0; + + velocities[p] = vel; + } + + if (invRotationalMasses[p] > 0) + { + // apply external torques (simplification: we don't use full inertia tensor here) + float3 angularVel = angularVelocities[p].xyz + invRotationalMasses[p] * externalTorques[p].xyz * deltaTime; + + // project angular velocity to 2D plane normal if needed: + if (mode == 1) + angularVel = Project(angularVel,float3(0, 0, 1)); + + angularVelocities[p] = float4(angularVel, angularVelocities[p].w); + } + + positions[p] = IntegrateLinear(positions[p], velocities[p], deltaTime); + orientations[p] = IntegrateAngular(orientations[p], angularVelocities[p], deltaTime); +} + +[numthreads(128, 1, 1)] +void UpdateVelocities (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= particleCount) return; + + int p = activeParticles[i]; + + // Project particles on the XY plane if we are in 2D mode: + if (mode == 1) + { + // restrict position to the 2D plane + float4 pos = positions[p]; + pos[2] = prevPositions[p][2]; + positions[p] = pos; + } + + if (invMasses[p] > 0) + velocities[p] = DifferentiateLinear(positions[p],prevPositions[p],deltaTime); + else + velocities[p] = FLOAT4_ZERO; + + if (invRotationalMasses[p] > 0) + angularVelocities[p].xyz = DifferentiateAngular(orientations[p], prevOrientations[p], deltaTime).xyz; + else + angularVelocities[p] = FLOAT4_ZERO; +} + +[numthreads(128, 1, 1)] +void UpdatePositions (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= particleCount) return; + + int p = activeParticles[i]; + + // damp velocities: + velocities[p] *= velocityScale; + angularVelocities[p].xyz *= velocityScale; + + // clamp velocities: + float velMagnitude = length(velocities[p]); + float angularVelMagnitude = length(angularVelocities[p].xyz); + + if (velMagnitude > EPSILON) + velocities[p] *= min(maxVelocity, velMagnitude) / velMagnitude; + + if (angularVelMagnitude > EPSILON) + angularVelocities[p].xyz *= min(maxAngularVelocity, angularVelMagnitude) / angularVelMagnitude; + + // if the kinetic energy is below the sleep threshold, keep the particle at its previous position. + if (velMagnitude * velMagnitude * 0.5f + angularVelMagnitude * angularVelMagnitude * 0.5f <= sleepThreshold) + { + positions[p] = prevPositions[p]; + orientations[p] = prevOrientations[p]; + velocities[p] = FLOAT4_ZERO; + angularVelocities[p].xyz = float3(0,0,0); + } +} + +[numthreads(128, 1, 1)] +void Interpolate (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= particleCount) return; + + if (interpolation == 1) + { + renderablePositions[i] = lerp(R_startPositions[i], R_endPositions[i], blendFactor); + renderableOrientations[i] = normalize(q_slerp(R_startOrientations[i], R_endOrientations[i], blendFactor)); + renderableRadii[i] = principalRadii[i]; + } + else if (interpolation == 2) + { + renderablePositions[i] = lerp(R_endPositions[i], positions[i], blendFactor); + renderableOrientations[i] = normalize(q_slerp(R_endOrientations[i], orientations[i], blendFactor)); + renderableRadii[i] = principalRadii[i]; + } + else + { + renderablePositions[i] = R_endPositions[i]; + renderableOrientations[i] = normalize(R_endOrientations[i]); + renderableRadii[i] = principalRadii[i]; + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/Solver.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/Solver.compute.meta new file mode 100644 index 00000000..5e953895 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Solver.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8f597cb6a5a9e45499d9fd0f6160e5b4 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/SolverParameters.cginc b/xiaofang/Assets/Obi/Resources/Compute/SolverParameters.cginc new file mode 100644 index 00000000..122712f4 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SolverParameters.cginc @@ -0,0 +1,22 @@ +#ifndef SOLVERPARAMS_INCLUDE +#define SOLVERPARAMS_INCLUDE + +int mode; +int interpolation; +float3 gravity; +float damping; +float worldLinearInertiaScale; +float worldAngularInertiaScale; +float maxAnisotropy; +float sleepThreshold; +float maxVelocity; +float maxAngularVelocity; +float collisionMargin; +float maxDepenetration; +float colliderCCD; +float particleCCD; +float shockPropagation; +int surfaceCollisionIterations; +float surfaceCollisionTolerance; + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/SolverParameters.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/SolverParameters.cginc.meta new file mode 100644 index 00000000..a591ec8c --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SolverParameters.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 57c61c65170924f0aa225156e164ceb8 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/SortParticleData.compute b/xiaofang/Assets/Obi/Resources/Compute/SortParticleData.compute new file mode 100644 index 00000000..80282cf6 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SortParticleData.compute @@ -0,0 +1,30 @@ +#pragma kernel SortData + +StructuredBuffer sortedToOriginal; + +StructuredBuffer positions; +StructuredBuffer prevPositions; +StructuredBuffer principalRadii; +StructuredBuffer userData; + +RWStructuredBuffer sortedPositions; +RWStructuredBuffer sortedPrevPositions; +RWStructuredBuffer sortedPrincipalRadii; +RWStructuredBuffer sortedUserData; + +StructuredBuffer dispatchBuffer; + +[numthreads(128, 1, 1)] +void SortData (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= dispatchBuffer[3]) return; + + int original = sortedToOriginal[i]; + + sortedPositions[i] = positions[original]; + sortedPrevPositions[i] = prevPositions[original]; + sortedPrincipalRadii[i] = principalRadii[original]; + sortedUserData[i] = userData[original]; +} + diff --git a/xiaofang/Assets/Obi/Resources/Compute/SortParticleData.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/SortParticleData.compute.meta new file mode 100644 index 00000000..13aa550a --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SortParticleData.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9cd8eed4d0d6e45c18941232e855994f +ComputeShaderImporter: + externalObjects: {} + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/SpatialQueries.compute b/xiaofang/Assets/Obi/Resources/Compute/SpatialQueries.compute new file mode 100644 index 00000000..b9db064d --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SpatialQueries.compute @@ -0,0 +1,314 @@ +#include "GridUtils.cginc" +#include "CollisionMaterial.cginc" +#include "ContactHandling.cginc" +#include "ColliderDefinitions.cginc" +#include "Rigidbody.cginc" +#include "Bounds.cginc" +#include "Simplex.cginc" +#include "SolverParameters.cginc" +#include "AtomicDeltas.cginc" +#include "Phases.cginc" +#include "QueryDefinitions.cginc" + +#define MAX_RESULTS_PER_SIMPLEX 32 + +#pragma kernel Clear +#pragma kernel BuildUnsortedList +#pragma kernel FindPopulatedLevels +#pragma kernel SortList +#pragma kernel BuildContactList +#pragma kernel PrefixSumColliderCounts +#pragma kernel SortContactPairs + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer principalRadii; + +StructuredBuffer activeParticles; +StructuredBuffer simplices; +StructuredBuffer filters; +RWStructuredBuffer simplexBounds; // bounding box of each simplex. + +StructuredBuffer transforms; +StructuredBuffer shapes; +RWStructuredBuffer sortedColliderIndices; + +RWStructuredBuffer colliderTypeCounts; +RWStructuredBuffer contactOffsetsPerType; +RWStructuredBuffer unsortedContactPairs; + +RWStructuredBuffer cellIndices; +RWStructuredBuffer cellOffsets; + +RWStructuredBuffer cellCounts; +RWStructuredBuffer offsetInCells; + +RWStructuredBuffer contacts; +RWStructuredBuffer contactPairs; +RWStructuredBuffer dispatchBuffer; + +StructuredBuffer solverToWorld; +StructuredBuffer worldToSolver; + +uint maxResults; +uint queryCount; // amount of colliders in the grid. +uint cellsPerShape; // max amount of cells a collider can be inserted into. Typically this is 8. +int shapeTypeCount; // number of different query shapes, ie: box, sphere, ray, etc. + +aabb CalculateShapeAABB(in queryShape shape) +{ + float offset = shape.contactOffset + shape.maxDistance; + + aabb bounds; + bounds.min_ = FLT_MAX; + bounds.max_ = FLT_MIN; + switch (shape.type) + { + case SPHERE_QUERY: + bounds.FromParticle(shape.center, shape.size.x + offset); break; + case BOX_QUERY: + bounds.FromEdge(shape.center - shape.size*0.5f, shape.center + shape.size * 0.5f, offset); break; + case RAY_QUERY: + bounds.FromEdge(shape.center, shape.center + shape.size, offset); break; + } + return bounds; +} + +[numthreads(128, 1, 1)] +void Clear (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i == 0) + { + for (int l = 0; l <= GRID_LEVELS; ++l) + levelPopulation[l] = 0; + } + + // clear all cell offsets to invalid, so that we can later use atomic minimum to calculate the offset. + if (i < maxCells) + { + cellOffsets[i] = INVALID; + cellCounts[i] = 0; + } + + // clear all cell indices to invalid. + if (i < queryCount) + { + for (uint j = 0; j < cellsPerShape; ++j) + cellIndices[i*cellsPerShape+j] = INVALID; + } +} + +[numthreads(128, 1, 1)] +void BuildUnsortedList (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + if (i >= queryCount) return; + + // get bounds in solver space: + aabb bounds = CalculateShapeAABB(shapes[i]).Transformed(worldToSolver[0].Multiply(transforms[i])); + + // calculate bounds size, grid level and cell size: + float4 size = bounds.max_ - bounds.min_; + float maxSize = max(max (size.x, size.y), size.z); + int level = GridLevelForSize(maxSize); + float cellSize = CellSizeOfLevel(level); + + // calculate max and min cell coordinates (force 4th component to zero, might not be after expanding) + int4 minCell = floor(bounds.min_ / cellSize); + int4 maxCell = floor(bounds.max_ / cellSize); + minCell[3] = 0; + maxCell[3] = 0; + + int4 cellSpan = maxCell - minCell; + + // insert collider in cells: + for (int x = 0; x <= cellSpan[0]; ++x) + { + for (int y = 0; y <= cellSpan[1]; ++y) + { + for (int z = 0; z <= cellSpan[2]; ++z) + { + int cellIndex = GridHash(minCell + int4(x, y, z, level)); + + // calculate flat index of this cell into arrays: + int k = x + y*2 + z*4 + i*cellsPerShape; + + cellIndices[k] = cellIndex; + InterlockedAdd(cellCounts[cellIndex],1,offsetInCells[k]); + } + } + } + + // atomically increase this level's population by one: + InterlockedAdd(levelPopulation[1 + level],1); +} + +[numthreads(128, 1, 1)] +void SortList (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + if (i >= queryCount * cellsPerShape) return; + + uint cellIndex = cellIndices[i]; + + if (cellIndex != INVALID) + { + // write shape to its sorted index: + uint sortedIndex = cellOffsets[cellIndex] + offsetInCells[i]; + sortedColliderIndices[sortedIndex] = i; + } +} + +[numthreads(128, 1, 1)] +void BuildContactList (uint3 id : SV_DispatchThreadID) +{ + unsigned int threadIndex = id.x; + + if (threadIndex >= pointCount + edgeCount + triangleCount) return; + + uint cellCount = queryCount * cellsPerShape; + int candidateCount = 0; + uint candidates[MAX_RESULTS_PER_SIMPLEX]; + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(threadIndex, simplexSize); + + aabb b = simplexBounds[threadIndex]; + + // max size of the particle bounds in cells: + int4 maxSize = int4(10,10,10,10); + + // build a list of candidate colliders: + for (uint m = 1; m <= levelPopulation[0]; ++m) + { + uint l = levelPopulation[m]; + float cellSize = CellSizeOfLevel(l); + + int4 minCell = floor(b.min_ / cellSize); + int4 maxCell = floor(b.max_ / cellSize); + maxCell = minCell + min(maxCell - minCell, maxSize); + + for (int x = minCell[0]; x <= maxCell[0]; ++x) + { + for (int y = minCell[1]; y <= maxCell[1]; ++y) + { + for (int z = minCell[2]; z <= maxCell[2]; ++z) + { + uint flatCellIndex = GridHash(int4(x,y,z,l)); + uint cellStart = cellOffsets[flatCellIndex]; + uint cellCount = cellCounts[flatCellIndex]; + + // iterate through queries in the neighbour cell + for (uint n = cellStart; n < cellStart + cellCount; ++n) + { + if (candidateCount < MAX_RESULTS_PER_SIMPLEX) + candidates[candidateCount++] = sortedColliderIndices[n] / cellsPerShape; + } + + } + } + } + } + + //evaluate candidates and create contacts: + if (candidateCount > 0) + { + // insert sort: + for (int k = 1; k < candidateCount; ++k) + { + uint key = candidates[k]; + int j = k - 1; + + while (j >= 0 && candidates[j] > key) + candidates[j + 1] = candidates[j--]; + + candidates[j + 1] = key; + } + + // make sure each candidate only shows up once in the list: + int first = 0, contactCount = 0; + while(++first != candidateCount) + { + if (candidates[contactCount] != candidates[first]) + candidates[++contactCount] = candidates[first]; + } + contactCount++; + + // append contacts: + for (int i = 0; i < contactCount; i++) + { + int c = candidates[i]; + + // get shape bounds in solver space: + aabb colliderBoundsSS = CalculateShapeAABB(shapes[c]).Transformed(worldToSolver[0].Multiply(transforms[c])); + + // check if any simplex particle and the collider should collide: + bool shouldCollide = false; + int colliderCategory = shapes[c].filter & CategoryMask; + int colliderMask = (shapes[c].filter & MaskMask) >> 16; + for (int j = 0; j < simplexSize; ++j) + { + int simplexCategory = filters[simplices[simplexStart + j]] & CategoryMask; + int simplexMask = (filters[simplices[simplexStart + j]] & MaskMask) >> 16; + shouldCollide = shouldCollide || ((simplexCategory & colliderMask) != 0 && (simplexMask & colliderCategory) != 0); + } + + if (shouldCollide && b.IntersectsAabb(colliderBoundsSS)) + { + uint count; + InterlockedAdd(dispatchBuffer[7], 1, count); + + // technically incorrect, as number of pairs != number of contacts but + // we will ignore either excess pairs or contacts. + if (count < maxResults) + { + // increment the amount of contacts for this shape type: + InterlockedAdd(colliderTypeCounts[shapes[c].type],1); + + // enqueue a new contact pair: + unsortedContactPairs[count] = uint2(threadIndex,c); + + InterlockedMax(dispatchBuffer[4],(count + 1) / 128 + 1); + } + } + } + } +} + +[numthreads(1, 1, 1)] +void PrefixSumColliderCounts (uint3 id : SV_DispatchThreadID) +{ + contactOffsetsPerType[0] = 0; + int i; + + for (i = 0; i < shapeTypeCount; ++i) + { + contactOffsetsPerType[i+1] = contactOffsetsPerType[i] + colliderTypeCounts[i]; + + // write amount of pairs per collider type in the dispatch buffer: + dispatchBuffer[8 + i*4] = colliderTypeCounts[i] / 128 + 1; + dispatchBuffer[8 + i*4 + 3] = colliderTypeCounts[i]; + } +} + +[numthreads(128, 1, 1)] +void SortContactPairs (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + if (i >= dispatchBuffer[7] || i >= maxResults) return; + + uint2 pair = unsortedContactPairs[i]; + int shapeType = (int)shapes[pair.y].type; + + // decrement amount of pairs for the given collider type: + uint count; + InterlockedAdd(colliderTypeCounts[shapeType],-1, count); + + // write the pair directly at its position in the sorted array: + contactPairs[contactOffsetsPerType[shapeType] + count - 1] = pair; +} + + + diff --git a/xiaofang/Assets/Obi/Resources/Compute/SpatialQueries.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/SpatialQueries.compute.meta new file mode 100644 index 00000000..69122c2b --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SpatialQueries.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dbbb4eb0bd2fa43e08564bf661b00670 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/SphereShape.compute b/xiaofang/Assets/Obi/Resources/Compute/SphereShape.compute new file mode 100644 index 00000000..c88ecfa3 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SphereShape.compute @@ -0,0 +1,96 @@ +#include "ColliderDefinitions.cginc" +#include "ContactHandling.cginc" +#include "Transform.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "Optimization.cginc" + +#pragma kernel GenerateContacts + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer principalRadii; +StructuredBuffer velocities; + +StructuredBuffer simplices; + +StructuredBuffer transforms; +StructuredBuffer shapes; + +StructuredBuffer contactPairs; +StructuredBuffer contactOffsetsPerType; + +RWStructuredBuffer contacts; +RWStructuredBuffer dispatchBuffer; + +StructuredBuffer worldToSolver; + +uint maxContacts; + +struct Sphere : IDistanceFunction +{ + shape s; + transform colliderToSolver; + + void Evaluate(in float4 pos, in float4 radii, in quaternion orientation, inout SurfacePoint projectedPoint) + { + float4 center = s.center * colliderToSolver.scale; + float4 pnt = colliderToSolver.InverseTransformPointUnscaled(pos) - center; + + if (s.is2D()) + pnt[2] = 0; + + float radius = s.size.x * cmax(colliderToSolver.scale.xyz); + float distanceToCenter = length(pnt); + + float4 normal = pnt / (distanceToCenter + EPSILON); + + projectedPoint.pos = colliderToSolver.TransformPointUnscaled(center + normal * (radius + s.contactOffset)); + projectedPoint.normal = colliderToSolver.TransformDirection(normal); + projectedPoint.bary = float4(1,0,0,0); + } +}; + +[numthreads(128, 1, 1)] +void GenerateContacts (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + // entry #11 in the dispatch buffer is the amount of pairs for the first shape type. + if (i >= dispatchBuffer[11 + 4*SPHERE_SHAPE]) return; + + uint count = contacts.IncrementCounter(); + if (count < maxContacts) + { + int firstPair = contactOffsetsPerType[SPHERE_SHAPE]; + int simplexIndex = contactPairs[firstPair + i].x; + int colliderIndex = contactPairs[firstPair + i].y; + + contact c = (contact)0; + + Sphere sphereShape; + sphereShape.colliderToSolver = worldToSolver[0].Multiply(transforms[colliderIndex]); + sphereShape.s = shapes[colliderIndex]; + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(simplexIndex, simplexSize); + + float4 simplexBary = BarycenterForSimplexOfSize(simplexSize); + float4 simplexPoint; + + SurfacePoint surfacePoint = Optimize(sphereShape, positions, orientations, principalRadii, + simplices, simplexStart, simplexSize, simplexBary, simplexPoint, surfaceCollisionIterations, surfaceCollisionTolerance); + + c.pointB = surfacePoint.pos; + c.normal = surfacePoint.normal * sphereShape.s.isInverted(); + c.pointA = simplexBary; + c.bodyA = simplexIndex; + c.bodyB = colliderIndex; + + contacts[count] = c; + + InterlockedMax(dispatchBuffer[0],(count + 1) / 128 + 1); + InterlockedMax(dispatchBuffer[3], count + 1); + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/SphereShape.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/SphereShape.compute.meta new file mode 100644 index 00000000..282bd67c --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SphereShape.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6bde4f5390fee479ba06d6691eb9450b +ComputeShaderImporter: + externalObjects: {} + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/SphereShapeQuery.compute b/xiaofang/Assets/Obi/Resources/Compute/SphereShapeQuery.compute new file mode 100644 index 00000000..cea2c12e --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SphereShapeQuery.compute @@ -0,0 +1,107 @@ +#include "ColliderDefinitions.cginc" +#include "QueryDefinitions.cginc" +#include "ContactHandling.cginc" +#include "Transform.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "Optimization.cginc" + +#pragma kernel GenerateResults + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer principalRadii; +StructuredBuffer simplices; + +StructuredBuffer transforms; +StructuredBuffer shapes; + +StructuredBuffer contactPairs; +StructuredBuffer contactOffsetsPerType; + +RWStructuredBuffer results; +RWStructuredBuffer dispatchBuffer; + +StructuredBuffer worldToSolver; + +uint maxContacts; + +struct Sphere : IDistanceFunction +{ + queryShape s; + transform colliderToSolver; + + void Evaluate(in float4 pos, in float4 radii, in quaternion orientation, inout SurfacePoint projectedPoint) + { + float4 center = s.center * colliderToSolver.scale; + float4 pnt = colliderToSolver.InverseTransformPointUnscaled(pos) - center; + + float radius = s.size.x * cmax(colliderToSolver.scale.xyz); + float distanceToCenter = length(pnt); + + float4 normal = pnt / (distanceToCenter + EPSILON); + + projectedPoint.pos = colliderToSolver.TransformPointUnscaled(center + normal * (radius + s.contactOffset)); + projectedPoint.normal = colliderToSolver.TransformDirection(normal); + projectedPoint.bary = float4(1,0,0,0); + } +}; + +[numthreads(128, 1, 1)] +void GenerateResults (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + // entry #11 in the dispatch buffer is the amount of pairs for the first shape type. + if (i >= dispatchBuffer[11 + 4*SPHERE_QUERY]) return; + + int firstPair = contactOffsetsPerType[SPHERE_QUERY]; + int simplexIndex = contactPairs[firstPair + i].x; + int queryIndex = contactPairs[firstPair + i].y; + + queryResult c = (queryResult)0; + + Sphere sphereShape; + sphereShape.colliderToSolver = worldToSolver[0].Multiply(transforms[queryIndex]); + sphereShape.s = shapes[queryIndex]; + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(simplexIndex, simplexSize); + + float4 simplexBary = BarycenterForSimplexOfSize(simplexSize); + float4 simplexPoint; + + SurfacePoint surfacePoint = Optimize(sphereShape, positions, orientations, principalRadii, + simplices, simplexStart, simplexSize, simplexBary, simplexPoint, surfaceCollisionIterations, surfaceCollisionTolerance); + + + float4 simplexPrevPosition = FLOAT4_ZERO; + float simplexRadius = 0; + for (int j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + simplexPrevPosition += positions[particleIndex] * simplexBary[j]; + simplexRadius += EllipsoidRadius(surfacePoint.normal, orientations[particleIndex], principalRadii[particleIndex].xyz) * simplexBary[j]; + } + + c.queryPoint = surfacePoint.pos; + c.normal = surfacePoint.normal; + c.simplexBary = simplexBary; + c.simplexIndex = simplexIndex; + c.queryIndex = queryIndex; + c.dist = dot(simplexPrevPosition - surfacePoint.pos,surfacePoint.normal) - simplexRadius; + + if (c.dist <= sphereShape.s.maxDistance) + { + uint count = results.IncrementCounter(); + if (count < maxContacts) + { + results[count] = c; + + InterlockedMax(dispatchBuffer[0],(count + 1) / 128 + 1); + InterlockedMax(dispatchBuffer[3], count + 1); + } + } + +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/SphereShapeQuery.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/SphereShapeQuery.compute.meta new file mode 100644 index 00000000..c8efb5a7 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SphereShapeQuery.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1b86e67abd0f74accb1c47af5aa6ffbe +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/StitchConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/StitchConstraints.compute new file mode 100644 index 00000000..e26a380f --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/StitchConstraints.compute @@ -0,0 +1,64 @@ +#pragma kernel Project +#pragma kernel Apply + +#include "MathUtils.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer particleIndices; +StructuredBuffer stiffnesses; +RWStructuredBuffer lambdas; + +RWStructuredBuffer positions; +StructuredBuffer invMasses; + +// Variables set from the CPU +uint activeConstraintCount; +float deltaTime; +float sorFactor; + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p1 = particleIndices[i * 2]; + int p2 = particleIndices[i * 2 + 1]; + + float w1 = invMasses[p1]; + float w2 = invMasses[p2]; + + // calculate time adjusted compliance + float compliance = stiffnesses[i] / (deltaTime * deltaTime); + + // calculate position and lambda deltas: + float4 dist = positions[p1] - positions[p2]; + float constraint = length(dist); + + // calculate lambda and position deltas: + float dlambda = (-constraint - compliance * lambdas[i]) / (w1 + w2 + compliance + EPSILON); + float4 delta = dlambda * dist / (constraint + EPSILON); + + lambdas[i] += dlambda; + + float4 delta1 = delta * w1; + float4 delta2 = -delta * w2; + + AddPositionDelta(p1, delta1); + AddPositionDelta(p2, delta2); +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p1 = particleIndices[i * 2]; + int p2 = particleIndices[i * 2 + 1]; + + ApplyPositionDelta(positions, p1, sorFactor); + ApplyPositionDelta(positions, p2, sorFactor); +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/StitchConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/StitchConstraints.compute.meta new file mode 100644 index 00000000..bf07c4dc --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/StitchConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9d8b905ab89234f6c9c7774317150282 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/StretchShearConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/StretchShearConstraints.compute new file mode 100644 index 00000000..5da22d7e --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/StretchShearConstraints.compute @@ -0,0 +1,86 @@ +#pragma kernel Project +#pragma kernel Apply + +#include "MathUtils.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer particleIndices; +StructuredBuffer orientationIndices; +StructuredBuffer restLengths; +StructuredBuffer restOrientations; +StructuredBuffer stiffnesses; +RWStructuredBuffer lambdas; + +RWStructuredBuffer positions; +RWStructuredBuffer orientations; +StructuredBuffer invMasses; +StructuredBuffer invRotationalMasses; + +// Variables set from the CPU +uint activeConstraintCount; +float deltaTime; +float sorFactor; + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p1 = particleIndices[i * 2]; + int p2 = particleIndices[i * 2 + 1]; + int q = orientationIndices[i]; + + float w1 = invMasses[p1]; + float w2 = invMasses[p2]; + + // calculate time adjusted compliance + float3 compliances = stiffnesses[i] / (deltaTime * deltaTime); + + float3 e = rotate_vector(restOrientations[i], float3(0, 0, 1)); + quaternion basis = qmul(orientations[q],restOrientations[i]); + + // calculate rod vector in local element space: + float3 gamma = rotate_vector(q_conj(basis), (positions[p2] - positions[p1]).xyz) / (restLengths[i] + EPSILON); + + // subtract third director vector (0,0,1): + gamma[2] -= 1; + + float W = (w1 + w2) / (restLengths[i] + EPSILON) + invRotationalMasses[q] * 4.0f * restLengths[i]; + float3 dlambda = (gamma - compliances * lambdas[i]) / (W + compliances + EPSILON); + lambdas[i] += dlambda; + + // convert lambda delta lambda back to world space: + dlambda = rotate_vector(basis, dlambda); + + float4 delta1 = float4(dlambda, 0) * w1; + float4 delta2 = -float4(dlambda, 0) * w2; + + quaternion e_3 = quaternion(e.x,e.y,e.z,0); + quaternion q_e_3_bar = qmul(orientations[q],q_conj(e_3)); + + // calculate rotation delta: + quaternion rotDelta = qmul(quaternion(dlambda[0], dlambda[1], dlambda[2], 0.0f),q_e_3_bar); + rotDelta *= 2.0f * invRotationalMasses[q] * restLengths[i]; + + AddPositionDelta(p1, delta1); + AddPositionDelta(p2, delta2); + AddOrientationDelta(q, rotDelta); +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p1 = particleIndices[i * 2]; + int p2 = particleIndices[i * 2 + 1]; + int q = orientationIndices[i]; + + ApplyPositionDelta(positions, p1, sorFactor); + ApplyPositionDelta(positions, p2, sorFactor); + ApplyOrientationDelta(orientations, q, sorFactor); +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/StretchShearConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/StretchShearConstraints.compute.meta new file mode 100644 index 00000000..99b251af --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/StretchShearConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 09e95e8821fe445bf87f0d434d789822 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/SurfacePoint.cginc b/xiaofang/Assets/Obi/Resources/Compute/SurfacePoint.cginc new file mode 100644 index 00000000..e9d25466 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SurfacePoint.cginc @@ -0,0 +1,19 @@ +#ifndef SURFACEPOINT_INCLUDE +#define SURFACEPOINT_INCLUDE + +/** + * point in the surface of a signed distance field. + */ +struct SurfacePoint +{ + float4 bary; + float4 pos; + float4 normal; +}; + +interface IDistanceFunction +{ + void Evaluate(in float4 pos, in float4 radii, in quaternion orientation, inout SurfacePoint projectedPoint); +}; + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/SurfacePoint.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/SurfacePoint.cginc.meta new file mode 100644 index 00000000..f7b123e2 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/SurfacePoint.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b54db800f0f884467b02edb24ca317d4 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/TetherConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/TetherConstraints.compute new file mode 100644 index 00000000..cd99220f --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/TetherConstraints.compute @@ -0,0 +1,64 @@ +#pragma kernel Project +#pragma kernel Apply + +#include "MathUtils.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer particleIndices; +StructuredBuffer maxLengthScale; +StructuredBuffer stiffnesses; +RWStructuredBuffer lambdas; + +RWStructuredBuffer positions; +StructuredBuffer invMasses; + +// Variables set from the CPU +uint activeConstraintCount; +float deltaTime; +float sorFactor; + +[numthreads(128, 1, 1)] +void Project (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p1 = particleIndices[i * 2]; + int p2 = particleIndices[i * 2 + 1]; + + float w1 = invMasses[p1]; + float w2 = invMasses[p2]; + + // calculate time adjusted compliance + float compliance = stiffnesses[i] / (deltaTime * deltaTime); + + // calculate position and lambda deltas: + float4 dist = positions[p1] - positions[p2]; + float d = length(dist); + + // calculate constraint value (distance - rest length) + float constraint = d - (maxLengthScale[i].x * maxLengthScale[i].y); + + if (constraint > 0) + { + // calculate lambda and position deltas: + float dlambda = (-constraint - compliance * lambdas[i]) / (w1 + w2 + compliance + EPSILON); + float4 delta = dlambda * dist / (d + EPSILON); + lambdas[i] += dlambda; + + AddPositionDelta(p1, delta * w1); + } +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + int p = particleIndices[i * 2]; + + ApplyPositionDelta(positions, p, sorFactor); +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/TetherConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/TetherConstraints.compute.meta new file mode 100644 index 00000000..280042e3 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/TetherConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dcd2ea33ecfcb4fb0ac44c5a66ea69f8 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/Transform.cginc b/xiaofang/Assets/Obi/Resources/Compute/Transform.cginc new file mode 100644 index 00000000..039279a4 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Transform.cginc @@ -0,0 +1,98 @@ +#ifndef TRANSFORM_INCLUDE +#define TRANSFORM_INCLUDE + +#include "Quaternion.cginc" +#include "Integration.cginc" + +struct transform +{ + float4 translation; + float4 scale; + quaternion rotation; + + transform Transform(float4 translation_, quaternion rotation_, float4 scale_) + { + // make sure there are good values in the 4th component: + translation_[3] = 0; + scale_[3] = 1; + + transform t; + t.translation = translation_; + t.rotation = rotation_; + t.scale = scale_; + return t; + } + + transform Inverse() + { + return Transform(float4(rotate_vector(q_conj(rotation),(translation / -scale).xyz),0), + q_conj(rotation), + 1 / scale); + } + + transform Interpolate(transform other, float translationalMu, float rotationalMu, float scaleMu) + { + return Transform(lerp(translation, other.translation, translationalMu), + q_slerp(rotation, other.rotation, rotationalMu), + lerp(scale, other.scale, scaleMu)); + } + + transform Integrate(float4 linearVelocity, float4 angularVelocity, float dt) + { + return Transform(IntegrateLinear(translation, linearVelocity, dt), + IntegrateAngular(rotation, angularVelocity, dt), + scale); + } + + float4 TransformPoint(float4 pnt) + { + return float4(translation.xyz + rotate_vector(rotation, (pnt * scale).xyz),0); + } + + float4 InverseTransformPoint(float4 pnt) + { + return float4(rotate_vector(q_conj(rotation),(pnt - translation).xyz) / scale.xyz , 0); + } + + float4 TransformPointUnscaled(float4 pnt) + { + return float4(translation.xyz + rotate_vector(rotation,pnt.xyz), 0); + } + + float4 InverseTransformPointUnscaled(float4 pnt) + { + return float4(rotate_vector(q_conj(rotation), (pnt - translation).xyz), 0); + } + + float4 TransformDirection(float4 dir) + { + return float4(rotate_vector(rotation, dir.xyz), 0); + } + + float4 InverseTransformDirection(float4 dir) + { + return float4(rotate_vector(q_conj(rotation), dir.xyz), 0); + } + + float4 TransformVector(float4 vect) + { + return float4(rotate_vector(rotation, (vect * scale).xyz), 0); + } + + float4 InverseTransformVector(float4 vect) + { + return float4(rotate_vector(q_conj(rotation),vect.xyz) / scale.xyz, 0); + } + + transform Multiply(transform b) + { + return Transform(this.TransformPoint(b.translation), + qmul(this.rotation,b.rotation), + this.scale * b.scale); + } +}; + + + + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/Transform.cginc.meta b/xiaofang/Assets/Obi/Resources/Compute/Transform.cginc.meta new file mode 100644 index 00000000..f749fcd8 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/Transform.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7e54b6c6b777643958abffa4510e0518 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/TriangleMeshShape.compute b/xiaofang/Assets/Obi/Resources/Compute/TriangleMeshShape.compute new file mode 100644 index 00000000..619c9302 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/TriangleMeshShape.compute @@ -0,0 +1,208 @@ +#include "ColliderDefinitions.cginc" +#include "ContactHandling.cginc" +#include "Transform.cginc" +#include "Simplex.cginc" +#include "Bounds.cginc" +#include "SolverParameters.cginc" +#include "Optimization.cginc" + +#pragma kernel GenerateContacts + +struct BIHNode +{ + int firstChild; /**< index of the first child node. The second one is right after the first.*/ + int start; /**< index of the first element in this node.*/ + int count; /**< amount of elements in this node.*/ + + int axis; /**< axis of the split plane (0,1,2 = x,y,z)*/ + float min_; /**< minimum split plane*/ + float max_; /**< maximum split plane*/ +}; + +struct TriangleMeshHeader +{ + int firstNode; + int nodeCount; + int firstTriangle; + int triangleCount; + int firstVertex; + int vertexCount; +}; + +struct Triangle +{ + int i1; + int i2; + int i3; + aabb b; +}; + + +StructuredBuffer positions; +StructuredBuffer orientations; +StructuredBuffer principalRadii; +StructuredBuffer velocities; + +StructuredBuffer simplices; +StructuredBuffer simplexBounds; // bounding box of each simplex. + +StructuredBuffer transforms; +StructuredBuffer shapes; + +// triangle mesh data: +StructuredBuffer triangleMeshHeaders; +StructuredBuffer bihNodes; +StructuredBuffer triangles; +StructuredBuffer vertices; + +StructuredBuffer contactPairs; +StructuredBuffer contactOffsetsPerType; + +RWStructuredBuffer contacts; +RWStructuredBuffer dispatchBuffer; + +StructuredBuffer worldToSolver; + +uint maxContacts; +float deltaTime; + +struct TriangleMesh : IDistanceFunction +{ + shape s; + transform colliderToSolver; + + CachedTri tri; + + void Evaluate(in float4 pos, in float4 radii, in quaternion orientation, inout SurfacePoint projectedPoint) + { + float4 pnt = colliderToSolver.InverseTransformPointUnscaled(pos); + + if (s.is2D()) + pnt[2] = 0; + + float4 bary = FLOAT4_ZERO; + float4 nearestPoint = NearestPointOnTri(tri, pnt, bary); + float4 normal = normalizesafe(pnt - nearestPoint); + + projectedPoint.pos = colliderToSolver.TransformPointUnscaled(nearestPoint + normal * s.contactOffset); + projectedPoint.normal = colliderToSolver.TransformDirection(normal); + projectedPoint.bary = float4(1,0,0,0); + } + +}; + +[numthreads(128, 1, 1)] +void GenerateContacts (uint3 id : SV_DispatchThreadID) +{ + uint i = id.x; + + // entry #11 in the dispatch buffer is the amount of pairs for the first shape type. + if (i >= dispatchBuffer[11 + 4 * TRIANGLE_MESH_SHAPE]) return; + + int firstPair = contactOffsetsPerType[TRIANGLE_MESH_SHAPE]; + int simplexIndex = contactPairs[firstPair + i].x; + int colliderIndex = contactPairs[firstPair + i].y; + shape s = shapes[colliderIndex]; + + if (s.dataIndex < 0) return; + + TriangleMeshHeader header = triangleMeshHeaders[s.dataIndex]; + + TriangleMesh meshShape; + meshShape.colliderToSolver = worldToSolver[0].Multiply(transforms[colliderIndex]); + meshShape.s = s; + + // invert a full matrix here to accurately represent collider bounds scale. + float4x4 solverToCollider = Inverse(TRS(meshShape.colliderToSolver.translation.xyz, meshShape.colliderToSolver.rotation, meshShape.colliderToSolver.scale.xyz)); + aabb simplexBound = simplexBounds[simplexIndex].Transformed(solverToCollider); + + float4 marginCS = float4((s.contactOffset + collisionMargin) / meshShape.colliderToSolver.scale.xyz, 0); + + int simplexSize; + int simplexStart = GetSimplexStartAndSize(simplexIndex, simplexSize); + + int stack[12]; + int stackTop = 0; + + stack[stackTop++] = 0; + + while (stackTop > 0) + { + // pop node index from the stack: + int nodeIndex = stack[--stackTop]; + + BIHNode node = bihNodes[header.firstNode + nodeIndex]; + + // leaf node: + if (node.firstChild < 0) + { + // check for contact against all triangles: + for (int dataOffset = node.start; dataOffset < node.start + node.count; ++dataOffset) + { + Triangle t = triangles[header.firstTriangle + dataOffset]; + float4 v1 = float4(vertices[header.firstVertex + t.i1], 0); + float4 v2 = float4(vertices[header.firstVertex + t.i2], 0); + float4 v3 = float4(vertices[header.firstVertex + t.i3], 0); + aabb triangleBounds; + triangleBounds.FromTriangle(v1, v2, v3, marginCS); + + if (triangleBounds.IntersectsAabb(simplexBound, s.is2D())) + { + float4 simplexBary = BarycenterForSimplexOfSize(simplexSize); + float4 simplexPoint; + + meshShape.tri.Cache(v1 * meshShape.colliderToSolver.scale, v2 * meshShape.colliderToSolver.scale, v3 * meshShape.colliderToSolver.scale); + + SurfacePoint surfacePoint = Optimize(meshShape, positions, orientations, principalRadii, + simplices, simplexStart, simplexSize, simplexBary, simplexPoint, surfaceCollisionIterations, surfaceCollisionTolerance); + + float4 velocity = FLOAT4_ZERO; + float simplexRadius = 0; + for (int j = 0; j < simplexSize; ++j) + { + int particleIndex = simplices[simplexStart + j]; + simplexRadius += principalRadii[particleIndex].x * simplexBary[j]; + velocity += velocities[particleIndex] * simplexBary[j]; + } + + /*float4 rbVelocity = float4.zero; + if (rigidbodyIndex >= 0) + rbVelocity = BurstMath.GetRigidbodyVelocityAtPoint(rigidbodyIndex, colliderPoint.point, rigidbodies, solverToWorld);*/ + + float dAB = dot(simplexPoint - surfacePoint.pos, surfacePoint.normal); + float vel = dot(velocity /*- rbVelocity*/, surfacePoint.normal); + + if (vel * deltaTime + dAB <= simplexRadius + s.contactOffset + collisionMargin) + { + uint count = contacts.IncrementCounter(); + if (count < maxContacts) + { + contact c = (contact)0; + + c.pointB = surfacePoint.pos; + c.normal = surfacePoint.normal * meshShape.s.isInverted(); + c.pointA = simplexBary; + c.bodyA = simplexIndex; + c.bodyB = colliderIndex; + + contacts[count] = c; + + InterlockedMax(dispatchBuffer[0],(count + 1) / 128 + 1); + InterlockedMax(dispatchBuffer[3], count + 1); + } + } + } + } + } + else // check min and/or max children: + { + // visit min node: + if (simplexBound.min_[node.axis] <= node.min_) + stack[stackTop++] = node.firstChild; + + // visit max node: + if (simplexBound.max_[node.axis] >= node.max_) + stack[stackTop++] = node.firstChild + 1; + } + } +} \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/Compute/TriangleMeshShape.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/TriangleMeshShape.compute.meta new file mode 100644 index 00000000..a677721a --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/TriangleMeshShape.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a5454af20f9614aa79e51a90271093e3 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/Compute/VolumeConstraints.compute b/xiaofang/Assets/Obi/Resources/Compute/VolumeConstraints.compute new file mode 100644 index 00000000..4f6e3d71 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/VolumeConstraints.compute @@ -0,0 +1,153 @@ +#pragma kernel Gradients +#pragma kernel CalculateVolume +#pragma kernel Denominators +#pragma kernel Constraint +#pragma kernel AccumulateDeltas +#pragma kernel Apply + +//#pragma kernel Project +//#pragma kernel Apply + +#include "MathUtils.cginc" +#include "AtomicDeltas.cginc" + +StructuredBuffer triangles; +StructuredBuffer firstTriangle; +StructuredBuffer numTriangles; +StructuredBuffer restVolumes; +StructuredBuffer pressureStiffness; +RWStructuredBuffer lambdas; + +RWStructuredBuffer denominators; +RWStructuredBuffer volumes; +RWStructuredBuffer gradients; + +StructuredBuffer particles; +StructuredBuffer particleConstraintIndex; +StructuredBuffer triangleConstraintIndex; + +RWStructuredBuffer positions; +StructuredBuffer invMasses; + +// Variables set from the CPU +uint activeConstraintCount; +uint trianglesCount; +uint particlesCount; + +float deltaTime; +float sorFactor; + + +void AccumulateGradient(in int index, in float3 grad) +{ + InterlockedAddFloat(gradients, index, 0, grad.x); + InterlockedAddFloat(gradients, index, 1, grad.y); + InterlockedAddFloat(gradients, index, 2, grad.z); +} + +[numthreads(128, 1, 1)] +void Gradients (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= trianglesCount) return; + + int v = i * 3; + int i1 = triangles[v]; + int i2 = triangles[v + 1]; + int i3 = triangles[v + 2]; + + //accumulate gradient for each particle in the triangle: + AccumulateGradient(i1,cross(positions[i2].xyz, positions[i3].xyz)); + AccumulateGradient(i2,cross(positions[i3].xyz, positions[i1].xyz)); + AccumulateGradient(i3,cross(positions[i1].xyz, positions[i2].xyz)); +} + +[numthreads(128, 1, 1)] +void CalculateVolume (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= trianglesCount) return; + + int constraintIndex = triangleConstraintIndex[i]; + + int v = i * 3; + int i1 = triangles[v]; + int i2 = triangles[v + 1]; + int i3 = triangles[v + 2]; + + float vol = dot(cross(positions[i1].xyz, positions[i2].xyz), positions[i3].xyz) / 6.0f; + InterlockedAddFloat(volumes, triangleConstraintIndex[i],vol); +} + +// One denominator per constraint +// each particle in the constraint contributes only once. + +[numthreads(128, 1, 1)] +void Denominators (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= particlesCount) return; + + int p = particles[i]; + + float3 grad = asfloat(gradients[p]).xyz; + float denom = invMasses[p] * dot(grad, grad); + InterlockedAddFloat(denominators, particleConstraintIndex[i], denom); +} + +[numthreads(128, 1, 1)] +void Constraint (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + float compliance = pressureStiffness[i].y / (deltaTime * deltaTime); + + // equality constraint: volume - pressure * rest volume = 0 + float constraint = asfloat(volumes[i]) - pressureStiffness[i].x * restVolumes[i]; + + // calculate lagrange multiplier delta: + float dlambda = (-constraint - compliance * 0) / (asfloat(denominators[i]) + compliance + EPSILON); + lambdas[i] = dlambda;//+= dlambda; + + volumes[i] = asuint(0); + denominators[i] = asuint(0); +} + +[numthreads(128, 1, 1)] +void AccumulateDeltas (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= particlesCount) return; + + int p = particles[i]; + int c = particleConstraintIndex[i]; + + AddPositionDelta(p, lambdas[c] * invMasses[p] * asfloat(gradients[p])); + gradients[p] = asuint(FLOAT4_ZERO); +} + +[numthreads(128, 1, 1)] +void Apply (uint3 id : SV_DispatchThreadID) +{ + unsigned int i = id.x; + + if (i >= activeConstraintCount) return; + + for (int j = 0; j < numTriangles[i]; ++j) + { + int v = (firstTriangle[i] + j) * 3; + int p1 = triangles[v]; + int p2 = triangles[v + 1]; + int p3 = triangles[v + 2]; + + ApplyPositionDelta(positions, p1, sorFactor); + ApplyPositionDelta(positions, p2, sorFactor); + ApplyPositionDelta(positions, p3, sorFactor); + } +} diff --git a/xiaofang/Assets/Obi/Resources/Compute/VolumeConstraints.compute.meta b/xiaofang/Assets/Obi/Resources/Compute/VolumeConstraints.compute.meta new file mode 100644 index 00000000..33f05bbe --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/Compute/VolumeConstraints.compute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fef3adb748a41466696a32b41ecc8831 +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 65536 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/DefaultRopeSection.asset b/xiaofang/Assets/Obi/Resources/DefaultRopeSection.asset new file mode 100644 index 00000000..1cd5bb94 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/DefaultRopeSection.asset @@ -0,0 +1,26 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ee7737c43f5734f87be9e49d1bbfba78, type: 3} + m_Name: DefaultRopeSection + m_EditorClassIdentifier: + vertices: + - {x: 1, y: 0} + - {x: 0.70710677, y: 0.70710677} + - {x: -0.00000004371139, y: 1} + - {x: -0.70710677, y: 0.70710677} + - {x: -1, y: -0.00000008742278} + - {x: -0.70710665, y: -0.7071069} + - {x: 0.000000011924881, y: -1} + - {x: 0.707107, y: -0.70710653} + - {x: 1, y: 0.00000017484555} + snapX: 32 + snapY: 32 diff --git a/xiaofang/Assets/Obi/Resources/DefaultRopeSection.asset.meta b/xiaofang/Assets/Obi/Resources/DefaultRopeSection.asset.meta new file mode 100644 index 00000000..989bd9ac --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/DefaultRopeSection.asset.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a0bc36a59515f413e90e10895929c938 +labels: +- ObiRope +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/GUI.meta b/xiaofang/Assets/Obi/Resources/GUI.meta new file mode 100644 index 00000000..63fee6bd --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/GUI.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: bd46757354fbf4182af57f2913e20fc1 +folderAsset: yes +timeCreated: 1474532461 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/GUI/ProfilerSkin.guiskin b/xiaofang/Assets/Obi/Resources/GUI/ProfilerSkin.guiskin new file mode 100644 index 00000000..1265b3e6 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/GUI/ProfilerSkin.guiskin @@ -0,0 +1,1494 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12001, guid: 0000000000000000e000000000000000, type: 0} + m_Name: ProfilerSkin + m_EditorClassIdentifier: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_box: + m_Name: box + m_Normal: + m_Background: {fileID: 2800000, guid: 98f1105e6aebd46a1878df08ab79b5d7, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.79999995, g: 0.79999995, b: 0.79999995, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 1 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_button: + m_Name: button + m_Normal: + m_Background: {fileID: 11006, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9, g: 0.9, b: 0.9, a: 1} + m_Hover: + m_Background: {fileID: 11003, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: 11002, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9, g: 0.9, b: 0.9, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: 11005, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9019608, g: 0.9019608, b: 0.9019608, a: 1} + m_OnHover: + m_Background: {fileID: 11004, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 11002, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9, g: 0.9, b: 0.9, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 6 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_toggle: + m_Name: toggle + m_Normal: + m_Background: {fileID: 11018, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.89112896, g: 0.89112896, b: 0.89112896, a: 1} + m_Hover: + m_Background: {fileID: 11014, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: 11013, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 11016, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.8901961, g: 0.8901961, b: 0.8901961, a: 1} + m_OnHover: + m_Background: {fileID: 11015, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 11017, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 14 + m_Right: 0 + m_Top: 14 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 15 + m_Right: 0 + m_Top: 3 + m_Bottom: 0 + m_Overflow: + m_Left: -1 + m_Right: 0 + m_Top: -4 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_label: + m_Name: label + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.5882353, g: 0.5882353, b: 0.5882353, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 1 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_textField: + m_Name: textfield + m_Normal: + m_Background: {fileID: 11024, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.79999995, g: 0.79999995, b: 0.79999995, a: 1} + m_Hover: + m_Background: {fileID: 11026, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9, g: 0.9, b: 0.9, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 11026, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: 11025, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 3 + m_Right: 3 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 3 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_textArea: + m_Name: textarea + m_Normal: + m_Background: {fileID: 11024, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9019608, g: 0.9019608, b: 0.9019608, a: 1} + m_Hover: + m_Background: {fileID: 11026, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.79999995, g: 0.79999995, b: 0.79999995, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 11025, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 3 + m_Right: 3 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 1 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_window: + m_Name: window + m_Normal: + m_Background: {fileID: 11023, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 11022, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 8 + m_Right: 8 + m_Top: 18 + m_Bottom: 8 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 10 + m_Right: 10 + m_Top: 20 + m_Bottom: 10 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 1 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: -18} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalSlider: + m_Name: horizontalslider + m_Normal: + m_Background: {fileID: 11009, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 3 + m_Right: 3 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: -1 + m_Right: -1 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: -2 + m_Bottom: -3 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 2 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 12 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalSliderThumb: + m_Name: horizontalsliderthumb + m_Normal: + m_Background: {fileID: 11011, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 11012, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 11010, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 4 + m_Right: 4 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 7 + m_Right: 7 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: -1 + m_Right: -1 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 2 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 12 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_verticalSlider: + m_Name: verticalslider + m_Normal: + m_Background: {fileID: 11021, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 3 + m_Bottom: 3 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: -1 + m_Bottom: -1 + m_Overflow: + m_Left: -2 + m_Right: -3 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 0 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 12 + m_FixedHeight: 0 + m_StretchWidth: 0 + m_StretchHeight: 1 + m_verticalSliderThumb: + m_Name: verticalsliderthumb + m_Normal: + m_Background: {fileID: 11011, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 11012, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 11010, guid: 0000000000000000e000000000000000, type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 7 + m_Bottom: 7 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: -1 + m_Bottom: -1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 12 + m_FixedHeight: 0 + m_StretchWidth: 0 + m_StretchHeight: 1 + m_horizontalScrollbar: + m_Name: horizontalscrollbar + m_Normal: + m_Background: {fileID: 2800000, guid: a3476527001d2494a88fa4236e8dbf0b, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 9 + m_Right: 9 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 0 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 2 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 10 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalScrollbarThumb: + m_Name: horizontalscrollbarthumb + m_Normal: + m_Background: {fileID: 2800000, guid: 06f4c4a011cc740c08e92ac6806b7353, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 3 + m_Right: 3 + m_Top: 3 + m_Bottom: 3 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 10 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalScrollbarLeftButton: + m_Name: horizontalscrollbarleftbutton + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalScrollbarRightButton: + m_Name: horizontalscrollbarrightbutton + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_verticalScrollbar: + m_Name: verticalscrollbar + m_Normal: + m_Background: {fileID: 2800000, guid: a3476527001d2494a88fa4236e8dbf0b, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 9 + m_Bottom: 9 + m_Margin: + m_Left: 0 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 1 + m_Bottom: 1 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 10 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_verticalScrollbarThumb: + m_Name: verticalscrollbarthumb + m_Normal: + m_Background: {fileID: 2800000, guid: 06f4c4a011cc740c08e92ac6806b7353, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 6 + m_Bottom: 6 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 6 + m_Bottom: 6 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 2 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 10 + m_FixedHeight: 0 + m_StretchWidth: 0 + m_StretchHeight: 1 + m_verticalScrollbarUpButton: + m_Name: verticalscrollbarupbutton + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_verticalScrollbarDownButton: + m_Name: verticalscrollbardownbutton + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_ScrollView: + m_Name: scrollview + m_Normal: + m_Background: {fileID: 2800000, guid: a3476527001d2494a88fa4236e8dbf0b, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_CustomStyles: + - m_Name: Task + m_Normal: + m_Background: {fileID: 2800000, guid: c237f5e557ded47598c1e8e4c650aeda, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_Hover: + m_Background: {fileID: 2800000, guid: c237f5e557ded47598c1e8e4c650aeda, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_Active: + m_Background: {fileID: 2800000, guid: c237f5e557ded47598c1e8e4c650aeda, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_Focused: + m_Background: {fileID: 2800000, guid: c237f5e557ded47598c1e8e4c650aeda, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_OnNormal: + m_Background: {fileID: 2800000, guid: c237f5e557ded47598c1e8e4c650aeda, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_OnHover: + m_Background: {fileID: 2800000, guid: c237f5e557ded47598c1e8e4c650aeda, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_OnActive: + m_Background: {fileID: 2800000, guid: c237f5e557ded47598c1e8e4c650aeda, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_OnFocused: + m_Background: {fileID: 2800000, guid: c237f5e557ded47598c1e8e4c650aeda, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_Border: + m_Left: 2 + m_Right: 2 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 11 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + - m_Name: Thread + m_Normal: + m_Background: {fileID: 2800000, guid: 8b6df8323f27749f58cbd0563786435b, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_Hover: + m_Background: {fileID: 2800000, guid: 8b6df8323f27749f58cbd0563786435b, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_Active: + m_Background: {fileID: 2800000, guid: 8b6df8323f27749f58cbd0563786435b, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_Focused: + m_Background: {fileID: 2800000, guid: 8b6df8323f27749f58cbd0563786435b, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_OnNormal: + m_Background: {fileID: 2800000, guid: 8b6df8323f27749f58cbd0563786435b, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_OnHover: + m_Background: {fileID: 2800000, guid: 8b6df8323f27749f58cbd0563786435b, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_OnActive: + m_Background: {fileID: 2800000, guid: 8b6df8323f27749f58cbd0563786435b, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_OnFocused: + m_Background: {fileID: 2800000, guid: 8b6df8323f27749f58cbd0563786435b, type: 3} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 11 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_Settings: + m_DoubleClickSelectsWord: 1 + m_TripleClickSelectsLine: 1 + m_CursorColor: {r: 1, g: 1, b: 1, a: 1} + m_CursorFlashSpeed: -1 + m_SelectionColor: {r: 1, g: 0.38403907, b: 0, a: 0.7} diff --git a/xiaofang/Assets/Obi/Resources/GUI/ProfilerSkin.guiskin.meta b/xiaofang/Assets/Obi/Resources/GUI/ProfilerSkin.guiskin.meta new file mode 100644 index 00000000..d8811ce6 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/GUI/ProfilerSkin.guiskin.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b90d3c214c99743b0865fc0e0d1f1a15 +timeCreated: 1474532476 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/GUI/profiler_bck.png b/xiaofang/Assets/Obi/Resources/GUI/profiler_bck.png new file mode 100644 index 0000000000000000000000000000000000000000..ac91069b72a61b0176793f107655b3568508a0b4 GIT binary patch literal 2801 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 literal 0 HcmV?d00001 diff --git a/xiaofang/Assets/Obi/Resources/GUI/profiler_toolbar.png.meta b/xiaofang/Assets/Obi/Resources/GUI/profiler_toolbar.png.meta new file mode 100644 index 00000000..eb51c56c --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/GUI/profiler_toolbar.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 98f1105e6aebd46a1878df08ab79b5d7 +timeCreated: 1482234525 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 1 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Standalone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: iPhone + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + - buildTarget: Android + maxTextureSize: 2048 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/GUI/scroll_peg.png b/xiaofang/Assets/Obi/Resources/GUI/scroll_peg.png new file mode 100644 index 0000000000000000000000000000000000000000..2dcfb17ecd1ccf4c55ed7d5d71ed8c338640b44e GIT binary patch literal 2821 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 _InstanceTransforms; +StructuredBuffer _InvInstanceTransforms; +StructuredBuffer _Colors; + +#if UNITY_ANY_INSTANCING_ENABLED + // Based on : + // https://github.com/Unity-Technologies/Graphics/blob/master/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/ParticlesInstancing.hlsl + // and/or + // https://github.com/TwoTailsGames/Unity-Built-in-Shaders/blob/master/CGIncludes/UnityStandardParticleInstancing.cginc + + void vertInstancingSetup() { + } +#endif + +void GetInstanceData_float(uint svInstanceID, float3 pos, out float3 outPos, out float4 color) +{ + InitIndirectDrawArgs(0); + uint instanceID = GetIndirectInstanceID_Base(svInstanceID); + + unity_ObjectToWorld = _InstanceTransforms[instanceID]; + unity_WorldToObject = _InvInstanceTransforms[instanceID]; + color = _Colors[instanceID]; + + outPos = pos; +} + +#endif \ No newline at end of file diff --git a/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Compute/ProceduralInstancing.cginc.meta b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Compute/ProceduralInstancing.cginc.meta new file mode 100644 index 00000000..68b2e76d --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Instanced/Compute/ProceduralInstancing.cginc.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9d77a2f1bd0624d4aa045916cb0955c9 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoids.cginc b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoids.cginc new file mode 100644 index 00000000..63513cb9 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoids.cginc @@ -0,0 +1,103 @@ +#ifndef OBIELLIPSOIDS_INCLUDED +#define OBIELLIPSOIDS_INCLUDED + +// Eye ray origin in world space. +// Works both for orthographic and perspective cameras. +float3 WorldEye(float3 worldPos){ + if ((UNITY_MATRIX_P[3].x == 0.0) && (UNITY_MATRIX_P[3].y == 0.0) && (UNITY_MATRIX_P[3].z == 0.0)){ + return mul(UNITY_MATRIX_I_V,float4(mul(UNITY_MATRIX_V, float4(worldPos,1)).xy,0,1)).xyz; + }else + return _WorldSpaceCameraPos; +} + +// Returns visible ellipsoid radius and offset from center, given the eye position in parameter space. +// Works both for orthographic and perspective cameras. +float VisibleEllipsoidCircleRadius(float3 eye, out float3 m){ + if ((UNITY_MATRIX_P[3].x == 0.0) && (UNITY_MATRIX_P[3].y == 0.0) && (UNITY_MATRIX_P[3].z == 0.0)){ + m = float3(0,0,0); + return 1; + }else{ + float t = 1/dot(eye,eye); + m = t * eye; + return sqrt(1-t); + } +} + +// Performs accurate raycasting of a spherical impostor. +// Works both for orthographic and perspective cameras. +float IntersectEllipsoid(float3 v, float4 mapping, float3 a2, float3 a3, out float3 eyePos, out float3 eyeNormal) +{ + float r2 = dot(mapping.xy, mapping.xy); + float iq = 1 - r2/mapping.w; + clip(iq); // the ray does not intersect the sphere. + + float sqrtiq = sqrt(iq); + float lambda = 1/(1 + mapping.z * sqrtiq); + + eyePos = lambda * v; + eyeNormal = normalize(a2 + lambda * a3); + + // return gaussian-falloff thickness. + return 2 * sqrtiq * exp(-r2*2.0f); +} + +void BuildVelocityStretchedBasis(float3 velocity, float stretchIntensity, float radius, out float4 t0, out float4 t1, out float4 t2) +{ + t0 = float4(UNITY_MATRIX_V[0].xyz, radius); // camera right vector + t2 = float4(UNITY_MATRIX_V[2].xyz, radius); // camera forward vector + + float3 eyeVel = velocity - dot(velocity, t2.xyz) * t2.xyz; + float velNorm = length(eyeVel); + float stretchAmount = velNorm * stretchIntensity; + + // use it to lerp between velocity vector and camera right: + t0 = float4(velNorm > 0.00001 ? eyeVel / velNorm : t0, radius * (1 + stretchAmount)); + t1 = float4(normalize(cross(t0.xyz,t2.xyz)), radius); +} + +void BuildParameterSpaceMatrices(float4 t0, float4 t1, float4 t2, out float3x3 P, out float3x3 IP) +{ + // build 3x3 orientation matrix and its inverse; + float3x3 IO = float3x3(t0.xyz,t1.xyz,t2.xyz); + float3x3 O = transpose(IO); + + // build 3x3 scaling matrix and its inverse: + float3x3 S = float3x3(t0.w,0,0,0,t1.w,0,0,0,t2.w); + float3x3 IS = float3x3(1/t0.w,0,0,0,1/t1.w,0,0,0,1/t2.w); + + // build 3x3 transformation matrix and its inverse: + P = mul((float3x3)unity_ObjectToWorld, mul(O,mul(S,IO)) ); + IP = mul(mul(mul(O,IS),IO), (float3x3)unity_WorldToObject); +} + +float BuildEllipsoidBillboard(float3 center, float3 corner, float3x3 P, float3x3 IP, out float3 worldPos, out float3 view, out float3 eye) +{ + // eye position and quad vectors in parameter space: + eye = mul(IP, WorldEye(center) - center); + float3 u = normalize(cross(-eye,UNITY_MATRIX_V[1].xyz)); + float3 k = normalize(cross(-eye,u)); + + // visible circle radius and offset from center in the direction of the view ray: + float3 m; + float radius = VisibleEllipsoidCircleRadius(eye,m); + + // world position of the billboard corner, and view vector to it: + worldPos = center + mul(P, m) + radius * (mul(P,u)* corner.x + mul(P,k)* corner.y); + view = worldPos - WorldEye(worldPos); + + return radius; +} + +void BuildAuxiliaryNormalVectors(float3 center, float3 worldPos, float3 view, float3x3 P, float3x3 IP, out float3 a2, out float3 a3) +{ + // calculate T^-2 in object space, then multiply by + // inverse transpose of modelview to rotate normal from object to eye. + // This way the normal calculated in IntersectEllipsoid() is already in view space. + IP = mul((float3x3)unity_ObjectToWorld,IP); + float3x3 IP2 = mul((float3x3)UNITY_MATRIX_IT_MV, mul((float3x3)unity_WorldToObject,mul (IP, IP))); + + a2 = mul(IP2,WorldEye(worldPos) - center); //T^-2 * (eye - center) + a3 = mul(IP2,view); //T^-2 * A[0] +} + +#endif diff --git a/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoids.cginc.meta b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoids.cginc.meta new file mode 100644 index 00000000..f4ed8219 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoids.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 083c49fc96643477889bfd68e70cf998 +timeCreated: 1445285630 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoidsHDRP.cginc b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoidsHDRP.cginc new file mode 100644 index 00000000..e850de75 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoidsHDRP.cginc @@ -0,0 +1,104 @@ +#ifndef OBIELLIPSOIDS_INCLUDED +#define OBIELLIPSOIDS_INCLUDED + +// Eye ray origin in world space. +// Works both for orthographic and perspective cameras. +float3 WorldEye(float3 worldPos){ + if ((UNITY_MATRIX_P[3].x == 0.0) && (UNITY_MATRIX_P[3].y == 0.0) && (UNITY_MATRIX_P[3].z == 0.0)){ + return mul(UNITY_MATRIX_I_V,float4(mul(UNITY_MATRIX_V, float4(worldPos,1)).xy,0,1)).xyz; + }else + return _WorldSpaceCameraPos; +} + +// Returns visible ellipsoid radius and offset from center, given the eye position in parameter space. +// Works both for orthographic and perspective cameras. +float VisibleEllipsoidCircleRadius(float3 eye, out float3 m){ + if ((UNITY_MATRIX_P[3].x == 0.0) && (UNITY_MATRIX_P[3].y == 0.0) && (UNITY_MATRIX_P[3].z == 0.0)){ + m = float3(0,0,0); + return 1; + }else{ + float t = 1/dot(eye,eye); + m = t * eye; + return sqrt(1-t); + } +} + +// Performs accurate raycasting of a spherical impostor. +// Works both for orthographic and perspective cameras. +void IntersectEllipsoid_float(float3 v, float4 mapping, float3 a2, float3 a3, out float3 eyePos, out float3 eyeNormal, out float thickness, out float clipThreshold) +{ + float r2 = dot(mapping.xy, mapping.xy); + + // clip if the ray does not intersect the sphere. + clipThreshold = r2/mapping.w; + float iq = 1 - clipThreshold; + + float sqrtiq = sqrt(iq); + float lambda = 1/(1 + mapping.z * sqrtiq); + + eyePos = lambda * v; + eyeNormal = normalize(a2 + lambda * a3); + + // return gaussian-falloff thickness. + thickness = 2 * sqrtiq * exp(-r2*2.0f); +} + +void BuildVelocityStretchedBasis_float(float3 velocity, float stretchIntensity, float radius, out float4 t0, out float4 t1, out float4 t2) +{ + t0 = float4(UNITY_MATRIX_V[0].xyz, radius); // camera right vector + t2 = float4(UNITY_MATRIX_V[2].xyz, radius); // camera forward vector + + float3 eyeVel = velocity - dot(velocity, t2.xyz) * t2.xyz; + float velNorm = length(eyeVel); + float stretchAmount = velNorm * stretchIntensity; + + // use it to lerp between velocity vector and camera right: + t0 = float4(velNorm > 0.00001 ? eyeVel / velNorm : t0.xyz, radius * (1 + stretchAmount)); + t1 = float4(normalize(cross(t0.xyz,t2.xyz)), radius); +} + +void BuildParameterSpaceMatrices_float(float4 t0, float4 t1, float4 t2, float radiusScale, out float3x3 P, out float3x3 IP) +{ + // build 3x3 orientation matrix and its inverse; + float3x3 IO = float3x3(t0.xyz,t1.xyz,t2.xyz); + float3x3 O = transpose(IO); + + // build 3x3 scaling matrix and its inverse: + float3x3 S = float3x3(radiusScale*t0.w,0,0,0,radiusScale*t1.w,0,0,0,radiusScale*t2.w); + float3x3 IS = float3x3(1/(radiusScale*t0.w),0,0,0,1/(radiusScale*t1.w),0,0,0,1/(radiusScale*t2.w)); + + // build 3x3 transformation matrix and its inverse: + P = mul((float3x3)UNITY_MATRIX_M, mul(O,mul(S,IO)) ); + IP = mul(mul(mul(O,IS),IO), (float3x3)UNITY_MATRIX_I_M); +} + +void BuildEllipsoidBillboard_float(float3 center, float3 corner, float3x3 P, float3x3 IP, out float3 worldPos, out float3 view, out float3 eye, out float radius) +{ + // eye position and quad vectors in parameter space: + eye = mul(IP,WorldEye(center) - center); + float3 u = normalize(cross(-eye,UNITY_MATRIX_V[1].xyz)); + float3 k = normalize(cross(-eye,u)); + + // visible circle radius and offset from center in the direction of the view ray: + float3 m; + radius = VisibleEllipsoidCircleRadius(eye,m); + + // world position of the billboard corner, and view vector to it: + worldPos = center + mul(P, m) + radius * (mul(P,u)* corner.x + mul(P,k)* corner.y); + view = worldPos - WorldEye(worldPos); +} + +void BuildAuxiliaryNormalVectors_float(float3 center, float3 worldPos, float3 view, float3x3 P, float3x3 IP, out float3 a2, out float3 a3) +{ + // calculate T^-2 in object space, then multiply by + // inverse transpose of modelview to rotate normal from object to eye. + // This way the normal calculated in IntersectEllipsoid() is already in view space. + IP = mul((float3x3)UNITY_MATRIX_M,IP); + float3x3 IT_MV = transpose(mul((float3x3)UNITY_MATRIX_I_V, (float3x3)UNITY_MATRIX_I_M)); + float3x3 IP2 = mul(IT_MV, mul((float3x3)UNITY_MATRIX_I_M,mul (IP, IP))); // UNITY_MATRIX_IT_MV + + a2 = mul(IP2,WorldEye(worldPos) - center); //T^-2 * (eye - center) + a3 = mul(IP2,view); //T^-2 * A[0] +} + +#endif diff --git a/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoidsHDRP.cginc.meta b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoidsHDRP.cginc.meta new file mode 100644 index 00000000..62b29876 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiEllipsoidsHDRP.cginc.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bc807595df1f54350ac0027aaf7cb91b +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiUtils.cginc b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiUtils.cginc new file mode 100644 index 00000000..bd161f27 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiUtils.cginc @@ -0,0 +1,28 @@ +#ifndef OBIUTILS_INCLUDED +#define OBIUTILS_INCLUDED + +float4x4 _Camera_to_World; + +// abstract texture declaration/sampling over built-in and SRPs: +#ifndef TEXTURE2D +#define TEXTURE2D(name) sampler2D name +#endif + +#ifndef TEXTURE2D_HALF +#define TEXTURE2D_HALF(name) sampler2D_half name +#endif + +#ifndef TEXTURE2D_FLOAT +#define TEXTURE2D_FLOAT(name) sampler2D_float name +#endif + +#ifndef SAMPLE_TEXTURE2D +#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) tex2D(textureName,coord2) +#endif + +#ifndef SAMPLER +#define SAMPLER(samplerName) +#endif + + +#endif diff --git a/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiUtils.cginc.meta b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiUtils.cginc.meta new file mode 100644 index 00000000..d7668afa --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ObiUtils.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fe1b10a99f88a45a09abf1a13d62b63f +timeCreated: 1445285630 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ParticleShader.shadergraph b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ParticleShader.shadergraph new file mode 100644 index 00000000..4b61fbcd --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ParticleShader.shadergraph @@ -0,0 +1,5867 @@ +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.GraphData", + "m_ObjectId": "78d72b84620c4d40bd076ace556c78f8", + "m_Properties": [ + { + "m_Id": "1f4b884eb7a5494fa0a4c6b1726ae6e9" + }, + { + "m_Id": "22b23a850ca345f6b5b35205f12039ae" + }, + { + "m_Id": "ac709b9b0cc14e26a2611422b499ba45" + } + ], + "m_Keywords": [], + "m_Dropdowns": [], + "m_CategoryData": [ + { + "m_Id": "4c99293183f94afb9e94b8936dbbcc14" + } + ], + "m_Nodes": [ + { + "m_Id": "1fdb294276af4309848652e8d2e07def" + }, + { + "m_Id": "5ff456959eca4fbd934a5aac0280d67f" + }, + { + "m_Id": "d11f8fd02e364ad5b8eadd3550fa2851" + }, + { + "m_Id": "cf2c0d4033c24443b7c21cb036226b3f" + }, + { + "m_Id": "dffaa900d1d04a7db60ef0ccab276839" + }, + { + "m_Id": "0dcd4dbbd33e4365be4d2cdfdc121036" + }, + { + "m_Id": "84cbbe352286486abb8cf0a951e3e458" + }, + { + "m_Id": "2ece075db2b3411a80af471816c4e871" + }, + { + "m_Id": "4f921bef2597498da8ae8c75e3007b37" + }, + { + "m_Id": "1a63d9f74e5943368bfe7e3f9bba296a" + }, + { + "m_Id": "5ee2f7c86c814012bd5eba803e4b36ea" + }, + { + "m_Id": "79ee34ad93234f7880a9f2680b904beb" + }, + { + "m_Id": "44656ed842a54a34b956fc57e356de21" + }, + { + "m_Id": "18eff50f7a64480385a1ad3698dc0a1d" + }, + { + "m_Id": "7c1b54d0ae564cce9fee0e3b18b0f945" + }, + { + "m_Id": "9a540fa4d7fd41edb663c20d392cc937" + }, + { + "m_Id": "b585fdf2c7ce438b8a72c6f452ff31ab" + }, + { + "m_Id": "b397b42dfd5342b0b6291c60e22ae6d4" + }, + { + "m_Id": "e185f6e703b749569fec95035ae86e44" + }, + { + "m_Id": "7e7b6ef93c414bec8d608482fc837fb3" + }, + { + "m_Id": "b35a3765628d49f69d75dfc77df38114" + }, + { + "m_Id": "29c676f6f7fc4d2dbb627a099736baaa" + }, + { + "m_Id": "32c989810b8e4fe7b964240b81ea9def" + }, + { + "m_Id": "a5babea545924715b0ba888ac6373f66" + }, + { + "m_Id": "babccae7634a4d2090f45aa9e154b2ca" + }, + { + "m_Id": "2ed72e60304c47509002fc1b2c204a99" + }, + { + "m_Id": "6f0ad27166324e6fbc829bc0e4076d27" + }, + { + "m_Id": "7650578a1434466faec6ab2d3fe8f0a6" + }, + { + "m_Id": "69d4f0ec92ff4182be437caf84eafb72" + }, + { + "m_Id": "af8c0d42edcd4eda8e6e86de937dbadf" + }, + { + "m_Id": "4c900e907c5340d88caa515b644c0a70" + }, + { + "m_Id": "97bd7a4169c641a59a7012a029b44964" + }, + { + "m_Id": "3b5798f4b422481bb94c97f7014cd7b9" + }, + { + "m_Id": "ee946d6d4c7c4cb1b920e447bb01d580" + }, + { + "m_Id": "f5da1c6b4af04e169c2dce3319f17d13" + }, + { + "m_Id": "675f1b67f80444599ddf4ba675419f8d" + }, + { + "m_Id": "4959d2015a38402881b6fec5e5a518a6" + }, + { + "m_Id": "463beca994a14896865c0978dffaa08b" + }, + { + "m_Id": "e445db0b154846179887a9470ff3aa66" + }, + { + "m_Id": "e94b4e133a134411aa01241421f711cb" + }, + { + "m_Id": "dfd25b2a19df42beba356ef0e5e0b3be" + }, + { + "m_Id": "23a24fff90ba43ab9e3d17e24ec85ad7" + }, + { + "m_Id": "c6116508eb7246469fe9c6ae81460410" + }, + { + "m_Id": "186ed2ae0dbb4487a943f3930c952fc4" + }, + { + "m_Id": "26e1af9d3ae14f71adf1a395a49b937e" + }, + { + "m_Id": "51ff74a2115b4f07940322b02e8b9806" + }, + { + "m_Id": "115b4d546e6b497dae56cf2a084bb730" + }, + { + "m_Id": "4142867127cb4a21bfa771e4c5b504bc" + }, + { + "m_Id": "e17c109ffbe942c89e40ff95cd1cfd7a" + }, + { + "m_Id": "7be03ef72fc946ff81de225831947baf" + } + ], + "m_GroupDatas": [], + "m_StickyNoteDatas": [], + "m_Edges": [ + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "115b4d546e6b497dae56cf2a084bb730" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "af8c0d42edcd4eda8e6e86de937dbadf" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "186ed2ae0dbb4487a943f3930c952fc4" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "5ee2f7c86c814012bd5eba803e4b36ea" + }, + "m_SlotId": 3 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "18eff50f7a64480385a1ad3698dc0a1d" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "4f921bef2597498da8ae8c75e3007b37" + }, + "m_SlotId": 3 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "1a63d9f74e5943368bfe7e3f9bba296a" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "23a24fff90ba43ab9e3d17e24ec85ad7" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "1a63d9f74e5943368bfe7e3f9bba296a" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "5ee2f7c86c814012bd5eba803e4b36ea" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "1a63d9f74e5943368bfe7e3f9bba296a" + }, + "m_SlotId": 5 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "6f0ad27166324e6fbc829bc0e4076d27" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "1a63d9f74e5943368bfe7e3f9bba296a" + }, + "m_SlotId": 6 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "115b4d546e6b497dae56cf2a084bb730" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "1a63d9f74e5943368bfe7e3f9bba296a" + }, + "m_SlotId": 6 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "5ee2f7c86c814012bd5eba803e4b36ea" + }, + "m_SlotId": 2 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "1a63d9f74e5943368bfe7e3f9bba296a" + }, + "m_SlotId": 7 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "babccae7634a4d2090f45aa9e154b2ca" + }, + "m_SlotId": 3 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "23a24fff90ba43ab9e3d17e24ec85ad7" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "1fdb294276af4309848652e8d2e07def" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "26e1af9d3ae14f71adf1a395a49b937e" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "5ee2f7c86c814012bd5eba803e4b36ea" + }, + "m_SlotId": 4 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "29c676f6f7fc4d2dbb627a099736baaa" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7c1b54d0ae564cce9fee0e3b18b0f945" + }, + "m_SlotId": 2 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "2ece075db2b3411a80af471816c4e871" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "1a63d9f74e5943368bfe7e3f9bba296a" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "2ece075db2b3411a80af471816c4e871" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "5ee2f7c86c814012bd5eba803e4b36ea" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "2ed72e60304c47509002fc1b2c204a99" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "babccae7634a4d2090f45aa9e154b2ca" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "2ed72e60304c47509002fc1b2c204a99" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "babccae7634a4d2090f45aa9e154b2ca" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "32c989810b8e4fe7b964240b81ea9def" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7c1b54d0ae564cce9fee0e3b18b0f945" + }, + "m_SlotId": 3 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "3b5798f4b422481bb94c97f7014cd7b9" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "5ff456959eca4fbd934a5aac0280d67f" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "44656ed842a54a34b956fc57e356de21" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "4f921bef2597498da8ae8c75e3007b37" + }, + "m_SlotId": 2 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "4959d2015a38402881b6fec5e5a518a6" + }, + "m_SlotId": 3 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f5da1c6b4af04e169c2dce3319f17d13" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "4c900e907c5340d88caa515b644c0a70" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "3b5798f4b422481bb94c97f7014cd7b9" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "4f921bef2597498da8ae8c75e3007b37" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "186ed2ae0dbb4487a943f3930c952fc4" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "4f921bef2597498da8ae8c75e3007b37" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "1a63d9f74e5943368bfe7e3f9bba296a" + }, + "m_SlotId": 2 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "4f921bef2597498da8ae8c75e3007b37" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "1a63d9f74e5943368bfe7e3f9bba296a" + }, + "m_SlotId": 3 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "4f921bef2597498da8ae8c75e3007b37" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "26e1af9d3ae14f71adf1a395a49b937e" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "51ff74a2115b4f07940322b02e8b9806" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "2ed72e60304c47509002fc1b2c204a99" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "5ee2f7c86c814012bd5eba803e4b36ea" + }, + "m_SlotId": 5 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7e7b6ef93c414bec8d608482fc837fb3" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "5ee2f7c86c814012bd5eba803e4b36ea" + }, + "m_SlotId": 6 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "b35a3765628d49f69d75dfc77df38114" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "675f1b67f80444599ddf4ba675419f8d" + }, + "m_SlotId": 3 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f5da1c6b4af04e169c2dce3319f17d13" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "69d4f0ec92ff4182be437caf84eafb72" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "af8c0d42edcd4eda8e6e86de937dbadf" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "6f0ad27166324e6fbc829bc0e4076d27" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7650578a1434466faec6ab2d3fe8f0a6" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7650578a1434466faec6ab2d3fe8f0a6" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "babccae7634a4d2090f45aa9e154b2ca" + }, + "m_SlotId": 2 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "79ee34ad93234f7880a9f2680b904beb" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "4f921bef2597498da8ae8c75e3007b37" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7be03ef72fc946ff81de225831947baf" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "dffaa900d1d04a7db60ef0ccab276839" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7c1b54d0ae564cce9fee0e3b18b0f945" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "4959d2015a38402881b6fec5e5a518a6" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7c1b54d0ae564cce9fee0e3b18b0f945" + }, + "m_SlotId": 5 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "a5babea545924715b0ba888ac6373f66" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7c1b54d0ae564cce9fee0e3b18b0f945" + }, + "m_SlotId": 7 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "dfd25b2a19df42beba356ef0e5e0b3be" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "84cbbe352286486abb8cf0a951e3e458" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "1a63d9f74e5943368bfe7e3f9bba296a" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "84cbbe352286486abb8cf0a951e3e458" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "51ff74a2115b4f07940322b02e8b9806" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "97bd7a4169c641a59a7012a029b44964" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "3b5798f4b422481bb94c97f7014cd7b9" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "a5babea545924715b0ba888ac6373f66" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "463beca994a14896865c0978dffaa08b" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "af8c0d42edcd4eda8e6e86de937dbadf" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "b585fdf2c7ce438b8a72c6f452ff31ab" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "b397b42dfd5342b0b6291c60e22ae6d4" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7c1b54d0ae564cce9fee0e3b18b0f945" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "babccae7634a4d2090f45aa9e154b2ca" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "9a540fa4d7fd41edb663c20d392cc937" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "c6116508eb7246469fe9c6ae81460410" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "675f1b67f80444599ddf4ba675419f8d" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "e185f6e703b749569fec95035ae86e44" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7c1b54d0ae564cce9fee0e3b18b0f945" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "e185f6e703b749569fec95035ae86e44" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "c6116508eb7246469fe9c6ae81460410" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "e445db0b154846179887a9470ff3aa66" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "4f921bef2597498da8ae8c75e3007b37" + }, + "m_SlotId": 5 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "f5da1c6b4af04e169c2dce3319f17d13" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "ee946d6d4c7c4cb1b920e447bb01d580" + }, + "m_SlotId": 0 + } + } + ], + "m_VertexContext": { + "m_Position": { + "x": 535.0, + "y": 29.9999942779541 + }, + "m_Blocks": [ + { + "m_Id": "7e7b6ef93c414bec8d608482fc837fb3" + }, + { + "m_Id": "b35a3765628d49f69d75dfc77df38114" + }, + { + "m_Id": "1fdb294276af4309848652e8d2e07def" + }, + { + "m_Id": "b585fdf2c7ce438b8a72c6f452ff31ab" + }, + { + "m_Id": "9a540fa4d7fd41edb663c20d392cc937" + }, + { + "m_Id": "4142867127cb4a21bfa771e4c5b504bc" + }, + { + "m_Id": "e17c109ffbe942c89e40ff95cd1cfd7a" + } + ] + }, + "m_FragmentContext": { + "m_Position": { + "x": 535.0000610351563, + "y": 411.0000305175781 + }, + "m_Blocks": [ + { + "m_Id": "5ff456959eca4fbd934a5aac0280d67f" + }, + { + "m_Id": "463beca994a14896865c0978dffaa08b" + }, + { + "m_Id": "d11f8fd02e364ad5b8eadd3550fa2851" + }, + { + "m_Id": "cf2c0d4033c24443b7c21cb036226b3f" + }, + { + "m_Id": "dffaa900d1d04a7db60ef0ccab276839" + }, + { + "m_Id": "0dcd4dbbd33e4365be4d2cdfdc121036" + }, + { + "m_Id": "ee946d6d4c7c4cb1b920e447bb01d580" + }, + { + "m_Id": "e94b4e133a134411aa01241421f711cb" + }, + { + "m_Id": "dfd25b2a19df42beba356ef0e5e0b3be" + } + ] + }, + "m_PreviewData": { + "serializedMesh": { + "m_SerializedMesh": "{\"mesh\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "preventRotation": false + }, + "m_Path": "Shader Graphs", + "m_GraphPrecision": 1, + "m_PreviewMode": 2, + "m_OutputNode": { + "m_Id": "" + }, + "m_ActiveTargets": [ + { + "m_Id": "5915510c968749209ff6f351ddb9a96e" + }, + { + "m_Id": "4790e9cb06234cefa4390fb194e36e9d" + }, + { + "m_Id": "9f0ab621b28741df9e2a65a37837af56" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "02661c44bbcb4c2f9ba17e80d7961c8b", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.LightingData", + "m_ObjectId": "0302a9604b3f4175835f2fe805babd5b", + "m_NormalDropOffSpace": 0, + "m_BlendPreserveSpecular": true, + "m_ReceiveDecals": false, + "m_ReceiveSSR": true, + "m_ReceiveSSRTransparent": false, + "m_SpecularAA": false, + "m_SpecularOcclusionMode": 1, + "m_OverrideBakedGI": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Matrix3MaterialSlot", + "m_ObjectId": "036bc09f36e2448f81db41a6ae1e8190", + "m_Id": 2, + "m_DisplayName": "P", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "P", + "m_StageCapability": 3, + "m_Value": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicMatrixMaterialSlot", + "m_ObjectId": "0486de2ab41b4463853f8b70b1c609d6", + "m_Id": 0, + "m_DisplayName": "", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "0631b78f49ed4369abc26bddeecd8c71", + "m_Id": 2, + "m_DisplayName": "view", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "view", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "06a2fcfa697b4e19af278e2c539b8d2d", + "m_Id": 0, + "m_DisplayName": "Ambient Occlusion", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Occlusion", + "m_StageCapability": 2, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "08351f97eeea4b6485b39a61a65a3fe8", + "m_Id": 5, + "m_DisplayName": "RGB", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "RGB", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "09069b51882f444b840aabb69c7c506f", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.BuiltinData", + "m_ObjectId": "094b0804cd0a4e33920a4abe743454a6", + "m_Distortion": false, + "m_DistortionMode": 0, + "m_DistortionDepthTest": true, + "m_AddPrecomputedVelocity": false, + "m_TransparentWritesMotionVec": false, + "m_AlphaToMask": false, + "m_DepthOffset": true, + "m_ConservativeDepthOffset": false, + "m_TransparencyFog": true, + "m_AlphaTestShadow": false, + "m_BackThenFrontRendering": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_SupportLodCrossFade": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "09cd01e9020d48e1bda65b06c6a71b16", + "m_Id": 0, + "m_DisplayName": "_Smoothness", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "0a65b1a8a9cc4d26aa3d5676905379a0", + "m_Id": 0, + "m_DisplayName": "Depth Offset", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "DepthOffset", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "0ba2bd333a584e04a0f559269a5cb217", + "m_Id": 0, + "m_DisplayName": "Base Color", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "BaseColor", + "m_StageCapability": 2, + "m_Value": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.5, + "g": 0.5, + "b": 0.5, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "0bed110901394810986b7c46885c2dbb", + "m_Id": 3, + "m_DisplayName": "a3", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "a3", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "0c6df044f18e4fca8e0602ab941e36b3", + "m_Id": 5, + "m_DisplayName": "a2", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "a2", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "0dcd4dbbd33e4365be4d2cdfdc121036", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Occlusion", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "06a2fcfa697b4e19af278e2c539b8d2d" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Occlusion" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.RedirectNodeData", + "m_ObjectId": "115b4d546e6b497dae56cf2a084bb730", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Redirect Node", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -215.00003051757813, + "y": 216.00003051757813, + "width": 56.00001525878906, + "height": 24.0 + } + }, + "m_Slots": [ + { + "m_Id": "34b089445d94443bae321419aba92376" + }, + { + "m_Id": "ef8a1c0804ec4253ad73c319031bec6e" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.RedirectNodeData", + "m_ObjectId": "186ed2ae0dbb4487a943f3930c952fc4", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Redirect Node", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1105.0, + "y": -97.00000762939453, + "width": 56.0, + "height": 24.000015258789064 + } + }, + "m_Slots": [ + { + "m_Id": "0486de2ab41b4463853f8b70b1c609d6" + }, + { + "m_Id": "3cdefcef62e446c6820185746a0ec7a1" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVNode", + "m_ObjectId": "18eff50f7a64480385a1ad3698dc0a1d", + "m_Group": { + "m_Id": "" + }, + "m_Name": "UV", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1908.0, + "y": 196.0000457763672, + "width": 145.0, + "height": 128.99998474121095 + } + }, + "m_Slots": [ + { + "m_Id": "9d04c3fa0c6848bd908018475a5ec9cf" + } + ], + "synonyms": [ + "texcoords", + "coords", + "coordinates" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_OutputChannel": 2 +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.CustomFunctionNode", + "m_ObjectId": "1a63d9f74e5943368bfe7e3f9bba296a", + "m_Group": { + "m_Id": "" + }, + "m_Name": "BuildEllipsoidBillboard (Custom Function)", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1105.0, + "y": -20.999990463256837, + "width": 279.0, + "height": 165.99998474121095 + } + }, + "m_Slots": [ + { + "m_Id": "24cc20330a6746e78f01f178e5c0ee25" + }, + { + "m_Id": "54c2e40c04ab4fa88a6d13a3467a46bd" + }, + { + "m_Id": "036bc09f36e2448f81db41a6ae1e8190" + }, + { + "m_Id": "48d6d267a6b6420c974cd75196394443" + }, + { + "m_Id": "436f317395f24909887811586c2f866e" + }, + { + "m_Id": "5861051e6958489e94681625dec6c335" + }, + { + "m_Id": "6fe22af4b335449785d1591830c50ad8" + }, + { + "m_Id": "5649099a965447e4a907f5c05f14dbbd" + } + ], + "synonyms": [ + "code", + "HLSL" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SourceType": 0, + "m_FunctionName": "BuildEllipsoidBillboard", + "m_FunctionSource": "bc807595df1f54350ac0027aaf7cb91b", + "m_FunctionBody": "Enter function body here..." +} + +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.Internal.ColorShaderProperty", + "m_ObjectId": "1f4b884eb7a5494fa0a4c6b1726ae6e9", + "m_Guid": { + "m_GuidSerialized": "763834f5-9d1d-4816-ab86-2702663f61f8" + }, + "m_Name": "_ParticleColor", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "_ParticleColor", + "m_DefaultReferenceName": "_ParticleColor", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "isMainColor": false, + "m_ColorMode": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "1f4c9820a5b244deb7bd8e2bf0aa5270", + "m_Id": 0, + "m_DisplayName": "Metallic", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Metallic", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "1fdb294276af4309848652e8d2e07def", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Position", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 549.0, + "y": 56.99999237060547, + "width": 200.0, + "height": 41.000022888183597 + } + }, + "m_Slots": [ + { + "m_Id": "7e16c891692f43b1951da51f4eb47500" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Position" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "202b523ecf9e4573829b429baf158c79", + "m_Id": 0, + "m_DisplayName": "", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Matrix3MaterialSlot", + "m_ObjectId": "212c4e3679184df4b049b834fa8b8426", + "m_Id": 4, + "m_DisplayName": "IP", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "IP", + "m_StageCapability": 3, + "m_Value": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.Internal.Vector1ShaderProperty", + "m_ObjectId": "22b23a850ca345f6b5b35205f12039ae", + "m_Guid": { + "m_GuidSerialized": "50e8f452-c4bb-469f-bc6d-d232542d1f49" + }, + "m_Name": "_RadiusScale", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "_RadiusScale", + "m_DefaultReferenceName": "_RadiusScale", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": 1.0, + "m_FloatType": 0, + "m_RangeValues": { + "x": 0.0, + "y": 1.0 + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.TransformNode", + "m_ObjectId": "23a24fff90ba43ab9e3d17e24ec85ad7", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Transform", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -426.00006103515627, + "y": -20.999967575073243, + "width": 211.00003051757813, + "height": 156.99998474121095 + } + }, + "m_Slots": [ + { + "m_Id": "09069b51882f444b840aabb69c7c506f" + }, + { + "m_Id": "2bd336d88e8e4c18a43bb2689820da8b" + } + ], + "synonyms": [ + "world", + "tangent", + "object", + "view", + "screen", + "convert" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Conversion": { + "from": 2, + "to": 0 + }, + "m_ConversionType": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "24cc20330a6746e78f01f178e5c0ee25", + "m_Id": 0, + "m_DisplayName": "center", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "center", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.RedirectNodeData", + "m_ObjectId": "26e1af9d3ae14f71adf1a395a49b937e", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Redirect Node", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1105.0, + "y": -72.99999237060547, + "width": 56.0, + "height": 24.00000762939453 + } + }, + "m_Slots": [ + { + "m_Id": "f66158b6241342c88d2a4991233e93a8" + }, + { + "m_Id": "bfadf92d913d48b88b7911b3bf4952ba" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CustomInterpolatorNode", + "m_ObjectId": "29c676f6f7fc4d2dbb627a099736baaa", + "m_Group": { + "m_Id": "" + }, + "m_Name": "a2 (Custom Interpolator)", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -757.0000610351563, + "y": 766.0, + "width": 186.0, + "height": 94.0 + } + }, + "m_Slots": [ + { + "m_Id": "c1114c7b3db74f0da0e27c4938d3b793" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "customBlockNodeName": "a2", + "serializedType": 4 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "2b95d6ad64994e1b81cadbf3a7869b7f", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "2bd336d88e8e4c18a43bb2689820da8b", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "2c02d7c314a54cb8bed120d81563a87f", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.PositionNode", + "m_ObjectId": "2ece075db2b3411a80af471816c4e871", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Position", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1571.0001220703125, + "y": -238.0, + "width": 206.0001220703125, + "height": 131.0 + } + }, + "m_Slots": [ + { + "m_Id": "719c4a0aa83440f1abe407eb97fe03d1" + } + ], + "synonyms": [ + "location" + ], + "m_Precision": 1, + "m_PreviewExpanded": false, + "m_PreviewMode": 2, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Space": 2, + "m_PositionSource": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SplitNode", + "m_ObjectId": "2ed72e60304c47509002fc1b2c204a99", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Split", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -534.0, + "y": 266.0, + "width": 119.99993896484375, + "height": 149.00003051757813 + } + }, + "m_Slots": [ + { + "m_Id": "d9e1566528a04795a93b9222cfe9b841" + }, + { + "m_Id": "feae803029f141b7b77576f65de3f361" + }, + { + "m_Id": "9932077343944e9ea934ada791a438e8" + }, + { + "m_Id": "b61bc63901084fca9804abee48abddfd" + }, + { + "m_Id": "ae35ddc362bb47d9831f62b11095e69c" + } + ], + "synonyms": [ + "separate" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CustomInterpolatorNode", + "m_ObjectId": "32c989810b8e4fe7b964240b81ea9def", + "m_Group": { + "m_Id": "" + }, + "m_Name": "a3 (Custom Interpolator)", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -757.0000610351563, + "y": 865.0, + "width": 186.0, + "height": 94.0 + } + }, + "m_Slots": [ + { + "m_Id": "2c02d7c314a54cb8bed120d81563a87f" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "customBlockNodeName": "a3", + "serializedType": 4 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "32c9f709646841e6b3d5d2ecf3b88217", + "m_Id": 3, + "m_DisplayName": "B", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "333055955acb46f7b454539413c183b0", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "34b089445d94443bae321419aba92376", + "m_Id": 0, + "m_DisplayName": "", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", + "m_ObjectId": "3b5798f4b422481bb94c97f7014cd7b9", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Multiply", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 245.99986267089845, + "y": 410.9999694824219, + "width": 129.9999542236328, + "height": 118.00003051757813 + } + }, + "m_Slots": [ + { + "m_Id": "9d0a9a76df624baebeb40acbf1676a05" + }, + { + "m_Id": "6706229ffa8a452fb31f3e611a4e969f" + }, + { + "m_Id": "e27b00a5d6b8496e888b33ff61e843e3" + } + ], + "synonyms": [ + "multiplication", + "times", + "x" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicMatrixMaterialSlot", + "m_ObjectId": "3cdefcef62e446c6820185746a0ec7a1", + "m_Id": 1, + "m_DisplayName": "", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "3e0e2d1e47374294b5539e85bc63baf7", + "m_Id": 6, + "m_DisplayName": "a3", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "a3", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "3f7e82d473a94fab86903e3875520da8", + "m_Id": 4, + "m_DisplayName": "A", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "4142867127cb4a21bfa771e4c5b504bc", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Normal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "b456d184e007428eb74e555e1d369069" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Normal" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TangentMaterialSlot", + "m_ObjectId": "41c7519efb9a45fb85dcded2b16d584d", + "m_Id": 0, + "m_DisplayName": "Tangent", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Tangent", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "436f317395f24909887811586c2f866e", + "m_Id": 4, + "m_DisplayName": "worldPos", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "worldPos", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVNode", + "m_ObjectId": "44656ed842a54a34b956fc57e356de21", + "m_Group": { + "m_Id": "" + }, + "m_Name": "UV", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1908.0, + "y": 62.000003814697269, + "width": 145.0, + "height": 129.0 + } + }, + "m_Slots": [ + { + "m_Id": "2b95d6ad64994e1b81cadbf3a7869b7f" + } + ], + "synonyms": [ + "texcoords", + "coords", + "coordinates" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_OutputChannel": 1 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "463beca994a14896865c0978dffaa08b", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.NormalWS", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 541.0000610351563, + "y": 518.0, + "width": 199.99993896484376, + "height": 41.0 + } + }, + "m_Slots": [ + { + "m_Id": "d08d226deab44224a9c127e0838da1ec" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.NormalWS" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDTarget", + "m_ObjectId": "4790e9cb06234cefa4390fb194e36e9d", + "m_ActiveSubTarget": { + "m_Id": "f63f238dcaed45b9859faec9503ae798" + }, + "m_Datas": [ + { + "m_Id": "de8e93dbd1744203a66905de95755eec" + }, + { + "m_Id": "094b0804cd0a4e33920a4abe743454a6" + }, + { + "m_Id": "0302a9604b3f4175835f2fe805babd5b" + }, + { + "m_Id": "91a6a3e7575d45f9ad4d9f157973bc76" + } + ], + "m_CustomEditorGUI": "", + "m_SupportVFX": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Matrix3MaterialSlot", + "m_ObjectId": "48d6d267a6b6420c974cd75196394443", + "m_Id": 3, + "m_DisplayName": "IP", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "IP", + "m_StageCapability": 3, + "m_Value": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SplitNode", + "m_ObjectId": "4959d2015a38402881b6fec5e5a518a6", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Split", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -100.99998474121094, + "y": 973.0, + "width": 120.0, + "height": 149.0 + } + }, + "m_Slots": [ + { + "m_Id": "aa904b9834494fefae0603bbf51a46ae" + }, + { + "m_Id": "a04bfc2e0f9748878673606fffc20b60" + }, + { + "m_Id": "d5ab07535b904d6c95b72aefdd4d8ccd" + }, + { + "m_Id": "7e1b86be59204bddbf54c850cfe7f7fd" + }, + { + "m_Id": "ea691d98931f4db5b57fa9074c8ac113" + } + ], + "synonyms": [ + "separate" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "4c900e907c5340d88caa515b644c0a70", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 49.99992752075195, + "y": 511.9999694824219, + "width": 148.99998474121095, + "height": 34.000030517578128 + } + }, + "m_Slots": [ + { + "m_Id": "ec49096fac914af0a3faddf1feb3953c" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "1f4b884eb7a5494fa0a4c6b1726ae6e9" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CategoryData", + "m_ObjectId": "4c99293183f94afb9e94b8936dbbcc14", + "m_Name": "", + "m_ChildObjectList": [ + { + "m_Id": "1f4b884eb7a5494fa0a4c6b1726ae6e9" + }, + { + "m_Id": "22b23a850ca345f6b5b35205f12039ae" + }, + { + "m_Id": "ac709b9b0cc14e26a2611422b499ba45" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "4d1be359822e42259ed2488d64051ddd", + "m_Id": 2, + "m_DisplayName": "t1", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "t1", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.CustomFunctionNode", + "m_ObjectId": "4f921bef2597498da8ae8c75e3007b37", + "m_Group": { + "m_Id": "" + }, + "m_Name": "BuildParameterSpaceMatrices (Custom Function)", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1690.999755859375, + "y": 29.999990463256837, + "width": 326.0, + "height": 166.00001525878907 + } + }, + "m_Slots": [ + { + "m_Id": "6de4193c77c443cf829c0b9051349796" + }, + { + "m_Id": "4d1be359822e42259ed2488d64051ddd" + }, + { + "m_Id": "67fa16b6c3424083aaed5ff9d043584a" + }, + { + "m_Id": "d3003457079944b499113867ead39439" + }, + { + "m_Id": "cd294f26621f499cb86c60132cc4143c" + }, + { + "m_Id": "774879720fdb4a149503b61c37ca1170" + } + ], + "synonyms": [ + "code", + "HLSL" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SourceType": 0, + "m_FunctionName": "BuildParameterSpaceMatrices", + "m_FunctionSource": "bc807595df1f54350ac0027aaf7cb91b", + "m_FunctionBody": "Enter function body here..." +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "51b895e1b64e43529095cc44fc769771", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.RedirectNodeData", + "m_ObjectId": "51ff74a2115b4f07940322b02e8b9806", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Redirect Node", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1005.9999389648438, + "y": 304.0, + "width": 56.0, + "height": 24.0 + } + }, + "m_Slots": [ + { + "m_Id": "202b523ecf9e4573829b429baf158c79" + }, + { + "m_Id": "7597891277e54542b0e496704bf8a7f6" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "53f213ac70a7461ab7fb3813e00bb7f6", + "m_Id": 0, + "m_DisplayName": "", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "54c2e40c04ab4fa88a6d13a3467a46bd", + "m_Id": 1, + "m_DisplayName": "corner", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "corner", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "5649099a965447e4a907f5c05f14dbbd", + "m_Id": 7, + "m_DisplayName": "radius", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "radius", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "5861051e6958489e94681625dec6c335", + "m_Id": 6, + "m_DisplayName": "view", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "view", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 2, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInTarget", + "m_ObjectId": "5915510c968749209ff6f351ddb9a96e", + "m_ActiveSubTarget": { + "m_Id": "64c04874fef94dbaa74657a68a9696db" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZWriteControl": 0, + "m_ZTestMode": 4, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": true, + "m_CustomEditorGUI": "" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "5cb55dd043474b2ca931483a70806fb7", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.CustomFunctionNode", + "m_ObjectId": "5ee2f7c86c814012bd5eba803e4b36ea", + "m_Group": { + "m_Id": "" + }, + "m_Name": "BuildAuxiliaryNormalVectors (Custom Function)", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -533.9999389648438, + "y": -262.9999694824219, + "width": 316.00006103515627, + "height": 189.99996948242188 + } + }, + "m_Slots": [ + { + "m_Id": "855a9ade904b45bcac021a0c28779459" + }, + { + "m_Id": "60093ed6facb41ca9cb2a1c011469dfd" + }, + { + "m_Id": "0631b78f49ed4369abc26bddeecd8c71" + }, + { + "m_Id": "e3ffd102837b43d98258c9830c869bff" + }, + { + "m_Id": "212c4e3679184df4b049b834fa8b8426" + }, + { + "m_Id": "0c6df044f18e4fca8e0602ab941e36b3" + }, + { + "m_Id": "3e0e2d1e47374294b5539e85bc63baf7" + } + ], + "synonyms": [ + "code", + "HLSL" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SourceType": 0, + "m_FunctionName": "BuildAuxiliaryNormalVectors", + "m_FunctionSource": "bc807595df1f54350ac0027aaf7cb91b", + "m_FunctionBody": "Enter function body here..." +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "5ff456959eca4fbd934a5aac0280d67f", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.BaseColor", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "0ba2bd333a584e04a0f559269a5cb217" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.BaseColor" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "60093ed6facb41ca9cb2a1c011469dfd", + "m_Id": 1, + "m_DisplayName": "worldPos", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "worldPos", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "619732196dbf41f6a0e7b1174688f54c", + "m_Id": 6, + "m_DisplayName": "RG", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "RG", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "61c80ef969694adf838815d13bc5cd67", + "m_Id": 0, + "m_DisplayName": "Emission", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Emission", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 1, + "m_DefaultColor": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInLitSubTarget", + "m_ObjectId": "64c04874fef94dbaa74657a68a9696db", + "m_WorkflowMode": 1, + "m_NormalDropOffSpace": 2 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "6706229ffa8a452fb31f3e611a4e969f", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "e00": 2.0, + "e01": 2.0, + "e02": 2.0, + "e03": 2.0, + "e10": 2.0, + "e11": 2.0, + "e12": 2.0, + "e13": 2.0, + "e20": 2.0, + "e21": 2.0, + "e22": 2.0, + "e23": 2.0, + "e30": 2.0, + "e31": 2.0, + "e32": 2.0, + "e33": 2.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SplitNode", + "m_ObjectId": "675f1b67f80444599ddf4ba675419f8d", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Split", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -101.00003814697266, + "y": 815.0, + "width": 120.00003814697266, + "height": 149.0 + } + }, + "m_Slots": [ + { + "m_Id": "9dcc637f334c4ca6bf1c804405d3a006" + }, + { + "m_Id": "80b7c010fc9449a6be2b2971c67263b6" + }, + { + "m_Id": "b7ad4b8143794b239501e5624069fe3e" + }, + { + "m_Id": "32c9f709646841e6b3d5d2ecf3b88217" + }, + { + "m_Id": "3f7e82d473a94fab86903e3875520da8" + } + ], + "synonyms": [ + "separate" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "67fa16b6c3424083aaed5ff9d043584a", + "m_Id": 3, + "m_DisplayName": "t2", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "t2", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Matrix4MaterialSlot", + "m_ObjectId": "6938d733952943ab93dd81dd0cee899e", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TransformationMatrixNode", + "m_ObjectId": "69d4f0ec92ff4182be437caf84eafb72", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Transformation Matrix", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -214.9999237060547, + "y": 89.0, + "width": 171.99996948242188, + "height": 111.99996948242188 + } + }, + "m_Slots": [ + { + "m_Id": "6938d733952943ab93dd81dd0cee899e" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_matrix": -1, + "m_MatrixType": 2 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "6ad20bbbd1074108a572a177504cb6ea", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "6de4193c77c443cf829c0b9051349796", + "m_Id": 1, + "m_DisplayName": "t0", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "t0", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "6f08d1c6b86e499681f60f1f6a7f9196", + "m_Id": 6, + "m_DisplayName": "thickness", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "thickness", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.LengthNode", + "m_ObjectId": "6f0ad27166324e6fbc829bc0e4076d27", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Length", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -663.9999389648438, + "y": 368.0000305175781, + "width": 129.99993896484376, + "height": 93.99993896484375 + } + }, + "m_Slots": [ + { + "m_Id": "8b53ecbd13194b99a498b327fe512e93" + }, + { + "m_Id": "e716e7c9ae6e45278a7d746d0a1da856" + } + ], + "synonyms": [ + "measure" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "6fe22af4b335449785d1591830c50ad8", + "m_Id": 5, + "m_DisplayName": "eye", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "eye", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "719c4a0aa83440f1abe407eb97fe03d1", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "74076c4a517f4a9bb9273882b00b51a6", + "m_Id": 1, + "m_DisplayName": "", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "748d29134b584213abde74716f79052b", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "7597891277e54542b0e496704bf8a7f6", + "m_Id": 1, + "m_DisplayName": "", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ReciprocalNode", + "m_ObjectId": "7650578a1434466faec6ab2d3fe8f0a6", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Reciprocal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -414.00006103515627, + "y": 368.0000305175781, + "width": 145.0, + "height": 128.99996948242188 + } + }, + "m_Slots": [ + { + "m_Id": "5cb55dd043474b2ca931483a70806fb7" + }, + { + "m_Id": "02661c44bbcb4c2f9ba17e80d7961c8b" + } + ], + "synonyms": [ + "rcp" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_ReciprocalMethod": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalLitSubTarget", + "m_ObjectId": "773994bbd21543a0aefb333735078a53", + "m_WorkflowMode": 1, + "m_NormalDropOffSpace": 2, + "m_ClearCoat": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Matrix3MaterialSlot", + "m_ObjectId": "774879720fdb4a149503b61c37ca1170", + "m_Id": 4, + "m_DisplayName": "IP", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "IP", + "m_StageCapability": 3, + "m_Value": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "789d3c4acdee4777a68a43567cc7de51", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "79ab31681e3e419183510b2fa4f09f6a", + "m_Id": 2, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVNode", + "m_ObjectId": "79ee34ad93234f7880a9f2680b904beb", + "m_Group": { + "m_Id": "" + }, + "m_Name": "UV", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1908.0, + "y": -73.0, + "width": 145.0, + "height": 129.0 + } + }, + "m_Slots": [ + { + "m_Id": "748d29134b584213abde74716f79052b" + } + ], + "synonyms": [ + "texcoords", + "coords", + "coordinates" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_OutputChannel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "7be03ef72fc946ff81de225831947baf", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 362.0, + "y": 616.0, + "width": 145.0, + "height": 34.0 + } + }, + "m_Slots": [ + { + "m_Id": "09cd01e9020d48e1bda65b06c6a71b16" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "ac709b9b0cc14e26a2611422b499ba45" + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.CustomFunctionNode", + "m_ObjectId": "7c1b54d0ae564cce9fee0e3b18b0f945", + "m_Group": { + "m_Id": "" + }, + "m_Name": "IntersectEllipsoid (Custom Function)", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -425.99981689453127, + "y": 599.9999389648438, + "width": 251.99984741210938, + "height": 166.0 + } + }, + "m_Slots": [ + { + "m_Id": "afbbb64c9a7b4d16963c20b5f2af4154" + }, + { + "m_Id": "f30fd08bbcc74a6198fb279d65f82696" + }, + { + "m_Id": "b9f263f81f814659b65ba7c8965c6b7e" + }, + { + "m_Id": "0bed110901394810986b7c46885c2dbb" + }, + { + "m_Id": "d068f1207b3340f6a006284eb45ddb8b" + }, + { + "m_Id": "ce9414174ca54d1293c032bb45fac6a3" + }, + { + "m_Id": "6f08d1c6b86e499681f60f1f6a7f9196" + }, + { + "m_Id": "f50f51a906cb44dcbc8403263a8cfa32" + } + ], + "synonyms": [ + "code", + "HLSL" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SourceType": 0, + "m_FunctionName": "IntersectEllipsoid", + "m_FunctionSource": "bc807595df1f54350ac0027aaf7cb91b", + "m_FunctionBody": "Enter function body here..." +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PositionMaterialSlot", + "m_ObjectId": "7e16c891692f43b1951da51f4eb47500", + "m_Id": 0, + "m_DisplayName": "Position", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Position", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "7e1b86be59204bddbf54c850cfe7f7fd", + "m_Id": 3, + "m_DisplayName": "B", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "7e7b6ef93c414bec8d608482fc837fb3", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.CustomInterpolator", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 540.0000610351563, + "y": 51.99999237060547, + "width": 199.99993896484376, + "height": 41.00001525878906 + } + }, + "m_Slots": [ + { + "m_Id": "9d1228b7470642dd9a33ba2fb5148690" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.a2#4" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "8053f38f7ace4f8c9ae0b53fca131228", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "80b7c010fc9449a6be2b2971c67263b6", + "m_Id": 1, + "m_DisplayName": "R", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "R", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalVectorNode", + "m_ObjectId": "84cbbe352286486abb8cf0a951e3e458", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Normal Vector", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1570.9998779296875, + "y": -106.99996948242188, + "width": 206.0, + "height": 131.0 + } + }, + "m_Slots": [ + { + "m_Id": "6ad20bbbd1074108a572a177504cb6ea" + } + ], + "synonyms": [ + "surface direction" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 2, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "855a9ade904b45bcac021a0c28779459", + "m_Id": 0, + "m_DisplayName": "center", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "center", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "8b53ecbd13194b99a498b327fe512e93", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.SystemData", + "m_ObjectId": "91a6a3e7575d45f9ad4d9f157973bc76", + "m_MaterialNeedsUpdateHash": 529, + "m_SurfaceType": 0, + "m_RenderingPass": 1, + "m_BlendMode": 0, + "m_ZTest": 4, + "m_ZWrite": false, + "m_TransparentCullMode": 2, + "m_OpaqueCullMode": 2, + "m_SortPriority": 0, + "m_AlphaTest": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_SupportLodCrossFade": false, + "m_DoubleSidedMode": 0, + "m_DOTSInstancing": false, + "m_CustomVelocity": false, + "m_Tessellation": false, + "m_TessellationMode": 0, + "m_TessellationFactorMinDistance": 20.0, + "m_TessellationFactorMaxDistance": 50.0, + "m_TessellationFactorTriangleSize": 100.0, + "m_TessellationShapeFactor": 0.75, + "m_TessellationBackFaceCullEpsilon": -0.25, + "m_TessellationMaxDisplacement": 0.009999999776482582, + "m_Version": 1, + "inspectorFoldoutMask": 9 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "94d8bef9ca4146a9bc8013782aa27188", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.VertexColorNode", + "m_ObjectId": "97bd7a4169c641a59a7012a029b44964", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Vertex Color", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 81.0, + "y": 391.0, + "width": 118.00001525878906, + "height": 93.99990844726563 + } + }, + "m_Slots": [ + { + "m_Id": "333055955acb46f7b454539413c183b0" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 2, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "9932077343944e9ea934ada791a438e8", + "m_Id": 2, + "m_DisplayName": "G", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "G", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "9a540fa4d7fd41edb663c20d392cc937", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.CustomInterpolator", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 557.0, + "y": 316.0, + "width": 200.0001220703125, + "height": 40.999969482421878 + } + }, + "m_Slots": [ + { + "m_Id": "f14b3173a44b48f1a3ab3e787ab15403" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.mapping#4" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "9d04c3fa0c6848bd908018475a5ec9cf", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "9d0a9a76df624baebeb40acbf1676a05", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "9d1228b7470642dd9a33ba2fb5148690", + "m_Id": 0, + "m_DisplayName": "a2", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "a2", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "9dcc637f334c4ca6bf1c804405d3a006", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalTarget", + "m_ObjectId": "9f0ab621b28741df9e2a65a37837af56", + "m_ActiveSubTarget": { + "m_Id": "773994bbd21543a0aefb333735078a53" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZTestMode": 4, + "m_ZWriteControl": 0, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": true, + "m_CastShadows": true, + "m_ReceiveShadows": true, + "m_CustomEditorGUI": "", + "m_SupportVFX": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "a04bfc2e0f9748878673606fffc20b60", + "m_Id": 1, + "m_DisplayName": "R", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "R", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.TransformNode", + "m_ObjectId": "a5babea545924715b0ba888ac6373f66", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Transform", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -24.000009536743165, + "y": 594.0, + "width": 211.00003051757813, + "height": 157.0 + } + }, + "m_Slots": [ + { + "m_Id": "789d3c4acdee4777a68a43567cc7de51" + }, + { + "m_Id": "8053f38f7ace4f8c9ae0b53fca131228" + } + ], + "synonyms": [ + "world", + "tangent", + "object", + "view", + "screen", + "convert" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Conversion": { + "from": 1, + "to": 2 + }, + "m_ConversionType": 1 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "a7a558d25384460e8b0995dc9f89165a", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "aa904b9834494fefae0603bbf51a46ae", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "ac5ddd82d3a84a4cbf509ddfe1beb229", + "m_Id": 3, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.Internal.Vector1ShaderProperty", + "m_ObjectId": "ac709b9b0cc14e26a2611422b499ba45", + "m_Guid": { + "m_GuidSerialized": "fd0f61ba-fe9f-4b6c-a0ab-7f54fec438ab" + }, + "m_Name": "_Smoothness", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "_Smoothness", + "m_DefaultReferenceName": "_Smoothness", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": 0.5, + "m_FloatType": 1, + "m_RangeValues": { + "x": 0.0, + "y": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "acddb4312eae4453829ee3b01c3b96e1", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "ae35ddc362bb47d9831f62b11095e69c", + "m_Id": 4, + "m_DisplayName": "A", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", + "m_ObjectId": "af8c0d42edcd4eda8e6e86de937dbadf", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Multiply", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -5.000051021575928, + "y": 145.00003051757813, + "width": 143.00003051757813, + "height": 117.99993896484375 + } + }, + "m_Slots": [ + { + "m_Id": "eefaca546df646d9bab0a7e8ead8fe9f" + }, + { + "m_Id": "e82eba05d3404e81a4d1193cf676653b" + }, + { + "m_Id": "acddb4312eae4453829ee3b01c3b96e1" + } + ], + "synonyms": [ + "multiplication", + "times", + "x" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "afbbb64c9a7b4d16963c20b5f2af4154", + "m_Id": 0, + "m_DisplayName": "v", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "v", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "b35a3765628d49f69d75dfc77df38114", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.CustomInterpolator", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 547.0, + "y": 88.00001525878906, + "width": 200.0001220703125, + "height": 40.999969482421878 + } + }, + "m_Slots": [ + { + "m_Id": "c81b0a23ef5c4e1bbc194418c1316342" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.a3#4" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CustomInterpolatorNode", + "m_ObjectId": "b397b42dfd5342b0b6291c60e22ae6d4", + "m_Group": { + "m_Id": "" + }, + "m_Name": "mapping (Custom Interpolator)", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -787.0000610351563, + "y": 672.0, + "width": 221.0, + "height": 94.0 + } + }, + "m_Slots": [ + { + "m_Id": "94d8bef9ca4146a9bc8013782aa27188" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "customBlockNodeName": "mapping", + "serializedType": 4 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "b456d184e007428eb74e555e1d369069", + "m_Id": 0, + "m_DisplayName": "Normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Normal", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "b585fdf2c7ce438b8a72c6f452ff31ab", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.CustomInterpolator", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 235.00001525878907, + "y": 189.0, + "width": 199.99989318847657, + "height": 40.99998474121094 + } + }, + "m_Slots": [ + { + "m_Id": "e5ebb82ec44c4baf91e6301f7c8864a9" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.viewRay#3" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "b61bc63901084fca9804abee48abddfd", + "m_Id": 3, + "m_DisplayName": "B", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "b7ad4b8143794b239501e5624069fe3e", + "m_Id": 2, + "m_DisplayName": "G", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "G", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "b97286e6cc284c43a67b57f07ce0539b", + "m_Id": 0, + "m_DisplayName": "Alpha", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Alpha", + "m_StageCapability": 2, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "b9f263f81f814659b65ba7c8965c6b7e", + "m_Id": 2, + "m_DisplayName": "a2", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "a2", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CombineNode", + "m_ObjectId": "babccae7634a4d2090f45aa9e154b2ca", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Combine", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -215.00001525878907, + "y": 266.0, + "width": 140.00001525878907, + "height": 166.0 + } + }, + "m_Slots": [ + { + "m_Id": "f4036022b00d4f13bf8f03f2b55d5b41" + }, + { + "m_Id": "d49b15aa5cf746cf954a2b46e033e76d" + }, + { + "m_Id": "79ab31681e3e419183510b2fa4f09f6a" + }, + { + "m_Id": "ac5ddd82d3a84a4cbf509ddfe1beb229" + }, + { + "m_Id": "c6fd8c5c8cf744a58bb4efca3dab998f" + }, + { + "m_Id": "08351f97eeea4b6485b39a61a65a3fe8" + }, + { + "m_Id": "619732196dbf41f6a0e7b1174688f54c" + } + ], + "synonyms": [ + "append" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicMatrixMaterialSlot", + "m_ObjectId": "bfadf92d913d48b88b7911b3bf4952ba", + "m_Id": 1, + "m_DisplayName": "", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "c1114c7b3db74f0da0e27c4938d3b793", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.RedirectNodeData", + "m_ObjectId": "c6116508eb7246469fe9c6ae81460410", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Redirect Node", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -426.00006103515627, + "y": 864.9999389648438, + "width": 56.000030517578128, + "height": 24.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "53f213ac70a7461ab7fb3813e00bb7f6" + }, + { + "m_Id": "74076c4a517f4a9bb9273882b00b51a6" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "c6fd8c5c8cf744a58bb4efca3dab998f", + "m_Id": 4, + "m_DisplayName": "RGBA", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "RGBA", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "c81b0a23ef5c4e1bbc194418c1316342", + "m_Id": 0, + "m_DisplayName": "a3", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "a3", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Matrix3MaterialSlot", + "m_ObjectId": "cd294f26621f499cb86c60132cc4143c", + "m_Id": 0, + "m_DisplayName": "P", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "P", + "m_StageCapability": 3, + "m_Value": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "ce61c417fb924d9098ede6f08e533041", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "ce9414174ca54d1293c032bb45fac6a3", + "m_Id": 5, + "m_DisplayName": "eyeNormal", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "eyeNormal", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "cf2c0d4033c24443b7c21cb036226b3f", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Emission", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "61c80ef969694adf838815d13bc5cd67" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Emission" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "d068f1207b3340f6a006284eb45ddb8b", + "m_Id": 4, + "m_DisplayName": "eyePos", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "eyePos", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "d08d226deab44224a9c127e0838da1ec", + "m_Id": 0, + "m_DisplayName": "Normal (World Space)", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "NormalWS", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 2 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "d11f8fd02e364ad5b8eadd3550fa2851", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Metallic", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "1f4c9820a5b244deb7bd8e2bf0aa5270" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Metallic" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "d3003457079944b499113867ead39439", + "m_Id": 5, + "m_DisplayName": "radiusScale", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "radiusScale", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "d49b15aa5cf746cf954a2b46e033e76d", + "m_Id": 1, + "m_DisplayName": "G", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "G", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "d5ab07535b904d6c95b72aefdd4d8ccd", + "m_Id": 2, + "m_DisplayName": "G", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "G", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "d9e1566528a04795a93b9222cfe9b841", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "db6f119a98ed4aee872e15302095fbfb", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "dba07545e112449c9e6450b20a948fe0", + "m_Id": 0, + "m_DisplayName": "Smoothness", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Smoothness", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.5, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDLitData", + "m_ObjectId": "de8e93dbd1744203a66905de95755eec", + "m_RayTracing": false, + "m_MaterialType": 0, + "m_RefractionModel": 0, + "m_SSSTransmission": true, + "m_EnergyConservingSpecular": true, + "m_ClearCoat": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "dfd25b2a19df42beba356ef0e5e0b3be", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.AlphaClipThreshold", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "f73cd7a7841243ac96286fd2afaf7862" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.AlphaClipThreshold" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "dffaa900d1d04a7db60ef0ccab276839", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Smoothness", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "dba07545e112449c9e6450b20a948fe0" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Smoothness" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "e09a4f7448b74893a9745d1625d39a19", + "m_Id": 0, + "m_DisplayName": "_RadiusScale", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "e17c109ffbe942c89e40ff95cd1cfd7a", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Tangent", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "41c7519efb9a45fb85dcded2b16d584d" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Tangent" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CustomInterpolatorNode", + "m_ObjectId": "e185f6e703b749569fec95035ae86e44", + "m_Group": { + "m_Id": "" + }, + "m_Name": "viewRay (Custom Interpolator)", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -790.0000610351563, + "y": 576.0, + "width": 219.0, + "height": 94.0 + } + }, + "m_Slots": [ + { + "m_Id": "db6f119a98ed4aee872e15302095fbfb" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "customBlockNodeName": "viewRay", + "serializedType": 3 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "e27b00a5d6b8496e888b33ff61e843e3", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Matrix3MaterialSlot", + "m_ObjectId": "e3ffd102837b43d98258c9830c869bff", + "m_Id": 3, + "m_DisplayName": "P", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "P", + "m_StageCapability": 3, + "m_Value": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "e445db0b154846179887a9470ff3aa66", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1906.9998779296875, + "y": 331.0, + "width": 143.9998779296875, + "height": 33.999969482421878 + } + }, + "m_Slots": [ + { + "m_Id": "e09a4f7448b74893a9745d1625d39a19" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "22b23a850ca345f6b5b35205f12039ae" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "e5ebb82ec44c4baf91e6301f7c8864a9", + "m_Id": 0, + "m_DisplayName": "viewRay", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "viewRay", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "e716e7c9ae6e45278a7d746d0a1da856", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "e82eba05d3404e81a4d1193cf676653b", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "e00": 2.0, + "e01": 2.0, + "e02": 2.0, + "e03": 2.0, + "e10": 2.0, + "e11": 2.0, + "e12": 2.0, + "e13": 2.0, + "e20": 2.0, + "e21": 2.0, + "e22": 2.0, + "e23": 2.0, + "e30": 2.0, + "e31": 2.0, + "e32": 2.0, + "e33": 2.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "e94b4e133a134411aa01241421f711cb", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Alpha", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "b97286e6cc284c43a67b57f07ce0539b" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Alpha" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "ea691d98931f4db5b57fa9074c8ac113", + "m_Id": 4, + "m_DisplayName": "A", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "ec49096fac914af0a3faddf1feb3953c", + "m_Id": 0, + "m_DisplayName": "_ParticleColor", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "ee946d6d4c7c4cb1b920e447bb01d580", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.DepthOffset", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 546.0, + "y": 732.0, + "width": 200.0, + "height": 41.0 + } + }, + "m_Slots": [ + { + "m_Id": "0a65b1a8a9cc4d26aa3d5676905379a0" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.DepthOffset" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "eefaca546df646d9bab0a7e8ead8fe9f", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "ef8a1c0804ec4253ad73c319031bec6e", + "m_Id": 1, + "m_DisplayName": "", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "f14b3173a44b48f1a3ab3e787ab15403", + "m_Id": 0, + "m_DisplayName": "mapping", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "mapping", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "f30fd08bbcc74a6198fb279d65f82696", + "m_Id": 1, + "m_DisplayName": "mapping", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "mapping", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "f4036022b00d4f13bf8f03f2b55d5b41", + "m_Id": 0, + "m_DisplayName": "R", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "R", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "f50f51a906cb44dcbc8403263a8cfa32", + "m_Id": 7, + "m_DisplayName": "clipThreshold", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "clipThreshold", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SubtractNode", + "m_ObjectId": "f5da1c6b4af04e169c2dce3319f17d13", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Subtract", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 63.999977111816409, + "y": 877.0, + "width": 126.00000762939453, + "height": 118.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "a7a558d25384460e8b0995dc9f89165a" + }, + { + "m_Id": "ce61c417fb924d9098ede6f08e533041" + }, + { + "m_Id": "51b895e1b64e43529095cc44fc769771" + } + ], + "synonyms": [ + "subtraction", + "remove", + "minus", + "take away" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDLitSubTarget", + "m_ObjectId": "f63f238dcaed45b9859faec9503ae798" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicMatrixMaterialSlot", + "m_ObjectId": "f66158b6241342c88d2a4991233e93a8", + "m_Id": 0, + "m_DisplayName": "", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "f73cd7a7841243ac96286fd2afaf7862", + "m_Id": 0, + "m_DisplayName": "Alpha Clip Threshold", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "AlphaClipThreshold", + "m_StageCapability": 2, + "m_Value": 0.5, + "m_DefaultValue": 0.5, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "feae803029f141b7b77576f65de3f361", + "m_Id": 1, + "m_DisplayName": "R", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "R", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + diff --git a/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ParticleShader.shadergraph.meta b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ParticleShader.shadergraph.meta new file mode 100644 index 00000000..59a0a5bc --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/ParticleShader.shadergraph.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 99a2f8857960c44ca980d85023572447 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} diff --git a/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Particles.mat b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Particles.mat new file mode 100644 index 00000000..3f9b1b29 --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Particles.mat @@ -0,0 +1,123 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-5466045192948715276 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 639247ca83abc874e893eb93af2b5e44, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 0 +--- !u!114 &-4382110247035737841 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 5 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Particles + m_Shader: {fileID: -6465566751694194690, guid: 99a2f8857960c44ca980d85023572447, type: 3} + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 10300, guid: 0000000000000000f000000000000000, type: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BUILTIN_QueueControl: 0 + - _BUILTIN_QueueOffset: 0 + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _Glossiness: 0.5 + - _InvFade: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _RadiusScale: 1 + - _Smoothness: 0.6 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _ParticleColor: {r: 1, g: 1, b: 1, a: 0} + - _TintColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5} + m_BuildTextureStacks: [] diff --git a/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Particles.mat.meta b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Particles.mat.meta new file mode 100644 index 00000000..c30f265c --- /dev/null +++ b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/Particles.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fb88690dea2394644849cde5abd037f9 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/particle.png b/xiaofang/Assets/Obi/Resources/ObiMaterials/Common/particle.png new file mode 100644 index 0000000000000000000000000000000000000000..1eea413c76754653ab725abbd890e799eef59cc2 GIT binary patch literal 4796 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≺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 z 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%0DS>5>v;T#vs4mK-O-`RV}xoPE;i%_>4 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