added object management

This commit is contained in:
Amazed 2020-04-17 17:39:48 +02:00
parent bcdd439d12
commit ed7262c14f
7 changed files with 417 additions and 32 deletions

31
3d.gd
View File

@ -12,10 +12,37 @@ onready var camera = get_node("Player/Head/Camera")
##################################################
func create_water():
# create water
var waterscene = load("res://realistic_water_shader/water.tscn")
for x in range(-1000,1000, 128):
for y in range(-1000,1000, 128):
var water_instance = waterscene.instance()
water_instance.transform.origin.x = x
water_instance.transform.origin.y = 0
water_instance.transform.origin.z = y
add_child(water_instance)
func _ready() -> void:
if fast_close:
print("** Fast Close enabled in the 's_main.gd' script **")
print("** 'Esc' to close 'Shift + F1' to release mouse **")
var giantsscript = load("res://objectmanager.gd")
var objmgr = giantsscript.ObjectManager.new()
# var giants_dir_browser = FileDialog.new()
# giants_dir_browser.mode = FileDialog.MODE_OPEN_DIR
# giants_dir_browser.window_title = "Select your Giants directory"
# giants_dir_browser.access = FileDialog.ACCESS_FILESYSTEM
# add_child(giants_dir_browser)
# giants_dir_browser.popup_centered()
objmgr.build()
var m = objmgr.load_model("W_story1_rock_2.gbs")
# print(m.tex)
# print(m.point_uv)
print(m.tex)
var meshinstance = objmgr.load_model_mesh(m)
meshinstance.transform.origin.y = 50
add_child(meshinstance)
func _input(event: InputEvent) -> void:
@ -40,3 +67,7 @@ func _process(delta):
func _on_Button_pressed():
get_tree().quit()
func _on_GiantsDirectory_dir_selected(dir):
pass # Replace with function body.

69
3d.tscn
View File

