private void createLodSys(MeshInstance _mesh) { if (_mesh != null) { GD.Print("Create mesh"); if (_mesh.GetChildCount() > 0) { GD.Print("Mesh needs to be clear. Remove childs at first"); return; } var q2 = (float)(editDock.GetNode("lod2_quality") as Slider).Value; var q3 = (float)(editDock.GetNode("lod3_quality") as Slider).Value; var lod2Mesh = MeshDecimator.MeshDecimatorTool.generateMesh(q2, _mesh); var lod3Mesh = MeshDecimator.MeshDecimatorTool.generateMesh(q3, _mesh); //set scale to all other meshinstances var tf = (MeshLod)GD.Load <PackedScene>("res://addons/mesh_lod/MeshLod.tscn").Instance(); _mesh.GetParent().AddChild(tf); tf.Translation = _mesh.Translation; tf.Rotation = _mesh.Rotation; tf.Scale = _mesh.Scale; tf.lod2Quality = q2; tf.lod3Quality = q3; tf.Owner = GetEditorInterface().GetEditedSceneRoot(); _mesh.GetParent().RemoveChild(_mesh); tf.AddChild(_mesh); _mesh.Owner = GetEditorInterface().GetEditedSceneRoot(); tf.Name = _mesh.Name; _mesh.Name = "lod1"; _mesh.Translation = Vector3.Zero; _mesh.Rotation = Vector3.Zero; _mesh.Scale = new Vector3(1, 1, 1); var lod2 = createLodMesh(_mesh, lod2Mesh); lod2.Name = "lod2"; var lod3 = createLodMesh(_mesh, lod3Mesh); lod3.Name = "lod3"; tf.AddChild(lod2); tf.AddChild(lod3); lod2.Owner = GetEditorInterface().GetEditedSceneRoot(); lod3.Owner = GetEditorInterface().GetEditedSceneRoot(); tf.doLoding(); } }
void CreateGround(MeshInstance meshInstance, float x, int index) { float height1 = _mTerrain.GetHeight(x); float height2 = _mTerrain.GetHeight(x + WIDTH); // test slope meshInstance._mVerts.Add(new Vector3(x, BOTTOM, 0)); meshInstance._mVerts.Add(new Vector3(x + WIDTH, BOTTOM, 0)); meshInstance._mVerts.Add(new Vector3(x + WIDTH, height2, 0)); meshInstance._mVerts.Add(new Vector3(x, height1, 0)); CreateFaces(meshInstance, index, false); }
public void CreateChunk(int x, int y, int z) { MeshInstance newChunk = new MeshInstance(); var id = newChunk.GetInstanceId(); newChunk.SetScript(chunkScript); Chunk chunk = GD.InstanceFromId(id) as Chunk; chunk.SetGenerator(terrainGen); chunk.ConstructChunk(chunkSize, x, y, z); AddChild(chunk); chunks.Add(new Vector3(x, y, z), chunk); }
public void Init(Vector3 position) { this.noise = References.noise; this.chunkSize = References.chunkSize; this.position = position * chunkSize; Translation = this.position; chunkBorders = (MeshInstance)GetChild(0); collisionArea = (Area)GetChild(1); chunkBorders.Scale = new Vector3(References.chunkSize * 0.5f, References.chunkBorderAreaHeight, References.chunkSize * 0.5f); collisionArea.Scale = new Vector3(References.chunkSize * 0.5f, References.chunkCollisionAreaHeight, References.chunkSize * 0.5f); }
public override void _Ready() { Mesh = GetNode <MeshInstance>("MeshInstance"); ShaderMaterial Mat = new ShaderMaterial(); Mat.Shader = Items.TileShader; Mat.SetShaderParam("texture_albedo", Items.Textures[Type]); GetNode <MeshInstance>("MeshInstance").MaterialOverride = Mat; CurrentChunkTuple = World.GetChunkTuple(Translation); World.AddEntityToChunk(this); }
public void ChangeTexture(Spatial mesh, string name, string newTextureName, Color newColor) { var mi = mesh.FindNode(name); MeshInstance m = (MeshInstance)mi; SpatialMaterial mat = new SpatialMaterial(); var texture = (Texture)GD.Load(newTextureName); mat.AlbedoTexture = texture; mat.AlbedoColor = newColor; m.MaterialOverride = mat; }
public override void _Ready() { red = (Material)ResourceLoader.Load("res://Assets/Buildings/Outline/OutlineMaterialRed.tres"); green = (Material)ResourceLoader.Load("res://Assets/Buildings/Outline/OutlineMaterialGreen.tres"); outline_scene = (PackedScene)ResourceLoader.Load("res://Assets/Buildings/Outline/Outline.tscn"); outline = (Spatial)outline_scene.Instance(); outline.Name = "Outline"; outline_mesh = (MeshInstance)outline.GetNode("luftballonmesherinorotzskelettbaumgraphtankstellenwartjareicht"); AddChild(outline); base._Ready(); }
// Called when the node enters the scene tree for the first time. public override void _Ready() { _steeringWheel = this.GetNode("JeepSteeringWheel") as MeshInstance; _gear = this.GetNode("Camera/Panel/Gear") as Label; _speed = this.GetNode("Camera/Panel2/Speed") as Label; _gear.Text = "Park"; _state = States.Park; states[(int)States.Drive] = new StateDrive(this); states[(int)States.Reverse] = new StateReverse(this); states[(int)States.Park] = new StatePark(this); Input.SetMouseMode(Input.MouseMode.Captured); }
public void Initialise() { Report = new DynamicCarReport(); LastCarModel++; if (LastCarModel >= CarModels.Length) { LastCarModel = 0; } MeshInstance mesh = (MeshInstance)((PackedScene)GD.Load(CarModels[LastCarModel])).Instance(); AddChild(mesh); _bubble = GetNode <BubbleSprite>("BubbleSprite"); }
public override void _Ready() { GetNode <RigidBody>("DotPhysics").GravityScale = 0; dotMesh = GetNode <MeshInstance>("DotPhysics/DotCollision/Dot"); var mat = new SpatialMaterial(); mat.AlbedoColor = Color.FromHsv(1, 1, 1, 0); mat.EmissionEnabled = true; mat.Emission = Color.FromHsv(GD.Randf(), 1, 1); mat.EmissionEnergy = 1; dotMesh.MaterialOverride = mat; }
public MeshInstance addPlane(int side) { MeshInstance p = new MeshInstance { }; p.Mesh = new PlaneMesh { }; Vector3 new_loc = new Vector3(0, 0, 0); Vector3 new_rot = new Vector3(0, 0, 0); var spread = 1.15f; switch (side) { case side_top: new_loc.y = spread; break; case side_bottom: new_rot.x = 180f; new_loc.y = -spread; break; case side_left: new_rot.z = -90f; new_loc.x = spread; break; case side_right: new_rot.z = 90f; new_loc.x = -spread; break; case side_back: new_rot.x = 90f; new_loc.z = spread; break; case side_front: new_rot.x = -90f; new_loc.z = -spread; break; } p.Scale = new_scale; p.Translate(new_loc); p.RotationDegrees = new_rot; return(p); }
private static MeshInstance DebugMesh() { SurfaceTool tool = new SurfaceTool(); tool.Begin(PrimitiveMesh.PrimitiveType.Lines); //Front tool.AddVertex(new Vector3(0, 0, 0)); tool.AddVertex(new Vector3(1, 0, 0)); tool.AddVertex(new Vector3(1, 0, 0)); tool.AddVertex(new Vector3(1, 1, 0)); tool.AddVertex(new Vector3(1, 1, 0)); tool.AddVertex(new Vector3(0, 1, 0)); tool.AddVertex(new Vector3(0, 1, 0)); tool.AddVertex(new Vector3(0, 0, 0)); //Back tool.AddVertex(new Vector3(0, 0, 1)); tool.AddVertex(new Vector3(1, 0, 1)); tool.AddVertex(new Vector3(1, 0, 1)); tool.AddVertex(new Vector3(1, 1, 1)); tool.AddVertex(new Vector3(1, 1, 1)); tool.AddVertex(new Vector3(0, 1, 1)); tool.AddVertex(new Vector3(0, 1, 1)); tool.AddVertex(new Vector3(0, 0, 1)); //BOTTOM tool.AddVertex(new Vector3(0, 0, 0)); tool.AddVertex(new Vector3(0, 0, 1)); tool.AddVertex(new Vector3(0, 0, 1)); tool.AddVertex(new Vector3(1, 0, 1)); tool.AddVertex(new Vector3(1, 0, 1)); tool.AddVertex(new Vector3(1, 0, 0)); tool.AddVertex(new Vector3(1, 0, 0)); tool.AddVertex(new Vector3(0, 0, 0)); //TOP tool.AddVertex(new Vector3(0, 1, 0)); tool.AddVertex(new Vector3(0, 1, 1)); tool.AddVertex(new Vector3(0, 1, 1)); tool.AddVertex(new Vector3(1, 1, 1)); tool.AddVertex(new Vector3(1, 1, 1)); tool.AddVertex(new Vector3(1, 1, 0)); tool.AddVertex(new Vector3(1, 1, 0)); tool.AddVertex(new Vector3(0, 1, 0)); MeshInstance instance = new MeshInstance(); instance.Mesh = tool.Commit(); return(instance); }
public InventoryView( IPlayerControl playerControl, InspectingView viewControl, MeshInstance itemStand, bool pauseWhenVisible, Option <string> closeAction, Godot.Control node, Tree tree, Container buttonContainer, Panel infoPanel, Label titleLabel, Option <Label> typeLabel, Option <RichTextLabel> descriptionLabel, PackedScene actionButton, ILoggerFactory loggerFactory) : base(pauseWhenVisible, closeAction, playerControl, node, loggerFactory) { Ensure.That(viewControl, nameof(viewControl)).IsNotNull(); Ensure.That(tree, nameof(tree)).IsNotNull(); Ensure.That(itemStand, nameof(itemStand)).IsNotNull(); Ensure.That(buttonContainer, nameof(buttonContainer)).IsNotNull(); Ensure.That(infoPanel, nameof(infoPanel)).IsNotNull(); Ensure.That(titleLabel, nameof(titleLabel)).IsNotNull(); Ensure.That(actionButton, nameof(actionButton)).IsNotNull(); ViewControl = viewControl; Tree = tree; ButtonContainer = buttonContainer; ItemStand = itemStand; InfoPanel = infoPanel; TitleLabel = titleLabel; TypeLabel = typeLabel; DescriptionLabel = descriptionLabel; ActionButton = actionButton; _buttonListeners = new CompositeDisposable(); OnEquipmentContainerChange = PlayerControl.OnCharacterChange .Select(c => c.Select(v => v.Equipments).ToObservable()) .Switch(); OnItemsChange = OnEquipmentContainerChange .Select(c => c.OnItemsChange) .Switch(); OnSelectionChange = Tree.OnItemSelect() .Select(v => v.Bind(i => Optional(i.GetMeta(SlotKey) as string))) .Merge(OnItemsChange.Select(_ => Option <string> .None)) .CombineLatest(OnEquipmentContainerChange, (slot, slots) => (slot, slots)) .Select(t => t.slot.Bind(s => t.slots.FindItemInSlot(s)).HeadOrNone()) .Do(current => Selected = current); }
private Vector3 get_dimensions(Spatial node) { MeshInstance node_mesh = new MeshInstance(); foreach (Spatial child in node.GetChildren()) { // if(child is Godot.MeshInstance) // { // node_mesh = (MeshInstance) child; // } } return(new Vector3()); }
public override MeshInstance CreateChunkMesh(ref ChunkStruct c) { // Console.WriteLine("Curr Chunk {0},{1},{2}",c.Dx,c.Dy,c.Dz); String startTime = DateTime.Now.ToString("HH:mm:ss:ffff"); c.surfaceTool.Begin(Mesh.PrimitiveType.Points); c.surfaceTool.SetMaterial(mat); String initTime = DateTime.Now.ToString("HH:mm:ss:ffff"); // for (int i = 0; i < CHUNK_SIZE; i += 1) // { // for (int j = 0; j < CHUNK_SIZE; j += 1) // { // for (int k = 0; k < CHUNK_SIZE; k += 1) // { // if (c[i, j, k] == 0) // { // continue; // } // createVoxel(i, j, k, ref c); // } // } // } int maxChunk = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE; for (int i = 0; i < maxChunk; i++) { int x = i / (CHUNK_SIZE * CHUNK_SIZE); int y = (i / CHUNK_SIZE) % CHUNK_SIZE; int z = i % CHUNK_SIZE; if (c[x, y, z] == 0) { continue; } createVoxel(x, y, z, ref c); } String pointCreationTime = DateTime.Now.ToString("HH:mm:ss:ffff"); c.surfaceTool.Index(); MeshInstance mesh = new MeshInstance(); mesh.SetMesh(c.surfaceTool.Commit()); c.surfaceTool.Clear(); String indexTime = DateTime.Now.ToString("HH:mm:ss:ffff"); // Console.WriteLine("Curr Chunk {0},{1},{2} Curr Thread: {3}, StartTime: {4}, Initialization Time: {5}, Greedy Time: {6}, Index Time {7}",c.Dx,c.Dy,c.Dz, // System.Threading.Thread.CurrentThread.ManagedThreadId,startTime // ,initTime,pointCreationTime,indexTime); return(mesh); }
public static Mesh Combine(MeshInstance[] _combines) { Mesh mesh = new Mesh(); mesh.name = "Combined Mesh"; CombineInstance[] combineInsts = new CombineInstance[_combines.Length]; int i = 0; while (i < _combines.Length) { combineInsts[i].mesh = _combines[i].mesh; combineInsts[i].transform = _combines[i].transform; ++i; } mesh.CombineMeshes(combineInsts); return mesh; }
private static int getIndex(Dictionary <int, int> indexTranslation, MeshInstance meshInstance, int inputVert, List <Vector3> vertices, List <Vector3> normals, List <Vector4> tangents, List <Vector2> uvs, List <Vector2> uv2s, List <Vector2> uv3s, List <Color> colors, Vector3[] inputVertices, Vector3[] inputNormals, Vector4[] inputTangents, Vector2[] inputUVs, Color[] inputColors, Vector2?uv2Force, Vector2?uv3Force) { int newVert; if (indexTranslation.ContainsKey(inputVert)) { newVert = indexTranslation[inputVert]; } else { newVert = vertices.Count; indexTranslation[inputVert] = newVert; vertices.Add(meshInstance.transform.MultiplyPoint(inputVertices[inputVert])); Matrix4x4 invTranspose = meshInstance.transform; invTranspose = invTranspose.inverse.transpose; normals.Add(invTranspose.MultiplyVector(inputNormals[inputVert]).normalized); Vector4 p4 = inputTangents[inputVert]; Vector3 p = new Vector3(p4.x, p4.y, p4.z); p = invTranspose.MultiplyVector(p).normalized; tangents.Add(invTranspose.MultiplyVector(new Vector4(p.x, p.y, p.z, p4.w))); uvs.Add(meshInstance.uv1Transform.MultiplyPoint(inputUVs[inputVert])); if (!uv2Force.HasValue) { uv2s.Add(meshInstance.uv2Transform.MultiplyPoint(inputUVs[inputVert])); } else { uv2s.Add(uv2Force.Value); } if (!uv3Force.HasValue) { uv3s.Add(meshInstance.uv3Transform.MultiplyPoint(inputUVs[inputVert])); } else { uv3s.Add(uv3Force.Value); } if (inputColors.Length > 0) { colors.Add(meshInstance.color.linear * inputColors[inputVert]); } else { colors.Add(meshInstance.color.linear); } } return(newVert); }
// Function that is called when the selected object is changed // Connected to the "ObjectSelectList" option button through the editor public void _on_ObjectSelectList_item_selected(int index) { // Hide the previously selected object objectMesh.Visible = false; // Set the current object's index currentObjectIndex = index; // Reassign the selected mesh instance to the new object objectMesh = objectMeshRoot.GetChild <MeshInstance>(FIRST_OBJECT_INDEX + currentObjectIndex); // Show the new object objectMesh.Visible = true; }
public override void _Ready() { System = new PipeSystem(this); Friends = new HashSet <PipeCoreLogic>(); Position1 = GetNode <Spatial>("Positions/Position1"); OpenEndMesh = GetNode <MeshInstance>("OpenEndMesh"); OpenEndCollision = GetNode <CollisionShape>("OpenEndCollision"); OpenEnd = GetNode <StaticBody>("OpenEnd"); CallDeferred(nameof(GridUpdate)); base._Ready(); }
/// <summary> /// Add a mesh instance to the combiner. /// </summary> /// <param name="instance">The mesh instance to add.</param> public void AddMeshInstance(MeshInstance instance) { int baseVertexIndex = _vertices.Count; PrepareForAddingVertices(instance.mesh.vertexCount); _vertices.AddRange(instance.mesh.vertices.Select(v => instance.transform.MultiplyPoint(v))); _normals.AddRange( instance.mesh.normals.Select(n => instance.transform.inverse.transpose.MultiplyVector(n).normalized)); _tangents.AddRange(instance.mesh.tangents.Select(t => { var p = new Vector3(t.x, t.y, t.z); p = instance.transform.inverse.transpose. MultiplyVector(p).normalized; return(new Vector4(p.x, p.y, p.z, t.w)); })); _uv.AddRange(instance.mesh.uv); _uv1.AddRange(instance.mesh.uv1); _colors.AddRange(instance.mesh.colors); if (_generateStrips) { int[] inputstrip = instance.mesh.GetTriangleStrip(instance.subMeshIndex); PrepareForAddingStrips(instance.targetSubMeshIndex, new[] { inputstrip.Length }); List <int> outputstrip = _strip[instance.targetSubMeshIndex]; if (outputstrip.Count != 0) { if ((outputstrip.Count & 1) == 1) { outputstrip.Add(outputstrip[outputstrip.Count - 1]); outputstrip.Add(inputstrip[0] + baseVertexIndex); outputstrip.Add(inputstrip[0] + baseVertexIndex); } else { outputstrip.Add(outputstrip[outputstrip.Count - 1]); outputstrip.Add(inputstrip[0] + baseVertexIndex); } } outputstrip.AddRange(inputstrip.Select(s => s + baseVertexIndex)); } else { int[] inputtriangles = instance.mesh.GetTriangles(instance.subMeshIndex); PrepareForAddingTriangles(instance.targetSubMeshIndex, inputtriangles.Length); _triangles[instance.targetSubMeshIndex].AddRange(inputtriangles.Select(t => t + baseVertexIndex)); } }
void CombinaQuads() { MeshInstance cube = new MeshInstance { Name = "Chunk" }; ArrayMesh cubeArray = new ArrayMesh(); Godot.Collections.Array kids = chunk.GetChildren(); Material[] materiais = new Material[kids.Count]; int contador = 0; foreach (MeshInstance meshI in kids) { Vector3[] vertLocal = (Vector3[])meshI.Mesh.SurfaceGetArrays(0)[(int)ArrayMesh.ArrayType.Vertex]; Vector3[] vertGlobal = new Vector3[vertLocal.Length]; //convertendo as coordenads de locais para globais dos quads for (int i = 0; i < vertLocal.Length; i++) { vertGlobal[i].x = vertLocal[i].x + meshI.Translation.x; vertGlobal[i].y = vertLocal[i].y + meshI.Translation.y; vertGlobal[i].z = vertLocal[i].z + meshI.Translation.z; } ArrayMesh combineArray = new ArrayMesh(); var arrays = new Godot.Collections.Array(); arrays.Resize((int)ArrayMesh.ArrayType.Max); arrays[(int)ArrayMesh.ArrayType.Vertex] = vertGlobal; arrays[(int)ArrayMesh.ArrayType.Normal] = meshI.Mesh.SurfaceGetArrays(0)[(int)ArrayMesh.ArrayType.Normal]; arrays[(int)ArrayMesh.ArrayType.TexUv] = meshI.Mesh.SurfaceGetArrays(0)[(int)ArrayMesh.ArrayType.TexUv]; arrays[(int)ArrayMesh.ArrayType.Index] = meshI.Mesh.SurfaceGetArrays(0)[(int)ArrayMesh.ArrayType.Index]; cubeArray.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays); materiais[contador] = meshI.GetSurfaceMaterial(0); meshI.QueueFree(); contador++; } cube.Mesh = cubeArray; for (int i = 0; i < materiais.Length; i++) { cube.SetSurfaceMaterial(i, materiais[i]); } chunk.AddChild(cube); }
public void CreateLeaf() { SphereMesh mesh = new SphereMesh(); mesh.Radius = 0.4f; mesh.Height = mesh.Radius * 2; mesh.RadialSegments = 8; mesh.Rings = 4; MeshInstance meshInstance = new MeshInstance(); meshInstance.Mesh = mesh; meshInstance.SetSurfaceMaterial(0, LeafMaterial); AddChild(meshInstance); }
/// <summary> /// Add a mesh instance to the combiner. /// </summary> /// <param name="instance">The mesh instance to add.</param> public void AddMeshInstance(MeshInstance instance) { int baseVertexIndex = _vertices.Count; PrepareForAddingVertices(instance.mesh.vertexCount); _vertices.AddRange(instance.mesh.vertices.Select(v => instance.transform.MultiplyPoint(v))); _normals.AddRange( instance.mesh.normals.Select(n => instance.transform.inverse.transpose.MultiplyVector(n).normalized)); _tangents.AddRange(instance.mesh.tangents.Select(t => { var p = new Vector3(t.x, t.y, t.z); p = instance.transform.inverse.transpose. MultiplyVector(p).normalized; return new Vector4(p.x, p.y, p.z, t.w); })); _uv.AddRange(instance.mesh.uv); _uv1.AddRange(instance.mesh.uv1); _colors.AddRange(instance.mesh.colors); if (_generateStrips) { int[] inputstrip = instance.mesh.GetTriangles(instance.subMeshIndex); PrepareForAddingStrips(instance.targetSubMeshIndex, new[] {inputstrip.Length}); List<int> outputstrip = _strip[instance.targetSubMeshIndex]; if (outputstrip.Count != 0) { if ((outputstrip.Count & 1) == 1) { outputstrip.Add(outputstrip[outputstrip.Count - 1]); outputstrip.Add(inputstrip[0] + baseVertexIndex); outputstrip.Add(inputstrip[0] + baseVertexIndex); } else { outputstrip.Add(outputstrip[outputstrip.Count - 1]); outputstrip.Add(inputstrip[0] + baseVertexIndex); } } outputstrip.AddRange(inputstrip.Select(s => s + baseVertexIndex)); } else { int[] inputtriangles = instance.mesh.GetTriangles(instance.subMeshIndex); PrepareForAddingTriangles(instance.targetSubMeshIndex, inputtriangles.Length); _triangles[instance.targetSubMeshIndex].AddRange(inputtriangles.Select(t => t + baseVertexIndex)); } }
// Called when the node enters the scene tree for the first time. public override void _Ready() { // Get references to parts of tanks trackleft = (MeshInstance)GetNode("TrackLeft"); trackright = (MeshInstance)GetNode("TrackRight"); body = (MeshInstance)GetNode("Body"); turret = (KinematicBody)GetNode("Turret"); gun = (MeshInstance)GetNode("Turret/TurretMesh/Gun"); // load sounds trackmovementsound = (AudioStreamPlayer3D)GetNode("SoundGroup/TrackMovementSound"); firesound = (AudioStreamPlayer3D)GetNode("SoundGroup/FireSound"); explodesound = (AudioStreamPlayer3D)GetNode("SoundGroup/ExplosionSound"); soundgroup = GetNode("SoundGroup"); // load cameras thirdpersoncamera = (Camera)GetNode("ThirdPersonCam"); firstpersoncamera = (Camera)GetNode("Turret/TurretMesh/Gun/BulletSpawn/Camera"); // reference to explosion for death explosion = (Particles)GetNode("Explosion/Particles"); explosion.SetEmitting(false); // Load bullet scene bulletscene = ResourceLoader.Load("res://Bullet.tscn") as Godot.PackedScene; // Set a color for the tank setTankColor(defaultTankColor); health = maxhealth; // add signals AddUserSignal("dec_local_health"); AddUserSignal("respawn"); AddUserSignal("bullet_fired"); // connect respawn timer AddChild(deathtimer); deathtimer.Connect("timeout", this, "Respawn"); deathtimer.SetWaitTime(RESPAWN_SECONDS); SetProcess(true); // required to appear at spawn MoveAndSlide(new Vector3(0, 0, 0), new Vector3(0, 1, 0), true); // enforce no flying tanks issue #20 originalY = Transform.origin.y; }
void find_LODs() { Godot.Collections.Array childrens = this.GetChildren(); foreach (Node child in childrens) { string name = child.Name; if (name.Contains("_LOD1")) { LOD1_Inst = (MeshInstance)child; } else if (name.Contains("_LOD2")) { LOD2_Inst = (MeshInstance)child; } else if (name.Contains("_LOD3")) { LOD3_Inst = (MeshInstance)child; } else if (name.Contains("_LOD0")) { LOD0_Inst = (MeshInstance)child; } else if (!name.Contains("_Coll")) { //LOD0_Inst = (MeshInstance)child; } } LOD_Num = 4; if (LOD3_Inst == null) { LOD3_Inst = new MeshInstance(); LOD_Num = 3; } if (LOD2_Inst == null) { LOD2_Inst = new MeshInstance(); LOD_Num = 2; } if (LOD1_Inst == null) { LOD1_Inst = new MeshInstance(); LOD_Num = 1; } if (LOD0_Inst == null) { LOD0_Inst = new MeshInstance(); LOD_Num = 0; } }
public override void _Ready() { Joint = GetNode <Spatial>("EverythingJoint"); Mesh = Joint.GetNode <MeshInstance>("Mesh"); Head = Joint.GetNode <Hitbox>("HeadHitbox"); Feet = Joint.GetNode <Hitbox>("FeetHitbox"); CamJoint = GetNode <Spatial>("CamJoint"); Cam = CamJoint.GetNode <Camera>("Cam"); Holder = Cam.GetNode <WeaponHolder>("WeaponHolder"); Cam.Current = false; base._Ready(); }
private Action <object> ActionCreateChunkMesh(Tuple <int, int, int> value) { return(t => { if (t == null) { throw new ArgumentNullException(nameof(t)); } // Tuple<int, int, int> value = t1; // Console.WriteLine("{0},{1},{2}", value.Item1, value.Item2, value.Item3); MeshInstance mesh = this.mesher.CreateChunkMesh(ref this.chunksList[value.Item1, value.Item2, value.Item3]); this.chunkQueue.Enqueue(mesh); }); }
/** * Start auto loding */ public static ArrayMesh generateMesh(float quality, MeshInstance origMeshInst) { var arr_mesh = new ArrayMesh(); var arrayMesh = origMeshInst.Mesh as ArrayMesh; quality = MathHelper.Clamp01(quality); for (int i = 0; i < origMeshInst.Mesh.GetSurfaceCount(); i++) { var arrays = generateMeshFromSurface(quality, origMeshInst, i); arr_mesh.AddSurfaceFromArrays(Godot.Mesh.PrimitiveType.Triangles, arrays); } return(arr_mesh); }
public static void DrawSphere(Vector3 globalLocation, Spatial parent, float diameter = 0.05f) { MeshInstance sphere = new MeshInstance(); SphereMesh shape = new SphereMesh(); parent.AddChild(sphere); Transform placeholder = sphere.GlobalTransform; placeholder.origin = globalLocation; sphere.GlobalTransform = placeholder; shape.Radius = diameter / 2.0f; shape.Height = diameter; sphere.Mesh = shape; sphere.Visible = true; }
public void CreateQuad(Vector3 vertex0, Vector3 vertex1, Vector3 vertex2, Vector3 vertex3) { // Generate quad mesh (2 triangles) Vector3[] vertices = { vertex0, //top-left vertex1, //top-right vertex2, //bottom-left vertex3 }; //bottom-right int[] index = new int[6] { 0, 1, 2, 3, 2, 1 }; // UVs Vector2[] uvs = { new Vector2(0f, 1f), //top-left new Vector2(1f, 1f), //top-right new Vector2(0f, 0f), //bottom-left new Vector2(1f, 0f) }; //bottom-right // Normals Vector3[] normals = new Vector3[4] { Vector3.Up, Vector3.Up, Vector3.Up, Vector3.Up }; Godot.Collections.Array arrays = new Godot.Collections.Array(); arrays.Resize(9); // see arrays[0] = vertices; arrays[1] = normals; arrays[4] = uvs; arrays[8] = index; // Create the Mesh. // Initialize the ArrayMesh. ArrayMesh arr_mesh = new ArrayMesh(); arr_mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays); MeshInstance quad = new MeshInstance(); quad.Mesh = arr_mesh; quad.MaterialOverride = cubeMaterial; // apply texture - rock, dirt, grass, etc. quad.MaterialOverride = cubeMaterial; // apply texture - rock, dirt, grass, etc. cube.AddChild(quad); // add quad to the cube node }
// public override MeshInstance CreateChunkMesh(ref ChunkStruct c) // { // // c.chunkData = SnappyCodec.Uncompress(c.compChunkData); // c.surfaceTool.Begin(Mesh.PrimitiveType.Triangles); // c.surfaceTool.SetMaterial(mat); // for (int i = 0; i < CHUNK_SIZE; i++) // { // for (int j = 0; j < CHUNK_SIZE; j++) // { // for (int k = 0; k < CHUNK_SIZE; k++) // { // if (c[i, j, k] == 0) // { // continue; // } // createFaces(i, j, k, c.Dx, c.Dy, c.Dz, ref c.surfaceTool, ref c); // } // } // } // c.surfaceTool.Index(); // MeshInstance mesh = new MeshInstance(); // mesh.SetMesh(c.surfaceTool.Commit()); // c.surfaceTool.Clear(); // // c.chunkData = new byte[1]; // return mesh; // } public override MeshInstance CreateChunkMesh(ref ChunkStruct c) { String startTime = DateTime.Now.ToString("HH:mm:ss:ffff"); byte[][] firstMask; byte[][] secondMask; MeshInstance mesh = new MeshInstance(); c.surfaceTool.Begin(Mesh.PrimitiveType.Triangles); c.surfaceTool.SetMaterial(mat); firstMask = new byte[CHUNK_SIZE][]; secondMask = new byte[CHUNK_SIZE][]; initializeJaggedArr(ref firstMask); initializeJaggedArr(ref secondMask); String initTime = DateTime.Now.ToString("HH:mm:ss:ffff"); for (int x = 0; x < CHUNK_SIZE; x++) { this.FillMasksWithLeftRight(ref c, x, ref firstMask, ref secondMask); this.FillWithQuads(firstMask, x, ref c, CreateLeftQuad); this.FillWithQuads(secondMask, x + 1, ref c, CreateRightQuad); } for (int y = 0; y < CHUNK_SIZE; y++) { this.FillMasksWithBottomTop(ref c, y, ref firstMask, ref secondMask); this.FillWithQuads(firstMask, y, ref c, CreateBottomQuad); this.FillWithQuads(secondMask, y + 1, ref c, CreateTopQuad); } for (int z = 0; z < CHUNK_SIZE; z++) { this.FillMasksWithBackFront(ref c, z, ref firstMask, ref secondMask); this.FillWithQuads(firstMask, z, ref c, CreateBackQuad); this.FillWithQuads(secondMask, z + 1, ref c, CreateFrontQuad); } String greedyMeshingTime = DateTime.Now.ToString("HH:mm:ss:ffff"); c.surfaceTool.Index(); mesh.SetMesh(c.surfaceTool.Commit()); c.surfaceTool.Clear(); String indexTime = DateTime.Now.ToString("HH:mm:ss:ffff"); Console.WriteLine("Curr Thread: {0}, StartTime: {1}, Initialization Time: {2}, Greedy Time: {3}, Index Time {4}", System.Threading.Thread.CurrentThread.ManagedThreadId, startTime , initTime, greedyMeshingTime, indexTime); return(mesh); }
public GroundNode(MeshInstance meshInstance) : base() { this.meshInstance = meshInstance; Godot.Collections.Array children = meshInstance.GetChildren(); foreach (var child in children) { if (child is CollisionObject collider) { collider.Connect("input_event", this, nameof(this.onInputEvent)); collider.Connect("mouse_entered", this, nameof(this.onMouseEntered)); collider.Connect("mouse_exited", this, nameof(this.onMouseExited)); break; } } // meshInstance.MaterialOverride = new }
public static Mesh Combine (MeshInstance[] combines, bool generateStrips) { int vertexCount = 0; int triangleCount = 0; int stripCount = 0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { vertexCount += combine.mesh.vertexCount; if (generateStrips) { #if UNITY_4_2 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 int curStripCount = combine.mesh.GetTriangleStrip(combine.subMeshIndex).Length; #endif #if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5 int curStripCount = combine.mesh.GetTriangles(combine.subMeshIndex).Length; #endif if (curStripCount != 0) { if( stripCount != 0 ) { if ((stripCount & 1) == 1 ) stripCount += 3; else stripCount += 2; } stripCount += curStripCount; } else { generateStrips = false; } } } } if (!generateStrips) { foreach( MeshInstance combine in combines ) { if (combine.mesh) { #if UNITY_4_2 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 triangleCount += combine.mesh.GetTriangleStrip(combine.subMeshIndex).Length; #endif #if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5 triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length; #endif } } } Vector3[] vertices = new Vector3[vertexCount] ; Vector3[] normals = new Vector3[vertexCount] ; Vector4[] tangents = new Vector4[vertexCount] ; Vector2[] uv = new Vector2[vertexCount]; Vector2[] uv1 = new Vector2[vertexCount]; Color[] colors = new Color[vertexCount]; int[] triangles = new int[triangleCount]; int[] strip = new int[stripCount]; int offset; offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose); } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose); } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.uv2, uv1, ref offset); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset); } int triangleOffset=0; int stripOffset=0; int vertexOffset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { if (generateStrips) { #if UNITY_4_2 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 int[] inputstrip = combine.mesh.GetTriangleStrip(combine.subMeshIndex); #endif #if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5 int[] inputstrip = combine.mesh.GetTriangles(combine.subMeshIndex); #endif if (stripOffset != 0) { if ((stripOffset & 1) == 1) { strip[stripOffset+0] = strip[stripOffset-1]; strip[stripOffset+1] = inputstrip[0] + vertexOffset; strip[stripOffset+2] = inputstrip[0] + vertexOffset; stripOffset+=3; } else { strip[stripOffset+0] = strip[stripOffset-1]; strip[stripOffset+1] = inputstrip[0] + vertexOffset; stripOffset+=2; } } for (int i=0;i<inputstrip.Length;i++) { strip[i+stripOffset] = inputstrip[i] + vertexOffset; } stripOffset += inputstrip.Length; } else { #if UNITY_4_2 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 int[] inputtriangles = combine.mesh.GetTriangleStrip(combine.subMeshIndex); #endif #if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5 int[] inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex); #endif for (int i=0;i<inputtriangles.Length;i++) { triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset; } triangleOffset += inputtriangles.Length; } vertexOffset += combine.mesh.vertexCount; } } Mesh mesh = new Mesh(); mesh.name = "Combined Mesh"; mesh.vertices = vertices; mesh.normals = normals; mesh.colors = colors; mesh.uv = uv; mesh.uv2 = uv1; mesh.tangents = tangents; if (generateStrips) #if UNITY_4_2 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 mesh.SetTriangleStrip(strip, 0); #endif #if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5 mesh.SetTriangles(strip, 0); #endif else mesh.triangles = triangles; return mesh; }
public static Mesh Combine(MeshInstance[] combines, bool generateStrips) { int vertexCount = 0; int triangleCount = 0; int stripCount = 0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { vertexCount += combine.mesh.vertexCount; if (generateStrips) { // SUBOPTIMAL FOR PERFORMANCE //int curStripCount = combine.mesh.GetTriangleStrip(combine.subMeshIndex).Length; int curStripCount = combine.mesh.GetTriangles(combine.subMeshIndex).Length; if (curStripCount != 0) { if( stripCount != 0 ) { if ((stripCount & 1) == 1 ) stripCount += 3; else stripCount += 2; } stripCount += curStripCount; } else { generateStrips = false; } } } } // Precomputed how many triangles we need instead if (!generateStrips) { foreach( MeshInstance combine in combines ) { if (combine.mesh) { triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length; } } } Vector3[] vertices = new Vector3[vertexCount] ; Vector3[] normals = new Vector3[vertexCount] ; Vector4[] tangents = new Vector4[vertexCount] ; Vector2[] uv = new Vector2[vertexCount]; Vector2[] uv1 = new Vector2[vertexCount]; Color[] colors = new Color[vertexCount]; int[] triangles = new int[triangleCount]; int[] strip = new int[stripCount]; int offset; offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose); } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose); } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.uv1, uv1, ref offset); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset); } int triangleOffset=0; int stripOffset=0; int vertexOffset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { if (generateStrips) { //int[] inputstrip = combine.mesh.GetTriangleStrip(combine.subMeshIndex); int[] inputstrip = combine.mesh.GetTriangles(combine.subMeshIndex); if (stripOffset != 0) { if ((stripOffset & 1) == 1) { strip[stripOffset+0] = strip[stripOffset-1]; strip[stripOffset+1] = inputstrip[0] + vertexOffset; strip[stripOffset+2] = inputstrip[0] + vertexOffset; stripOffset+=3; } else { strip[stripOffset+0] = strip[stripOffset-1]; strip[stripOffset+1] = inputstrip[0] + vertexOffset; stripOffset+=2; } } for (int i=0;i<inputstrip.Length;i++) { strip[i+stripOffset] = inputstrip[i] + vertexOffset; } stripOffset += inputstrip.Length; } else { int[] inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex); for (int i=0;i<inputtriangles.Length;i++) { triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset; } triangleOffset += inputtriangles.Length; } vertexOffset += combine.mesh.vertexCount; } } Mesh mesh = new Mesh(); mesh.name = "Combined Mesh"; mesh.vertices = vertices; mesh.normals = normals; mesh.colors = colors; mesh.uv = uv; mesh.uv1 = uv1; mesh.tangents = tangents; if (generateStrips) //mesh.SetTriangleStrip(strip, 0); mesh.SetTriangles(strip, 0); else mesh.triangles = triangles; return mesh; }
public static Mesh Combine(MeshInstance[] combines) { int vertexCount = 0; int triangleCount = 0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { vertexCount += combine.mesh.vertexCount; } } // Precomputed how many triangles we need instead foreach( MeshInstance combine in combines ) { if (combine.mesh) { triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length; } } Vector3[] vertices = new Vector3[vertexCount] ; Vector3[] normals = new Vector3[vertexCount] ; Vector4[] tangents = new Vector4[vertexCount] ; Vector2[] uv = new Vector2[vertexCount]; Vector2[] uv1 = new Vector2[vertexCount]; int offset; offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose); } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose); } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.uv1, uv1, ref offset); } int triangleOffset=0; int vertexOffset=0; int j=0; Mesh mesh = new Mesh(); mesh.vertices = vertices; mesh.normals = normals; mesh.uv = uv; mesh.uv1 = uv1; mesh.tangents = tangents; //Setting SubMeshes mesh.subMeshCount = combines.Length; foreach( MeshInstance combine in combines ) { int[] inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex); int[] trianglesx = new int[inputtriangles.Length]; for (int i=0;i<inputtriangles.Length;i++) { //triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset; trianglesx[i] = inputtriangles[i] + vertexOffset; } triangleOffset += inputtriangles.Length; mesh.SetTriangles(trianglesx,j++); vertexOffset += combine.mesh.vertexCount; } mesh.name = "Combined Mesh"; return mesh; }
public static MeshData ColorCombine(MeshInstance[] combines, out bool success) { int length = combines.Length; int vertexCount = 0; int triangleCount = 0; int maxVertices = 0; for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { int count = combines[combIndex].meshData.vertexCount; vertexCount += count; if (maxVertices < count) maxVertices = count; } } for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { triangleCount += combines[combIndex].meshData.triangles.Length; } } List<Vector3> vertices = new List<Vector3>(vertexCount); List<Vector3> normals = new List<Vector3>(vertexCount); List<Vector4> tangents = new List<Vector4>(vertexCount); List<Vector2> uvs = new List<Vector2>(vertexCount); List<Vector2> uv2s = new List<Vector2>(vertexCount); List<Color> colors = new List<Color>(vertexCount); Dictionary<int, int> indexTranslation = new Dictionary<int, int>(maxVertices); List<int> triangles = new List<int>(triangleCount); for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { int[] inputtriangles = combines[combIndex].meshData.triangles; var inputVertices = combines[combIndex].meshData.vertices; var inputNormals = combines[combIndex].meshData.normals; var inputUVs = combines[combIndex].meshData.uv; var inputColors = combines[combIndex].meshData.colors; var inputTangents = combines[combIndex].meshData.tangents; int copiedTriangles = 0; for (int i = 0; i < inputtriangles.Length; i += 3) { int vert0 = inputtriangles[i + 0]; int vert1 = inputtriangles[i + 1]; int vert2 = inputtriangles[i + 2]; if (((combines[combIndex].hiddenFaces & HiddenFaces.Up) == HiddenFaces.Up) && (inputVertices[vert0].y > topThreshold) && (inputVertices[vert1].y > topThreshold) && (inputVertices[vert2].y > topThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.Down) == HiddenFaces.Down) && (inputVertices[vert0].y < -topThreshold) && (inputVertices[vert1].y < -topThreshold) && (inputVertices[vert2].y < -topThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.North) == HiddenFaces.North) && (inputVertices[vert0].z > sideThreshold) && (inputVertices[vert1].z > sideThreshold) && (inputVertices[vert2].z > sideThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.South) == HiddenFaces.South) && (inputVertices[vert0].z < -sideThreshold) && (inputVertices[vert1].z < -sideThreshold) && (inputVertices[vert2].z < -sideThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.East) == HiddenFaces.East) && (inputVertices[vert0].x > sideThreshold) && (inputVertices[vert1].x > sideThreshold) && (inputVertices[vert2].x > sideThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.West) == HiddenFaces.West) && (inputVertices[vert0].x < -sideThreshold) && (inputVertices[vert1].x < -sideThreshold) && (inputVertices[vert2].x < -sideThreshold)) continue; int newVert0 = getIndex(indexTranslation, combines[combIndex], vert0, vertices, normals, tangents, uvs, uv2s, colors, inputVertices, inputNormals, inputTangents, inputUVs, inputColors); int newVert1 = getIndex(indexTranslation, combines[combIndex], vert1, vertices, normals, tangents, uvs, uv2s, colors, inputVertices, inputNormals, inputTangents, inputUVs, inputColors); int newVert2 = getIndex(indexTranslation, combines[combIndex], vert2, vertices, normals, tangents, uvs, uv2s, colors, inputVertices, inputNormals, inputTangents, inputUVs, inputColors); if (newVert0 > 65532 || newVert1 > 65532 || newVert2 > 65532) goto failure; triangles.Add(newVert0); triangles.Add(newVert1); triangles.Add(newVert2); copiedTriangles += 3; } } indexTranslation.Clear(); } success = true; return new MeshData( vertices: vertices.ToArray(), normals: normals.ToArray(), tangents: tangents.ToArray(), uv: uvs.ToArray(), uv2: uv2s.ToArray(), colors: colors.ToArray(), triangles: triangles.ToArray() ); failure: success = false; return new MeshData( vertices: vertices.ToArray(), normals: normals.ToArray(), tangents: tangents.ToArray(), uv: uvs.ToArray(), uv2: uv2s.ToArray(), colors: colors.ToArray(), triangles: triangles.ToArray() ); }
public static ControlCombineChildrenINfiniDyGrass.Meshy CombineM(int ID,List<int> Has_mesh,bool thread_started, MeshInstance[] combines, bool generateStrips, int vertexCount, int triangleCount,List<int> Combine_Mesh_vertexCount,List<Vector3[]> Combine_Mesh_vertices,List<Vector3[]> Combine_Mesh_normals,List<Vector4[]> Combine_Mesh_tangets, List<Vector2[]> Combine_Mesh_uv,List<Vector2[]> Combine_Mesh_uv1,List<Color[]> Combine_Mesh_colors,List<int[]> Combine_Mesh_triangles) { Vector3[] vertices = new Vector3[vertexCount] ; Vector3[] normals = new Vector3[vertexCount] ; Vector4[] tangents = new Vector4[vertexCount] ; Vector2[] uv = new Vector2[vertexCount]; Vector2[] uv1 = new Vector2[vertexCount]; Color[] colors = new Color[vertexCount]; int[] triangles = new int[triangleCount]; int offset; offset=0; int count = 0 ; foreach( MeshInstance combine in combines ) { if(Has_mesh[count] == 1){ Copy(Combine_Mesh_vertexCount[count], Combine_Mesh_vertices[count], vertices, ref offset, combine.transform); } count++; } offset=0; count = 0 ; foreach( MeshInstance combine in combines ) { //if (combine.mesh) if(Has_mesh[count] == 1) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyNormal(Combine_Mesh_vertexCount[count], Combine_Mesh_normals[count], normals, ref offset, invTranspose); count++; } } offset=0; count = 0 ; foreach( MeshInstance combine in combines ) { if(Has_mesh[count] == 1) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyTangents(Combine_Mesh_vertexCount[count], Combine_Mesh_tangets[count], tangents, ref offset, invTranspose); count++; } } offset=0; count = 0 ; //foreach( MeshInstance combine in combines ) for(int i =0;i< combines.Length;i++) { if(Has_mesh[count] == 1){ Copy(Combine_Mesh_vertexCount[count], Combine_Mesh_uv[count], uv, ref offset); } count++; } offset=0; count = 0 ; //foreach( MeshInstance combine in combines ) for(int i =0;i< combines.Length;i++) { if(Has_mesh[count] == 1){ Copy(Combine_Mesh_vertexCount[count], Combine_Mesh_uv1[count], uv1, ref offset); } count++; } offset=0; count = 0 ; //foreach( MeshInstance combine in combines ) for(int i =0;i< combines.Length;i++) { if(Has_mesh[count] == 1){ CopyColors(Combine_Mesh_vertexCount[count], Combine_Mesh_colors[count], colors, ref offset); } count++; } int triangleOffset=0; int vertexOffset=0; count = 0 ; //foreach( MeshInstance combine in combines ) for(int j =0;j< combines.Length;j++) { if(Has_mesh[count] == 1) { int[] inputtriangles = Combine_Mesh_triangles[count]; for (int i=0;i<inputtriangles.Length;i++) { triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset; } triangleOffset += inputtriangles.Length; vertexOffset += Combine_Mesh_vertexCount[count]; count++; } } //Mesh mesh = new Mesh(); ControlCombineChildrenINfiniDyGrass.Meshy mesh = new ControlCombineChildrenINfiniDyGrass.Meshy(); mesh.name = "Combined Mesh"; mesh.vertices = vertices; mesh.normals = normals; mesh.colors = colors; mesh.uv = uv; mesh.uv1 = uv1; mesh.tangents = tangents; mesh.triangles = triangles; //thread_started = false; mesh.thread_ended = true; //Debug.Log ("ID = "+ID); return mesh; }
public static Mesh Combine(MeshInstance[] combines, bool generateStrips) { int vertexCount = 0; int triangleCount = 0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { vertexCount += combine.mesh.vertexCount; } } // Precompute how many triangles we need foreach( MeshInstance combine in combines ) { if (combine.mesh) { triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length; } } Vector3[] vertices = new Vector3[vertexCount] ; Vector3[] normals = new Vector3[vertexCount] ; Vector4[] tangents = new Vector4[vertexCount] ; Vector2[] uv = new Vector2[vertexCount]; Vector2[] uv1 = new Vector2[vertexCount]; Color[] colors = new Color[vertexCount]; int[] triangles = new int[triangleCount]; int offset; offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose); } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose); } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.uv2, uv1, ref offset); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset); } int triangleOffset=0; int vertexOffset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { int[] inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex); for (int i=0;i<inputtriangles.Length;i++) { triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset; } triangleOffset += inputtriangles.Length; vertexOffset += combine.mesh.vertexCount; } } Mesh mesh = new Mesh(); mesh.name = "Combined Mesh"; mesh.vertices = vertices; mesh.normals = normals; mesh.colors = colors; mesh.uv = uv; mesh.uv2 = uv1; mesh.tangents = tangents; mesh.triangles = triangles; return mesh; }
/// <summary> /// Combines the specified sm renderers. /// </summary> public void Combine(SkinnedMeshRenderer resultTarget, SkinnedMeshRenderer[] smRenderers) { if (smRenderers == null || smRenderers.Length == 0) { Debug.LogWarning("Combine skinned mesh: child renderers are null or empty"); return; } //Debug.Log("Combine skinned mesh: child " + smRenderers.Length ); // Temp values int modeDuplicate_boneOffset = 0; // for CombineMode.SharedBoneBindpose // Iterate all sub renderers for (int i = 0; i < smRenderers.Length; i++) { //Getting one by one SkinnedMeshRenderer smRenderer = smRenderers[i]; // Making changes to the Skinned Renderer MeshInstance instance = new MeshInstance(); // Setting the Mesh for the instance instance.mesh = smRenderer.sharedMesh; // Getting all materials Material[] sharedMaterials = smRenderer.sharedMaterials; for (int t = 0; t < sharedMaterials.Length; t++) materials.Add(sharedMaterials[t]); // if (smRenderer != null && smRenderer.sharedMesh != null) { //instance.transform = Matrix4x4.identity; // myTransform /*transform.worldToLocalMatrix */ * smRenderer.transform.localToWorldMatrix; //Getting subMesh for (int t = 0; t < smRenderer.sharedMesh.subMeshCount; t++) { instance.subMeshIndex = t; meshInstances.Add(instance); } //Copying Bones Transform[] smBones = smRenderer.bones; Matrix4x4[] smBindposes = smRenderer.sharedMesh.bindposes; BoneWeight[] smBoneweights = smRenderer.sharedMesh.boneWeights; switch (optimizeType) { case CombineMode.CalculateOverlappedBoneBindpose: { //Copying Bones for (int b = 0; b < smBones.Length; b++) { // New bone/bindpose combination SharedBoneBindpose sharedBoneBindpose = sharedGroups.Find(smBones[b], smBindposes[b]); if (sharedBoneBindpose != null) continue; // Create new bone/bindpose sharedBoneBindpose = sharedGroups.Create(smBones[b], smBindposes[b], bones.Count); //inserting bones in totalBones bones.Add(smBones[b]); //Recalculating BindPoses bindposes.Add(smBindposes[b]); //totalBindPoses[offset] = smRenderer.bones[x].worldToLocalMatrix * transform.localToWorldMatrix; } //RecalculateBoneWeights for (int bw = 0; bw < smBoneweights.Length; bw++) { //Just Copying and changing the Bones Indexes !! boneWeights.Add(RecalculateBoneIndexes(smBoneweights[bw], sharedGroups, smBones, smBindposes)); } } break; case CombineMode.SharedBoneBindpose: { //Copying Bones for (int b = 0; b < smBones.Length; b++) { // New bone/bindpose combination if (boneIndexLookup.ContainsKey(smBones[b])) continue; // Add to lookup boneIndexLookup.Add(smBones[b], bones.Count); //inserting bones in totalBones bones.Add(smBones[b]); //Recalculating BindPoses bindposes.Add(smBindposes[b]); } //RecalculateBoneWeights for (int bw = 0; bw < smBoneweights.Length; bw++) { //Just Copying and changing the Bones Indexes !! boneWeights.Add(RecalculateBoneIndexes(smBoneweights[bw], boneIndexLookup, smBones, smBindposes)); } } break; case CombineMode.DuplicateBoneBindpose: { // May want to modify this if the renderer shares bones as unnecessary bones will get added. foreach (BoneWeight bw in smBoneweights) { BoneWeight _bw = bw; _bw.boneIndex0 += modeDuplicate_boneOffset; _bw.boneIndex1 += modeDuplicate_boneOffset; _bw.boneIndex2 += modeDuplicate_boneOffset; _bw.boneIndex3 += modeDuplicate_boneOffset; boneWeights.Add(_bw); } modeDuplicate_boneOffset += smBones.Length; foreach (Transform bone in smBones) bones.Add(bone); for (int b = 0; b < smBones.Length; b++) { bindposes.Add(smBindposes[b]); // bones[b].worldToLocalMatrix * transform.localToWorldMatrix); } } break; } // Disabling current SkinnedMeshRenderer EndCombineChildRenderer(smRenderer); } } // Build final mesh Build(resultTarget); }
private IVertexRenderer<TexturedColouredVertex4> GetRendererFor(MeshInstance meshInstance) { IVertexRenderer<TexturedColouredVertex4> renderer; if (_vertexRenderers.TryGetValue(meshInstance.TriangleCount, out renderer)) { return renderer; } renderer = _graphicsContext.CreateVertexRenderer<TexturedColouredVertex4>(meshInstance.TriangleCount * 3); _vertexRenderers[meshInstance.TriangleCount] = renderer; return renderer; }
public static MeshData ColorCombine(MeshInstance[] combines, out bool success) { int length = combines.Length; int vertexCount = 0; int triangleCount = 0; for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { vertexCount += combines[combIndex].meshData.vertexCount; } } if(vertexCount > 65535) { //Debug.LogError("Combined mesh would have " + vertexCount + " vertices. Should not be more than 65535"); success = false; return null; } // Precomputed how many triangles we need instead for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { triangleCount += combines[combIndex].meshData.triangles.Length; } } Vector3[] vertices = new Vector3[vertexCount]; Vector3[] normals = new Vector3[vertexCount]; Vector4[] tangents = new Vector4[vertexCount]; Vector2[] uv = new Vector2[vertexCount]; Vector2[] uv2 = new Vector2[vertexCount]; Color[] colors = new Color[vertexCount]; List<int> triangles = new List<int>(); triangles.Capacity = triangleCount; int offset; offset = 0; for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) Copy(combines[combIndex].meshData.vertexCount, combines[combIndex].meshData.vertices, vertices, ref offset, combines[combIndex].transform); } offset = 0; for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { Matrix4x4 invTranspose = combines[combIndex].transform; invTranspose = invTranspose.inverse.transpose; CopyNormal(combines[combIndex].meshData.vertexCount, combines[combIndex].meshData.normals, normals, ref offset, invTranspose); } } offset = 0; for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { Matrix4x4 invTranspose = combines[combIndex].transform; invTranspose = invTranspose.inverse.transpose; CopyTangents(combines[combIndex].meshData.vertexCount, combines[combIndex].meshData.tangents, tangents, ref offset, invTranspose); } } offset = 0; for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { Copy(combines[combIndex].meshData.vertexCount, combines[combIndex].meshData.uv, uv, ref offset, combines[combIndex].uv1Transform); } } offset = 0; for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { Copy(combines[combIndex].meshData.vertexCount, combines[combIndex].meshData.uv, uv2, ref offset, combines[combIndex].uv2Transform); } } offset = 0; for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) CopyColors(combines[combIndex].meshData.vertexCount, combines[combIndex].meshData.colors, colors, ref offset, combines[combIndex].color); } int triangleOffset = 0; int vertexOffset = 0; for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { int[] inputtriangles = combines[combIndex].meshData.triangles; var inputVertices = combines[combIndex].meshData.vertices; int copiedTriangles = 0; for (int i = 0; i < inputtriangles.Length; i += 3) { int vert0 = inputtriangles[i + 0]; int vert1 = inputtriangles[i + 1]; int vert2 = inputtriangles[i + 2]; if (((combines[combIndex].hiddenFaces & HiddenFaces.Up) == HiddenFaces.Up) && (inputVertices[vert0].y > topThreshold) && (inputVertices[vert1].y > topThreshold) && (inputVertices[vert2].y > topThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.Down) == HiddenFaces.Down) && (inputVertices[vert0].y < -topThreshold) && (inputVertices[vert1].y < -topThreshold) && (inputVertices[vert2].y < -topThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.North) == HiddenFaces.North) && (inputVertices[vert0].z > sideThreshold) && (inputVertices[vert1].z > sideThreshold) && (inputVertices[vert2].z > sideThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.South) == HiddenFaces.South) && (inputVertices[vert0].z < -sideThreshold) && (inputVertices[vert1].z < -sideThreshold) && (inputVertices[vert2].z < -sideThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.East) == HiddenFaces.East) && (inputVertices[vert0].x > sideThreshold) && (inputVertices[vert1].x > sideThreshold) && (inputVertices[vert2].x > sideThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.West) == HiddenFaces.West) && (inputVertices[vert0].x < -sideThreshold) && (inputVertices[vert1].x < -sideThreshold) && (inputVertices[vert2].x < -sideThreshold)) continue; triangles.Add(vert0 + vertexOffset); triangles.Add(vert1 + vertexOffset); triangles.Add(vert2 + vertexOffset); copiedTriangles += 3; } triangleOffset += copiedTriangles; vertexOffset += combines[combIndex].meshData.vertexCount; } } success = true; return new MeshData( vertices: vertices, normals: normals, tangents: tangents, uv: uv, uv2: uv2, colors: colors, triangles: triangles.ToArray() ); }
public static Mesh Combine (MeshInstance[] combines, bool generateStrips) { int vertexCount = 0; int triangleCount = 0; int stripCount = 0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { vertexCount += combine.mesh.vertexCount; if (generateStrips) { int curStripCount = combine.mesh.GetTriangleStrip(combine.subMeshIndex).Length; // int curStripCount = combine.mesh.GetTriangles(combine.subMeshIndex).Length if (curStripCount != 0) { if( stripCount != 0 ) { if ((stripCount & 1) == 1 ) stripCount += 3; else stripCount += 2; } stripCount += curStripCount; } else { generateStrips = false; } } } } if (!generateStrips) { foreach( MeshInstance combine in combines ) { if (combine.mesh) { triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length; } } } Vector3[] vertices = new Vector3[vertexCount] ; Vector3[] normals = new Vector3[vertexCount] ; Vector4[] tangents = new Vector4[vertexCount] ; Vector2[] uv = new Vector2[vertexCount]; Vector2[] uv1 = new Vector2[vertexCount]; int[] triangles = new int[triangleCount]; int[] strip = new int[stripCount]; int offset; System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose); } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose); } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.uv1, uv1, ref offset); } int triangleOffset=0; int stripOffset=0; int vertexOffset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { if (generateStrips) { int[] inputstrip = combine.mesh.GetTriangleStrip(combine.subMeshIndex); //int[] inputstrip = combine.mesh.GetTriangles(combine.subMeshIndex); if (stripOffset != 0) { if ((stripOffset & 1) == 1) { strip[stripOffset+0] = strip[stripOffset-1]; strip[stripOffset+1] = inputstrip[0] + vertexOffset; strip[stripOffset+2] = inputstrip[0] + vertexOffset; stripOffset+=3; } else { strip[stripOffset+0] = strip[stripOffset-1]; strip[stripOffset+1] = inputstrip[0] + vertexOffset; stripOffset+=2; } } for (int i=0;i<inputstrip.Length;i++) { strip[i+stripOffset] = inputstrip[i] + vertexOffset; } stripOffset += inputstrip.Length; } else { int[] inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex); for (int i=0;i<inputtriangles.Length;i++) { triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset; } triangleOffset += inputtriangles.Length; } vertexOffset += combine.mesh.vertexCount; } } Mesh mesh = new Mesh(); mesh.name = "Combined Mesh"; mesh.vertices = vertices; mesh.normals = normals; mesh.tangents = tangents; mesh.uv = uv; mesh.uv1 = uv1; if (generateStrips) mesh.SetTriangleStrip(strip, 0); else mesh.triangles = triangles; sw.Stop(); Mogo.Util.LoggerHelper.Debug("Combine Mesh cost: " + sw.ElapsedMilliseconds); return mesh; }
internal static Mesh InternalCombineVertices(MeshInstance[] meshes, string meshName){}
public static Mesh[] Combine(MeshInstance[] combines) { int vertexCount = 0; int triangleCount = 0; for (int i = 0; i < combines.Length; i++) { if (combines [i].mesh != null) { vertexCount += combines [i].mesh.vertexCount; triangleCount += combines [i].mesh.GetTriangles(combines [i].subMeshIndex).Length; } } int indexOffset = 0; int numOfSplits = Mathf.CeilToInt(vertexCount / 60000.0f); int vertsPerSplit = vertexCount / numOfSplits; List<Mesh> meshSplits = new List<Mesh>(); for (int i = 1; i <= numOfSplits; i++) { List<Vector3> vertices = new List<Vector3>(vertsPerSplit); List<Vector3> normals = new List<Vector3>(vertsPerSplit); List<Vector4> tangents = new List<Vector4>(vertsPerSplit); List<Vector2> uv = new List<Vector2>(vertsPerSplit); List<Vector2> uv1 = new List<Vector2>(vertsPerSplit); List<Vector2> uv2 = new List<Vector2>(vertsPerSplit); List<Color> colors = new List<Color>(vertsPerSplit); List<int> triangles = new List<int>(triangleCount / numOfSplits); int vertexOffset = 0; while (indexOffset < combines.Length && vertexOffset <= vertsPerSplit) { if (combines [indexOffset].mesh != null) { Copy(combines [indexOffset].mesh.vertices, vertices, combines [indexOffset].transform); Matrix4x4 invTranspose = combines [indexOffset].transform; invTranspose = invTranspose.inverse.transpose; CopyNormal(combines [indexOffset].mesh.normals, normals, invTranspose); CopyTangents(combines [indexOffset].mesh.tangents, tangents, invTranspose); Copy(combines [indexOffset].mesh.uv, uv); Copy(combines [indexOffset].mesh.uv1, uv1); Copy(combines [indexOffset].mesh.uv2, uv2); if (combines [indexOffset].mesh.colors.Length == combines [indexOffset].mesh.vertexCount) { CopyColors(combines [indexOffset].mesh.colors, colors); } else { Color[] newColors = new Color[combines [indexOffset].mesh.vertexCount]; for (int x = 0; x < newColors .Length; x++) { newColors [x] = Color.white; } CopyColors(newColors, colors); } CopyTriangles(combines [indexOffset].mesh.GetTriangles(combines [indexOffset].subMeshIndex), triangles, vertexOffset); vertexOffset += combines [indexOffset].mesh.vertexCount; } indexOffset++; } Mesh mesh = new Mesh(); mesh.name = "Combined Mesh"; mesh.vertices = vertices.ToArray(); mesh.normals = normals.ToArray(); mesh.colors = colors.ToArray(); mesh.uv = uv.ToArray(); mesh.uv1 = uv1.ToArray(); mesh.uv2 = uv2.ToArray(); mesh.tangents = tangents.ToArray(); mesh.triangles = triangles.ToArray(); meshSplits.Add(mesh); } return meshSplits.ToArray(); }
public static Mesh Combine (MeshInstance[] combines, bool bakeGroundLightingGrass, bool bakeGroundLightingFoliage, float randomBrightness, float randomPulse, float randomBending, float randomFluttering, Color HealthyColor, Color DryColor, float NoiseSpread, bool bakeScale, bool simplyCombine, float NoiseSpreadFoliage, bool createUniqueUV2, bool useUV4 ) { int vertexCount = 0; int triangleCount = 0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { vertexCount += combine.mesh.vertexCount; triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length; } } Vector3[] vertices = new Vector3[vertexCount] ; Vector3[] normals = new Vector3[vertexCount] ; Vector4[] tangents = new Vector4[vertexCount] ; Vector2[] uv = new Vector2[vertexCount]; // Vector2[] uv1 = new Vector2[vertexCount]; Color[] colors = new Color[vertexCount]; // Vector2[] uv4 = new Vector2[vertexCount]; int[] triangles = new int[triangleCount]; int offset; offset=0; bool copyUV4 = false; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform); } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; //if (bakeGroundLightingGrassTrans) { // CopyNormalGroundTrans (combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose, combine.groundNormal); //} if (bakeGroundLightingGrass) { CopyNormalGround (combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose, combine.groundNormal); } //else if (!bakeGroundLightingGrassTrans) { else { CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose); } } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose); } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset); } offset=0; // only needed when using the foliage shader ground lighting version if (bakeGroundLightingFoliage) { foreach( MeshInstance combine in combines ) { if (combine.mesh) Copy_uv1(combine.mesh.vertexCount, combine.mesh.uv, uv1, ref offset, new Vector2(combine.groundNormal.x, combine.groundNormal.z)); } offset=0; } // Copy uv4 foreach( MeshInstance combine in combines ) { if (combine.mesh.uv4 != null && useUV4) { //Debug.Log("UV4 found"); copyUV4 = true; Copy_uv4(combine.mesh.vertexCount, combine.mesh.uv4, uv4, ref offset, combine.scale, bakeScale, combine.pivot, NoiseSpreadFoliage, randomBending); } } offset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { // either add healthy and dry colors (grass shader) if (bakeGroundLightingGrass) { CopyColors_grass(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset, HealthyColor, DryColor, NoiseSpread, combine.pivot ); } // or simply add random color to create more variety (r,a and b) and bake scale else { //CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset, new Color (Random.Range(0.0f, randomPulse), Random.Range(-randomFluttering, randomFluttering), Random.Range(-randomBending, randomBending), Random.Range(randomBrightness, -randomBrightness)), combine.scale, bakeScale); CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset, combine.scale, bakeScale, combine.pivot, NoiseSpreadFoliage, randomPulse, randomFluttering, randomBrightness, randomBending, copyUV4); } } } int triangleOffset=0; int vertexOffset=0; foreach( MeshInstance combine in combines ) { if (combine.mesh) { int[] inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex); for (int i=0;i<inputtriangles.Length;i++) { triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset; } triangleOffset += inputtriangles.Length; vertexOffset += combine.mesh.vertexCount; // Clean up inputtriangles = null; } } Mesh mesh = new Mesh(); mesh.name = "Combined Mesh"; mesh.vertices = vertices; mesh.normals = normals; mesh.colors = colors; mesh.uv = uv; // only needed for foliage shader, skip it on grass and plants using the regular shader if (bakeGroundLightingFoliage) { mesh.uv2 = uv1; } if (copyUV4) { mesh.uv4 = uv4; } mesh.tangents = tangents; mesh.triangles = triangles; mesh.Optimize(); #if UNITY_EDITOR if(createUniqueUV2 && !bakeGroundLightingFoliage) { Unwrapping.GenerateSecondaryUVSet(mesh); } #endif // Clean up vertices = null; normals = null; tangents = null; uv = null; uv1 = null; colors = null; triangles = null; return mesh; }
private static int getIndex(Dictionary<int, int> indexTranslation, MeshInstance meshInstance, int inputVert, List<Vector3> vertices, List<Vector3> normals, List<Vector4> tangents, List<Vector2> uvs, List<Vector2> uv2s, List<Vector2> uv3s, List<Color> colors, Vector3[] inputVertices, Vector3[] inputNormals, Vector4[] inputTangents, Vector2[] inputUVs, Color[] inputColors, Vector2? uv2Force, Vector2? uv3Force) { int newVert; if (indexTranslation.ContainsKey(inputVert)) { newVert = indexTranslation[inputVert]; } else { newVert = vertices.Count; indexTranslation[inputVert] = newVert; vertices.Add(meshInstance.transform.MultiplyPoint(inputVertices[inputVert])); Matrix4x4 invTranspose = meshInstance.transform; invTranspose = invTranspose.inverse.transpose; normals.Add(invTranspose.MultiplyVector(inputNormals[inputVert]).normalized); Vector4 p4 = inputTangents[inputVert]; Vector3 p = new Vector3(p4.x, p4.y, p4.z); p = invTranspose.MultiplyVector(p).normalized; tangents.Add(invTranspose.MultiplyVector(new Vector4(p.x, p.y, p.z, p4.w))); uvs.Add(meshInstance.uv1Transform.MultiplyPoint(inputUVs[inputVert])); if (!uv2Force.HasValue) uv2s.Add(meshInstance.uv2Transform.MultiplyPoint(inputUVs[inputVert])); else uv2s.Add(uv2Force.Value); if (!uv3Force.HasValue) uv3s.Add(meshInstance.uv3Transform.MultiplyPoint(inputUVs[inputVert])); else uv3s.Add(uv3Force.Value); if (inputColors.Length > 0) colors.Add(meshInstance.color * inputColors[inputVert]); else colors.Add(meshInstance.color); } return newVert; }
/// <summary> /// Event raised by the planet when a new surface is generated. /// If enabled, adds SurfaceObjects component to the Surface and populates it with objects /// </summary> public void OnSurfaceGenerated(Surface surface) { for(int f = 0; f < foliageTypes.Length; f++) { if(surface.lodLevel == foliageTypes[f].lodLevel) { // create new list MeshInstanceList mil = new MeshInstanceList(); mil.meshInstances = new List<MeshInstance>(); // save surface reference and listen for its destruction mil.surface = surface; surface.SurfaceDestroyed += SurfaceDestroyed; // get mesh Vector3[] vertices = surface.mesh.vertices; Vector3[] normals = surface.mesh.normals; Color[] colors = surface.mesh.colors; Vector3 right = Vector3.zero; //, perpendicular = Vector3.one, normalized = Vector3.zero; //float vertexDistance = 0f; for(int i = 0; i < vertices.Length; i++) { if(i + 1 < vertices.Length) { right = vertices[i] - vertices[i+1]; //vertexDistance = right.magnitude; right.Normalize(); } if(colors[i].r >= foliageTypes[f].minHeight && colors[i].r <= foliageTypes[f].maxHeight && colors[i].g >= foliageTypes[f].minPolarity && colors[i].g <= foliageTypes[f].maxPolarity && colors[i].b >= foliageTypes[f].minSlope && colors[i].b <= foliageTypes[f].maxSlope ) { float terrainValue = terrainModule.module.GetValue(vertices[i].normalized); if(terrainValue >= foliageTypes[f].minNoiseValue && terrainValue <= foliageTypes[f].maxNoiseValue) { MeshInstance newInstance = new MeshInstance(); Vector3 vertex = planet.transform.TransformPoint(vertices[i]); Vector3 normal = planet.transform.TransformDirection(normals[i]); /*if(foliageTypes[f].positionVariation != Vector3.zero) { normalized = vertices[i].normalized; perpendicular = Vector3.Cross(right, normalized); newInstance.position += right * vertexDistance * Random.Range(-foliageTypes[f].positionVariation.x, foliageTypes[f].positionVariation.x); newInstance.position += normalized * vertexDistance * Random.Range(-foliageTypes[f].positionVariation.y, foliageTypes[f].positionVariation.y); newInstance.position += perpendicular * vertexDistance * Random.Range(-foliageTypes[f].positionVariation.z, foliageTypes[f].positionVariation.z); }*/ Quaternion adjustedRotation; if(foliageTypes[f].useGroundNormalAsUp) adjustedRotation = Quaternion.LookRotation(normal); else adjustedRotation = Quaternion.LookRotation(vertex.normalized); adjustedRotation *= Quaternion.Euler(foliageTypes[f].rotation); adjustedRotation *= Quaternion.Euler(new Vector3(Random.Range(-foliageTypes[f].rotationVariation.x, foliageTypes[f].rotationVariation.x), Random.Range(-foliageTypes[f].rotationVariation.y, foliageTypes[f].rotationVariation.y), Random.Range(-foliageTypes[f].rotationVariation.z, foliageTypes[f].rotationVariation.z))); Vector3 adjustedScale = foliageTypes[f].scale * (1f + foliageTypes[f].scaleVariation * Random.Range(0f, 1f)); newInstance.position = vertex; newInstance.scale = adjustedScale; newInstance.matrix = new Matrix4x4(); newInstance.matrix.SetTRS(newInstance.position, adjustedRotation, adjustedScale); newInstance.mesh = foliageTypes[f].mesh; newInstance.materials = foliageTypes[f].materials; newInstance.layer = foliageTypes[f].meshLayer; newInstance.castShadows = foliageTypes[f].castShadows; newInstance.receiveShadows = foliageTypes[f].receiveShadows; mil.meshInstances.Add(newInstance); } } } // add list to other lists foliageTypes[f].meshLists.Add(mil); } } }
public static CPUMesh ColorCombine(MeshInstance[] combines, out bool success, bool topLayer = false, CPUMesh sourceMesh = null) { int length = combines.Length; int vertexCount = 0; int triangleCount = 0; int maxVertices = 0; for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { int count = combines[combIndex].meshData.vertexCount; vertexCount += count; if (maxVertices < count) maxVertices = count; } } for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { triangleCount += combines[combIndex].meshData.triangles.Length; } } List<Vector3> vertices = new List<Vector3>(vertexCount); List<Vector3> normals = new List<Vector3>(vertexCount); List<Vector4> tangents = new List<Vector4>(vertexCount); List<Vector2> uvs = new List<Vector2>(vertexCount); List<Vector2> uv2s = new List<Vector2>(vertexCount); List<Vector2> uv3s = new List<Vector2>(vertexCount); List<Color> colors = new List<Color>(vertexCount); List<int> triangles = new List<int>(triangleCount); if ( sourceMesh != null && sourceMesh.vertices != null && sourceMesh.vertices.Length != 0 && sourceMesh.triangles != null && sourceMesh.triangles.Length != 0) { vertices.AddRange(sourceMesh.vertices); if (sourceMesh.normals != null) normals.AddRange(sourceMesh.normals); else normals.AddRange(new Vector3[sourceMesh.vertices.Length]); if (sourceMesh.tangents != null) tangents.AddRange(sourceMesh.tangents); else tangents.AddRange(new Vector4[sourceMesh.vertices.Length]); if (sourceMesh.uv != null) uvs.AddRange(sourceMesh.uv); else uvs.AddRange(new Vector2[sourceMesh.vertices.Length]); if (sourceMesh.uv2 != null) uv2s.AddRange(sourceMesh.uv2); else uv2s.AddRange(new Vector2[sourceMesh.vertices.Length]); if (sourceMesh.uv3 != null) uv3s.AddRange(sourceMesh.uv3); else uv3s.AddRange(new Vector2[sourceMesh.vertices.Length]); if (sourceMesh.colors != null) colors.AddRange(sourceMesh.colors); else colors.AddRange(new Color[sourceMesh.vertices.Length]); triangles.AddRange(sourceMesh.triangles); } Dictionary<int, int> indexTranslation = new Dictionary<int, int>(maxVertices); for (int combIndex = 0; combIndex < length; combIndex++) { if (combines[combIndex].meshData != null) { int[] inputtriangles = combines[combIndex].meshData.triangles; var inputVertices = combines[combIndex].meshData.vertices; var inputNormals = combines[combIndex].meshData.normals; var inputUVs = combines[combIndex].meshData.uv; var inputColors = combines[combIndex].meshData.colors; var inputTangents = combines[combIndex].meshData.tangents; for (int i = 0; i < inputtriangles.Length; i += 3) { int vert0 = inputtriangles[i + 0]; int vert1 = inputtriangles[i + 1]; int vert2 = inputtriangles[i + 2]; if (topLayer) { if (!(((combines[combIndex].hiddenFaces & HiddenFaces.Up) == HiddenFaces.Up) && (inputVertices[vert0].y > topThreshold) && (inputVertices[vert1].y > topThreshold) && (inputVertices[vert2].y > topThreshold))) continue; } else { if (((combines[combIndex].hiddenFaces & HiddenFaces.Up) == HiddenFaces.Up) && (inputVertices[vert0].y > topThreshold) && (inputVertices[vert1].y > topThreshold) && (inputVertices[vert2].y > topThreshold)) continue; } if (((combines[combIndex].hiddenFaces & HiddenFaces.Down) == HiddenFaces.Down) && (inputVertices[vert0].y < -topThreshold) && (inputVertices[vert1].y < -topThreshold) && (inputVertices[vert2].y < -topThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.North) == HiddenFaces.North) && (inputVertices[vert0].z > sideThreshold) && (inputVertices[vert1].z > sideThreshold) && (inputVertices[vert2].z > sideThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.South) == HiddenFaces.South) && (inputVertices[vert0].z < -sideThreshold) && (inputVertices[vert1].z < -sideThreshold) && (inputVertices[vert2].z < -sideThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.East) == HiddenFaces.East) && (inputVertices[vert0].x > sideThreshold) && (inputVertices[vert1].x > sideThreshold) && (inputVertices[vert2].x > sideThreshold)) continue; if (((combines[combIndex].hiddenFaces & HiddenFaces.West) == HiddenFaces.West) && (inputVertices[vert0].x < -sideThreshold) && (inputVertices[vert1].x < -sideThreshold) && (inputVertices[vert2].x < -sideThreshold)) continue; int newVert0 = getIndex(indexTranslation, combines[combIndex], vert0, vertices, normals, tangents, uvs, uv2s, uv3s, colors, inputVertices, inputNormals, inputTangents, inputUVs, inputColors, combines[combIndex].uv2Force, combines[combIndex].uv3Force); int newVert1 = getIndex(indexTranslation, combines[combIndex], vert1, vertices, normals, tangents, uvs, uv2s, uv3s, colors, inputVertices, inputNormals, inputTangents, inputUVs, inputColors, combines[combIndex].uv2Force, combines[combIndex].uv3Force); int newVert2 = getIndex(indexTranslation, combines[combIndex], vert2, vertices, normals, tangents, uvs, uv2s, uv3s, colors, inputVertices, inputNormals, inputTangents, inputUVs, inputColors, combines[combIndex].uv2Force, combines[combIndex].uv3Force); if (newVert0 > 65531 || newVert1 > 65531 || newVert2 > 65531) goto failure; triangles.Add(newVert0); triangles.Add(newVert1); triangles.Add(newVert2); } } indexTranslation.Clear(); } success = true; return new CPUMesh( vertices: vertices.ToArray(), normals: normals.ToArray(), tangents: tangents.ToArray(), uv: uvs.ToArray(), uv2: uv2s.ToArray(), uv3: uv3s.ToArray(), colors: colors.ToArray(), triangles: triangles.ToArray() ); failure: success = false; return new CPUMesh( vertices: vertices.ToArray(), normals: normals.ToArray(), tangents: tangents.ToArray(), uv: uvs.ToArray(), uv2: uv2s.ToArray(), uv3: uv3s.ToArray(), colors: colors.ToArray(), triangles: triangles.ToArray() ); }
public static Mesh Combine(MeshInstance[] combines, bool generateStrips) { int vertexCount = 0; int triangleCount = 0; int stripCount = 0; foreach (MeshInstance combine in combines) { if (combine.mesh) { vertexCount += combine.mesh.vertexCount; if (generateStrips) { // SUBOPTIMAL FOR PERFORMANCE int curStripCount = combine.mesh.GetTriangleStrip(combine.subMeshIndex).Length; if (curStripCount != 0) { if (stripCount != 0) { if ((stripCount & 1) == 1) { stripCount += 3; } else { stripCount += 2; } } stripCount += curStripCount; } else { generateStrips = false; } } } } // Precomputed how many triangles we need instead if (!generateStrips) { foreach (MeshInstance combine in combines) { if (combine.mesh) { triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length; } } } var vertices = new Vector3[vertexCount]; var normals = new Vector3[vertexCount]; var tangents = new Vector4[vertexCount]; var uv = new Vector2[vertexCount]; var uv1 = new Vector2[vertexCount]; var colors = new Color[vertexCount]; var triangles = new int[triangleCount]; var strip = new int[stripCount]; int offset; int offsetUv; float sizeUv; int row; offset = 0; foreach (MeshInstance combine in combines) { if (combine.mesh) { Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform); } } offset = 0; foreach (MeshInstance combine in combines) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose); } } offset = 0; foreach (MeshInstance combine in combines) { if (combine.mesh) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose); } } offset = 0; foreach (MeshInstance combine in combines) { if (combine.mesh) { Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset); } } offset = 0; offsetUv = 0; row = (int) Mathf.Ceil(Mathf.Sqrt(combines.Length)); sizeUv = (float) 1 / row; foreach (MeshInstance combine in combines) { if (combine.mesh) { CopyUv(combine.mesh.vertexCount, combine.mesh.uv1, uv1, sizeUv, row, ref offset, ref offsetUv); } } offset = 0; foreach (MeshInstance combine in combines) { if (combine.mesh) { CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset); } } int triangleOffset = 0; int stripOffset = 0; int vertexOffset = 0; foreach (MeshInstance combine in combines) { if (combine.mesh) { if (generateStrips) { int[] inputstrip = combine.mesh.GetTriangleStrip(combine.subMeshIndex); if (stripOffset != 0) { if ((stripOffset & 1) == 1) { strip[stripOffset + 0] = strip[stripOffset - 1]; strip[stripOffset + 1] = inputstrip[0] + vertexOffset; strip[stripOffset + 2] = inputstrip[0] + vertexOffset; stripOffset += 3; } else { strip[stripOffset + 0] = strip[stripOffset - 1]; strip[stripOffset + 1] = inputstrip[0] + vertexOffset; stripOffset += 2; } } for (int i = 0; i < inputstrip.Length; i++) { strip[i + stripOffset] = inputstrip[i] + vertexOffset; } stripOffset += inputstrip.Length; } else { int[] inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex); for (int i = 0; i < inputtriangles.Length; i++) { triangles[i + triangleOffset] = inputtriangles[i] + vertexOffset; } triangleOffset += inputtriangles.Length; } vertexOffset += combine.mesh.vertexCount; } } var mesh = new Mesh(); mesh.name = "Combined Mesh"; mesh.vertices = vertices; mesh.normals = normals; mesh.colors = colors; mesh.uv = uv; mesh.uv1 = uv1; mesh.tangents = tangents; if (generateStrips) { mesh.SetTriangleStrip(strip, 0); } else { mesh.triangles = triangles; } return mesh; }