Godot Version
v4.4.stable.mono.official [4c311cbee]
Question
I used ArrayMesh in a MeshInstance3D.And I write a c# script to load a mesh.I use Visual Studio to build it.But the mesh position is very different in Debug and ExportRelease build mode.
the script is:
using Godot;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public partial class MyMeshInstance3d : MeshInstance3D
{
List<Vector3> verts = [];
List<int> indices = [];
Godot.Collections.Array surfaceArray = [];
public override void _Ready()
{
try
{
surfaceArray.Resize((int)Mesh.ArrayType.Max);
//"box4" is a abaqus inp file containing verts and indices
ConstructFromFile("box4");
//They do almost same thing,only some rounding errors
// ConstructFromFile2("box4");
surfaceArray[(int)Mesh.ArrayType.Vertex] = verts.ToArray();
surfaceArray[(int)Mesh.ArrayType.Index] = indices.ToArray();
var arrMesh = Mesh as ArrayMesh;
arrMesh?.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, surfaceArray);
}
catch (System.Exception e)
{
GD.Print(e.Message);
}
}
// This function is similar to ConstructFromFile2
// It just load some verts and indices from a abaqus inp file
public void ConstructFromFile(string fileName)
{
try
{
var lines_raw = File.ReadAllLines(fileName).Select(i => i.Trim());
var lines = lines_raw.Where(i => !i.StartsWith("**"));
IEnumerable<(string header, int index)> headers = lines.Select((line, index) => (line, index)).Where(v => v.line.StartsWith("*")).Select(v => (v.line[1..], v.index));
headers = headers.Append(("end", -1));
var indexs = headers.Select(i => i.index);
IEnumerable<(string header, int start, int end)> headers_info = headers.ToArray()[..^1].Zip(indexs.Skip(1)).Select(x => (x.First.header, x.First.index + 1, x.Second));
// 序号从1开始
foreach (var (header, start, end) in headers_info)
{
if (header.StartsWith("node", System.StringComparison.CurrentCultureIgnoreCase))
{
foreach (var line in lines.ToList()[start..end])
{
var items = line.Split(",", false).Select(static i => double.Parse(s: i)).ToList();
var relative = new Vector3((int)items[1], (int)items[2], (int)items[3]);
verts.Add(relative + Position);
}
}
}
foreach (var h in headers_info)
{
var name = h.header.ToLower();
if (name.Contains("type=C3D4", System.StringComparison.CurrentCultureIgnoreCase) ||
name.Contains("type=CPS3", System.StringComparison.CurrentCultureIgnoreCase))
{
var slice = h.end == -1 ? lines.ToList()[h.start..] : lines.ToList()[h.start..h.end];
var point_indexs = slice.Select(x => x.Split(",", false).Skip(1).Select(x => int.Parse(x.Trim())).ToArray()).ToList();
indices = [.. indices, .. point_indexs.SelectMany(x => x).ToList()];
}
}
}
catch (System.Exception e)
{
GD.PrintErr(e.Message);
}
}
public void ConstructFromFile2(string fileName)
{
verts =
[
new Vector3(0,5,0),
new Vector3(-0,5,-0),
new Vector3(0,5,0),
new Vector3(0,0,5),
new Vector3(0,0,-5),
new Vector3(0,0,5),
new Vector3(0,-5,0),
new Vector3(0,-5,0),
new Vector3(0,-5,0),
];
indices = [
0,1,3,1,2,4,3,4,6,4,5,7
];
}
}
inp file is text file:
*Heading
C:\Users\x\Desktop\pdb-godot\box3d
*NODE
1, 0,5,0
2, -0,5,-0
3,0,5,0
4,0,-2.1855695E-07,5
5,-4.371139E-07,-2.1855695E-07,-5
6,8.742278E-07,-2.1855695E-07,5
7,-0,-5,-4.371139E-07
8,3.8213712E-14,-5,4.371139E-07
9,-7.6427424E-14,-5,-4.371139E-07
*ELEMENT, type=CPS3, ELSET=Surface6
1, 0,1,3
2,1,2,4
3, 3,4,6
4,4,5,7
The strange thing:
The render result of the Mesh is the triangle,the ball is just for reference.The position of the mesh is chaning,sometimes the first picture,some times the second when i swich between the build mode or switch between ConstructFromFile(“box4”) and ConstructFromFile2(“box4”).
Theoretically,result from ConstructFromFile and ConstructFromFile2 is same.They only differ slightly after the decimal point.But the position difference is too strange.