@ -1,20 +1,35 @@
[gd_scene load_steps=8 format=2]
[gd_scene load_steps=9 format=2]
[ext_resource path="res://player/Player.tscn" type="PackedScene" id=1]
[ext_resource path="res://MeshInstance.tscn" type="PackedScene" id=2]
[ext_resource path="res://3d.gd" type="Script" id=3]
[ext_resource path="res://ImmediateGeometry.gd" type="Script" id=4]
[ext_resource path="res://Water.tscn" type="PackedScene" id=5]
[sub_resource type="SpatialMaterial" id=7]
[sub_resource type="SpatialMaterial" id=1]
vertex_color_use_as_albedo = true
params_cull_mode = 2
[sub_resource type="SpatialMaterial" id=6]
vertex_color_use_as_albedo = true
params_diffuse_mode = 4
params_specular_mode = 4
params_cull_mode = 2
[sub_resource type="ProceduralSky" id=2]
sky_top_color = Color( 0.00392157, 0.235294, 0.360784, 1 )
sky_horizon_color = Color( 0.0117647, 0.482353, 0.980392, 1 )
ground_bottom_color = Color( 0.0431373, 0.509804, 0.980392, 1 )
ground_horizon_color = Color( 0.0117647, 0.482353, 0.980392, 1 )
ground_energy = 1.5
sun_color = Color( 0.686275, 0.196078, 0.00392157, 1 )
sun_longitude = 180.0
sun_energy = 2.0
[sub_resource type="Environment" id=3]
background_mode = 2
background_sky = SubResource( 2 )
background_color = Color( 0.0627451, 0.541176, 0.772549, 1 )
auto_exposure_speed = 2.0
[sub_resource type="CubeMesh" id=4]
size = Vector3( 5000, 2, 5000 )
[sub_resource type="SpatialMaterial" id=5]
flags_transparent = true
albedo_color = Color( 0, 0.882353, 1, 0.0313726 )
[node name="Spatial" type="Spatial"]
script = ExtResource( 3 )
@ -23,7 +38,7 @@ script = ExtResource( 3 )
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.151, 200, -0.003 )
[node name="GiantsTerrain" parent="." instance=ExtResource( 2 )]
material_override = SubResource( 7 )
material_override = SubResource( 1 )
[node name="Label" type="Label" parent="."]
margin_right = 40.0
@ -32,19 +47,6 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="DirectionalLight" type="DirectionalLight" parent="."]
transform = Transform( 1, 0, 0, 0, -0.00790628, 0.999969, 0, -0.999969, -0.00790628, 0, 300, 0 )
light_energy = 1.94
shadow_enabled = true
[node name="ImmediateGeometry" type="ImmediateGeometry" parent="."]
material_override = SubResource( 6 )
cast_shadow = 0
script = ExtResource( 4 )
[node name="Water" parent="." instance=ExtResource( 5 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -10, 0 )
[node name="Button" type="Button" parent="."]
margin_top = 579.365
margin_right = 40.0
@ -53,4 +55,25 @@ text = "Quit"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource( 3 )
[node name="MyWater" type="MeshInstance" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -10, 0 )
visible = false
mesh = SubResource( 4 )
material/0 = SubResource( 5 )
[node name="GiantsDirectory" type="FileDialog" parent="."]
margin_right = 307.0
margin_bottom = 130.0
popup_exclusive = true
window_title = "Open Giants directory"
resizable = true
mode = 2
access = 2
current_dir = "/home/tasty/Jeux/GiantsEdit"
current_path = "/home/tasty/Jeux/GiantsEdit/"
[connection signal="pressed" from="Button" to="." method="_on_Button_pressed"]
[connection signal="dir_selected" from="GiantsDirectory" to="." method="_on_GiantsDirectory_dir_selected"]

View File

@ -6,6 +6,7 @@ var xoffset
var yoffset
var minheight
var maxheight
var heightscale
var xverticesnumber
var yverticesnumber
var stretch
@ -37,9 +38,8 @@ func _on_MeshInstance_ready():
mesh = m
func fill():
print("version="+str(version))
# fill read values
print("fill")
# print("fill")
var p = 0
while p < xverticesnumber * yverticesnumber:
var b = file.get_8()
@ -54,13 +54,13 @@ func fill():
if p >= xverticesnumber * yverticesnumber:
return
if version != 7:
vertices[p][2] = file.get_float() # height
vertices[p][2] = file.get_float() * heightscale # height
vertices[p][3] = file.get_8() # triangulation
vertices[p][4] = file.get_8() # R
vertices[p][5] = file.get_8() # G
vertices[p][6] = file.get_8() # B
else:
vertices[p][2] = file.get_float() # height
vertices[p][2] = file.get_float() * heightscale # height
vertices[p][3] = file.get_8() # triangulation
vertices[p][4] = file.get_8() # R
vertices[p][5] = file.get_8() # G
@ -84,6 +84,8 @@ func readgti(filename):
xverticesnumber = file.get_32()
yverticesnumber = file.get_32()
stretch = file.get_float()
stretch = 40.0
heightscale = stretch/40.0 # normal stretch
u1 = file.get_float()
u2 = file.get_float()
u3 = file.get_float()
@ -97,7 +99,7 @@ func readgti(filename):
vertices.resize(xverticesnumber * yverticesnumber)
# initialize empty terrain
print("init")
# print("init")
for y in range(yverticesnumber):
for x in range(xverticesnumber):
vertices[y * xverticesnumber + x] = []
@ -114,7 +116,7 @@ func readgti(filename):
file.close()
# sort triangles
print("sort")
# print("sort")
var i = 0
# triangles.resize(2*len(vertices))
for y in range(yverticesnumber-1):

28
model.gd Normal file
View File

@ -0,0 +1,28 @@
extends Node
class Model:
var magic
var u1
var basepoints
var basepoint = []
var texpos
var vertexrefs
var vertexref = []
var points
var point_1 = []
var point_2 = []
var point_uv = []
var point_c = []
var ref1 = []
var u2
var u3
var u4
var u5
var u6
var u7
var part = []
var tex = []
var parts
var bounds1
var bounds2
var maxbound

23
modelitem.gd Normal file
View File

@ -0,0 +1,23 @@
extends Node
class ModelItem:
var objname
var objindex
var refs
var wordz
var refs_
var refstart
var refnum
var texture
var bumptexture
var falloff
var blend
var flags
var emissive
var ambiant
var diffuse
var specular
var power
var triangle = []

280
objectmanager.gd Normal file
View File

@ -0,0 +1,280 @@
extends Node
class ObjectManager:
var GIANTS_PATH = "/home/tasty/Jeux/Giants Citizen Kabuto"
var index = {}
func build() -> void:
var bin_dir = Directory.new()
if bin_dir.open(GIANTS_PATH+"/Bin") == OK:
bin_dir.list_dir_begin()
var file_name = bin_dir.get_next()
while (file_name != ""):
if not bin_dir.current_is_dir() and file_name.ends_with(".gzp"):
# print("Found GZP file: " + file_name)
var gzp_file = File.new()
gzp_file.open(GIANTS_PATH+"/Bin/"+file_name, File.READ)
read_gzp_to_indexes(gzp_file)
gzp_file.close()
file_name = bin_dir.get_next()
func read_gzp_to_indexes(file: File) -> void:
var checksum = file.get_32()
assert(checksum == 0x6608F101)
var meta_info_offset = file.get_32()
file.seek(meta_info_offset)
var unk = file.get_32()
var entries_count = file.get_32()
for i in range(entries_count):
var compressed_size = file.get_32()
var original_size = file.get_32()
var file_time = file.get_32()
var content_offset = file.get_32() + 16
var compression = file.get_8()
var name_length = file.get_8()
var name = file.get_buffer(name_length).get_string_from_ascii()
if name.ends_with(".tga") or name.ends_with(".gbs"):
index[name] = file.get_path_absolute()
# if name.ends_with(".gbs"):
# print(name)
func read_file_in_gzp(filename: String) -> StreamPeerBuffer:
var gzp_file = index[filename]
var res = StreamPeerBuffer.new()
var file = File.new()
if not file.open(gzp_file, File.READ) == OK:
print("Could not open "+filename)
return res
var checksum = file.get_32()
assert(checksum == 0x6608F101)
var meta_info_offset = file.get_32()
file.seek(meta_info_offset)
var unk = file.get_32()
var entries_count = file.get_32()
for i in range(entries_count):
var compressed_size = file.get_32()
var original_size = file.get_32()
var file_time = file.get_32()
var content_offset = file.get_32() + 16
var compression = file.get_8()
var name_length = file.get_8()
var name = file.get_buffer(name_length).get_string_from_ascii()
if name == filename:
var current_offset = file.get_position()
file.seek(content_offset)
var data = file.get_buffer(compressed_size)
file.seek(current_offset)
if compression == 1:
data = _decompress(data, original_size)
res.data_array = data
file.close()
return res
func load_model(gbs_file: String):
var pos = 0
var gbs_stream = read_file_in_gzp(gbs_file)
var model = load("res://model.gd").Model.new()
var modelitem_gd = load("res://modelitem.gd")
model.magic = gbs_stream.get_32()
model.u1 = gbs_stream.get_32()
model.basepoints = gbs_stream.get_32()
print("basepoints="+str(model.basepoints))
model.basepoint = []
model.basepoint.resize(model.basepoints)
for s in range(model.basepoints):
var x = gbs_stream.get_float()
var y = gbs_stream.get_float()
var z = gbs_stream.get_float()
model.basepoint[s] = [x, y, z]
if model.u1 == 7:
model.texpos = gbs_stream.get_32()
model.vertexrefs = gbs_stream.get_32()
model.vertexref.resize(model.vertexrefs)
for s in range(model.vertexrefs):
model.vertexref[s] = gbs_stream.get_16()
model.points = gbs_stream.get_32()
model.point_1.resize(model.points)
print("points="+str(model.points))
if model.u1 == 7:
model.point_2.resize(model.points)
model.point_uv.resize(model.points)
# model.point_c.resize(model.points*3)
for s in range(model.points):
model.point_1[s] = gbs_stream.get_16()
if model.u1 == 7:
for s in range(model.points):
model.point_2[s] = gbs_stream.get_16()
for s in range(model.points):
model.point_uv[s] = []
model.point_uv[s].resize(2)
model.point_uv[s][0] = gbs_stream.get_float()
model.point_uv[s][1] = gbs_stream.get_float()
for s in range(model.points):
var r = gbs_stream.get_8()
var g = gbs_stream.get_8()
var b = gbs_stream.get_8()
model.point_c.append(r)
model.point_c.append(g)
model.point_c.append(b)
var i = gbs_stream.get_32()
print("i="+str(i))
model.ref1.resize(i)
for s in range(i):
model.ref1[s] = []
model.ref1[s].resize(5)
model.ref1[s][0] = gbs_stream.get_32()
model.ref1[s][1] = gbs_stream.get_32()
model.ref1[s][2] = gbs_stream.get_32()
model.ref1[s][3] = gbs_stream.get_32()
model.ref1[s][4] = gbs_stream.get_32()
model.parts = gbs_stream.get_32()
print("parts="+str(model.parts))
model.part.resize(model.parts)
for p in range(model.parts):
model.part[p] = modelitem_gd.ModelItem.new()
model.part[p].objname = gbs_stream.get_string(32)
print("Objname: "+model.part[p].objname)
model.part[p].objindex = gbs_stream.get_32()
model.part[p].refs = gbs_stream.get_32()
model.part[p].wordz = gbs_stream.get_32()
model.part[p].refs_ = gbs_stream.get_16()
model.part[p].triangle.resize(model.part[p].refs)
for s in range(model.part[p].refs):
model.part[p].triangle[s] = []
model.part[p].triangle[s].resize(3)
model.part[p].triangle[s][0] = gbs_stream.get_16()
model.part[p].triangle[s][1] = gbs_stream.get_16()
model.part[p].triangle[s][2] = gbs_stream.get_16()
model.part[p].refstart = gbs_stream.get_32()
model.part[p].refnum = gbs_stream.get_32()
model.part[p].texture = gbs_stream.get_string(32)
model.part[p].bumptexture = gbs_stream.get_string(32)
model.part[p].falloff = gbs_stream.get_float()
model.part[p].blend = gbs_stream.get_float()
model.part[p].flags = gbs_stream.get_32()
model.part[p].emissive = gbs_stream.get_32()
model.part[p].ambiant = gbs_stream.get_32()
model.part[p].diffuse = gbs_stream.get_32()
model.part[p].specular = gbs_stream.get_32()
model.part[p].power = gbs_stream.get_float()
model.tex.resize(model.parts)
for s in range(model.parts):
if model.part[s].texture != "":
model.tex[s] = load_texture(model.part[s].texture+".tga")
else:
model.tex[s] = null
model.bounds1 = model.basepoint[0]
model.bounds2 = model.basepoint[0]
model.maxbound = 0
for s in range(model.basepoints):
var r = sqrt(pow(model.basepoint[s][0], 2) + pow(model.basepoint[s][1], 2) + pow(model.basepoint[s][2], 2))
if r > model.maxbound:
model.maxbound = r
for s in range(model.basepoints):
if model.basepoint[s][0] < model.bounds1[0]:
model.bounds1[0] = model.basepoint[s][0]
if model.basepoint[s][1] < model.bounds1[1]:
model.bounds1[1] = model.basepoint[s][1]
if model.basepoint[s][2] < model.bounds1[2]:
model.bounds1[2] = model.basepoint[s][2]
if model.basepoint[s][0] > model.bounds2[0]:
model.bounds2[0] = model.basepoint[s][0]
if model.basepoint[s][1] > model.bounds2[1]:
model.bounds2[1] = model.basepoint[s][1]
if model.basepoint[s][2] > model.bounds2[2]:
model.bounds2[2] = model.basepoint[s][2]
return model
func load_texture(texture_file: String) -> ImageTexture:
print("Loading texture "+texture_file)
var tmpDirectory = Directory.new()
if not tmpDirectory.dir_exists("res://tmp"):
tmpDirectory.make_dir("res://tmp")
var stream = read_file_in_gzp(texture_file)
var tmpFile = File.new()
tmpFile.open("res://tmp/"+texture_file, File.WRITE)
tmpFile.store_buffer(stream.data_array)
print("Saved to: "+tmpFile.get_path_absolute())
tmpFile.close()
var img = Image.new()
var tex = ImageTexture.new()
img.load("res://tmp/"+texture_file)
tex.create_from_image(img)
# tmpDirectory.remove("res://tmp/"+texture_file)
return tex
func load_model_mesh(model) -> MeshInstance:
var meshinstance = MeshInstance.new()
var mesh = Mesh.new()
for i in range(model.parts):
var st = SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
var mat = SpatialMaterial.new()
mat.params_cull_mode = SpatialMaterial.CULL_DISABLED
if model.tex[i]:
mat.albedo_texture = model.tex[i]
st.set_material(mat)
assert(len(model.basepoint) % 3 == 0)
for j in range(len(model.part[i].triangle)):
for k in range(2):
var l = model.part[i].triangle[j][k]
st.add_uv(Vector2(model.point_uv[l][0], model.point_uv[l][1]))
st.add_color(Color(
model.point_c[l*3+0] / 255.0 + (model.part[i].diffuse & 255) / 255.0,
model.point_c[l*3+1] / 255.0 + ((model.part[i].diffuse >> 8) & 255) / 255.0,
model.point_c[l*3+2] / 255.0 + ((model.part[i].diffuse >> 16) & 255) / 255.0))
l = model.point_1[l]
st.add_vertex(Vector3(
model.basepoint[l][0],
model.basepoint[l][1],
model.basepoint[l][2]))
mesh = st.commit(mesh)
meshinstance.mesh = mesh
return meshinstance
func _decompress(compressed_bytes: PoolByteArray, original_size: int) -> PoolByteArray:
var i = 0
var j = 0
var dec_byte = 0
var dec_bits = 8
var buff_start = 0xFEE
var res = PoolByteArray()
res.resize(original_size)
if (original_size == 0):
return res
while j < original_size:
if dec_bits == 8:
dec_byte = compressed_bytes[i]
i+=1
dec_bits = 0
if (dec_byte >> dec_bits & 1) == 0:
var dec_pos = ((compressed_bytes[i] + ((compressed_bytes[i + 1] & 0xF0) << 4) - buff_start - j) & 0xFFF) - 0x1000 + j
var dec_len = (compressed_bytes[i + 1] & 0xF) + 3
i+=2
while dec_len > 0:
if dec_pos >= 0:
res[j] = res[dec_pos]
else:
res[j] = 32
j+=1
dec_pos += 1
dec_len -= 1
else:
res[j] = compressed_bytes[i]
i+=1
j+=1
dec_bits += 1
return res

View File

@ -1,7 +1,6 @@
[gd_scene load_steps=4 format=2]
[gd_scene load_steps=3 format=2]
[ext_resource path="res://player/player_controller.gd" type="Script" id=1]
[ext_resource path="res://default_env.tres" type="Environment" id=2]
[sub_resource type="CapsuleShape" id=1]
radius = 0.6
@ -24,6 +23,5 @@ shape = SubResource( 1 )
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0 )
[node name="Camera" type="Camera" parent="Head"]
environment = ExtResource( 2 )
fov = 80.0
far = 10000.0