commit
This commit is contained in:
commit
dc30d654bf
Binary file not shown.
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 329ec9409c534054d896e1b927a1b71c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,31 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
[CustomEditor(typeof(TurtleLSystem),true)]
|
||||
public class TurtleEditor : Editor
|
||||
{
|
||||
TurtleLSystem turtleLSystem;
|
||||
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
DrawDefaultInspector();
|
||||
|
||||
if (GUILayout.Button("Load file")) {
|
||||
turtleLSystem.loadFile();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Evaluate")) {
|
||||
turtleLSystem.evaluateAndPresent();
|
||||
}
|
||||
|
||||
}
|
||||
void OnEnable() {
|
||||
turtleLSystem = (TurtleLSystem)target;
|
||||
Tools.hidden = true;
|
||||
}
|
||||
|
||||
void OnDisable() {
|
||||
Tools.hidden = false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5805e7212a5b20b4da42e342c1edaf04
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 53a6756541318784f8b822a4dd8564c2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,13 @@
|
|||
#axiom
|
||||
B
|
||||
#rules
|
||||
B -> #stochastic
|
||||
p=3 XF
|
||||
p=2 [-XB]X&&&--///L\\\++^^^X++&&&///L\\\^^^--XF
|
||||
p=2 [&XB]X&&&--///L\\\++^^^X++&&&///L\\\^^^--XF
|
||||
p=2 [^XB]X&&&--///L\\\++^^^X&++&&///L\\\^^^--XF
|
||||
p=2 [+XB]X&&&--///L\\\++^^^X++&&&///L\\\^^^--XF
|
||||
p=2 [\+XB]X&&&--///L\\\++^^^X++&&&///L\\\^^^--XF
|
||||
p=2 [/+XB]X&&&--///L\\\++^^^X++&&&///L\\\^^^--XF
|
||||
#stochastic end
|
||||
#rules end
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cc28d00b512b3174eba36e99fbe5f55e
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 89cf392879d4c2541b060051f92c5d3c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,78 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: leaf material
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords: _ALPHAPREMULTIPLY_ON
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: 3000
|
||||
stringTagMap:
|
||||
RenderType: Transparent
|
||||
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: 4cf885f6598282142af25712ee21ee4c, 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_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 10
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.426
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 3
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 0
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 40be7c60f27d0cf48818ffb9777dd7fb
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3c3b87c72381e5d428800a1a82fa4fcc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,107 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 06838bfd0bf73c647812994a50837eaf
|
||||
ModelImporter:
|
||||
serializedVersion: 20200
|
||||
internalIDToNameTable: []
|
||||
externalObjects:
|
||||
- first:
|
||||
type: UnityEngine:Material
|
||||
assembly: UnityEngine.CoreModule
|
||||
name: lambert2
|
||||
second: {fileID: 2100000, guid: 40be7c60f27d0cf48818ffb9777dd7fb, type: 2}
|
||||
materials:
|
||||
materialImportMode: 1
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
materialLocation: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
rigImportErrors:
|
||||
rigImportWarnings:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
importAnimatedCustomProperties: 0
|
||||
importConstraints: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
extraUserProperties: []
|
||||
clipAnimations: []
|
||||
isReadable: 0
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
useSRGBMaterialColor: 1
|
||||
sortHierarchyByName: 1
|
||||
importVisibility: 1
|
||||
importBlendShapes: 1
|
||||
importCameras: 1
|
||||
importLights: 1
|
||||
fileIdsGeneration: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
bakeAxisConversion: 0
|
||||
preserveHierarchy: 0
|
||||
skinWeightsMode: 0
|
||||
maxBonesPerVertex: 4
|
||||
minBoneWeight: 0.001
|
||||
meshOptimizationFlags: -1
|
||||
indexFormat: 0
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVMarginMethod: 1
|
||||
secondaryUVMinLightmapResolution: 40
|
||||
secondaryUVMinObjectScale: 1
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
normalCalculationMode: 4
|
||||
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
|
||||
blendShapeNormalImportMode: 1
|
||||
normalSmoothingSource: 0
|
||||
referencedClips: []
|
||||
importAnimation: 1
|
||||
humanDescription:
|
||||
serializedVersion: 3
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
globalScale: 0.01
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 1
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
autoGenerateAvatarMappingIfUnspecified: 1
|
||||
animationType: 2
|
||||
humanoidOversampling: 1
|
||||
avatarSetup: 0
|
||||
addHumanoidExtraRootOnlyWhenUsingAvatar: 0
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,102 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a3c2912313688e7409f0487619dfe166
|
||||
ModelImporter:
|
||||
serializedVersion: 20200
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
materials:
|
||||
materialImportMode: 2
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
materialLocation: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
rigImportErrors:
|
||||
rigImportWarnings:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
importAnimatedCustomProperties: 0
|
||||
importConstraints: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
extraUserProperties: []
|
||||
clipAnimations: []
|
||||
isReadable: 0
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
useSRGBMaterialColor: 1
|
||||
sortHierarchyByName: 1
|
||||
importVisibility: 1
|
||||
importBlendShapes: 1
|
||||
importCameras: 1
|
||||
importLights: 1
|
||||
fileIdsGeneration: 2
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
bakeAxisConversion: 0
|
||||
preserveHierarchy: 0
|
||||
skinWeightsMode: 0
|
||||
maxBonesPerVertex: 4
|
||||
minBoneWeight: 0.001
|
||||
meshOptimizationFlags: -1
|
||||
indexFormat: 0
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVMarginMethod: 1
|
||||
secondaryUVMinLightmapResolution: 40
|
||||
secondaryUVMinObjectScale: 1
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
normalCalculationMode: 4
|
||||
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
|
||||
blendShapeNormalImportMode: 1
|
||||
normalSmoothingSource: 0
|
||||
referencedClips: []
|
||||
importAnimation: 1
|
||||
humanDescription:
|
||||
serializedVersion: 3
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
globalScale: 1
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 1
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
autoGenerateAvatarMappingIfUnspecified: 1
|
||||
animationType: 2
|
||||
humanoidOversampling: 1
|
||||
avatarSetup: 0
|
||||
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,102 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ca516c08d816f5f4d8454c64e6d9eeab
|
||||
ModelImporter:
|
||||
serializedVersion: 20200
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
materials:
|
||||
materialImportMode: 2
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
materialLocation: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
rigImportErrors:
|
||||
rigImportWarnings:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
importAnimatedCustomProperties: 0
|
||||
importConstraints: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
extraUserProperties: []
|
||||
clipAnimations: []
|
||||
isReadable: 0
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
useSRGBMaterialColor: 1
|
||||
sortHierarchyByName: 1
|
||||
importVisibility: 1
|
||||
importBlendShapes: 1
|
||||
importCameras: 1
|
||||
importLights: 1
|
||||
fileIdsGeneration: 2
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
bakeAxisConversion: 0
|
||||
preserveHierarchy: 0
|
||||
skinWeightsMode: 0
|
||||
maxBonesPerVertex: 4
|
||||
minBoneWeight: 0.001
|
||||
meshOptimizationFlags: -1
|
||||
indexFormat: 0
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVMarginMethod: 1
|
||||
secondaryUVMinLightmapResolution: 40
|
||||
secondaryUVMinObjectScale: 1
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
normalCalculationMode: 4
|
||||
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
|
||||
blendShapeNormalImportMode: 1
|
||||
normalSmoothingSource: 0
|
||||
referencedClips: []
|
||||
importAnimation: 1
|
||||
humanDescription:
|
||||
serializedVersion: 3
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
globalScale: 1
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 1
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
autoGenerateAvatarMappingIfUnspecified: 1
|
||||
animationType: 2
|
||||
humanoidOversampling: 1
|
||||
avatarSetup: 0
|
||||
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,81 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3132964252630352729
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7594502901394162009}
|
||||
- component: {fileID: 4391870333044285248}
|
||||
- component: {fileID: 4416866696227822882}
|
||||
m_Layer: 0
|
||||
m_Name: cylinder
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &7594502901394162009
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3132964252630352729}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: -1, z: 0}
|
||||
m_LocalScale: {x: 0.5, y: 1, z: 0.5}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!33 &4391870333044285248
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3132964252630352729}
|
||||
m_Mesh: {fileID: 10206, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!23 &4416866696227822882
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3132964252630352729}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: -876546973899608171, guid: aac0ac856409e5c40acd3911f70271ca, type: 3}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 537804071d025f14d907bbea26a5b603
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,102 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cc42f516e5f34114f99b98c835b8c85f
|
||||
ModelImporter:
|
||||
serializedVersion: 20200
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
materials:
|
||||
materialImportMode: 2
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
materialLocation: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
rigImportErrors:
|
||||
rigImportWarnings:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
importAnimatedCustomProperties: 0
|
||||
importConstraints: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
extraUserProperties: []
|
||||
clipAnimations: []
|
||||
isReadable: 0
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
useSRGBMaterialColor: 1
|
||||
sortHierarchyByName: 1
|
||||
importVisibility: 1
|
||||
importBlendShapes: 1
|
||||
importCameras: 1
|
||||
importLights: 1
|
||||
fileIdsGeneration: 2
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
bakeAxisConversion: 0
|
||||
preserveHierarchy: 0
|
||||
skinWeightsMode: 0
|
||||
maxBonesPerVertex: 4
|
||||
minBoneWeight: 0.001
|
||||
meshOptimizationFlags: -1
|
||||
indexFormat: 0
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVMarginMethod: 1
|
||||
secondaryUVMinLightmapResolution: 40
|
||||
secondaryUVMinObjectScale: 1
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
normalCalculationMode: 4
|
||||
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
|
||||
blendShapeNormalImportMode: 1
|
||||
normalSmoothingSource: 0
|
||||
referencedClips: []
|
||||
importAnimation: 1
|
||||
humanDescription:
|
||||
serializedVersion: 3
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
globalScale: 1
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 1
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
autoGenerateAvatarMappingIfUnspecified: 1
|
||||
animationType: 2
|
||||
humanoidOversampling: 1
|
||||
avatarSetup: 0
|
||||
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,96 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8d0c2fec8c571c349b438fde39c3938e
|
||||
ModelImporter:
|
||||
serializedVersion: 19300
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
materials:
|
||||
materialImportMode: 1
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
materialLocation: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
rigImportErrors:
|
||||
rigImportWarnings:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
importAnimatedCustomProperties: 0
|
||||
importConstraints: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
extraUserProperties: []
|
||||
clipAnimations: []
|
||||
isReadable: 0
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 0.2
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
useSRGBMaterialColor: 1
|
||||
sortHierarchyByName: 1
|
||||
importVisibility: 1
|
||||
importBlendShapes: 1
|
||||
importCameras: 1
|
||||
importLights: 1
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
preserveHierarchy: 0
|
||||
skinWeightsMode: 0
|
||||
maxBonesPerVertex: 4
|
||||
minBoneWeight: 0.001
|
||||
meshOptimizationFlags: -1
|
||||
indexFormat: 0
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
normalCalculationMode: 4
|
||||
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
|
||||
blendShapeNormalImportMode: 1
|
||||
normalSmoothingSource: 0
|
||||
referencedClips: []
|
||||
importAnimation: 1
|
||||
humanDescription:
|
||||
serializedVersion: 3
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
globalScale: 0.002
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 1
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
autoGenerateAvatarMappingIfUnspecified: 1
|
||||
animationType: 2
|
||||
humanoidOversampling: 1
|
||||
avatarSetup: 0
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,102 @@
|
|||
fileFormatVersion: 2
|
||||
guid: aac0ac856409e5c40acd3911f70271ca
|
||||
ModelImporter:
|
||||
serializedVersion: 20200
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
materials:
|
||||
materialImportMode: 2
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
materialLocation: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
motionNodeName:
|
||||
rigImportErrors:
|
||||
rigImportWarnings:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
importAnimatedCustomProperties: 0
|
||||
importConstraints: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
extraUserProperties: []
|
||||
clipAnimations: []
|
||||
isReadable: 0
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
useSRGBMaterialColor: 1
|
||||
sortHierarchyByName: 1
|
||||
importVisibility: 1
|
||||
importBlendShapes: 1
|
||||
importCameras: 1
|
||||
importLights: 1
|
||||
fileIdsGeneration: 2
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
bakeAxisConversion: 0
|
||||
preserveHierarchy: 0
|
||||
skinWeightsMode: 0
|
||||
maxBonesPerVertex: 4
|
||||
minBoneWeight: 0.001
|
||||
meshOptimizationFlags: -1
|
||||
indexFormat: 0
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVMarginMethod: 1
|
||||
secondaryUVMinLightmapResolution: 40
|
||||
secondaryUVMinObjectScale: 1
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
normalCalculationMode: 4
|
||||
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
|
||||
blendShapeNormalImportMode: 1
|
||||
normalSmoothingSource: 0
|
||||
referencedClips: []
|
||||
importAnimation: 1
|
||||
humanDescription:
|
||||
serializedVersion: 3
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
globalScale: 1
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 1
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
autoGenerateAvatarMappingIfUnspecified: 1
|
||||
animationType: 2
|
||||
humanoidOversampling: 1
|
||||
avatarSetup: 0
|
||||
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0ca0a699eef019647a81d0cedf67bf1f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7b146ace23aa4ca4b98c431ce3cf7fe7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
After Width: | Height: | Size: 1010 KiB |
|
@ -0,0 +1,103 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4cf885f6598282142af25712ee21ee4c
|
||||
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: 1
|
||||
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: 0
|
||||
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:
|
|
@ -0,0 +1,85 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: New Material
|
||||
m_Shader: {fileID: 106, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords: _SUNDISK_SIMPLE
|
||||
m_LightmapFlags: 4
|
||||
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}
|
||||
m_Floats:
|
||||
- _AtmosphereThickness: 0
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _Exposure: 1.3
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _SunDisk: 1
|
||||
- _SunSize: 0.074
|
||||
- _SunSizeConvergence: 5
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _GroundColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SkyTint: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_BuildTextureStacks: []
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 15df3041f931a4b3189530813766d6c2
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a7209ff67dfb5d44a85024a84dd4f84a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 12af647ed3c081041a127bb7756c2996
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c0b8448007c1f7d4c89463b38c587b65
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 099938b93a3869e47a560e0a8d63bcaf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,312 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
|
||||
//TODO add parsing for more than single letter
|
||||
|
||||
namespace ConsoleLSystem {
|
||||
abstract public class LSystemGeneralWordBuilder {
|
||||
abstract public LSystemNode createLSystemNode(string name, int values_number);
|
||||
abstract public void fillArguments(LSystemNode node, string[] arguments_strings);
|
||||
}
|
||||
public class LSystemWordBuilder : LSystemGeneralWordBuilder {
|
||||
public override LSystemNode createLSystemNode(string name, int values_number) {
|
||||
return new LSystemNode(new LSystemNodeLiteral(name, values_number));
|
||||
}
|
||||
|
||||
|
||||
public override void fillArguments(LSystemNode node, string[] arguments_strings) {
|
||||
for (int i = 0; i < arguments_strings.Length; i++) {
|
||||
node.literal.values[i] = float.Parse(arguments_strings[i], NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class LSystemWordGeneratorBuilder : LSystemGeneralWordBuilder {
|
||||
public Dictionary<string, int> variableIndex { get;}
|
||||
public LSystemWordGeneratorBuilder(Dictionary<string,int> variable_index) {
|
||||
this.variableIndex = variable_index;
|
||||
}
|
||||
public override LSystemNode createLSystemNode(string name, int values_number) {
|
||||
return new LSystemNodeGenerator(name, values_number);
|
||||
}
|
||||
|
||||
public override void fillArguments(LSystemNode node, string[] arguments_strings) {
|
||||
MathExpression[] expressions = arguments_strings.Select(argument => new MathExpression(variableIndex, argument)).ToArray();
|
||||
LSystemNodeGenerator ng = (LSystemNodeGenerator)node;
|
||||
ng.fillArguments(expressions);
|
||||
}
|
||||
|
||||
}
|
||||
public class LSystemFileParser {
|
||||
//LSystemWordParser wordParser;
|
||||
//LSystemRulesParser ruleParser;
|
||||
|
||||
//public LSystemFileParser(LSystemWordParser wordParser, LSystemRulesParser ruleParser) {
|
||||
// this.wordParser = wordParser;
|
||||
// this.ruleParser = ruleParser;
|
||||
//}
|
||||
public static int countParenthesisEnd(string line,char opening_char, char closing_char) {
|
||||
var parenthesises_number = 1;
|
||||
var length = -1;
|
||||
while (parenthesises_number > 0) {
|
||||
length++;
|
||||
var c = line[1 + length];
|
||||
if (c == opening_char) {
|
||||
parenthesises_number++;
|
||||
}
|
||||
if (c == closing_char) {
|
||||
parenthesises_number--;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
public static bool parenthesisCheck(string line) {
|
||||
var parenthesises_number = 0;
|
||||
var brackets_number = 0;
|
||||
foreach (var s in line) {
|
||||
if (s == '(') {
|
||||
parenthesises_number++;
|
||||
}
|
||||
if (s == ')') {
|
||||
parenthesises_number--;
|
||||
}
|
||||
if (s == '[') {
|
||||
brackets_number++;
|
||||
}
|
||||
if (s == ']') {
|
||||
brackets_number--;
|
||||
}
|
||||
if (brackets_number<0 || parenthesises_number < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return (brackets_number == 0 && parenthesises_number == 0);
|
||||
}
|
||||
|
||||
public static LSystemNode parseWord(string line, LSystemGeneralWordBuilder builder) {
|
||||
var read_characters = 0;
|
||||
LSystemNode node;
|
||||
if (line[0] == '[') {
|
||||
node = builder.createLSystemNode("", 0);
|
||||
}
|
||||
else {
|
||||
var literal_name = line.Substring(0, 1);
|
||||
if (line.Length>1 && line[1] == '(') {
|
||||
var length = countParenthesisEnd(line.Substring(1), '(', ')');
|
||||
var values_string = line.Substring(2, length).Split(',');
|
||||
node = builder.createLSystemNode(literal_name, values_string.Length);
|
||||
|
||||
builder.fillArguments(node, values_string);
|
||||
//Leter and: (, )
|
||||
read_characters += length + 3;
|
||||
|
||||
}
|
||||
else {
|
||||
read_characters += 1;
|
||||
node = builder.createLSystemNode(line.Substring(0,1),0);
|
||||
}
|
||||
}
|
||||
while (line.Length > read_characters && line[read_characters] == '[') {
|
||||
|
||||
var brackets_number = 1;
|
||||
var length = countParenthesisEnd(line.Substring(read_characters), '[', ']');
|
||||
var child_node = parseWord(line.Substring(read_characters + 1, length),builder);
|
||||
read_characters += length + 2;
|
||||
child_node.parent = node;
|
||||
node.children.Add(child_node);
|
||||
}
|
||||
if (read_characters < line.Length) {
|
||||
var child_node = parseWord(line.Substring(read_characters),builder);
|
||||
child_node.parent = node;
|
||||
node.mainChild = (child_node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public static LSystemNodeLiteralVariable parsePredecesor(string line) {
|
||||
var name = line.Substring(0, 1);
|
||||
var varable_index = new Dictionary<string, int>();
|
||||
if (line.Length > 1) {
|
||||
foreach (var i in line.Substring(2, line.Length - 3).Split(',').Select((name, Index) => new { name, Index })) {
|
||||
varable_index.Add(i.name, i.Index);
|
||||
};
|
||||
}
|
||||
return new LSystemNodeLiteralVariable(name, varable_index.Count, varable_index);
|
||||
}
|
||||
//private static String[] parseIgnore(string line) {
|
||||
// var items = line.Trim().Split(' ');
|
||||
// var resut = List
|
||||
|
||||
//}
|
||||
|
||||
public static LSystemEvaluator parseLSystem(StreamReader sr) {
|
||||
string line;
|
||||
int line_number = 0;
|
||||
var ignored = new String[0];
|
||||
LSystemNode axiom = null;
|
||||
List<LSystemRule> rules = null;
|
||||
while ((line = sr.ReadLine()) != null) {
|
||||
line_number++;
|
||||
if (line.Trim() == "#axiom") {
|
||||
line = sr.ReadLine();
|
||||
if (!parenthesisCheck(line)) {
|
||||
throw new Exception(String.Format("In line {0} invalid syntax", line_number));
|
||||
}
|
||||
axiom = parseWord(line,new LSystemWordBuilder());
|
||||
}
|
||||
if (line.Trim().Split(' ')[0].Trim() == "#ignore") {
|
||||
ignored = line.Trim().Split(' ').Where(x=> x!= "#ignore" && x.Length>0).Select(x => x.Trim()).ToArray();
|
||||
}
|
||||
if (line.Trim() == "#rules") {
|
||||
rules = parseLSystemRules(sr);
|
||||
}
|
||||
|
||||
}
|
||||
return new LSystemEvaluator(axiom, rules, ignored);
|
||||
}
|
||||
|
||||
private static List<LSystemRule> parseLSystemRules(StreamReader sr) {
|
||||
List<LSystemRule> rules = new List<LSystemRule>();
|
||||
Regex separator = new Regex(@"-(\d*\.?\d*){1}>");
|
||||
Regex weight_regex = new Regex(@"p=(\d+\.?\d*){1}");
|
||||
string line;
|
||||
while ((line = sr.ReadLine()) != null && line.Trim() != "#rules end") {
|
||||
try {
|
||||
if (line.Length == 0 || line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
MathExpressionComparison[] conditions = new MathExpressionComparison[0];
|
||||
var split = separator.Match(line);
|
||||
var line_parts = line.Split(new string[] { split.Value }, StringSplitOptions.None);
|
||||
// check conditions;
|
||||
//parse predecesor
|
||||
var _t = line_parts[0].Split(':');
|
||||
var predecesor_string = _t[0];
|
||||
LSystemNodeLiteralVariable predecesor;
|
||||
LSystemContext context;
|
||||
//check if contains < or >
|
||||
|
||||
// check context
|
||||
getPredecesorContext(predecesor_string, out predecesor, out context);
|
||||
|
||||
if (_t.Length > 1) {
|
||||
conditions = _t[1].Trim().Split(';').Select(text => MathExpressionComparasionParser.parse(predecesor.variableIndex, text.Trim())).ToArray();
|
||||
}
|
||||
// tochastic rule parsing
|
||||
var sucsessor_string = line_parts[1];
|
||||
var probabilities_list = new List<float>();
|
||||
var consequents_list = new List<LSystemNodeGenerator>();
|
||||
if (sucsessor_string.Trim() == "#stochastic") {
|
||||
while ((line = sr.ReadLine()) != null && line.Trim() != "#stochastic end") {
|
||||
if (line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
var weight_string = weight_regex.Match(line);
|
||||
var weight = float.Parse(weight_string.Value.Substring(2), NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
probabilities_list.Add(weight);
|
||||
|
||||
var prob_len = weight_string.Value.Length;
|
||||
consequents_list.Add((LSystemNodeGenerator)parseWord(line.Substring(prob_len).Trim(), new LSystemWordGeneratorBuilder(predecesor.variableIndex)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
consequents_list.Add((LSystemNodeGenerator)parseWord(sucsessor_string.Trim(), new LSystemWordGeneratorBuilder(predecesor.variableIndex)));
|
||||
}
|
||||
//context
|
||||
if (context != null) {
|
||||
if (consequents_list.Count > 1) {
|
||||
rules.Add(new LSystemRuleParametricStochasticContext(predecesor, conditions, consequents_list.ToArray(), probabilities_list.ToArray(), context));
|
||||
}
|
||||
else {
|
||||
rules.Add(new LSystemRuleParametricStochasticContext(predecesor, conditions, consequents_list[0], context));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (consequents_list.Count > 1) {
|
||||
rules.Add(new LSystemRuleParametricStochastic(predecesor, conditions, consequents_list.ToArray(), probabilities_list.ToArray()));
|
||||
}
|
||||
else {
|
||||
rules.Add(new LSystemRuleParametric(predecesor, conditions, consequents_list[0]));
|
||||
}
|
||||
}
|
||||
//var conditions = parts[0];
|
||||
//var result
|
||||
}
|
||||
catch (Exception e) {
|
||||
sr.Close();
|
||||
throw new Exception(String.Format("error in {0} with a message \n {1}", line,e.Message));
|
||||
}
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
|
||||
private static void getPredecesorContext(string predecesor_string, out LSystemNodeLiteralVariable predecesor, out LSystemContext context) {
|
||||
string partent_context_str = null;
|
||||
string child_context_str = null;
|
||||
string mid_context_str = null;
|
||||
int mid_start = 0;
|
||||
|
||||
for (int i = 0; i < predecesor_string.Length; i++) {
|
||||
if (predecesor_string[i] == '<' && partent_context_str == null) {
|
||||
partent_context_str = predecesor_string.Substring(0, i).Trim();
|
||||
mid_start = i+1;
|
||||
//Console.WriteLine(i);
|
||||
}
|
||||
if (predecesor_string[i] == '>' && child_context_str == null) {
|
||||
child_context_str = predecesor_string.Substring(i + 1).Trim();
|
||||
mid_context_str = predecesor_string.Substring(mid_start, i - mid_start).Trim();
|
||||
//Console.WriteLine(i);
|
||||
}
|
||||
|
||||
}
|
||||
if (mid_context_str == null) {
|
||||
mid_context_str = predecesor_string.Substring(mid_start).Trim();
|
||||
}
|
||||
LSystemNodeLiteralVariable parent = null;
|
||||
LSystemNodeLiteralVariable child = null;
|
||||
predecesor = LSystemFileParser.parsePredecesor(mid_context_str);
|
||||
if (partent_context_str != null) {
|
||||
parent = LSystemFileParser.parsePredecesor(partent_context_str);
|
||||
foreach (KeyValuePair<string, int> kvp in new Dictionary<string, int>(predecesor.variableIndex)) {
|
||||
//textBox3.Text += ("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
|
||||
predecesor.variableIndex[kvp.Key] = kvp.Value + parent.variableIndex.Count;
|
||||
}
|
||||
foreach (KeyValuePair<string, int> kvp in parent.variableIndex) {
|
||||
//textBox3.Text += ("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
|
||||
predecesor.variableIndex.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
if (child_context_str != null) {
|
||||
int size = predecesor.variableIndex.Count;
|
||||
child = LSystemFileParser.parsePredecesor(child_context_str);
|
||||
foreach (KeyValuePair<string, int> kvp in child.variableIndex) {
|
||||
//textBox3.Text += ("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
|
||||
predecesor.variableIndex.Add(kvp.Key, kvp.Value + size);
|
||||
}
|
||||
}
|
||||
if (child_context_str != null) {
|
||||
if (partent_context_str != null) {
|
||||
context = new LSystemContext(parent, child);
|
||||
}
|
||||
else {
|
||||
context = new LSystemContext();
|
||||
context.setOnlySucceeding(child);
|
||||
}
|
||||
}
|
||||
else if (partent_context_str != null) {
|
||||
context = new LSystemContext();
|
||||
context.setOnlyPreceding(parent);
|
||||
}
|
||||
else {
|
||||
context = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5d9ea0d39208315468053b0ae8bb3e95
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,313 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ConsoleLSystem {
|
||||
public class LSystemNodeLiteralVariable : LSystemNodeLiteral {
|
||||
public Dictionary<string, int> variableIndex { get; }
|
||||
|
||||
public LSystemNodeLiteralVariable(string name, int values_number, Dictionary<string, int> variableIndex) : base(name, values_number) {
|
||||
this.variableIndex = variableIndex;
|
||||
}
|
||||
|
||||
}
|
||||
public class LSystemNodeGenerator : LSystemNode {
|
||||
MathExpression[] math_expressions;
|
||||
|
||||
public LSystemNodeGenerator(string name, int arguments) : base(new LSystemNodeLiteral(name, arguments)) {
|
||||
}
|
||||
public void fillArguments(MathExpression[] math_expressions) {
|
||||
this.math_expressions = math_expressions;
|
||||
}
|
||||
public LSystemNode eval(float[] values) {
|
||||
var literal = new LSystemNodeLiteral(this.literal.name, this.literal.values_number);
|
||||
for (int i = 0; i < literal.values_number; i++) {
|
||||
literal.values[i] = math_expressions[i].eval(values);
|
||||
}
|
||||
var result = new LSystemNode(literal);
|
||||
foreach (LSystemNodeGenerator child in children) {
|
||||
var _child = child.eval(values);
|
||||
_child.parent = result;
|
||||
result.children.Add(_child);
|
||||
|
||||
}
|
||||
if (mainChild != null) {
|
||||
var _mainChild = ((LSystemNodeGenerator)mainChild).eval(values);
|
||||
_mainChild.parent = result;
|
||||
result.mainChild = _mainChild;
|
||||
}
|
||||
else {
|
||||
result.mainChild = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
abstract public class LSystemRule {
|
||||
abstract public bool is_aplicable(LSystemNode processed_node, String[] ignored);
|
||||
abstract public LSystemNode rewrite(LSystemNode processed_node, String[] ignored);
|
||||
}
|
||||
|
||||
public class LSystemRuleBasic : LSystemRule {
|
||||
LSystemNodeLiteral input;// { get; }
|
||||
LSystemNode output;
|
||||
|
||||
public LSystemRuleBasic(LSystemNodeLiteral input, LSystemNode output) {
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
override public bool is_aplicable(LSystemNode processed_node, String[] ignored) {
|
||||
if (processed_node.literal == input) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
override public LSystemNode rewrite(LSystemNode processed_node, String[] ignored) {
|
||||
if (is_aplicable(processed_node, ignored)) {
|
||||
return output.deep_copy();
|
||||
}
|
||||
else {
|
||||
return new LSystemNode(processed_node.literal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class LSystemRuleParametric : LSystemRule {
|
||||
LSystemNodeLiteralVariable predecesor;// { get; }
|
||||
LSystemNodeGenerator consequent;
|
||||
MathExpressionComparison[] conditions;
|
||||
|
||||
public LSystemRuleParametric(LSystemNodeLiteralVariable predecesor, MathExpressionComparison[] conditions, LSystemNodeGenerator consequent) {
|
||||
this.predecesor = predecesor;
|
||||
this.consequent = consequent;
|
||||
this.conditions = conditions;
|
||||
}
|
||||
|
||||
public override bool is_aplicable(LSystemNode processed_node, String[] ignored) {
|
||||
if (processed_node.literal.name != predecesor.name || processed_node.literal.values_number != predecesor.values_number) {
|
||||
return false;
|
||||
}
|
||||
foreach (var condition in conditions) {
|
||||
if (!condition.eval(processed_node.literal.values)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override LSystemNode rewrite(LSystemNode processed_node, String[] ignored) {
|
||||
if (is_aplicable(processed_node, ignored)) {
|
||||
return consequent.eval(processed_node.literal.values);
|
||||
}
|
||||
else {
|
||||
return new LSystemNode(processed_node.literal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class LSystemRuleParametricStochastic : LSystemRule {
|
||||
protected LSystemNodeLiteralVariable predecesor;// { get; }
|
||||
protected LSystemNodeGenerator[] consequents;
|
||||
protected float[] probabilities;
|
||||
protected MathExpressionComparison[] conditions;
|
||||
protected Random random;
|
||||
|
||||
public LSystemRuleParametricStochastic(LSystemNodeLiteralVariable predecesor, MathExpressionComparison[] conditions, LSystemNodeGenerator[] consequents, float[] probabilities) {
|
||||
this.predecesor = predecesor;
|
||||
this.consequents = consequents;
|
||||
this.conditions = conditions;
|
||||
float probabilities_sum = 0;
|
||||
foreach (var probability in probabilities) { probabilities_sum += probability; }
|
||||
float acumulator = 0;
|
||||
this.probabilities = new float[consequents.Length];
|
||||
for (int i = 0; i < consequents.Length; i++) {
|
||||
var probability = probabilities[i] / probabilities_sum;
|
||||
this.probabilities[i] = probability + acumulator;
|
||||
acumulator += probability;
|
||||
}
|
||||
random = new Random();
|
||||
|
||||
}
|
||||
public LSystemRuleParametricStochastic(LSystemNodeLiteralVariable predecesor, MathExpressionComparison[] conditions, LSystemNodeGenerator consequent) {
|
||||
this.predecesor = predecesor;
|
||||
this.consequents = new LSystemNodeGenerator[] { consequent };
|
||||
this.conditions = conditions;
|
||||
float probabilities_sum = 0;
|
||||
probabilities = new float[1] { 1 };
|
||||
random = new Random();
|
||||
|
||||
}
|
||||
public override bool is_aplicable(LSystemNode processed_node, String[] ignored) {
|
||||
if (processed_node.literal.name != predecesor.name || processed_node.literal.values_number != predecesor.values_number) {
|
||||
return false;
|
||||
}
|
||||
foreach (var condition in conditions) {
|
||||
if (!condition.eval(processed_node.literal.values)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override LSystemNode rewrite(LSystemNode processed_node, String[] ignored) {
|
||||
var result = random.NextDouble();
|
||||
int consequent_index = 0;
|
||||
for (int i = 0; i < probabilities.Length; i++) {
|
||||
if (result < probabilities[i]) {
|
||||
consequent_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_aplicable(processed_node, ignored)) {
|
||||
return consequents[consequent_index].eval(processed_node.literal.values);
|
||||
}
|
||||
else {
|
||||
return new LSystemNode(processed_node.literal);
|
||||
}
|
||||
}
|
||||
}
|
||||
public class LSystemContext {
|
||||
public LSystemNodeLiteral parent { get; set; }
|
||||
public LSystemNodeLiteral child { get; set; }
|
||||
public LSystemNodeLiteral mid { get; set; }
|
||||
bool isPreceding = false;
|
||||
bool isSucceeding = false;
|
||||
|
||||
public LSystemContext(LSystemNodeLiteral parent, LSystemNodeLiteral child) {
|
||||
this.parent = parent;
|
||||
this.child = child;
|
||||
this.isPreceding = true;
|
||||
this.isSucceeding = true;
|
||||
}
|
||||
public LSystemContext() {
|
||||
|
||||
}
|
||||
public void setOnlyPreceding(LSystemNodeLiteral parent) {
|
||||
this.parent = parent;
|
||||
this.mid = mid;
|
||||
this.isPreceding = true;
|
||||
this.isSucceeding = false;
|
||||
}
|
||||
public void setOnlySucceeding(LSystemNodeLiteral child) {
|
||||
this.child = child;
|
||||
this.isPreceding = false;
|
||||
this.isSucceeding = true;
|
||||
}
|
||||
public bool isAplicable(LSystemNode node, String[] ignored, out float[] variables) {
|
||||
var variables_list = new List<float>();
|
||||
var currentParent = node.parent;
|
||||
while (ignored.Contains(currentParent.literal.name)) {
|
||||
currentParent = currentParent.parent;
|
||||
}
|
||||
if (isPreceding && parent != currentParent.literal) {
|
||||
variables = new float[0];
|
||||
return false;
|
||||
}
|
||||
if (isPreceding) {
|
||||
variables_list.AddRange(currentParent.literal.values);
|
||||
}
|
||||
variables_list.AddRange(node.literal.values);
|
||||
if (isSucceeding) {
|
||||
var result = false;
|
||||
LSystemNodeLiteral childLiteral;
|
||||
Queue<LSystemNode> ignoredChildren = new Queue<LSystemNode>();
|
||||
foreach(var child in node.getAllChildren()) {
|
||||
if (ignored.Contains(child.literal.name)) {
|
||||
ignoredChildren.Enqueue(child);
|
||||
}
|
||||
if (child.literal == this.child) {
|
||||
childLiteral = child.literal;
|
||||
result = true;
|
||||
variables_list.AddRange(child.literal.values);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (!result && ignoredChildren.Count>0) {
|
||||
var ignoredChild = ignoredChildren.Dequeue();
|
||||
foreach (var child in ignoredChild.getAllChildren()) {
|
||||
if (ignored.Contains(child.literal.name)) {
|
||||
ignoredChildren.Enqueue(child);
|
||||
}
|
||||
if (child.literal == this.child) {
|
||||
childLiteral = child.literal;
|
||||
result = true;
|
||||
variables_list.AddRange(child.literal.values);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result) {
|
||||
variables = new float[0];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
variables = variables_list.ToArray();
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class LSystemRuleParametricStochasticContext : LSystemRuleParametricStochastic {
|
||||
LSystemContext context;
|
||||
public LSystemRuleParametricStochasticContext(LSystemNodeLiteralVariable predecesor, MathExpressionComparison[] conditions, LSystemNodeGenerator[] consequents, float[] probabilities, LSystemContext context) : base(predecesor, conditions, consequents, probabilities) {
|
||||
this.context = context;
|
||||
}
|
||||
public LSystemRuleParametricStochasticContext(LSystemNodeLiteralVariable predecesor, MathExpressionComparison[] conditions, LSystemNodeGenerator consequent, LSystemContext context) : base(predecesor, conditions, consequent) {
|
||||
this.context = context;
|
||||
}
|
||||
public override bool is_aplicable(LSystemNode processed_node,String[] ignored) {
|
||||
if (processed_node.literal.name != predecesor.name || processed_node.literal.values_number != predecesor.values_number) {
|
||||
return false;
|
||||
}
|
||||
var variables = new float[0];
|
||||
if (!context.isAplicable(processed_node, ignored, out variables)) {
|
||||
return false;
|
||||
}
|
||||
foreach (var condition in conditions) {
|
||||
if (!condition.eval(variables)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool is_aplicable(LSystemNode processed_node, String[] ignored, out float[] variables) {
|
||||
variables = new float[0];
|
||||
if (processed_node.literal.name != predecesor.name || processed_node.literal.values_number != predecesor.values_number) {
|
||||
return false;
|
||||
}
|
||||
if (!context.isAplicable(processed_node, ignored, out variables)) {
|
||||
return false;
|
||||
}
|
||||
foreach (var condition in conditions) {
|
||||
if (!condition.eval(variables)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override LSystemNode rewrite(LSystemNode processed_node, String[] ignored) {
|
||||
var result = random.NextDouble();
|
||||
int consequent_index = 0;
|
||||
for (int i = 0; i < probabilities.Length; i++) {
|
||||
if (result < probabilities[i]) {
|
||||
consequent_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
float[] variables;
|
||||
if (is_aplicable(processed_node, ignored, out variables)) {
|
||||
return consequents[consequent_index].eval(variables);
|
||||
}
|
||||
else {
|
||||
return new LSystemNode(processed_node.literal);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fbf81cc8f22e1b040aa2f1b218391989
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,210 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ConsoleLSystem {
|
||||
public class MathExpressionComparison{
|
||||
MathExpression leftSide;
|
||||
MathExpression rightSide;
|
||||
Func<float, float,bool> comparisonFunction;
|
||||
|
||||
public MathExpressionComparison(MathExpression leftSide, MathExpression rightSide, Func<float, float, bool> comparisonFunction) {
|
||||
this.leftSide = leftSide;
|
||||
this.rightSide = rightSide;
|
||||
this.comparisonFunction = comparisonFunction;
|
||||
}
|
||||
public bool eval(float[] variables) {
|
||||
return comparisonFunction(leftSide.eval(variables), rightSide.eval(variables));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public class MathExpressionNode {
|
||||
Func<float[], float[], float> function;
|
||||
MathExpressionNode[] childNodes;
|
||||
|
||||
public MathExpressionNode(Func<float[], float[], float> function, MathExpressionNode[] childNodes) {
|
||||
this.function = function;
|
||||
this.childNodes = childNodes;
|
||||
}
|
||||
|
||||
public float eval(float[] variables) {
|
||||
var x = childNodes.Select(node => node.eval(variables)).ToArray();
|
||||
return function(x, variables);
|
||||
}
|
||||
}
|
||||
public class MathExpression {
|
||||
private static Random random = new Random();
|
||||
|
||||
private static Dictionary<char, int> expression_hierarchy = new Dictionary<char, int>{
|
||||
{'^', 4},
|
||||
{'*', 3},
|
||||
{'/', 3},
|
||||
{'+', 1},
|
||||
{'-', 1},
|
||||
};
|
||||
MathExpressionNode rootNode;
|
||||
public float eval(float [] variables) {
|
||||
return rootNode.eval(variables);
|
||||
}
|
||||
private static float negate(float[] children, float[] variables) {
|
||||
return -children[0];
|
||||
}
|
||||
private static float mulitply(float[] children, float[] variables) {
|
||||
return children[0] * children[1];
|
||||
}
|
||||
private static float power(float[] children, float[] variables) {
|
||||
return (float)Math.Pow(children[0],children[1]);
|
||||
}
|
||||
private static float divide(float[] children, float[] variables) {
|
||||
return children[0] / children[1];
|
||||
}
|
||||
private static float add(float[] children, float[] variables) {
|
||||
return children[0] + children[1];
|
||||
}
|
||||
private static float subtract(float[] children, float[] variables) {
|
||||
return children[0] - children[1];
|
||||
}
|
||||
|
||||
//private MathExpressionNode parse(Dictionary<string, int> variableNames, string expression_string) {
|
||||
|
||||
|
||||
// var read_characters = 0;
|
||||
// var node = new MathExpressionNode();
|
||||
// if (expression_string[0] == '(') {
|
||||
// var length = LSystemFileParser.countParenthesisEnd(expression_string, '(', ')');
|
||||
// if (length == expression_string.Length - 2) {
|
||||
// return parse(variableNames, expression_string.Substring(1, length));
|
||||
// }
|
||||
|
||||
// var left_child_node = parse(variableNames, expression_string.Substring(1, length));
|
||||
// read_characters += length + 2;
|
||||
|
||||
// node.function = getFunction(expression_string[read_characters]);
|
||||
// read_characters += 1;
|
||||
|
||||
// if (expression_string[read_characters] == '(')
|
||||
// }
|
||||
|
||||
|
||||
|
||||
//}
|
||||
|
||||
private static MathExpressionNode parse(Dictionary<string, int> variableNames, string expression_string) {
|
||||
expression_string = expression_string.Trim();
|
||||
var expression_pos = -1;
|
||||
var current_level = 1000;
|
||||
for (int i = 0; i < expression_string.Length; i++) {
|
||||
if (expression_string[i] == '(') {
|
||||
var length = LSystemFileParser.countParenthesisEnd(expression_string.Substring(i), '(', ')');
|
||||
if (length == expression_string.Length - 2) {
|
||||
return parse(variableNames, expression_string.Substring(1, length));
|
||||
}
|
||||
//skip parenthesis
|
||||
// if expression is covered in ( )
|
||||
if (i == 0 && length == expression_string.Length - 2) {
|
||||
return parse(variableNames, expression_string.Substring(1, length));
|
||||
}
|
||||
else {
|
||||
i += length + 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
int new_level;
|
||||
if (expression_hierarchy.TryGetValue(expression_string[i],out new_level)) {
|
||||
if (i>0 && !(i - 1 == expression_pos && expression_string[i] == '-')) {
|
||||
if (new_level <= current_level) {
|
||||
current_level = new_level;
|
||||
expression_pos = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (expression_pos > 0) {
|
||||
var left_node = parse(variableNames, expression_string.Substring(0, expression_pos));
|
||||
var right_node = parse(variableNames, expression_string.Substring(expression_pos + 1));
|
||||
MathExpressionNode[] child_nodes = { left_node, right_node };
|
||||
switch (expression_string[expression_pos]) {
|
||||
case '*':
|
||||
return new MathExpressionNode(mulitply, child_nodes);
|
||||
break;
|
||||
case '/':
|
||||
return new MathExpressionNode(divide, child_nodes);
|
||||
break;
|
||||
case '+':
|
||||
return new MathExpressionNode(add, child_nodes);
|
||||
break;
|
||||
case '-':
|
||||
return new MathExpressionNode(subtract, child_nodes);
|
||||
break;
|
||||
case '^':
|
||||
return new MathExpressionNode(power, child_nodes);
|
||||
break;
|
||||
default:
|
||||
throw new Exception(String.Format("unknown operation {0} in {1}", expression_string[expression_pos], expression_string));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (expression_string[0] == '-') {
|
||||
MathExpressionNode[] a = { parse(variableNames, expression_string.Substring(1)) };
|
||||
return new MathExpressionNode(negate, a);
|
||||
}
|
||||
else {
|
||||
int index;
|
||||
if (expression_string == "RANDOM") {
|
||||
return new MathExpressionNode((float[] children, float[] arguments) => (float)random.NextDouble(), new MathExpressionNode[0]);
|
||||
}
|
||||
if (variableNames.TryGetValue(expression_string.Trim(),out index)){
|
||||
return new MathExpressionNode((float[] children, float[] arguments) => arguments[index], new MathExpressionNode[0]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
float value = float.Parse(expression_string, NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
return new MathExpressionNode((float[] children, float[] arguments) => value, new MathExpressionNode[0]);
|
||||
}
|
||||
catch (Exception) {
|
||||
|
||||
throw new Exception(String.Format("can't parse ``{0}``. It's not a number nor a known variable", expression_string));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public MathExpression(Dictionary<string,int> variableNames, string expression_string) {
|
||||
rootNode = parse(variableNames, expression_string);
|
||||
}
|
||||
}
|
||||
public class MathExpressionComparasionParser {
|
||||
private static bool le(float a, float b) { return a < b; }
|
||||
private static bool leq(float a, float b) { return a <= b; }
|
||||
private static bool eq(float a, float b) { return a == b; }
|
||||
|
||||
public static MathExpressionComparison parse(Dictionary<string, int> variableNames, string expression_string) {
|
||||
//var operations = new string[]{ "<=", ">=", "<", ">"};
|
||||
if (expression_string.Contains("<=")) {
|
||||
|
||||
var parts = expression_string.Split(new string[] { "<=" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray();
|
||||
return new MathExpressionComparison(new MathExpression(variableNames, parts[0]), new MathExpression(variableNames, parts[1]), leq);
|
||||
}
|
||||
if (expression_string.Contains(">=")) {
|
||||
var parts = expression_string.Split(new string[] { ">=" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray();
|
||||
return new MathExpressionComparison(new MathExpression(variableNames, parts[1]), new MathExpression(variableNames, parts[0]), leq);
|
||||
}
|
||||
if (expression_string.Contains("==")) {
|
||||
var parts = expression_string.Split(new string[] { "==" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray();
|
||||
return new MathExpressionComparison(new MathExpression(variableNames, parts[1]), new MathExpression(variableNames, parts[0]), eq);
|
||||
}
|
||||
if (expression_string.Contains("<")) {
|
||||
var parts = expression_string.Split('<').Select(s => s.Trim()).ToArray();
|
||||
return new MathExpressionComparison(new MathExpression(variableNames, parts[0]), new MathExpression(variableNames, parts[1]), le);
|
||||
}
|
||||
if (expression_string.Contains(">")) {
|
||||
var parts = expression_string.Split('>').Select(s => s.Trim()).ToArray();
|
||||
return new MathExpressionComparison(new MathExpression(variableNames, parts[1]), new MathExpression(variableNames, parts[0]), le);
|
||||
}
|
||||
|
||||
throw new Exception(String.Format("comparison operation not recognized in {}", expression_string));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9f4cd6c897dbc5741b23eee6d073826c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,353 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ConsoleLSystem {
|
||||
public class LSystemNodeLiteral {
|
||||
public string name { get; }
|
||||
public int values_number { get; }
|
||||
|
||||
public float[] values { get; set; }
|
||||
|
||||
public LSystemNodeLiteral(string name, int values_number) {
|
||||
this.name = name;
|
||||
this.values_number = values_number;
|
||||
//in case it would be 0
|
||||
values = new float[values_number];
|
||||
}
|
||||
public LSystemNodeLiteral(LSystemNodeLiteral other) {
|
||||
this.name = other.name;
|
||||
this.values_number = other.values_number;
|
||||
//in case it would be 0
|
||||
values = new float[this.values_number];
|
||||
other.values.CopyTo(values, 0);
|
||||
}
|
||||
|
||||
public static bool operator ==(LSystemNodeLiteral thisLiteral, LSystemNodeLiteral other) {
|
||||
return thisLiteral.name == other.name && thisLiteral.values_number == other.values_number;
|
||||
}
|
||||
public static bool operator !=(LSystemNodeLiteral thisLiteral, LSystemNodeLiteral other) {
|
||||
return !(thisLiteral.name == other.name && thisLiteral.values_number == other.values_number);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
if (values_number == 0) {
|
||||
return name;
|
||||
}
|
||||
else {
|
||||
StringBuilder sb = new StringBuilder(name, name.Length + values_number * 7 + 4);
|
||||
sb.Append("(");
|
||||
for (int i = 0; i < values_number; i++) {
|
||||
var v = values[i];
|
||||
sb.AppendFormat("{0:0.##}", v);
|
||||
if (i < values_number - 1) {
|
||||
sb.Append(",");
|
||||
}
|
||||
}
|
||||
sb.Append(")");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class LSystemNode {
|
||||
public LSystemNodeLiteral literal { get; set; }
|
||||
public List<LSystemNode> children { get; set; }
|
||||
public LSystemNode mainChild { get; set; }
|
||||
|
||||
private LSystemNode _parent;
|
||||
public LSystemNode parent {
|
||||
get { if (_parent is null) { return new LSystemNode(new LSystemNodeLiteral(" _ ", 0)); }
|
||||
else { return _parent; } }
|
||||
set { _parent = value; } }
|
||||
|
||||
public LSystemNode(LSystemNodeLiteral nodeLiteral) {
|
||||
literal = nodeLiteral;
|
||||
children = new List<LSystemNode>();
|
||||
mainChild = null;
|
||||
}
|
||||
|
||||
public LSystemNode(LSystemNodeLiteral nodeLiteral, List<LSystemNode> children, LSystemNode mainChild) {
|
||||
literal = nodeLiteral;
|
||||
this.children = children;
|
||||
this.mainChild = mainChild;
|
||||
}
|
||||
public LSystemNode(LSystemNodeLiteral nodeLiteral, List<LSystemNode> children) {
|
||||
literal = nodeLiteral;
|
||||
this.children = children;
|
||||
this.mainChild = null;
|
||||
}
|
||||
public List<LSystemNode> getAllChildren() {
|
||||
var result = new List<LSystemNode>(children);
|
||||
if (mainChild != null){
|
||||
result.Add(mainChild);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public LSystemNode deep_copy() {
|
||||
if (children.Count() == 0 && mainChild == null) {
|
||||
return new LSystemNode(new LSystemNodeLiteral(literal));
|
||||
}
|
||||
else if (mainChild != null) {
|
||||
var result = new LSystemNode(new LSystemNodeLiteral(literal));
|
||||
result.mainChild = mainChild.deep_copy();
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
var new_children = new List<LSystemNode>();
|
||||
foreach (var x in children) {
|
||||
new_children.Add(x.deep_copy());
|
||||
}
|
||||
return new LSystemNode(literal, new_children, this.mainChild.deep_copy());
|
||||
}
|
||||
}
|
||||
|
||||
private static LSystemNode deepestNode(LSystemNode node) {
|
||||
while (node.mainChild != null) {
|
||||
node = node.mainChild;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public LSystemNode newParent() {
|
||||
return deepestNode(this);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
StringBuilder sb = new StringBuilder(literal.ToString());
|
||||
var node = this;
|
||||
while (true) {
|
||||
foreach (var child in node.children) {
|
||||
sb.Append("[");
|
||||
sb.Append(child.ToString());
|
||||
sb.Append("]");
|
||||
}
|
||||
if (node.mainChild != null) {
|
||||
sb.Append(node.mainChild.literal.ToString());
|
||||
node = node.mainChild;
|
||||
}
|
||||
else {
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class LSystemEvaluator {
|
||||
public LSystemNode lSystemString { get; set; }
|
||||
public List<LSystemRule> lSystemRules { get; set; }
|
||||
public String[] ignored { get; set; }
|
||||
|
||||
public LSystemEvaluator(LSystemNode startingString, List<LSystemRule> rules) {
|
||||
lSystemString = startingString;
|
||||
lSystemRules = rules;
|
||||
ignored = new String[0];
|
||||
}
|
||||
public LSystemEvaluator(LSystemNode startingString, List<LSystemRule> rules, String[] ignored) {
|
||||
lSystemString = startingString;
|
||||
lSystemRules = rules;
|
||||
this.ignored = ignored;
|
||||
}
|
||||
private LSystemNode _rewrite(LSystemNode node) {
|
||||
foreach (var rule in lSystemRules) {
|
||||
if (rule.is_aplicable(node, ignored)) {
|
||||
return rule.rewrite(node, ignored);
|
||||
}
|
||||
}
|
||||
return new LSystemNode(node.literal);
|
||||
}
|
||||
//private void _rewrite_recursive(LSystemNode node, LSystemNode parent) {
|
||||
// var new_node = _rewrite(node);
|
||||
// parent.children.Add(new_node);
|
||||
// new_node.parent = parent;
|
||||
// var new_parent = new_node.newParent();
|
||||
|
||||
// foreach (var child in node.children) {
|
||||
// _rewrite_recursive(child, new_parent);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
private void _rewrite_recursive(LSystemNode node, LSystemNode parent) {
|
||||
var new_node = _rewrite(node);
|
||||
parent.children.Add(new_node);
|
||||
new_node.parent = parent;
|
||||
var new_parent = new_node.newParent();
|
||||
|
||||
foreach (var child in node.children) {
|
||||
_rewrite_recursive(child, new_parent);
|
||||
}
|
||||
while (node.mainChild != null) {
|
||||
new_node = _rewrite(node.mainChild);
|
||||
new_node.parent = new_parent;
|
||||
|
||||
new_parent.mainChild = new_node;
|
||||
new_parent = new_node.newParent();
|
||||
foreach (var child in node.mainChild.children) {
|
||||
_rewrite_recursive(child, new_parent);
|
||||
}
|
||||
node = node.mainChild;
|
||||
}
|
||||
}
|
||||
public void rewrite() {
|
||||
var new_root = _rewrite(lSystemString);
|
||||
var new_parent = new_root.newParent();
|
||||
foreach (var child in lSystemString.children) {
|
||||
_rewrite_recursive(child, new_parent);
|
||||
}
|
||||
var node = lSystemString;
|
||||
|
||||
while (node.mainChild != null) {
|
||||
var new_node = _rewrite(node.mainChild);
|
||||
new_node.parent = new_parent;
|
||||
|
||||
new_parent.mainChild = new_node;
|
||||
new_parent = new_node.newParent();
|
||||
foreach (var child in node.mainChild.children) {
|
||||
_rewrite_recursive(child, new_parent);
|
||||
}
|
||||
node = node.mainChild;
|
||||
}
|
||||
lSystemString = new_root;
|
||||
}
|
||||
//private void rewrite(ref LSystemNode currentNode)
|
||||
}
|
||||
//abstract class LSystemWordParser { }
|
||||
//abstract class LSystemRulesParser { }
|
||||
|
||||
class A {
|
||||
public int B { get; set; }
|
||||
public A[] AA { get; set; }
|
||||
}
|
||||
class Program {
|
||||
static void runParametric() {
|
||||
|
||||
Dictionary<string, int> variableIndex = new Dictionary<string, int> {
|
||||
{"a", 0},
|
||||
{"b", 1},
|
||||
|
||||
};
|
||||
var predecesor1 = LSystemFileParser.parsePredecesor("B(a,b)");
|
||||
var predecesor2 = LSystemFileParser.parsePredecesor("A(a)");
|
||||
var condition1 = MathExpressionComparasionParser.parse(variableIndex, "a>b");
|
||||
var condition2 = MathExpressionComparasionParser.parse(variableIndex, "a>5");
|
||||
|
||||
var builder = new LSystemWordGeneratorBuilder(variableIndex);
|
||||
|
||||
var consequent1 = (LSystemNodeGenerator)LSystemFileParser.parseWord("B(0,b)[A(a/2)]A(a/2)", builder);
|
||||
var consequent2 = (LSystemNodeGenerator)LSystemFileParser.parseWord("B(a+3.5,b+1)", builder);
|
||||
var consequent3 = (LSystemNodeGenerator)LSystemFileParser.parseWord("B(0,a)", builder);
|
||||
var consequent4 = (LSystemNodeGenerator)LSystemFileParser.parseWord("A(a+1)", builder);
|
||||
|
||||
var rule1 = new LSystemRuleParametric(predecesor1, new MathExpressionComparison[] { condition1 }, consequent1 );
|
||||
var rule2 = new LSystemRuleParametric(predecesor1, new MathExpressionComparison[] { }, consequent2 );
|
||||
var rule3 = new LSystemRuleParametric(predecesor2, new MathExpressionComparison[] { condition2 }, consequent3 );
|
||||
var rule4 = new LSystemRuleParametric(predecesor2, new MathExpressionComparison[] { }, consequent4);
|
||||
|
||||
var axiom = LSystemFileParser.parseWord("A(6)", new LSystemWordBuilder());
|
||||
|
||||
var rules = new List<LSystemRule> { rule1, rule2, rule3, rule4 };
|
||||
var evaluator = new LSystemEvaluator(axiom, rules);
|
||||
Console.WriteLine(evaluator.lSystemString.ToString());
|
||||
for (int i = 0; i < 20; i++) {
|
||||
evaluator.rewrite();
|
||||
Console.WriteLine(evaluator.lSystemString.ToString());
|
||||
}
|
||||
}
|
||||
static void runContext() {
|
||||
var axiom = LSystemFileParser.parseWord("A(1)A(1)A(1)A(1)A(1)A(1)B(2)", new LSystemWordBuilder());
|
||||
var predecesor = LSystemFileParser.parsePredecesor("A(a)");
|
||||
var predecesor1 = LSystemFileParser.parsePredecesor("B(b)");
|
||||
|
||||
var contex = new LSystemContext();
|
||||
contex.setOnlySucceeding(new LSystemNodeLiteral("B", 1));
|
||||
|
||||
var contex1 = new LSystemContext();
|
||||
contex1.setOnlyPreceding(new LSystemNodeLiteral("A", 1));
|
||||
|
||||
|
||||
Dictionary<string, int> variableIndex = new Dictionary<string, int> {
|
||||
{ "a", 0 },
|
||||
{ "b", 1 },
|
||||
};
|
||||
var builder = new LSystemWordGeneratorBuilder(variableIndex);
|
||||
var consequent = (LSystemNodeGenerator)LSystemFileParser.parseWord("B(a)", builder);
|
||||
var consequent1 = (LSystemNodeGenerator)LSystemFileParser.parseWord("A(1)", builder);
|
||||
var consequent2 = (LSystemNodeGenerator)LSystemFileParser.parseWord("A(a+1)", builder);
|
||||
|
||||
MathExpressionComparison comparison = MathExpressionComparasionParser.parse(variableIndex, "a>b");
|
||||
MathExpressionComparison comparison1 = MathExpressionComparasionParser.parse(variableIndex, "a<=b");
|
||||
|
||||
var rule = new LSystemRuleParametricStochasticContext(predecesor, new MathExpressionComparison[] { comparison }, consequent, contex);
|
||||
var rule1 = new LSystemRuleParametricStochasticContext(predecesor, new MathExpressionComparison[] { }, consequent2, contex);
|
||||
var rule2 = new LSystemRuleParametricStochasticContext(predecesor1, new MathExpressionComparison[] { comparison }, consequent1, contex1);
|
||||
|
||||
|
||||
var rules = new List<LSystemRule> { rule, rule1, rule2 };
|
||||
var evaluator = new LSystemEvaluator(axiom, rules);
|
||||
Console.WriteLine(evaluator.lSystemString.ToString());
|
||||
for (int i = 0; i < 20; i++) {
|
||||
evaluator.rewrite();
|
||||
Console.WriteLine(evaluator.lSystemString.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
static void runFile() {
|
||||
Console.WriteLine("Enter filepath:");
|
||||
string filepath = Console.ReadLine();
|
||||
var evaluator = LSystemFileParser.parseLSystem(new StreamReader(filepath));
|
||||
Console.WriteLine(evaluator.lSystemString.ToString());
|
||||
while (true) {
|
||||
Console.ReadLine();
|
||||
evaluator.rewrite();
|
||||
Console.WriteLine(evaluator.lSystemString.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
static void Main(string[] args) {
|
||||
runFile();
|
||||
//runContext();
|
||||
//var Al = new LSystemNodeLiteral("Al", 0);
|
||||
//var Ar = new LSystemNodeLiteral("Ar", 0);
|
||||
//var Bl = new LSystemNodeLiteral("Bl", 0);
|
||||
//var Br = new LSystemNodeLiteral("Br", 0);
|
||||
|
||||
//var root = new LSystemNode(Ar);
|
||||
//var rule_list = new List<LSystemRule>();
|
||||
|
||||
//var result = new LSystemNode(Al);
|
||||
//result.children.Add(new LSystemNode(Br));
|
||||
|
||||
//rule_list.Add(new LSystemRuleBasic(Ar, result));
|
||||
|
||||
//result = new LSystemNode(Bl);
|
||||
//result.children.Add(new LSystemNode(Ar));
|
||||
//rule_list.Add(new LSystemRuleBasic(Al, result));
|
||||
|
||||
//result = new LSystemNode(Ar);
|
||||
//rule_list.Add(new LSystemRuleBasic(Br, result));
|
||||
|
||||
//result = new LSystemNode(Al);
|
||||
//rule_list.Add(new LSystemRuleBasic(Bl, result));
|
||||
|
||||
|
||||
//var evaluator = new LSystemEvaluator(root, rule_list);
|
||||
//for (int i=0; i < 5; i++) {
|
||||
// Console.WriteLine(evaluator.lSystemString.ToString());
|
||||
// evaluator.rewrite();
|
||||
//}
|
||||
//Console.WriteLine(evaluator.lSystemString.ToString());
|
||||
|
||||
|
||||
|
||||
|
||||
//var node = LSystemFileParser.parseWord("A[AA][A]AB(1,2)[A(1)]C", new LSystemWordBuilder());
|
||||
//Console.WriteLine(node.ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5526e59b834cf36449875f1fb1ee497f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f5cb7c8fa9b906b45877c23773714b31
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,36 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
public static class MatrixExtensions {
|
||||
public static Quaternion ExtractRotation(this Matrix4x4 matrix) {
|
||||
Vector3 forward;
|
||||
forward.x = matrix.m02;
|
||||
forward.y = matrix.m12;
|
||||
forward.z = matrix.m22;
|
||||
|
||||
Vector3 upwards;
|
||||
upwards.x = matrix.m01;
|
||||
upwards.y = matrix.m11;
|
||||
upwards.z = matrix.m21;
|
||||
|
||||
return Quaternion.LookRotation(forward, upwards);
|
||||
}
|
||||
|
||||
public static Vector3 ExtractPosition(this Matrix4x4 matrix) {
|
||||
Vector3 position;
|
||||
position.x = matrix.m03;
|
||||
position.y = matrix.m13;
|
||||
position.z = matrix.m23;
|
||||
return position;
|
||||
}
|
||||
|
||||
public static Vector3 ExtractScale(this Matrix4x4 matrix) {
|
||||
Vector3 scale;
|
||||
scale.x = new Vector4(matrix.m00, matrix.m10, matrix.m20, matrix.m30).magnitude;
|
||||
scale.y = new Vector4(matrix.m01, matrix.m11, matrix.m21, matrix.m31).magnitude;
|
||||
scale.z = new Vector4(matrix.m02, matrix.m12, matrix.m22, matrix.m32).magnitude;
|
||||
return scale;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6dbfc235df030184f8ddf6b894d9d3ec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,33 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using ConsoleLSystem;
|
||||
using System;
|
||||
|
||||
public class Turtle3D : TurtleLSystem {
|
||||
public GameObject obj;
|
||||
public GameObject flower;
|
||||
public GameObject leaf;
|
||||
public float angle;
|
||||
|
||||
protected override void initLiteralInterpretation() {
|
||||
turtleInterpretation = new Dictionary<string, Func<float[], Tuple<GameObject, Matrix4x4>>>();
|
||||
//turtleInterpretation
|
||||
var transformation = Matrix4x4.Translate(new Vector3(0.0f, 0.1f, 0)) * Matrix4x4.Scale(new Vector3 (0.05f, 0.1f, 0.05f));
|
||||
|
||||
turtleInterpretation.Add("+", (float[] args) => new Tuple<GameObject, Matrix4x4>(null, Matrix4x4.Rotate(Quaternion.Euler(0, 0, -angle))));
|
||||
turtleInterpretation.Add("-", (float[] args) => new Tuple<GameObject, Matrix4x4>(null, Matrix4x4.Rotate(Quaternion.Euler(0, 0, angle))));
|
||||
turtleInterpretation.Add("/", (float[] args) => new Tuple<GameObject, Matrix4x4>(null, Matrix4x4.Rotate(Quaternion.Euler(0, angle, 0))));
|
||||
turtleInterpretation.Add("\\", (float[] args) => new Tuple<GameObject, Matrix4x4>(null, Matrix4x4.Rotate(Quaternion.Euler(0, -angle, 0))));
|
||||
turtleInterpretation.Add("&", (float[] args) => new Tuple<GameObject, Matrix4x4>(null, Matrix4x4.Rotate(Quaternion.Euler(angle, 0, 0))));
|
||||
turtleInterpretation.Add("^", (float[] args) => new Tuple<GameObject, Matrix4x4>(null, Matrix4x4.Rotate(Quaternion.Euler(-angle, 0, 0))));
|
||||
turtleInterpretation.Add("F", (float[] args) => new Tuple<GameObject, Matrix4x4>(flower, Matrix4x4.Rotate(Quaternion.Euler(0, 0, 0))));
|
||||
turtleInterpretation.Add("L", (float[] args) => new Tuple<GameObject, Matrix4x4>(leaf, Matrix4x4.Rotate(Quaternion.Euler(0, 0, 0))));
|
||||
|
||||
//Wildcard how to represent any other symbol
|
||||
turtleInterpretation.Add("*.*", (float[] args) => new Tuple<GameObject, Matrix4x4>(obj, transformation));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fdbab7936197e9c4e9c5225e40810916
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,162 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using ConsoleLSystem;
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
abstract public class TurtleLSystem : MonoBehaviour
|
||||
{
|
||||
public string LSystemPath;
|
||||
|
||||
public uint steps;
|
||||
|
||||
public Dictionary<string, Func<float[], Tuple<GameObject, Matrix4x4>>> turtleInterpretation = new Dictionary<string, Func<float[], Tuple<GameObject, Matrix4x4>>>();
|
||||
|
||||
private List<GameObject> gameObjects = new List<GameObject>();
|
||||
|
||||
private Mesh getCylinder(int quality,float width,float length) {
|
||||
Mesh mesh = new Mesh();
|
||||
//mesh.triangles
|
||||
var points = new List<Vector3>();
|
||||
var normals = new List<Vector3>();
|
||||
var indices = new List<int>();
|
||||
for (float i = 0; i < quality; i++) {
|
||||
points.Add(new Vector3(Mathf.Cos((i / quality) * 2 * Mathf.PI) * width, 0, Mathf.Sin((i / quality) * 2 * Mathf.PI) * width));
|
||||
}
|
||||
for (float i = 0; i < quality; i++) {
|
||||
points.Add(new Vector3(Mathf.Cos((i / quality) * 2 * Mathf.PI) * width, length, Mathf.Sin((i / quality) * 2 * Mathf.PI) * width));
|
||||
}
|
||||
//points.Add(new Vector3(0,0,0));
|
||||
//points.Add(new Vector3(0, length, 0));
|
||||
|
||||
for (float i = 0; i < quality; i++) {
|
||||
normals.Add(new Vector3(Mathf.Cos((i / quality) * 2 * Mathf.PI) * width, 0, Mathf.Sin((i / quality) * 2 * Mathf.PI) * width));
|
||||
}
|
||||
for (float i = 0; i < quality; i++) {
|
||||
normals.Add(new Vector3(Mathf.Cos((i / quality) * 2 * Mathf.PI) * width, 0, Mathf.Sin((i / quality) * 2 * Mathf.PI) * width));
|
||||
}
|
||||
|
||||
//for (int i = 0; i < quality; i++) {
|
||||
// indices.Add(i);
|
||||
// indices.Add((i + 1) % quality);
|
||||
// indices.Add(quality * 2);
|
||||
//}
|
||||
//for (int i = 0; i < quality; i++) {
|
||||
// indices.Add((i + 1) % quality + quality);
|
||||
// indices.Add(i + quality);
|
||||
// indices.Add(quality * 2 + 1);
|
||||
//}
|
||||
for (int i = 0; i < quality; i++) {
|
||||
indices.Add((i + 1) % quality);
|
||||
indices.Add(i);
|
||||
indices.Add(i + quality);
|
||||
|
||||
indices.Add(i + quality);
|
||||
indices.Add((i + 1) % quality + quality);
|
||||
indices.Add((i + 1) % quality);
|
||||
}
|
||||
mesh.vertices = points.ToArray();
|
||||
mesh.triangles = indices.ToArray();
|
||||
mesh.normals = normals.ToArray();
|
||||
return mesh;
|
||||
}
|
||||
|
||||
private LSystemEvaluator evaluator = null;
|
||||
|
||||
private void parseRules(StreamReader sr) {
|
||||
|
||||
}
|
||||
public void evaluate() {
|
||||
for (int i=0; i < steps; i++) {
|
||||
evaluator.rewrite();
|
||||
}
|
||||
Debug.Log(evaluator.lSystemString.ToString());
|
||||
}
|
||||
private GameObject prepeareGameObject(string name, GameObject gameObject,Matrix4x4 transformation) {
|
||||
GameObject instance;
|
||||
if (PrefabUtility.GetPrefabAssetType(gameObject) != PrefabAssetType.NotAPrefab) {
|
||||
instance = Instantiate(gameObject);
|
||||
}
|
||||
else {
|
||||
instance = gameObject;
|
||||
}
|
||||
|
||||
instance.name = String.Format("LSystem Literal {0}", name);
|
||||
instance.tag = "LSystemLiteral";
|
||||
instance.transform.parent = this.gameObject.transform;
|
||||
instance.transform.position = transformation.ExtractPosition() + transformation.MultiplyPoint(instance.transform.position);
|
||||
instance.transform.rotation *= transformation.ExtractRotation();
|
||||
instance.transform.localScale = Vector3.Scale(transformation.ExtractScale(), instance.transform.localScale);
|
||||
return instance;
|
||||
|
||||
}
|
||||
void createModelsRecursive(LSystemNode node, Matrix4x4 transformation) {
|
||||
while (node != null) {
|
||||
Matrix4x4 new_transformation=transformation;
|
||||
Func<float[], Tuple<GameObject, Matrix4x4>> interpretation;
|
||||
var name = node.literal.name;
|
||||
if (turtleInterpretation.TryGetValue(name, out interpretation) || turtleInterpretation.TryGetValue("*.*", out interpretation)) {
|
||||
var result = interpretation(node.literal.values);
|
||||
new_transformation = new_transformation * result.Item2;
|
||||
if (result.Item1 != null) {
|
||||
var instance = prepeareGameObject(name, result.Item1, new_transformation);
|
||||
}
|
||||
//gameObjects.Add(gameObject);
|
||||
//remove scale, rather unnecesary
|
||||
new_transformation = new_transformation * Matrix4x4.Scale(result.Item2.ExtractScale()).inverse;
|
||||
}
|
||||
foreach (var child in node.children) {
|
||||
createModelsRecursive(child, new_transformation);
|
||||
}
|
||||
node = node.mainChild;
|
||||
transformation = new_transformation;
|
||||
}
|
||||
}
|
||||
private void clearObjects() {
|
||||
//var objects = Resources.FindObjectsOfTypeAll<GameObject>().Where(obj => obj.name == "Name");
|
||||
foreach (GameObject gameObject in GameObject.FindGameObjectsWithTag("LSystemLiteral")) {
|
||||
DestroyImmediate(gameObject);
|
||||
|
||||
}
|
||||
gameObjects = new List<GameObject>();
|
||||
}
|
||||
|
||||
public void present() {
|
||||
clearObjects();
|
||||
createModelsRecursive(evaluator.lSystemString, Matrix4x4.identity);
|
||||
}
|
||||
abstract protected void initLiteralInterpretation();
|
||||
public void loadFile() {
|
||||
clearObjects();
|
||||
var sr = new StreamReader(LSystemPath);
|
||||
evaluator = LSystemFileParser.parseLSystem(sr);
|
||||
sr.Close();
|
||||
turtleInterpretation = new Dictionary<string, Func<float[], Tuple<GameObject, Matrix4x4>>>();
|
||||
initLiteralInterpretation();
|
||||
}
|
||||
public void evaluateAndPresent() {
|
||||
evaluate();
|
||||
present();
|
||||
Debug.Log(evaluator.lSystemString.ToString().Length);
|
||||
//x.name = "aaa";
|
||||
|
||||
//Instantiate(x,Matrix4x4.identity);
|
||||
}
|
||||
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e9f830130a88dbd40a2663c6a1dc301a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue