Compare commits
41 Commits
1c165601c2
...
v1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b32671567e | ||
|
|
f4cf597a95 | ||
|
|
5f2e84d8cf | ||
|
|
7754e410fd | ||
|
|
5a3a524cb3 | ||
|
|
55b8e827c2 | ||
|
|
368664d246 | ||
|
|
90f0e2dd42 | ||
|
|
355df2ee44 | ||
|
|
e126db573a | ||
|
|
ceb8ccb7d4 | ||
|
|
e81750300d | ||
|
|
446ff24fcf | ||
|
|
309af8f59e | ||
|
|
7b6ce73fa5 | ||
|
|
ce465ef449 | ||
|
|
9478bca2ad | ||
|
|
da59158fd1 | ||
|
|
ff2924a0b7 | ||
|
|
24ddb047aa | ||
|
|
0ba2cdee1c | ||
|
|
ae4a62f584 | ||
|
|
e43391caa3 | ||
|
|
eb17923448 | ||
|
|
9cd4aee87a | ||
|
|
310889bd2c | ||
|
|
0629b042ad | ||
|
|
3c780c7290 | ||
|
|
943a8cd1d9 | ||
|
|
2c1ee84791 | ||
|
|
8990e415d3 | ||
|
|
85d5f4f019 | ||
|
|
82fcbb6fed | ||
|
|
130e0f1050 | ||
|
|
fff7690222 | ||
|
|
2bf947018c | ||
|
|
6f2a27c03f | ||
|
|
8b359412f2 | ||
|
|
2cae13dc2d | ||
|
|
7facb3a9d1 | ||
|
|
aef3de3df9 |
@@ -13,12 +13,13 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: 'true'
|
submodules: 'true'
|
||||||
- run: mkdir build build/k3 bin bin/assets
|
- run: mkdir build build/k3 build/k3/compr bin bin/assets
|
||||||
- run: CC="i686-w64-mingw32-gcc" CFLAGS="-I/usr/i686-w64-mingw32/include -I/usr/i686-w64-mingw32/include/lua5.3 -L/usr/i686-w64-mingw32/lib -Wno-error" make -B
|
- run: CC="i686-w64-mingw32-gcc" CFLAGS="-I/usr/i686-w64-mingw32/include -I/usr/i686-w64-mingw32/include/lua5.3 -L/usr/i686-w64-mingw32/lib -Wno-error" make -B
|
||||||
- run: CC="i686-linux-gnu-gcc" CFLAGS="-I/usr/i686-linux-gnu/include -I/usr/i686-linux-gnu/include/lua5.3 -L/usr/i686-linux-gnu/lib -Wno-error" make -B
|
- run: CC="i686-linux-gnu-gcc" CFLAGS="-I/usr/i686-linux-gnu/include -I/usr/i686-linux-gnu/include/lua5.3 -L/usr/i686-linux-gnu/lib -Wno-error -include /home/git/force_link_glibc_2.20.h" make -B
|
||||||
- run: cp /usr/lib/gcc/i686-w64-mingw32/10-win32/libgcc_s_dw2-1.dll /usr/lib/gcc/i686-w64-mingw32/10-win32/libstdc++-6.dll /usr/i686-w64-mingw32/lib/libportaudio-2.dll /usr/i686-w64-mingw32/lib/libwinpthread-1.dll bin/
|
- run: cp /usr/lib/gcc/i686-w64-mingw32/12-win32/libgcc_s_dw2-1.dll /usr/lib/gcc/i686-w64-mingw32/12-win32/libstdc++-6.dll /usr/i686-w64-mingw32/lib/libportaudio-2.dll /usr/i686-w64-mingw32/lib/libwinpthread-1.dll /usr/lib/gcc/i686-w64-mingw32/12-win32/libgomp-1.dll bin/
|
||||||
- run: cp -r /home/git/k4templateassets/* bin/assets/
|
- run: cp -r /home/git/k4templateassets/* bin/assets/
|
||||||
- run: zip -9r "k4${{ github.ref_name }}.zip" bin/
|
- run: mv bin k4
|
||||||
|
- run: zip -9r "k4${{ github.ref_name }}.zip" k4/
|
||||||
- name: Create package
|
- name: Create package
|
||||||
uses: akkuman/gitea-release-action@v1
|
uses: akkuman/gitea-release-action@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
20
Makefile
20
Makefile
@@ -1,24 +1,26 @@
|
|||||||
k4_SRCS := $(wildcard src/*.c)
|
rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))
|
||||||
k4_HDRS := $(wildcard src/*.h)
|
|
||||||
|
k4_SRCS := $(call rwildcard,src,*.c)
|
||||||
|
k4_HDRS := $(call rwildcard,src,*.h)
|
||||||
k4_OBJS := $(patsubst src/%.c, build/%.o, $(k4_SRCS))
|
k4_OBJS := $(patsubst src/%.c, build/%.o, $(k4_SRCS))
|
||||||
k4_DEPS := $(patsubst src/%.c, build/%.d, $(k4_SRCS))
|
k4_DEPS := $(patsubst src/%.c, build/%.d, $(k4_SRCS))
|
||||||
|
|
||||||
k3_SRCS = $(wildcard k3/src/*.c)
|
k3_SRCS := $(call rwildcard,k3/src,*.c)
|
||||||
k3_HDRS = $(wildcard k3/src/*.h)
|
k3_HDRS := $(call rwildcard,k3/src,*.h)
|
||||||
k3_OBJS := $(patsubst k3/src/%.c, build/k3/%.o, $(k3_SRCS))
|
k3_OBJS := $(patsubst k3/src/%.c, build/k3/%.o, $(k3_SRCS))
|
||||||
k3_DEPS := $(patsubst k3/src/%.c, build/k3/%.d, $(k3_SRCS))
|
k3_DEPS := $(patsubst k3/src/%.c, build/k3/%.d, $(k3_SRCS))
|
||||||
|
|
||||||
CFLAGS := $(CFLAGS) -Ik3/src
|
CFLAGS := $(CFLAGS) -D_GNU_SOURCE -D_DEFAULT_SOURCE -Ik3/src -O2 -fopenmp -flto -s
|
||||||
|
|
||||||
ifneq (,$(findstring mingw,$(CC)))
|
ifneq (,$(findstring mingw,$(CC)))
|
||||||
CFLAGS := -static-libgcc -static-libstdc++ -std=gnu99 -march=pentium4 -D_WIN32_WINNT=0x600 -DENET_FEATURE_ADDRESS_MAPPING -fno-pic -no-pie -fms-extensions -fno-pie -O0 -g -gdwarf-2 -Isrc $(CFLAGS)
|
CFLAGS := -static-libgcc -static-libstdc++ -std=gnu99 -march=pentium4 -D_WIN32_WINNT=0x600 -DENET_FEATURE_ADDRESS_MAPPING -fno-pic -no-pie -fms-extensions -fno-pie -Isrc $(CFLAGS)
|
||||||
LIBS := -l:libglfw3.a -lopengl32 -pthread -lm -l:libode.a -l:libvorbisfile.a -l:libvorbis.a -l:libogg.a -lportaudio -lgdi32 -lws2_32 -lwinmm -lstdc++ -lole32 -lsetupapi -lhid -l:liblua5.3.a $(LIBS)
|
LIBS := -l:libglfw3.a -lopengl32 -pthread -lm -l:libode.a -l:libvorbisfile.a -l:libvorbis.a -l:libogg.a -lportaudio -lgdi32 -lws2_32 -lwinmm -lstdc++ -lole32 -lsetupapi -lhid -l:liblua5.3.a -liphlpapi $(LIBS)
|
||||||
else
|
else
|
||||||
CFLAGS := -march=opteron $(SAN) -std=gnu99 -DENET_FEATURE_ADDRESS_MAPPING -fms-extensions -fno-pic -no-pie -fno-pie -O0 -g -Isrc $(CFLAGS)
|
CFLAGS := -march=opteron $(SAN) -std=gnu99 -DENET_FEATURE_ADDRESS_MAPPING -fms-extensions -fno-pic -no-pie -fno-pie -Isrc $(CFLAGS)
|
||||||
LIBS := -lglfw3 -pthread -ldl -lm -lode -lstdc++ -llua5.3 -lvorbis -lvorbisfile -lportaudio $(LIBS)
|
LIBS := -lglfw3 -pthread -ldl -lm -lode -lstdc++ -llua5.3 -lvorbis -lvorbisfile -lportaudio $(LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS := $(CFLAGS) -DLOCALHOST_ONLY -Dk3_IRREGULAR_SHADOWS
|
CFLAGS := $(CFLAGS) -DLOCALHOST_ONLY
|
||||||
|
|
||||||
build/k3/%.o: k3/src/%.c
|
build/k3/%.o: k3/src/%.c
|
||||||
$(CC) $(CFLAGS) -MMD -o $@ -c $<
|
$(CC) $(CFLAGS) -MMD -o $@ -c $<
|
||||||
|
|||||||
393
gltf2tok3.py
Executable file
393
gltf2tok3.py
Executable file
@@ -0,0 +1,393 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import pygltflib
|
||||||
|
import sys
|
||||||
|
import numpy
|
||||||
|
import os
|
||||||
|
import base64
|
||||||
|
import pathlib
|
||||||
|
import struct
|
||||||
|
|
||||||
|
def mat3_to_quat(m):
|
||||||
|
trace = numpy.trace(m)
|
||||||
|
|
||||||
|
if trace >= 0:
|
||||||
|
r = (1 + trace) ** 0.5
|
||||||
|
rinv = 0.5 / r
|
||||||
|
|
||||||
|
q0 = rinv * (m[1, 2] - m[2, 1])
|
||||||
|
q1 = rinv * (m[2, 0] - m[0, 2])
|
||||||
|
q2 = rinv * (m[0, 1] - m[1, 0])
|
||||||
|
q3 = r * 0.5
|
||||||
|
elif m[0, 0] >= m[1, 1] and m[0, 0] >= m[2, 2]:
|
||||||
|
r = (1 - m[1, 1] - m[2, 2] + m[0, 0]) ** 0.5
|
||||||
|
rinv = 0.5 / r
|
||||||
|
|
||||||
|
q0 = r * 0.5
|
||||||
|
q1 = rinv * (m[0, 1] + m[1, 0])
|
||||||
|
q2 = rinv * (m[0, 2] + m[2, 0])
|
||||||
|
q3 = rinv * (m[1, 2] - m[2, 1])
|
||||||
|
elif m[1, 1] >= m[2, 2]:
|
||||||
|
r = (1 - m[0, 0] - m[2, 2] + m[1, 1]) ** 0.5
|
||||||
|
rinv = 0.5 / r
|
||||||
|
|
||||||
|
q0 = rinv * (m[0, 1] + m[1, 0])
|
||||||
|
q1 = r * 0.5
|
||||||
|
q2 = rinv * (m[1, 2] + m[2, 1])
|
||||||
|
q3 = rinv * (m[2, 0] - m[0, 2])
|
||||||
|
else:
|
||||||
|
r = (1 - m[0, 0] - m[1, 1] + m[2, 2]) ** 0.5
|
||||||
|
rinv = 0.5 / r
|
||||||
|
|
||||||
|
q0 = rinv * (m[0, 2] + m[2, 0])
|
||||||
|
q1 = rinv * (m[1, 2] + m[2, 1])
|
||||||
|
q2 = r * 0.5
|
||||||
|
q3 = rinv * (m[0, 1] - m[1, 0])
|
||||||
|
|
||||||
|
q = numpy.array([q0, q1, q2, q3])
|
||||||
|
|
||||||
|
if q[3] < 0:
|
||||||
|
q = -q
|
||||||
|
|
||||||
|
return q
|
||||||
|
|
||||||
|
def mat3_from_quat(q):
|
||||||
|
b, c, d, a = q[0], q[1], q[2], q[3]
|
||||||
|
|
||||||
|
return numpy.array([
|
||||||
|
[a ** 2 + b ** 2 - c ** 2 - d ** 2, 2 * b * c + 2 * a * d, 2 * b * d - 2 * a * c],
|
||||||
|
[2 * b * c - 2 * a * d, a ** 2 - b ** 2 + c ** 2 - d ** 2, 2 * c * d - 2 * a * b],
|
||||||
|
[2 * b * d - 2 * a * c, 2 * c * d + 2 * a * b, a ** 2 - b ** 2 - c ** 2 + d ** 2],
|
||||||
|
])
|
||||||
|
|
||||||
|
def mat4_decompose(m):
|
||||||
|
translation = m[3][:3]
|
||||||
|
|
||||||
|
rs_matrix = m[:3, :3]
|
||||||
|
|
||||||
|
scale = (rs_matrix ** 2).sum(-1) ** 0.5
|
||||||
|
|
||||||
|
rs_matrix[0] /= scale[0]
|
||||||
|
rs_matrix[1] /= scale[1]
|
||||||
|
rs_matrix[2] /= scale[2]
|
||||||
|
|
||||||
|
if numpy.dot(numpy.cross(m[0][:3], m[1][:3]), m[2][:3]) < 0:
|
||||||
|
rs_matrix[0] *= -1
|
||||||
|
rs_matrix[1] *= -1
|
||||||
|
rs_matrix[2] *= -1
|
||||||
|
scale *= -1
|
||||||
|
|
||||||
|
return translation, mat3_to_quat(rs_matrix), scale
|
||||||
|
|
||||||
|
def mat4_compose(t, r, s):
|
||||||
|
m = numpy.zeros((4, 4))
|
||||||
|
|
||||||
|
rm = mat3_from_quat(r) if r is not None else numpy.eye(3)
|
||||||
|
|
||||||
|
if s is not None:
|
||||||
|
rm[0] *= s[0]
|
||||||
|
rm[1] *= s[1]
|
||||||
|
rm[2] *= s[2]
|
||||||
|
|
||||||
|
m[:3, :3] = rm
|
||||||
|
|
||||||
|
if t is not None:
|
||||||
|
m[3][:3] = t
|
||||||
|
|
||||||
|
m[3][3] = 1
|
||||||
|
|
||||||
|
return m
|
||||||
|
|
||||||
|
def lerp(a, b, alpha):
|
||||||
|
return a + (b - a) * alpha
|
||||||
|
|
||||||
|
def slerp(a, b, alpha):
|
||||||
|
angle = numpy.arccos(min(1, max(-1, numpy.dot(a, b))))
|
||||||
|
denominator = numpy.sin(angle)
|
||||||
|
if abs(denominator) < 0.000001:
|
||||||
|
return lerp(a, b, alpha)
|
||||||
|
return (a * numpy.sin((1 - alpha) * angle) + b * numpy.sin(alpha * angle)) / denominator
|
||||||
|
|
||||||
|
TYPE_SIZES = {
|
||||||
|
"SCALAR": 1,
|
||||||
|
"VEC2": 2,
|
||||||
|
"VEC3": 3,
|
||||||
|
"VEC4": 4,
|
||||||
|
"MAT2": 4,
|
||||||
|
"MAT4": 16,
|
||||||
|
"MAT3": 9,
|
||||||
|
pygltflib.FLOAT: 4,
|
||||||
|
pygltflib.UNSIGNED_INT: 4,
|
||||||
|
pygltflib.UNSIGNED_SHORT: 2,
|
||||||
|
pygltflib.UNSIGNED_BYTE: 1,
|
||||||
|
pygltflib.SHORT: 2,
|
||||||
|
pygltflib.BYTE: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
GLTF_NUMPY_MAPPING = {
|
||||||
|
pygltflib.FLOAT: numpy.float32,
|
||||||
|
pygltflib.UNSIGNED_INT: numpy.uint32,
|
||||||
|
pygltflib.UNSIGNED_SHORT: numpy.uint16,
|
||||||
|
pygltflib.UNSIGNED_BYTE: numpy.uint8,
|
||||||
|
pygltflib.SHORT: numpy.int16,
|
||||||
|
pygltflib.BYTE: numpy.int8,
|
||||||
|
}
|
||||||
|
|
||||||
|
errors = []
|
||||||
|
def err(s):
|
||||||
|
errors.append(s)
|
||||||
|
def err_barrier():
|
||||||
|
for e in errors:
|
||||||
|
print(e)
|
||||||
|
if os.name == "nt" and "PROMPT" not in os.environ:
|
||||||
|
raw_input()
|
||||||
|
if len(errors):
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
for input_filename in sys.argv[1:]:
|
||||||
|
gltf = pygltflib.GLTF2().load(input_filename)
|
||||||
|
gltf.convert_buffers(pygltflib.BufferFormat.DATAURI)
|
||||||
|
|
||||||
|
def get_nd(acc_idx):
|
||||||
|
if acc_idx == None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
accessor = gltf.accessors[acc_idx]
|
||||||
|
buf_view = gltf.bufferViews[accessor.bufferView]
|
||||||
|
buf = gltf.buffers[buf_view.buffer]
|
||||||
|
uri = buf.uri
|
||||||
|
|
||||||
|
if "base64," in uri:
|
||||||
|
buf_data = base64.decodebytes(buf.uri.split("base64,")[-1].encode())
|
||||||
|
else:
|
||||||
|
with open(uri, "rb") as urifile:
|
||||||
|
buf_data = urifile.read()
|
||||||
|
|
||||||
|
start = buf_view.byteOffset + accessor.byteOffset
|
||||||
|
array = numpy.frombuffer(buf_data[start : start + accessor.count * TYPE_SIZES[accessor.type] * TYPE_SIZES[accessor.componentType]], dtype = GLTF_NUMPY_MAPPING[accessor.componentType])
|
||||||
|
return numpy.reshape(array, (array.shape[0] // TYPE_SIZES[accessor.type], TYPE_SIZES[accessor.type]))
|
||||||
|
|
||||||
|
def get(acc_idx):
|
||||||
|
array = get_nd(acc_idx)
|
||||||
|
return array.ravel() if array is not None else None
|
||||||
|
|
||||||
|
mesh_nodes = [n for n in gltf.nodes if n.mesh != None]
|
||||||
|
|
||||||
|
if len(mesh_nodes) > 1:
|
||||||
|
err("All meshes except first are ignored")
|
||||||
|
|
||||||
|
mesh_node = mesh_nodes[0]
|
||||||
|
|
||||||
|
mesh = gltf.meshes[mesh_node.mesh]
|
||||||
|
skin = gltf.skins[mesh_node.skin] if mesh_node.skin != None else None
|
||||||
|
|
||||||
|
k3result = {
|
||||||
|
"animations": [],
|
||||||
|
"bones": [],
|
||||||
|
"meshes": [],
|
||||||
|
}
|
||||||
|
|
||||||
|
for primitive in mesh.primitives:
|
||||||
|
material_name = ""
|
||||||
|
|
||||||
|
if primitive.material is not None:
|
||||||
|
material_name = gltf.materials[primitive.material].name
|
||||||
|
if not material_name:
|
||||||
|
err("Missing material name")
|
||||||
|
material_name = ""
|
||||||
|
else:
|
||||||
|
err("Missing material information")
|
||||||
|
|
||||||
|
mehs = {
|
||||||
|
"positions": get_nd(primitive.attributes.POSITION),
|
||||||
|
"normals": get_nd(primitive.attributes.NORMAL),
|
||||||
|
"uvs": get_nd(primitive.attributes.TEXCOORD_0),
|
||||||
|
"colors": get_nd(primitive.attributes.COLOR_0),
|
||||||
|
"boneids": get_nd(primitive.attributes.JOINTS_0),
|
||||||
|
"boneweights": get_nd(primitive.attributes.WEIGHTS_0),
|
||||||
|
"indices": get(primitive.indices),
|
||||||
|
"material_name": material_name
|
||||||
|
}
|
||||||
|
|
||||||
|
if mehs["normals"] is None:
|
||||||
|
err("Missing normal data")
|
||||||
|
if mehs["uvs"] is None:
|
||||||
|
err("Missing UVs")
|
||||||
|
|
||||||
|
k3result["meshes"].append(mehs)
|
||||||
|
|
||||||
|
if skin and len(skin.joints) > 255:
|
||||||
|
err("Bone maximum is 255")
|
||||||
|
|
||||||
|
err_barrier()
|
||||||
|
|
||||||
|
joint_gltf_to_k3_id_mapping = {}
|
||||||
|
joint_k3_to_gltf_id_mapping = {}
|
||||||
|
if skin:
|
||||||
|
# Topologically sort joints just in case they aren't
|
||||||
|
joint_parents = {i: next((j for j in skin.joints if i in gltf.nodes[j].children), None) for i in skin.joints}
|
||||||
|
joint_graph = joint_parents.copy()
|
||||||
|
while len(k3result["bones"]) != len(skin.joints):
|
||||||
|
minimal_elements = [k for k, v in joint_graph.items() if v == None]
|
||||||
|
for j in minimal_elements:
|
||||||
|
joint_gltf_to_k3_id_mapping[j] = len(k3result["bones"])
|
||||||
|
joint_k3_to_gltf_id_mapping[len(k3result["bones"])] = j
|
||||||
|
k3result["bones"].append({
|
||||||
|
"parent": joint_gltf_to_k3_id_mapping.get(joint_parents[j], 255),
|
||||||
|
"bind": mat4_compose(gltf.nodes[j].translation, gltf.nodes[j].rotation, gltf.nodes[j].scale)
|
||||||
|
})
|
||||||
|
for k, v in joint_graph.copy().items():
|
||||||
|
if v in minimal_elements:
|
||||||
|
joint_graph[k] = None
|
||||||
|
if v == None:
|
||||||
|
del joint_graph[k]
|
||||||
|
|
||||||
|
for k3b in k3result["bones"]:
|
||||||
|
if k3b["parent"] != 255:
|
||||||
|
k3b["bind"] = k3result["bones"][k3b["parent"]]["bind"] @ k3b["bind"]
|
||||||
|
|
||||||
|
for anim_idx, animation in enumerate(gltf.animations):
|
||||||
|
timelines = {}
|
||||||
|
duration = 0
|
||||||
|
|
||||||
|
# Fill timelines from GLTF data
|
||||||
|
|
||||||
|
for channel in animation.channels:
|
||||||
|
target_node = channel.target.node
|
||||||
|
|
||||||
|
if target_node not in joint_gltf_to_k3_id_mapping:
|
||||||
|
# Not a bone
|
||||||
|
continue
|
||||||
|
|
||||||
|
sampler = animation.samplers[channel.sampler]
|
||||||
|
times = get(sampler.input)
|
||||||
|
values = get_nd(sampler.output)
|
||||||
|
|
||||||
|
timeline = []
|
||||||
|
|
||||||
|
for t, v in zip(times, values):
|
||||||
|
timeline.append((t, v))
|
||||||
|
duration = max(duration, t)
|
||||||
|
|
||||||
|
timeline.sort(key = lambda kf: kf[0])
|
||||||
|
|
||||||
|
timelines.setdefault(joint_gltf_to_k3_id_mapping[target_node], {})[channel.target.path] = timeline
|
||||||
|
|
||||||
|
# Make sure that all bones & transform types have at least one keyframe
|
||||||
|
|
||||||
|
for bone_id, k3b in enumerate(k3result["bones"]):
|
||||||
|
bone_timelines = timelines.setdefault(bone_id, {})
|
||||||
|
l = bone_timelines.setdefault("translation", [])
|
||||||
|
if len(l) == 0:
|
||||||
|
l.append((0, numpy.array([0, 0, 0])))
|
||||||
|
l = bone_timelines.setdefault("rotation", [])
|
||||||
|
if len(l) == 0:
|
||||||
|
l.append((0, numpy.array([0, 0, 0, 1])))
|
||||||
|
l = bone_timelines.setdefault("scale", [])
|
||||||
|
if len(l) == 0:
|
||||||
|
l.append((0, numpy.array([1, 1, 1])))
|
||||||
|
|
||||||
|
# Playback and store all bone transforms per frame as k3 format needs
|
||||||
|
|
||||||
|
fps = 30
|
||||||
|
frame_interval = 1 / fps
|
||||||
|
|
||||||
|
frame_times = numpy.arange(0, duration, frame_interval)
|
||||||
|
|
||||||
|
k3anim = {"id": anim_idx, "fps": fps, "frames": []}
|
||||||
|
|
||||||
|
for t in frame_times:
|
||||||
|
bone_transfs = []
|
||||||
|
|
||||||
|
for bone_id, k3b in enumerate(k3result["bones"]):
|
||||||
|
def dothing(transf_type, interp_func):
|
||||||
|
tm = timelines[bone_id][transf_type]
|
||||||
|
k1 = [k for k in range(len(tm)) if tm[k][0] <= t]
|
||||||
|
k2 = [k for k in range(len(tm)) if tm[k][0] > t]
|
||||||
|
k1 = max(k1) if len(k1) else 0
|
||||||
|
k2 = min(k2) if len(k2) else len(tm) - 1
|
||||||
|
alpha = (t - tm[k1][0]) / (tm[k2][0] - tm[k1][0]) if tm[k2][0] != tm[k1][0] else 0
|
||||||
|
return interp_func(tm[k1][1], tm[k2][1], alpha)
|
||||||
|
translation = dothing("translation", lerp)
|
||||||
|
rotation = dothing("rotation", slerp)
|
||||||
|
scale = dothing("scale", lerp)
|
||||||
|
|
||||||
|
bone_transfs.append((translation, rotation))
|
||||||
|
|
||||||
|
k3anim["frames"].append(bone_transfs)
|
||||||
|
|
||||||
|
k3result["animations"].append(k3anim)
|
||||||
|
|
||||||
|
# Finally, output
|
||||||
|
|
||||||
|
output_filename = pathlib.Path(input_filename).with_suffix(".k3m")
|
||||||
|
|
||||||
|
with open(output_filename, "wb") as f:
|
||||||
|
f.write(b"K3M ")
|
||||||
|
|
||||||
|
vertex_count = sum([len(mesh["positions"]) for mesh in k3result["meshes"]])
|
||||||
|
index_count = sum([len(mesh["indices"]) for mesh in k3result["meshes"]])
|
||||||
|
|
||||||
|
f.write(struct.pack("I", vertex_count))
|
||||||
|
f.write(struct.pack("I", index_count))
|
||||||
|
f.write(struct.pack("B", len(k3result["bones"])))
|
||||||
|
|
||||||
|
colorsEnabled = any([mesh["colors"] is not None for mesh in k3result["meshes"]])
|
||||||
|
|
||||||
|
# todo
|
||||||
|
colorsEnabled = False
|
||||||
|
|
||||||
|
f.write(struct.pack("B", 1 if colorsEnabled else 0))
|
||||||
|
|
||||||
|
f.write(struct.pack("H", len(k3result["animations"])))
|
||||||
|
|
||||||
|
for k3b in k3result["bones"]:
|
||||||
|
f.write(struct.pack("16f", *numpy.reshape(numpy.linalg.inv(k3b["bind"]), (16,))))
|
||||||
|
for k3b in k3result["bones"]:
|
||||||
|
f.write(struct.pack("B", k3b["parent"]))
|
||||||
|
|
||||||
|
for mesh in k3result["meshes"]:
|
||||||
|
f.write(mesh["positions"][:, :3].astype(numpy.float32).ravel().tobytes())
|
||||||
|
|
||||||
|
for mesh in k3result["meshes"]:
|
||||||
|
normals = mesh["normals"][:, :3].astype(numpy.float32)
|
||||||
|
for i in range(len(normals)):
|
||||||
|
normals[i] /= numpy.max(numpy.abs(normals[i]))
|
||||||
|
normals[i] *= 127
|
||||||
|
f.write(normals.astype(numpy.int8).ravel().tobytes())
|
||||||
|
|
||||||
|
for mesh in k3result["meshes"]:
|
||||||
|
f.write(mesh["uvs"][:, :2].astype(numpy.float32).ravel().tobytes())
|
||||||
|
|
||||||
|
if mesh["boneids"] is not None:
|
||||||
|
for mesh in k3result["meshes"]:
|
||||||
|
f.write(mesh["boneids"][:, :4].astype(numpy.int8).ravel().tobytes())
|
||||||
|
|
||||||
|
for mesh in k3result["meshes"]:
|
||||||
|
f.write((mesh["boneweights"][:, :4].astype(numpy.float32) * 65535).astype(numpy.int16).ravel().tobytes())
|
||||||
|
|
||||||
|
if colorsEnabled:
|
||||||
|
# TODO
|
||||||
|
#for mesh in k3result["colors"]:
|
||||||
|
# f.write(mesh["colors"][:, :4])
|
||||||
|
pass
|
||||||
|
|
||||||
|
for mesh in k3result["meshes"]:
|
||||||
|
f.write(mesh["indices"].astype(numpy.uint16).tobytes())
|
||||||
|
|
||||||
|
f.write(struct.pack("H", len(k3result["meshes"])))
|
||||||
|
|
||||||
|
offset = 0
|
||||||
|
for mesh in k3result["meshes"]:
|
||||||
|
ind_count = len(mesh["indices"])
|
||||||
|
f.write(struct.pack("2H", offset, ind_count))
|
||||||
|
f.write(mesh["material_name"].encode("UTF-8") + b'\x00')
|
||||||
|
offset += ind_count
|
||||||
|
|
||||||
|
for anim in k3result["animations"]:
|
||||||
|
f.write(struct.pack("4H", anim["id"], len(anim["frames"]), anim["fps"], 0))
|
||||||
|
|
||||||
|
for frame in anim["frames"]:
|
||||||
|
for bone_idx in range(len(k3result["bones"])):
|
||||||
|
f.write(struct.pack("4f", frame[bone_idx][0][0], frame[bone_idx][0][1], frame[bone_idx][0][2], 1))
|
||||||
|
f.write(struct.pack("4f", *frame[bone_idx][1]))
|
||||||
1
k3
Submodule
1
k3
Submodule
Submodule k3 added at 4d74b5e3e9
321
src/game.c
321
src/game.c
@@ -5,6 +5,8 @@
|
|||||||
#include"resman.h"
|
#include"resman.h"
|
||||||
#include<cglm/vec3.h>
|
#include<cglm/vec3.h>
|
||||||
|
|
||||||
|
#define SUBFEET(cp) (cp->capsule.radius)
|
||||||
|
|
||||||
struct Game Game;
|
struct Game Game;
|
||||||
|
|
||||||
void game_init() {
|
void game_init() {
|
||||||
@@ -29,8 +31,8 @@ void game_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct CollisionPair {
|
struct CollisionPair {
|
||||||
dGeomID g1; // greater
|
uint16_t e1; // greater
|
||||||
dGeomID g2; // lesser
|
uint16_t e2; // lesser
|
||||||
uint8_t x;
|
uint8_t x;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
static size_t activeCollisionCount, activeCollisionCapacity;
|
static size_t activeCollisionCount, activeCollisionCapacity;
|
||||||
@@ -38,22 +40,22 @@ static struct CollisionPair *activeCollisions;
|
|||||||
int pair_comparator(const void *a_, const void *b_) {
|
int pair_comparator(const void *a_, const void *b_) {
|
||||||
const struct CollisionPair *a = a_;
|
const struct CollisionPair *a = a_;
|
||||||
const struct CollisionPair *b = b_;
|
const struct CollisionPair *b = b_;
|
||||||
if(a->g1 == b->g1) {
|
if(a->e1 == b->e1) {
|
||||||
return (uintptr_t) a->g2 - (uintptr_t) b->g2;
|
return (intmax_t) a->e2 - (intmax_t) b->e2;
|
||||||
} else {
|
} else {
|
||||||
return (uintptr_t) a->g1 - (uintptr_t) b->g1;
|
return (intmax_t) a->e1 - (intmax_t) b->e1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static int activate_pair(dGeomID g1, dGeomID g2) {
|
static int activate_pair(uint16_t e1, uint16_t e2) {
|
||||||
struct CollisionPair p = {
|
struct CollisionPair p = {
|
||||||
.g1 = g1 > g2 ? g1 : g2,
|
.e1 = e1 > e2 ? e1 : e2,
|
||||||
.g2 = g1 > g2 ? g2 : g1,
|
.e2 = e1 > e2 ? e2 : e1,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CollisionPair *peepee = bsearch(&p, activeCollisions, activeCollisionCount, sizeof(struct CollisionPair), pair_comparator);
|
struct CollisionPair *peepee = bsearch(&p, activeCollisions, activeCollisionCount, sizeof(struct CollisionPair), pair_comparator);
|
||||||
|
|
||||||
if(peepee) {
|
if(peepee) {
|
||||||
peepee->x++;
|
peepee->x = 2;
|
||||||
return TRIGGER_EV_CONTINUOUS;
|
return TRIGGER_EV_CONTINUOUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,8 +74,8 @@ static int activate_pair(dGeomID g1, dGeomID g2) {
|
|||||||
static void tick_pairs() {
|
static void tick_pairs() {
|
||||||
for(size_t i = 0; i < activeCollisionCount;) {
|
for(size_t i = 0; i < activeCollisionCount;) {
|
||||||
if(--activeCollisions[i].x == 0) {
|
if(--activeCollisions[i].x == 0) {
|
||||||
uint16_t e1 = (uintptr_t) dGeomGetData(activeCollisions[i].g1);
|
uint16_t e1 = activeCollisions[i].e1;
|
||||||
uint16_t e2 = (uintptr_t) dGeomGetData(activeCollisions[i].g2);
|
uint16_t e2 = activeCollisions[i].e2;
|
||||||
|
|
||||||
if(e1 != ENT_ID_INVALID) {
|
if(e1 != ENT_ID_INVALID) {
|
||||||
struct CPhysics *p1 = game_getcomponent(e1, physics);
|
struct CPhysics *p1 = game_getcomponent(e1, physics);
|
||||||
@@ -97,10 +99,21 @@ static void tick_pairs() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vec3_project_to_plane(vec3 v, vec3 n, vec3 ret) {
|
||||||
|
float scale = glm_vec3_dot(v, n) / glm_vec3_dot(n, n);
|
||||||
|
|
||||||
|
vec3 n2;
|
||||||
|
glm_vec3_scale(n, scale, n2);
|
||||||
|
|
||||||
|
glm_vec3_sub(v, n2, ret);
|
||||||
|
}
|
||||||
|
|
||||||
static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
|
static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
|
||||||
uint16_t e1 = (uintptr_t) dGeomGetData(g1);
|
uint16_t e1 = (uintptr_t) dGeomGetData(g1);
|
||||||
uint16_t e2 = (uintptr_t) dGeomGetData(g2);
|
uint16_t e2 = (uintptr_t) dGeomGetData(g2);
|
||||||
|
|
||||||
|
if(e1 != ENT_ID_INVALID && e1 == e2) return;
|
||||||
|
|
||||||
dBodyID b1 = dGeomGetBody(g1);
|
dBodyID b1 = dGeomGetBody(g1);
|
||||||
dBodyID b2 = dGeomGetBody(g2);
|
dBodyID b2 = dGeomGetBody(g2);
|
||||||
|
|
||||||
@@ -124,8 +137,6 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
|
|||||||
if(movingPlatform) {
|
if(movingPlatform) {
|
||||||
const dReal *platvel = dBodyGetLinearVel(movingPlatform == 1 ? b1 : b2);
|
const dReal *platvel = dBodyGetLinearVel(movingPlatform == 1 ? b1 : b2);
|
||||||
|
|
||||||
//if(i == 0)printf("get %f %f %f\n", platvel[0], platvel[1], platvel[2]);
|
|
||||||
|
|
||||||
contact[i].surface.mode |= dContactMotion1 | dContactMotion2 | dContactMotionN | dContactFDir1;
|
contact[i].surface.mode |= dContactMotion1 | dContactMotion2 | dContactMotionN | dContactFDir1;
|
||||||
contact[i].surface.mode |= dContactSoftERP;
|
contact[i].surface.mode |= dContactSoftERP;
|
||||||
contact[i].surface.soft_erp = 0.9;
|
contact[i].surface.soft_erp = 0.9;
|
||||||
@@ -146,17 +157,42 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
|
|||||||
|
|
||||||
int ghost = 0;
|
int ghost = 0;
|
||||||
|
|
||||||
|
if(dGeomGetCategoryBits(g1) & CATEGORY_GHOST) ghost = 1;
|
||||||
|
if(dGeomGetCategoryBits(g2) & CATEGORY_GHOST) ghost = 1;
|
||||||
|
|
||||||
if(numc) {
|
if(numc) {
|
||||||
int triggerType = activate_pair(g1, g2);
|
int triggerType = activate_pair(e1, e2);
|
||||||
|
|
||||||
if(e1 != ENT_ID_INVALID) {
|
if(e1 != ENT_ID_INVALID) {
|
||||||
if(game_getcomponent(e1, physics)->dynamics & CPHYSICS_GHOST) {
|
struct CPhysics *cp = game_getcomponent(e1, physics);
|
||||||
|
if(!cp) {
|
||||||
|
// Entity being killed maybe
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cp->dynamics & CPHYSICS_GHOST) {
|
||||||
|
ghost = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CMovement *cm = game_getcomponent(e1, movement);
|
||||||
|
if(cm && cm->holding != ENT_ID_INVALID && cm->holding == e2) {
|
||||||
ghost = 1;
|
ghost = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(e2 != ENT_ID_INVALID) {
|
if(e2 != ENT_ID_INVALID) {
|
||||||
if(game_getcomponent(e2, physics)->dynamics & CPHYSICS_GHOST) {
|
struct CPhysics *cp = game_getcomponent(e2, physics);
|
||||||
|
if(!cp) {
|
||||||
|
// Entity being killed maybe
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cp->dynamics & CPHYSICS_GHOST) {
|
||||||
|
ghost = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CMovement *cm = game_getcomponent(e2, movement);
|
||||||
|
if(cm && cm->holding != ENT_ID_INVALID && cm->holding == e1) {
|
||||||
ghost = 1;
|
ghost = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,37 +204,6 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
|
|||||||
|
|
||||||
friction *= c->friction;
|
friction *= c->friction;
|
||||||
|
|
||||||
vec4 q;
|
|
||||||
if(b1) {
|
|
||||||
memcpy(q, dBodyGetQuaternion(b1), sizeof(q));
|
|
||||||
} else {
|
|
||||||
dGeomGetQuaternion(c->geom, q);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
float temp = q[0];
|
|
||||||
q[0] = q[1];
|
|
||||||
q[1] = q[2];
|
|
||||||
q[2] = q[3];
|
|
||||||
q[3] = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 n = {0, 1, 0};
|
|
||||||
glm_quat_rotatev(q, n, n);
|
|
||||||
|
|
||||||
if(!ghost) for(int i = 0; i < numc; i++) {
|
|
||||||
if(glm_vec3_dot(contact[i].geom.normal, n) >= 0.7) {
|
|
||||||
struct CMovement *m = game_getcomponent(e1, movement);
|
|
||||||
if(m) {
|
|
||||||
if(m->holding != ENT_ID_INVALID && m->holding == e2) {
|
|
||||||
ghost = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
m->canJump = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(c->trigger != TRIGGER_INVALID) {
|
if(c->trigger != TRIGGER_INVALID) {
|
||||||
Game.triggers[c->trigger - 1](c->trigger, e1, e2, triggerType);
|
Game.triggers[c->trigger - 1](c->trigger, e1, e2, triggerType);
|
||||||
}
|
}
|
||||||
@@ -209,37 +214,6 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
|
|||||||
|
|
||||||
friction *= c->friction;
|
friction *= c->friction;
|
||||||
|
|
||||||
vec4 q;
|
|
||||||
if(b2) {
|
|
||||||
memcpy(q, dBodyGetQuaternion(b2), sizeof(q));
|
|
||||||
} else {
|
|
||||||
dGeomGetQuaternion(c->geom, q);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
float temp = q[0];
|
|
||||||
q[0] = q[1];
|
|
||||||
q[1] = q[2];
|
|
||||||
q[2] = q[3];
|
|
||||||
q[3] = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 n = {0, -1, 0};
|
|
||||||
glm_quat_rotatev(q, n, n);
|
|
||||||
|
|
||||||
if(!ghost) for(int i = 0; i < numc; i++) {
|
|
||||||
if(glm_vec3_dot(contact[i].geom.normal, n) >= 0.7) {
|
|
||||||
struct CMovement *m = game_getcomponent(e2, movement);
|
|
||||||
if(m) {
|
|
||||||
if(m->holding != ENT_ID_INVALID && m->holding == e1) {
|
|
||||||
ghost = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
m->canJump = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(c->trigger != TRIGGER_INVALID) {
|
if(c->trigger != TRIGGER_INVALID) {
|
||||||
Game.triggers[c->trigger - 1](c->trigger, e2, e1, triggerType);
|
Game.triggers[c->trigger - 1](c->trigger, e2, e1, triggerType);
|
||||||
}
|
}
|
||||||
@@ -337,7 +311,102 @@ void game_raycast(struct LocalRay *rays, size_t count) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void game_character_controller_raycast_handler(void *data, dGeomID g1, dGeomID g2) {
|
||||||
|
if(dGeomGetClass(g1) != dRayClass && dGeomGetClass(g2) != dRayClass) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t e1 = (uintptr_t) dGeomGetData(g1);
|
||||||
|
uint16_t e2 = (uintptr_t) dGeomGetData(g2);
|
||||||
|
|
||||||
|
if(e1 == e2) {
|
||||||
|
// This means the ray is hitting the entity casting it.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dContact contact[1];
|
||||||
|
memset(contact, 0, sizeof(contact));
|
||||||
|
|
||||||
|
int numc = dCollide(g1, g2, 1, &contact[0].geom, sizeof(dContact));
|
||||||
|
|
||||||
|
if(numc) {
|
||||||
|
|
||||||
|
vec3 n = {0, -1, 0};
|
||||||
|
|
||||||
|
struct CPhysics *cp1 = game_getcomponent(e1, physics);
|
||||||
|
struct CPhysics *cp2 = game_getcomponent(e2, physics);
|
||||||
|
|
||||||
|
if((cp2 && (cp2->dynamics & CPHYSICS_GHOST)) || (cp1 && (cp1->dynamics & CPHYSICS_GHOST))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dGeomGetClass(g1) == dRayClass) {
|
||||||
|
dBodyID bid = dGeomGetBody(cp1->geom);
|
||||||
|
|
||||||
|
struct CMovement *cm = game_getcomponent(e1, movement);
|
||||||
|
|
||||||
|
cm->groundDepth = dGeomRayGetLength(g1) - contact[0].geom.depth;
|
||||||
|
|
||||||
|
if(glm_vec3_dot(contact[0].geom.normal, n) <= -0.7 && cm->groundDepth > SUBFEET(cp1)) {
|
||||||
|
cm->canJump = 1;
|
||||||
|
glm_vec3_scale(contact[0].geom.normal, -1, cm->groundNormal);
|
||||||
|
}
|
||||||
|
} else if(dGeomGetClass(g2) == dRayClass) {
|
||||||
|
dBodyID bid = dGeomGetBody(cp2->geom);
|
||||||
|
|
||||||
|
struct CMovement *cm = game_getcomponent(e2, movement);
|
||||||
|
|
||||||
|
cm->groundDepth = dGeomRayGetLength(g2) - contact[0].geom.depth;
|
||||||
|
|
||||||
|
if(glm_vec3_dot(contact[0].geom.normal, n) >= +0.7 && cm->groundDepth > SUBFEET(cp2)) {
|
||||||
|
cm->canJump = 1;
|
||||||
|
glm_vec3_scale(contact[0].geom.normal, +1, cm->groundNormal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void game_character_controller_raycast() {
|
||||||
|
dGeomID rayGeoms[Game.entities.movementCount];
|
||||||
|
|
||||||
|
for(size_t i = 0; i < Game.entities.movementCount; i++) {
|
||||||
|
Game.entities.movement[i].canJump = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < Game.entities.movementCount; i++) {
|
||||||
|
struct CPhysics *cp = game_getcomponent(Game.entities.movement[i].entity, physics);
|
||||||
|
|
||||||
|
if(!cp || !cp->geom || cp->type != CPHYSICS_CAPSULE) {
|
||||||
|
rayGeoms[i] = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rayGeoms[i] = dCreateRay(Game.space, cp->capsule.length / 2 + cp->capsule.radius + SUBFEET(cp));
|
||||||
|
|
||||||
|
dGeomSetData(rayGeoms[i], (void*) (uintptr_t) Game.entities.movement[i].entity);
|
||||||
|
|
||||||
|
dGeomSetCategoryBits(rayGeoms[i], CATEGORY_RAY);
|
||||||
|
dGeomSetCollideBits(rayGeoms[i], CATEGORY_STATIC | CATEGORY_ENTITY);
|
||||||
|
|
||||||
|
dBodyID bid = dGeomGetBody(cp->geom);
|
||||||
|
|
||||||
|
const float *position = dBodyGetPosition(bid);
|
||||||
|
|
||||||
|
dGeomRaySet(rayGeoms[i], position[0], position[1], position[2], 0, -1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
dSpaceCollide(Game.space, NULL, game_character_controller_raycast_handler);
|
||||||
|
|
||||||
|
for(int i = 0; i < Game.entities.movementCount; i++) {
|
||||||
|
if(rayGeoms[i]) {
|
||||||
|
dGeomDestroy(rayGeoms[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void game_update() {
|
void game_update() {
|
||||||
|
game_character_controller_raycast();
|
||||||
|
|
||||||
for(size_t i = 0; i < Game.entities.playerctrlCount; i++) {
|
for(size_t i = 0; i < Game.entities.playerctrlCount; i++) {
|
||||||
struct CPlayerCtrl *cc = &Game.entities.playerctrl[i];
|
struct CPlayerCtrl *cc = &Game.entities.playerctrl[i];
|
||||||
|
|
||||||
@@ -383,9 +452,18 @@ void game_update() {
|
|||||||
if(cp && cp->geom) {
|
if(cp && cp->geom) {
|
||||||
dBodyID bid = dGeomGetBody(cp->geom);
|
dBodyID bid = dGeomGetBody(cp->geom);
|
||||||
if(Game.entities.movement[i].canJump) {
|
if(Game.entities.movement[i].canJump) {
|
||||||
dBodySetLinearVel(bid, 0, 0, 0);
|
if(dBodyGetLinearVel(bid)[1] <= 0) {
|
||||||
|
Game.entities.movement[i].isJumping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Game.entities.movement[i].isJumping) {
|
||||||
|
const float *pos = dBodyGetPosition(bid);
|
||||||
|
dBodySetPosition(bid, pos[0], pos[1] + Game.entities.movement[i].groundDepth - cp->capsule.radius / 2 - SUBFEET(cp), pos[2]);
|
||||||
|
|
||||||
|
dBodySetLinearVel(bid, 0, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dBodySetGravityMode(bid, !Game.entities.movement[i].canJump);
|
dBodySetGravityMode(bid, Game.entities.movement[i].canJump && !Game.entities.movement[i].isJumping ? 0 : 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,14 +499,21 @@ void game_update() {
|
|||||||
Game.entities.physics[i].box.l);
|
Game.entities.physics[i].box.l);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case CPHYSICS_CAPSULE:
|
case CPHYSICS_CAPSULE: {
|
||||||
Game.entities.physics[i].geom = dCreateCapsule(Game.space,
|
dGeomID top = dCreateCapsule(Game.space,
|
||||||
Game.entities.physics[i].capsule.radius,
|
Game.entities.physics[i].capsule.radius,
|
||||||
Game.entities.physics[i].capsule.length);
|
Game.entities.physics[i].capsule.length - Game.entities.physics[i].capsule.radius);
|
||||||
|
|
||||||
|
dGeomID feet = dCreateSphere(Game.space,
|
||||||
|
Game.entities.physics[i].capsule.radius);
|
||||||
|
|
||||||
|
Game.entities.physics[i].geom = top;
|
||||||
|
Game.entities.physics[i].geom2 = feet;
|
||||||
|
|
||||||
dMassSetCapsuleTotal(&mass, Game.entities.physics[i].mass, 2, Game.entities.physics[i].capsule.radius, Game.entities.physics[i].capsule.length);
|
dMassSetCapsuleTotal(&mass, Game.entities.physics[i].mass, 2, Game.entities.physics[i].capsule.radius, Game.entities.physics[i].capsule.length);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case CPHYSICS_SPHERE:
|
case CPHYSICS_SPHERE:
|
||||||
Game.entities.physics[i].geom = dCreateSphere(Game.space,
|
Game.entities.physics[i].geom = dCreateSphere(Game.space,
|
||||||
Game.entities.physics[i].sphere.radius);
|
Game.entities.physics[i].sphere.radius);
|
||||||
@@ -442,6 +527,12 @@ void game_update() {
|
|||||||
dGeomSetCollideBits(Game.entities.physics[i].geom, Game.entities.physics[i].collide);
|
dGeomSetCollideBits(Game.entities.physics[i].geom, Game.entities.physics[i].collide);
|
||||||
dGeomSetData(Game.entities.physics[i].geom, (void*) Game.entities.physics[i].entity);
|
dGeomSetData(Game.entities.physics[i].geom, (void*) Game.entities.physics[i].entity);
|
||||||
|
|
||||||
|
if(Game.entities.physics[i].type == CPHYSICS_CAPSULE) {
|
||||||
|
dGeomSetCategoryBits(Game.entities.physics[i].geom2, CATEGORY_ENTITY | CATEGORY_GHOST);
|
||||||
|
dGeomSetCollideBits(Game.entities.physics[i].geom2, Game.entities.physics[i].collide);
|
||||||
|
dGeomSetData(Game.entities.physics[i].geom2, (void*) Game.entities.physics[i].entity);
|
||||||
|
}
|
||||||
|
|
||||||
if((Game.entities.physics[i].dynamics & ~CPHYSICS_GHOST) != CPHYSICS_STATIC) {
|
if((Game.entities.physics[i].dynamics & ~CPHYSICS_GHOST) != CPHYSICS_STATIC) {
|
||||||
dBodyID body = dBodyCreate(Game.phys);
|
dBodyID body = dBodyCreate(Game.phys);
|
||||||
|
|
||||||
@@ -452,10 +543,16 @@ void game_update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dGeomSetBody(Game.entities.physics[i].geom, body);
|
dGeomSetBody(Game.entities.physics[i].geom, body);
|
||||||
|
if(Game.entities.physics[i].geom2) {
|
||||||
|
dGeomSetBody(Game.entities.physics[i].geom2, body);
|
||||||
|
}
|
||||||
|
|
||||||
if(Game.entities.physics[i].type == CPHYSICS_CAPSULE) {
|
if(Game.entities.physics[i].type == CPHYSICS_CAPSULE) {
|
||||||
dBodySetMaxAngularSpeed(body, 0);
|
dBodySetMaxAngularSpeed(body, 0);
|
||||||
|
|
||||||
|
dGeomSetOffsetPosition(Game.entities.physics[i].geom, 0, Game.entities.physics[i].capsule.radius / 2, 0);
|
||||||
|
dGeomSetOffsetPosition(Game.entities.physics[i].geom2, 0, -Game.entities.physics[i].capsule.length / 2, 0);
|
||||||
|
|
||||||
// Rotate to Y-up
|
// Rotate to Y-up
|
||||||
dQuaternion q;
|
dQuaternion q;
|
||||||
dQFromAxisAndAngle(q, 1, 0, 0, M_PI * 0.5);
|
dQFromAxisAndAngle(q, 1, 0, 0, M_PI * 0.5);
|
||||||
@@ -516,6 +613,10 @@ void game_update() {
|
|||||||
if(glm_vec3_norm(wishvel) > 3) {
|
if(glm_vec3_norm(wishvel) > 3) {
|
||||||
glm_vec3_scale_as(wishvel, 3, wishvel);
|
glm_vec3_scale_as(wishvel, 3, wishvel);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// We project the movement vector onto the ground plane (set by game_character_controller_raycast_handler)
|
||||||
|
// to "slide" along the ground with minimal bouncing
|
||||||
|
vec3_project_to_plane(wishvel, Game.entities.movement[mi].groundNormal, wishvel);
|
||||||
}
|
}
|
||||||
|
|
||||||
float currentspeed = glm_vec3_dot(wishvel, dBodyGetLinearVel(bid));
|
float currentspeed = glm_vec3_dot(wishvel, dBodyGetLinearVel(bid));
|
||||||
@@ -538,23 +639,19 @@ void game_update() {
|
|||||||
dQFromAxisAndAngle(q, 0, 1, 0, Game.entities.movement[mi].pointing + M_PI);
|
dQFromAxisAndAngle(q, 0, 1, 0, Game.entities.movement[mi].pointing + M_PI);
|
||||||
dBodySetQuaternion(bid, q);
|
dBodySetQuaternion(bid, q);
|
||||||
|
|
||||||
if(Game.entities.movement[mi].jump && (0||Game.entities.movement[mi].canJump)) {
|
if(Game.entities.movement[mi].jump && Game.entities.movement[mi].canJump) {
|
||||||
Game.entities.movement[mi].canJump = 0;
|
dVector3 force = {};
|
||||||
|
dWorldImpulseToForce(Game.phys, 1.f / GAME_TPS, 0, 6.5, 0, force);
|
||||||
dVector3 force;
|
|
||||||
dWorldImpulseToForce(Game.phys, 1.f / GAME_TPS, 0, 5, 0, force);
|
|
||||||
|
|
||||||
if(bid) {
|
if(bid) {
|
||||||
dBodyAddForce(bid, force[0], force[1], force[2]);
|
dBodyAddForce(bid, force[0], force[1], force[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Game.entities.movement[mi].isJumping = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(size_t i = 0; i < Game.entities.movementCount; i++) {
|
|
||||||
Game.entities.movement[i].canJump = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dSpaceCollide(Game.space, 0, &contact_callback);
|
dSpaceCollide(Game.space, 0, &contact_callback);
|
||||||
|
|
||||||
tick_pairs();
|
tick_pairs();
|
||||||
@@ -889,10 +986,46 @@ void game_cleanup() {
|
|||||||
Game.phys = dWorldCreate();
|
Game.phys = dWorldCreate();
|
||||||
dWorldSetGravity(Game.phys, 0, -15, 0);
|
dWorldSetGravity(Game.phys, 0, -15, 0);
|
||||||
|
|
||||||
dWorldSetCFM(Game.phys, 0.0001);
|
dWorldSetCFM(Game.phys, 0.00002);
|
||||||
dWorldSetERP(Game.phys, 0.5);
|
dWorldSetERP(Game.phys, 0.1);
|
||||||
|
|
||||||
Game.space = dHashSpaceCreate(NULL);
|
Game.space = dHashSpaceCreate(NULL);
|
||||||
|
|
||||||
Game.contactgroup = dJointGroupCreate(0);
|
Game.contactgroup = dJointGroupCreate(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void game_killentity(uint16_t eid) {
|
||||||
|
// XXX: Go over ALL component types!
|
||||||
|
|
||||||
|
struct CPhysics *cp = game_getcomponent(eid, physics);
|
||||||
|
if(cp) {
|
||||||
|
dBodyID bid = dGeomGetBody(cp->geom);
|
||||||
|
|
||||||
|
if(bid) {
|
||||||
|
for(dGeomID gid = dBodyGetFirstGeom(bid); gid; gid = dBodyGetNextGeom(gid)) {
|
||||||
|
dGeomDestroy(gid);
|
||||||
|
}
|
||||||
|
|
||||||
|
dBodyDestroy(bid);
|
||||||
|
} else {
|
||||||
|
dGeomDestroy(cp->geom);
|
||||||
|
}
|
||||||
|
|
||||||
|
game_killcomponent_ptr(cp, physics);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CRender *cr = game_getcomponent(eid, render);
|
||||||
|
if(cr) {
|
||||||
|
if(cr->cache) {
|
||||||
|
if(resman_rev(cr->cache)) {
|
||||||
|
resman_unref(RESMAN_MODEL, cr->cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
game_killcomponent_ptr(cr, render);
|
||||||
|
}
|
||||||
|
|
||||||
|
game_killcomponent(eid, movement);
|
||||||
|
game_killcomponent(eid, playerctrl);
|
||||||
|
game_killcomponent(eid, boned);
|
||||||
|
}
|
||||||
|
|||||||
24
src/game.h
24
src/game.h
@@ -13,6 +13,7 @@
|
|||||||
#define CATEGORY_STATIC 1
|
#define CATEGORY_STATIC 1
|
||||||
#define CATEGORY_RAY 2
|
#define CATEGORY_RAY 2
|
||||||
#define CATEGORY_ENTITY 4
|
#define CATEGORY_ENTITY 4
|
||||||
|
#define CATEGORY_GHOST 8
|
||||||
|
|
||||||
#define TRIGGER_INVALID 0
|
#define TRIGGER_INVALID 0
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ struct TrimeshData {
|
|||||||
#define CPHYSICS_GHOST 128
|
#define CPHYSICS_GHOST 128
|
||||||
struct CPhysics {
|
struct CPhysics {
|
||||||
uint16_t entity;
|
uint16_t entity;
|
||||||
dGeomID geom;
|
dGeomID geom, geom2;
|
||||||
uint16_t trigger;
|
uint16_t trigger;
|
||||||
|
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
@@ -87,7 +88,9 @@ struct CMovement {
|
|||||||
uint16_t entity;
|
uint16_t entity;
|
||||||
vec3 dir;
|
vec3 dir;
|
||||||
float pointing;
|
float pointing;
|
||||||
char jump, canJump;
|
char jump, canJump, isJumping;
|
||||||
|
vec3 groundNormal;
|
||||||
|
float groundDepth;
|
||||||
uint16_t holding;
|
uint16_t holding;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -214,7 +217,7 @@ static inline size_t game_nextid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void game_claimentid(size_t i) {
|
static inline void game_claimentid(size_t i) {
|
||||||
Game.entities.freeIDs[i / 64] |= 1 << (i % 64);
|
Game.entities.freeIDs[i / 64] |= 1UL << (i % 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int game_componentcomparator(const void *a, const void *b) {
|
static inline int game_componentcomparator(const void *a, const void *b) {
|
||||||
@@ -248,7 +251,22 @@ static inline void *game_ensurecomponent_(uint16_t eid, void *array, size_t comp
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define game_killcomponent_ptr(c, arr) do { \
|
||||||
|
size_t idx = c - Game.entities.arr; \
|
||||||
|
memmove(c, c + 1, sizeof(*c) * (Game.entities.arr##Count - idx - 1)); \
|
||||||
|
Game.entities.arr##Count--; \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
#define game_killcomponent(eid, arr) do { \
|
||||||
|
typeof(&Game.entities.arr[0]) c = game_getcomponent(eid, arr); \
|
||||||
|
if(c) { \
|
||||||
|
game_killcomponent_ptr(c, arr); \
|
||||||
|
} \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
// An artifact of using a third-party physics engine
|
// An artifact of using a third-party physics engine
|
||||||
void game_synccphysics();
|
void game_synccphysics();
|
||||||
|
|
||||||
void game_cleanup();
|
void game_cleanup();
|
||||||
|
|
||||||
|
void game_killentity(uint16_t eid);
|
||||||
|
|||||||
84
src/gl.h
84
src/gl.h
@@ -1,11 +1,11 @@
|
|||||||
/**
|
/**
|
||||||
* Loader generated by glad 2.0.8 on Sun Nov 17 08:36:10 2024
|
* Loader generated by glad 2.0.8 on Fri May 9 09:20:04 2025
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
|
* SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
|
||||||
*
|
*
|
||||||
* Generator: C/C++
|
* Generator: C/C++
|
||||||
* Specification: gl
|
* Specification: gl
|
||||||
* Extensions: 31
|
* Extensions: 37
|
||||||
*
|
*
|
||||||
* APIs:
|
* APIs:
|
||||||
* - gl:compatibility=4.6
|
* - gl:compatibility=4.6
|
||||||
@@ -19,10 +19,10 @@
|
|||||||
* - ON_DEMAND = False
|
* - ON_DEMAND = False
|
||||||
*
|
*
|
||||||
* Commandline:
|
* Commandline:
|
||||||
* --api='gl:compatibility=4.6' --extensions='GL_ARB_compatibility,GL_ARB_debug_output,GL_ARB_fragment_program,GL_ARB_fragment_shader,GL_ARB_framebuffer_sRGB,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_storage_buffer_object,GL_ARB_shading_language_100,GL_ARB_texture_float,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_2_10_10_10_rev,GL_EXT_direct_state_access,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_shader4,GL_EXT_shader_image_load_store,GL_EXT_texture_array,GL_EXT_texture_compression_s3tc,GL_EXT_texture_integer,GL_EXT_texture_sRGB,GL_EXT_transform_feedback,GL_INTEL_conservative_rasterization,GL_NV_conservative_raster' c --header-only
|
* --api='gl:compatibility=4.6' --extensions='GL_ARB_compatibility,GL_ARB_debug_output,GL_ARB_fragment_program,GL_ARB_fragment_shader,GL_ARB_framebuffer_sRGB,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_storage_buffer_object,GL_ARB_shading_language_100,GL_ARB_texture_compression_bptc,GL_ARB_texture_float,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_2_10_10_10_rev,GL_EXT_direct_state_access,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_shader4,GL_EXT_shader_image_load_store,GL_EXT_texture_array,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_integer,GL_EXT_texture_sRGB,GL_EXT_transform_feedback,GL_INTEL_conservative_rasterization,GL_KHR_texture_compression_astc_ldr,GL_NV_conservative_raster' c --header-only
|
||||||
*
|
*
|
||||||
* Online:
|
* Online:
|
||||||
* http://glad.sh/#api=gl%3Acompatibility%3D4.6&extensions=GL_ARB_compatibility%2CGL_ARB_debug_output%2CGL_ARB_fragment_program%2CGL_ARB_fragment_shader%2CGL_ARB_framebuffer_sRGB%2CGL_ARB_shader_image_load_store%2CGL_ARB_shader_image_size%2CGL_ARB_shader_objects%2CGL_ARB_shader_storage_buffer_object%2CGL_ARB_shading_language_100%2CGL_ARB_texture_float%2CGL_ARB_texture_rg%2CGL_ARB_texture_rgb10_a2ui%2CGL_ARB_vertex_buffer_object%2CGL_ARB_vertex_program%2CGL_ARB_vertex_shader%2CGL_ARB_vertex_type_2_10_10_10_rev%2CGL_EXT_direct_state_access%2CGL_EXT_framebuffer_blit%2CGL_EXT_framebuffer_object%2CGL_EXT_framebuffer_sRGB%2CGL_EXT_geometry_shader4%2CGL_EXT_gpu_shader4%2CGL_EXT_shader_image_load_store%2CGL_EXT_texture_array%2CGL_EXT_texture_compression_s3tc%2CGL_EXT_texture_integer%2CGL_EXT_texture_sRGB%2CGL_EXT_transform_feedback%2CGL_INTEL_conservative_rasterization%2CGL_NV_conservative_raster&generator=c&options=HEADER_ONLY
|
* http://glad.sh/#api=gl%3Acompatibility%3D4.6&extensions=GL_ARB_compatibility%2CGL_ARB_debug_output%2CGL_ARB_fragment_program%2CGL_ARB_fragment_shader%2CGL_ARB_framebuffer_sRGB%2CGL_ARB_shader_image_load_store%2CGL_ARB_shader_image_size%2CGL_ARB_shader_objects%2CGL_ARB_shader_storage_buffer_object%2CGL_ARB_shading_language_100%2CGL_ARB_texture_compression_bptc%2CGL_ARB_texture_float%2CGL_ARB_texture_rg%2CGL_ARB_texture_rgb10_a2ui%2CGL_ARB_vertex_buffer_object%2CGL_ARB_vertex_program%2CGL_ARB_vertex_shader%2CGL_ARB_vertex_type_2_10_10_10_rev%2CGL_EXT_direct_state_access%2CGL_EXT_framebuffer_blit%2CGL_EXT_framebuffer_multisample%2CGL_EXT_framebuffer_multisample_blit_scaled%2CGL_EXT_framebuffer_object%2CGL_EXT_framebuffer_sRGB%2CGL_EXT_geometry_shader4%2CGL_EXT_gpu_shader4%2CGL_EXT_shader_image_load_store%2CGL_EXT_texture_array%2CGL_EXT_texture_compression_rgtc%2CGL_EXT_texture_compression_s3tc%2CGL_EXT_texture_filter_anisotropic%2CGL_EXT_texture_integer%2CGL_EXT_texture_sRGB%2CGL_EXT_transform_feedback%2CGL_INTEL_conservative_rasterization%2CGL_KHR_texture_compression_astc_ldr%2CGL_NV_conservative_raster&generator=c&options=HEADER_ONLY
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -465,7 +465,9 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||||||
#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
|
#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
|
||||||
#define GL_COMPRESSED_R11_EAC 0x9270
|
#define GL_COMPRESSED_R11_EAC 0x9270
|
||||||
#define GL_COMPRESSED_RED 0x8225
|
#define GL_COMPRESSED_RED 0x8225
|
||||||
|
#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
|
||||||
#define GL_COMPRESSED_RED_RGTC1 0x8DBB
|
#define GL_COMPRESSED_RED_RGTC1 0x8DBB
|
||||||
|
#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
|
||||||
#define GL_COMPRESSED_RG 0x8226
|
#define GL_COMPRESSED_RG 0x8226
|
||||||
#define GL_COMPRESSED_RG11_EAC 0x9272
|
#define GL_COMPRESSED_RG11_EAC 0x9272
|
||||||
#define GL_COMPRESSED_RGB 0x84ED
|
#define GL_COMPRESSED_RGB 0x84ED
|
||||||
@@ -473,16 +475,35 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||||||
#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
|
#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
|
||||||
#define GL_COMPRESSED_RGBA 0x84EE
|
#define GL_COMPRESSED_RGBA 0x84EE
|
||||||
#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
|
#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
|
||||||
|
#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
|
||||||
#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
|
#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
|
||||||
|
#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
|
||||||
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
||||||
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
|
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
|
||||||
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
||||||
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
|
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
|
||||||
|
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
|
||||||
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
|
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
|
||||||
|
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
|
||||||
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
|
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
|
||||||
#define GL_COMPRESSED_RG_RGTC2 0x8DBD
|
#define GL_COMPRESSED_RG_RGTC2 0x8DBD
|
||||||
#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
|
#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
|
||||||
|
#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
|
||||||
#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
|
#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
|
||||||
|
#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
|
||||||
#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
|
#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
|
||||||
#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
|
#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
|
||||||
#define GL_COMPRESSED_SLUMINANCE 0x8C4A
|
#define GL_COMPRESSED_SLUMINANCE 0x8C4A
|
||||||
@@ -490,11 +511,26 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||||||
#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
|
#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
|
||||||
#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
|
#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
|
||||||
#define GL_COMPRESSED_SRGB 0x8C48
|
#define GL_COMPRESSED_SRGB 0x8C48
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
|
||||||
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
|
||||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
|
#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
|
||||||
#define GL_COMPRESSED_SRGB8_ETC2 0x9275
|
#define GL_COMPRESSED_SRGB8_ETC2 0x9275
|
||||||
#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
|
#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
|
||||||
#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
|
#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
|
||||||
#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
|
#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
|
||||||
|
#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
|
||||||
#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
|
#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
|
||||||
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
|
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
|
||||||
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
|
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
|
||||||
@@ -833,6 +869,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||||||
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
|
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
|
||||||
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
|
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
|
||||||
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
|
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
|
||||||
|
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
|
||||||
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
|
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
|
||||||
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
|
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
|
||||||
#define GL_FRAMEBUFFER_RENDERABLE 0x8289
|
#define GL_FRAMEBUFFER_RENDERABLE 0x8289
|
||||||
@@ -1335,6 +1372,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||||||
#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
|
#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
|
||||||
#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
|
#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
|
||||||
#define GL_MAX_SAMPLES 0x8D57
|
#define GL_MAX_SAMPLES 0x8D57
|
||||||
|
#define GL_MAX_SAMPLES_EXT 0x8D57
|
||||||
#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
|
#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
|
||||||
#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
|
#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
|
||||||
#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
|
#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
|
||||||
@@ -1370,6 +1408,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||||||
#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
|
#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
|
||||||
#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
|
#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
|
||||||
#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
|
#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
|
||||||
|
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
|
||||||
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
||||||
#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39
|
#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39
|
||||||
#define GL_MAX_TEXTURE_UNITS 0x84E2
|
#define GL_MAX_TEXTURE_UNITS 0x84E2
|
||||||
@@ -1730,6 +1769,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||||||
#define GL_RENDERBUFFER_RED_SIZE 0x8D50
|
#define GL_RENDERBUFFER_RED_SIZE 0x8D50
|
||||||
#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
|
#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
|
||||||
#define GL_RENDERBUFFER_SAMPLES 0x8CAB
|
#define GL_RENDERBUFFER_SAMPLES 0x8CAB
|
||||||
|
#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
|
||||||
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
|
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
|
||||||
#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
|
#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
|
||||||
#define GL_RENDERBUFFER_WIDTH 0x8D42
|
#define GL_RENDERBUFFER_WIDTH 0x8D42
|
||||||
@@ -1864,6 +1904,8 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||||||
#define GL_SAMPLE_MASK_VALUE 0x8E52
|
#define GL_SAMPLE_MASK_VALUE 0x8E52
|
||||||
#define GL_SAMPLE_POSITION 0x8E50
|
#define GL_SAMPLE_POSITION 0x8E50
|
||||||
#define GL_SAMPLE_SHADING 0x8C36
|
#define GL_SAMPLE_SHADING 0x8C36
|
||||||
|
#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA
|
||||||
|
#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB
|
||||||
#define GL_SCISSOR_BIT 0x00080000
|
#define GL_SCISSOR_BIT 0x00080000
|
||||||
#define GL_SCISSOR_BOX 0x0C10
|
#define GL_SCISSOR_BOX 0x0C10
|
||||||
#define GL_SCISSOR_TEST 0x0C11
|
#define GL_SCISSOR_TEST 0x0C11
|
||||||
@@ -2174,6 +2216,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||||
#define GL_TEXTURE_MATRIX 0x0BA8
|
#define GL_TEXTURE_MATRIX 0x0BA8
|
||||||
#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
|
#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
|
||||||
|
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||||
#define GL_TEXTURE_MAX_LEVEL 0x813D
|
#define GL_TEXTURE_MAX_LEVEL 0x813D
|
||||||
#define GL_TEXTURE_MAX_LOD 0x813B
|
#define GL_TEXTURE_MAX_LOD 0x813B
|
||||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||||
@@ -2889,6 +2932,8 @@ GLAD_API_CALL int GLAD_GL_ARB_shader_objects;
|
|||||||
GLAD_API_CALL int GLAD_GL_ARB_shader_storage_buffer_object;
|
GLAD_API_CALL int GLAD_GL_ARB_shader_storage_buffer_object;
|
||||||
#define GL_ARB_shading_language_100 1
|
#define GL_ARB_shading_language_100 1
|
||||||
GLAD_API_CALL int GLAD_GL_ARB_shading_language_100;
|
GLAD_API_CALL int GLAD_GL_ARB_shading_language_100;
|
||||||
|
#define GL_ARB_texture_compression_bptc 1
|
||||||
|
GLAD_API_CALL int GLAD_GL_ARB_texture_compression_bptc;
|
||||||
#define GL_ARB_texture_float 1
|
#define GL_ARB_texture_float 1
|
||||||
GLAD_API_CALL int GLAD_GL_ARB_texture_float;
|
GLAD_API_CALL int GLAD_GL_ARB_texture_float;
|
||||||
#define GL_ARB_texture_rg 1
|
#define GL_ARB_texture_rg 1
|
||||||
@@ -2907,6 +2952,10 @@ GLAD_API_CALL int GLAD_GL_ARB_vertex_type_2_10_10_10_rev;
|
|||||||
GLAD_API_CALL int GLAD_GL_EXT_direct_state_access;
|
GLAD_API_CALL int GLAD_GL_EXT_direct_state_access;
|
||||||
#define GL_EXT_framebuffer_blit 1
|
#define GL_EXT_framebuffer_blit 1
|
||||||
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_blit;
|
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_blit;
|
||||||
|
#define GL_EXT_framebuffer_multisample 1
|
||||||
|
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_multisample;
|
||||||
|
#define GL_EXT_framebuffer_multisample_blit_scaled 1
|
||||||
|
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_multisample_blit_scaled;
|
||||||
#define GL_EXT_framebuffer_object 1
|
#define GL_EXT_framebuffer_object 1
|
||||||
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_object;
|
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_object;
|
||||||
#define GL_EXT_framebuffer_sRGB 1
|
#define GL_EXT_framebuffer_sRGB 1
|
||||||
@@ -2919,8 +2968,12 @@ GLAD_API_CALL int GLAD_GL_EXT_gpu_shader4;
|
|||||||
GLAD_API_CALL int GLAD_GL_EXT_shader_image_load_store;
|
GLAD_API_CALL int GLAD_GL_EXT_shader_image_load_store;
|
||||||
#define GL_EXT_texture_array 1
|
#define GL_EXT_texture_array 1
|
||||||
GLAD_API_CALL int GLAD_GL_EXT_texture_array;
|
GLAD_API_CALL int GLAD_GL_EXT_texture_array;
|
||||||
|
#define GL_EXT_texture_compression_rgtc 1
|
||||||
|
GLAD_API_CALL int GLAD_GL_EXT_texture_compression_rgtc;
|
||||||
#define GL_EXT_texture_compression_s3tc 1
|
#define GL_EXT_texture_compression_s3tc 1
|
||||||
GLAD_API_CALL int GLAD_GL_EXT_texture_compression_s3tc;
|
GLAD_API_CALL int GLAD_GL_EXT_texture_compression_s3tc;
|
||||||
|
#define GL_EXT_texture_filter_anisotropic 1
|
||||||
|
GLAD_API_CALL int GLAD_GL_EXT_texture_filter_anisotropic;
|
||||||
#define GL_EXT_texture_integer 1
|
#define GL_EXT_texture_integer 1
|
||||||
GLAD_API_CALL int GLAD_GL_EXT_texture_integer;
|
GLAD_API_CALL int GLAD_GL_EXT_texture_integer;
|
||||||
#define GL_EXT_texture_sRGB 1
|
#define GL_EXT_texture_sRGB 1
|
||||||
@@ -2929,6 +2982,8 @@ GLAD_API_CALL int GLAD_GL_EXT_texture_sRGB;
|
|||||||
GLAD_API_CALL int GLAD_GL_EXT_transform_feedback;
|
GLAD_API_CALL int GLAD_GL_EXT_transform_feedback;
|
||||||
#define GL_INTEL_conservative_rasterization 1
|
#define GL_INTEL_conservative_rasterization 1
|
||||||
GLAD_API_CALL int GLAD_GL_INTEL_conservative_rasterization;
|
GLAD_API_CALL int GLAD_GL_INTEL_conservative_rasterization;
|
||||||
|
#define GL_KHR_texture_compression_astc_ldr 1
|
||||||
|
GLAD_API_CALL int GLAD_GL_KHR_texture_compression_astc_ldr;
|
||||||
#define GL_NV_conservative_raster 1
|
#define GL_NV_conservative_raster 1
|
||||||
GLAD_API_CALL int GLAD_GL_NV_conservative_raster;
|
GLAD_API_CALL int GLAD_GL_NV_conservative_raster;
|
||||||
|
|
||||||
@@ -3949,6 +4004,7 @@ typedef GLint (GLAD_API_PTR *PFNGLRENDERMODEPROC)(GLenum mode);
|
|||||||
typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
||||||
typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEEXTPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEEXTPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
||||||
typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
|
typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
|
||||||
|
typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
|
||||||
typedef void (GLAD_API_PTR *PFNGLRESUMETRANSFORMFEEDBACKPROC)(void);
|
typedef void (GLAD_API_PTR *PFNGLRESUMETRANSFORMFEEDBACKPROC)(void);
|
||||||
typedef void (GLAD_API_PTR *PFNGLROTATEDPROC)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
|
typedef void (GLAD_API_PTR *PFNGLROTATEDPROC)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
|
||||||
typedef void (GLAD_API_PTR *PFNGLROTATEFPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
|
typedef void (GLAD_API_PTR *PFNGLROTATEFPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
|
||||||
@@ -6458,6 +6514,8 @@ GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT;
|
|||||||
#define glRenderbufferStorageEXT glad_glRenderbufferStorageEXT
|
#define glRenderbufferStorageEXT glad_glRenderbufferStorageEXT
|
||||||
GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample;
|
GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample;
|
||||||
#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample
|
#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample
|
||||||
|
GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT;
|
||||||
|
#define glRenderbufferStorageMultisampleEXT glad_glRenderbufferStorageMultisampleEXT
|
||||||
GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback;
|
GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback;
|
||||||
#define glResumeTransformFeedback glad_glResumeTransformFeedback
|
#define glResumeTransformFeedback glad_glResumeTransformFeedback
|
||||||
GLAD_API_CALL PFNGLROTATEDPROC glad_glRotated;
|
GLAD_API_CALL PFNGLROTATEDPROC glad_glRotated;
|
||||||
@@ -7480,6 +7538,7 @@ int GLAD_GL_ARB_shader_image_size = 0;
|
|||||||
int GLAD_GL_ARB_shader_objects = 0;
|
int GLAD_GL_ARB_shader_objects = 0;
|
||||||
int GLAD_GL_ARB_shader_storage_buffer_object = 0;
|
int GLAD_GL_ARB_shader_storage_buffer_object = 0;
|
||||||
int GLAD_GL_ARB_shading_language_100 = 0;
|
int GLAD_GL_ARB_shading_language_100 = 0;
|
||||||
|
int GLAD_GL_ARB_texture_compression_bptc = 0;
|
||||||
int GLAD_GL_ARB_texture_float = 0;
|
int GLAD_GL_ARB_texture_float = 0;
|
||||||
int GLAD_GL_ARB_texture_rg = 0;
|
int GLAD_GL_ARB_texture_rg = 0;
|
||||||
int GLAD_GL_ARB_texture_rgb10_a2ui = 0;
|
int GLAD_GL_ARB_texture_rgb10_a2ui = 0;
|
||||||
@@ -7489,17 +7548,22 @@ int GLAD_GL_ARB_vertex_shader = 0;
|
|||||||
int GLAD_GL_ARB_vertex_type_2_10_10_10_rev = 0;
|
int GLAD_GL_ARB_vertex_type_2_10_10_10_rev = 0;
|
||||||
int GLAD_GL_EXT_direct_state_access = 0;
|
int GLAD_GL_EXT_direct_state_access = 0;
|
||||||
int GLAD_GL_EXT_framebuffer_blit = 0;
|
int GLAD_GL_EXT_framebuffer_blit = 0;
|
||||||
|
int GLAD_GL_EXT_framebuffer_multisample = 0;
|
||||||
|
int GLAD_GL_EXT_framebuffer_multisample_blit_scaled = 0;
|
||||||
int GLAD_GL_EXT_framebuffer_object = 0;
|
int GLAD_GL_EXT_framebuffer_object = 0;
|
||||||
int GLAD_GL_EXT_framebuffer_sRGB = 0;
|
int GLAD_GL_EXT_framebuffer_sRGB = 0;
|
||||||
int GLAD_GL_EXT_geometry_shader4 = 0;
|
int GLAD_GL_EXT_geometry_shader4 = 0;
|
||||||
int GLAD_GL_EXT_gpu_shader4 = 0;
|
int GLAD_GL_EXT_gpu_shader4 = 0;
|
||||||
int GLAD_GL_EXT_shader_image_load_store = 0;
|
int GLAD_GL_EXT_shader_image_load_store = 0;
|
||||||
int GLAD_GL_EXT_texture_array = 0;
|
int GLAD_GL_EXT_texture_array = 0;
|
||||||
|
int GLAD_GL_EXT_texture_compression_rgtc = 0;
|
||||||
int GLAD_GL_EXT_texture_compression_s3tc = 0;
|
int GLAD_GL_EXT_texture_compression_s3tc = 0;
|
||||||
|
int GLAD_GL_EXT_texture_filter_anisotropic = 0;
|
||||||
int GLAD_GL_EXT_texture_integer = 0;
|
int GLAD_GL_EXT_texture_integer = 0;
|
||||||
int GLAD_GL_EXT_texture_sRGB = 0;
|
int GLAD_GL_EXT_texture_sRGB = 0;
|
||||||
int GLAD_GL_EXT_transform_feedback = 0;
|
int GLAD_GL_EXT_transform_feedback = 0;
|
||||||
int GLAD_GL_INTEL_conservative_rasterization = 0;
|
int GLAD_GL_INTEL_conservative_rasterization = 0;
|
||||||
|
int GLAD_GL_KHR_texture_compression_astc_ldr = 0;
|
||||||
int GLAD_GL_NV_conservative_raster = 0;
|
int GLAD_GL_NV_conservative_raster = 0;
|
||||||
|
|
||||||
|
|
||||||
@@ -8520,6 +8584,7 @@ PFNGLRENDERMODEPROC glad_glRenderMode = NULL;
|
|||||||
PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL;
|
PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL;
|
||||||
PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT = NULL;
|
PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT = NULL;
|
||||||
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL;
|
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL;
|
||||||
|
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT = NULL;
|
||||||
PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL;
|
PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL;
|
||||||
PFNGLROTATEDPROC glad_glRotated = NULL;
|
PFNGLROTATEDPROC glad_glRotated = NULL;
|
||||||
PFNGLROTATEFPROC glad_glRotatef = NULL;
|
PFNGLROTATEFPROC glad_glRotatef = NULL;
|
||||||
@@ -10618,6 +10683,10 @@ static void glad_gl_load_GL_EXT_framebuffer_blit( GLADuserptrloadfunc load, void
|
|||||||
if(!GLAD_GL_EXT_framebuffer_blit) return;
|
if(!GLAD_GL_EXT_framebuffer_blit) return;
|
||||||
glad_glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC) load(userptr, "glBlitFramebufferEXT");
|
glad_glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC) load(userptr, "glBlitFramebufferEXT");
|
||||||
}
|
}
|
||||||
|
static void glad_gl_load_GL_EXT_framebuffer_multisample( GLADuserptrloadfunc load, void* userptr) {
|
||||||
|
if(!GLAD_GL_EXT_framebuffer_multisample) return;
|
||||||
|
glad_glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) load(userptr, "glRenderbufferStorageMultisampleEXT");
|
||||||
|
}
|
||||||
static void glad_gl_load_GL_EXT_framebuffer_object( GLADuserptrloadfunc load, void* userptr) {
|
static void glad_gl_load_GL_EXT_framebuffer_object( GLADuserptrloadfunc load, void* userptr) {
|
||||||
if(!GLAD_GL_EXT_framebuffer_object) return;
|
if(!GLAD_GL_EXT_framebuffer_object) return;
|
||||||
glad_glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) load(userptr, "glBindFramebufferEXT");
|
glad_glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) load(userptr, "glBindFramebufferEXT");
|
||||||
@@ -10816,6 +10885,7 @@ static int glad_gl_find_extensions_gl(void) {
|
|||||||
GLAD_GL_ARB_shader_objects = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_objects");
|
GLAD_GL_ARB_shader_objects = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_objects");
|
||||||
GLAD_GL_ARB_shader_storage_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_storage_buffer_object");
|
GLAD_GL_ARB_shader_storage_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_storage_buffer_object");
|
||||||
GLAD_GL_ARB_shading_language_100 = glad_gl_has_extension(exts, exts_i, "GL_ARB_shading_language_100");
|
GLAD_GL_ARB_shading_language_100 = glad_gl_has_extension(exts, exts_i, "GL_ARB_shading_language_100");
|
||||||
|
GLAD_GL_ARB_texture_compression_bptc = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_compression_bptc");
|
||||||
GLAD_GL_ARB_texture_float = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_float");
|
GLAD_GL_ARB_texture_float = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_float");
|
||||||
GLAD_GL_ARB_texture_rg = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_rg");
|
GLAD_GL_ARB_texture_rg = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_rg");
|
||||||
GLAD_GL_ARB_texture_rgb10_a2ui = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_rgb10_a2ui");
|
GLAD_GL_ARB_texture_rgb10_a2ui = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_rgb10_a2ui");
|
||||||
@@ -10825,17 +10895,22 @@ static int glad_gl_find_extensions_gl(void) {
|
|||||||
GLAD_GL_ARB_vertex_type_2_10_10_10_rev = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_type_2_10_10_10_rev");
|
GLAD_GL_ARB_vertex_type_2_10_10_10_rev = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_type_2_10_10_10_rev");
|
||||||
GLAD_GL_EXT_direct_state_access = glad_gl_has_extension(exts, exts_i, "GL_EXT_direct_state_access");
|
GLAD_GL_EXT_direct_state_access = glad_gl_has_extension(exts, exts_i, "GL_EXT_direct_state_access");
|
||||||
GLAD_GL_EXT_framebuffer_blit = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_blit");
|
GLAD_GL_EXT_framebuffer_blit = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_blit");
|
||||||
|
GLAD_GL_EXT_framebuffer_multisample = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_multisample");
|
||||||
|
GLAD_GL_EXT_framebuffer_multisample_blit_scaled = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_multisample_blit_scaled");
|
||||||
GLAD_GL_EXT_framebuffer_object = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_object");
|
GLAD_GL_EXT_framebuffer_object = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_object");
|
||||||
GLAD_GL_EXT_framebuffer_sRGB = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_sRGB");
|
GLAD_GL_EXT_framebuffer_sRGB = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_sRGB");
|
||||||
GLAD_GL_EXT_geometry_shader4 = glad_gl_has_extension(exts, exts_i, "GL_EXT_geometry_shader4");
|
GLAD_GL_EXT_geometry_shader4 = glad_gl_has_extension(exts, exts_i, "GL_EXT_geometry_shader4");
|
||||||
GLAD_GL_EXT_gpu_shader4 = glad_gl_has_extension(exts, exts_i, "GL_EXT_gpu_shader4");
|
GLAD_GL_EXT_gpu_shader4 = glad_gl_has_extension(exts, exts_i, "GL_EXT_gpu_shader4");
|
||||||
GLAD_GL_EXT_shader_image_load_store = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_image_load_store");
|
GLAD_GL_EXT_shader_image_load_store = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_image_load_store");
|
||||||
GLAD_GL_EXT_texture_array = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_array");
|
GLAD_GL_EXT_texture_array = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_array");
|
||||||
|
GLAD_GL_EXT_texture_compression_rgtc = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_rgtc");
|
||||||
GLAD_GL_EXT_texture_compression_s3tc = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_s3tc");
|
GLAD_GL_EXT_texture_compression_s3tc = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_s3tc");
|
||||||
|
GLAD_GL_EXT_texture_filter_anisotropic = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_filter_anisotropic");
|
||||||
GLAD_GL_EXT_texture_integer = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_integer");
|
GLAD_GL_EXT_texture_integer = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_integer");
|
||||||
GLAD_GL_EXT_texture_sRGB = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_sRGB");
|
GLAD_GL_EXT_texture_sRGB = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_sRGB");
|
||||||
GLAD_GL_EXT_transform_feedback = glad_gl_has_extension(exts, exts_i, "GL_EXT_transform_feedback");
|
GLAD_GL_EXT_transform_feedback = glad_gl_has_extension(exts, exts_i, "GL_EXT_transform_feedback");
|
||||||
GLAD_GL_INTEL_conservative_rasterization = glad_gl_has_extension(exts, exts_i, "GL_INTEL_conservative_rasterization");
|
GLAD_GL_INTEL_conservative_rasterization = glad_gl_has_extension(exts, exts_i, "GL_INTEL_conservative_rasterization");
|
||||||
|
GLAD_GL_KHR_texture_compression_astc_ldr = glad_gl_has_extension(exts, exts_i, "GL_KHR_texture_compression_astc_ldr");
|
||||||
GLAD_GL_NV_conservative_raster = glad_gl_has_extension(exts, exts_i, "GL_NV_conservative_raster");
|
GLAD_GL_NV_conservative_raster = glad_gl_has_extension(exts, exts_i, "GL_NV_conservative_raster");
|
||||||
|
|
||||||
glad_gl_free_extensions(exts_i);
|
glad_gl_free_extensions(exts_i);
|
||||||
@@ -10929,6 +11004,7 @@ int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) {
|
|||||||
glad_gl_load_GL_ARB_vertex_type_2_10_10_10_rev(load, userptr);
|
glad_gl_load_GL_ARB_vertex_type_2_10_10_10_rev(load, userptr);
|
||||||
glad_gl_load_GL_EXT_direct_state_access(load, userptr);
|
glad_gl_load_GL_EXT_direct_state_access(load, userptr);
|
||||||
glad_gl_load_GL_EXT_framebuffer_blit(load, userptr);
|
glad_gl_load_GL_EXT_framebuffer_blit(load, userptr);
|
||||||
|
glad_gl_load_GL_EXT_framebuffer_multisample(load, userptr);
|
||||||
glad_gl_load_GL_EXT_framebuffer_object(load, userptr);
|
glad_gl_load_GL_EXT_framebuffer_object(load, userptr);
|
||||||
glad_gl_load_GL_EXT_geometry_shader4(load, userptr);
|
glad_gl_load_GL_EXT_geometry_shader4(load, userptr);
|
||||||
glad_gl_load_GL_EXT_gpu_shader4(load, userptr);
|
glad_gl_load_GL_EXT_gpu_shader4(load, userptr);
|
||||||
|
|||||||
40
src/k3mix.c
40
src/k3mix.c
@@ -6,6 +6,11 @@
|
|||||||
#include<math.h>
|
#include<math.h>
|
||||||
#include<pthread.h>
|
#include<pthread.h>
|
||||||
#include<assert.h>
|
#include<assert.h>
|
||||||
|
#include"k3.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define strncasecmp _strnicmp
|
||||||
|
#endif
|
||||||
|
|
||||||
static uint32_t FinalSampleRate;
|
static uint32_t FinalSampleRate;
|
||||||
static uint8_t FinalChannels;
|
static uint8_t FinalChannels;
|
||||||
@@ -19,12 +24,22 @@ struct k3MixSource {
|
|||||||
char *filepath;
|
char *filepath;
|
||||||
OggVorbis_File vf;
|
OggVorbis_File vf;
|
||||||
int bitstream;
|
int bitstream;
|
||||||
|
size_t looppoint;
|
||||||
};
|
};
|
||||||
struct k3MixSource *k3MixSourceFile(const char *path) {
|
struct k3MixSource *k3MixSourceFile(const char *path) {
|
||||||
struct k3MixSource *ret = calloc(1, sizeof(*ret));
|
struct k3MixSource *ret = calloc(1, sizeof(*ret));
|
||||||
ret->filepath = strdup(path);
|
ret->filepath = strdup(path);
|
||||||
ov_fopen(path, &ret->vf);
|
ov_fopen(path, &ret->vf);
|
||||||
ret->bitstream = 0;
|
ret->bitstream = 0;
|
||||||
|
|
||||||
|
ret->looppoint = 0;
|
||||||
|
for(size_t ci = 0; ci < ret->vf.vc->comments; ci++) {
|
||||||
|
if(strncasecmp(ret->vf.vc->user_comments[ci], "looppoint=", 10) == 0) {
|
||||||
|
ret->looppoint = strtol(ret->vf.vc->user_comments[ci] + 10, NULL, 0);
|
||||||
|
k3Log(k3_DEBUG, "%s has loop point %lu", path, ret->looppoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
void k3MixSourceClose(struct k3MixSource *src) {
|
void k3MixSourceClose(struct k3MixSource *src) {
|
||||||
@@ -42,7 +57,7 @@ __attribute__((optimize("Ofast"))) static intmax_t ogg_read(struct k3MixWave *th
|
|||||||
long lastRead = ov_read_float(&od->vf, &ni, sampleCount, &od->bitstream);
|
long lastRead = ov_read_float(&od->vf, &ni, sampleCount, &od->bitstream);
|
||||||
|
|
||||||
if(this->loop && lastRead == 0) {
|
if(this->loop && lastRead == 0) {
|
||||||
ov_pcm_seek(&od->vf, 0);
|
ov_pcm_seek(&od->vf, od->looppoint);
|
||||||
continue;
|
continue;
|
||||||
} else if(lastRead <= 0) {
|
} else if(lastRead <= 0) {
|
||||||
this->end = true;
|
this->end = true;
|
||||||
@@ -161,12 +176,13 @@ static void queue_clone(struct k3MixWave *this, struct k3MixWave *new) {
|
|||||||
new->clone = queue_clone;
|
new->clone = queue_clone;
|
||||||
new->close = queue_close;
|
new->close = queue_close;
|
||||||
|
|
||||||
|
new->end = this->end;
|
||||||
new->loop = this->loop;
|
new->loop = this->loop;
|
||||||
new->dam = this->dam;
|
new->dam = this->dam;
|
||||||
new->volume = this->volume;
|
new->volume = this->volume;
|
||||||
}
|
}
|
||||||
struct k3MixWave *k3MixQueue() {
|
struct k3MixWave *k3MixQueue() {
|
||||||
struct k3MixWave *ret = malloc(sizeof(*ret));
|
struct k3MixWave *ret = calloc(1, sizeof(*ret));
|
||||||
ret->refs = 1;
|
ret->refs = 1;
|
||||||
ret->sampleRate = FinalSampleRate;
|
ret->sampleRate = FinalSampleRate;
|
||||||
ret->channels = FinalChannels;
|
ret->channels = FinalChannels;
|
||||||
@@ -182,6 +198,7 @@ struct k3MixWave *k3MixQueue() {
|
|||||||
ret->loop = 0;
|
ret->loop = 0;
|
||||||
ret->dam = 0;
|
ret->dam = 0;
|
||||||
ret->volume = 1;
|
ret->volume = 1;
|
||||||
|
ret->end = false;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -260,6 +277,7 @@ static void power_measurement_clone(struct k3MixWave *this, struct k3MixWave *ne
|
|||||||
new->clone = power_measurement_clone;
|
new->clone = power_measurement_clone;
|
||||||
new->close = power_measurement_close;
|
new->close = power_measurement_close;
|
||||||
|
|
||||||
|
new->end = this->end;
|
||||||
new->loop = this->loop;
|
new->loop = this->loop;
|
||||||
new->dam = this->dam;
|
new->dam = this->dam;
|
||||||
new->volume = this->volume;
|
new->volume = this->volume;
|
||||||
@@ -308,6 +326,10 @@ struct k3MixWave *k3MixPowerMeasurement(struct k3MixWave *child) {
|
|||||||
static size_t playingCount, playingCapacity;
|
static size_t playingCount, playingCapacity;
|
||||||
static struct k3MixWave **playings;
|
static struct k3MixWave **playings;
|
||||||
|
|
||||||
|
void k3MixStopSmooth(struct k3MixWave *wav) {
|
||||||
|
wav->fade = -0.01;
|
||||||
|
}
|
||||||
|
|
||||||
void k3MixStop(struct k3MixWave *wav) {
|
void k3MixStop(struct k3MixWave *wav) {
|
||||||
for(size_t i = 0; i < playingCount; i++) {
|
for(size_t i = 0; i < playingCount; i++) {
|
||||||
if(playings[i] == wav) {
|
if(playings[i] == wav) {
|
||||||
@@ -346,12 +368,22 @@ __attribute__((optimize("Ofast"))) static void k3MixDoYourThang(size_t sampleCou
|
|||||||
for(size_t i = 0; i < playingCount;) {
|
for(size_t i = 0; i < playingCount;) {
|
||||||
intmax_t read = playings[i]->read(playings[i], sampleCount, FinalData);
|
intmax_t read = playings[i]->read(playings[i], sampleCount, FinalData);
|
||||||
|
|
||||||
|
if(playings[i]->fade) {
|
||||||
|
playings[i]->volume += playings[i]->fade;
|
||||||
|
if(playings[i]->volume > 1) {
|
||||||
|
playings[i]->volume = 1;
|
||||||
|
playings[i]->fade = 0;
|
||||||
|
} else if(playings[i]->volume < 0) {
|
||||||
|
playings[i]->end = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(playings[i]->end) {
|
if(playings[i]->end) {
|
||||||
k3MixStop(playings[i]);
|
k3MixStop(playings[i]);
|
||||||
} else i++;
|
} else i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(size_t i = 0; i < sampleCount * FinalChannels; i += 4) {
|
/*for(size_t i = 0; i < sampleCount * FinalChannels; i += 4) {
|
||||||
// Compute tanh approximation x*(27+x*x)/(27+9*x*x)
|
// Compute tanh approximation x*(27+x*x)/(27+9*x*x)
|
||||||
|
|
||||||
float *ptr = FinalData + i;
|
float *ptr = FinalData + i;
|
||||||
@@ -363,7 +395,7 @@ __attribute__((optimize("Ofast"))) static void k3MixDoYourThang(size_t sampleCou
|
|||||||
__m128 denom = _mm_add_ps(_mm_set1_ps(27), _mm_mul_ps(_mm_set1_ps(9), xx));
|
__m128 denom = _mm_add_ps(_mm_set1_ps(27), _mm_mul_ps(_mm_set1_ps(9), xx));
|
||||||
|
|
||||||
_mm_storeu_ps(ptr, _mm_div_ps(numer, denom));
|
_mm_storeu_ps(ptr, _mm_div_ps(numer, denom));
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// The accuracy isn't worth the function call per sample
|
// The accuracy isn't worth the function call per sample
|
||||||
/*for(size_t i = 0; i < sampleCount * FinalChannels; i++) {
|
/*for(size_t i = 0; i < sampleCount * FinalChannels; i++) {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ struct k3MixWave {
|
|||||||
bool end;
|
bool end;
|
||||||
uint16_t dam;
|
uint16_t dam;
|
||||||
float volume;
|
float volume;
|
||||||
|
float fade;
|
||||||
};
|
};
|
||||||
|
|
||||||
void k3MixInit(uint32_t sampleRate, uint8_t channels);
|
void k3MixInit(uint32_t sampleRate, uint8_t channels);
|
||||||
@@ -44,6 +45,7 @@ struct k3MixWave *k3MixPowerMeasurement(struct k3MixWave *child);
|
|||||||
float k3MixPowerMeasurementGetRMS(struct k3MixWave*);
|
float k3MixPowerMeasurementGetRMS(struct k3MixWave*);
|
||||||
|
|
||||||
void k3MixStop(struct k3MixWave*);
|
void k3MixStop(struct k3MixWave*);
|
||||||
|
void k3MixStopSmooth(struct k3MixWave*);
|
||||||
struct k3MixWave *k3MixPlay(struct k3MixWave*);
|
struct k3MixWave *k3MixPlay(struct k3MixWave*);
|
||||||
void k3MixPlayDirect(struct k3MixWave*);
|
void k3MixPlayDirect(struct k3MixWave*);
|
||||||
|
|
||||||
|
|||||||
14
src/k4.h
14
src/k4.h
@@ -5,20 +5,26 @@
|
|||||||
struct k3MScreen;
|
struct k3MScreen;
|
||||||
|
|
||||||
#include"stoon.h"
|
#include"stoon.h"
|
||||||
struct NetWrap {
|
/*struct NetWrap {
|
||||||
struct Stoon stoon;
|
struct Stoon stoon;
|
||||||
|
|
||||||
int stage;
|
int stage;
|
||||||
float timeout;
|
float timeout;
|
||||||
|
|
||||||
int isHost;
|
bool isHost;
|
||||||
|
|
||||||
// Used for punching stage
|
// Used for punching stage
|
||||||
int gotten;
|
int gotten;
|
||||||
|
|
||||||
char otherpeer[STOON_CONN_INFO_SIZE];
|
// Server-side
|
||||||
|
#define NETWRAP_BACKLOG 32
|
||||||
|
char otherpeers[NETWRAP_BACKLOG][STOON_CONN_INFO_SIZE];
|
||||||
|
bool otherpeersActive[NETWRAP_BACKLOG];
|
||||||
|
|
||||||
|
// Client-side
|
||||||
|
char connectto[STOON_CONN_INFO_SIZE];
|
||||||
};
|
};
|
||||||
extern struct NetWrap NetWrap;
|
extern struct NetWrap NetWrap;*/
|
||||||
|
|
||||||
extern struct k3MScreen *UiActive;
|
extern struct k3MScreen *UiActive;
|
||||||
|
|
||||||
|
|||||||
@@ -253,15 +253,27 @@ static int refresh_texture(struct ResManRes *res) {
|
|||||||
|
|
||||||
int w, h, origN;
|
int w, h, origN;
|
||||||
unsigned char *data = stbi_load(namebuf, &w, &h, &origN, n);
|
unsigned char *data = stbi_load(namebuf, &w, &h, &origN, n);
|
||||||
int stbifree = 1;
|
|
||||||
|
|
||||||
if(TextureResolutionReduction && data) {
|
int newW = w, newH = h;
|
||||||
int newW = w >> TextureResolutionReduction;
|
|
||||||
int newH = h >> TextureResolutionReduction;
|
if(TextureResolutionReduction) {
|
||||||
|
newW = newW >> TextureResolutionReduction;
|
||||||
if(newW <= 4) newW = 4;
|
newH = newH >> TextureResolutionReduction;
|
||||||
if(newH <= 4) newH = 4;
|
}
|
||||||
|
if(newW > k3TexSzMax()) {
|
||||||
|
newW = k3TexSzMax();
|
||||||
|
}
|
||||||
|
if(newH > k3TexSzMax()) {
|
||||||
|
newH = k3TexSzMax();
|
||||||
|
}
|
||||||
|
if(newW < 4) {
|
||||||
|
newW = 4;
|
||||||
|
}
|
||||||
|
if(newH < 4) {
|
||||||
|
newH = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newW != w || newH != h) {
|
||||||
unsigned char *data2 = malloc(newW * newH * n);
|
unsigned char *data2 = malloc(newW * newH * n);
|
||||||
int success = stbir_resize_uint8_generic(data, w, h, 0, data2, newW, newH, 0, n, n == 4 ? 3 : -1, 0, STBIR_EDGE_WRAP, STBIR_FILTER_DEFAULT, gamma ? STBIR_COLORSPACE_SRGB : STBIR_COLORSPACE_LINEAR, NULL);
|
int success = stbir_resize_uint8_generic(data, w, h, 0, data2, newW, newH, 0, n, n == 4 ? 3 : -1, 0, STBIR_EDGE_WRAP, STBIR_FILTER_DEFAULT, gamma ? STBIR_COLORSPACE_SRGB : STBIR_COLORSPACE_LINEAR, NULL);
|
||||||
|
|
||||||
@@ -271,7 +283,6 @@ static int refresh_texture(struct ResManRes *res) {
|
|||||||
w = newW;
|
w = newW;
|
||||||
h = newH;
|
h = newH;
|
||||||
data = data2;
|
data = data2;
|
||||||
stbifree = 0;
|
|
||||||
} else {
|
} else {
|
||||||
free(data2);
|
free(data2);
|
||||||
}
|
}
|
||||||
@@ -283,12 +294,7 @@ static int refresh_texture(struct ResManRes *res) {
|
|||||||
|
|
||||||
if(data) {
|
if(data) {
|
||||||
k3TexUpdate(res->thing, type, 0, w, h, data);
|
k3TexUpdate(res->thing, type, 0, w, h, data);
|
||||||
|
free(data);
|
||||||
if(stbifree) {
|
|
||||||
stbi_image_free(data);
|
|
||||||
} else {
|
|
||||||
free(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
801
src/luaapi.c
801
src/luaapi.c
File diff suppressed because it is too large
Load Diff
282
src/main.c
282
src/main.c
@@ -40,14 +40,13 @@
|
|||||||
|
|
||||||
#include<ctype.h>
|
#include<ctype.h>
|
||||||
|
|
||||||
struct NetWrap NetWrap;
|
|
||||||
|
|
||||||
GLFWwindow *GameWnd;
|
GLFWwindow *GameWnd;
|
||||||
|
|
||||||
static int TextureResolutionReduction = 0;
|
static int TextureResolutionReduction = 0;
|
||||||
|
|
||||||
static int IrregularShadows = 0;
|
static int IrregularShadows = 0;
|
||||||
|
|
||||||
|
static int InstantCamShift = 5;
|
||||||
static float CamPitch, CamYaw;
|
static float CamPitch, CamYaw;
|
||||||
static vec3 CamPos;
|
static vec3 CamPos;
|
||||||
static int ThirdPerson = 1;
|
static int ThirdPerson = 1;
|
||||||
@@ -171,8 +170,10 @@ static void charcallback(GLFWwindow *window, unsigned int codepoint) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fix_resol();
|
||||||
static void resizecallback(GLFWwindow *window, int width, int height) {
|
static void resizecallback(GLFWwindow *window, int width, int height) {
|
||||||
k3Resize(width, height);
|
k3Resize(width, height);
|
||||||
|
fix_resol();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int argc;
|
static int argc;
|
||||||
@@ -186,83 +187,6 @@ const char *k4_get_arg(const char *name) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void netwrap_step() {
|
|
||||||
if(NetWrap.stage && CurrentTime >= NetWrap.timeout) {
|
|
||||||
if(NetWrap.stage == 1) {
|
|
||||||
if(stoon_req(&NetWrap.stoon)) {
|
|
||||||
if(stoon_listen(&NetWrap.stoon)) {
|
|
||||||
uint8_t conndata[STOON_CONN_INFO_SIZE] = {};
|
|
||||||
stoon_serialize(&NetWrap.stoon, conndata);
|
|
||||||
|
|
||||||
char str[STOON_CONN_INFO_SIZE * 2 + 1] = {};
|
|
||||||
for(int i = 0; i < sizeof(conndata); i++) {
|
|
||||||
snprintf(str + i * 2, 3, "%02x", conndata[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
luaapi_peercode_found(str);
|
|
||||||
|
|
||||||
//glfwSetClipboardString(NULL, str);
|
|
||||||
|
|
||||||
//screenMain.lblpeerdata->invisible = 0;
|
|
||||||
//screenMain.btnconnect->invisible = 0;
|
|
||||||
|
|
||||||
NetWrap.stage = 2;
|
|
||||||
} else {
|
|
||||||
k3Log(k3_INFO, "Stoon listen timeout.");
|
|
||||||
NetWrap.timeout = CurrentTime + 0.5;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
k3Log(k3_INFO, "Stoon request failed.");
|
|
||||||
NetWrap.timeout = CurrentTime + 0.5;
|
|
||||||
}
|
|
||||||
} else if(NetWrap.stage == 2) {
|
|
||||||
stoon_keepalive(&NetWrap.stoon);
|
|
||||||
|
|
||||||
NetWrap.timeout = CurrentTime + 1;
|
|
||||||
} else if(NetWrap.stage == 3) {
|
|
||||||
int status = stoon_poonch(&NetWrap.stoon, NetWrap.otherpeer);
|
|
||||||
|
|
||||||
//screenMain.lblpeerdata->txt = strdup("Trying to connect...\nMay not work if both are\nbehind symmetric NATs.");
|
|
||||||
|
|
||||||
if(status == STOON_POONCH_INCOMPATIBLE_NETFAMS) {
|
|
||||||
NetWrap.stage = 0;
|
|
||||||
|
|
||||||
stoon_kill(&NetWrap.stoon);
|
|
||||||
|
|
||||||
//screenMain.lblpeerdata->txt = strdup("Connection cannot be established:\nIncompatible netfams.");
|
|
||||||
} else if(status == STOON_POONCH_NO_KNOCK && NetWrap.stoon.poonchstage == POONCH_STAGE_ACK) {
|
|
||||||
if(NetWrap.gotten++ > 5) {
|
|
||||||
NetWrap.stage = 0;
|
|
||||||
stoon_kill(&NetWrap.stoon);
|
|
||||||
|
|
||||||
if(NetWrap.isHost) {
|
|
||||||
net_server_init();
|
|
||||||
} else {
|
|
||||||
char ip[64];
|
|
||||||
int port;
|
|
||||||
if(*(uint16_t*) (NetWrap.otherpeer + 22) == 0) {
|
|
||||||
inet_ntop(AF_INET, NetWrap.otherpeer, ip, sizeof(ip));
|
|
||||||
port = ntohs(*(uint16_t*) (NetWrap.otherpeer + 4));
|
|
||||||
} else {
|
|
||||||
inet_ntop(AF_INET6, NetWrap.otherpeer + 6, ip, sizeof(ip));
|
|
||||||
port = ntohs(*(uint16_t*) (NetWrap.otherpeer + 22));
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Trying [%s]:%u\n", ip, port);
|
|
||||||
|
|
||||||
net_client_init();
|
|
||||||
net_client_connect(ip, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
//screenMain.lblpeerdata->txt = strdup("Connection successful.");
|
|
||||||
}
|
|
||||||
} else NetWrap.gotten = 0;
|
|
||||||
|
|
||||||
NetWrap.timeout = CurrentTime + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include<signal.h>
|
#include<signal.h>
|
||||||
void k4k3LogCallback(enum k3LogLevel lvl, const char *str, size_t len) {
|
void k4k3LogCallback(enum k3LogLevel lvl, const char *str, size_t len) {
|
||||||
static const char *prefixes[] = {
|
static const char *prefixes[] = {
|
||||||
@@ -303,6 +227,7 @@ static int eng_init() {
|
|||||||
GameWnd = glfwCreateWindow(START_WIDTH, START_HEIGHT, START_TITLE, NULL, NULL);
|
GameWnd = glfwCreateWindow(START_WIDTH, START_HEIGHT, START_TITLE, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attempt compatibility
|
||||||
if(!GameWnd) {
|
if(!GameWnd) {
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE);
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE);
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE);
|
||||||
@@ -350,6 +275,7 @@ static int eng_init() {
|
|||||||
printf("GL vendor: %s\n", glGetString(GL_VENDOR));
|
printf("GL vendor: %s\n", glGetString(GL_VENDOR));
|
||||||
|
|
||||||
k3SetLogCallback(k4k3LogCallback);
|
k3SetLogCallback(k4k3LogCallback);
|
||||||
|
|
||||||
k3Init();
|
k3Init();
|
||||||
|
|
||||||
k3BatchInit();
|
k3BatchInit();
|
||||||
@@ -373,152 +299,8 @@ static void fix_resol() {
|
|||||||
gr_lowres(roundf(w * ResolPercentage / 100.f / 4) * 4, roundf(h * ResolPercentage / 100.f / 4) * 4);
|
gr_lowres(roundf(w * ResolPercentage / 100.f / 4) * 4, roundf(h * ResolPercentage / 100.f / 4) * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool onqualitypress(struct k3MEvent *ev, uint8_t *ud) {
|
|
||||||
k3GraphicalReduction = (k3GraphicalReduction + 1) % 3;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
static bool onresolpress(struct k3MEvent *ev, uint8_t *ud) {
|
|
||||||
struct k3MTextButton *btn = (void*) ev->target;
|
|
||||||
|
|
||||||
ResolPercentage -= 10;
|
|
||||||
|
|
||||||
if(ResolPercentage <= 0) {
|
|
||||||
ResolPercentage = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *txt = NULL;
|
|
||||||
|
|
||||||
switch(ResolPercentage) {
|
|
||||||
case 10:
|
|
||||||
txt = "10%";
|
|
||||||
break;
|
|
||||||
case 20:
|
|
||||||
txt = "20%";
|
|
||||||
break;
|
|
||||||
case 30:
|
|
||||||
txt = "30%";
|
|
||||||
break;
|
|
||||||
case 40:
|
|
||||||
txt = "40%";
|
|
||||||
break;
|
|
||||||
case 50:
|
|
||||||
txt = "50%";
|
|
||||||
break;
|
|
||||||
case 60:
|
|
||||||
txt = "60%";
|
|
||||||
break;
|
|
||||||
case 70:
|
|
||||||
txt = "70%";
|
|
||||||
break;
|
|
||||||
case 80:
|
|
||||||
txt = "80%";
|
|
||||||
break;
|
|
||||||
case 90:
|
|
||||||
txt = "90%";
|
|
||||||
break;
|
|
||||||
case 100:
|
|
||||||
txt = "Full Resolution";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
btn->txt = strdup(txt);
|
|
||||||
|
|
||||||
fix_resol();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
static bool ontexrespress(struct k3MEvent *ev, uint8_t *ud) {
|
|
||||||
TextureResolutionReduction = (TextureResolutionReduction + 1) % 3;
|
|
||||||
refresh_textures();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
static bool onresumepress(struct k3MEvent *ev, uint8_t *ud) {
|
|
||||||
UiActive = NULL;
|
|
||||||
set_ui_mode(0);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#ifdef LOCALHOST_ONLY
|
|
||||||
static bool onhostpress(struct k3MEvent *ev, uint8_t *ud) {
|
|
||||||
net_server_init();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
static bool onjoinpress(struct k3MEvent *ev, uint8_t *ud) {
|
|
||||||
net_client_init();
|
|
||||||
net_client_connect("127.0.0.1", 26656);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
static bool onconnectpress(struct k3MEvent *ev, uint8_t *ud) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static bool onhostpress(struct k3MEvent *ev, uint8_t *ud) {
|
|
||||||
screenMain.btnhost->disabled = 1;
|
|
||||||
screenMain.btnjoin->disabled = 1;
|
|
||||||
|
|
||||||
NetWrap.stage = 1;
|
|
||||||
NetWrap.timeout = glfwGetTime() + 0;
|
|
||||||
NetWrap.isHost = 1;
|
|
||||||
NetWrap.stoon = stoon_init("stun.easybell.de", 3478, 26656);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
static bool onjoinpress(struct k3MEvent *ev, uint8_t *ud) {
|
|
||||||
screenMain.btnhost->disabled = 1;
|
|
||||||
screenMain.btnjoin->disabled = 1;
|
|
||||||
|
|
||||||
NetWrap.stage = 1;
|
|
||||||
NetWrap.timeout = glfwGetTime() + 0;
|
|
||||||
NetWrap.isHost = 0;
|
|
||||||
NetWrap.stoon = stoon_init("stun.easybell.de", 3478, 26656);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
static bool onconnectpress(struct k3MEvent *ev, uint8_t *ud) {
|
|
||||||
const char *name = glfwGetClipboardString(NULL);
|
|
||||||
|
|
||||||
while(isspace(*name)) name++;
|
|
||||||
|
|
||||||
if(strlen(name) < STOON_CONN_INFO_SIZE * 2) {
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < STOON_CONN_INFO_SIZE; i++) {
|
|
||||||
int b = 0;
|
|
||||||
|
|
||||||
if(name[i * 2 + 0] >= '0' && name[i * 2 + 0] <= '9') {
|
|
||||||
b |= (name[i * 2 + 0] - '0') << 4;
|
|
||||||
} else if(name[i * 2 + 0] >= 'a' && name[i * 2 + 0] <= 'f') {
|
|
||||||
b |= (name[i * 2 + 0] - 'a' + 10) << 4;
|
|
||||||
} else goto bad;
|
|
||||||
|
|
||||||
if(name[i * 2 + 1] >= '0' && name[i * 2 + 1] <= '9') {
|
|
||||||
b |= (name[i * 2 + 1] - '0') << 0;
|
|
||||||
} else if(name[i * 2 + 1] >= 'a' && name[i * 2 + 1] <= 'f') {
|
|
||||||
b |= (name[i * 2 + 1] - 'a' + 10) << 0;
|
|
||||||
} else goto bad;
|
|
||||||
|
|
||||||
NetWrap.otherpeer[i] = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetWrap.stage = 3;
|
|
||||||
screenMain.btnconnect->disabled = 1;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
bad:
|
|
||||||
screenMain.lblpeerdata->txt = strdup("Incorrect peer conndata.");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
static bool onconsoleenter(struct k3MEvent *ev, uint8_t *ud) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void eng_ui_init() {
|
static void eng_ui_init() {
|
||||||
set_ui_mode(1);
|
set_ui_mode(!!UiActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fps_counter_step(double newDT) {
|
static void fps_counter_step(double newDT) {
|
||||||
@@ -557,6 +339,7 @@ static int gr_shadowmap_init() {
|
|||||||
"!!ARBfp1.0\n"
|
"!!ARBfp1.0\n"
|
||||||
"TEMP col;\n"
|
"TEMP col;\n"
|
||||||
"TEX col, fragment.texcoord, texture[0], 2D;\n"
|
"TEX col, fragment.texcoord, texture[0], 2D;\n"
|
||||||
|
"MOV result.color, col;\n"
|
||||||
"MAD col.xyz, -col, 29.9, 30.1;\n"
|
"MAD col.xyz, -col, 29.9, 30.1;\n"
|
||||||
"RCP col.x, col.x;\n"
|
"RCP col.x, col.x;\n"
|
||||||
"RCP col.y, col.y;\n"
|
"RCP col.y, col.y;\n"
|
||||||
@@ -601,32 +384,17 @@ static int gr_lowres(int newW, int newH) {
|
|||||||
}
|
}
|
||||||
k3TexUpdate(lowresDepth, k3_DEPTH, 0, newW, newH, NULL);
|
k3TexUpdate(lowresDepth, k3_DEPTH, 0, newW, newH, NULL);
|
||||||
|
|
||||||
lowresOffscreen = k3OffscreenCreate(lowres, lowresDepth);
|
lowresOffscreen = k3OffscreenCreateMultisampled(lowres, lowresDepth, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!lowresOffscreen;
|
return !!lowresOffscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_RAYS 64
|
|
||||||
static struct LocalRay RaysToCast[MAX_RAYS];
|
|
||||||
static size_t RaysToCastCount = 0;
|
|
||||||
|
|
||||||
struct LocalRay *request_ray(struct LocalRay *lr) {
|
|
||||||
if(RaysToCastCount == MAX_RAYS) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(RaysToCast + RaysToCastCount, lr, sizeof(*lr));
|
|
||||||
|
|
||||||
return &RaysToCast[RaysToCastCount++];
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc_, char **argv_) {
|
int main(int argc_, char **argv_) {
|
||||||
argc = argc_;
|
argc = argc_;
|
||||||
argv = argv_;
|
argv = argv_;
|
||||||
|
|
||||||
eng_init();
|
eng_init();
|
||||||
eng_ui_init();
|
|
||||||
|
|
||||||
gr_shadowmap_init();
|
gr_shadowmap_init();
|
||||||
gr_bloom_init();
|
gr_bloom_init();
|
||||||
@@ -643,10 +411,10 @@ int main(int argc_, char **argv_) {
|
|||||||
|
|
||||||
// INIT LEVEL
|
// INIT LEVEL
|
||||||
game_init();
|
game_init();
|
||||||
luaapi_load(k4_get_arg("script") ? k4_get_arg("script") : "lvl1");
|
luaapi_load(k4_get_arg("script") ? k4_get_arg("script") : "init");
|
||||||
//
|
//
|
||||||
|
|
||||||
LuaapiStartTime = glfwGetTime();
|
eng_ui_init();
|
||||||
|
|
||||||
LastTime = glfwGetTime();
|
LastTime = glfwGetTime();
|
||||||
|
|
||||||
@@ -663,7 +431,7 @@ int main(int argc_, char **argv_) {
|
|||||||
|
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
netwrap_step();
|
net_hi_update(CurrentTime);
|
||||||
|
|
||||||
float alpha = fmodf(accumulator * GAME_TPS, 1.f);
|
float alpha = fmodf(accumulator * GAME_TPS, 1.f);
|
||||||
|
|
||||||
@@ -699,9 +467,6 @@ int main(int argc_, char **argv_) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
game_raycast(RaysToCast, RaysToCastCount);
|
|
||||||
RaysToCastCount = 0;
|
|
||||||
|
|
||||||
while(accumulator >= 1. / GAME_TPS) {
|
while(accumulator >= 1. / GAME_TPS) {
|
||||||
for(size_t i = 0; i < Game.entities.renderCount; i++) {
|
for(size_t i = 0; i < Game.entities.renderCount; i++) {
|
||||||
glm_vec4_copy(Game.entities.render[i].pos, Game.entities.render[i].posLast);
|
glm_vec4_copy(Game.entities.render[i].pos, Game.entities.render[i].posLast);
|
||||||
@@ -728,10 +493,10 @@ int main(int argc_, char **argv_) {
|
|||||||
glfwGetFramebufferSize(GameWnd, &width, &height);
|
glfwGetFramebufferSize(GameWnd, &width, &height);
|
||||||
|
|
||||||
mat4 proj;
|
mat4 proj;
|
||||||
glm_perspective(glm_rad(LuaapiFov), (float) width / height, 0.01f, 100.f, proj);
|
glm_perspective(glm_rad(LuaapiFov), (float) width / height, 0.1f, 80.f, proj);
|
||||||
|
|
||||||
/* Third-person camera movement */
|
/* Third-person camera movement */
|
||||||
struct LocalRay camray;
|
struct LocalRay camray = {};
|
||||||
if(Game.spectated != ENT_ID_INVALID) {
|
if(Game.spectated != ENT_ID_INVALID) {
|
||||||
struct CRender *c = game_getcomponent(Game.spectated, render);
|
struct CRender *c = game_getcomponent(Game.spectated, render);
|
||||||
if(c) {
|
if(c) {
|
||||||
@@ -752,12 +517,20 @@ int main(int argc_, char **argv_) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mat4 cam;
|
mat4 cam;
|
||||||
|
if(InstantCamShift) {
|
||||||
|
InstantCamShift--;
|
||||||
|
}
|
||||||
if(LuaapiFirstPerson) {
|
if(LuaapiFirstPerson) {
|
||||||
struct CRender *c = game_getcomponent(Game.spectated, render);
|
struct CRender *cr = game_getcomponent(Game.spectated, render);
|
||||||
|
struct CPhysics *cp = game_getcomponent(Game.spectated, physics);
|
||||||
|
|
||||||
if(c) {
|
if(cr) {
|
||||||
vec3 p;
|
vec3 p;
|
||||||
glm_vec3_lerp(c->posLast, c->pos, alpha, p);
|
glm_vec3_lerp(cr->posLast, cr->pos, alpha, p);
|
||||||
|
|
||||||
|
if(cp && cp->type == CPHYSICS_CAPSULE) {
|
||||||
|
p[1] += cp->capsule.length / 2;
|
||||||
|
}
|
||||||
|
|
||||||
mat4 view;
|
mat4 view;
|
||||||
glm_look(p, cameraForwardDir, (vec3) {0, 1, 0}, view);
|
glm_look(p, cameraForwardDir, (vec3) {0, 1, 0}, view);
|
||||||
@@ -770,10 +543,15 @@ int main(int argc_, char **argv_) {
|
|||||||
vec3 almostThere;
|
vec3 almostThere;
|
||||||
|
|
||||||
if(LuaapiCamFocus) {
|
if(LuaapiCamFocus) {
|
||||||
|
float lerpa = InstantCamShift ? 1 : 0.1;
|
||||||
|
|
||||||
glm_vec3_copy(LuaapiCamFocusPos, almostThere);
|
glm_vec3_copy(LuaapiCamFocusPos, almostThere);
|
||||||
glm_vec3_lerp(CamPos, almostThere, 0.1, CamPos);
|
glm_vec3_lerp(CamPos, almostThere, 0.1, CamPos);
|
||||||
|
glm_vec3_copy(LuaapiCamFocusPos, CamPos);
|
||||||
glm_look(CamPos, LuaapiCamFocusDir, (vec3) {0, 1, 0}, cam);
|
glm_look(CamPos, LuaapiCamFocusDir, (vec3) {0, 1, 0}, cam);
|
||||||
} else {
|
} else {
|
||||||
|
float lerpa = InstantCamShift ? 1 : 0.2;
|
||||||
|
|
||||||
vec3 dirneg;
|
vec3 dirneg;
|
||||||
glm_vec3_negate_to(camray.dir, dirneg);
|
glm_vec3_negate_to(camray.dir, dirneg);
|
||||||
|
|
||||||
@@ -887,7 +665,7 @@ int main(int argc_, char **argv_) {
|
|||||||
|
|
||||||
// Shadowmap debugging
|
// Shadowmap debugging
|
||||||
if(glfwGetKey(GameWnd, GLFW_KEY_F5) == GLFW_PRESS) {
|
if(glfwGetKey(GameWnd, GLFW_KEY_F5) == GLFW_PRESS) {
|
||||||
k3BlitToScreen(shadowmapOffscreen, 0);
|
k3BlitToScreenEffect(shadowmapOffscreen, 0, k3_ARBFRAG, shadowmapDebugThing, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwSwapBuffers(GameWnd);
|
glfwSwapBuffers(GameWnd);
|
||||||
|
|||||||
@@ -26,12 +26,16 @@ void net_client_init() {
|
|||||||
Game.isAuthority = 0;
|
Game.isAuthority = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_client_connect(const char *addr, uint16_t port) {
|
bool net_client_connect(ENetAddress eaddr) {
|
||||||
ENetAddress eaddr;
|
|
||||||
enet_address_set_host(&eaddr, addr);
|
|
||||||
eaddr.port = port;
|
|
||||||
|
|
||||||
peer = enet_host_connect(host, &eaddr, 1, 0);
|
peer = enet_host_connect(host, &eaddr, 1, 0);
|
||||||
|
|
||||||
|
ENetEvent ev;
|
||||||
|
if(enet_host_service(host, &ev, 200) <= 0 || ev.type != ENET_EVENT_TYPE_CONNECT) {
|
||||||
|
enet_peer_reset(peer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern double glfwGetTime();
|
extern double glfwGetTime();
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include"enet.h"
|
||||||
|
|
||||||
void net_client_init();
|
void net_client_init();
|
||||||
void net_client_connect(const char *addr, uint16_t port);
|
bool net_client_connect(ENetAddress addr);
|
||||||
void net_client_receive();
|
void net_client_receive();
|
||||||
void net_client_update();
|
void net_client_update();
|
||||||
void net_client_dejitter();
|
void net_client_dejitter();
|
||||||
|
|||||||
211
src/net_hi.c
Normal file
211
src/net_hi.c
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
#include"net_hi.h"
|
||||||
|
|
||||||
|
#include<stddef.h>
|
||||||
|
#include"enet.h"
|
||||||
|
#include<stdlib.h>
|
||||||
|
#include"stoon.h"
|
||||||
|
#include"net_server.h"
|
||||||
|
#include"net_client.h"
|
||||||
|
#include<math.h>
|
||||||
|
#include"k3.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handles networking on a higher-level, combining hole punching with
|
||||||
|
* basic client & server interface
|
||||||
|
* */
|
||||||
|
|
||||||
|
static void *ReqPeercodeUD;
|
||||||
|
static void(*ReqPeercodeCB)(void*, struct StoonPeercode *peercode);
|
||||||
|
|
||||||
|
static struct Stoon stoon;
|
||||||
|
|
||||||
|
static bool inited = false;
|
||||||
|
static bool isHost;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ENetAddress pv4;
|
||||||
|
ENetAddress pv6;
|
||||||
|
|
||||||
|
ENetAddress lv4;
|
||||||
|
ENetAddress lv6;
|
||||||
|
} ToPunch;
|
||||||
|
static ToPunch *topunch = NULL;
|
||||||
|
static size_t topunchCount = 0;
|
||||||
|
|
||||||
|
static double Timeout = 0;
|
||||||
|
|
||||||
|
static bool connected = false;
|
||||||
|
|
||||||
|
static uint16_t servport = 0;
|
||||||
|
|
||||||
|
bool net_hi_request_peercode(void *ud, void(*callback)(void*, struct StoonPeercode *peercode)) {
|
||||||
|
if(inited) return false;
|
||||||
|
|
||||||
|
ReqPeercodeUD = ud;
|
||||||
|
ReqPeercodeCB = callback;
|
||||||
|
|
||||||
|
for(size_t port = 25000; port <= 26656; port++) {
|
||||||
|
stoon = stoon_init("stun.easybell.de", 3478, port);
|
||||||
|
|
||||||
|
if(stoon.fd4 >= 0 || stoon.fd6 >= 0) {
|
||||||
|
servport = port;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timeout = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool net_hi_setup(bool host) {
|
||||||
|
if(inited) return false;
|
||||||
|
|
||||||
|
stoon_kill(&stoon);
|
||||||
|
|
||||||
|
inited = true;
|
||||||
|
isHost = host;
|
||||||
|
|
||||||
|
if(host) {
|
||||||
|
net_server_init(servport);
|
||||||
|
} else {
|
||||||
|
net_client_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_hi_update(double now) {
|
||||||
|
if(now <= Timeout) return;
|
||||||
|
|
||||||
|
if(ReqPeercodeCB) {
|
||||||
|
|
||||||
|
if(stoon_req(&stoon)) {
|
||||||
|
if(stoon_listen(&stoon)) {
|
||||||
|
ReqPeercodeCB(ReqPeercodeUD, &stoon.peercode);
|
||||||
|
|
||||||
|
ReqPeercodeCB = NULL;
|
||||||
|
} else {
|
||||||
|
k3Log(k3_INFO, "stoon_listen failure");
|
||||||
|
|
||||||
|
Timeout = now + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
k3Log(k3_INFO, "stoon_req failure");
|
||||||
|
|
||||||
|
Timeout = now + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(!inited) {
|
||||||
|
|
||||||
|
stoon_keepalive(&stoon);
|
||||||
|
|
||||||
|
Timeout = now + 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if(isHost) {
|
||||||
|
|
||||||
|
ENetHost *h = net_server_get_enethost();
|
||||||
|
|
||||||
|
ENetBuffer buf = {.data = "Punch!", .dataLength = 6};
|
||||||
|
|
||||||
|
for(size_t tpi = 0; tpi < topunchCount; tpi++) {
|
||||||
|
ToPunch *tp = &topunch[tpi];
|
||||||
|
|
||||||
|
if(tp->lv6.port) enet_socket_send(h->socket, &tp->lv6, &buf, 1);
|
||||||
|
if(tp->lv4.port) enet_socket_send(h->socket, &tp->lv4, &buf, 1);
|
||||||
|
|
||||||
|
if(tp->pv6.port) enet_socket_send(h->socket, &tp->pv6, &buf, 1);
|
||||||
|
if(tp->pv4.port) enet_socket_send(h->socket, &tp->pv4, &buf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Timeout = now + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool stoonpeer_to_enet4(uint8_t *publicV4, uint8_t *publicP4, ENetAddress *enet) {
|
||||||
|
memset(enet, 0, sizeof(*enet));
|
||||||
|
|
||||||
|
if(*(uint32_t*) publicV4 == 0 || *(uint16_t*) publicP4 == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *addr8 = (uint8_t*) &enet->host;
|
||||||
|
|
||||||
|
memset(addr8, 0, 16);
|
||||||
|
addr8[10] = 0xFF;
|
||||||
|
addr8[11] = 0xFF;
|
||||||
|
addr8[12] = publicV4[0];
|
||||||
|
addr8[13] = publicV4[1];
|
||||||
|
addr8[14] = publicV4[2];
|
||||||
|
addr8[15] = publicV4[3];
|
||||||
|
enet->port = *(uint16_t*) publicP4;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool stoonpeer_to_enet6(uint8_t *publicV6, uint8_t *publicP6, ENetAddress *enet) {
|
||||||
|
memset(enet, 0, sizeof(*enet));
|
||||||
|
|
||||||
|
if(*(uint32_t*) publicV6 == 0 || *(uint16_t*) publicP6 == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *addr8 = (uint8_t*) &enet->host;
|
||||||
|
|
||||||
|
memcpy(addr8, publicV6, 16);
|
||||||
|
enet->port = *(uint16_t*) publicP6;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_hi_add_punch(struct StoonPeercode *peercode) {
|
||||||
|
topunch = realloc(topunch, sizeof(*topunch) * (++topunchCount));
|
||||||
|
ToPunch *tp = &topunch[topunchCount - 1];
|
||||||
|
|
||||||
|
stoonpeer_to_enet4(peercode->publicV4, peercode->publicP4, &tp->pv4);
|
||||||
|
stoonpeer_to_enet6(peercode->publicV6, peercode->publicP6, &tp->pv6);
|
||||||
|
|
||||||
|
stoonpeer_to_enet4(peercode->localV4, peercode->localP4, &tp->lv4);
|
||||||
|
stoonpeer_to_enet6(peercode->localV6, peercode->localP6, &tp->lv6);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool net_hi_connect(struct StoonPeercode *peercode) {
|
||||||
|
if(!inited) return false;
|
||||||
|
|
||||||
|
if(connected) return false;
|
||||||
|
|
||||||
|
ENetAddress pv4, pv6;
|
||||||
|
stoonpeer_to_enet4(peercode->publicV4, peercode->publicP4, &pv4);
|
||||||
|
stoonpeer_to_enet6(peercode->publicV6, peercode->publicP6, &pv6);
|
||||||
|
|
||||||
|
ENetAddress lv4, lv6;
|
||||||
|
stoonpeer_to_enet4(peercode->localV4, peercode->localP4, &lv4);
|
||||||
|
stoonpeer_to_enet6(peercode->localV6, peercode->localP6, &lv6);
|
||||||
|
|
||||||
|
if(lv6.port && net_client_connect(lv6)) {
|
||||||
|
k3Log(k3_INFO, "Found local IPv6");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(lv4.port && net_client_connect(lv4)) {
|
||||||
|
k3Log(k3_INFO, "Found local IPv4");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pv6.port && net_client_connect(pv6)) {
|
||||||
|
k3Log(k3_INFO, "Found remote IPv6");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(pv4.port && net_client_connect(pv4)) {
|
||||||
|
k3Log(k3_INFO, "Found remote IPv4");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
k3Log(k3_INFO, "Failed to establish connection");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
13
src/net_hi.h
Normal file
13
src/net_hi.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include<stdbool.h>
|
||||||
|
|
||||||
|
struct StoonPeercode;
|
||||||
|
|
||||||
|
bool net_hi_request_peercode(void *ud, void(*callback)(void*, struct StoonPeercode *peercode));
|
||||||
|
bool net_hi_setup(bool host);
|
||||||
|
void net_hi_update(double now);
|
||||||
|
|
||||||
|
void net_hi_add_punch(struct StoonPeercode *peercode);
|
||||||
|
|
||||||
|
bool net_hi_connect(struct StoonPeercode *peercode);
|
||||||
@@ -18,8 +18,8 @@ struct Conn {
|
|||||||
#define MAX_PLAYERS 64
|
#define MAX_PLAYERS 64
|
||||||
static struct Conn conns[MAX_PLAYERS];
|
static struct Conn conns[MAX_PLAYERS];
|
||||||
|
|
||||||
void net_server_init() {
|
void net_server_init(uint16_t port) {
|
||||||
host = enet_host_create(&(ENetAddress) {.host = ENET_HOST_ANY, .port = 26656}, 16, 1, 0, 0);
|
host = enet_host_create(&(ENetAddress) {.host = ENET_HOST_ANY, .port = port}, 16, 1, 0, 0);
|
||||||
|
|
||||||
Game.isMultiplayer = 1;
|
Game.isMultiplayer = 1;
|
||||||
Game.isAuthority = 1;
|
Game.isAuthority = 1;
|
||||||
@@ -342,3 +342,7 @@ void net_server_broadcast_msg(struct bstr *data) {
|
|||||||
|
|
||||||
free(b.data);
|
free(b.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *net_server_get_enethost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
struct _ENetPeer;
|
struct _ENetPeer;
|
||||||
struct bstr;
|
struct bstr;
|
||||||
|
|
||||||
void net_server_init();
|
void net_server_init(uint16_t port);
|
||||||
void net_server_receive();
|
void net_server_receive();
|
||||||
void net_server_update();
|
void net_server_update();
|
||||||
|
|
||||||
@@ -14,3 +14,5 @@ void net_server_force_load(struct _ENetPeer *peer, const char *script);
|
|||||||
|
|
||||||
void net_server_send_msg(struct _ENetPeer *peer, struct bstr *data);
|
void net_server_send_msg(struct _ENetPeer *peer, struct bstr *data);
|
||||||
void net_server_broadcast_msg(struct bstr *data);
|
void net_server_broadcast_msg(struct bstr *data);
|
||||||
|
|
||||||
|
void *net_server_get_enethost();
|
||||||
|
|||||||
524
src/noise1234.c
Normal file
524
src/noise1234.c
Normal file
@@ -0,0 +1,524 @@
|
|||||||
|
// noise1234
|
||||||
|
//
|
||||||
|
// Author: Stefan Gustavson, 2003-2005
|
||||||
|
// Contact: stefan.gustavson@liu.se
|
||||||
|
//
|
||||||
|
// This code was GPL licensed until February 2011.
|
||||||
|
// As the original author of this code, I hereby
|
||||||
|
// release it into the public domain.
|
||||||
|
// Please feel free to use it for whatever you want.
|
||||||
|
// Credit is appreciated where appropriate, and I also
|
||||||
|
// appreciate being told where this code finds any use,
|
||||||
|
// but you may do as you like.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This implementation is "Improved Noise" as presented by
|
||||||
|
* Ken Perlin at Siggraph 2002. The 3D function is a direct port
|
||||||
|
* of his Java reference code which was once publicly available
|
||||||
|
* on www.noisemachine.com (although I cleaned it up, made it
|
||||||
|
* faster and made the code more readable), but the 1D, 2D and
|
||||||
|
* 4D functions were implemented from scratch by me.
|
||||||
|
*
|
||||||
|
* This is a backport to C of my improved noise class in C++
|
||||||
|
* which was included in the Aqsis renderer project.
|
||||||
|
* It is highly reusable without source code modifications.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "noise1234.h"
|
||||||
|
|
||||||
|
// This is the new and improved, C(2) continuous interpolant
|
||||||
|
#define FADE(t) ( t * t * t * ( t * ( t * 6 - 15 ) + 10 ) )
|
||||||
|
|
||||||
|
#define FASTFLOOR(x) ( ((int)(x)<(x)) ? ((int)x) : ((int)x-1 ) )
|
||||||
|
#define LERP(t, a, b) ((a) + (t)*((b)-(a)))
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Static data
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Permutation table. This is just a random jumble of all numbers 0-255,
|
||||||
|
* repeated twice to avoid wrapping the index at 255 for each lookup.
|
||||||
|
* This needs to be exactly the same for all instances on all platforms,
|
||||||
|
* so it's easiest to just keep it as static explicit data.
|
||||||
|
* This also removes the need for any initialisation of this class.
|
||||||
|
*
|
||||||
|
* Note that making this an int[] instead of a char[] might make the
|
||||||
|
* code run faster on platforms with a high penalty for unaligned single
|
||||||
|
* byte addressing. Intel x86 is generally single-byte-friendly, but
|
||||||
|
* some other CPUs are faster with 4-aligned reads.
|
||||||
|
* However, a char[] is smaller, which avoids cache trashing, and that
|
||||||
|
* is probably the most important aspect on most architectures.
|
||||||
|
* This array is accessed a *lot* by the noise functions.
|
||||||
|
* A vector-valued noise over 3D accesses it 96 times, and a
|
||||||
|
* float-valued 4D noise 64 times. We want this to fit in the cache!
|
||||||
|
*/
|
||||||
|
unsigned char perm[] = {151,160,137,91,90,15,
|
||||||
|
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
||||||
|
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
||||||
|
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
||||||
|
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
||||||
|
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
||||||
|
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
||||||
|
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
||||||
|
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
||||||
|
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
||||||
|
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
||||||
|
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
||||||
|
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
|
||||||
|
151,160,137,91,90,15,
|
||||||
|
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
||||||
|
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
||||||
|
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
||||||
|
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
||||||
|
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
||||||
|
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
||||||
|
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
||||||
|
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
||||||
|
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
||||||
|
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
||||||
|
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
||||||
|
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper functions to compute gradients-dot-residualvectors (1D to 4D)
|
||||||
|
* Note that these generate gradients of more than unit length. To make
|
||||||
|
* a close match with the value range of classic Perlin noise, the final
|
||||||
|
* noise values need to be rescaled. To match the RenderMan noise in a
|
||||||
|
* statistical sense, the approximate scaling values (empirically
|
||||||
|
* determined from test renderings) are:
|
||||||
|
* 1D noise needs rescaling with 0.188
|
||||||
|
* 2D noise needs rescaling with 0.507
|
||||||
|
* 3D noise needs rescaling with 0.936
|
||||||
|
* 4D noise needs rescaling with 0.87
|
||||||
|
* Note that these noise functions are the most practical and useful
|
||||||
|
* signed version of Perlin noise. To return values according to the
|
||||||
|
* RenderMan specification from the SL noise() and pnoise() functions,
|
||||||
|
* the noise values need to be scaled and offset to [0,1], like this:
|
||||||
|
* float SLnoise = (noise3(x,y,z) + 1.0) * 0.5;
|
||||||
|
*/
|
||||||
|
|
||||||
|
float grad1( int hash, float x ) {
|
||||||
|
int h = hash & 15;
|
||||||
|
float grad = 1.0 + (h & 7); // Gradient value 1.0, 2.0, ..., 8.0
|
||||||
|
if (h&8) grad = -grad; // and a random sign for the gradient
|
||||||
|
return ( grad * x ); // Multiply the gradient with the distance
|
||||||
|
}
|
||||||
|
|
||||||
|
float grad2( int hash, float x, float y ) {
|
||||||
|
int h = hash & 7; // Convert low 3 bits of hash code
|
||||||
|
float u = h<4 ? x : y; // into 8 simple gradient directions,
|
||||||
|
float v = h<4 ? y : x; // and compute the dot product with (x,y).
|
||||||
|
return ((h&1)? -u : u) + ((h&2)? -2.0*v : 2.0*v);
|
||||||
|
}
|
||||||
|
|
||||||
|
float grad3( int hash, float x, float y , float z ) {
|
||||||
|
int h = hash & 15; // Convert low 4 bits of hash code into 12 simple
|
||||||
|
float u = h<8 ? x : y; // gradient directions, and compute dot product.
|
||||||
|
float v = h<4 ? y : h==12||h==14 ? x : z; // Fix repeats at h = 12 to 15
|
||||||
|
return ((h&1)? -u : u) + ((h&2)? -v : v);
|
||||||
|
}
|
||||||
|
|
||||||
|
float grad4( int hash, float x, float y, float z, float t ) {
|
||||||
|
int h = hash & 31; // Convert low 5 bits of hash code into 32 simple
|
||||||
|
float u = h<24 ? x : y; // gradient directions, and compute dot product.
|
||||||
|
float v = h<16 ? y : z;
|
||||||
|
float w = h<8 ? z : t;
|
||||||
|
return ((h&1)? -u : u) + ((h&2)? -v : v) + ((h&4)? -w : w);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/** 1D float Perlin noise, SL "noise()"
|
||||||
|
*/
|
||||||
|
float noise1( float x )
|
||||||
|
{
|
||||||
|
int ix0, ix1;
|
||||||
|
float fx0, fx1;
|
||||||
|
float s, n0, n1;
|
||||||
|
|
||||||
|
ix0 = FASTFLOOR( x ); // Integer part of x
|
||||||
|
fx0 = x - ix0; // Fractional part of x
|
||||||
|
fx1 = fx0 - 1.0f;
|
||||||
|
ix1 = ( ix0+1 ) & 0xff;
|
||||||
|
ix0 = ix0 & 0xff; // Wrap to 0..255
|
||||||
|
|
||||||
|
s = FADE( fx0 );
|
||||||
|
|
||||||
|
n0 = grad1( perm[ ix0 ], fx0 );
|
||||||
|
n1 = grad1( perm[ ix1 ], fx1 );
|
||||||
|
return 0.188f * ( LERP( s, n0, n1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/** 1D float Perlin periodic noise, SL "pnoise()"
|
||||||
|
*/
|
||||||
|
float pnoise1( float x, int px )
|
||||||
|
{
|
||||||
|
int ix0, ix1;
|
||||||
|
float fx0, fx1;
|
||||||
|
float s, n0, n1;
|
||||||
|
|
||||||
|
ix0 = FASTFLOOR( x ); // Integer part of x
|
||||||
|
fx0 = x - ix0; // Fractional part of x
|
||||||
|
fx1 = fx0 - 1.0f;
|
||||||
|
ix1 = (( ix0 + 1 ) % px) & 0xff; // Wrap to 0..px-1 *and* wrap to 0..255
|
||||||
|
ix0 = ( ix0 % px ) & 0xff; // (because px might be greater than 256)
|
||||||
|
|
||||||
|
s = FADE( fx0 );
|
||||||
|
|
||||||
|
n0 = grad1( perm[ ix0 ], fx0 );
|
||||||
|
n1 = grad1( perm[ ix1 ], fx1 );
|
||||||
|
return 0.188f * ( LERP( s, n0, n1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/** 2D float Perlin noise.
|
||||||
|
*/
|
||||||
|
float noise2( float x, float y )
|
||||||
|
{
|
||||||
|
int ix0, iy0, ix1, iy1;
|
||||||
|
float fx0, fy0, fx1, fy1;
|
||||||
|
float s, t, nx0, nx1, n0, n1;
|
||||||
|
|
||||||
|
ix0 = FASTFLOOR( x ); // Integer part of x
|
||||||
|
iy0 = FASTFLOOR( y ); // Integer part of y
|
||||||
|
fx0 = x - ix0; // Fractional part of x
|
||||||
|
fy0 = y - iy0; // Fractional part of y
|
||||||
|
fx1 = fx0 - 1.0f;
|
||||||
|
fy1 = fy0 - 1.0f;
|
||||||
|
ix1 = (ix0 + 1) & 0xff; // Wrap to 0..255
|
||||||
|
iy1 = (iy0 + 1) & 0xff;
|
||||||
|
ix0 = ix0 & 0xff;
|
||||||
|
iy0 = iy0 & 0xff;
|
||||||
|
|
||||||
|
t = FADE( fy0 );
|
||||||
|
s = FADE( fx0 );
|
||||||
|
|
||||||
|
nx0 = grad2(perm[ix0 + perm[iy0]], fx0, fy0);
|
||||||
|
nx1 = grad2(perm[ix0 + perm[iy1]], fx0, fy1);
|
||||||
|
n0 = LERP( t, nx0, nx1 );
|
||||||
|
|
||||||
|
nx0 = grad2(perm[ix1 + perm[iy0]], fx1, fy0);
|
||||||
|
nx1 = grad2(perm[ix1 + perm[iy1]], fx1, fy1);
|
||||||
|
n1 = LERP(t, nx0, nx1);
|
||||||
|
|
||||||
|
return 0.507f * ( LERP( s, n0, n1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/** 2D float Perlin periodic noise.
|
||||||
|
*/
|
||||||
|
float pnoise2( float x, float y, int px, int py )
|
||||||
|
{
|
||||||
|
int ix0, iy0, ix1, iy1;
|
||||||
|
float fx0, fy0, fx1, fy1;
|
||||||
|
float s, t, nx0, nx1, n0, n1;
|
||||||
|
|
||||||
|
ix0 = FASTFLOOR( x ); // Integer part of x
|
||||||
|
iy0 = FASTFLOOR( y ); // Integer part of y
|
||||||
|
fx0 = x - ix0; // Fractional part of x
|
||||||
|
fy0 = y - iy0; // Fractional part of y
|
||||||
|
fx1 = fx0 - 1.0f;
|
||||||
|
fy1 = fy0 - 1.0f;
|
||||||
|
ix1 = (( ix0 + 1 ) % px) & 0xff; // Wrap to 0..px-1 and wrap to 0..255
|
||||||
|
iy1 = (( iy0 + 1 ) % py) & 0xff; // Wrap to 0..py-1 and wrap to 0..255
|
||||||
|
ix0 = ( ix0 % px ) & 0xff;
|
||||||
|
iy0 = ( iy0 % py ) & 0xff;
|
||||||
|
|
||||||
|
t = FADE( fy0 );
|
||||||
|
s = FADE( fx0 );
|
||||||
|
|
||||||
|
nx0 = grad2(perm[ix0 + perm[iy0]], fx0, fy0);
|
||||||
|
nx1 = grad2(perm[ix0 + perm[iy1]], fx0, fy1);
|
||||||
|
n0 = LERP( t, nx0, nx1 );
|
||||||
|
|
||||||
|
nx0 = grad2(perm[ix1 + perm[iy0]], fx1, fy0);
|
||||||
|
nx1 = grad2(perm[ix1 + perm[iy1]], fx1, fy1);
|
||||||
|
n1 = LERP(t, nx0, nx1);
|
||||||
|
|
||||||
|
return 0.507f * ( LERP( s, n0, n1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/** 3D float Perlin noise.
|
||||||
|
*/
|
||||||
|
float noise3( float x, float y, float z )
|
||||||
|
{
|
||||||
|
int ix0, iy0, ix1, iy1, iz0, iz1;
|
||||||
|
float fx0, fy0, fz0, fx1, fy1, fz1;
|
||||||
|
float s, t, r;
|
||||||
|
float nxy0, nxy1, nx0, nx1, n0, n1;
|
||||||
|
|
||||||
|
ix0 = FASTFLOOR( x ); // Integer part of x
|
||||||
|
iy0 = FASTFLOOR( y ); // Integer part of y
|
||||||
|
iz0 = FASTFLOOR( z ); // Integer part of z
|
||||||
|
fx0 = x - ix0; // Fractional part of x
|
||||||
|
fy0 = y - iy0; // Fractional part of y
|
||||||
|
fz0 = z - iz0; // Fractional part of z
|
||||||
|
fx1 = fx0 - 1.0f;
|
||||||
|
fy1 = fy0 - 1.0f;
|
||||||
|
fz1 = fz0 - 1.0f;
|
||||||
|
ix1 = ( ix0 + 1 ) & 0xff; // Wrap to 0..255
|
||||||
|
iy1 = ( iy0 + 1 ) & 0xff;
|
||||||
|
iz1 = ( iz0 + 1 ) & 0xff;
|
||||||
|
ix0 = ix0 & 0xff;
|
||||||
|
iy0 = iy0 & 0xff;
|
||||||
|
iz0 = iz0 & 0xff;
|
||||||
|
|
||||||
|
r = FADE( fz0 );
|
||||||
|
t = FADE( fy0 );
|
||||||
|
s = FADE( fx0 );
|
||||||
|
|
||||||
|
nxy0 = grad3(perm[ix0 + perm[iy0 + perm[iz0]]], fx0, fy0, fz0);
|
||||||
|
nxy1 = grad3(perm[ix0 + perm[iy0 + perm[iz1]]], fx0, fy0, fz1);
|
||||||
|
nx0 = LERP( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
nxy0 = grad3(perm[ix0 + perm[iy1 + perm[iz0]]], fx0, fy1, fz0);
|
||||||
|
nxy1 = grad3(perm[ix0 + perm[iy1 + perm[iz1]]], fx0, fy1, fz1);
|
||||||
|
nx1 = LERP( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
n0 = LERP( t, nx0, nx1 );
|
||||||
|
|
||||||
|
nxy0 = grad3(perm[ix1 + perm[iy0 + perm[iz0]]], fx1, fy0, fz0);
|
||||||
|
nxy1 = grad3(perm[ix1 + perm[iy0 + perm[iz1]]], fx1, fy0, fz1);
|
||||||
|
nx0 = LERP( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
nxy0 = grad3(perm[ix1 + perm[iy1 + perm[iz0]]], fx1, fy1, fz0);
|
||||||
|
nxy1 = grad3(perm[ix1 + perm[iy1 + perm[iz1]]], fx1, fy1, fz1);
|
||||||
|
nx1 = LERP( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
n1 = LERP( t, nx0, nx1 );
|
||||||
|
|
||||||
|
return 0.936f * ( LERP( s, n0, n1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/** 3D float Perlin periodic noise.
|
||||||
|
*/
|
||||||
|
float pnoise3( float x, float y, float z, int px, int py, int pz )
|
||||||
|
{
|
||||||
|
int ix0, iy0, ix1, iy1, iz0, iz1;
|
||||||
|
float fx0, fy0, fz0, fx1, fy1, fz1;
|
||||||
|
float s, t, r;
|
||||||
|
float nxy0, nxy1, nx0, nx1, n0, n1;
|
||||||
|
|
||||||
|
ix0 = FASTFLOOR( x ); // Integer part of x
|
||||||
|
iy0 = FASTFLOOR( y ); // Integer part of y
|
||||||
|
iz0 = FASTFLOOR( z ); // Integer part of z
|
||||||
|
fx0 = x - ix0; // Fractional part of x
|
||||||
|
fy0 = y - iy0; // Fractional part of y
|
||||||
|
fz0 = z - iz0; // Fractional part of z
|
||||||
|
fx1 = fx0 - 1.0f;
|
||||||
|
fy1 = fy0 - 1.0f;
|
||||||
|
fz1 = fz0 - 1.0f;
|
||||||
|
ix1 = (( ix0 + 1 ) % px ) & 0xff; // Wrap to 0..px-1 and wrap to 0..255
|
||||||
|
iy1 = (( iy0 + 1 ) % py ) & 0xff; // Wrap to 0..py-1 and wrap to 0..255
|
||||||
|
iz1 = (( iz0 + 1 ) % pz ) & 0xff; // Wrap to 0..pz-1 and wrap to 0..255
|
||||||
|
ix0 = ( ix0 % px ) & 0xff;
|
||||||
|
iy0 = ( iy0 % py ) & 0xff;
|
||||||
|
iz0 = ( iz0 % pz ) & 0xff;
|
||||||
|
|
||||||
|
r = FADE( fz0 );
|
||||||
|
t = FADE( fy0 );
|
||||||
|
s = FADE( fx0 );
|
||||||
|
|
||||||
|
nxy0 = grad3(perm[ix0 + perm[iy0 + perm[iz0]]], fx0, fy0, fz0);
|
||||||
|
nxy1 = grad3(perm[ix0 + perm[iy0 + perm[iz1]]], fx0, fy0, fz1);
|
||||||
|
nx0 = LERP( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
nxy0 = grad3(perm[ix0 + perm[iy1 + perm[iz0]]], fx0, fy1, fz0);
|
||||||
|
nxy1 = grad3(perm[ix0 + perm[iy1 + perm[iz1]]], fx0, fy1, fz1);
|
||||||
|
nx1 = LERP( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
n0 = LERP( t, nx0, nx1 );
|
||||||
|
|
||||||
|
nxy0 = grad3(perm[ix1 + perm[iy0 + perm[iz0]]], fx1, fy0, fz0);
|
||||||
|
nxy1 = grad3(perm[ix1 + perm[iy0 + perm[iz1]]], fx1, fy0, fz1);
|
||||||
|
nx0 = LERP( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
nxy0 = grad3(perm[ix1 + perm[iy1 + perm[iz0]]], fx1, fy1, fz0);
|
||||||
|
nxy1 = grad3(perm[ix1 + perm[iy1 + perm[iz1]]], fx1, fy1, fz1);
|
||||||
|
nx1 = LERP( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
n1 = LERP( t, nx0, nx1 );
|
||||||
|
|
||||||
|
return 0.936f * ( LERP( s, n0, n1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/** 4D float Perlin noise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
float noise4( float x, float y, float z, float w )
|
||||||
|
{
|
||||||
|
int ix0, iy0, iz0, iw0, ix1, iy1, iz1, iw1;
|
||||||
|
float fx0, fy0, fz0, fw0, fx1, fy1, fz1, fw1;
|
||||||
|
float s, t, r, q;
|
||||||
|
float nxyz0, nxyz1, nxy0, nxy1, nx0, nx1, n0, n1;
|
||||||
|
|
||||||
|
ix0 = FASTFLOOR( x ); // Integer part of x
|
||||||
|
iy0 = FASTFLOOR( y ); // Integer part of y
|
||||||
|
iz0 = FASTFLOOR( z ); // Integer part of y
|
||||||
|
iw0 = FASTFLOOR( w ); // Integer part of w
|
||||||
|
fx0 = x - ix0; // Fractional part of x
|
||||||
|
fy0 = y - iy0; // Fractional part of y
|
||||||
|
fz0 = z - iz0; // Fractional part of z
|
||||||
|
fw0 = w - iw0; // Fractional part of w
|
||||||
|
fx1 = fx0 - 1.0f;
|
||||||
|
fy1 = fy0 - 1.0f;
|
||||||
|
fz1 = fz0 - 1.0f;
|
||||||
|
fw1 = fw0 - 1.0f;
|
||||||
|
ix1 = ( ix0 + 1 ) & 0xff; // Wrap to 0..255
|
||||||
|
iy1 = ( iy0 + 1 ) & 0xff;
|
||||||
|
iz1 = ( iz0 + 1 ) & 0xff;
|
||||||
|
iw1 = ( iw0 + 1 ) & 0xff;
|
||||||
|
ix0 = ix0 & 0xff;
|
||||||
|
iy0 = iy0 & 0xff;
|
||||||
|
iz0 = iz0 & 0xff;
|
||||||
|
iw0 = iw0 & 0xff;
|
||||||
|
|
||||||
|
q = FADE( fw0 );
|
||||||
|
r = FADE( fz0 );
|
||||||
|
t = FADE( fy0 );
|
||||||
|
s = FADE( fx0 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx0, fy0, fz0, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx0, fy0, fz0, fw1);
|
||||||
|
nxy0 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx0, fy0, fz1, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx0, fy0, fz1, fw1);
|
||||||
|
nxy1 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nx0 = LERP ( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx0, fy1, fz0, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx0, fy1, fz0, fw1);
|
||||||
|
nxy0 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx0, fy1, fz1, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx0, fy1, fz1, fw1);
|
||||||
|
nxy1 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nx1 = LERP ( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
n0 = LERP( t, nx0, nx1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx1, fy0, fz0, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx1, fy0, fz0, fw1);
|
||||||
|
nxy0 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx1, fy0, fz1, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx1, fy0, fz1, fw1);
|
||||||
|
nxy1 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nx0 = LERP ( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx1, fy1, fz0, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx1, fy1, fz0, fw1);
|
||||||
|
nxy0 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx1, fy1, fz1, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx1, fy1, fz1, fw1);
|
||||||
|
nxy1 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nx1 = LERP ( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
n1 = LERP( t, nx0, nx1 );
|
||||||
|
|
||||||
|
return 0.87f * ( LERP( s, n0, n1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/** 4D float Perlin periodic noise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
float pnoise4( float x, float y, float z, float w,
|
||||||
|
int px, int py, int pz, int pw )
|
||||||
|
{
|
||||||
|
int ix0, iy0, iz0, iw0, ix1, iy1, iz1, iw1;
|
||||||
|
float fx0, fy0, fz0, fw0, fx1, fy1, fz1, fw1;
|
||||||
|
float s, t, r, q;
|
||||||
|
float nxyz0, nxyz1, nxy0, nxy1, nx0, nx1, n0, n1;
|
||||||
|
|
||||||
|
ix0 = FASTFLOOR( x ); // Integer part of x
|
||||||
|
iy0 = FASTFLOOR( y ); // Integer part of y
|
||||||
|
iz0 = FASTFLOOR( z ); // Integer part of y
|
||||||
|
iw0 = FASTFLOOR( w ); // Integer part of w
|
||||||
|
fx0 = x - ix0; // Fractional part of x
|
||||||
|
fy0 = y - iy0; // Fractional part of y
|
||||||
|
fz0 = z - iz0; // Fractional part of z
|
||||||
|
fw0 = w - iw0; // Fractional part of w
|
||||||
|
fx1 = fx0 - 1.0f;
|
||||||
|
fy1 = fy0 - 1.0f;
|
||||||
|
fz1 = fz0 - 1.0f;
|
||||||
|
fw1 = fw0 - 1.0f;
|
||||||
|
ix1 = (( ix0 + 1 ) % px ) & 0xff; // Wrap to 0..px-1 and wrap to 0..255
|
||||||
|
iy1 = (( iy0 + 1 ) % py ) & 0xff; // Wrap to 0..py-1 and wrap to 0..255
|
||||||
|
iz1 = (( iz0 + 1 ) % pz ) & 0xff; // Wrap to 0..pz-1 and wrap to 0..255
|
||||||
|
iw1 = (( iw0 + 1 ) % pw ) & 0xff; // Wrap to 0..pw-1 and wrap to 0..255
|
||||||
|
ix0 = ( ix0 % px ) & 0xff;
|
||||||
|
iy0 = ( iy0 % py ) & 0xff;
|
||||||
|
iz0 = ( iz0 % pz ) & 0xff;
|
||||||
|
iw0 = ( iw0 % pw ) & 0xff;
|
||||||
|
|
||||||
|
q = FADE( fw0 );
|
||||||
|
r = FADE( fz0 );
|
||||||
|
t = FADE( fy0 );
|
||||||
|
s = FADE( fx0 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx0, fy0, fz0, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx0, fy0, fz0, fw1);
|
||||||
|
nxy0 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx0, fy0, fz1, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx0, fy0, fz1, fw1);
|
||||||
|
nxy1 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nx0 = LERP ( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx0, fy1, fz0, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx0, fy1, fz0, fw1);
|
||||||
|
nxy0 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx0, fy1, fz1, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx0, fy1, fz1, fw1);
|
||||||
|
nxy1 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nx1 = LERP ( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
n0 = LERP( t, nx0, nx1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx1, fy0, fz0, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx1, fy0, fz0, fw1);
|
||||||
|
nxy0 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx1, fy0, fz1, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx1, fy0, fz1, fw1);
|
||||||
|
nxy1 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nx0 = LERP ( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx1, fy1, fz0, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx1, fy1, fz0, fw1);
|
||||||
|
nxy0 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx1, fy1, fz1, fw0);
|
||||||
|
nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx1, fy1, fz1, fw1);
|
||||||
|
nxy1 = LERP( q, nxyz0, nxyz1 );
|
||||||
|
|
||||||
|
nx1 = LERP ( r, nxy0, nxy1 );
|
||||||
|
|
||||||
|
n1 = LERP( t, nx0, nx1 );
|
||||||
|
|
||||||
|
return 0.87f * ( LERP( s, n0, n1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
41
src/noise1234.h
Normal file
41
src/noise1234.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// noise1234
|
||||||
|
//
|
||||||
|
// Author: Stefan Gustavson, 2003-2005
|
||||||
|
// Contact: stefan.gustavson@liu.se
|
||||||
|
//
|
||||||
|
// This code was GPL licensed until February 2011.
|
||||||
|
// As the original author of this code, I hereby
|
||||||
|
// release it into the public domain.
|
||||||
|
// Please feel free to use it for whatever you want.
|
||||||
|
// Credit is appreciated where appropriate, and I also
|
||||||
|
// appreciate being told where this code finds any use,
|
||||||
|
// but you may do as you like.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This implementation is "Improved Noise" as presented by
|
||||||
|
* Ken Perlin at Siggraph 2002. The 3D function is a direct port
|
||||||
|
* of his Java reference code which was once publicly available
|
||||||
|
* on www.noisemachine.com (although I cleaned it up, made it
|
||||||
|
* faster and made the code more readable), but the 1D, 2D and
|
||||||
|
* 4D functions were implemented from scratch by me.
|
||||||
|
*
|
||||||
|
* This is a backport to C of my improved noise class in C++
|
||||||
|
* which was included in the Aqsis renderer project.
|
||||||
|
* It is highly reusable without source code modifications.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 1D, 2D, 3D and 4D float Perlin noise
|
||||||
|
*/
|
||||||
|
extern float noise1( float x );
|
||||||
|
extern float noise2( float x, float y );
|
||||||
|
extern float noise3( float x, float y, float z );
|
||||||
|
extern float noise4( float x, float y, float z, float w );
|
||||||
|
|
||||||
|
/** 1D, 2D, 3D and 4D float Perlin periodic noise
|
||||||
|
*/
|
||||||
|
extern float pnoise1( float x, int px );
|
||||||
|
extern float pnoise2( float x, float y, int px, int py );
|
||||||
|
extern float pnoise3( float x, float y, float z, int px, int py, int pz );
|
||||||
|
extern float pnoise4( float x, float y, float z, float w,
|
||||||
|
int px, int py, int pz, int pw );
|
||||||
136
src/stoon.c
136
src/stoon.c
@@ -4,11 +4,13 @@
|
|||||||
#include<winsock2.h>
|
#include<winsock2.h>
|
||||||
#include<ws2tcpip.h>
|
#include<ws2tcpip.h>
|
||||||
#include<ntsecapi.h>
|
#include<ntsecapi.h>
|
||||||
|
#include<iphlpapi.h>
|
||||||
#else
|
#else
|
||||||
#include<netdb.h>
|
#include<netdb.h>
|
||||||
#include<sys/socket.h>
|
#include<sys/socket.h>
|
||||||
#include<sys/random.h>
|
#include<sys/random.h>
|
||||||
#include<arpa/inet.h>
|
#include<arpa/inet.h>
|
||||||
|
#include<ifaddrs.h>
|
||||||
#endif
|
#endif
|
||||||
#include<unistd.h>
|
#include<unistd.h>
|
||||||
#include<sys/types.h>
|
#include<sys/types.h>
|
||||||
@@ -43,7 +45,7 @@ struct StunMsg {
|
|||||||
uint8_t id[12];
|
uint8_t id[12];
|
||||||
};
|
};
|
||||||
|
|
||||||
static int stoon_init_mini(struct addrinfo *serv, uint16_t myport) {
|
static int stoon_init_mini(struct Stoon *this, struct addrinfo *serv, uint16_t myport) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
errno = 0;
|
errno = 0;
|
||||||
int fd = socket(serv->ai_family, serv->ai_socktype, serv->ai_protocol);
|
int fd = socket(serv->ai_family, serv->ai_socktype, serv->ai_protocol);
|
||||||
@@ -59,16 +61,79 @@ static int stoon_init_mini(struct addrinfo *serv, uint16_t myport) {
|
|||||||
char p[6];
|
char p[6];
|
||||||
sprintf(p, "%u", myport);
|
sprintf(p, "%u", myport);
|
||||||
|
|
||||||
struct addrinfo *myaddr;
|
struct addrinfo *myaddrinfo;
|
||||||
if(getaddrinfo(NULL, p, &(struct addrinfo) {.ai_family = serv->ai_family, .ai_socktype = SOCK_DGRAM, .ai_protocol = IPPROTO_UDP, .ai_flags = AI_PASSIVE}, &myaddr)) {
|
if(getaddrinfo(NULL, p, &(struct addrinfo) {.ai_family = serv->ai_family, .ai_socktype = SOCK_DGRAM, .ai_protocol = IPPROTO_UDP, .ai_flags = AI_PASSIVE}, &myaddrinfo)) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(bind(fd, myaddr->ai_addr, myaddr->ai_addrlen)) {
|
if(bind(fd, myaddrinfo->ai_addr, myaddrinfo->ai_addrlen)) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
freeaddrinfo(myaddr);
|
|
||||||
|
freeaddrinfo(myaddrinfo);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
size_t sz = 1024 * 64;
|
||||||
|
IP_ADAPTER_ADDRESSES *addrs = malloc(sz);
|
||||||
|
if(GetAdaptersAddresses(serv->ai_family, GAA_FLAG_SKIP_MULTICAST, NULL, addrs, &sz) == NO_ERROR) {
|
||||||
|
for(IP_ADAPTER_ADDRESSES *ifa = addrs; ifa; ifa = ifa->Next) {
|
||||||
|
if(!ifa->FirstUnicastAddress) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(serv->ai_family == AF_INET6) {
|
||||||
|
uint8_t *addr = (void*) &((struct sockaddr_in6*) ifa->FirstUnicastAddress->Address.lpSockaddr)->sin6_addr;
|
||||||
|
if(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0 && addr[4] == 0 && addr[5] == 0 && addr[6] == 0 && addr[7] == 0 && addr[8] == 0 && addr[9] == 0 && addr[10] == 0 && addr[11] == 0 && addr[12] == 0 && addr[13] == 0 && addr[14] == 0 && (addr[15] == 0 || addr[15] == 1)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(this->peercode.localV6, addr, 16);
|
||||||
|
memcpy(this->peercode.localP6, &myport, 2);
|
||||||
|
} else {
|
||||||
|
uint8_t *addr = (void*) &((struct sockaddr_in*) ifa->FirstUnicastAddress->Address.lpSockaddr)->sin_addr;
|
||||||
|
if(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0 || addr[0] == 127 && addr[1] == 0 && addr[2] == 0 && addr[3] == 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(this->peercode.localV4, addr, 4);
|
||||||
|
memcpy(this->peercode.localP4, &myport, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(addrs);
|
||||||
|
#else
|
||||||
|
struct ifaddrs *ifaddr;
|
||||||
|
if(getifaddrs(&ifaddr) >= 0) {
|
||||||
|
for(struct ifaddrs *ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
|
||||||
|
if(!ifa->ifa_addr || ifa->ifa_addr->sa_family != serv->ai_family) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(serv->ai_family == AF_INET6) {
|
||||||
|
uint8_t *addr = (void*) &((struct sockaddr_in6*) ifa->ifa_addr)->sin6_addr;
|
||||||
|
if(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0 && addr[4] == 0 && addr[5] == 0 && addr[6] == 0 && addr[7] == 0 && addr[8] == 0 && addr[9] == 0 && addr[10] == 0 && addr[11] == 0 && addr[12] == 0 && addr[13] == 0 && addr[14] == 0 && (addr[15] == 0 || addr[15] == 1)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(this->peercode.localV6, addr, 16);
|
||||||
|
memcpy(this->peercode.localP6, &myport, 2);
|
||||||
|
} else {
|
||||||
|
uint8_t *addr = (void*) &((struct sockaddr_in*) ifa->ifa_addr)->sin_addr;
|
||||||
|
if(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0 || addr[0] == 127 && addr[1] == 0 && addr[2] == 0 && addr[3] == 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(this->peercode.localV4, addr, 4);
|
||||||
|
memcpy(this->peercode.localP4, &myport, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeifaddrs(ifaddr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@@ -92,18 +157,16 @@ struct Stoon stoon_init(const char *stunhost, uint16_t stunport, uint16_t myport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Stoon ret;
|
struct Stoon ret = {};
|
||||||
|
|
||||||
memset(&ret.my4, 0, sizeof(ret.my4));
|
|
||||||
if(v4) {
|
if(v4) {
|
||||||
memcpy(&ret.stu4, v4->ai_addr, v4->ai_addrlen);
|
memcpy(&ret.stu4, v4->ai_addr, v4->ai_addrlen);
|
||||||
ret.fd4 = stoon_init_mini(v4, myport);
|
ret.fd4 = stoon_init_mini(&ret, v4, myport);
|
||||||
} else ret.fd4 = -1;
|
} else ret.fd4 = -1;
|
||||||
|
|
||||||
memset(&ret.my6, 0, sizeof(ret.my6));
|
|
||||||
if(v6) {
|
if(v6) {
|
||||||
memcpy(&ret.stu6, v6->ai_addr, v6->ai_addrlen);
|
memcpy(&ret.stu6, v6->ai_addr, v6->ai_addrlen);
|
||||||
ret.fd6 = stoon_init_mini(v6, myport);
|
ret.fd6 = stoon_init_mini(&ret, v6, myport);
|
||||||
} else ret.fd6 = -1;
|
} else ret.fd6 = -1;
|
||||||
|
|
||||||
ret.poonchstage = 0;
|
ret.poonchstage = 0;
|
||||||
@@ -121,12 +184,21 @@ static int stoon_req_mini(struct Stoon *this, int *fd, struct sockaddr *serv, in
|
|||||||
if(errno == ENETUNREACH) {
|
if(errno == ENETUNREACH) {
|
||||||
close(*fd);
|
close(*fd);
|
||||||
*fd = -1;
|
*fd = -1;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
int stoon_req(struct Stoon *this) {
|
int stoon_req(struct Stoon *this) {
|
||||||
if(this->fd4 >= 0) stoon_req_mini(this, &this->fd4, (struct sockaddr*) &this->stu4, sizeof(struct sockaddr_in));
|
if(this->fd4 >= 0) stoon_req_mini(this, &this->fd4, (struct sockaddr*) &this->stu4, sizeof(struct sockaddr_in));
|
||||||
if(this->fd6 >= 0) stoon_req_mini(this, &this->fd6, (struct sockaddr*) &this->stu6, sizeof(struct sockaddr_in6));
|
if(this->fd6 >= 0) stoon_req_mini(this, &this->fd6, (struct sockaddr*) &this->stu6, sizeof(struct sockaddr_in6));
|
||||||
|
|
||||||
|
if(this->fd4 < 0 && this->fd6 < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv, int servlen) {
|
static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv, int servlen) {
|
||||||
@@ -161,11 +233,10 @@ static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv,
|
|||||||
uint16_t netfam = ntohs(((uint16_t*) d)[2]);
|
uint16_t netfam = ntohs(((uint16_t*) d)[2]);
|
||||||
uint16_t publicPort = ntohs(((uint16_t*) d)[3]) ^ (STUN_MAGIC >> 16);
|
uint16_t publicPort = ntohs(((uint16_t*) d)[3]) ^ (STUN_MAGIC >> 16);
|
||||||
if(netfam == STUN_NETFAM_IPV4) {
|
if(netfam == STUN_NETFAM_IPV4) {
|
||||||
uint32_t publicIp = ntohl(((uint32_t*) d)[2]) ^ STUN_MAGIC;
|
uint32_t publicIp = htonl(ntohl(((uint32_t*) d)[2]) ^ STUN_MAGIC);
|
||||||
|
|
||||||
this->my4.sin_family = AF_INET;
|
memcpy(this->peercode.publicV4, &publicIp, 4);
|
||||||
memcpy(&this->my4.sin_addr, &publicIp, 4);
|
memcpy(this->peercode.publicP4, &publicPort, 2);
|
||||||
this->my4.sin_port = htons(publicPort);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} else if(netfam == STUN_NETFAM_IPV6) {
|
} else if(netfam == STUN_NETFAM_IPV6) {
|
||||||
@@ -175,9 +246,8 @@ static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv,
|
|||||||
publicIp[2] = ((uint32_t*) d)[4] ^ ((uint32_t*) res.base.id)[1];
|
publicIp[2] = ((uint32_t*) d)[4] ^ ((uint32_t*) res.base.id)[1];
|
||||||
publicIp[3] = ((uint32_t*) d)[5] ^ ((uint32_t*) res.base.id)[2];
|
publicIp[3] = ((uint32_t*) d)[5] ^ ((uint32_t*) res.base.id)[2];
|
||||||
|
|
||||||
this->my6.sin6_family = AF_INET6;
|
memcpy(this->peercode.publicV6, &publicIp, 16);
|
||||||
memcpy(&this->my6.sin6_addr, &publicIp, 16);
|
memcpy(this->peercode.publicP6, &publicPort, 2);
|
||||||
this->my6.sin6_port = htons(publicPort);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
@@ -188,12 +258,12 @@ static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv,
|
|||||||
d += 4 + attribLen;
|
d += 4 + attribLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
int stoon_listen(struct Stoon *this) {
|
int stoon_listen(struct Stoon *this) {
|
||||||
if(this->fd4 >= 0) if(stoon_listen_mini(this, this->fd4, (struct sockaddr*) &this->stu4, sizeof(struct sockaddr_in)) < 0) return 0;
|
if(this->fd4 >= 0) if(stoon_listen_mini(this, this->fd4, (struct sockaddr*) &this->stu4, sizeof(struct sockaddr_in)) < 0) return 0;
|
||||||
if(this->fd6 >= 0) if(stoon_listen_mini(this, this->fd6, (struct sockaddr*) &this->stu6, sizeof(struct sockaddr_in6)) < 0) return 0;
|
if(this->fd6 >= 0) if(stoon_listen_mini(this, this->fd6, (struct sockaddr*) &this->stu6, sizeof(struct sockaddr_in6)) < 0) return 0;
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stoon_keepalive(struct Stoon *this) {
|
void stoon_keepalive(struct Stoon *this) {
|
||||||
@@ -217,31 +287,7 @@ void stoon_kill(struct Stoon *this) {
|
|||||||
this->fd6 = -1;
|
this->fd6 = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int stoon_v4_available(struct Stoon *this) {
|
/*int stoon_poonch(struct Stoon *this, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]) {
|
||||||
return this->fd4 >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int stoon_v6_available(struct Stoon *this) {
|
|
||||||
return this->fd6 >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void stoon_serialize(struct Stoon *this, uint8_t ret[static STOON_CONN_INFO_SIZE]) {
|
|
||||||
if(this->fd4 >= 0) {
|
|
||||||
memcpy(ret + 0, &this->my4.sin_addr, 4);
|
|
||||||
memcpy(ret + 4, &this->my4.sin_port, 2);
|
|
||||||
} else {
|
|
||||||
memset(ret, 0, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this->fd6 >= 0) {
|
|
||||||
memcpy(ret + 6, &this->my6.sin6_addr, 16);
|
|
||||||
memcpy(ret + 22, &this->my6.sin6_port, 2);
|
|
||||||
} else {
|
|
||||||
memset(ret + 6, 0, 18);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int stoon_poonch(struct Stoon *this, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]) {
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t addr4;
|
uint32_t addr4;
|
||||||
uint16_t port4;
|
uint16_t port4;
|
||||||
@@ -303,7 +349,7 @@ int stoon_poonch(struct Stoon *this, const uint8_t peerdata[static STOON_CONN_IN
|
|||||||
}
|
}
|
||||||
|
|
||||||
return STOON_POONCH_NO_KNOCK;
|
return STOON_POONCH_NO_KNOCK;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
#ifdef STOON_STANDALONE
|
#ifdef STOON_STANDALONE
|
||||||
int main() {
|
int main() {
|
||||||
|
|||||||
29
src/stoon.h
29
src/stoon.h
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include<stddef.h>
|
#include<stddef.h>
|
||||||
#include<stdint.h>
|
#include<stdint.h>
|
||||||
|
#include<stdbool.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include<winsock2.h>
|
#include<winsock2.h>
|
||||||
@@ -16,8 +17,6 @@
|
|||||||
|
|
||||||
/* Standalone hole punching libary (IPv4 & IPv6 compatible) */
|
/* Standalone hole punching libary (IPv4 & IPv6 compatible) */
|
||||||
|
|
||||||
#define STOON_CONN_INFO_SIZE (4 + 2 + 16 + 2)
|
|
||||||
|
|
||||||
#define POONCH_MAGIC 0x504F4348
|
#define POONCH_MAGIC 0x504F4348
|
||||||
#define POONCH_STAGE_KNOCKING 0
|
#define POONCH_STAGE_KNOCKING 0
|
||||||
#define POONCH_STAGE_ACK 1
|
#define POONCH_STAGE_ACK 1
|
||||||
@@ -26,16 +25,30 @@ struct Poonch {
|
|||||||
uint32_t stage;
|
uint32_t stage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct StoonPeercode {
|
||||||
|
uint8_t publicV4[4];
|
||||||
|
uint8_t publicP4[2];
|
||||||
|
|
||||||
|
uint8_t publicV6[16];
|
||||||
|
uint8_t publicP6[2];
|
||||||
|
|
||||||
|
uint8_t localV4[4];
|
||||||
|
uint8_t localP4[2];
|
||||||
|
|
||||||
|
uint8_t localV6[16];
|
||||||
|
uint8_t localP6[2];
|
||||||
|
};
|
||||||
|
|
||||||
struct Stoon {
|
struct Stoon {
|
||||||
struct sockaddr_in stu4;
|
struct sockaddr_in stu4;
|
||||||
struct sockaddr_in my4;
|
|
||||||
int fd4;
|
int fd4;
|
||||||
|
|
||||||
struct sockaddr_in6 stu6;
|
struct sockaddr_in6 stu6;
|
||||||
struct sockaddr_in6 my6;
|
|
||||||
int fd6;
|
int fd6;
|
||||||
|
|
||||||
uint8_t poonchstage;
|
uint8_t poonchstage;
|
||||||
|
|
||||||
|
struct StoonPeercode peercode;
|
||||||
};
|
};
|
||||||
|
|
||||||
// stunhost: Self-explanatory
|
// stunhost: Self-explanatory
|
||||||
@@ -53,12 +66,8 @@ void stoon_keepalive(struct Stoon*);
|
|||||||
|
|
||||||
void stoon_kill(struct Stoon*);
|
void stoon_kill(struct Stoon*);
|
||||||
|
|
||||||
int stoon_v4_available(struct Stoon*);
|
/*#define STOON_POONCH_INCOMPATIBLE_NETFAMS (-1)
|
||||||
int stoon_v6_available(struct Stoon*);
|
|
||||||
|
|
||||||
void stoon_serialize(struct Stoon*, uint8_t ret[static STOON_CONN_INFO_SIZE]);
|
|
||||||
|
|
||||||
#define STOON_POONCH_INCOMPATIBLE_NETFAMS (-1)
|
|
||||||
#define STOON_POONCH_NO_KNOCK 0
|
#define STOON_POONCH_NO_KNOCK 0
|
||||||
#define STOON_POONCH_ACKED 1
|
#define STOON_POONCH_ACKED 1
|
||||||
int stoon_poonch(struct Stoon*, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]);
|
int stoon_poonch(struct Stoon*, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]);
|
||||||
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user