/// <summary> /// Initialize this AnimationInstance /// </summary> /// <param name="m"></param> public void InitializeInstance(MeshInstancer m, int skeletonID = 0, int bone_type = 0, float radius = 1.0f, int property_id = 0) { if (this.m != null) { throw new System.Exception("Error, this AnimationInstacne was already initialized."); } if (!m.Initialized()) { throw new System.Exception("Error, mesh instancer must be initialized!"); } if (bone_type > ushort.MaxValue || bone_type < 0 || skeletonID < 0 || property_id <= 0) { throw new System.Exception("Error, invalid input in AnimationInstance Input"); } m.InitializeSet(data); this.m = m; var animation = Controller.animations[0]; for (int i = 0; i < Controller.BoneCount; i++) { if (!animation.boneAnimations[i].IsInitialize) { throw new System.Exception("Error, bone animation not initialized."); } data[i].BoneIndex = i; data[i].BoneType = (ushort)bone_type; data[i].BoneLOD = this.Controller.BoneLODLevels[i]; // set to animate at all LOD by default data[i].IsBone = true; data[i].skeletonID = skeletonID; data[i].radius = radius; data[i].propertyID = property_id; // use the supplied propertyID to get a property with all the animation data (ie animation clip, anim speed, time, etc..) } }
void Start() { this.instances = new GPUMesh[this.N]; this.paths = new Path[this.N]; // Initialize GPU Instancer this.m = new MeshInstancer(); this.m.Initialize(pathCount: 4); this.p = new PathArrayHelper(this.m); // Add all mesh types to GPU Instancer foreach (var a in this.asteroids) { this.m.AddGPUMeshType(a); } // Do stuff for (int i = 0; i < N; i++) { var mesh = asteroids[Random.Range(0, asteroids.Count)].MeshTypes[0]; instances[i] = new GPUMesh(mesh, this.m); var size = Random.Range(1f, ScaleRange); instances[i].mesh.scale = Vector3.one * size; instances[i].SetRadius(4f * size); // set large enough radius so model doesnt get culled to early instances[i].Initialize(); var path = GetNewPath(); // create new path instances[i].mesh.SetPath(path, this.m); // assign path to instance paths[i] = path; instances[i].Update(); } }
// Use this for initialization private void Start() { InstanceMeshDeltaBuffer <instancemesh.instance_delta> .InstanceMeshIndirectIDBuffer.test(); InstanceHierarchyMap.test(); imesher = new MeshInstancer(); //initialize imesher.Initialize(); imesher.FrustumCamera = frustum_culling ? GameObject.Find("Main Camera").GetComponent <Camera>() : null; parent = new InstanceData(imesher.Default); parent.props_color32 = Color.red; child1 = new InstanceData(imesher.Default); child1.props_color32 = Color.green; child2 = new InstanceData(imesher.Default); child2.props_color32 = Color.blue; imesher.Initialize(ref parent); imesher.Initialize(ref child1); imesher.Initialize(ref child2); parent.parentID = instancemesh.NULL_ID; child1.parentID = parent.id; child2.parentID = child1.id; child1.position = new Vector3(2, 2, 2); child2.position = new Vector3(2, 2, 2); imesher.Append(ref parent); imesher.Append(ref child1); imesher.Append(ref child2); imesher.Update(0); }
public bool Update(List <Transform> points, PathArrayHelper p, MeshInstancer m, bool force_update = false) { if (points.Count != this._cached_path.Length) { throw new System.Exception("Error, please dont change the path length. Make a new path instead."); } bool dirty = this._cached_path.loop != this.loop || this._cached_path.PathCompletionTime != this.completion_time || this._cached_path.avg_path != this.do_avg || this._cached_path.AvgWeight != this.avg_weight || this._cached_path.smoothing != this.smoothing || this._cached_path.use_constants != this.use_constants || this._cached_path.yaw_only != this.yaw_only; this._cached_path.loop = this.loop; this._cached_path.avg_path = this.do_avg; this._cached_path.smoothing = this.smoothing; this._cached_path.AvgWeight = this.avg_weight; this._cached_path.PathCompletionTime = this.completion_time; this._cached_path.yaw_only = this.yaw_only; this._cached_path.SetUseConstants(this.use_constants, m); if (dirty || force_update) { var start_index = p.StartIndexOfPath(this._cached_path); // get index of path in paths array for (int i = 0; i < points.Count; i++) // set the path points for instances to follow { p.path[start_index + i] = points[i].position; } p.AutoCalcPathUpAndT(this._cached_path, this.path_up_rotation_modifier); // recalc up and T } return(dirty || force_update); }
// Start is called before the first frame update void Start() { List <TextureUVAnimation> anims = new List <TextureUVAnimation>(); anims.Add(MakeGPUTextureAnim(this.RunBack)); anims.Add(MakeGPUTextureAnim(this.RunForward)); anims.Add(MakeGPUTextureAnim(this.RunLeft)); anims.Add(MakeGPUTextureAnim(this.RunRight)); var tlib = new TextureAnimationLibrary(anims); // make texture animation library object.. This will just combine all the above lists into a single buffer this.m = new MeshInstancer(); // create & initialize mesh instancer this.m.Initialize(override_mesh: BaseMeshLibrary.CreatePlane2Sides(), override_material: this.material, pathCount: 4); // override default cube with a two-sided plane that uses uv cutout shader this.m.SetAllTextureAnimations(tlib); // set all texture animations on GPU // initialize paths that the instances will follow this.p = new PathArrayHelper(this.m); // Create instances for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { // specify instance data var random_anim_id = anims[Random.Range(0, anims.Count)].animation_id; InstanceData <InstanceProperties> dat = new InstanceData <InstanceProperties>(this.m.Default); dat.position = new Vector3(i, 0, j); dat.rotation = Quaternion.Euler(-90, 0, 0); dat.props_IsTextureAnimation = true; dat.props_animationID = random_anim_id; dat.props_AnimationSpeed = Random.Range(0.5f, 2.0f); dat.props_AnimationSeconds = Random.Range(0, 1.0f); // create & assign path Path path = new Path(path_length: 4, m: this.m, use_constants: true); this.p.InitializePath(ref path); this.p.SetPathConstants(path, new Vector3(0, 0, Random.Range(-10.0f, 10.0f)), new Vector3(Random.Range(-1.0f, 1.0f), 0, Random.Range(-1.0f, 1.0f)), dat.rotation, dat.position); this.p.UpdatePath(ref path); dat.SetPath(path, this.m); // Initialize & send instance to gpu this.m.Initialize(ref dat); this.m.Append(ref dat); // Make a unity gameobject follow the first instance.. Just for testing CPU instance transform approximation if (i == 0 && j == 0) { this.follow_obj = GameObject.CreatePrimitive(PrimitiveType.Cube); this.follow_obj.name = "Calculated Object Transform"; this.follow_obj.transform.localScale = Vector3.one * 0.25f; this.follow_obj.transform.position = dat.position; this.follow_obj.transform.rotation = dat.rotation; this.follow_instance = dat; this.follow_path = path; } } } }
// Use this for initialization void Awake() { //initialize buffer = new InstanceData[instanceCountsq * instanceCountsq]; imesher = new MeshInstancer(); imesher.Initialize(max_parent_depth: 2, pathCount: 4); this.p = new PathArrayHelper(this.imesher); // load all the textures var keys = Texture2MeshType.Textures2MeshType(this.Textures, imesher.Default.shared_mesh, imesher.Default.shared_material); // create all the mesh types that we can use foreach (var key in keys) { imesher.AddNewMeshType(key.mesh_key, key.material_key); } //make parent object parent = new InstanceData(imesher.Default); parent.position = position; parent.scale = scale; parent.rotation = Quaternion.Euler(rotation); buffer[0] = parent; float v = this.VelocityRange; var rangemax = keys.Count; for (int i = 0; i < instanceCountsq; i++) { for (int j = 0; j < instanceCountsq; j++) { if (i == 0 && j == 0) { continue; // skip parent } var tkey = Random.Range(1, rangemax); // get random texture var newt = new InstanceData(imesher.GetMeshType(keys[tkey].mesh_key, keys[tkey].material_key)); // make instance data newt.position = new Vector3(i, 0, j); // assign position of instance newt.parentID = 0; // parent to instance at index 0 newt.props_color32 = new Color32((byte)Random.Range(0, 256), (byte)Random.Range(0, 256), (byte)Random.Range(0, 256), (byte)255); // set random color // create & assign path Path path = new Path(path_length: 4, m: this.imesher, use_constants: true); this.p.InitializePath(ref path); this.p.SetPathConstants(path, new Vector3(Random.Range(-10.0f, 10.0f), Random.Range(-10.0f, 10.0f), Random.Range(-10.0f, 10.0f)), new Vector3(Random.Range(-v, v), Random.Range(-v, v), Random.Range(-v, v)), newt.rotation, newt.position); this.p.UpdatePath(ref path); newt.SetPath(path, this.imesher); buffer[i * instanceCountsq + j] = newt; // assign in buffer } } imesher.InitializeSet(buffer); imesher.AppendMany(buffer); parent = buffer[0]; }
// Start is called before the first frame update void Start() { this.m = new MeshInstancer(); this.m.Initialize(pathCount: Mathf.Max(path1.Count, Mathf.Max(path2.Count, path3.Count))); this.p = new PathArrayHelper(this.m); InitInstance(ref this.instance1, this.path1, ref this.path1_props, Color.red); InitInstance(ref this.instance2, this.path2, ref this.path2_props, Color.green); InitInstance(ref this.instance3, this.path3, ref this.path3_props, Color.blue); }
void Start() { // Initialize character mesh list int hierarchy_depth, skeleton_bone_count; var controllers = GPUSkinnedMeshComponent.PrepareControllers(characters, out hierarchy_depth, out skeleton_bone_count); // Initialize GPU Instancer this.m = new MeshInstancer(); this.m.Initialize(max_parent_depth: hierarchy_depth + 2, num_skeleton_bones: skeleton_bone_count, pathCount: 2); this.p = new PathArrayHelper(this.m); // Add all animations to GPU buffer this.m.SetAllAnimations(controllers); // Add all character mesh types to GPU Instancer foreach (var character in this.characters) { this.m.AddGPUSkinnedMeshType(character); } // Do stuff for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { var mesh = characters[Random.Range(0, characters.Count)]; var anim = mesh.anim.namedAnimations["walk"]; instances[i, j] = new SkinnedMesh(mesh, this.m); instances[i, j].mesh.position = new Vector3(i, 0, j); instances[i, j].SetRadius(1.75f); // set large enough radius so model doesnt get culled to early instances[i, j].Initialize(); instances[i, j].SetAnimation(anim, speed: 1.4f, start_time: Random.Range(0.0f, 1.0f)); // set animation var path = GetNewPath(); // create new path instances[i, j].mesh.SetPath(path, this.m); // assign path to instance paths[i, j] = path; instances[i, j].UpdateAll(); } } // For testing purposes.. do bone visualization of [0,0] model bones_unity = new GameObject[instances[0, 0].skeleton.data.Length]; for (int i = 0; i < bones_unity.Length; i++) { var obj = GameObject.CreatePrimitive(PrimitiveType.Cube); obj.name = "Calculated Bone Transform " + i.ToString(); bones_unity[i] = obj; } }
// Use this for initialization void Start() { Mesh mesh = BaseMeshLibrary.CreateDefault(); Material material = new Material(Shader.Find("Instanced/instancemeshdefault_Transparent")); material.enableInstancing = true; imesher = new MeshInstancer(); imesher.Initialize(64, 64, override_mesh: BaseMeshLibrary.CreatePlane2Sides(), override_material: BaseMaterialLibrary.CreateDefault(), max_parent_depth: 1, num_skeleton_bones: 1); var keys = Texture2MeshType.Textures2MeshType(this.Textures, mesh, material); foreach (var key in keys) { imesher.AddNewMeshType(key.mesh_key, key.material_key); } imesher.FrustumCamera = frustum_culling ? GameObject.Find("Main Camera").GetComponent <Camera>() : null; var udat = keys.Where(x => x.material_key.mainTexture.name == "clear3").First(); InstanceData d1 = new InstanceData(imesher.GetMeshType(udat.mesh_key, udat.material_key)); d1.props_color32 = new Color32(0, 0, 255, 90); d1.position = new Vector3(0.5f, 0, 0); d1.rotation = Quaternion.Euler(-90, 0, 0); d1.props_color32 = Color.blue; imesher.Initialize(ref d1); imesher.Append(ref d1); InstanceData d2 = new InstanceData(imesher.GetMeshType(udat.mesh_key, udat.material_key)); d2.props_color32 = new Color32(0, 0, 255, 90); d2.position = new Vector3(0, 0, 0); d2.rotation = Quaternion.Euler(-90, 0, 0); d2.props_color32 = Color.blue; imesher.Initialize(ref d2); imesher.Append(ref d2); InstanceData d3 = new InstanceData(imesher.GetMeshType(udat.mesh_key, udat.material_key)); d3.props_color32 = new Color32(0, 0, 255, 90); d3.position = new Vector3(-0.5f, 0, 0); d3.rotation = Quaternion.Euler(-90, 0, 0); d3.props_color32 = Color.blue; imesher.Initialize(ref d3); imesher.Append(ref d3); }
// Start is called before the first frame update void Start() { model1.anim.Initialize(); model2.anim.Initialize(); int hierarchy_depth = System.Math.Max(model1.anim.BoneHierarchyDepth, model2.anim.BoneHierarchyDepth) + 2; // maximum allowed hierarchy depth int bone_count = System.Math.Max(model1.anim.BoneCount, model2.anim.BoneCount); // maximum allowed skeleton size in number of bones this.m = new MeshInstancer(); this.m.Initialize(num_skeleton_bones: bone_count, max_parent_depth: hierarchy_depth, deltaBufferCount: 3, PropertyBufferMaxDeltaCount: 3, PathDeltaBufferSize: 3); // initialize meshinstancer (intentially picking terrible small delta buffer sizes for testing purposes) this.p = new PathArrayHelper(this.m); this.m.SetAllAnimations(new AnimationController[] { model1.anim, model2.anim }); // add all animations this.m.AddGPUSkinnedMeshType(model1); // add each mesh type this.m.AddGPUSkinnedMeshType(model2); }
public Skeleton(AnimationController c, MeshInstancer m) { if (!c.IsIntialized || !m.Initialized()) { throw new System.Exception("Error, input is not initialized."); } var default_type = m.Default; this.m = null; this.Controller = c; this.data = new InstanceData <BoneProperties> [c.BoneCount]; //set bone data for (int i = 0; i < c.BoneCount; i++) { this.data[i] = new InstanceData <BoneProperties>(default_type, has_props: false); this.data[i].parentID = c.bone_parents[i]; //set local parent this.data[i].Invisible = true; //invisible=true so that nothing is rendered (ie, always will be culled and not added to DrawMeshIndirect) } }
// Start is called before the first frame update void Start() { List <TextureUVAnimation> anims = new List <TextureUVAnimation>(); anims.Add(MakeGPUTextureAnim(this.Explosion)); this.m = new MeshInstancer(); this.m.Initialize(max_parent_depth: 1, pathCount: 2, override_mesh: BaseMeshLibrary.CreatePlane()); this.p = new PathArrayHelper(this.m); var tlib = new TextureAnimationLibrary(anims); this.m.SetAllTextureAnimations(tlib); this.m.FrustumCamera = this.FrustumCamera; var explosion_mesh_type = this.m.AddNewMeshType(this.m.Default.shared_mesh, Instantiate(this.ExplosionMaterial)); float f = 80.0f; for (int i = 0; i < N; i++) { this.instances[i] = new InstanceData <InstanceProperties>(explosion_mesh_type); this.instances[i].position = new Vector3(Random.Range(-f, f), Random.Range(-f, f), Random.Range(-f, f)); this.instances[i].props_animationID = tlib.Animations[0].animation_id; this.instances[i].props_IsTextureAnimation = true; this.instances[i].props_AnimationSeconds = Random.Range(0, 1.0f); this.instances[i].props_AnimationSpeed = 2.0f; var path = new Path(2, this.m, look_at_camera: true); // instruct instance to look at camera via path API this.p.InitializePath(ref path); this.p.SetPathStaticPosition(path, this.instances[i].position, Vector3.up); // just set a not-moving path this.p.UpdatePath(ref path); this.instances[i].SetPath(path, this.m); this.paths[i] = path; this.m.Initialize(ref this.instances[i]); this.m.Append(ref this.instances[i]); } }