From 325516eee745f1c45da1388c3ca61ff087399c17 Mon Sep 17 00:00:00 2001 From: Piotr Stanczyk Date: Tue, 6 Aug 2019 09:50:02 +0200 Subject: [PATCH] Project import generated by Copybara. PiperOrigin-RevId: 261857820 --- CHANGELOG | 10 +- README.md | 6 + gfootball/build_game_engine.sh | 2 +- gfootball/dump_to_txt.py | 23 ++-- .../{render_dump.py => dump_to_video.py} | 20 +-- gfootball/env/observation_processor.py | 124 ++++++++---------- gfootball/env/script_helpers.py | 119 +++++++++++++++++ gfootball/env/wrappers.py | 9 +- gfootball/play_game.py | 5 + gfootball/replay.py | 78 ++--------- setup.py | 2 +- third_party/gfootball_engine/CMakeLists.txt | 8 +- third_party/gfootball_engine/__init__.py | 2 +- third_party/gfootball_engine/ai.cpp | 4 - third_party/gfootball_engine/sources.cmake | 2 - third_party/gfootball_engine/src/base/log.cpp | 3 - .../src/base/math/bluntmath.hpp | 15 +-- .../src/base/math/matrix4.cpp | 2 +- .../src/base/math/matrix4.hpp | 2 +- .../gfootball_engine/src/base/properties.cpp | 2 - .../gfootball_engine/src/base/properties.hpp | 4 +- third_party/gfootball_engine/src/main.cpp | 1 - third_party/gfootball_engine/src/main.hpp | 7 + .../gfootball_engine/src/onthepitch/match.cpp | 26 ++-- .../strategies/special/celebration.cpp | 18 --- .../strategies/special/celebration.hpp | 23 ---- .../onthepitch/player/humanoid/humanoid.cpp | 48 +++---- .../player/humanoid/humanoidbase.cpp | 6 +- .../player/humanoid/humanoidbase.hpp | 2 - .../src/onthepitch/player/playerbase.cpp | 5 +- .../src/onthepitch/player/playerbase.hpp | 6 - .../src/onthepitch/proceduralpitch.cpp | 73 +++++------ .../src/onthepitch/proceduralpitch.hpp | 3 - .../graphics/rendering/opengl_renderer3d.hpp | 5 - 34 files changed, 314 insertions(+), 351 deletions(-) rename gfootball/{render_dump.py => dump_to_video.py} (60%) create mode 100644 gfootball/env/script_helpers.py delete mode 100755 third_party/gfootball_engine/src/onthepitch/player/controller/strategies/special/celebration.cpp delete mode 100755 third_party/gfootball_engine/src/onthepitch/player/controller/strategies/special/celebration.hpp diff --git a/CHANGELOG b/CHANGELOG index 70bc5f95..2fc132fa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,14 @@ Numbering scheme: Each environment release number is of the form vX.Y. X is the major version number, Y is the minor version number. Experiment results within the same X should not change, as modifications made to the environment are either -new features or backward compatible bug fixes. We will maintain vX branches -pointing at the most recent vX.Y +new features or backward compatible bug fixes. We will maintain vX branches +pointing at the most recent vX.Y. + +v1.2 +- Reduction of memory usage by the environment (https://github.com/google-research/football/issues/47). +- Reduction of memory usage during compilation (https://github.com/google-research/football/issues/49). +- Elimination of --no-pie compilation flag (https://github.com/google-research/football/issues/53). +- Fix for broken wrappers.py (https://github.com/google-research/football/issues/54). v1.1 - Add support for running multiple environment instances in a single process. diff --git a/README.md b/README.md index 67be223c..e92b1eb0 100644 --- a/README.md +++ b/README.md @@ -263,6 +263,12 @@ are controlled by the following set of flags: If rendering is disabled (`render` config flag), the video contains a simple episode animation. +There are following scripts provided to operate on trace dumps: + +- `dump_to_txt.py` - converts trace dump to human-readable form. +- `dump_to_video.py` - converts trace dump to a 2D representation video. +- `replay.py` - replays a given trace dump using environment. + ## Frequent Problems & Solutions ### Rendering not working / "OpenGL version not equal to or higher than 3.2" diff --git a/gfootball/build_game_engine.sh b/gfootball/build_game_engine.sh index 13603e6e..1ca0fee2 100755 --- a/gfootball/build_game_engine.sh +++ b/gfootball/build_game_engine.sh @@ -15,5 +15,5 @@ set -e # Delete pre-existing version of CMakeCache.txt to make 'pip3 install' work. rm -f third_party/gfootball_engine/CMakeCache.txt -pushd third_party/gfootball_engine && cmake . && make -j && popd +pushd third_party/gfootball_engine && cmake . && make -j `nproc` && popd pushd third_party/gfootball_engine && ln -sf libgame.so _gameplayfootball.so && popd diff --git a/gfootball/dump_to_txt.py b/gfootball/dump_to_txt.py index 3af6586e..977b1fdb 100644 --- a/gfootball/dump_to_txt.py +++ b/gfootball/dump_to_txt.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. + """Script converting dump file to human readable format. Example usage: @@ -19,30 +20,28 @@ """ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from gfootball.env import script_helpers from absl import app from absl import flags -import six.moves.cPickle - FLAGS = flags.FLAGS -flags.DEFINE_string('dump', '', 'Trace file to convert') -flags.DEFINE_string('output', '', 'Output txt file') +flags.DEFINE_string('trace_file', None, 'Trace file to convert') +flags.DEFINE_string('output', None, 'Output txt file') flags.DEFINE_bool('include_debug', True, 'Include debug information for each step') +flags.mark_flag_as_required('trace_file') +flags.mark_flag_as_required('output') def main(_): - with open(FLAGS.dump, 'rb') as f: - replay = six.moves.cPickle.load(f) - if not FLAGS.include_debug: - for s in replay: - if 'debug' in s: - del s['debug'] - with open(FLAGS.output, 'w') as f: - f.write(str(replay)) + script_helpers.ScriptHelpers().dump_to_txt(FLAGS.trace_file, FLAGS.output, + FLAGS.include_debug) if __name__ == '__main__': diff --git a/gfootball/render_dump.py b/gfootball/dump_to_video.py similarity index 60% rename from gfootball/render_dump.py rename to gfootball/dump_to_video.py index 092572a0..ab1734e5 100644 --- a/gfootball/render_dump.py +++ b/gfootball/dump_to_video.py @@ -16,26 +16,16 @@ from absl import app from absl import flags -from gfootball.env import config -from gfootball.env import observation_processor - -import six.moves.cPickle +from gfootball.env import script_helpers FLAGS = flags.FLAGS -flags.DEFINE_string('file', '', 'Dump file to render') +flags.DEFINE_string('trace_file', None, 'Trace file to render') +flags.mark_flag_as_required('trace_file') def main(_): - cfg = config.Config() - cfg['dump_full_episodes'] = True - cfg['write_video'] = True - cfg['display_game_stats'] = True - with open(FLAGS.file, 'rb') as f: - dump = six.moves.cPickle.load(f) - processor = observation_processor.ObservationProcessor(cfg) - for frame in dump: - processor.update(frame) - processor.write_dump('episode_done') + script_helpers.ScriptHelpers().dump_to_video(FLAGS.trace_file) + if __name__ == '__main__': app.run(main) diff --git a/gfootball/env/observation_processor.py b/gfootball/env/observation_processor.py index 46e81844..3e2bcc4e 100644 --- a/gfootball/env/observation_processor.py +++ b/gfootball/env/observation_processor.py @@ -36,6 +36,8 @@ import six.moves.cPickle import tensorflow as tf +REMOVED_FRAME = 'removed' + try: import cv2 except ImportError: @@ -48,13 +50,11 @@ class DumpConfig(object): def __init__(self, max_length=200, max_count=1, - skip_visuals=False, snapshot_delay=0, min_frequency=10): self._max_length = max_length self._max_count = max_count self._last_dump = 0 - self._skip_visuals = skip_visuals self._snapshot_delay = snapshot_delay self._file_name = None self._result = None @@ -86,53 +86,54 @@ def write(self, text, scale_factor=1): def get_frame(trace): if 'frame' in trace._trace['observation']: frame = trace._trace['observation']['frame'] - else: - frame = np.uint8(np.zeros((600, 800, 3))) - corner1 = (0, 0) - corner2 = (799, 0) - corner3 = (799, 599) - corner4 = (0, 599) - line_color = (0, 255, 255) - cv2.line(frame, corner1, corner2, line_color) - cv2.line(frame, corner2, corner3, line_color) - cv2.line(frame, corner3, corner4, line_color) - cv2.line(frame, corner4, corner1, line_color) - cv2.line(frame, (399, 0), (399, 799), line_color) + if frame != REMOVED_FRAME: + return frame + frame = np.uint8(np.zeros((600, 800, 3))) + corner1 = (0, 0) + corner2 = (799, 0) + corner3 = (799, 599) + corner4 = (0, 599) + line_color = (0, 255, 255) + cv2.line(frame, corner1, corner2, line_color) + cv2.line(frame, corner2, corner3, line_color) + cv2.line(frame, corner3, corner4, line_color) + cv2.line(frame, corner4, corner1, line_color) + cv2.line(frame, (399, 0), (399, 799), line_color) + writer = TextWriter( + frame, + trace['ball'][0], + trace['ball'][1], + field_coords=True, + color=(255, 0, 0)) + writer.write('B') + for player_idx, player_coord in enumerate(trace['left_team']): + writer = TextWriter( + frame, + player_coord[0], + player_coord[1], + field_coords=True, + color=(0, 255, 0)) + letter = 'H' + if 'active' in trace and player_idx in trace['active']: + letter = 'X' + elif 'left_agent_controlled_player' in trace and player_idx in trace[ + 'left_agent_controlled_player']: + letter = 'X' + writer.write(letter) + for player_idx, player_coord in enumerate(trace['right_team']): writer = TextWriter( frame, - trace['ball'][0], - trace['ball'][1], + player_coord[0], + player_coord[1], field_coords=True, - color=(255, 0, 0)) - writer.write('B') - for player_idx, player_coord in enumerate(trace['left_team']): - writer = TextWriter( - frame, - player_coord[0], - player_coord[1], - field_coords=True, - color=(0, 255, 0)) - letter = 'H' - if 'active' in trace and player_idx in trace['active']: - letter = 'X' - elif 'left_agent_controlled_player' in trace and player_idx in trace[ - 'left_agent_controlled_player']: - letter = 'X' - writer.write(letter) - for player_idx, player_coord in enumerate(trace['right_team']): - writer = TextWriter( - frame, - player_coord[0], - player_coord[1], - field_coords=True, - color=(0, 0, 255)) - letter = 'A' - if 'opponent_active' in trace and player_idx in trace['opponent_active']: - letter = 'Y' - elif 'right_agent_controlled_player' in trace and player_idx in trace[ - 'right_agent_controlled_player']: - letter = 'Y' - writer.write(letter) + color=(0, 0, 255)) + letter = 'A' + if 'opponent_active' in trace and player_idx in trace['opponent_active']: + letter = 'Y' + elif 'right_agent_controlled_player' in trace and player_idx in trace[ + 'right_agent_controlled_player']: + letter = 'Y' + writer.write(letter) return frame @@ -216,7 +217,7 @@ def write_dump(name, trace, skip_visuals=False, config={}): for o in trace: if 'frame' in o._trace['observation']: temp_frames.append(o._trace['observation']['frame']) - o._trace['observation']['frame'] = 'removed' + o._trace['observation']['frame'] = REMOVED_FRAME to_pickle.append(o._trace) with tf.io.gfile.GFile(name + '.dump', 'wb') as f: six.moves.cPickle.dump(to_pickle, f) @@ -229,14 +230,6 @@ def write_dump(name, trace, skip_visuals=False, config={}): return True -def logging_write_dump(name, trace, skip_visuals=False, config={}): - try: - write_dump(name, trace, skip_visuals=skip_visuals, config=config) - except Exception as e: - logging.info(traceback.format_exc()) - raise - - class ObservationState(object): def __init__(self, trace): @@ -245,7 +238,6 @@ def __init__(self, trace): self._additional_frames = [] self._debugs = [] self._time = timeit.default_timer() - self._right_defence_max_x = -10 def __getitem__(self, key): if key in self._trace: @@ -290,21 +282,17 @@ def __init__(self, config): max_length=200, max_count=(100000 if config['dump_scores'] else 0), min_frequency=600, - snapshot_delay=10, - skip_visuals=not config['write_video']) + snapshot_delay=10) self._dump_config['lost_score'] = DumpConfig( max_length=200, max_count=(100000 if config['dump_scores'] else 0), min_frequency=600, - snapshot_delay=10, - skip_visuals=not config['write_video']) + snapshot_delay=10) self._dump_config['episode_done'] = DumpConfig( max_length=(200 if HIGH_RES else 10000), - max_count=(100000 if config['dump_full_episodes'] else 0), - skip_visuals=not config['write_video']) + max_count=(100000 if config['dump_full_episodes'] else 0)) self._dump_config['shutdown'] = DumpConfig( - max_length=(200 if HIGH_RES else 10000), - skip_visuals=not config['write_video']) + max_length=(200 if HIGH_RES else 10000)) self._thread_pool = None self._dump_directory = None self._config = config @@ -331,13 +319,13 @@ def __getitem__(self, key): return self._trace[key] def add_frame(self, frame): - if len(self._trace) > 0: + if len(self._trace) > 0 and self._config['write_video']: self._trace[-1].add_frame(frame) @cfg.log def update(self, trace): self._frame += 1 - if not self._config['write_video'] and 'frame' in trace: + if not self._config['write_video'] and 'frame' in trace['observation']: # Don't record frame in the trace if we don't write video - full episode # consumes over 8G. no_video_trace = trace @@ -385,11 +373,11 @@ def process_pending_dumps(self, finish): if finish or config._trigger_step <= self._frame: logging.info('Start dump %s', name) trace = list(self._trace)[-config._max_length:] - write_dump(config._file_name, trace, config._skip_visuals, + write_dump(config._file_name, trace, self._config['write_video'], self._config) config._file_name = None if config._result: assert not config._file_name if config._result.ready() or finish: config._result.get() - config._result = None + config._result = None \ No newline at end of file diff --git a/gfootball/env/script_helpers.py b/gfootball/env/script_helpers.py new file mode 100644 index 00000000..4b49974d --- /dev/null +++ b/gfootball/env/script_helpers.py @@ -0,0 +1,119 @@ +# coding=utf-8 +# Copyright 2019 Google LLC +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Set of functions used by command line scripts.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from gfootball.env import config +from gfootball.env import football_action_set +from gfootball.env import football_env +from gfootball.env import observation_processor + +import copy +import six.moves.cPickle +import os +import tempfile +import tensorflow as tf + +class ScriptHelpers(object): + """Set of methods used by command line scripts.""" + + def __init__(self): + pass + + def __modify_trace(self, replay, fps): + """Adopt replay to the new framerate and add additional steps at the end.""" + trace = [] + min_fps = replay[0]['debug']['config']['physics_steps_per_frame'] + assert fps % min_fps == 0, ( + 'Trace has to be rendered in framerate being multiple of {}'.formmat( + min_fps)) + assert fps <= 100, ('Framerate of up to 100 is supported') + empty_steps = int(fps / min_fps) - 1 + for f in replay: + trace.append(f) + idle_step = copy.deepcopy(f) + idle_step['debug']['action'] = [football_action_set.action_idle + ] * len(f['debug']['action']) + for _ in range(empty_steps): + trace.append(idle_step) + # Add some empty steps at the end, so that we can record videos. + for _ in range(10): + trace.append(idle_step) + return trace + + def __build_players(self, dump_file, spec): + players = [] + for player in spec: + players.extend(['replay:path={},left_players=1'.format( + dump_file)] * config.count_left_players(player)) + players.extend(['replay:path={},right_players=1'.format( + dump_file)] * config.count_right_players(player)) + return players + + def dump_to_txt(self, dump_file, output, include_debug): + with open(dump_file, 'rb') as f: + replay = six.moves.cPickle.load(f) + if not include_debug: + for s in replay: + if 'debug' in s: + del s['debug'] + with open(output, 'w') as f: + f.write(str(replay)) + + def dump_to_video(self, dump_file): + with open(dump_file, 'rb') as f: + dump = six.moves.cPickle.load(f) + cfg = config.Config(dump[0]['debug']['config']) + cfg['dump_full_episodes'] = True + cfg['write_video'] = True + cfg['display_game_stats'] = True + processor = observation_processor.ObservationProcessor(cfg) + for frame in dump: + processor.update(frame) + processor.write_dump('episode_done') + + def replay(self, dump, fps=10, config_update={}, directory=None): + with open(dump, 'rb') as f: + replay = six.moves.cPickle.load(f) + trace = self.__modify_trace(replay, fps) + fd, temp_path = tempfile.mkstemp(suffix='.dump') + with open(temp_path, 'wb') as f: + six.moves.cPickle.dump(trace, f) + assert replay[0]['debug']['frame_cnt'] == 1, ( + 'Trace does not start from the beginning of the episode, can not replay') + cfg = config.Config(replay[0]['debug']['config']) + cfg['players'] = self.__build_players(temp_path, cfg['players']) + config_update['physics_steps_per_frame'] = int(100 / fps) + config_update['real_time'] = False + if 'render' not in config_update: + config_update['render'] = True + if directory: + config_update['tracesdir'] = directory + config_update['write_video'] = True + cfg.update(config_update) + env = football_env.FootballEnv(cfg) + env.reset() + done = False + try: + while not done: + _, _, done, _ = env.step(None) + except KeyboardInterrupt: + env.write_dump('shutdown') + exit(1) + os.close(fd) diff --git a/gfootball/env/wrappers.py b/gfootball/env/wrappers.py index 1961703c..0460863a 100644 --- a/gfootball/env/wrappers.py +++ b/gfootball/env/wrappers.py @@ -66,18 +66,18 @@ def __init__(self, env): self.observation_space = gym.spaces.Box( low=-1, high=1, shape=shape, dtype=np.float32) - def observation(self, obs): + def observation(self, observation): """Converts an observation into simple115 format. Args: - obs: observation that the environment returns + observation: observation that the environment returns Returns: (N, 155) shaped representation, where N stands for the number of players being controlled. """ final_obs = [] - for a in obs['active']: + for obs in observation: o = [] o.extend(obs['left_team'].flatten()) o.extend(obs['left_team_direction'].flatten()) @@ -103,7 +103,8 @@ def observation(self, obs): o.extend([0, 0, 1]) active = [0] * 11 - active[a] = 1 + if obs['active'] != -1: + active[obs['active']] = 1 o.extend(active) game_mode = [0] * 7 diff --git a/gfootball/play_game.py b/gfootball/play_game.py index 7a279646..f021bddb 100644 --- a/gfootball/play_game.py +++ b/gfootball/play_game.py @@ -12,8 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. + """Script allowing to play the game by multiple players.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + from absl import app from absl import flags diff --git a/gfootball/replay.py b/gfootball/replay.py index fcc082c1..9c1738cc 100644 --- a/gfootball/replay.py +++ b/gfootball/replay.py @@ -12,92 +12,30 @@ # See the License for the specific language governing permissions and # limitations under the License. + """Script allowing to replay a given trace file. Example usage: python replay.py --trace_file=/tmp/dumps/shutdown_20190521-165136974075.dump """ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function -from gfootball.env import football_action_set -from gfootball.env import football_env -from gfootball.env import config +from gfootball.env import script_helpers from absl import app from absl import flags -import copy -import six.moves.cPickle -import tempfile -import tensorflow as tf -import os FLAGS = flags.FLAGS -flags.DEFINE_string('trace_file', '', 'Trace file to replay') +flags.DEFINE_string('trace_file', None, 'Trace file to replay') flags.DEFINE_integer('fps', 10, 'How many frames per second to render') - - -def modify_trace(replay): - """Adopt replay to the new framerate and add additional steps at the end.""" - trace = [] - min_fps = replay[0]['debug']['config']['physics_steps_per_frame'] - assert FLAGS.fps % min_fps == 0, ( - 'Trace has to be rendered in framerate being multiple of {}'.formmat( - min_fps)) - assert FLAGS.fps <= 100, ('Framerate of up to 100 is supported') - empty_steps = int(FLAGS.fps / min_fps) - 1 - for f in replay: - trace.append(f) - idle_step = copy.deepcopy(f) - idle_step['debug']['action'] = [football_action_set.action_idle - ] * len(f['debug']['action']) - for _ in range(empty_steps): - trace.append(idle_step) - # Add some empty steps at the end, so that we can record videos. - for _ in range(10): - trace.append(idle_step) - return trace - -def build_players(dump_file, spec): - players = [] - for player in spec: - players.extend(['replay:path={},left_players=1'.format( - dump_file)] * config.count_left_players(player)) - players.extend(['replay:path={},right_players=1'.format( - dump_file)] * config.count_right_players(player)) - return players - -def replay(directory, dump, config_update={}): - with open(dump, 'rb') as f: - replay = six.moves.cPickle.load(f) - trace = modify_trace(replay) - fd, temp_path = tempfile.mkstemp(suffix='.dump') - with tf.gfile.Open(temp_path, 'wb') as f: - six.moves.cPickle.dump(trace, f) - assert replay[0]['debug']['frame_cnt'] == 1, ( - 'Trace does not start from the beginning of the episode, can not replay') - cfg = config.Config(replay[0]['debug']['config']) - cfg['players'] = build_players(temp_path, cfg['players']) - config_update['physics_steps_per_frame'] = int(100 / FLAGS.fps) - config_update['real_time'] = False - if 'render' not in config_update: - config_update['render'] = True - config_update['tracesdir'] = directory - config_update['write_video'] = True - cfg.update(config_update) - env = football_env.FootballEnv(cfg) - env.reset() - done = False - try: - while not done: - _, _, done, _ = env.step(None) - except KeyboardInterrupt: - env.write_dump('shutdown') - exit(1) - os.close(fd) +flags.mark_flag_as_required('trace_file') def main(_): - replay('/tmp/dumps', FLAGS.trace_file) + script_helpers.ScriptHelpers().replay(FLAGS.trace_file, FLAGS.fps) if __name__ == '__main__': app.run(main) diff --git a/setup.py b/setup.py index c29442b8..1ff4ed77 100644 --- a/setup.py +++ b/setup.py @@ -41,7 +41,7 @@ def run(self): setup( name='gfootball', - version='1.1', + version='1.2', description=('Google Research Football - RL environment based on ' 'open-source game Gameplay Football'), author='Google LLC', diff --git a/third_party/gfootball_engine/CMakeLists.txt b/third_party/gfootball_engine/CMakeLists.txt index b1157c3d..49fbf39c 100644 --- a/third_party/gfootball_engine/CMakeLists.txt +++ b/third_party/gfootball_engine/CMakeLists.txt @@ -19,11 +19,11 @@ project(gameplayfootball) set (CMAKE_CXX_STANDARD 14) if(UNIX) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -g -O3 -no-pie -L/usr/X11/lib -lX11 -lSDL2") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -g -O3 -no-pie -L/usr/X11/lib -lX11 -lSDL2") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -g -O3 -L/usr/X11/lib -lX11 -lSDL2") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -g -O3 -L/usr/X11/lib -lX11 -lSDL2") endif(UNIX) -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS} -fPIC -g -O3 -no-pie -L/usr/X11/lib -lX11 -lSDL2") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -O3 -g -no-pie -L/usr/X11/lib -lX11 -lSDL2") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS} -fPIC -g -O3 -L/usr/X11/lib -lX11 -lSDL2") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -O3 -g -L/usr/X11/lib -lX11 -lSDL2") # Find needed libraries FIND_PACKAGE(OpenGL REQUIRED) diff --git a/third_party/gfootball_engine/__init__.py b/third_party/gfootball_engine/__init__.py index 6f6431f1..b5d037f0 100644 --- a/third_party/gfootball_engine/__init__.py +++ b/third_party/gfootball_engine/__init__.py @@ -43,7 +43,7 @@ logging.warning('Looks like game engine is not compiled, please run:') engine_path = os.path.abspath(os.path.dirname(__file__)) logging.warning( - '  pushd {} && cmake . && make -j && popd'.format(game_path)) + '  pushd {} && cmake . && make -j `nproc` && popd'.format(game_path)) logging.warning('  pushd {} && ln -s libgame.so ' '_gameplayfootball.so && popd'.format(engine_path)) raise diff --git a/third_party/gfootball_engine/ai.cpp b/third_party/gfootball_engine/ai.cpp index d67122a0..a481a4f5 100644 --- a/third_party/gfootball_engine/ai.cpp +++ b/third_party/gfootball_engine/ai.cpp @@ -34,8 +34,6 @@ using namespace boost::interprocess; #define FRAME_SIZE (1280*720*3) -boost::shared_ptr game_; - using std::string; void GameEnv::do_step(int count) { @@ -111,8 +109,6 @@ std::string GameEnv::start_game(GameConfig game_config) { config->Set("game", 0); // Enable AI. config->SetBool("ai_keyboard", true); - // Disable Audio (not needed and sometimes causes trouble). - config->SetBool("disable_audio", true); if (game_config.render_mode == e_Disabled) { config->Set("graphics3d_renderer", "mock"); } else if (game_config.render_mode == e_Offscreen) { diff --git a/third_party/gfootball_engine/sources.cmake b/third_party/gfootball_engine/sources.cmake index fb94e6b5..b282785c 100644 --- a/third_party/gfootball_engine/sources.cmake +++ b/third_party/gfootball_engine/sources.cmake @@ -341,7 +341,6 @@ set(GAME_HEADERS src/onthepitch/player/controller/elizacontroller.hpp src/onthepitch/player/controller/humancontroller.hpp src/onthepitch/player/controller/playercontroller.hpp - src/onthepitch/player/controller/strategies/special/celebration.hpp src/onthepitch/player/controller/strategies/strategy.hpp src/onthepitch/player/controller/strategies/offtheball/default_off.hpp src/onthepitch/player/controller/strategies/offtheball/default_def.hpp @@ -372,7 +371,6 @@ set(GAME_SOURCES src/onthepitch/player/controller/icontroller.cpp src/onthepitch/player/controller/refereecontroller.cpp src/onthepitch/player/controller/elizacontroller.cpp - src/onthepitch/player/controller/strategies/special/celebration.cpp src/onthepitch/player/controller/strategies/strategy.cpp src/onthepitch/player/controller/strategies/offtheball/default_mid.cpp src/onthepitch/player/controller/strategies/offtheball/default_off.cpp diff --git a/third_party/gfootball_engine/src/base/log.cpp b/third_party/gfootball_engine/src/base/log.cpp index a71857d9..35afa3b4 100644 --- a/third_party/gfootball_engine/src/base/log.cpp +++ b/third_party/gfootball_engine/src/base/log.cpp @@ -32,8 +32,6 @@ std::string now() { namespace blunted { - signal_LogCallback callback; - void Log(e_LogType logType, std::string className, std::string methodName, std::string message) { std::string logTypeString; @@ -51,7 +49,6 @@ namespace blunted { std::string date = now(); date = date.substr(0, date.length() - 1); - callback(logType, className.c_str(), methodName.c_str(), message.c_str()); printf("%s [%s] in [%s::%s]: %s\n", date.c_str(), logTypeString.c_str(), className.c_str(), methodName.c_str(), message.c_str()); diff --git a/third_party/gfootball_engine/src/base/math/bluntmath.hpp b/third_party/gfootball_engine/src/base/math/bluntmath.hpp index 2a75405b..48121e95 100644 --- a/third_party/gfootball_engine/src/base/math/bluntmath.hpp +++ b/third_party/gfootball_engine/src/base/math/bluntmath.hpp @@ -31,9 +31,7 @@ namespace blunted { real NormalizedClamp(const real value, const real min, const real max); // you can never be too specific ;) - const real pi = 3.1415926535897932384626433832795028841972f; // last decimal rounded ;) - extern unsigned int fastrandseed; - + constexpr real pi = 3.1415926535897932384626433832795028841972f; // last decimal rounded ;) typedef real radian; void normalize(real v[3]); @@ -43,17 +41,6 @@ namespace blunted { real boostrandom(real min, real max); real random_non_determ(real min, real max); - inline void fastrandomseed(unsigned int seed) { - fastrandseed = seed; - } - - inline real fastrandom(real min, real max) { - real range = max - min; - real tmp = (fastrandseed / (std::numeric_limits::max() * 1.0f)) * range + min; - fastrandseed = (214013 * fastrandseed + 2531011); - return tmp; - } - inline float curve(float source, float bias = 1.0f) { // make linear / into sined _/- return (std::sin((source - 0.5f) * pi) * 0.5f + 0.5f) * bias + source * (1.0f - bias); diff --git a/third_party/gfootball_engine/src/base/math/matrix4.cpp b/third_party/gfootball_engine/src/base/math/matrix4.cpp index 17900f23..ebcde2ad 100644 --- a/third_party/gfootball_engine/src/base/math/matrix4.cpp +++ b/third_party/gfootball_engine/src/base/math/matrix4.cpp @@ -27,7 +27,7 @@ namespace blunted { } } - Matrix4::Matrix4(real values[16]) { + Matrix4::Matrix4(const real values[16]) { for (int i = 0; i < 16; i++) { elements[i] = values[i]; } diff --git a/third_party/gfootball_engine/src/base/math/matrix4.hpp b/third_party/gfootball_engine/src/base/math/matrix4.hpp index 8a499613..4d23fbd0 100644 --- a/third_party/gfootball_engine/src/base/math/matrix4.hpp +++ b/third_party/gfootball_engine/src/base/math/matrix4.hpp @@ -33,7 +33,7 @@ namespace blunted { public: Matrix4(); - Matrix4(real values[16]); + Matrix4(const real values[16]); virtual ~Matrix4(); // ----- operator overloading diff --git a/third_party/gfootball_engine/src/base/properties.cpp b/third_party/gfootball_engine/src/base/properties.cpp index 350c416f..50608075 100644 --- a/third_party/gfootball_engine/src/base/properties.cpp +++ b/third_party/gfootball_engine/src/base/properties.cpp @@ -28,8 +28,6 @@ using namespace std; namespace blunted { - std::string Properties::emptyString = ""; - Properties::Properties() { } diff --git a/third_party/gfootball_engine/src/base/properties.hpp b/third_party/gfootball_engine/src/base/properties.hpp index f6fe013c..343e45a5 100644 --- a/third_party/gfootball_engine/src/base/properties.hpp +++ b/third_party/gfootball_engine/src/base/properties.hpp @@ -42,7 +42,7 @@ namespace blunted { void SetBool(const std::string &name, bool value); const std::string &Get( const std::string &name, - const std::string &defaultValue = emptyString) const; + const std::string &defaultValue = "") const; bool GetBool(const std::string &name, bool defaultValue = false) const; real GetReal(const std::string &name, real defaultValue = 0) const; int GetInt(const std::string &name, int defaultValue = 0) const; @@ -52,8 +52,6 @@ namespace blunted { protected: map_Properties properties; - - static std::string emptyString; }; } diff --git a/third_party/gfootball_engine/src/main.cpp b/third_party/gfootball_engine/src/main.cpp index 30917184..17ee52f0 100755 --- a/third_party/gfootball_engine/src/main.cpp +++ b/third_party/gfootball_engine/src/main.cpp @@ -79,7 +79,6 @@ void randomize(unsigned int seed) { srand(seed); rand(); // mingw32? buggy compiler? first value seems bogus randomseed(seed); // for the boost random - fastrandomseed(seed); } void run_game(Properties* input_config) { diff --git a/third_party/gfootball_engine/src/main.hpp b/third_party/gfootball_engine/src/main.hpp index 3aeee1f2..17ceff7f 100755 --- a/third_party/gfootball_engine/src/main.hpp +++ b/third_party/gfootball_engine/src/main.hpp @@ -146,6 +146,13 @@ struct GameContext { // game state. Second one is used in places which are optional and don't // affect observations (like position of the sun). Generator rng_non_deterministic; + bool already_loaded = false; + int playerCount = 0; + int stablePlayerCount = 0; + BiasedOffsets emptyOffsets; + boost::shared_ptr anims; + std::map> animPositionCache; + std::map colorCoords; }; class Match; diff --git a/third_party/gfootball_engine/src/onthepitch/match.cpp b/third_party/gfootball_engine/src/onthepitch/match.cpp index 1ad9aadc..a8ccfc61 100755 --- a/third_party/gfootball_engine/src/onthepitch/match.cpp +++ b/third_party/gfootball_engine/src/onthepitch/match.cpp @@ -32,22 +32,18 @@ #include "player/playerofficial.hpp" #include "proceduralpitch.hpp" -const unsigned int replaySize_ms = 10000; -const unsigned int camPosSize = 150;//180; //130 +constexpr unsigned int replaySize_ms = 10000; +constexpr unsigned int camPosSize = 150;//180; //130 -boost::shared_ptr anims; -std::map < Animation*, std::vector > animPositionCache; - -boost::shared_ptr Match::GetAnimCollection() { return anims; } - -std::map colorCoords; +boost::shared_ptr Match::GetAnimCollection() { return GetContext().anims; } const std::vector &Match::GetAnimPositionCache(Animation *anim) const { - return animPositionCache.find(anim)->second; + return GetContext().animPositionCache.find(anim)->second; } Match::Match(MatchData *matchData, const std::vector &controllers) : matchData(matchData), controllers(controllers) { - PlayerBase::resetPlayerCount(); + auto& anims = GetContext().anims; + GetContext().stablePlayerCount = 0; // shared ptr to menutask, because menutask shouldn't die before match does menuTask = GetMenuTask(); @@ -89,9 +85,9 @@ Match::Match(MatchData *matchData, const std::vector &controllers) : //position.Print(); } //printf("\n"); - animPositionCache.insert(std::pair < Animation*, std::vector >(someAnim, positions)); + GetContext().animPositionCache.insert(std::pair < Animation*, std::vector >(someAnim, positions)); } - GetVertexColors(colorCoords); + GetVertexColors(GetContext().colorCoords); } @@ -110,8 +106,8 @@ Match::Match(MatchData *matchData, const std::vector &controllers) : teams[0] = new Team(0, this, matchData->GetTeamData(0)); teams[1] = new Team(1, this, matchData->GetTeamData(1)); - teams[0]->InitPlayers(fullbodyNode, fullbody2Node, colorCoords); - teams[1]->InitPlayers(fullbodyNode, fullbody2Node, colorCoords); + teams[0]->InitPlayers(fullbodyNode, fullbody2Node, GetContext().colorCoords); + teams[1]->InitPlayers(fullbodyNode, fullbody2Node, GetContext().colorCoords); std::vector activePlayers; teams[0]->GetActivePlayers(activePlayers); @@ -124,7 +120,7 @@ Match::Match(MatchData *matchData, const std::vector &controllers) : std::string kitFilename = "media/objects/players/textures/referee_kit.png"; boost::intrusive_ptr > kit = GetContext().surface_manager.Fetch(kitFilename); - officials = new Officials(this, fullbodyNode, colorCoords, kit, anims); + officials = new Officials(this, fullbodyNode, GetContext().colorCoords, kit, anims); dynamicNode->AddObject(officials->GetYellowCardGeom()); dynamicNode->AddObject(officials->GetRedCardGeom()); diff --git a/third_party/gfootball_engine/src/onthepitch/player/controller/strategies/special/celebration.cpp b/third_party/gfootball_engine/src/onthepitch/player/controller/strategies/special/celebration.cpp deleted file mode 100755 index 621549ad..00000000 --- a/third_party/gfootball_engine/src/onthepitch/player/controller/strategies/special/celebration.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2019 Google LLC & Bastiaan Konings -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// written by bastiaan konings schuiling 2008 - 2015 -// this work is public domain. the code is undocumented, scruffy, untested, and should generally not be used for anything important. -// i do not offer support, so don't ask. to be used for inspiration :) - -#include "celebration.hpp" diff --git a/third_party/gfootball_engine/src/onthepitch/player/controller/strategies/special/celebration.hpp b/third_party/gfootball_engine/src/onthepitch/player/controller/strategies/special/celebration.hpp deleted file mode 100755 index 7efc1832..00000000 --- a/third_party/gfootball_engine/src/onthepitch/player/controller/strategies/special/celebration.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2019 Google LLC & Bastiaan Konings -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// written by bastiaan konings schuiling 2008 - 2015 -// this work is public domain. the code is undocumented, scruffy, untested, and should generally not be used for anything important. -// i do not offer support, so don't ask. to be used for inspiration :) - -#ifndef _HPP_STRATEGY_CELEBRATION -#define _HPP_STRATEGY_CELEBRATION - -#include "../strategy.hpp" - -#endif diff --git a/third_party/gfootball_engine/src/onthepitch/player/humanoid/humanoid.cpp b/third_party/gfootball_engine/src/onthepitch/player/humanoid/humanoid.cpp index 35cd6dc4..ba3803dd 100755 --- a/third_party/gfootball_engine/src/onthepitch/player/humanoid/humanoid.cpp +++ b/third_party/gfootball_engine/src/onthepitch/player/humanoid/humanoid.cpp @@ -35,30 +35,30 @@ #include "../../../systems/graphics/graphics_scene.hpp" #include "../../../systems/graphics/graphics_system.hpp" -const bool animSmoothing = true; -const float cheatFactor = 0.5f; -const bool useContinuousBallCheck = true; -const bool enableMovementSmuggle = true; -const float cheatDiscardDistance = 0.02f; // don't 'display' this distance of cheat (looks better for small distances, but will look funny when too large, players 'missing' the ball and all. also has big influence on gameplay, since this influences player collisions etc) -const float cheatDistanceBonus = 0.02f; // add extra allowed cheat distance (in meters). don't 'display' this distance of cheat (looks better for small distances, but will look funny when too large, players 'missing' the ball and all. also has big influence on gameplay, since this influences player collisions etc) -const float cheatDiscardDistanceMultiplier = 0.4f; // lower == more snappy -const float maxSmuggleDiscardDistance = 0.2f; -const bool enableActionSmuggleDiscard = true; -const bool forceFullActionSmuggleDiscard = false; -const bool discardForwardSmuggle = true; -const bool discardSidewaysSmuggle = false; -const float bodyRotationSmoothingFactor = 1.0f; -const float bodyRotationSmoothingMaxAngle = animSmoothing ? 0.25f * pi : 0.0f; -const int initialReQueueDelayFrames = 22; -const int minRemainingMovementReQueueFrames = 6; // after this # of frames remaining, just let anim finish; we're almost there anyway -const int minRemainingTrapReQueueFrames = 6; // after this # of frames remaining to touchframe, just let anim finish; we're almost there anyway -const int maxBallControlReQueueFrame = 8; -const bool allowReQueue = true; -const bool allowMovementReQueue = true; -const bool allowBallControlReQueue = true; -const bool allowTrapReQueue = true; -const bool allowPreTouchRotationSmuggle = false; -const bool enableControlledBallCollisions = true; +constexpr bool animSmoothing = true; +constexpr float cheatFactor = 0.5f; +constexpr bool useContinuousBallCheck = true; +constexpr bool enableMovementSmuggle = true; +constexpr float cheatDiscardDistance = 0.02f; // don't 'display' this distance of cheat (looks better for small distances, but will look funny when too large, players 'missing' the ball and all. also has big influence on gameplay, since this influences player collisions etc) +constexpr float cheatDistanceBonus = 0.02f; // add extra allowed cheat distance (in meters). don't 'display' this distance of cheat (looks better for small distances, but will look funny when too large, players 'missing' the ball and all. also has big influence on gameplay, since this influences player collisions etc) +constexpr float cheatDiscardDistanceMultiplier = 0.4f; // lower == more snappy +constexpr float maxSmuggleDiscardDistance = 0.2f; +constexpr bool enableActionSmuggleDiscard = true; +constexpr bool forceFullActionSmuggleDiscard = false; +constexpr bool discardForwardSmuggle = true; +constexpr bool discardSidewaysSmuggle = false; +constexpr float bodyRotationSmoothingFactor = 1.0f; +constexpr float bodyRotationSmoothingMaxAngle = animSmoothing ? 0.25f * pi : 0.0f; +constexpr int initialReQueueDelayFrames = 22; +constexpr int minRemainingMovementReQueueFrames = 6; // after this # of frames remaining, just let anim finish; we're almost there anyway +constexpr int minRemainingTrapReQueueFrames = 6; // after this # of frames remaining to touchframe, just let anim finish; we're almost there anyway +constexpr int maxBallControlReQueueFrame = 8; +constexpr bool allowReQueue = true; +constexpr bool allowMovementReQueue = true; +constexpr bool allowBallControlReQueue = true; +constexpr bool allowTrapReQueue = true; +constexpr bool allowPreTouchRotationSmuggle = false; +constexpr bool enableControlledBallCollisions = true; Humanoid::Humanoid(Player *player, boost::intrusive_ptr humanoidSourceNode, boost::intrusive_ptr fullbodySourceNode, std::map &colorCoords, boost::shared_ptr animCollection, boost::intrusive_ptr fullbodyTargetNode, boost::intrusive_ptr < Resource > kit, int bodyUpdatePhaseOffset) : HumanoidBase(player, player->GetTeam()->GetMatch(), humanoidSourceNode, fullbodySourceNode, colorCoords, animCollection, fullbodyTargetNode, kit, bodyUpdatePhaseOffset) { diff --git a/third_party/gfootball_engine/src/onthepitch/player/humanoid/humanoidbase.cpp b/third_party/gfootball_engine/src/onthepitch/player/humanoid/humanoidbase.cpp index 13a38ccb..439498e9 100755 --- a/third_party/gfootball_engine/src/onthepitch/player/humanoid/humanoidbase.cpp +++ b/third_party/gfootball_engine/src/onthepitch/player/humanoid/humanoidbase.cpp @@ -31,9 +31,9 @@ #include "../../../scene/objectfactory.hpp" -const float bodyRotationSmoothingFactor = 1.0f; -const float bodyRotationSmoothingMaxAngle = 0.25f * pi; -const float initialReQueueDelayFrames = 32; +constexpr float bodyRotationSmoothingFactor = 1.0f; +constexpr float bodyRotationSmoothingMaxAngle = 0.25f * pi; +constexpr float initialReQueueDelayFrames = 32; void FillTemporalHumanoidNodes(boost::intrusive_ptr targetNode, std::vector &temporalHumanoidNodes) { //printf("%s\n", targetNode->GetName().c_str()); diff --git a/third_party/gfootball_engine/src/onthepitch/player/humanoid/humanoidbase.hpp b/third_party/gfootball_engine/src/onthepitch/player/humanoid/humanoidbase.hpp index 2ff257fa..0671813a 100755 --- a/third_party/gfootball_engine/src/onthepitch/player/humanoid/humanoidbase.hpp +++ b/third_party/gfootball_engine/src/onthepitch/player/humanoid/humanoidbase.hpp @@ -186,8 +186,6 @@ struct SpatialState { e_Foot foot; }; -static const Vector3 emptyVec(0); - class HumanoidBase { public: diff --git a/third_party/gfootball_engine/src/onthepitch/player/playerbase.cpp b/third_party/gfootball_engine/src/onthepitch/player/playerbase.cpp index 533fbaeb..0946ee7b 100755 --- a/third_party/gfootball_engine/src/onthepitch/player/playerbase.cpp +++ b/third_party/gfootball_engine/src/onthepitch/player/playerbase.cpp @@ -27,10 +27,7 @@ #include "../../base/geometry/triangle.hpp" -int PlayerBase::playerCount = 0; -int PlayerBase::stablePlayerCount = 0; - -PlayerBase::PlayerBase(Match *match, PlayerData *playerData) : match(match), playerData(playerData), id(playerCount++), stable_id(stablePlayerCount++), humanoid(0), controller(0), externalController(0), isActive(false) { +PlayerBase::PlayerBase(Match *match, PlayerData *playerData) : match(match), playerData(playerData), id(GetContext().playerCount++), stable_id(GetContext().stablePlayerCount++), humanoid(0), controller(0), externalController(0), isActive(false) { lastTouchTime_ms = 0; lastTouchType = e_TouchType_None; fatigueFactorInv = 1.0; diff --git a/third_party/gfootball_engine/src/onthepitch/player/playerbase.hpp b/third_party/gfootball_engine/src/onthepitch/player/playerbase.hpp index 7e9724d3..3db5c555 100755 --- a/third_party/gfootball_engine/src/onthepitch/player/playerbase.hpp +++ b/third_party/gfootball_engine/src/onthepitch/player/playerbase.hpp @@ -104,9 +104,6 @@ class PlayerBase { } virtual void ResetSituation(const Vector3 &focusPos); - static void resetPlayerCount() { - stablePlayerCount = 0; - } protected: Match *match; @@ -124,9 +121,6 @@ class PlayerBase { unsigned long lastTouchTime_ms = 0; e_TouchType lastTouchType; - static int playerCount; - static int stablePlayerCount; - float fatigueFactorInv = 0.0f; std::vector positionHistoryPerSecond; // resets too (on ResetSituation() calls) diff --git a/third_party/gfootball_engine/src/onthepitch/proceduralpitch.cpp b/third_party/gfootball_engine/src/onthepitch/proceduralpitch.cpp index d02b7afb..8a8599d9 100755 --- a/third_party/gfootball_engine/src/onthepitch/proceduralpitch.cpp +++ b/third_party/gfootball_engine/src/onthepitch/proceduralpitch.cpp @@ -28,18 +28,12 @@ #include "../main.hpp" // for getconfig -float *perlinTex; -int perlinTexW = 0; -int perlinTexH = 0; - -Vector3 *seamlessTex; -int seamlessTexW = 0; -int seamlessTexH = 0; - -Vector3 *overlayTex; -float *overlay_alphaTex; -int overlayTexW = 0; -int overlayTexH = 0; +constexpr int perlinTexW = 1600; +constexpr int perlinTexH = 1000; +constexpr int seamlessTexW = 1200; +constexpr int seamlessTexH = 1200; +constexpr int overlayTexW = 4096; +constexpr int overlayTexH = 2048; template T BilinearSample(T* tex, float x, float y, int w, int h) { // nearest neighbor version @@ -62,7 +56,7 @@ template T BilinearSample(T* tex, float x, float y, int w, int h) { return result; } -Uint32 GetPitchDiffuseColor(SDL_Surface *pitchSurf, float xCoord, float yCoord) { +Uint32 GetPitchDiffuseColor(SDL_Surface *pitchSurf, Vector3 *seamlessTex, float *perlinTex, Vector3* overlayTex, float* overlay_alphaTex, float xCoord, float yCoord) { float texMultiplier = 0.3f; float texScale = 0.32f; @@ -91,9 +85,9 @@ Uint32 GetPitchDiffuseColor(SDL_Surface *pitchSurf, float xCoord, float yCoord) float perlX = ((xCoord / pitchFullHalfW) * 0.5 + 0.5) * perlinTexW; float perlY = ((yCoord / pitchFullHalfH) * 0.5 + 0.5) * perlinTexH; float randomSpread = 2.5f; - float randomX = fastrandom(-1, 1); + float randomX = random_non_determ(-1, 1); perlX = clamp(perlX + randomX * randomSpread, 0, perlinTexW - 1); - float randomY = fastrandom(-1, 1); + float randomY = random_non_determ(-1, 1); perlY = clamp(perlY + randomY * randomSpread, 0, perlinTexH - 1); float perlinNoise = BilinearSample(perlinTex, perlX, perlY, perlinTexW, perlinTexH) - 0.5f; float perlinNoiseR = perlinNoise; @@ -110,7 +104,7 @@ Uint32 GetPitchDiffuseColor(SDL_Surface *pitchSurf, float xCoord, float yCoord) */ float randomNoise = 0.0f; - if (randomNoiseMultiplier > 0.0f) randomNoise = fastrandom(-1, 1); + if (randomNoiseMultiplier > 0.0f) randomNoise = random_non_determ(-1, 1); r += ((perlinNoiseR * perlinNoiseMultiplier) + (randomNoise * randomNoiseMultiplier)) * 40.0f; g += ((perlinNoiseG * perlinNoiseMultiplier) + (randomNoise * randomNoiseMultiplier)) * 40.0f; b += ((perlinNoiseB * perlinNoiseMultiplier) + (randomNoise * randomNoiseMultiplier)) * 40.0f; @@ -141,7 +135,7 @@ Uint32 GetPitchDiffuseColor(SDL_Surface *pitchSurf, float xCoord, float yCoord) return color; } -inline Uint32 GetPitchSpecularColor(SDL_Surface *pitchSurf, float xCoord, float yCoord) { +inline Uint32 GetPitchSpecularColor(SDL_Surface *pitchSurf, float* perlinTex, float xCoord, float yCoord) { float base = 2.0f; float noisefac = 18.0f; @@ -149,9 +143,9 @@ inline Uint32 GetPitchSpecularColor(SDL_Surface *pitchSurf, float xCoord, float float perlX = ((xCoord / pitchFullHalfW) * 0.5 + 0.5) * perlinTexW; float perlY = ((yCoord / pitchFullHalfH) * 0.5 + 0.5) * perlinTexH; float randomSpread = 2.5f; - float randomX = fastrandom(-1, 1); + float randomX = random_non_determ(-1, 1); perlX = clamp(perlX + randomX * randomSpread, 0, perlinTexW - 1); - float randomY = fastrandom(-1, 1); + float randomY = random_non_determ(-1, 1); perlY = clamp(perlY + randomY * randomSpread, 0, perlinTexH - 1); float noise = base + BilinearSample(perlinTex, perlX, perlY, perlinTexW, perlinTexH) * noisefac; @@ -196,8 +190,8 @@ Uint32 GetPitchNormalColor(SDL_Surface *pitchSurf, float xCoord, float yCoord, f } - normal.coords[0] += fastrandom(-1, 1) * noisefac; - normal.coords[1] += fastrandom(-1, 1) * noisefac; + normal.coords[0] += random_non_determ(-1, 1) * noisefac; + normal.coords[1] += random_non_determ(-1, 1) * noisefac; normal.Normalize(); @@ -214,7 +208,10 @@ void DrawMud(SDL_PixelFormat *pixelFormat, Uint32 *diffuseBitmap, int resX, int } */ -void CreateChunk(int i, int resX, int resY, int resSpecularX, int resSpecularY, int resNormalX, int resNormalY, float grassNormalRepeatMultiplier = 0.5f) { +void CreateChunk(int i, int resX, int resY, int resSpecularX, int resSpecularY, + int resNormalX, int resNormalY, float grassNormalRepeatMultiplier, + Vector3* seamlessTex, float* perlinTex, Vector3* overlayTex, + float* overlay_alphaTex) { signed int offsetW, offsetH; if (i == 1 || i == 3) offsetW = -1; else @@ -238,14 +235,14 @@ void CreateChunk(int i, int resX, int resY, int resSpecularX, int resSpecularY, for (int y = 0; y < resY; y++) { float xCoord = x / (resX * 1.0) * pitchFullHalfW + pitchFullHalfW * offsetW; float yCoord = y / (resY * 1.0) * pitchFullHalfH + pitchFullHalfH * offsetH; - diffuseBitmap[y * resX + x] = GetPitchDiffuseColor(pitchDiffuseSurf, xCoord, yCoord); + diffuseBitmap[y * resX + x] = GetPitchDiffuseColor(pitchDiffuseSurf, seamlessTex, perlinTex, overlayTex, overlay_alphaTex, xCoord, yCoord); } } for (int x = 0; x < resSpecularX; x++) { for (int y = 0; y < resSpecularY; y++) { float xSpecularCoord = x / (resSpecularX * 1.0) * pitchFullHalfW + pitchFullHalfW * offsetW; float ySpecularCoord = y / (resSpecularY * 1.0) * pitchFullHalfH + pitchFullHalfH * offsetH; - specularBitmap[y * resSpecularX + x] = GetPitchSpecularColor(pitchSpecularSurf, xSpecularCoord, ySpecularCoord); + specularBitmap[y * resSpecularX + x] = GetPitchSpecularColor(pitchSpecularSurf, perlinTex, xSpecularCoord, ySpecularCoord); } } for (int x = 0; x < resNormalX; x++) { @@ -300,19 +297,17 @@ void CreateChunk(int i, int resX, int resY, int resSpecularX, int resSpecularY, SDL_FreeSurface(pitchNormalSurf); } -static bool already_loaded = false; - void GeneratePitch(int resX, int resY, int resSpecularX, int resSpecularY, int resNormalX, int resNormalY) { - if (already_loaded) { + if (GetContext().already_loaded) { return; } - already_loaded = true; + GetContext().already_loaded = true; SDL_Surface *seamless = IMG_LoadBmp("media/textures/pitch/seamlessgrass08.png"); SDL_PixelFormat seamlessFormat = *seamless->format; - seamlessTexW = seamless->w; - seamlessTexH = seamless->h; - seamlessTex = new Vector3[seamlessTexW * seamlessTexH]; + assert(seamlessTexW == seamless->w); + assert(seamlessTexH == seamless->h); + Vector3 *seamlessTex = new Vector3[seamlessTexW * seamlessTexH]; for (int x = 0; x < seamlessTexW; x++) { for (int y = 0; y < seamlessTexH; y++) { Uint32 pixel = sdl_getpixel(seamless, x, y); @@ -325,10 +320,10 @@ void GeneratePitch(int resX, int resY, int resSpecularX, int resSpecularY, int r SDL_Surface *overlay = IMG_LoadBmp("media/textures/pitch/overlay.png"); SDL_PixelFormat overlayFormat = *overlay->format; - overlayTexW = overlay->w; - overlayTexH = overlay->h; - overlayTex = new Vector3[overlayTexW * overlayTexH]; - overlay_alphaTex = new float[overlayTexW * overlayTexH]; + assert(overlayTexW == overlay->w); + assert(overlayTexH == overlay->h); + Vector3 *overlayTex = new Vector3[overlayTexW * overlayTexH]; + float* overlay_alphaTex = new float[overlayTexW * overlayTexH]; for (int x = 0; x < overlayTexW; x++) { for (int y = 0; y < overlayTexH; y++) { Uint32 pixel = sdl_getpixel(overlay, x, y); @@ -346,9 +341,7 @@ void GeneratePitch(int resX, int resY, int resSpecularX, int resSpecularY, int r Perlin *perlin1 = new Perlin(4, 0.06 * scale, 0.5, time(NULL)); // low freq Perlin *perlin2 = new Perlin(4, 0.14 * scale, 0.5, time(NULL) + 139882); // mid freq // Perlin *perlin3 = new Perlin(4, 25.4 / 20.0, 3, 423423); // high freq - perlinTexW = 1600; - perlinTexH = 1000; - perlinTex = new float[perlinTexW * perlinTexH]; + float* perlinTex = new float[perlinTexW * perlinTexH]; // make sure sines are in range -1 to 1 // generate sine @@ -385,7 +378,9 @@ void GeneratePitch(int resX, int resY, int resSpecularX, int resSpecularY, int r // boost::thread pitchThread[4]; float grassNormalRepeatMultiplier = (boostrandom(0, 1) > 0.5f) ? 1.0f : 0.5f; for (int i = 0; i < 4; i++) { - CreateChunk(i + 1, resX, resY, resSpecularX, resSpecularY, resNormalX, resNormalY, grassNormalRepeatMultiplier); + CreateChunk(i + 1, resX, resY, resSpecularX, resSpecularY, resNormalX, + resNormalY, grassNormalRepeatMultiplier, seamlessTex, perlinTex, + overlayTex, overlay_alphaTex); } // for (int i = 0; i < 4; i++) { diff --git a/third_party/gfootball_engine/src/onthepitch/proceduralpitch.hpp b/third_party/gfootball_engine/src/onthepitch/proceduralpitch.hpp index 4006f4aa..4950ef0e 100755 --- a/third_party/gfootball_engine/src/onthepitch/proceduralpitch.hpp +++ b/third_party/gfootball_engine/src/onthepitch/proceduralpitch.hpp @@ -23,9 +23,6 @@ using namespace blunted; -Uint32 GetPitchDiffuseColor(SDL_Surface *pitchSurf, float xCoord, float yCoord); -Uint32 GetPitchSpecularColor(SDL_Surface *pitchSurf, float xCoord, - float yCoord); void GeneratePitch(int resX, int resY, int resSpecularX, int resSpecularY, int resNormalX, int resNormalY); diff --git a/third_party/gfootball_engine/src/systems/graphics/rendering/opengl_renderer3d.hpp b/third_party/gfootball_engine/src/systems/graphics/rendering/opengl_renderer3d.hpp index b3210860..256f788b 100644 --- a/third_party/gfootball_engine/src/systems/graphics/rendering/opengl_renderer3d.hpp +++ b/third_party/gfootball_engine/src/systems/graphics/rendering/opengl_renderer3d.hpp @@ -157,11 +157,6 @@ namespace blunted { screenshoot last_screen_; }; - -#ifdef WIN32 - static SDL_SysWMinfo wmInfo; -#endif - } #endif