diff --git a/README.md b/README.md index 51a0819..fd1f5dd 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # GTAVisionExport -Code to export full segmentations from GTA +Code to export full segmentations and depth data from GTA V, used for Matěj Račinský's master thesis, available [here](https://dspace.cvut.cz/handle/10467/76430), heavily modified from the original paper using the repo. diff --git a/database_schema.sql b/database_schema.sql deleted file mode 100644 index 2e4e44a..0000000 --- a/database_schema.sql +++ /dev/null @@ -1,200 +0,0 @@ -create type detection_type AS ENUM ('background', 'person', 'car', 'bicycle'); - -create type detection_class AS ENUM ('Unknown', 'Compacts', 'Sedans', 'SUVs', 'Coupes', 'Muscle', 'SportsClassics', 'Sports', 'Super', 'Motorcycles', 'OffRoad', 'Industrial', 'Utility', 'Vans', 'Cycles', 'Boats', 'Helicopters', 'Planes', 'Service', 'Emergency', 'Military', 'Commercial', 'Trains'); - -create type weather AS ENUM ('Unknown', 'ExtraSunny', 'Clear', 'Clouds', 'Smog', 'Foggy', 'Overcast', 'Raining', 'ThunderStorm', 'Clearing', 'Neutral', 'Snowing', 'Blizzard', 'Snowlight', 'Christmas', 'Halloween'); - -create table detections -( - detection_id serial not null - constraint detections_pkey - primary key, - snapshot_id integer, - type detection_type, - pos geometry(PointZ), - bbox box, - class detection_class default 'Unknown'::detection_class, - handle integer default '-1'::integer, - best_bbox box, - best_bbox_old box, - bbox3d box3d, - rot geometry, - coverage real default 0.0, - created timestamp without time zone default (now() at time zone 'utc') -) -; - - -create table runs -( - run_id serial not null - constraint runs_pkey - primary key, - runguid uuid, - archivepath text, - localpath text, - session_id integer default 1, - instance_id integer default 0, - created timestamp without time zone default (now() at time zone 'utc') -) -; - - -create table sessions -( - session_id serial not null - constraint sessions_pkey - primary key, - name text - constraint sessions_name_key - unique, - start timestamp with time zone, - "end" timestamp with time zone, - created timestamp without time zone default (now() at time zone 'utc') -) -; - -alter table runs - add constraint runs_session_fkey - foreign key (session_id) references sessions - on delete cascade -; - -create table snapshots -( - snapshot_id serial not null - constraint snapshots_pkey - primary key, - run_id integer - constraint snapshots_run_fkey - references runs - on delete cascade, - version integer, - imagepath text, - timestamp timestamp with time zone, - timeofday time, - currentweather weather, - camera_pos geometry(PointZ), - camera_direction geometry, - camera_fov real, - view_matrix double precision[], - proj_matrix double precision[], - processed boolean default false not null, - width integer, - height integer -) -; - - -alter table detections - add constraint detections_snapshot_fkey - foreign key (snapshot_id) references snapshots - on delete cascade -; - -create table instances -( - instance_id serial not null - constraint isntances_pkey - primary key, - hostname text, - instanceid text - constraint instanceid_uniq - unique, - instancetype text, - publichostname text, - amiid text, - created timestamp without time zone default (now() at time zone 'utc'), - constraint instance_info_uniq - unique (hostname, instanceid, instancetype, publichostname, amiid) -) -; - -alter table runs - add constraint runs_instance_fkey - foreign key (instance_id) references instances -; - -create table snapshot_weathers -( - weather_id serial not null - constraint snapshot_weathers_pkey - primary key, - snapshot_id integer - constraint snapshot_weathers_snapshot_id_fkey - references snapshots - on delete cascade, - weather_type weather, - snapshot_page integer, - created timestamp without time zone default (now() at time zone 'utc') -) -; - -create table uploads -( - id serial not null - constraint uploads_pkey - primary key, - bucket text, - key text, - uploadid text, - created timestamp without time zone default (now() at time zone 'utc') -) -; - -create table datasets -( - dataset_id serial not null - constraint datasets_pkey - primary key, - dataset_name text, - view_name text, - created timestamp without time zone default (now() at time zone 'utc') -) -; - -create table systems -( - system_uuid uuid not null - constraint systems_pkey - primary key, - vendor text, - dnshostname text, - username text, - systemtype text, - totalmem bigint, - created timestamp without time zone default (now() at time zone 'utc') -) -; - -create table system_graphics -( - system_graphic_id serial not null - constraint system_graphics_pkey - primary key, - deviceid text, - adaptercompatibility text, - adapterdactype text, - adapterram integer, - availability integer, - caption text, - description text, - driverdate timestamp with time zone, - driverversion text, - pnpdeviceid text, - name text, - videoarch integer, - memtype integer, - videoprocessor text, - bpp integer, - hrez integer, - vrez integer, - num_colors integer, - cols integer, - rows integer, - refresh integer, - scanmode integer, - videomodedesc text, - created timestamp without time zone default (now() at time zone 'utc') -) -; \ No newline at end of file diff --git a/db_schema.sql b/db_schema.sql new file mode 100644 index 0000000..54272d2 --- /dev/null +++ b/db_schema.sql @@ -0,0 +1,876 @@ +-- +-- PostgreSQL database dump +-- + +-- Dumped from database version 9.6.8 +-- Dumped by pg_dump version 9.6.8 + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET client_min_messages = warning; +SET row_security = off; + +-- +-- Name: DATABASE postgres; Type: COMMENT; Schema: -; Owner: postgres +-- + +COMMENT ON DATABASE postgres IS 'default administrative connection database'; + + +-- +-- Name: tiger; Type: SCHEMA; Schema: -; Owner: postgres +-- + +CREATE SCHEMA tiger; + + +ALTER SCHEMA tiger OWNER TO postgres; + +-- +-- Name: tiger_data; Type: SCHEMA; Schema: -; Owner: postgres +-- + +CREATE SCHEMA tiger_data; + + +ALTER SCHEMA tiger_data OWNER TO postgres; + +-- +-- Name: topology; Type: SCHEMA; Schema: -; Owner: postgres +-- + +CREATE SCHEMA topology; + + +ALTER SCHEMA topology OWNER TO postgres; + +-- +-- Name: SCHEMA topology; Type: COMMENT; Schema: -; Owner: postgres +-- + +COMMENT ON SCHEMA topology IS 'PostGIS Topology schema'; + + +-- +-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: +-- + +CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; + + +-- +-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: +-- + +COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; + + +-- +-- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: +-- + +CREATE EXTENSION IF NOT EXISTS fuzzystrmatch WITH SCHEMA public; + + +-- +-- Name: EXTENSION fuzzystrmatch; Type: COMMENT; Schema: -; Owner: +-- + +COMMENT ON EXTENSION fuzzystrmatch IS 'determine similarities and distance between strings'; + + +-- +-- Name: postgis; Type: EXTENSION; Schema: -; Owner: +-- + +CREATE EXTENSION IF NOT EXISTS postgis WITH SCHEMA public; + + +-- +-- Name: EXTENSION postgis; Type: COMMENT; Schema: -; Owner: +-- + +COMMENT ON EXTENSION postgis IS 'PostGIS geometry, geography, and raster spatial types and functions'; + + +-- +-- Name: postgis_tiger_geocoder; Type: EXTENSION; Schema: -; Owner: +-- + +CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder WITH SCHEMA tiger; + + +-- +-- Name: EXTENSION postgis_tiger_geocoder; Type: COMMENT; Schema: -; Owner: +-- + +COMMENT ON EXTENSION postgis_tiger_geocoder IS 'PostGIS tiger geocoder and reverse geocoder'; + + +-- +-- Name: postgis_topology; Type: EXTENSION; Schema: -; Owner: +-- + +CREATE EXTENSION IF NOT EXISTS postgis_topology WITH SCHEMA topology; + + +-- +-- Name: EXTENSION postgis_topology; Type: COMMENT; Schema: -; Owner: +-- + +COMMENT ON EXTENSION postgis_topology IS 'PostGIS topology spatial types and functions'; + + +-- +-- Name: detection_class; Type: TYPE; Schema: public; Owner: postgres +-- + +CREATE TYPE public.detection_class AS ENUM ( + 'Unknown', + 'Compacts', + 'Sedans', + 'SUVs', + 'Coupes', + 'Muscle', + 'SportsClassics', + 'Sports', + 'Super', + 'Motorcycles', + 'OffRoad', + 'Industrial', + 'Utility', + 'Vans', + 'Cycles', + 'Boats', + 'Helicopters', + 'Planes', + 'Service', + 'Emergency', + 'Military', + 'Commercial', + 'Trains' +); + + +ALTER TYPE public.detection_class OWNER TO postgres; + +-- +-- Name: detection_type; Type: TYPE; Schema: public; Owner: postgres +-- + +CREATE TYPE public.detection_type AS ENUM ( + 'background', + 'person', + 'car', + 'bicycle' +); + + +ALTER TYPE public.detection_type OWNER TO postgres; + +-- +-- Name: weather; Type: TYPE; Schema: public; Owner: postgres +-- + +CREATE TYPE public.weather AS ENUM ( + 'Unknown', + 'ExtraSunny', + 'Clear', + 'Clouds', + 'Smog', + 'Foggy', + 'Overcast', + 'Raining', + 'ThunderStorm', + 'Clearing', + 'Neutral', + 'Snowing', + 'Blizzard', + 'Snowlight', + 'Christmas', + 'Halloween' +); + + +ALTER TYPE public.weather OWNER TO postgres; + +SET default_tablespace = ''; + +SET default_with_oids = false; + +-- +-- Name: datasets; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.datasets ( + dataset_id integer NOT NULL, + dataset_name text, + view_name text, + created timestamp without time zone DEFAULT timezone('utc'::text, now()) +); + + +ALTER TABLE public.datasets OWNER TO postgres; + +-- +-- Name: datasets_dataset_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +CREATE SEQUENCE public.datasets_dataset_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.datasets_dataset_id_seq OWNER TO postgres; + +-- +-- Name: datasets_dataset_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres +-- + +ALTER SEQUENCE public.datasets_dataset_id_seq OWNED BY public.datasets.dataset_id; + + +-- +-- Name: detections; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.detections ( + detection_id integer NOT NULL, + snapshot_id integer, + type public.detection_type, + pos public.geometry(PointZ), + bbox box, + class public.detection_class DEFAULT 'Unknown'::public.detection_class, + handle integer DEFAULT '-1'::integer, + best_bbox box, + best_bbox_old box, + bbox3d public.box3d, + rot public.geometry, + coverage real DEFAULT 0.0, + created timestamp without time zone DEFAULT timezone('utc'::text, now()), + velocity public.geometry(PointZ) +); + + +ALTER TABLE public.detections OWNER TO postgres; + +-- +-- Name: detections_detection_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +CREATE SEQUENCE public.detections_detection_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.detections_detection_id_seq OWNER TO postgres; + +-- +-- Name: detections_detection_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres +-- + +ALTER SEQUENCE public.detections_detection_id_seq OWNED BY public.detections.detection_id; + + +-- +-- Name: instances; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.instances ( + instance_id integer NOT NULL, + hostname text, + instanceid text, + instancetype text, + publichostname text, + amiid text, + created timestamp without time zone DEFAULT timezone('utc'::text, now()) +); + + +ALTER TABLE public.instances OWNER TO postgres; + +-- +-- Name: instances_instance_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +CREATE SEQUENCE public.instances_instance_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.instances_instance_id_seq OWNER TO postgres; + +-- +-- Name: instances_instance_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres +-- + +ALTER SEQUENCE public.instances_instance_id_seq OWNED BY public.instances.instance_id; + + +-- +-- Name: runs; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.runs ( + run_id integer NOT NULL, + runguid uuid, + archivepath text, + localpath text, + session_id integer DEFAULT 1, + instance_id integer DEFAULT 0, + created timestamp without time zone DEFAULT timezone('utc'::text, now()) +); + + +ALTER TABLE public.runs OWNER TO postgres; + +-- +-- Name: runs_run_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +CREATE SEQUENCE public.runs_run_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.runs_run_id_seq OWNER TO postgres; + +-- +-- Name: runs_run_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres +-- + +ALTER SEQUENCE public.runs_run_id_seq OWNED BY public.runs.run_id; + + +-- +-- Name: sessions; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.sessions ( + session_id integer NOT NULL, + name text, + start timestamp with time zone, + "end" timestamp with time zone, + created timestamp without time zone DEFAULT timezone('utc'::text, now()) +); + + +ALTER TABLE public.sessions OWNER TO postgres; + +-- +-- Name: sessions_session_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +CREATE SEQUENCE public.sessions_session_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.sessions_session_id_seq OWNER TO postgres; + +-- +-- Name: sessions_session_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres +-- + +ALTER SEQUENCE public.sessions_session_id_seq OWNED BY public.sessions.session_id; + + +-- +-- Name: snapshot_weathers; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.snapshot_weathers ( + weather_id integer NOT NULL, + snapshot_id integer, + weather_type public.weather, + snapshot_page integer, + created timestamp without time zone DEFAULT timezone('utc'::text, now()) +); + + +ALTER TABLE public.snapshot_weathers OWNER TO postgres; + +-- +-- Name: snapshot_weathers_weather_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +CREATE SEQUENCE public.snapshot_weathers_weather_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.snapshot_weathers_weather_id_seq OWNER TO postgres; + +-- +-- Name: snapshot_weathers_weather_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres +-- + +ALTER SEQUENCE public.snapshot_weathers_weather_id_seq OWNED BY public.snapshot_weathers.weather_id; + + +-- +-- Name: snapshots; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.snapshots ( + snapshot_id integer NOT NULL, + run_id integer, + version integer, + scene_id uuid, + imagepath text, + "timestamp" timestamp with time zone, + timeofday time without time zone, + currentweather public.weather, + camera_pos public.geometry(PointZ), + camera_rot public.geometry(PointZ), + camera_relative_rotation public.geometry(PointZ), + camera_direction public.geometry, + camera_fov real, + car_model_box box3d, + world_matrix double precision[], + view_matrix double precision[], + proj_matrix double precision[], + processed boolean DEFAULT false NOT NULL, + width integer, + height integer, + ui_width integer, + ui_height integer, + cam_near_clip real, + cam_far_clip real, + player_pos public.geometry(PointZ), + velocity public.geometry(PointZ), + camera_relative_position public.geometry(PointZ), + current_target public.geometry(Point) +); + + +ALTER TABLE public.snapshots OWNER TO postgres; + +-- +-- Name: snapshots_snapshot_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +CREATE SEQUENCE public.snapshots_snapshot_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.snapshots_snapshot_id_seq OWNER TO postgres; + +-- +-- Name: snapshots_snapshot_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres +-- + +ALTER SEQUENCE public.snapshots_snapshot_id_seq OWNED BY public.snapshots.snapshot_id; + + +-- +-- Name: snapshots_snapshot_id_seq1; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +CREATE SEQUENCE public.snapshots_snapshot_id_seq1 + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.snapshots_snapshot_id_seq1 OWNER TO postgres; + +-- +-- Name: snapshots_snapshot_id_seq1; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres +-- + +ALTER SEQUENCE public.snapshots_snapshot_id_seq1 OWNED BY public.snapshots.snapshot_id; + + +-- +-- Name: snapshots_view; Type: VIEW; Schema: public; +-- + +CREATE VIEW public.snapshots_view AS + SELECT snapshots.snapshot_id, + snapshots.run_id, + snapshots.version, + snapshots.scene_id, + snapshots.imagepath, + snapshots."timestamp", + snapshots.timeofday, + snapshots.currentweather, + ARRAY[public.st_x(snapshots.camera_pos), public.st_y(snapshots.camera_pos), public.st_z(snapshots.camera_pos)] AS camera_pos, + ARRAY[public.st_x(snapshots.camera_rot), public.st_y(snapshots.camera_rot), public.st_z(snapshots.camera_rot)] AS camera_rot, + ARRAY[public.st_x(snapshots.camera_relative_rotation), public.st_y(snapshots.camera_relative_rotation), public.st_z(snapshots.camera_relative_rotation)] AS camera_relative_rotation, + ARRAY[public.st_x(snapshots.camera_relative_position), public.st_y(snapshots.camera_relative_position), public.st_z(snapshots.camera_relative_position)] AS camera_relative_position, + ARRAY[public.st_x(snapshots.camera_direction), public.st_y(snapshots.camera_direction), public.st_z(snapshots.camera_direction)] AS camera_direction, + snapshots.camera_fov, + snapshots.world_matrix, + snapshots.view_matrix, + snapshots.proj_matrix, + snapshots.processed, + snapshots.width, + snapshots.height, + snapshots.ui_width, + snapshots.ui_height, + snapshots.cam_near_clip, + snapshots.cam_far_clip, + ARRAY[public.st_x(snapshots.player_pos), public.st_y(snapshots.player_pos), public.st_z(snapshots.player_pos)] AS player_pos, + ARRAY[public.st_x(snapshots.velocity), public.st_y(snapshots.velocity), public.st_z(snapshots.velocity)] AS velocity + FROM public.snapshots; + + +-- +-- Name: system_graphics; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.system_graphics ( + system_graphic_id integer NOT NULL, + deviceid text, + adaptercompatibility text, + adapterdactype text, + adapterram integer, + availability integer, + caption text, + description text, + driverdate timestamp with time zone, + driverversion text, + pnpdeviceid text, + name text, + videoarch integer, + memtype integer, + videoprocessor text, + bpp integer, + hrez integer, + vrez integer, + num_colors integer, + cols integer, + rows integer, + refresh integer, + scanmode integer, + videomodedesc text, + created timestamp without time zone DEFAULT timezone('utc'::text, now()) +); + + +ALTER TABLE public.system_graphics OWNER TO postgres; + +-- +-- Name: system_graphics_system_graphic_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +CREATE SEQUENCE public.system_graphics_system_graphic_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.system_graphics_system_graphic_id_seq OWNER TO postgres; + +-- +-- Name: system_graphics_system_graphic_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres +-- + +ALTER SEQUENCE public.system_graphics_system_graphic_id_seq OWNED BY public.system_graphics.system_graphic_id; + + +-- +-- Name: systems; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.systems ( + system_uuid uuid NOT NULL, + vendor text, + dnshostname text, + username text, + systemtype text, + totalmem bigint, + created timestamp without time zone DEFAULT timezone('utc'::text, now()) +); + + +ALTER TABLE public.systems OWNER TO postgres; + +-- +-- Name: uploads; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public.uploads ( + id integer NOT NULL, + bucket text, + key text, + uploadid text, + created timestamp without time zone DEFAULT timezone('utc'::text, now()) +); + + +ALTER TABLE public.uploads OWNER TO postgres; + +-- +-- Name: uploads_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +CREATE SEQUENCE public.uploads_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.uploads_id_seq OWNER TO postgres; + +-- +-- Name: uploads_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres +-- + +ALTER SEQUENCE public.uploads_id_seq OWNED BY public.uploads.id; + + +-- +-- Name: datasets dataset_id; Type: DEFAULT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.datasets ALTER COLUMN dataset_id SET DEFAULT nextval('public.datasets_dataset_id_seq'::regclass); + + +-- +-- Name: detections detection_id; Type: DEFAULT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.detections ALTER COLUMN detection_id SET DEFAULT nextval('public.detections_detection_id_seq'::regclass); + + +-- +-- Name: instances instance_id; Type: DEFAULT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.instances ALTER COLUMN instance_id SET DEFAULT nextval('public.instances_instance_id_seq'::regclass); + + +-- +-- Name: runs run_id; Type: DEFAULT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.runs ALTER COLUMN run_id SET DEFAULT nextval('public.runs_run_id_seq'::regclass); + + +-- +-- Name: sessions session_id; Type: DEFAULT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.sessions ALTER COLUMN session_id SET DEFAULT nextval('public.sessions_session_id_seq'::regclass); + + +-- +-- Name: snapshot_weathers weather_id; Type: DEFAULT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.snapshot_weathers ALTER COLUMN weather_id SET DEFAULT nextval('public.snapshot_weathers_weather_id_seq'::regclass); + + +-- +-- Name: snapshots snapshot_id; Type: DEFAULT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.snapshots ALTER COLUMN snapshot_id SET DEFAULT nextval('public.snapshots_snapshot_id_seq'::regclass); + + +-- +-- Name: system_graphics system_graphic_id; Type: DEFAULT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.system_graphics ALTER COLUMN system_graphic_id SET DEFAULT nextval('public.system_graphics_system_graphic_id_seq'::regclass); + + +-- +-- Name: uploads id; Type: DEFAULT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.uploads ALTER COLUMN id SET DEFAULT nextval('public.uploads_id_seq'::regclass); + + +-- +-- Name: datasets datasets_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.datasets + ADD CONSTRAINT datasets_pkey PRIMARY KEY (dataset_id); + + +-- +-- Name: detections detections_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.detections + ADD CONSTRAINT detections_pkey PRIMARY KEY (detection_id); + + +-- +-- Name: instances instance_info_uniq; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.instances + ADD CONSTRAINT instance_info_uniq UNIQUE (hostname, instanceid, instancetype, publichostname, amiid); + + +-- +-- Name: instances instanceid_uniq; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.instances + ADD CONSTRAINT instanceid_uniq UNIQUE (instanceid); + + +-- +-- Name: instances isntances_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.instances + ADD CONSTRAINT isntances_pkey PRIMARY KEY (instance_id); + + +-- +-- Name: runs runs_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.runs + ADD CONSTRAINT runs_pkey PRIMARY KEY (run_id); + + +-- +-- Name: sessions sessions_name_key; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.sessions + ADD CONSTRAINT sessions_name_key UNIQUE (name); + + +-- +-- Name: sessions sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.sessions + ADD CONSTRAINT sessions_pkey PRIMARY KEY (session_id); + + +-- +-- Name: snapshot_weathers snapshot_weathers_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.snapshot_weathers + ADD CONSTRAINT snapshot_weathers_pkey PRIMARY KEY (weather_id); + + +-- +-- Name: snapshots snapshots_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.snapshots + ADD CONSTRAINT snapshots_pkey PRIMARY KEY (snapshot_id); + + +-- +-- Name: system_graphics system_graphics_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.system_graphics + ADD CONSTRAINT system_graphics_pkey PRIMARY KEY (system_graphic_id); + + +-- +-- Name: systems systems_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.systems + ADD CONSTRAINT systems_pkey PRIMARY KEY (system_uuid); + + +-- +-- Name: uploads uploads_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.uploads + ADD CONSTRAINT uploads_pkey PRIMARY KEY (id); + + +-- +-- Name: handle_index; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX handle_index ON public.detections USING btree (handle); + + +-- +-- Name: snapshot_index; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX snapshot_index ON public.detections USING btree (snapshot_id); + + +-- +-- Name: detections detections_snapshot_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.detections + ADD CONSTRAINT detections_snapshot_fkey FOREIGN KEY (snapshot_id) REFERENCES public.snapshots(snapshot_id) ON DELETE CASCADE; + + +-- +-- Name: runs runs_instance_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.runs + ADD CONSTRAINT runs_instance_fkey FOREIGN KEY (instance_id) REFERENCES public.instances(instance_id); + + +-- +-- Name: runs runs_session_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.runs + ADD CONSTRAINT runs_session_fkey FOREIGN KEY (session_id) REFERENCES public.sessions(session_id) ON DELETE CASCADE; + + +-- +-- Name: snapshot_weathers snapshot_weathers_snapshot_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.snapshot_weathers + ADD CONSTRAINT snapshot_weathers_snapshot_id_fkey FOREIGN KEY (snapshot_id) REFERENCES public.snapshots(snapshot_id) ON DELETE CASCADE; + + +-- +-- Name: snapshots snapshots_run_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public.snapshots + ADD CONSTRAINT snapshots_run_fkey FOREIGN KEY (run_id) REFERENCES public.runs(run_id) ON DELETE CASCADE; + diff --git a/managed/GTAVision.ini b/managed/GTAVision.ini index 9fdee4b..a295d31 100644 --- a/managed/GTAVision.ini +++ b/managed/GTAVision.ini @@ -1,5 +1,7 @@ [Database] -ConnectionString=Server=127.0.0.1;Port=5432;Database=postgres;User Id=postgres;Password=postgres; +ConnectionString=Server=127.0.0.1;Port=5432;Database=gta_v;User Id=postgres;Password=postgres; [Snapshots] OutputDir=D:\GTAV_extraction_output\ -LogFile=D:\GTAV_extraction_output\log.txt +LogFile=D:\Program Files\Rockstar Games\Grand Theft Auto V\my_log.txt +[MultiCamera] +GameplayTimeAfterSwitch=2000 \ No newline at end of file diff --git a/managed/GTAVisionExport.sln b/managed/GTAVisionExport.sln index 7126d34..dfa10f3 100644 --- a/managed/GTAVisionExport.sln +++ b/managed/GTAVisionExport.sln @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GTAVisionUtils", "GTAVision EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageViewer", "ImageViewer\ImageViewer.csproj", "{30284E7F-F081-42AA-AC6A-6D4267E87024}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sandbox", "Sandbox\Sandbox.csproj", "{35EC1C44-BEB8-4CF7-A5D8-AD3A2A029A5C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -41,6 +43,14 @@ Global {30284E7F-F081-42AA-AC6A-6D4267E87024}.Release|Any CPU.Build.0 = Release|Any CPU {30284E7F-F081-42AA-AC6A-6D4267E87024}.Release|x64.ActiveCfg = Release|Any CPU {30284E7F-F081-42AA-AC6A-6D4267E87024}.Release|x64.Build.0 = Release|Any CPU + {35EC1C44-BEB8-4CF7-A5D8-AD3A2A029A5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35EC1C44-BEB8-4CF7-A5D8-AD3A2A029A5C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35EC1C44-BEB8-4CF7-A5D8-AD3A2A029A5C}.Debug|x64.ActiveCfg = Debug|Any CPU + {35EC1C44-BEB8-4CF7-A5D8-AD3A2A029A5C}.Debug|x64.Build.0 = Debug|Any CPU + {35EC1C44-BEB8-4CF7-A5D8-AD3A2A029A5C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35EC1C44-BEB8-4CF7-A5D8-AD3A2A029A5C}.Release|Any CPU.Build.0 = Release|Any CPU + {35EC1C44-BEB8-4CF7-A5D8-AD3A2A029A5C}.Release|x64.ActiveCfg = Release|Any CPU + {35EC1C44-BEB8-4CF7-A5D8-AD3A2A029A5C}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/managed/GTAVisionExport/CameraHandling.cs b/managed/GTAVisionExport/CameraHandling.cs new file mode 100644 index 0000000..32bdf6b --- /dev/null +++ b/managed/GTAVisionExport/CameraHandling.cs @@ -0,0 +1,256 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Collections.Generic; +using System.Linq; +using GTA; +using GTA.Native; +using GTA.Math; +using GTA.NaturalMotion; +using GTAVisionUtils; +using MathNet.Numerics.LinearAlgebra; +using MathNet.Numerics.LinearAlgebra.Double; +using MathNet.Spatial.Euclidean; +using MathNet.Spatial.Units; + +namespace GTAVisionExport { +// Controls: +// P - mounts rendering camera on vehicle +// O - restores the rendering camera to original control + + public class CameraHandling : Script { + // camera used on the vehicle + private Camera activeCamera; + private bool enabled = false; + private int activeCameraIndex = -1; + private bool showCameras = false; + private bool showPosition = false; + + public CameraHandling() { + UI.Notify("Loaded CameraHandling.cs"); + + // create a new camera +// World.DestroyAllCameras(); + + // attach time methods + Tick += OnTick; + KeyUp += onKeyUp; + } + + // Function used to take control of the world rendering camera. + public void mountCameraOnVehicle() { + UI.Notify("Mounting camera to the vehicle."); + if (Game.Player.Character.IsInVehicle()) { + if (activeCameraIndex == -1) { + UI.Notify("Mounting free camera"); + CamerasList.ActivateMainCamera(); + } + else if (activeCameraIndex == -2) { + UI.Notify("Mounting free camera"); + CamerasList.ActivateGameplayCamera(); + } + else { + UI.Notify("Mounting camera from list"); + UI.Notify("My current rotation: " + Game.Player.Character.CurrentVehicle.Rotation); + Logger.WriteLine("My current rotation: " + Game.Player.Character.CurrentVehicle.Rotation); + activeCamera = CamerasList.ActivateCamera(activeCameraIndex); + } + } + else { + UI.Notify("Please enter a vehicle."); + } + } + + // Function used to allows the user original control of the camera. + public void restoreCamera() { + UI.Notify("Relinquishing control"); + CamerasList.Deactivate(); + } + + // Function used to keep camera on vehicle and facing forward on each tick step. + public void keepCameraOnVehicle() { + if (Game.Player.Character.IsInVehicle() && enabled) { + // keep the camera in the same position relative to the car + CamerasList.mainCamera.AttachTo(Game.Player.Character.CurrentVehicle, CamerasList.mainCameraPosition); + + // rotate the camera to face the same direction as the car + CamerasList.mainCamera.Rotation = Game.Player.Character.CurrentVehicle.Rotation; + } + } + + public void doRayCasting() { + var result = World.Raycast(Game.Player.Character.Position, + Game.Player.Character.Position + (Vector3.RelativeLeft * 100), IntersectOptions.Everything); + UI.Notify("raycast result:"); + Logger.WriteLine("raycast result:"); + UI.Notify(result.DitHitAnything.ToString()); + Logger.WriteLine(result.DitHitAnything.ToString()); + if (result.DitHitAnything) { + UI.Notify(result.HitCoords.ToString()); + Logger.WriteLine(result.HitCoords.ToString()); + World.DrawMarker(MarkerType.CheckeredFlagCircle, result.HitCoords, Vector3.RelativeRight, Vector3.WorldUp, new Vector3(10, 10, 10), Color.Chartreuse); + } + } + + // Test vehicle controls + private void onKeyUp(object sender, KeyEventArgs e) { + switch (e.KeyCode) { + case Keys.B: + doRayCasting(); + break; + case Keys.P: + activeCameraIndex = -1; + mountCameraOnVehicle(); + enabled = true; + break; + case Keys.O: + restoreCamera(); + enabled = false; + break; + +// UI.Notify("keycode is:" + e.KeyCode); + case Keys.Add: + UI.Notify("Pressed numpad +"); + showCameras = !showCameras; + UI.Notify("there are " + CamerasList.camerasPositions.Count + " cameras"); + if (showCameras) { + UI.Notify("enabled cameras showing"); + } + else { + UI.Notify("disabled cameras showing"); + } + break; + case Keys.Multiply: + UI.Notify("Pressed numpad *"); + showPosition = !showPosition; + if (showPosition) { + UI.Notify("enabled position showing"); + } + else { + UI.Notify("disabled position showing"); + } + break; + case Keys.NumPad0: + UI.Notify("Pressed numpad 0"); + activeCameraIndex = 0; + mountCameraOnVehicle(); + break; + case Keys.NumPad1: + UI.Notify("Pressed numpad 1"); + activeCameraIndex = 1; + mountCameraOnVehicle(); + break; + case Keys.NumPad2: + UI.Notify("Pressed numpad 2"); + activeCameraIndex = 2; + mountCameraOnVehicle(); + break; + case Keys.NumPad3: + UI.Notify("Pressed numpad 3"); + activeCameraIndex = 3; + mountCameraOnVehicle(); + break; + case Keys.Decimal: + UI.Notify("Pressed numpad ,"); + activeCameraIndex = -2; + mountCameraOnVehicle(); + break; + } + } + + public void OnTick(object sender, EventArgs e) { + keepCameraOnVehicle(); + if (showCameras) { + drawCamerasBoxes(); + } + if (showPosition) { + drawPosition(); + } +// drawAxesBoxesAround(new Vector3(-1078f, -216f, 200f)); + } + + public void drawPosition() { + var pos = Game.Player.Character.Position; + HashFunctions.Draw2DText($"X:{ pos.X:.##} Y:{pos.Y:.##} Z:{pos.Z:.##}", pos, Color.Red); + } + + public void drawCamerasBoxes() { +// WARNING, do not attempt to draw cameras as markes in their correct rotation. It does not work. +// I spent lots of time trying to show cameras in their direction, but shit just doesn't work. +// 3D boxes are enough I guess + +// this shows white boxes where cameras are + var curVehicle = Game.Player.Character.CurrentVehicle; + var rot = curVehicle.Rotation; + var rotX = Matrix3D.RotationAroundXAxis(Angle.FromDegrees(rot.X)); + var rotY = Matrix3D.RotationAroundYAxis(Angle.FromDegrees(rot.Y)); + var rotZ = Matrix3D.RotationAroundZAxis(Angle.FromDegrees(rot.Z)); + var rotMat = rotZ * rotY * rotX; + + for (var i = 0; i < CamerasList.cameras.Count; i++) { + var camPos = CamerasList.camerasPositions[i]; +// var camRot = CamerasList.camerasRotations[i]; + +// var relRotX = Matrix3D.RotationAroundXAxis(Angle.FromDegrees(camRot.X)); +// var relRotY = Matrix3D.RotationAroundYAxis(Angle.FromDegrees(camRot.Y)); +// var relRotZ = Matrix3D.RotationAroundZAxis(Angle.FromDegrees(camRot.Z)); +// var relRotMat = relRotZ * relRotY * relRotX; +// var relRotMat = relRotX * relRotY * relRotZ; + + var camPosToCar = rotMat * new Vector3D(camPos.X, camPos.Y, camPos.Z); +// var camDirection = new Vector3D(rotMat * relRotMat * new Vector3D(0f, 0f, -1f)); +// var camDirection = new Vector3D(relRotMat * new Vector3D(0f, 0f, -1f)); +// var camDirection = new Vector3D(0f, 0f, -1f); +// var camDirection = new Vector3D(0, 0, 0); +// var camRotation = new Vector3D(0, 0, 0); +// var camRotation = CamerasList.rotationMatrixToDegrees(rotMat * relRotMat); +// var camRotation = Game.Player.Character.CurrentVehicle.Rotation; +// camRotation.X *= -1; +// camRotation.Y = - Game.Player.Character.CurrentVehicle.Rotation.X; +// camRotation.X = Game.Player.Character.CurrentVehicle.Rotation.Y; +// var camRotation = CamerasList.rotationMatrixToDegrees(relRotMat * rotMat); +// var camRotation = CamerasList.rotationMatrixToDegrees(Matrix3D.RotationAroundZAxis(Angle.FromDegrees(90)) * rotMat); +// var camRotation = new Vector3D(Matrix3D.RotationAroundZAxis(Angle.FromDegrees(90)) * +// new Vector3D(rot.X, rot.Y, rot.Z)); +// var camRotation = CamerasList.rotationMatrixToDegrees(Matrix3D.RotationAroundXAxis(Angle.FromDegrees(-90))); + var absolutePosition = curVehicle.Position + new Vector3((float) camPosToCar[0], (float) camPosToCar[1], (float) camPosToCar[2]); + HashFunctions.Draw3DBox(absolutePosition, new Vector3(0.3f, 0.3f, 0.3f)); +// Logger.WriteLine($"{i}-th cam vector rotation"); +// Logger.WriteLine(camRotation); +// Logger.WriteLine($"{i}-th cam rotation matrix"); +// Logger.WriteLine(relRotMat * rotMat); + +// World.DrawMarker(MarkerType.ChevronUpx1, absolutePosition, +// new Vector3((float) camDirection.X, (float) camDirection.Y, (float) camDirection.Z), +// new Vector3((float) camRotation.X, (float) camRotation.Y, (float) camRotation.Z), +// new Vector3(1, 1, 1), Color.White); +// +// HashFunctions.Draw2DText($"X:{camRotation.X:.##} Y:{camRotation.Y:.##} Z:{camRotation.Z:.##}", absolutePosition, Color.Red); + } + HashFunctions.Draw2DText($"X:{rot.X:.##} Y:{rot.Y:.##} Z:{rot.Z:.##}", curVehicle.Position, Color.Red); +// Logger.WriteLine("car vector rotation"); +// Logger.WriteLine(Game.Player.Character.CurrentVehicle.Rotation); + } + + void drawAxesBoxesAround(Vector3 position) { + var dist = 10; + var vectors = new[] { + new Vector3(dist, 0, 0), new Vector3(-dist, 0, 0), // x, pos and neg + new Vector3(0, dist, 0), new Vector3(0, -dist, 0), // y, pos and neg + new Vector3(0, 0, dist), new Vector3(0, 0, -dist), // z, pos and neg + }; + var colors = new[] { + new Vector3(255, 0, 0), new Vector3(255, 180, 180), // x, pos and neg + new Vector3(0, 255, 0), new Vector3(180, 255, 180), // y, pos and neg + new Vector3(0, 0, 255), new Vector3(180, 180, 255), // z, pos and neg + }; + for (int i = 0; i < vectors.Length; i++) { + var relativePos = vectors[i]; + var color = colors[i]; + var absolutePosition = position + new Vector3((float) relativePos[0], (float) relativePos[1], (float) relativePos[2]); + HashFunctions.Draw3DBox(absolutePosition, new Vector3(0.3f, 0.3f, 0.3f), + (byte) colors[i][0], (byte) colors[i][1], (byte) colors[i][2]); + } + } + } +} \ No newline at end of file diff --git a/managed/GTAVisionExport/CamerasList.cs b/managed/GTAVisionExport/CamerasList.cs new file mode 100644 index 0000000..5044b53 --- /dev/null +++ b/managed/GTAVisionExport/CamerasList.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections.Generic; +using System.IO; +using GTA; +using GTA.Math; +using GTA.Native; +using GTAVisionUtils; +using IniParser; +using MathNet.Numerics.LinearAlgebra; +using MathNet.Spatial.Euclidean; +using MathNet.Spatial.Units; + +namespace GTAVisionExport { + public static class CamerasList { + public static Camera mainCamera { get; private set; } + public static Vector3 mainCameraPosition { get; private set; } + public static Vector3 mainCameraRotation { get; private set; } + + public static List cameras { get; } = new List(); + public static List camerasPositions { get; } = new List(); + public static List camerasRotations { get; } = new List(); + + public static Vector3? activeCameraRotation { get; private set; } = null; + public static Vector3? activeCameraPosition { get; private set; } = null; + + private static int? gameplayInterval = null; + +// public static Camera gameCam; + private static bool initialized = false; + + public static void initialize() { + if (initialized) { + return; + } + + World.DestroyAllCameras(); + Logger.WriteLine("destroying all cameras at the beginning, to be clear"); + var parser = new FileIniDataParser(); + var data = parser.ReadFile(Path.Combine(VisionExport.location, "GTAVision.ini")); + gameplayInterval = Convert.ToInt32(data["MultiCamera"]["GameplayTimeAfterSwitch"]); +// gameCam = World.RenderingCamera; + +// mainCamera.IsActive = false; + + initialized = true; + } + + public static void setMainCamera(Vector3 position = new Vector3(), Vector3 rotation = new Vector3(), float? fov = null, float? nearClip = null) { + if (!initialized) { + throw new Exception("not initialized, please, call CamerasList.initialize() method before this one"); + } + + Logger.WriteLine("setting main camera"); + if (!fov.HasValue) { + fov = GameplayCamera.FieldOfView; + } + if (!nearClip.HasValue) { + nearClip = World.RenderingCamera.NearClip; + } + + mainCamera = World.CreateCamera(position, rotation, fov.Value); +// mainCamera = World.CreateCamera(new Vector3(), new Vector3(), fov.Value); + mainCamera.NearClip = nearClip.Value; +// mainCamera.IsActive = true; + mainCameraPosition = position; + mainCameraRotation = rotation; + + mainCamera.IsActive = false; + World.RenderingCamera = null; + } + + public static void addCamera(Vector3 position, Vector3 rotation, float? fov = null, float? nearClip = null) { + if (!initialized) { + throw new Exception("not initialized, please, call CamerasList.initialize() method before this one"); + } + + Logger.WriteLine("adding new camera"); + if (!fov.HasValue) { + fov = GameplayCamera.FieldOfView; + } + if (!nearClip.HasValue) { + nearClip = World.RenderingCamera.NearClip; + } + + var newCamera = World.CreateCamera(new Vector3(), new Vector3(), fov.Value); + newCamera.NearClip = nearClip.Value; + cameras.Add(newCamera); + camerasPositions.Add(position); + camerasRotations.Add(rotation); + } + + public static void ActivateMainCamera() { + if (!initialized) { + throw new Exception("not initialized, please, call CamerasList.initialize() method before this one"); + } + + if (mainCamera == null) { + throw new Exception("please, set main camera"); + } + + mainCamera.IsActive = true; + World.RenderingCamera = mainCamera; + activeCameraRotation = mainCameraRotation; + activeCameraPosition = mainCameraPosition; + } + + public static void ActivateGameplayCamera() { + if (!initialized) { + throw new Exception("not initialized, please, call CamerasList.initialize() method before this one"); + } + + if (mainCamera == null) { + throw new Exception("please, set main camera"); + } + + mainCamera.IsActive = false; + World.RenderingCamera = null; + activeCameraRotation = GameplayCamera.Rotation; + activeCameraPosition = GameplayCamera.Position; + } + + public static Vector3 rotationMatrixToDegrees(Matrix r) { + var sy = Math.Sqrt(r[0, 0] * r[0, 0] + r[1, 0] * r[1, 0]); + + var singular = sy < 1e-6; + + var x = 0d; + var y = 0d; + var z = 0d; + if (!singular) { + x = Math.Atan2(r[2, 1], r[2, 2]); + y = Math.Atan2(-r[2, 0], sy); + z = Math.Atan2(r[1, 0], r[0, 0]); + } else { + x = Math.Atan2(-r[1, 2], r[1, 1]); + y = Math.Atan2(-r[2, 0], sy); + z = 0; + } + + return new Vector3((float) Angle.FromRadians(x).Degrees, (float) Angle.FromRadians(y).Degrees, (float) Angle.FromRadians(z).Degrees); + } + + public static Camera ActivateCamera(int i) { + if (!initialized) { + throw new Exception("not initialized, please, call CamerasList.initialize() method before this one"); + } + + if (i >= cameras.Count) { + throw new Exception("there is no camera with index " + i); + } + + Game.Pause(false); + cameras[i].IsActive = true; + World.RenderingCamera = cameras[i]; + cameras[i].AttachTo(Game.Player.Character.CurrentVehicle, camerasPositions[i]); +// if we want to rotate camera relatively to the car, we must do through rotation matrix multiplication, not addition +// cameras[i].Rotation = Game.Player.Character.CurrentVehicle.Rotation + camerasRotations[i]; // this row is wrong + var rot = Game.Player.Character.CurrentVehicle.Rotation; + var rotX = Matrix3D.RotationAroundXAxis(Angle.FromDegrees(rot.X)); + var rotY = Matrix3D.RotationAroundYAxis(Angle.FromDegrees(rot.Y)); + var rotZ = Matrix3D.RotationAroundZAxis(Angle.FromDegrees(rot.Z)); + var rotMat = rotZ * rotY * rotX; + var relRotX = Matrix3D.RotationAroundXAxis(Angle.FromDegrees(camerasRotations[i].X)); + var relRotY = Matrix3D.RotationAroundYAxis(Angle.FromDegrees(camerasRotations[i].Y)); + var relRotZ = Matrix3D.RotationAroundZAxis(Angle.FromDegrees(camerasRotations[i].Z)); + var relRotMat = relRotZ * relRotY * relRotX; + +// cameras[i].Rotation = rotationMatrixToDegrees(relRotMat * rotMat); + cameras[i].Rotation = rotationMatrixToDegrees(rotMat * relRotMat); +// WARNING: CAMERAS SETTING DO NOT WORK WHEN GAME IS PAUSED, SO WE NEED TO UNPAUSE THE GAME, SET THINGS UP, AND THEN PAUSE GAME AGAIN +// Script.Wait(1); +// //with time 1, sometimes depth does not correspond, and bounding boxes dont correspond by 1 frames +// //with time 2, depth does correspond, but bounding boxes dont correspond by 2 frames +// //with time 3, depth does correspond, but bounding boxes dont correspond by 3 frames +// //with time 4, depth does NOT correspond sometimes, but bounding boxes dont correspond by 3 frames +// //with time 5, depth is OK +// todo: pair detections with scene id, not with snapshot id, and gather them once per scene, not per snapshot +// Script.Wait(4);//tried 4 milliseconds instead of one, so screenshots correspond to their data + Script.Wait(gameplayInterval.Value); + Game.Pause(true); +// UI.Notify("new camera rotation is: " + rotation.ToString()); + Script.Wait(20); + Logger.WriteLine("new camera position is: " + World.RenderingCamera.Position); + Logger.WriteLine("new camera rotation is: " + World.RenderingCamera.Rotation); + Logger.WriteLine("new camera position offset is: " + camerasPositions[i]); + Logger.WriteLine("new camera rotation offset is: " + camerasRotations[i]); + activeCameraRotation = camerasRotations[i]; + activeCameraPosition = camerasPositions[i]; + return cameras[i]; + } + + public static void Deactivate() { + if (!initialized) { + throw new Exception("not initialized, please, call CamerasList.initialize() method before this one"); + } + + mainCamera.IsActive = false; + foreach (var camera in cameras) { + camera.IsActive = false; + } + + World.RenderingCamera = null; + } + } +} \ No newline at end of file diff --git a/managed/GTAVisionExport/GTAVisionExport.csproj b/managed/GTAVisionExport/GTAVisionExport.csproj index 40d7973..fe6589f 100644 --- a/managed/GTAVisionExport/GTAVisionExport.csproj +++ b/managed/GTAVisionExport/GTAVisionExport.csproj @@ -21,6 +21,7 @@ prompt 4 x64 + false pdbonly @@ -29,6 +30,7 @@ TRACE prompt 4 + false true @@ -39,6 +41,7 @@ prompt MinimumRecommendedRules.ruleset false + false bin\Release\ @@ -49,12 +52,9 @@ prompt MinimumRecommendedRules.ruleset true + false - - ..\packages\AWSSDK.2.3.55.2\lib\net45\AWSSDK.dll - True - ..\packages\BitMiracle.LibTiff.NET.2.4.571\lib\net20\BitMiracle.LibTiff.NET.dll True @@ -62,8 +62,11 @@ ..\packages\ini-parser.2.4.0\lib\net20\INIFileParser.dll - - ..\packages\MathNet.Numerics.3.17.0\lib\net40\MathNet.Numerics.dll + + ..\packages\MathNet.Numerics.3.8.0\lib\net40\MathNet.Numerics.dll + + + ..\packages\MathNet.Spatial.0.4.0\lib\net40\MathNet.Spatial.dll ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.1.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll @@ -74,16 +77,26 @@ ..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.0\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll - - C:\Program Files\Rockstar Games\Grand Theft Auto V\Scripts\NativeUI.dll + + False + ..\..\..\..\..\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\NativeUI.dll + + + D:\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\NativeUI.dll + + + ..\NativeUI.dll + + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll ..\packages\Npgsql.3.2.1\lib\net451\Npgsql.dll - - C:\Program Files\Rockstar Games\Grand Theft Auto V\ScriptHookVDotNet2.dll + + ..\packages\ScriptHookVDotNet2.2.10.5\lib\net452\ScriptHookVDotNet2.dll @@ -109,10 +122,22 @@ - C:\Program Files\Rockstar Games\Grand Theft Auto V\Scripts\VAutodrive.dll + ..\..\..\..\..\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\VAutodrive.dll + + + D:\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\VAutodrive.dll + + + ..\376923-VAutodrive V8.0.3\Scripts\VAutodrive.dll - C:\Program Files\Rockstar Games\Grand Theft Auto V\Scripts\VCommonFunctions.dll + ..\..\..\..\..\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\VCommonFunctions.dll + + + D:\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\VCommonFunctions.dll + + + ..\376923-VAutodrive V8.0.3\Scripts\VCommonFunctions.dll @@ -120,9 +145,12 @@ + + + diff --git a/managed/GTAVisionExport/GameUtils.cs b/managed/GTAVisionExport/GameUtils.cs index 86466ba..96de3f3 100644 --- a/managed/GTAVisionExport/GameUtils.cs +++ b/managed/GTAVisionExport/GameUtils.cs @@ -5,60 +5,167 @@ using System.Threading.Tasks; using GTA; using GTA.Math; +using GTA.Native; -namespace GTAVisionExport -{ +namespace GTAVisionExport { - public class speedAndTime - { - public int gameTime { get; set; } - public float speed { get; set; } + public class TimeChecker { + public int startTime { get; set; } public bool initialized { get; set; } - public speedAndTime() - { - gameTime = 0; - speed = 0; + public TimeSpan interval { get; set; } + + public TimeChecker(TimeSpan interval) { + /* Game.Gametime is in ms, so 1000000 ms = 16.6 min*/ + startTime = 0; initialized = false; + this.interval = interval; } - public void setTime(int time, float speed) - { - this.gameTime = time; - this.speed = speed; - this.initialized = true; - } - public void clearTime() - { + + public void clear() { this.initialized = false; } - public Boolean checkTrafficJam(int time, float speed) - { + + public bool isPassed(int time) { //UI.Notify("last time" + this.gameTime); //UI.Notify("time now" + time); - if (!initialized) - { - this.gameTime = time; - this.speed = speed; - this.initialized = true; + if (!initialized) { + startTime = time; + initialized = true; return false; } + + return time >= startTime + interval.TotalMilliseconds; + } + } + + public abstract class TimeDistanceChecker { + public int startTime { get; set; } + public bool initialized { get; set; } + public TimeSpan interval { get; set; } + public Vector3 center; + public int distance; + + public TimeDistanceChecker(TimeSpan interval, int distance, Vector3 center) { /* Game.Gametime is in ms, so 1000000 ms = 16.6 min*/ - else if (time >= this.gameTime + 200000) - { - return true; + startTime = 0; + initialized = false; + this.interval = interval; + this.center = center; + this.distance = distance; + } + + public void clear() { + initialized = false; + } + + public abstract bool isDistanceSatisfied(Vector3 position); + + public bool isPassed(int time, Vector3 position) { + //UI.Notify("last time" + this.gameTime); + //UI.Notify("time now" + time); + if (!initialized) { + startTime = time; + initialized = true; + center = position; + return false; + } + + if (time >= startTime + interval.TotalMilliseconds) { + return isDistanceSatisfied(position); } - else return false; + return false; + } + } + + /// + /// Use to check if vehicle is stuck in some area for some time (e.g. has not moved 1 meter or more from position in last minute) + /// + /// + public class TimeNearPointChecker : TimeDistanceChecker { + + public TimeNearPointChecker(TimeSpan interval, int distance, Vector3 center) : base(interval, distance, center) { + } + + public override bool isDistanceSatisfied(Vector3 position) { + return position.DistanceTo(center) < distance; } } - public enum GameStatus - { + /// + /// Use to check if vehicle is stuck in some area for some time (e.g. has not come nearer to a location (not moving to a target)) + /// + public class TimeDistantFromPointChecker : TimeDistanceChecker { + + public TimeDistantFromPointChecker(TimeSpan interval, int distance, Vector3 center) : base(interval, distance, center) { + } + + public override bool isDistanceSatisfied(Vector3 position) { + return position.DistanceTo(center) > distance; + } + + } + + /// + /// Use to check if vehicle is stuck in some area for some time (e.g. has not come nearer to a location (not moving to a target)) + /// Updates distance, checks if min distance is changing or not after some time. + /// + public class TimeNotMovingTowardsPointChecker { + public int startTime { get; set; } + public bool initialized { get; set; } + public TimeSpan interval { get; set; } + public Vector2 center { get; set; } + public float distance; + public float minDistance; + + public TimeNotMovingTowardsPointChecker(TimeSpan interval, Vector2 center) { + /* Game.Gametime is in ms, so 1000000 ms = 16.6 min*/ + startTime = 0; + initialized = false; + this.interval = interval; + this.center = center; + minDistance = float.MaxValue; + } + + public void clear() { + this.initialized = false; + } + + public bool isPassed(int time, Vector3 position) { + //UI.Notify("last time" + this.gameTime); + //UI.Notify("time now" + time); + if (!initialized) { + startTime = time; + initialized = true; + minDistance = float.MaxValue; + return false; + } + + distance = center.DistanceTo(new Vector2(position.X, position.Y)); + if (distance < minDistance) { + minDistance = distance; + startTime = time; + } + + if (time >= startTime + interval.TotalMilliseconds) { + return distance > minDistance; + } + return false; + } + + + } + + public enum GameStatus { NeedReload, NeedStart, NoActionNeeded } - public class GTAConst - { - public static Vector3 StartPos = new Vector3(311.7819f, -1372.574f, 31.84874f); + public class GTAConst { + public static Vector3 OriginalStartPos = new Vector3(311.7819f, -1372.574f, 31.84874f); + public static Vector3 HighwayStartPos = new Vector3(1209.5412f,-1936.0394f,38.3709f); + + public static VehicleHash OnroadVehicleHash = VehicleHash.Asea; + public static VehicleHash OffroadVehicleHash = OffroadPlanning.OffroadModel; } } diff --git a/managed/GTAVisionExport/OffroadPlanning.cs b/managed/GTAVisionExport/OffroadPlanning.cs new file mode 100644 index 0000000..c228da3 --- /dev/null +++ b/managed/GTAVisionExport/OffroadPlanning.cs @@ -0,0 +1,278 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Windows; +using System.Windows.Forms; +using GTA; +using GTA.Math; +using GTA.Native; +using GTAVisionUtils; +using VAutodrive; + +namespace GTAVisionExport { + // all driving and path planning related things are static and called from VisionExport script which behaves as controlling point + // it makes coordination and switching between onroad and offroad easier + public class OffroadPlanning : Script { +// constant for tried and sufficient offroad model +// it is single player car. Some cars here are multiplayer and disappear at most few seconds after spawning + public static VehicleHash OffroadModel = VehicleHash.Mesa; + private bool showOffroadAreas; + + public static List> areas; + private static Random rnd; + + public static bool offroadDrivingStarted; + private static bool currentlyDrivingToTarget; + public static Vector2? currentTarget = null; + private static int targetsFromSameStart = 0; + private static List currentArea = null; + static KeyHandling kh = new KeyHandling(); + + + public OffroadPlanning() { + UI.Notify("Loaded OffroadPlanning.cs"); + + // attach time methods + Tick += OnTick; + KeyUp += OnKeyUp; + areas = new List>(); + rnd = new Random(); + CreateOffroadAreas(); + } + + private void CreateOffroadAreas() { + var area1 = new List(); + area1.Add(new Rect(1400, -2650, 800, 1750)); + var area2 = new List(); + area2.Add(new Rect(1624, -418, 770, 1410)); + area2.Add(new Rect(1750, 992, 300, 410)); + var area3 = new List(); + area3.Add(new Rect(2180, 1300, 300, 1410)); + area3.Add(new Rect(1980, 1700, 200, 770)); + area3.Add(new Rect(2060, 1500, 120, 200)); + area3.Add(new Rect(2060, 2470, 120, 100)); + var area4 = new List(); + area4.Add(new Rect(2620, 1800, 350, 780)); + area4.Add(new Rect(2970, 2180, 250, 400)); + area4.Add(new Rect(2600, 2580, 750, 450)); + area4.Add(new Rect(3350, 2850, 220, 300)); + var area5 = new List(); + area5.Add(new Rect(150, 1400, 1500, 980)); + area5.Add(new Rect(150, 2380, 1300, 220)); + area5.Add(new Rect(-540, 2120, 690, 500)); + var area6 = new List(); + area6.Add(new Rect(300, 2720, 1200, 700)); + area6.Add(new Rect(1500, 2950, 230, 470)); + var area7 = new List(); + area7.Add(new Rect(2300, 3100, 300, 700)); + var area8 = new List(); + area8.Add(new Rect(-570, 4700, 410, 950)); + area8.Add(new Rect(-820, 4700, 250, 740)); + area8.Add(new Rect(-690, 5440, 120, 80)); + area8.Add(new Rect(-1100, 4700, 280, 600)); + area8.Add(new Rect(-1270, 4700, 170, 520)); + area8.Add(new Rect(-1470, 4700, 200, 300)); + area8.Add(new Rect(-1600, 4700, 130, 170)); + area8.Add(new Rect(-1700, 4700, 100, 90)); + area8.Add(new Rect(-1700, 4550, 300, 150)); + areas.Add(area1); + areas.Add(area2); + areas.Add(area3); + areas.Add(area4); + areas.Add(area5); + areas.Add(area6); + areas.Add(area7); + areas.Add(area8); + } + + // Test vehicle controls + private void OnKeyUp(object sender, KeyEventArgs e) { + switch (e.KeyCode) { + case Keys.Subtract: + UI.Notify("Pressed numpad -"); + showOffroadAreas = !showOffroadAreas; + if (showOffroadAreas) { + UI.Notify("enabled offroad areas showing"); + } + else { + UI.Notify("disabled offroad areas showing"); + } + + break; + case Keys.Pause: + UI.Notify("Pressed Pause/Break"); + offroadDrivingStarted = !offroadDrivingStarted; + if (offroadDrivingStarted) { + UI.Notify("offroad driving enabled"); + VisionExport.drivingOffroad = true; + } + else { + UI.Notify("offroad driving disabled"); + VisionExport.drivingOffroad = false; + } + + break; + } + } + + public static void checkDrivingToTarget() { + if (Game.Player.Character.CurrentVehicle.Position.DistanceTo2D(new Vector3(currentTarget.Value.X, currentTarget.Value.Y, 0)) < 3) { + currentlyDrivingToTarget = false; + } + + if (! Game.IsWaypointActive) { + currentlyDrivingToTarget = false; + } + + + } + + /// + /// behold, this function wraps most of fuckups that GetGroundHeight causes, + /// teleports player multiple times and perform waiting, call only when you know what your're doing + /// + /// + /// + public static float GetGroundHeightMagic(Vector2 position) { +// for distant position from player, which are not bufferent, function returns 0, so we need to teleport +// above that position and let player fall, in the meantime texture loads properly and getting ground height starts +// working. Raycasting returns exactly same results, so it seems that it's used as an implementation of this function +// when the player is falling on the exact same x,y location, this returns player's position as ground +// that is heavy evidence for thinking raycasting from above is used in that function. That's why here is +5, +5 +// for player position. For each position, height in which it starts working, differs, so that's why I tryit in cycle +// and check when it returns nonzero, and thus correct result + for (int i = 900; i > 100; i-= 50) { +// when I use the same position, the GetGroundHeight call takes coordinates of player as ground height + Game.Player.Character.Position = new Vector3(position.X + 5, position.Y + 5, i); + //just some more waiting for textures to load + Script.Wait(500); + var startZ = World.GetGroundHeight(new Vector2(position.X, position.Y)); + if (startZ != 0) { + return startZ; + } + } + + throw new Exception("height measurement is fucked up somehow, aborting"); + } + + public static void setNextStart() { +// Logger.WriteLine($"setting the next start"); + currentArea = GetRandomArea(); + var startRect = GetRandomRect(currentArea); + var start = GetRandomPoint(startRect); + var startZ = GetGroundHeightMagic(start); + Game.Player.Character.IsInvincible = true; + Logger.WriteLine($"{startZ} is ground height of {start}"); + var newPosition = new Vector3(start.X, start.Y, startZ + 2); // so we have some reserve, when setting to ground z coord, it falls through + if (Game.Player.Character.IsInVehicle()) { + Game.Player.Character.CurrentVehicle.Position = newPosition; + } + else { + Game.Player.Character.Position = newPosition; + } + targetsFromSameStart = 0; + currentlyDrivingToTarget = false; + Logger.WriteLine($"setting next start in {newPosition}"); + VisionExport.UINotify($"setting next start in {newPosition}"); + } + + public static void setNextTarget() { + if (currentlyDrivingToTarget) { + return; + } + +// setting the new start in new area after some number of targets from same start +// var targetsPerArea = 10; + var targetsPerArea = 5; //5 for testing purpose + if (targetsPerArea < targetsFromSameStart || currentArea == null) { + setNextStart(); + } + +// firstly, select some area and for a while, perform random walk in that area, then randomly selct other area +// at first, I'll randomly sample rectangle from area, then randomly sample point from that rectangle +// sampling rectangles is in ratio corresponsing to their sizes, so smaller rectangle is not sampled more often + +// because vehicle is driving onroad for longer routes, generated target shall be max. 200 meters from start, behaving as a "waypoint" on randomly sampled route + Vector2 target; + var playerPos = Game.Player.Character.Position; + do { + var targetRect = GetRandomRect(currentArea); + target = GetRandomPoint(targetRect); + } while (target.DistanceTo(new Vector2(playerPos.X, playerPos.Y)) > 200); + Logger.WriteLine($"setting next target in {target}"); + VisionExport.UINotify($"setting next target in {target}"); + DriveToPoint(target); + + currentlyDrivingToTarget = true; + currentTarget = target; + targetsFromSameStart += 1; + VisionExport.clearStuckCheckers(); + VisionExport.LongFarFromTarget.center = currentTarget.Value; + } + + private static void SetTargetAsWaypoint(Vector2 target) { + HashFunctions.SetNewWaypoint(target); + } + + private static Autopilot getAutopilot() { + var field = kh.GetType().GetField("_autopilot", BindingFlags.NonPublic | BindingFlags.Instance); + return (Autopilot) field.GetValue(kh); + } + + private static void DriveToPoint(Vector2 target) { + SetTargetAsWaypoint(target); + Wait(10); //just wait until target is set + var inf = kh.GetType().GetMethod("AtToggleAutopilot", BindingFlags.NonPublic | BindingFlags.Instance); + inf.Invoke(kh, new object[] {new KeyEventArgs(Keys.J)}); + } + + public static void DriveToCurrentTarget() { + DriveToPoint(currentTarget.Value); + } + + public static List GetRandomArea() { + var areaIdx = rnd.Next(areas.Count); +// Logger.WriteLine($"randomly selected area index {areaIdx} from {areas.Count} areas"); + var area = areas[areaIdx]; +// Logger.WriteLine($"selected area: {string.Join(", ", area)}, with size {area.Count}"); + return area; + } + + public static Rect GetRandomRect(List area) { +// Logger.WriteLine($"selecting random rect for area with size {area.Count}"); + Logger.ForceFlush(); + var volumes = new List(area.Count); + for (var i = 0; i < area.Count; i++) { + volumes.Add((int) (area[i].Width * area[i].Height)); + } + var sum = 0; + var rectIdx = MathUtils.digitize(rnd.Next(volumes.Sum()), MathUtils.cumsum(volumes)); + return area[rectIdx]; + } + + public static Vector2 GetRandomPoint(Rect rect) { + return new Vector2((float) (rect.X + rnd.Next((int) (rect.Width))), (float) (rect.Y + rnd.Next((int) rect.Height))); + } + + public void OnTick(object sender, EventArgs e) { + if (showOffroadAreas) { + DrawOffroadAreas(); + } + + // driving and planning related things are in VisionExport + } + + public void DrawOffroadAreas() { + foreach (var area in areas) { + foreach (var rect in area) { + HashFunctions.Draw3DBox( + new Vector3((float) (rect.X + rect.Width/2), (float) (rect.Y + rect.Height/2), 0), + new Vector3((float) rect.Width, (float) rect.Height, 500), + 255, 255, 255, 50); + } + } + } + + } +} diff --git a/managed/GTAVisionExport/VisionExport.cs b/managed/GTAVisionExport/VisionExport.cs index 9eb2bbd..2347572 100644 --- a/managed/GTAVisionExport/VisionExport.cs +++ b/managed/GTAVisionExport/VisionExport.cs @@ -15,12 +15,7 @@ using BitMiracle.LibTiff.Classic; using System.Drawing; using System.Drawing.Imaging; -using Amazon; -using Amazon.Runtime; using YamlDotNet.RepresentationModel; -using Amazon.S3; -using Amazon.S3.IO; -using Amazon.S3.Model; using System.IO.Pipes; using System.Net; using VAutodrive; @@ -35,11 +30,10 @@ using System.Configuration; using System.Threading; using IniParser; +using Newtonsoft.Json; namespace GTAVisionExport { - - class VisionExport : Script - { + class VisionExport : Script { #if DEBUG const string session_name = "NEW_DATA_CAPTURE_NATURAL_V4_3"; #else @@ -48,38 +42,64 @@ class VisionExport : Script //private readonly string dataPath = // Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Data"); private readonly string dataPath; - private readonly string logFilePath; - private readonly Weather[] wantedWeather = new Weather[] {Weather.Clear, Weather.Clouds, Weather.Overcast, Weather.Raining, Weather.Christmas}; + public static string logFilePath; + + private readonly Weather[] wantedWeathers = new Weather[] + {Weather.Clear, Weather.Clouds, Weather.Overcast, Weather.Raining, Weather.Christmas}; + + private readonly Weather wantedWeather = Weather.Clear; + private readonly bool multipleWeathers = false; // decides whether to use multiple weathers or just one + private readonly bool currentWeather = true; + private readonly bool clearEverything = false; +// private readonly bool useMultipleCameras = false; // when false, cameras handling script is not used at all + private readonly bool useMultipleCameras = true; // when false, cameras handling script is not used at all +// private readonly bool staticCamera = true; // this turns off whole car spawning, teleportation and autodriving procedure + private readonly bool staticCamera = false; // this turns off whole car spawning, teleportation and autodriving procedure private Player player; - private string outputPath; private GTARun run; private bool enabled = false; private Socket server; private Socket connection; private UTF8Encoding encoding = new UTF8Encoding(false); + +// this is the vaustodrive keyhandling private KeyHandling kh = new KeyHandling(); - private ZipArchive archive; - private Stream S3Stream; - private AmazonS3Client client; + private Task postgresTask; + private Task runTask; private int curSessionId = -1; - private speedAndTime lowSpeedTime = new speedAndTime(); - private bool IsGamePaused = false; + public static TimeChecker lowSpeedTime = new TimeChecker(TimeSpan.FromMinutes(2)); + public static TimeChecker notMovingTime = new TimeChecker(TimeSpan.FromSeconds(30)); + public static TimeChecker notMovingNorDrivingTime = new TimeChecker(TimeSpan.FromSeconds(6)); + public static TimeNearPointChecker NearPointFromStart = new TimeNearPointChecker(TimeSpan.FromSeconds(60), 10, new Vector3()); + public static TimeNotMovingTowardsPointChecker LongFarFromTarget = new TimeNotMovingTowardsPointChecker(TimeSpan.FromMinutes(2.5), new Vector2()); + private bool isGamePaused = false; // this is for external pause, not for internal pause inside the script + private static bool notificationsAllowed = true; private StereoCamera cams; - private bool notificationsEnabled = true; - public VisionExport() - { + private bool timeIntervalEnabled = false; + private TimeSpan timeFrom; + private TimeSpan timeTo; + public static string location; + private static Vector2 somePos; + + //this variable, when true, should be disabling car spawning and autodrive starting here, because offroad has different settings + public static bool drivingOffroad; + public static bool gatheringData = true; + public static bool triedRestartingAutodrive; + + public VisionExport() { // loading ini file var parser = new FileIniDataParser(); - var location = AppDomain.CurrentDomain.BaseDirectory; + location = AppDomain.CurrentDomain.BaseDirectory; var data = parser.ReadFile(Path.Combine(location, "GTAVision.ini")); //UINotify(ConfigurationManager.AppSettings["database_connection"]); dataPath = data["Snapshots"]["OutputDir"]; logFilePath = data["Snapshots"]["LogFile"]; + Logger.logFilePath = logFilePath; - System.IO.File.WriteAllText(logFilePath, "VisionExport constructor called.\n"); + Logger.WriteLine("VisionExport constructor called."); if (!Directory.Exists(dataPath)) Directory.CreateDirectory(dataPath); PostgresExport.InitSQLTypes(); player = Game.Player; @@ -92,51 +112,160 @@ public VisionExport() //outStream = File.CreateText(outputPath); this.Tick += new EventHandler(this.OnTick); this.KeyDown += OnKeyDown; - - Interval = 1000; - if (enabled) - { + + Interval = 50; + if (enabled) { postgresTask?.Wait(); postgresTask = StartSession(); runTask?.Wait(); runTask = StartRun(); } + + Logger.WriteLine("Logger prepared"); + UINotify("Logger initialized. Going to initialize cameras."); + CamerasList.initialize(); + initialize4cameras(); + +// var newCamera = World.CreateCamera(new Vector3(), new Vector3(), 50); +// newCamera.NearClip = 0.15f; +// newCamera.IsActive = true; +// newCamera.Position = new Vector3(-1078f, -216f, 37f); +//// newCamera.Rotation = new Vector3(270f, 0f, 0f); // x and y rotation seem to be switched. Can be fixed by setting the last parameter to 2 +// newCamera.Rotation = new Vector3(0f, 270f, 0f); // x and y rotation seem to be switched. Can be fixed by setting the last parameter to 2 +// World.RenderingCamera = newCamera; + +// {-1078,-216,37} +// CamerasList.setMainCamera(new Vector3(358f, -1308f, 52f), new Vector3(0f, 90f, 0f), 150, 0.15f); + + UINotify("VisionExport plugin initialized."); } - private void handlePipeInput() - { - System.IO.File.AppendAllText(logFilePath, "VisionExport handlePipeInput called.\n"); - if(notificationsEnabled) UI.Notify("handlePipeInput called"); - if (notificationsEnabled) UI.Notify("server connected:" + server.Connected.ToString()); - if (notificationsEnabled) UI.Notify(connection == null ? "connection is null" : "connection:" + connection.ToString()); - if (connection == null) return; + private void initialize4cameras() { +// cameras initialization: - byte[] inBuffer = new byte[1024]; - string str = ""; - int num = 0; - try - { +// for cameras mapping area before the car +// float r = 8f; //radius of circle with 4 cameras +// CamerasList.setMainCamera(); +// CamerasList.addCamera(new Vector3(0f, 2f, 0.4f), new Vector3(0f, 0f, 0f), 50, 1.5f); +// CamerasList.addCamera(new Vector3(r, r + 2f, 0.4f), new Vector3(0f, 0f, 90f), 50, 1.5f); +// CamerasList.addCamera(new Vector3(0f, 2*r + 2f, 0.4f), new Vector3(0f, 0f, 180f), 50, 1.5f); +// CamerasList.addCamera(new Vector3(-r, r + 2f, 0.4f), new Vector3(0f, 0f, 270f), 50, 1.5f); + +//// for 4 cameras of different sides of the car, for šochman +// CamerasList.setMainCamera(); +// CamerasList.addCamera(new Vector3(0f, 2f, 0.3f), new Vector3(0f, 0f, 0f), 50, 0.15f); +// CamerasList.addCamera(new Vector3(-0.8f, 0.8f, 0.4f), new Vector3(0f, 0f, 90f), 50, 0.15f); +// CamerasList.addCamera(new Vector3(0f, -2.3f, 0.3f), new Vector3(0f, 0f, 180f), 50, 0.15f); +// CamerasList.addCamera(new Vector3(0.8f, 0.8f, 0.4f), new Vector3(0f, 0f, 270f), 50, 0.15f); + +// for 4 cameras on top of car, heading 4 directions +// CamerasList.setMainCamera(); +// CamerasList.addCamera(new Vector3(0f, 0f, 1f), new Vector3(0f, 0f, 0f), 58, 0.15f); +// CamerasList.addCamera(new Vector3(0f, 0f, 1f), new Vector3(0f, 0f, 90f), 58, 0.15f); +// CamerasList.addCamera(new Vector3(0f, 0f, 1f), new Vector3(0f, 0f, 180f), 58, 0.15f); +// CamerasList.addCamera(new Vector3(0f, 0f, 1f), new Vector3(0f, 0f, 270f), 58, 0.15f); + +// set only main camera for static traffic camera +// CamerasList.setMainCamera(new Vector3(-1078f, -216f, 57f), new Vector3(270f, 0f, 0f), 50, 0.15f); + +//// two "cameras", as in KITTI dataset, so we have 4-camera setup in stereo +//// for cameras mapping area before the car +// CamerasList.setMainCamera(); +// const float r = 8f; //radius of circle with 4 cameras +// // this height is for 1.65 m above ground, as in KITTI. The car has height of model ASEA is 1.5626, its center is in 0.5735 above ground +// var carCenter = 0.5735f; +// var camOne = new Vector3(-0.06f, 0.27f, 1.65f - carCenter); +// var camTwo = new Vector3(-0.06f+0.54f, 0.27f, 1.65f - carCenter); +// CamerasList.addCamera(camOne + new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, 0f), 50, 0.15f); +// CamerasList.addCamera(camOne + new Vector3(r, r, 0f), new Vector3(0f, 0f, 90f), 50, 0.15f); +// CamerasList.addCamera(camOne + new Vector3(0, 2*r, 0f), new Vector3(0f, 0f, 180f), 50, 0.15f); +// CamerasList.addCamera(camOne + new Vector3(-r, r, 0f), new Vector3(0f, 0f, 270f), 50, 0.15f); +//// 4 camera layout from 1 camera should be ernough to reconstruct 3D map for both cameras +// CamerasList.addCamera(camTwo + new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, 0f), 50, 0.15f); +//// CamerasList.addCamera(camTwo + new Vector3(r, r, 0f), new Vector3(0f, 0f, 90f), 50, 0.15f); +//// CamerasList.addCamera(camTwo + new Vector3(0, 2*r, 0f), new Vector3(0f, 0f, 180f), 50, 0.15f); +//// CamerasList.addCamera(camTwo + new Vector3(-r, r, 0f), new Vector3(0f, 0f, 270f), 50, 0.15f); +//// and now, one camera from birds-eye view, with this configuration, it sees all other cameras +// CamerasList.addCamera(camOne + new Vector3(0, r, r + 4), new Vector3(270f, 0f, 0f), 70, 0.15f); + +//// two "cameras", as in KITTI dataset, so we have 4-camera setup in stereo, but for offroad car, specifically, for Mesa +//// for cameras mapping area before the car +//// KITTI images have ratio of 3.32, they are very large and thus have large horizontal fov. This ratio can not be obtained here +//// so I set higher vertical fov and image may be then cropped into KITTI-like one +// CamerasList.setMainCamera(); +// const float r = 8f; //radius of circle with 4 cameras +// // this height is for 1.65 m above ground, as in KITTI. The car has height of model ASEA is 1.5626, its center is in 0.5735 above ground +// var carCenter = 0.5735f; +// var camOne = new Vector3(-0.06f, 1.5f, 1.65f - carCenter); +// var camTwo = new Vector3(-0.06f+0.54f, 1.5f, 1.65f - carCenter); +// CamerasList.addCamera(camOne + new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, 0f), 90, 0.15f); +// CamerasList.addCamera(camOne + new Vector3(r, r, 0f), new Vector3(0f, 0f, 90f), 90, 0.15f); +// CamerasList.addCamera(camOne + new Vector3(0, 2*r, 0f), new Vector3(0f, 0f, 180f), 90, 0.15f); +// CamerasList.addCamera(camOne + new Vector3(-r, r, 0f), new Vector3(0f, 0f, 270f), 90, 0.15f); +//// 4 camera layout from 1 camera should be ernough to reconstruct 3D map for both cameras +// CamerasList.addCamera(camTwo + new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, 0f), 90, 0.15f); +//// CamerasList.addCamera(camTwo + new Vector3(r, r, 0f), new Vector3(0f, 0f, 90f), 50, 0.15f); +//// CamerasList.addCamera(camTwo + new Vector3(0, 2*r, 0f), new Vector3(0f, 0f, 180f), 50, 0.15f); +//// CamerasList.addCamera(camTwo + new Vector3(-r, r, 0f), new Vector3(0f, 0f, 270f), 50, 0.15f); +//// and now, one camera from birds-eye view, with this configuration, it sees all other cameras +// CamerasList.addCamera(camOne + new Vector3(0, r, r + 4), new Vector3(270f, 0f, 0f), 70, 0.15f); + +// na 32 metrů průměr, výš a natočit dolů +// two "cameras", as in KITTI dataset, so we have 4-camera setup in stereo, but for offroad car, specifically, for Mesa +// for cameras mapping area before the car +// KITTI images have ratio of 3.32, they are very large and thus have large horizontal fov. This ratio can not be obtained here +// so I set higher vertical fov and image may be then cropped into KITTI-like one + CamerasList.setMainCamera(); + const float r = 16f; //radius of circle with 4 cameras + // this height is for 1.65 m above ground, as in KITTI. The car has height of model ASEA is 1.5626, its center is in 0.5735 above ground + var carCenter = 0.5735f; + var camOne = new Vector3(-0.06f, 1.5f, 1.65f - carCenter); + var camTwo = new Vector3(-0.06f+0.54f, 1.5f, 1.65f - carCenter); + CamerasList.addCamera(camOne + new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, 0f), 90, 0.15f); + + CamerasList.addCamera(camOne + new Vector3(r, r, 5f), new Vector3(-30f, 0f, 90f), 90, 0.15f); + CamerasList.addCamera(camOne + new Vector3(0, 2*r, 5f), new Vector3(-30f, 0f, 180f), 90, 0.15f); + CamerasList.addCamera(camOne + new Vector3(-r, r, 5f), new Vector3(-30f, 0f, 270f), 90, 0.15f); +// 4 camera layout from 1 camera should be ernough to reconstruct 3D map for both cameras + CamerasList.addCamera(camTwo + new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, 0f), 90, 0.15f); +// and now, one camera from birds-eye view, with this configuration, it sees all other cameras + CamerasList.addCamera(camOne + new Vector3(0, r, r + 8), new Vector3(270f, 0f, 90f), 70, 0.15f); //to have bigger view of area in front of and behind car + } + + private void HandlePipeInput() { +// Logger.writeLine("VisionExport handlePipeInput called."); +// UINotify("handlePipeInput called"); + UINotify("server connected:" + server.Connected); + UINotify(connection == null ? "connection is null" : "connection:" + connection); + if (connection == null) return; + + var inBuffer = new byte[1024]; + var str = ""; + var num = 0; + try { num = connection.Receive(inBuffer); str = encoding.GetString(inBuffer, 0, num); } - catch (SocketException e) - { - if (e.SocketErrorCode == SocketError.WouldBlock) - { + catch (SocketException e) { + if (e.SocketErrorCode == SocketError.WouldBlock) { return; } + throw; } - if (num == 0) - { + + if (num == 0) { connection.Shutdown(SocketShutdown.Both); connection.Close(); connection = null; return; } - if (notificationsEnabled) UI.Notify(str.Length.ToString()); - switch (str) - { + + UINotify("str: " + str); + Logger.WriteLine("obtained json: " + str); + dynamic parameters = JsonConvert.DeserializeObject(str); + string commandName = parameters.name; + switch (commandName) { case "START_SESSION": postgresTask?.Wait(); postgresTask = StartSession(); @@ -151,7 +280,7 @@ private void handlePipeInput() ToggleNavigation(); break; case "ENTER_VEHICLE": - if (notificationsEnabled) UI.Notify("Trying to enter vehicle"); + UINotify("Trying to enter vehicle"); EnterVehicle(); break; case "AUTOSTART": @@ -161,94 +290,112 @@ private void handlePipeInput() ReloadGame(); break; case "RELOAD": - FieldInfo f = this.GetType().GetField("_scriptdomain", BindingFlags.NonPublic | BindingFlags.Instance); - object domain = f.GetValue(this); - MethodInfo m = domain.GetType() + var f = GetType() + .GetField("_scriptdomain", BindingFlags.NonPublic | BindingFlags.Instance); + var domain = f.GetValue(this); + var m = domain.GetType() .GetMethod("DoKeyboardMessage", BindingFlags.Instance | BindingFlags.Public); m.Invoke(domain, new object[] {Keys.Insert, true, false, false, false}); break; - case "GET_SCREEN": - var last = ImageUtils.getLastCapturedFrame(); - Int64 size = last.Length; - size = IPAddress.HostToNetworkOrder(size); - connection.Send(BitConverter.GetBytes(size)); - connection.Send(last); + case "SET_TIME": + string time = parameters.time; + UINotify("starting set time, obtained: " + time); + var hoursAndMinutes = time.Split(':'); + var hours = int.Parse(hoursAndMinutes[0]); + var minutes = int.Parse(hoursAndMinutes[1]); + GTA.World.CurrentDayTime = new TimeSpan(hours, minutes, 0); + UINotify("Time Set"); break; + case "SET_WEATHER": + try { + string weather = parameters.weather; + UINotify("Weather Set to " + weather.ToString()); + var weatherEnum = (Weather) Enum.Parse(typeof(Weather), weather); + GTA.World.Weather = weatherEnum; + } + catch (Exception e) { + Logger.WriteLine(e); + } + break; + case "SET_TIME_INTERVAL": + string timeFrom = parameters.timeFrom; + string timeTo = parameters.timeTo; + UINotify("starting set time, obtained from: " + timeFrom + ", to: " + timeTo); + var hoursAndMinutesFrom = timeFrom.Split(':'); + var hoursAndMinutesTo = timeTo.Split(':'); + var hoursFrom = int.Parse(hoursAndMinutesFrom[0]); + var minutesFrom = int.Parse(hoursAndMinutesFrom[1]); + var hoursTo = int.Parse(hoursAndMinutesTo[0]); + var minutesTo = int.Parse(hoursAndMinutesTo[1]); + this.timeIntervalEnabled = true; + this.timeFrom = new TimeSpan(hoursFrom, minutesFrom, 0); + this.timeTo = new TimeSpan(hoursTo, minutesTo, 0); + UINotify("Time Interval Set"); + break; + case "PAUSE": + UINotify("game paused"); + isGamePaused = true; + Game.Pause(true); + break; + case "UNPAUSE": + UINotify("game unpaused"); + isGamePaused = false; + Game.Pause(false); + break; +// uncomment when resolving, how the hell should I get image by socket correctly +// case "GET_SCREEN": +// var last = ImageUtils.getLastCapturedFrame(); +// Int64 size = last.Length; +// UINotify("last size: " + size.ToString()); +// size = IPAddress.HostToNetworkOrder(size); +// connection.Send(BitConverter.GetBytes(size)); +// connection.Send(last); +// break; } } - private void UploadFile() - { - - archive.Dispose(); - var oldOutput = outputPath; - if (oldOutput != null) - { - new Thread(() => - { - File.Move(oldOutput, Path.Combine(dataPath, run.guid + ".zip")); - }).Start(); - } - - outputPath = Path.GetTempFileName(); - S3Stream = File.Open(outputPath, FileMode.Truncate); - archive = new ZipArchive(S3Stream, ZipArchiveMode.Update); - //File.Delete(oldOutput); - - /* - archive.Dispose(); - var req = new PutObjectRequest { - BucketName = "gtadata", - Key = "images/" + run.guid + ".zip", - FilePath = outputPath - }; - var resp = client.PutObjectAsync(req); - outputPath = Path.GetTempFileName(); - S3Stream = File.Open(outputPath, FileMode.Truncate); - archive = new ZipArchive(S3Stream, ZipArchiveMode.Update); - - await resp; - File.Delete(req.FilePath); - */ + public void startRunAndSessionManual() { +// this method does not enable mod (used for manual data gathering) + postgresTask?.Wait(); + postgresTask = StartSession(); + runTask?.Wait(); + runTask = StartRun(false); } - public void OnTick(object o, EventArgs e) - { - - - if (server.Poll(10, SelectMode.SelectRead) && connection == null) - { + public void OnTick(object o, EventArgs e) { + if (server.Poll(10, SelectMode.SelectRead) && connection == null) { connection = server.Accept(); - if (notificationsEnabled) UI.Notify("CONNECTED"); + UINotify("CONNECTED"); connection.Blocking = false; } - handlePipeInput(); + + HandlePipeInput(); if (!enabled) return; - + //Array values = Enum.GetValues(typeof(Weather)); switch (checkStatus()) { case GameStatus.NeedReload: - //TODO: need to get a new session and run? + Logger.WriteLine("Status is NeedReload"); StopRun(); runTask?.Wait(); runTask = StartRun(); - //StopSession(); - //Autostart(); - if (notificationsEnabled) UI.Notify("need reload game"); - Script.Wait(100); + //StopSession(); + //Autostart(); + UINotify("need reload game"); + Wait(100); ReloadGame(); break; case GameStatus.NeedStart: - //TODO do the autostart manually or automatically? + Logger.WriteLine("Status is NeedStart"); //Autostart(); // use reloading temporarily StopRun(); - + ReloadGame(); - Script.Wait(100); + Wait(100); runTask?.Wait(); runTask = StartRun(); //Autostart(); @@ -256,103 +403,182 @@ public void OnTick(object o, EventArgs e) case GameStatus.NoActionNeeded: break; } + +// UINotify("runTask.IsCompleted: " + runTask.IsCompleted.ToString()); +// UINotify("postgresTask.IsCompleted: " + postgresTask.IsCompleted.ToString()); if (!runTask.IsCompleted) return; if (!postgresTask.IsCompleted) return; - List colors = new List(); - Game.Pause(true); - Script.Wait(500); - GTAData dat = GTAData.DumpData(Game.GameTime + ".tiff", new List()); - if (dat == null) return; - var thisframe = VisionNative.GetCurrentTime(); - var depth = VisionNative.GetDepthBuffer(); - var stencil = VisionNative.GetStencilBuffer(); - colors.Add(VisionNative.GetColorBuffer()); - /* - foreach (var wea in wantedWeather) { - World.TransitionToWeather(wea, 0.0f); - Script.Wait(1); - colors.Add(VisionNative.GetColorBuffer()); - }*/ - Game.Pause(false); - - /* - if (World.Weather != Weather.Snowing) - { - World.TransitionToWeather(Weather.Snowing, 1); - - }*/ - var colorframe = VisionNative.GetLastColorTime(); - var depthframe = VisionNative.GetLastConstantTime(); - var constantframe = VisionNative.GetLastConstantTime(); - //UI.Notify("DIFF: " + (colorframe - depthframe) + " FRAMETIME: " + (1 / Game.FPS) * 1000); - if (notificationsEnabled) UI.Notify(colors[0].Length.ToString()); - if (depth == null || stencil == null) - { - if (notificationsEnabled) UI.Notify("No DEPTH"); - return; + if (drivingOffroad && OffroadPlanning.offroadDrivingStarted) { + OffroadPlanning.checkDrivingToTarget(); + OffroadPlanning.setNextTarget(); } - /* - * this code checks to see if there's drift - * it's kinda pointless because we end up "straddling" a present call, - * so the capture time difference can be ~1/4th of a frame but still the - * depth/stencil and color buffers are one frame offset from each other - if (Math.Abs(thisframe - colorframe) < 60 && Math.Abs(colorframe - depthframe) < 60 && - Math.Abs(colorframe - constantframe) < 60) - { - +// UINotify("going to save images and save to postgres"); + if (gatheringData) { + try { + GamePause(true); + gatherData(); + GamePause(false); + } + catch (Exception exception) { + GamePause(false); + Logger.WriteLine("exception occured, logging and continuing"); + Logger.WriteLine(exception); + } + } +// if time interval is enabled, checkes game time and sets it to timeFrom, it current time is after timeTo + if (timeIntervalEnabled) { + var currentTime = World.CurrentDayTime; + if (currentTime > timeTo) { + World.CurrentDayTime = timeFrom; + } + } + } - - PostgresExport.SaveSnapshot(dat, run.guid); + private void gatherData(int delay = 5) { + if (clearEverything) { + ClearSurroundingEverything(Game.Player.Character.Position, 1000f); } - */ - ImageUtils.WaitForProcessing(); - ImageUtils.StartUploadTask(archive, Game.GameTime.ToString(), Game.ScreenResolution.Width, - Game.ScreenResolution.Height, colors, depth, stencil); + + Wait(100); + + var dateTimeFormat = @"yyyy-MM-dd--HH-mm-ss--fff"; + var guid = Guid.NewGuid(); + Logger.WriteLine("generated scene guid: " + guid.ToString()); - PostgresExport.SaveSnapshot(dat, run.guid); - S3Stream.Flush(); - if ((Int64)S3Stream.Length > (Int64)2048 * (Int64)1024 * (Int64)1024) { - ImageUtils.WaitForProcessing(); - StopRun(); - runTask?.Wait(); - runTask = StartRun(); + if (useMultipleCameras) { + for (var i = 0; i < CamerasList.cameras.Count; i++) { + Logger.WriteLine("activating camera " + i.ToString()); + CamerasList.ActivateCamera(i); + gatherDatForOneCamera(dateTimeFormat, guid); + Wait(delay); + } + CamerasList.Deactivate(); + } + else { +// when multiple cameras are not used, only main camera is being used. +// now it checks if it is active or not, and sets it + if (!CamerasList.mainCamera.IsActive) { + CamerasList.ActivateMainCamera(); + } + gatherDatForOneCamera(dateTimeFormat, guid); } } + private void gatherDatForOneCamera(string dateTimeFormat, Guid guid) { + GTAData dat; + bool success; + if (multipleWeathers) { + dat = GTAData.DumpData(DateTime.UtcNow.ToString(dateTimeFormat), wantedWeathers.ToList()); + } + else { + Weather weather = currentWeather ? GTA.World.Weather : wantedWeather; + dat = GTAData.DumpData(DateTime.UtcNow.ToString(dateTimeFormat), weather); + } + + if (CamerasList.activeCameraRotation.HasValue) { + dat.CamRelativeRot = new GTAVector(CamerasList.activeCameraRotation.Value); + } + else { + dat.CamRelativeRot = null; + } + + if (CamerasList.activeCameraPosition.HasValue) { + dat.CamRelativePos = new GTAVector(CamerasList.activeCameraPosition.Value); + } + else { + dat.CamRelativePos = null; + } + + if (drivingOffroad && OffroadPlanning.currentTarget != null) { + dat.CurrentTarget =GTAVector2.fromVector2(OffroadPlanning.currentTarget.Value); + } + else { + dat.CurrentTarget = null; + } + + dat.sceneGuid = guid; + + if (dat == null) { + return; + } + + if (multipleWeathers) { + success = saveSnapshotToFile(dat.ImageName, wantedWeathers, false); + } + else { + Weather weather = currentWeather ? World.Weather : wantedWeather; + success = saveSnapshotToFile(dat.ImageName, weather, false); + } + + if (!success) { +// when getting data and saving to file failed, saving to db is skipped + return; + } + + PostgresExport.SaveSnapshot(dat, run.guid); + } + /* -1 = need restart, 0 = normal, 1 = need to enter vehicle */ - public GameStatus checkStatus() - { - Ped player = Game.Player.Character; + public GameStatus checkStatus() { + var player = Game.Player.Character; if (player.IsDead) return GameStatus.NeedReload; - if (player.IsInVehicle()) - { - Vehicle vehicle = player.CurrentVehicle; - //UI.Notify("T:" + Game.GameTime.ToString() + " S: " + vehicle.Speed.ToString()); - if (vehicle.Speed < 1.0f) //speed is in mph - { - if (lowSpeedTime.checkTrafficJam(Game.GameTime, vehicle.Speed)) - { + if (player.IsInVehicle()) { + var vehicle = player.CurrentVehicle; +// here checking the time in low or no speed + if (vehicle.Speed < 1.0f) { //speed is in mph + if (lowSpeedTime.isPassed(Game.GameTime)) { + Logger.WriteLine("needed reload by low speed for 2 minutes"); + UINotify("needed reload by low speed for 2 minutes"); + return GameStatus.NeedReload; + } + } else { + lowSpeedTime.clear(); + } + + if (vehicle.Speed < 0.01f) { + if (notMovingTime.isPassed(Game.GameTime)) { + Logger.WriteLine("needed reload by staying in place 30 seconds"); + UINotify("needed reload by staying in place 30 seconds"); return GameStatus.NeedReload; } +// if (notMovingNorDrivingTime.isPassed(Game.GameTime) && !triedRestartingAutodrive) { + if (notMovingNorDrivingTime.isPassed(Game.GameTime)) { + Logger.WriteLine("starting driving from 6s inactivity"); + UINotify("starting driving from 6s inactivity"); + if (drivingOffroad) { + OffroadPlanning.DriveToCurrentTarget(); + triedRestartingAutodrive = true; + } + } + } else { + notMovingTime.clear(); + notMovingNorDrivingTime.clear(); } - else - { - lowSpeedTime.clearTime(); + +// here checking the movement from previous position on some time + if (NearPointFromStart.isPassed(Game.GameTime, vehicle.Position)) { + Logger.WriteLine("vehicle hasn't moved for 10 meters after 1 minute"); + return GameStatus.NeedReload; } + + if (LongFarFromTarget.isPassed(Game.GameTime, vehicle.Position)) { + Logger.WriteLine("hasn't been any nearer to goal after 90 seconds"); + return GameStatus.NeedReload; + } + return GameStatus.NoActionNeeded; } - else - { + else { return GameStatus.NeedReload; } } - public Bitmap CaptureScreen() - { + public Bitmap CaptureScreen() { + UINotify("CaptureScreen called"); var cap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); var gfx = Graphics.FromImage(cap); //var dat = GTAData.DumpData(Game.GameTime + ".jpg"); @@ -371,93 +597,154 @@ public Bitmap CaptureScreen() } */ return cap; //cap.Save(GetFileName(".png"), ImageFormat.Png); - } - public void Autostart() - { - EnterVehicle(); - Script.Wait(200); - ToggleNavigation(); - Script.Wait(200); + public void Autostart() { + if (! staticCamera) { + EnterVehicle(); + Wait(200); + ToggleNavigation(); + Wait(200); + } postgresTask?.Wait(); postgresTask = StartSession(); } - public async Task StartSession(string name = session_name) - { + public async Task StartSession(string name = session_name) { if (name == null) name = Guid.NewGuid().ToString(); if (curSessionId != -1) StopSession(); int id = await PostgresExport.StartSession(name); curSessionId = id; } - public void StopSession() - { + public void StopSession() { if (curSessionId == -1) return; PostgresExport.StopSession(curSessionId); curSessionId = -1; } - public async Task StartRun() - { + + public async Task StartRun(bool enable = true) { await postgresTask; - if(run != null) PostgresExport.StopRun(run); + if (run != null) PostgresExport.StopRun(run); var runid = await PostgresExport.StartRun(curSessionId); - - //var s3Info = new S3FileInfo(client, "gtadata", run.archiveKey); - //S3Stream = s3Info.Create(); - - outputPath = Path.GetTempFileName(); - S3Stream = File.Open(outputPath, FileMode.Truncate); - archive = new ZipArchive(S3Stream, ZipArchiveMode.Create); - - //archive = new ZipArchive(, ZipArchiveMode.Create); - - //archive = ZipFile.Open(Path.Combine(dataPath, run.guid + ".zip"), ZipArchiveMode.Create); - - run = runid; - enabled = true; + if (enable) { + enabled = true; + } } - public void StopRun() - { + public void StopRun() { runTask?.Wait(); ImageUtils.WaitForProcessing(); - if (S3Stream.CanWrite) - { - S3Stream.Flush(); - } enabled = false; PostgresExport.StopRun(run); - UploadFile(); +// UploadFile(); run = null; - + Game.Player.LastVehicle.Alpha = int.MaxValue; } - public void EnterVehicle() - { + public static void UINotify(string message) { + //just wrapper for UI.Notify, but lets us disable showing notifications ar all + if (notificationsAllowed) { + UI.Notify(message); + } + } + + public void GamePause(bool value) { + //wraper for pausing and unpausing game, because if its paused, I don't want to pause it again and unpause it. + if (!isGamePaused) { + Game.Pause(value); + } + } + + public static void EnterVehicle() { /* var vehicle = World.GetClosestVehicle(player.Character.Position, 30f); player.Character.SetIntoVehicle(vehicle, VehicleSeat.Driver); */ - Model mod = new Model(GTA.Native.VehicleHash.Asea); - var vehicle = GTA.World.CreateVehicle(mod, player.Character.Position); - player.Character.SetIntoVehicle(vehicle, VehicleSeat.Driver); - //vehicle.Alpha = 0; //transparent - //player.Character.Alpha = 0; + Model mod = null; + if (drivingOffroad) { + mod = new Model(GTAConst.OffroadVehicleHash); + } else { + mod = new Model(GTAConst.OnroadVehicleHash); + } + + var player = Game.Player; + if (mod == null) { + UINotify("mod is null"); + } + + if (player == null) { + UINotify("player is null"); + } + + if (player.Character == null) { + UINotify("player.Character is null"); + } + + UINotify("player position: " + player.Character.Position); + var vehicle = World.CreateVehicle(mod, player.Character.Position); + if (vehicle == null) { + UINotify("vehicle is null. Something is fucked up"); + } + else { + player.Character.SetIntoVehicle(vehicle, VehicleSeat.Driver); + } + +// vehicle.Alpha = 0; //transparent +// player.Character.Alpha = 0; + vehicle.Alpha = int.MaxValue; //back to visible, not sure what the exact value means in terms of transparency + player.Character.Alpha = int.MaxValue; + vehicle.IsInvincible = true; //very important for offroad + } + + public void ToggleNavigation() { + if (drivingOffroad) { + //offroad driving script should handle that separately + OffroadPlanning.setNextTarget(); + triedRestartingAutodrive = false; + } + else { + MethodInfo inf = kh.GetType().GetMethod("AtToggleAutopilot", BindingFlags.NonPublic | BindingFlags.Instance); + inf.Invoke(kh, new object[] {new KeyEventArgs(Keys.J)}); + } + } - public void ToggleNavigation() - { - //YOLO - MethodInfo inf = kh.GetType().GetMethod("AtToggleAutopilot", BindingFlags.NonPublic | BindingFlags.Instance); - inf.Invoke(kh, new object[] {new KeyEventArgs(Keys.J)}); + private void ClearSurroundingVehicles(Vector3 pos, float radius) { + ClearSurroundingVehicles(pos.X, pos.Y, pos.Z, radius); } - public void ReloadGame() - { + private void ClearSurroundingVehicles(float x, float y, float z, float radius) { + Function.Call(Hash.CLEAR_AREA_OF_VEHICLES, x, y, z, radius, false, false, false, false); + } + + private void ClearSurroundingEverything(Vector3 pos, float radius) { + ClearSurroundingEverything(pos.X, pos.Y, pos.Z, radius); + } + + private void ClearSurroundingEverything(float x, float y, float z, float radius) { + Function.Call(Hash.CLEAR_AREA, x, y, z, radius, false, false, false, false); + } + + public static void clearStuckCheckers() { + lowSpeedTime.clear(); + notMovingTime.clear(); + notMovingNorDrivingTime.clear(); + NearPointFromStart.clear(); + LongFarFromTarget.clear(); + triedRestartingAutodrive = false; + Logger.WriteLine("clearing checkers"); + } + + public void ReloadGame() { + if (staticCamera) { + return; + } + + clearStuckCheckers(); + /* Process p = Process.GetProcessesByName("Grand Theft Auto V").FirstOrDefault(); if (p != null) @@ -470,88 +757,93 @@ public void ReloadGame() */ // or use CLEAR_AREA_OF_VEHICLES Ped player = Game.Player.Character; - //UI.Notify("x = " + player.Position.X + "y = " + player.Position.Y + "z = " + player.Position.Z); + //UINotify("x = " + player.Position.X + "y = " + player.Position.Y + "z = " + player.Position.Z); // no need to release the autodrive here // delete all surrounding vehicles & the driver's car - Function.Call(GTA.Native.Hash.CLEAR_AREA_OF_VEHICLES, player.Position.X, player.Position.Y, player.Position.Z, 1000f, false, false, false, false); +// ClearSurroundingVehicles(player.Position, 1000f); player.LastVehicle.Delete(); // teleport to the spawning position, defined in GameUtils.cs, subject to changes - player.Position = GTAConst.StartPos; - Function.Call(GTA.Native.Hash.CLEAR_AREA_OF_VEHICLES, player.Position.X, player.Position.Y, player.Position.Z, 100f, false, false, false, false); +// player.Position = GTAConst.OriginalStartPos; + if (drivingOffroad) { + OffroadPlanning.setNextStart(); + OffroadPlanning.setNextTarget(); + } + else { + player.Position = GTAConst.HighwayStartPos; + } +// ClearSurroundingVehicles(player.Position, 100f); +// ClearSurroundingVehicles(player.Position, 50f); + ClearSurroundingVehicles(player.Position, 20f); // start a new run EnterVehicle(); //Script.Wait(2000); ToggleNavigation(); - lowSpeedTime.clearTime(); - + lowSpeedTime.clear(); } - public void TraverseWeather() - { - for (int i = 1; i < 14; i++) - { + public void TraverseWeather() { + for (int i = 1; i < 14; i++) { //World.Weather = (Weather)i; - World.TransitionToWeather((Weather)i, 0.0f); + World.TransitionToWeather((Weather) i, 0.0f); //Script.Wait(1000); } } - public void OnKeyDown(object o, KeyEventArgs k) - { - System.IO.File.AppendAllText(logFilePath, "VisionExport OnKeyDown called.\n"); - - if (k.KeyCode == Keys.Z) - { - if (notificationsEnabled) - { - UI.Notify("Notifications Disabled"); - notificationsEnabled = false; - } - else - { - UI.Notify("Notifications Enabled"); - notificationsEnabled = true; - - } - } - if (k.KeyCode == Keys.PageUp) - { - postgresTask?.Wait(); - postgresTask = StartSession(); - runTask?.Wait(); - runTask = StartRun(); - if (notificationsEnabled) UI.Notify("GTA Vision Enabled"); - } - if (k.KeyCode == Keys.PageDown) - { - StopRun(); - StopSession(); - if (notificationsEnabled) UI.Notify("GTA Vision Disabled"); - } - if (k.KeyCode == Keys.H) // temp modification - { - EnterVehicle(); - if (notificationsEnabled) UI.Notify("Trying to enter vehicle"); - ToggleNavigation(); - } - if (k.KeyCode == Keys.Y) // temp modification - { - ReloadGame(); - } - if (k.KeyCode == Keys.U) // temp modification - { - var settings = ScriptSettings.Load("GTAVisionExport.xml"); - var loc = AppDomain.CurrentDomain.BaseDirectory; + public void OnKeyDown(object o, KeyEventArgs k) { +// Logger.WriteLine("VisionExport OnKeyDown called."); + switch (k.KeyCode) { + case Keys.PageUp: + postgresTask?.Wait(); + postgresTask = StartSession(); + runTask?.Wait(); + runTask = StartRun(); + UINotify("GTA Vision Enabled"); +// there is set weather, just for testing + World.Weather = wantedWeather; + break; + case Keys.PageDown: + if (staticCamera) { + CamerasList.Deactivate(); + } + StopRun(); + StopSession(); + UINotify("GTA Vision Disabled"); + break; + // temp modification + case Keys.H: + EnterVehicle(); + UINotify("Trying to enter vehicle"); + ToggleNavigation(); + break; + // temp modification + case Keys.Y: + ReloadGame(); + break; + // temp modification + case Keys.X: + notificationsAllowed = !notificationsAllowed; + if (notificationsAllowed) { + UI.Notify("Notifications Enabled"); + } + else { + UI.Notify("Notifications Disabled"); + } - //UI.Notify(ConfigurationManager.AppSettings["database_connection"]); - var str = settings.GetValue("", "ConnectionString"); - if (notificationsEnabled) UI.Notify(loc); + break; + // temp modification + case Keys.U: + var settings = ScriptSettings.Load("GTAVisionExport.xml"); + var loc = AppDomain.CurrentDomain.BaseDirectory; - } - if (k.KeyCode == Keys.G) // temp modification - { - /* + //UINotify(ConfigurationManager.AppSettings["database_connection"]); + var str = settings.GetValue("", "ConnectionString"); + UINotify("BaseDirectory: " + loc); + UINotify("ConnectionString: " + str); + break; + // temp modification + case Keys.G: + /* IsGamePaused = true; Game.Pause(true); Script.Wait(500); @@ -560,146 +852,238 @@ public void OnKeyDown(object o, KeyEventArgs k) IsGamePaused = false; Game.Pause(false); */ - var data = GTAData.DumpData(Game.GameTime + ".tiff", new List(wantedWeather)); - - string path = @"C:\Users\NGV-02\Documents\Data\trymatrix.txt"; - // This text is added only once to the file. - if (!File.Exists(path)) - { - // Create a file to write to. - using (StreamWriter file = File.CreateText(path)) - { - - - file.WriteLine("cam direction file"); - file.WriteLine("direction:"); - file.WriteLine(GameplayCamera.Direction.X.ToString() + ' ' + GameplayCamera.Direction.Y.ToString() + ' ' + GameplayCamera.Direction.Z.ToString()); - file.WriteLine("Dot Product:"); - file.WriteLine(Vector3.Dot(GameplayCamera.Direction, GameplayCamera.Rotation)); - file.WriteLine("position:"); - file.WriteLine(GameplayCamera.Position.X.ToString() + ' ' + GameplayCamera.Position.Y.ToString() + ' ' + GameplayCamera.Position.Z.ToString()); - file.WriteLine("rotation:"); - file.WriteLine(GameplayCamera.Rotation.X.ToString() + ' ' + GameplayCamera.Rotation.Y.ToString() + ' ' + GameplayCamera.Rotation.Z.ToString()); - file.WriteLine("relative heading:"); - file.WriteLine(GameplayCamera.RelativeHeading.ToString()); - file.WriteLine("relative pitch:"); - file.WriteLine(GameplayCamera.RelativePitch.ToString()); - file.WriteLine("fov:"); - file.WriteLine(GameplayCamera.FieldOfView.ToString()); + GTAData data; + if (multipleWeathers) { + data = GTAData.DumpData(Game.GameTime + ".tiff", wantedWeathers.ToList()); + } + else { + Weather weather = currentWeather ? GTA.World.Weather : wantedWeather; + data = GTAData.DumpData(Game.GameTime + ".tiff", weather); } - } - } - if (k.KeyCode == Keys.T) // temp modification - { - World.Weather = Weather.Raining; - /* set it between 0 = stop, 1 = heavy rain. set it too high will lead to sloppy ground */ - Function.Call(GTA.Native.Hash._SET_RAIN_FX_INTENSITY, 0.5f); - var test = Function.Call(GTA.Native.Hash.GET_RAIN_LEVEL); - if (notificationsEnabled) UI.Notify("" + test); - World.CurrentDayTime = new TimeSpan(12, 0, 0); - //Script.Wait(5000); - } + string path = @"D:\GTAV_extraction_output\trymatrix.txt"; + // This text is added only once to the file. + if (!File.Exists(path)) { + // Create a file to write to. + using (StreamWriter file = File.CreateText(path)) { + file.WriteLine("cam direction file"); + file.WriteLine("direction:"); + file.WriteLine( + $"{World.RenderingCamera.Direction.X} {World.RenderingCamera.Direction.Y} {World.RenderingCamera.Direction.Z}"); + file.WriteLine("Dot Product:"); + file.WriteLine(Vector3.Dot(World.RenderingCamera.Direction, World.RenderingCamera.Rotation)); + file.WriteLine("position:"); + file.WriteLine( + $"{World.RenderingCamera.Position.X} {World.RenderingCamera.Position.Y} {World.RenderingCamera.Position.Z}"); + file.WriteLine("rotation:"); + file.WriteLine( + $"{World.RenderingCamera.Rotation.X} {World.RenderingCamera.Rotation.Y} {World.RenderingCamera.Rotation.Z}"); + file.WriteLine("relative heading:"); + file.WriteLine(GameplayCamera.RelativeHeading.ToString()); + file.WriteLine("relative pitch:"); + file.WriteLine(GameplayCamera.RelativePitch.ToString()); + file.WriteLine("fov:"); + file.WriteLine(GameplayCamera.FieldOfView.ToString()); + } + } - if (k.KeyCode == Keys.N) - { - /* - //var color = VisionNative.GetColorBuffer(); + break; + // temp modification + case Keys.T: + World.Weather = Weather.Raining; + /* set it between 0 = stop, 1 = heavy rain. set it too high will lead to sloppy ground */ + Function.Call(Hash._SET_RAIN_FX_INTENSITY, 0.5f); + var test = Function.Call(Hash.GET_RAIN_LEVEL); + UINotify("" + test); + World.CurrentDayTime = new TimeSpan(12, 0, 0); + //Script.Wait(5000); + break; + case Keys.N: + UINotify("N pressed, going to take screenshots"); + + startRunAndSessionManual(); + postgresTask?.Wait(); + runTask?.Wait(); + UINotify("starting screenshots"); + for (int i = 0; i < 2; i++) { + GamePause(true); + gatherData(100); + GamePause(false); + Script.Wait(200); // hoping game will go on during this wait + } + + if (staticCamera) { + CamerasList.Deactivate(); + } + + StopRun(); + StopSession(); + break; + case Keys.OemMinus: //to tlačítko vlevo od pravého shiftu, - + UINotify("- pressed, going to rotate cameras"); - List colors = new List(); - Game.Pause(true); - Script.Wait(1); - var depth = VisionNative.GetDepthBuffer(); - var stencil = VisionNative.GetStencilBuffer(); - foreach (var wea in wantedWeather) { - World.TransitionToWeather(wea, 0.0f); - Script.Wait(1); - colors.Add(VisionNative.GetColorBuffer()); - } - Game.Pause(false); - if (depth != null) - { - var res = Game.ScreenResolution; - var t = Tiff.Open(Path.Combine(dataPath, "test.tiff"), "w"); - ImageUtils.WriteToTiff(t, res.Width, res.Height, colors, depth, stencil); - t.Close(); - UI.Notify(GameplayCamera.FieldOfView.ToString()); - } - else - { - UI.Notify("No Depth Data quite yet"); - } - //UI.Notify((connection != null && connection.Connected).ToString()); - */ - //var color = VisionNative.GetColorBuffer(); - for (int i = 0; i < 100; i++) - { - List colors = new List(); Game.Pause(true); - var depth = VisionNative.GetDepthBuffer(); - var stencil = VisionNative.GetStencilBuffer(); - foreach (var wea in wantedWeather) - { - World.TransitionToWeather(wea, 0.0f); - Script.Wait(1); - colors.Add(VisionNative.GetColorBuffer()); + for (int i = 0; i < CamerasList.cameras.Count; i++) { + Logger.WriteLine($"activating camera {i}"); + CamerasList.ActivateCamera(i); + Script.Wait(1000); } - + CamerasList.Deactivate(); Game.Pause(false); - var res = Game.ScreenResolution; - var t = Tiff.Open(Path.Combine(dataPath, "info" + i.ToString() + ".tiff"), "w"); - ImageUtils.WriteToTiff(t, res.Width, res.Height, colors, depth, stencil); - t.Close(); - if (notificationsEnabled) UI.Notify(GameplayCamera.FieldOfView.ToString()); - //UI.Notify((connection != null && connection.Connected).ToString()); + break; + case Keys.I: + var info = new GTAVisionUtils.InstanceData(); + UINotify(info.type); + UINotify(info.publichostname); + break; + case Keys.Divide: + Logger.WriteLine($"{World.GetGroundHeight(Game.Player.Character.Position)} is the current player ({Game.Player.Character.Position}) ground position."); + var startRect = OffroadPlanning.GetRandomRect(OffroadPlanning.GetRandomArea()); + var start = OffroadPlanning.GetRandomPoint(startRect); + var startZ = World.GetGroundHeight(new Vector2(start.X, start.Y)); + Logger.WriteLine($"{startZ} is the ground position of {start}."); +// OffroadPlanning.setNextStart(); + startRect = OffroadPlanning.GetRandomRect(OffroadPlanning.GetRandomArea()); + start = OffroadPlanning.GetRandomPoint(startRect); + somePos = start; + startZ = World.GetGroundHeight(new Vector2(start.X, start.Y)); + Logger.WriteLine($"{startZ} is the ground position of {start}."); +// when I use the same position, the GetGroundHeight call takes coordinates of player as ground height + Game.Player.Character.Position = new Vector3(start.X + 5, start.Y + 5, 800); + Logger.WriteLine($"teleporting player above teh position."); + Script.Wait(50); + startZ = World.GetGroundHeight(new Vector2(start.X, start.Y)); + Logger.WriteLine($"{startZ} is the ground position of {start}."); + Logger.WriteLine($"{World.GetGroundHeight(Game.Player.Character.Position)} is the current player ({Game.Player.Character.Position}) ground position."); + Logger.ForceFlush(); + break; + case Keys.F12: + Logger.WriteLine($"{World.GetGroundHeight(Game.Player.Character.Position)} is the current player ({Game.Player.Character.Position}) ground position."); + Logger.WriteLine($"{World.GetGroundHeight(somePos)} is the {somePos} ground position."); + break; + case Keys.F11: + Model mod = new Model(GTAConst.OffroadVehicleHash); + var player = Game.Player; + var vehicle = World.CreateVehicle(mod, player.Character.Position); + player.Character.SetIntoVehicle(vehicle, VehicleSeat.Driver); + break; + case Keys.F10: + startRect = OffroadPlanning.GetRandomRect(OffroadPlanning.GetRandomArea()); + start = OffroadPlanning.GetRandomPoint(startRect); + somePos = start; + startZ = World.GetGroundHeight(new Vector2(start.X, start.Y)); + Logger.WriteLine($"{startZ} is the ground position of {start}."); + for (int i = 900; i > 100; i-= 50) { +// when I use the same position, the GetGroundHeight call takes coordinates of player as ground height + Game.Player.Character.Position = new Vector3(start.X + 5, start.Y + 5, i); + Logger.WriteLine($"teleporting player above teh position to height {i}."); + Script.Wait(500); + startZ = World.GetGroundHeight(new Vector2(start.X, start.Y)); + Logger.WriteLine($"{startZ} is the ground position of {start}."); + } + break; + case Keys.F9: + //turn on and off for datagathering during driving, mostly for testing offroad + gatheringData = !gatheringData; + if (gatheringData) { + UI.Notify("will be gathering data"); + } + else { + UI.Notify("won't be gathering data"); + } + break; - var data = GTAData.DumpData(Game.GameTime + ".dat", new List(wantedWeather)); + } + } - string path = @"C:\Users\NGV-02\Documents\Data\info.txt"; - // This text is added only once to the file. - if (!File.Exists(path)) - { - // Create a file to write to. - using (StreamWriter file = File.CreateText(path)) - { - file.WriteLine("cam direction & Ped pos file"); - } - } + private bool saveSnapshotToFile(String name, Weather[] weathers, bool manageGamePauses = true) { +// returns true on success, and false on failure + List colors = new List(); - using (StreamWriter file = File.AppendText(path)) - { - file.WriteLine("==============info" + i.ToString() + ".tiff 's metadata======================="); - file.WriteLine("cam pos"); - file.WriteLine(GameplayCamera.Position.X.ToString()); - file.WriteLine(GameplayCamera.Position.Y.ToString()); - file.WriteLine(GameplayCamera.Position.Z.ToString()); - file.WriteLine("cam direction"); - file.WriteLine(GameplayCamera.Direction.X.ToString()); - file.WriteLine(GameplayCamera.Direction.Y.ToString()); - file.WriteLine(GameplayCamera.Direction.Z.ToString()); - file.WriteLine("character"); - file.WriteLine(data.Pos.X.ToString()); - file.WriteLine(data.Pos.Y.ToString()); - file.WriteLine(data.Pos.Z.ToString()); - foreach (var detection in data.Detections) - { - file.WriteLine(detection.Type.ToString()); - file.WriteLine(detection.Pos.X.ToString()); - file.WriteLine(detection.Pos.Y.ToString()); - file.WriteLine(detection.Pos.Z.ToString()); - } - } + if (manageGamePauses) { + GamePause(true); + } + + var depth = VisionNative.GetDepthBuffer(); + var stencil = VisionNative.GetStencilBuffer(); + if (depth == null || stencil == null) { + return false; + } - Script.Wait(200); + foreach (var wea in weathers) { + World.TransitionToWeather(wea, 0.0f); + Script.Wait(1); + var color = VisionNative.GetColorBuffer(); + if (color == null) { + return false; } + + colors.Add(color); + } + + if (manageGamePauses) { + GamePause(false); + } + + var res = Game.ScreenResolution; + var fileName = Path.Combine(dataPath, name); + ImageUtils.WriteToTiff(fileName, res.Width, res.Height, colors, depth, stencil, false); +// UINotify("file saved to: " + fileName); + return true; } - if (k.KeyCode == Keys.I) - { - var info = new GTAVisionUtils.InstanceData(); - if (notificationsEnabled) UI.Notify(info.type); - if (notificationsEnabled) UI.Notify(info.publichostname); + + private bool saveSnapshotToFile(String name, Weather weather, bool manageGamePauses = true) { +// returns true on success, and false on failure + if (manageGamePauses) { + GamePause(true); + } + + World.TransitionToWeather(weather, + 0.0f); + Script.Wait(10); + var depth = VisionNative.GetDepthBuffer(); + var stencil = VisionNative.GetStencilBuffer(); + var color = VisionNative.GetColorBuffer(); + if (depth == null || stencil == null || color == null) { + return false; } + + + if (manageGamePauses) { + GamePause(false); + } + + var res = Game.ScreenResolution; + var fileName = Path.Combine(dataPath, name); + ImageUtils.WriteToTiff(fileName, res.Width, res.Height, new List() {color}, depth, stencil, false); +// UINotify("file saved to: " + fileName); + return true; + } + + private void dumpTest() { + List colors = new List(); + Game.Pause(true); + Script.Wait(1); + var depth = VisionNative.GetDepthBuffer(); + var stencil = VisionNative.GetStencilBuffer(); + foreach (var wea in wantedWeathers) { + World.TransitionToWeather(wea, 0.0f); + Script.Wait(1); + colors.Add(VisionNative.GetColorBuffer()); + } + + Game.Pause(false); + if (depth != null) { + var res = Game.ScreenResolution; + ImageUtils.WriteToTiff(Path.Combine(dataPath, "test"), res.Width, res.Height, colors, depth, stencil); + UINotify(World.RenderingCamera.FieldOfView.ToString()); + } + else { + UINotify("No Depth Data quite yet"); + } + + UINotify((connection != null && connection.Connected).ToString()); } } -} +} \ No newline at end of file diff --git a/managed/GTAVisionExport/packages.config b/managed/GTAVisionExport/packages.config index 1dea3ec..a3c59ab 100644 --- a/managed/GTAVisionExport/packages.config +++ b/managed/GTAVisionExport/packages.config @@ -1,15 +1,18 @@  - + + + + diff --git a/managed/GTAVisionUtils/GTADataStructures.cs b/managed/GTAVisionUtils/GTADataStructures.cs index 69b96a1..bcdda84 100644 --- a/managed/GTAVisionUtils/GTADataStructures.cs +++ b/managed/GTAVisionUtils/GTADataStructures.cs @@ -13,9 +13,11 @@ using SharpDX.Mathematics; using NativeUI; using System.Drawing; +using Amazon.KeyManagementService.Model.Internal.MarshallTransformations; using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics; +using Color = System.Drawing.Color; using Vector2 = GTA.Math.Vector2; using Vector3 = GTA.Math.Vector3; using Point = System.Drawing.Point; @@ -101,6 +103,7 @@ public class GTADetection public GTABoundingBox2 BBox { get; set; } public BoundingBox BBox3D { get; set; } public int Handle { get; set; } + public GTAVector velocity { get; set; } public GTADetection(Entity e, DetectionType type) { Type = type; @@ -110,11 +113,12 @@ public GTADetection(Entity e, DetectionType type) Handle = e.Handle; Rot = new GTAVector(e.Rotation); + velocity = new GTAVector(e.Velocity); cls = DetectionClass.Unknown; Vector3 gmin; Vector3 gmax; e.Model.GetDimensions(out gmin, out gmax); - BBox3D = new SharpDX.BoundingBox((SharpDX.Vector3)new GTAVector(gmin), (SharpDX.Vector3)new GTAVector(gmax)); + BBox3D = new BoundingBox((SharpDX.Vector3) new GTAVector(gmin), (SharpDX.Vector3)new GTAVector(gmax)); } public GTADetection(Ped p) : this(p, DetectionType.person) @@ -150,6 +154,10 @@ public class GTAVector2 public float X { get; set; } public float Y { get; set; } + public static GTAVector2 fromVector2(Vector2 vector2) { + return new GTAVector2(vector2.X, vector2.Y); + } + public GTAVector2(float x, float y) { X = x; @@ -177,14 +185,29 @@ public class GTAData public TimeSpan LocalTime { get; set; } public Weather CurrentWeather { get; set; } public List CapturedWeathers; - public GTAVector Pos { get; set; } + public GTAVector CamPos { get; set; } + public GTAVector CamRot { get; set; } + public BoundingBox CarModelBox { get; set; } public GTAVector CamDirection { get; set; } //mathnet's matrices are in heap storage, which is super annoying, //but we want to use double matrices to avoid numerical issues as we //decompose the MVP matrix into seperate M,V and P matrices + public DenseMatrix WorldMatrix { get; set; } public DenseMatrix ViewMatrix { get; set; } public DenseMatrix ProjectionMatrix { get; set; } public double CamFOV { get; set; } + + public double CamNearClip { get; set; } + public double CamFarClip { get; set; } + public GTAVector playerPos { get; set; } + public GTAVector velocity { get; set; } + public int UIHeight { get; set; } + public int UIWidth { get; set; } + public Guid sceneGuid { get; set; } + public GTAVector CamRelativeRot { get; set; } + public GTAVector CamRelativePos { get; set; } + public GTAVector2 CurrentTarget { get; set; } + public List Detections { get; set; } public static SharpDX.Vector3 CvtVec(GTA.Math.Vector3 inp) { return (SharpDX.Vector3)new GTAVector(inp); @@ -253,36 +276,55 @@ public static GTABoundingBox2 ComputeBoundingBox(Entity e, Vector3 offset, float rv.Max.Y = Math.Max(rv.Max.Y, s.Y); } -// int width = 1280; -// int height = 960; -// int x = (int)(rv.Min.X * width); -// int y = (int)(rv.Min.Y * height); -// int x2 = (int)(rv.Max.X * width); -// int y2 = (int)(rv.Max.Y * height); -// float w = rv.Max.X - rv.Min.X; -// float h = rv.Max.Y - rv.Min.Y; + float w = rv.Max.X - rv.Min.X; + float h = rv.Max.Y - rv.Min.Y; +// just for debug purposes, show visible and not visible entities in other color +// if (CheckVisible(e)) +// { +// HashFunctions.DrawRect(rv.Min.X + w / 2, rv.Min.Y + h / 2, rv.Max.X - rv.Min.X, rv.Max.Y - rv.Min.Y, +// Color.White, 100); +// } +// else +// { +// HashFunctions.DrawRect(rv.Min.X + w / 2, rv.Min.Y + h / 2, rv.Max.X - rv.Min.X, rv.Max.Y - rv.Min.Y, +// Color.Red, 100); +// } // HashFunctions.DrawRect(rv.Min.X + w/2, rv.Min.Y + h/2, rv.Max.X - rv.Min.X, rv.Max.Y - rv.Min.Y, 255, 255, 255, 100); -// new UIRectangle(new Point((int)(rv.Min.X * 1920), (int)(rv.Min.Y * 1080)), rv.) return rv; } public static bool CheckVisible(Entity e) { - return true; - //var p = Game.Player.LastVehicle; +// return true; - var ppos = GameplayCamera.Position; + var ppos = World.RenderingCamera.Position; var isLOS = Function.Call((GTA.Native.Hash) 0x0267D00AF114F17A, Game.Player.Character, e); - return isLOS; - //var ppos = GameplayCamera.Position; + if (isLOS) return true; +// return isLOS; +// var ppos = GameplayCamera.Position; - //var res = World.Raycast(ppos, e.Position, IntersectOptions.Everything, Game.Player.Character.CurrentVehicle); - //HashFunctions.Draw3DLine(ppos, e.Position); - //UI.Notify("Camera: " + ppos.X + " Ent: " + e.Position.X); - //World.DrawMarker(MarkerType.HorizontalCircleSkinny_Arrow, p.Position, (e.Position - p.Position).Normalized, Vector3.Zero, new Vector3(1, 1, 1), System.Drawing.Color.Red); - //return res.HitEntity == e; - //if (res.HitCoords == null) return false; - //return e.IsInRangeOf(res.HitCoords, 10); + var res = World.Raycast(ppos, e.Position, IntersectOptions.Everything, Game.Player.Character.CurrentVehicle); +// HashFunctions.Draw3DLine(ppos, e.Position); +// UI.Notify("Camera: " + ppos.X + " Ent: " + e.Position.X); +// World.DrawMarker(MarkerType.HorizontalCircleSkinny_Arrow, ppos, (e.Position - ppos).Normalized, Vector3.Zero, new Vector3(1, 1, 1), System.Drawing.Color.Green); + +// debugging visualization for visible or invisible vehicles +// var p = Game.Player.LastVehicle; +// HashFunctions.Draw3DLine(p.Position, e.Position, System.Drawing.Color.Green); +// var s = HashFunctions.Convert3dTo2d(e.Position); +// HashFunctions.Draw2DText("Just Monika", s.X, s.Y, 255, 255, 255, 255); + +// World.DrawMarker(MarkerType.HorizontalCircleSkinny_Arrow, p.Position, (e.Position - p.Position).Normalized, Vector3.Zero, new Vector3(1, 1, 1), System.Drawing.Color.Green); +// return res.HitEntity == e; + if (res.HitEntity == e) return true; + if (res.HitCoords == null) return false; + return e.IsInRangeOf(res.HitCoords, 10); //return res.HitEntity == e; } + + public static GTAData DumpData(string imageName, Weather capturedWeather) + { + return DumpData(imageName, new List() {capturedWeather}); + } + public static GTAData DumpData(string imageName, List capturedWeathers) { var ret = new GTAData(); @@ -293,15 +335,26 @@ public static GTAData DumpData(string imageName, List capturedWeathers) ret.Timestamp = DateTime.UtcNow; ret.LocalTime = World.CurrentDayTime; - ret.Pos = new GTAVector(GameplayCamera.Position); - ret.CamDirection = new GTAVector(GameplayCamera.Direction); - ret.CamFOV = GameplayCamera.FieldOfView; + ret.CamPos = new GTAVector(World.RenderingCamera.Position); + ret.CamRot = new GTAVector(World.RenderingCamera.Rotation); + //getting information about currently driving vehicle model size + Vector3 gmin; + Vector3 gmax; + Game.Player.Character.CurrentVehicle.Model.GetDimensions(out gmin, out gmax); + ret.CarModelBox = new BoundingBox((SharpDX.Vector3) new GTAVector(gmin), (SharpDX.Vector3) new GTAVector(gmax)); + ret.CamDirection = new GTAVector(World.RenderingCamera.Direction); + ret.CamFOV = World.RenderingCamera.FieldOfView; ret.ImageWidth = Game.ScreenResolution.Width; ret.ImageHeight = Game.ScreenResolution.Height; - //ret.Pos = new GTAVector(Game.Player.Character.Position); + ret.UIWidth = UI.WIDTH; + ret.UIHeight = UI.HEIGHT; + ret.playerPos = new GTAVector(Game.Player.Character.Position); + ret.velocity = new GTAVector(Game.Player.Character.Velocity); + ret.CamNearClip = World.RenderingCamera.NearClip; + ret.CamFarClip = World.RenderingCamera.FarClip; - var peds = World.GetNearbyPeds(Game.Player.Character, 150.0f); - var cars = World.GetNearbyVehicles(Game.Player.Character, 150.0f); + var peds = World.GetNearbyPeds(Game.Player.Character, 500.0f); + var cars = World.GetNearbyVehicles(Game.Player.Character, 500.0f); //var props = World.GetNearbyProps(Game.Player.Character.Position, 300.0f); var constants = VisionNative.GetConstants(); @@ -318,15 +371,19 @@ public static GTAData DumpData(string imageName, List capturedWeathers) var P = WVP*WV.Inverse(); ret.ProjectionMatrix = P as DenseMatrix; ret.ViewMatrix = V as DenseMatrix; + ret.WorldMatrix = W as DenseMatrix; var pedList = from ped in peds where ped.IsHuman && ped.IsOnFoot +// where ped.IsHuman && ped.IsOnFoot && CheckVisible(ped) select new GTADetection(ped); var cycles = from ped in peds where ped.IsOnBike +// where ped.IsOnBike && CheckVisible(ped) select new GTADetection(ped, DetectionType.bicycle); var vehicleList = from car in cars +// where CheckVisible(car) select new GTADetection(car); ret.Detections = new List(); ret.Detections.AddRange(pedList); diff --git a/managed/GTAVisionUtils/GTAVisionUtils.csproj b/managed/GTAVisionUtils/GTAVisionUtils.csproj index 28fca82..406c9b8 100644 --- a/managed/GTAVisionUtils/GTAVisionUtils.csproj +++ b/managed/GTAVisionUtils/GTAVisionUtils.csproj @@ -23,6 +23,7 @@ prompt 4 x64 + true pdbonly @@ -31,6 +32,7 @@ TRACE prompt 4 + true @@ -66,7 +68,13 @@ ..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.0\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll - C:\Program Files\Rockstar Games\Grand Theft Auto V\Scripts\NativeUI.dll + ..\..\..\..\..\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\NativeUI.dll + + + D:\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\NativeUI.dll + + + ..\NativeUI.dll ..\packages\Npgsql.3.2.1\lib\net451\Npgsql.dll @@ -79,8 +87,8 @@ ..\packages\GDAL.1.11.1\lib\net40\osr_csharp.dll True - - C:\Program Files\Rockstar Games\Grand Theft Auto V\ScriptHookVDotNet2.dll + + ..\packages\ScriptHookVDotNet2.2.10.5\lib\net452\ScriptHookVDotNet2.dll ..\packages\SharpDX.3.1.1\lib\net45\SharpDX.dll @@ -111,10 +119,22 @@ - C:\Program Files\Rockstar Games\Grand Theft Auto V\Scripts\VAutodrive.dll + ..\..\..\..\..\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\VAutodrive.dll + + + D:\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\VAutodrive.dll + + + ..\376923-VAutodrive V8.0.3\Scripts\VAutodrive.dll - C:\Program Files\Rockstar Games\Grand Theft Auto V\Scripts\VCommonFunctions.dll + ..\..\..\..\..\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\VCommonFunctions.dll + + + D:\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\VCommonFunctions.dll + + + ..\376923-VAutodrive V8.0.3\Scripts\VCommonFunctions.dll @@ -124,6 +144,8 @@ + + @@ -138,6 +160,9 @@ + + + diff --git a/managed/GTAVisionUtils/HashFunctions.cs b/managed/GTAVisionUtils/HashFunctions.cs index c188860..a515d4f 100644 --- a/managed/GTAVisionUtils/HashFunctions.cs +++ b/managed/GTAVisionUtils/HashFunctions.cs @@ -1,10 +1,13 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; +using GTA; using GTA.Math; using GTA.Native; +using Point = System.Windows.Markup; namespace GTAVisionUtils { @@ -40,6 +43,30 @@ public static void Draw3DLine(Vector3 iniPos, Vector3 finPos, byte col_r = 255, (int)col_a }); } + + public static void Draw3DBox(Vector3 pos, Vector3 size, byte col_r = 255, byte col_g = 255, byte col_b = 255, byte col_a = 255) { + Function.Call(Hash.DRAW_BOX, new InputArgument[] { + pos.X - size.X / 2, + pos.Y - size.Y / 2, + pos.Z - size.Z / 2, + pos.X + size.X / 2, + pos.Y + size.Y / 2, + pos.Z + size.Z / 2, + (int)col_r, + (int)col_g, + (int)col_b, + (int)col_a + }); + } + + public static void Draw3DLine(Vector3 iniPos, Vector3 finPos, Color color) { + Draw3DLine(iniPos, finPos, color.R, color.G, color.B, color.A); + } + + public static void Draw3DLine(Vector3 iniPos, Vector3 finPos, Color color, byte a) { + Draw3DLine(iniPos, finPos, color.R, color.G, color.B, a); + } + public static void DrawRect(float x, float y, float w, float h, byte r = 255, byte g = 255, byte b = 255, byte a = 255) { Function.Call(Hash.DRAW_RECT, new InputArgument[] { x, y, @@ -47,6 +74,62 @@ public static void DrawRect(float x, float y, float w, float h, byte r = 255, by (int)r, (int)g, (int)b, (int)a }); } + + public static void DrawRect(float x, float y, float w, float h, Color color) { + DrawRect(x, y, w, h, color.R, color.G, color.B, color.A); + } + + public static void DrawRect(float x, float y, float w, float h, Color color, byte a) { + DrawRect(x, y, w, h, color.R, color.G, color.B, a); + } + + public static void Draw2DText(string text, Vector2 pos, Color color) { + Draw2DText(text, pos.X, pos.Y, color.R, color.G, color.B, color.A); + } + + public static void Draw2DText(string text, Vector3 pos, Color color) { + Draw2DText(text, Convert3dTo2d(pos), color); + } + public static void Draw2DText(string text, float x, float y, Color color) { + Draw2DText(text, x, y, color.R, color.G, color.B, color.A); + } + + public static void Draw2DText(string text, float x, float y, byte r = 255, byte g = 255, byte b = 255, byte a = 255) { + Function.Call(Hash.SET_TEXT_FONT, 0); + Function.Call(Hash.SET_TEXT_SCALE, 0.3f, 0.3f); + Function.Call(Hash.SET_TEXT_COLOUR, (int)r, (int)g, (int)b, (int)a); + Function.Call(Hash.SET_TEXT_CENTRE, 1); + Function.Call(Hash._SET_TEXT_ENTRY, "STRING"); + Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, text); + Function.Call(Hash._DRAW_TEXT, x, y); + } + + public static void Draw2DText(string text, float x, float y, Color color, byte a) { + Draw2DText(text, x, y, color.R, color.G, color.B, a); + } + +// public static void SetCameraRotation(Camera camera, Vector3 value) { +// InputArgument[] inputArgumentArray = new InputArgument[5]; +// InputArgument inputArgument1 = new InputArgument(camera.Handle); +// inputArgumentArray[0] = inputArgument1; +// InputArgument inputArgument2 = new InputArgument(value.X); +// inputArgumentArray[1] = inputArgument2; +// InputArgument inputArgument3 = new InputArgument(value.Y); +// inputArgumentArray[2] = inputArgument3; +// InputArgument inputArgument4 = new InputArgument(value.Z); +// inputArgumentArray[3] = inputArgument4; +// InputArgument inputArgument5 = new InputArgument(3); +// inputArgumentArray[4] = inputArgument5; +// Function.Call(Hash.SET_CAM_ROT, inputArgumentArray); +// } + + public static void SetNewWaypoint(Vector2 point) { + Function.Call(Hash.SET_NEW_WAYPOINT, point.X, point.Y); + } + + public static void PlaceObjectOnGroundProperly(Entity entity) { + Function.Call(Hash.PLACE_OBJECT_ON_GROUND_PROPERLY, entity); + } } } diff --git a/managed/GTAVisionUtils/ImageUtils.cs b/managed/GTAVisionUtils/ImageUtils.cs index e758707..e9a9342 100644 --- a/managed/GTAVisionUtils/ImageUtils.cs +++ b/managed/GTAVisionUtils/ImageUtils.cs @@ -37,79 +37,181 @@ public static void UploadToArchive(ZipArchive archive, string name, int w, int h List colors, byte[] depth, byte[] stencil) { var memstream = new MemoryStream(); - var tiff = Tiff.ClientOpen(name, "w", memstream, new TiffStream()); - WriteToTiff(tiff, w, h, colors, depth, stencil); - tiff.Flush(); - tiff.Close(); + WriteToTiff(name, w, h, colors, depth, stencil); var entry = archive.CreateEntry(name + ".tiff", CompressionLevel.NoCompression); var entryStream = entry.Open(); lastCapturedBytes = memstream.ToArray(); entryStream.Write(lastCapturedBytes, 0, lastCapturedBytes.Length); entryStream.Close(); - //tiff.Close(); memstream.Close(); + } + public static async void WriteToTiff(string name, int width, int height, List colors, byte[] depth, + byte[] stencil, bool oneFile = true) + { + await Task.Run(() => + { + try + { + Logger.WriteLine("writing to tiff"); + Logger.WriteLine($"name: {name}"); + WriteToTiffImpl(name, width, height, colors, depth, stencil, oneFile); + } + catch (Exception e) + { + Logger.WriteLine(e); + Logger.WriteLine($"name: {name}"); + Logger.WriteLine($"width: {width}"); + Logger.WriteLine($"height: {height}"); + Logger.WriteLine($"oneFile: {oneFile}"); + + if (e is ArgumentException) { +// probably some problem with tiff, logging info avout images + if (colors.Count == 1) { + Logger.WriteLine($"color size: {colors[0].Length}"); + } + else { + for (int i = 0; i < colors.Count; i++) { + Logger.WriteLine($"{i}-th color size: {colors[i].Length}"); + } + } + Logger.WriteLine($"depth size: {depth.Length}"); + Logger.WriteLine($"stencil size: {stencil.Length}"); + + } + Logger.ForceFlush(); + throw; + } + }); } - public static void WriteToTiff(Tiff t, int width, int height, List colors, byte[] depth, byte[] stencil) + public static void WriteToTiffImpl(string name, int width, int height, List colors, byte[] depth, + byte[] stencil, bool oneFile = true) { - var pages = colors.Count + 2; - var page = 0; - foreach (var color in colors) + if (oneFile) { + var t = Tiff.Open(name + ".tiff", "w"); + var pages = colors.Count + 2; + var page = 0; + foreach (var color in colors) + { + t.CreateDirectory(); + t.SetField(TiffTag.IMAGEWIDTH, width); + t.SetField(TiffTag.IMAGELENGTH, height); + t.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG); + t.SetField(TiffTag.SAMPLESPERPIXEL, 4); + t.SetField(TiffTag.ROWSPERSTRIP, height); + t.SetField(TiffTag.BITSPERSAMPLE, 8); + t.SetField(TiffTag.SUBFILETYPE, FileType.PAGE); + t.SetField(TiffTag.PHOTOMETRIC, Photometric.RGB); + t.SetField(TiffTag.COMPRESSION, Compression.JPEG); + t.SetField(TiffTag.JPEGQUALITY, 95); + t.SetField(TiffTag.PREDICTOR, Predictor.HORIZONTAL); + t.SetField(TiffTag.SAMPLEFORMAT, SampleFormat.UINT); + t.SetField(TiffTag.PAGENUMBER, page, pages); + t.WriteEncodedStrip(0, color, color.Length); + page++; + t.WriteDirectory(); + } + t.CreateDirectory(); + //page 2 t.SetField(TiffTag.IMAGEWIDTH, width); t.SetField(TiffTag.IMAGELENGTH, height); + t.SetField(TiffTag.ROWSPERSTRIP, height); t.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG); - t.SetField(TiffTag.SAMPLESPERPIXEL, 4); + t.SetField(TiffTag.SAMPLESPERPIXEL, 1); + t.SetField(TiffTag.BITSPERSAMPLE, 32); + t.SetField(TiffTag.SUBFILETYPE, FileType.PAGE); + t.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK); + t.SetField(TiffTag.COMPRESSION, Compression.LZW); + t.SetField(TiffTag.PREDICTOR, Predictor.FLOATINGPOINT); + t.SetField(TiffTag.SAMPLEFORMAT, SampleFormat.IEEEFP); + t.SetField(TiffTag.PAGENUMBER, page, pages); + t.WriteEncodedStrip(0, depth, depth.Length); + page++; + t.WriteDirectory(); + + t.SetField(TiffTag.IMAGEWIDTH, width); + t.SetField(TiffTag.IMAGELENGTH, height); t.SetField(TiffTag.ROWSPERSTRIP, height); + t.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG); + t.SetField(TiffTag.SAMPLESPERPIXEL, 1); t.SetField(TiffTag.BITSPERSAMPLE, 8); t.SetField(TiffTag.SUBFILETYPE, FileType.PAGE); - t.SetField(TiffTag.PHOTOMETRIC, Photometric.RGB); - t.SetField(TiffTag.COMPRESSION, Compression.JPEG); - t.SetField(TiffTag.JPEGQUALITY, 60); + t.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK); + t.SetField(TiffTag.COMPRESSION, Compression.LZW); t.SetField(TiffTag.PREDICTOR, Predictor.HORIZONTAL); t.SetField(TiffTag.SAMPLEFORMAT, SampleFormat.UINT); t.SetField(TiffTag.PAGENUMBER, page, pages); - t.WriteEncodedStrip(0, color, color.Length); - page++; + t.WriteEncodedStrip(0, stencil, stencil.Length); t.WriteDirectory(); + t.Flush(); + t.Close(); } - - t.CreateDirectory(); - //page 2 - t.SetField(TiffTag.IMAGEWIDTH, width); - t.SetField(TiffTag.IMAGELENGTH, height); - t.SetField(TiffTag.ROWSPERSTRIP, height); - t.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG); - t.SetField(TiffTag.SAMPLESPERPIXEL, 1); - t.SetField(TiffTag.BITSPERSAMPLE, 32); - t.SetField(TiffTag.SUBFILETYPE, FileType.PAGE); - t.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK); - t.SetField(TiffTag.COMPRESSION, Compression.LZW); - t.SetField(TiffTag.PREDICTOR, Predictor.FLOATINGPOINT); - t.SetField(TiffTag.SAMPLEFORMAT, SampleFormat.IEEEFP); - t.SetField(TiffTag.PAGENUMBER, page, pages); - t.WriteEncodedStrip(0, depth, depth.Length); - page++; - t.WriteDirectory(); + else + { + var t = Tiff.Open(name + ".tiff", "w"); + var pages = colors.Count; + var page = 0; + foreach (var color in colors) + { + t.CreateDirectory(); + t.SetField(TiffTag.IMAGEWIDTH, width); + t.SetField(TiffTag.IMAGELENGTH, height); + t.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG); + t.SetField(TiffTag.SAMPLESPERPIXEL, 4); + t.SetField(TiffTag.ROWSPERSTRIP, height); + t.SetField(TiffTag.BITSPERSAMPLE, 8); + t.SetField(TiffTag.SUBFILETYPE, FileType.PAGE); + t.SetField(TiffTag.PHOTOMETRIC, Photometric.RGB); +// t.SetField(TiffTag.COMPRESSION, Compression.LZW); // JPEG conversion caused ungly artifacts, making screenshots unusable for computer vision related tasks + t.SetField(TiffTag.COMPRESSION, Compression.JPEG); + t.SetField(TiffTag.JPEGQUALITY, 95); + t.SetField(TiffTag.PREDICTOR, Predictor.HORIZONTAL); + t.SetField(TiffTag.SAMPLEFORMAT, SampleFormat.UINT); + t.SetField(TiffTag.PAGENUMBER, page, pages); + t.WriteEncodedStrip(0, color, color.Length); + page++; + t.WriteDirectory(); + } + + t.Flush(); + t.Close(); - t.SetField(TiffTag.IMAGEWIDTH, width); - t.SetField(TiffTag.IMAGELENGTH, height); - t.SetField(TiffTag.ROWSPERSTRIP, height); - t.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG); - t.SetField(TiffTag.SAMPLESPERPIXEL, 1); - t.SetField(TiffTag.BITSPERSAMPLE, 8); - t.SetField(TiffTag.SUBFILETYPE, FileType.PAGE); - t.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK); - t.SetField(TiffTag.COMPRESSION, Compression.LZW); - t.SetField(TiffTag.PREDICTOR, Predictor.HORIZONTAL); - t.SetField(TiffTag.SAMPLEFORMAT, SampleFormat.UINT); - t.SetField(TiffTag.PAGENUMBER, page, pages); - t.WriteEncodedStrip(0, stencil, stencil.Length); - t.WriteDirectory(); - t.Flush(); + t = Tiff.Open(name + "-depth.tiff", "w"); + t.SetField(TiffTag.IMAGEWIDTH, width); + t.SetField(TiffTag.IMAGELENGTH, height); + t.SetField(TiffTag.ROWSPERSTRIP, height); + t.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG); + t.SetField(TiffTag.SAMPLESPERPIXEL, 1); + t.SetField(TiffTag.BITSPERSAMPLE, 32); + t.SetField(TiffTag.SUBFILETYPE, FileType.PAGE); + t.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK); + t.SetField(TiffTag.COMPRESSION, Compression.LZW); + t.SetField(TiffTag.PREDICTOR, Predictor.FLOATINGPOINT); + t.SetField(TiffTag.SAMPLEFORMAT, SampleFormat.IEEEFP); + t.WriteEncodedStrip(0, depth, depth.Length); + + t.Flush(); + t.Close(); + + t = Tiff.Open(name + "-stencil.tiff", "w"); + t.SetField(TiffTag.IMAGEWIDTH, width); + t.SetField(TiffTag.IMAGELENGTH, height); + t.SetField(TiffTag.ROWSPERSTRIP, height); + t.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG); + t.SetField(TiffTag.SAMPLESPERPIXEL, 1); + t.SetField(TiffTag.BITSPERSAMPLE, 8); + t.SetField(TiffTag.SUBFILETYPE, FileType.PAGE); + t.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK); + t.SetField(TiffTag.COMPRESSION, Compression.LZW); + t.SetField(TiffTag.PREDICTOR, Predictor.HORIZONTAL); + t.SetField(TiffTag.SAMPLEFORMAT, SampleFormat.UINT); + t.WriteEncodedStrip(0, stencil, stencil.Length); + t.Flush(); + t.Close(); + } } - } -} +} \ No newline at end of file diff --git a/managed/GTAVisionUtils/Logger.cs b/managed/GTAVisionUtils/Logger.cs new file mode 100644 index 0000000..b39c226 --- /dev/null +++ b/managed/GTAVisionUtils/Logger.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BitMiracle.LibTiff.Classic; + +namespace GTAVisionUtils { + public class Logger { + + //most code taken from https://github.com/dbaaron/log-writer + private static Queue LogQueue = new Queue(); + public static string logFilePath { private get; set; } + public static int FlushAfterSeconds = 5; + public static int FlushAtQty = 10; + private static DateTime FlushedAt = DateTime.Now; + + public static void ForceFlush() + { + FlushLogToFile(); + } + + private static bool CheckTimeToFlush() + { + var time = DateTime.Now - FlushedAt; + if (time.TotalSeconds >= FlushAfterSeconds) + { + FlushedAt = DateTime.Now; + return true; + } + return false; + } + + private static void FlushLogToFile() + { + while (LogQueue.Count > 0) + { + + // Get entry to log + var entry = LogQueue.Dequeue(); + + // Crete filestream + var stream = new FileStream(logFilePath, FileMode.Append, FileAccess.Write); + using (var writer = new StreamWriter(stream)) + { + // Log to file + writer.Write(entry); + } + } + } + + private static string WrapLogMessage(string message) { + const string dateTimeFormat = @"yyyy-MM-dd--HH-mm-ss"; + return $"{DateTime.UtcNow.ToString(dateTimeFormat)}: {message}\r\n"; + } + + public static void WriteLine(string line) { + lock (LogQueue) + { + + // Create log + LogQueue.Enqueue(WrapLogMessage(line)); + + // Check if should flush + if (LogQueue.Count >= FlushAtQty || CheckTimeToFlush()) + { + FlushLogToFile(); + } + + } + } + + public static void WriteLine(Exception e) { + WriteLine(e.Message); + WriteLine(e.Source); + WriteLine(e.StackTrace); + } + + public static void WriteLine(object value) { + if (value == null) { + return; + } + + WriteLine(value.ToString()); + } + } +} \ No newline at end of file diff --git a/managed/GTAVisionUtils/MathUtils.cs b/managed/GTAVisionUtils/MathUtils.cs new file mode 100644 index 0000000..f6507b5 --- /dev/null +++ b/managed/GTAVisionUtils/MathUtils.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; + +namespace GTAVisionUtils { + public class MathUtils { + public static List cumsum(List arr) { + var cumsumArr = new List(arr.Count); + double sum = 0; + for (int i = 0; i < arr.Count; i++) { + sum += arr[i]; + cumsumArr[i] = sum; + } + + return cumsumArr; + } + + public static List cumsum(List arr) { + var cumsumArr = new List(arr.Count); + float sum = 0; + for (int i = 0; i < arr.Count; i++) { + sum += arr[i]; + cumsumArr[i] = sum; + } + + return cumsumArr; + } + + public static List cumsum(List arr) { + var cumsumArr = new List(arr.Count); + int sum = 0; + for (int i = 0; i < arr.Count; i++) { + sum += arr[i]; + cumsumArr.Add(sum); + } + + return cumsumArr; + } + + /// + /// Returns index of bin from cumulative sum array, same functionality as in numpy.digitize + /// + /// + public static int digitize(int number, List cumsumArr) { + for (int i = 0; i < cumsumArr.Count; i++) { + if (number < cumsumArr[i]) { + return i; + } + } + + throw new Exception("number is out of range of cumcum array"); + } + + } +} \ No newline at end of file diff --git a/managed/GTAVisionUtils/PostgresExport.cs b/managed/GTAVisionUtils/PostgresExport.cs index d450911..5bb501d 100644 --- a/managed/GTAVisionUtils/PostgresExport.cs +++ b/managed/GTAVisionUtils/PostgresExport.cs @@ -14,36 +14,32 @@ using NpgsqlTypes; using System.Reflection; using IniParser; + namespace GTAVisionUtils { - public class PostgresExport { - - public static void InitSQLTypes() - { + public static void InitSQLTypes() { NpgsqlConnection.MapEnumGlobally("weather", new NpgsqlNullNameTranslator()); NpgsqlConnection.MapEnumGlobally(); - NpgsqlConnection.MapEnumGlobally(pgName: "detection_class", nameTranslator: new NpgsqlNullNameTranslator()); + NpgsqlConnection.MapEnumGlobally(pgName: "detection_class", + nameTranslator: new NpgsqlNullNameTranslator()); } - - public static NpgsqlConnection OpenConnection() - { + + public static NpgsqlConnection OpenConnection() { var parser = new FileIniDataParser(); var location = AppDomain.CurrentDomain.BaseDirectory; var data = parser.ReadFile(Path.Combine(location, "GTAVision.ini")); //UI.Notify(ConfigurationManager.AppSettings["database_connection"]); var str = data["Database"]["ConnectionString"]; - + var conn = new NpgsqlConnection(str); conn.Open(); return conn; } - public static Guid InsertSystemData(NpgsqlConnection conn) - { + public static Guid InsertSystemData(NpgsqlConnection conn) { var systemInfo = new WMIInformation(); - using (var cmd = new NpgsqlCommand()) - { + using (var cmd = new NpgsqlCommand()) { cmd.Connection = conn; cmd.Parameters.AddWithValue("@system_uuid", systemInfo.system_uuid); cmd.Parameters.AddWithValue("@vendor", systemInfo.vendor); @@ -58,156 +54,201 @@ public static Guid InsertSystemData(NpgsqlConnection conn) return Guid.Parse(cmd.ExecuteScalar().ToString()); } } - - public static int InsertInstanceData(NpgsqlConnection conn) - { - + + public static int InsertInstanceData(NpgsqlConnection conn) { var instanceinfo = new InstanceData(); - using (var cmd = new NpgsqlCommand()) - { + using (var cmd = new NpgsqlCommand()) { cmd.Connection = conn; - + cmd.Parameters.AddWithValue("@host", System.Environment.MachineName); cmd.Parameters.AddWithValue("@iid", DBNull.Value); cmd.Parameters.AddWithValue("@typ", instanceinfo.type); cmd.Parameters.AddWithValue("@pubhost", DBNull.Value); cmd.Parameters.AddWithValue("@amiid", DBNull.Value); - - if (instanceinfo.type != "LOCALHOST") - { + + if (instanceinfo.type != "LOCALHOST") { cmd.Parameters.AddWithValue("@host", instanceinfo.hostname); cmd.Parameters.AddWithValue("@iid", instanceinfo.instanceid); cmd.Parameters.AddWithValue("@typ", instanceinfo.type); cmd.Parameters.AddWithValue("@pubhost", instanceinfo.publichostname); cmd.Parameters.AddWithValue("@amiid", instanceinfo.amiid); } + cmd.CommandText = "SELECT instance_id FROM instances WHERE hostname=@host AND instancetype=@typ AND instanceid=@iid AND amiid=@amiid AND publichostname=@pubhost"; var id = cmd.ExecuteScalar(); - if (id == null) - { + if (id == null) { cmd.CommandText = - "INSERT INTO instances (hostname, instanceid, instancetype, publichostname, amiid) VALUES (@host, @iid, @typ, @pubhost, @amiid) " + - "RETURNING instance_id"; + "INSERT INTO instances (hostname, instanceid, instancetype, publichostname, amiid) VALUES (@host, @iid, @typ, @pubhost, @amiid) " + + "RETURNING instance_id"; return (int) cmd.ExecuteScalar(); } return (int) id; - } } - public static async Task StartSession(string name) - { + public static async Task StartSession(string name) { return await Task.Run(() => StartSessionImpl(name)); } - public static int StartSessionImpl(string name) - { + + public static int StartSessionImpl(string name) { var conn = OpenConnection(); int result = 0; //int instance = InsertInstanceData(conn); - using (var cmd = new NpgsqlCommand()) - { - + using (var cmd = new NpgsqlCommand()) { cmd.Connection = conn; cmd.CommandText = "INSERT INTO sessions (name, start) VALUES (@name, @start) ON CONFLICT DO NOTHING"; cmd.Parameters.AddWithValue("@name", name); cmd.Parameters.AddWithValue("@start", DateTime.UtcNow); cmd.ExecuteNonQuery(); cmd.CommandText = "SELECT session_id FROM sessions WHERE name = @name"; - result = (int)cmd.ExecuteScalar(); + result = (int) cmd.ExecuteScalar(); } + conn.Close(); return result; } - public static async Task StopSession(int sessionid) - { + public static async Task StopSession(int sessionid) { await Task.Run(() => StopSessionImpl(sessionid)); } - public static void StopSessionImpl(int sessionid) - { + + public static void StopSessionImpl(int sessionid) { var conn = OpenConnection(); - using (var cmd = new NpgsqlCommand()) - { + using (var cmd = new NpgsqlCommand()) { cmd.Connection = conn; cmd.CommandText = @"UPDATE sessions SET ""end"" = @endtime WHERE session_id = @sessionid"; cmd.Parameters.AddWithValue("@endtime", DateTime.UtcNow); cmd.Parameters.AddWithValue("@sessionid", sessionid); cmd.ExecuteNonQuery(); } + conn.Close(); } - public static async Task StartRun(int sessionid) - { + public static async Task StartRun(int sessionid) { var t = Task.Run(() => StartRunImpl(sessionid)); return await t; } - public static GTARun StartRunImpl(int sessionid) - { + + public static GTARun StartRunImpl(int sessionid) { var run = new GTARun(); run.guid = Guid.NewGuid(); run.archiveKey = Path.Combine("images", run.guid + ".zip"); var conn = OpenConnection(); int instanceid = InsertInstanceData(conn); InsertSystemData(conn); - using (var cmd = new NpgsqlCommand()) - { + using (var cmd = new NpgsqlCommand()) { cmd.Connection = conn; - cmd.CommandText = "INSERT INTO runs (runguid, archivepath, session_id, instance_id) VALUES (@guid, @archivekey, @session, @instance);"; + cmd.CommandText = + "INSERT INTO runs (runguid, archivepath, session_id, instance_id) VALUES (@guid, @archivekey, @session, @instance);"; cmd.Parameters.AddWithValue("@guid", run.guid); cmd.Parameters.AddWithValue("@archivekey", run.archiveKey); cmd.Parameters.AddWithValue("@session", sessionid); cmd.Parameters.AddWithValue("@instance", instanceid); cmd.ExecuteNonQuery(); } + conn.Close(); - + return run; } - public static void StopRun(GTARun run) - { + public static void StopRun(GTARun run) { } - public static async void SaveSnapshot(GTAData data, Guid runId) - { + public static async void SaveSnapshot(GTAData data, Guid runId) { await Task.Run(() => SaveSnapshotImpl(data, runId)); } - - public static void SaveSnapshotImpl(GTAData data, Guid runId) - { + + public static void SaveSnapshotImpl(GTAData data, Guid runId) { var conn = OpenConnection(); var trans = conn.BeginTransaction(); - using (NpgsqlCommand cmd = new NpgsqlCommand()) - { - + + using (NpgsqlCommand cmd = new NpgsqlCommand()) { + var camRelativeRotString = "NULL"; + if (data.CamRelativeRot != null) { + camRelativeRotString = "ST_MakePoint(@relative_rot_x, @relative_rot_y, @relative_rot_z)"; + cmd.Parameters.AddWithValue("@relative_rot_x", data.CamRelativeRot.X); + cmd.Parameters.AddWithValue("@relative_rot_y", data.CamRelativeRot.Y); + cmd.Parameters.AddWithValue("@relative_rot_z", data.CamRelativeRot.Z); + } + + var camRelativePosString = "NULL"; + if (data.CamRelativePos != null) { + camRelativePosString = "ST_MakePoint(@relative_pos_x, @relative_pos_y, @relative_pos_z)"; + cmd.Parameters.AddWithValue("@relative_pos_x", data.CamRelativePos.X); + cmd.Parameters.AddWithValue("@relative_pos_y", data.CamRelativePos.Y); + cmd.Parameters.AddWithValue("@relative_pos_z", data.CamRelativePos.Z); + } + + var carModelBoxString = "NULL"; + if (data.CarModelBox != null) { + carModelBoxString = "ST_3DMakeBox(ST_MakePoint(@cam_box_min_x, @cam_box_min_y, @cam_box_min_z), " + + "ST_MakePoint(@cam_box_max_x, @cam_box_max_y, @cam_box_max_z))"; + cmd.Parameters.AddWithValue("@cam_box_min_x", data.CarModelBox.Minimum.X); + cmd.Parameters.AddWithValue("@cam_box_min_y", data.CarModelBox.Minimum.Y); + cmd.Parameters.AddWithValue("@cam_box_min_z", data.CarModelBox.Minimum.Z); + cmd.Parameters.AddWithValue("@cam_box_max_x", data.CarModelBox.Maximum.X); + cmd.Parameters.AddWithValue("@cam_box_max_y", data.CarModelBox.Maximum.Y); + cmd.Parameters.AddWithValue("@cam_box_max_z", data.CarModelBox.Maximum.Z); + } + + var currentTarget = "NULL"; + if (data.CurrentTarget != null) { + currentTarget = "ST_MakePoint(@target_x, @target_y)"; + cmd.Parameters.AddWithValue("@target_x", data.CurrentTarget.X); + cmd.Parameters.AddWithValue("@target_y", data.CurrentTarget.Y); + } + cmd.Connection = conn; cmd.Transaction = trans; cmd.CommandText = - "INSERT INTO snapshots (run_id, version, imagepath, timestamp, timeofday, currentweather, camera_pos, camera_direction, camera_fov, view_matrix, proj_matrix, width, height) " + - "VALUES ( (SELECT run_id FROM runs WHERE runguid=@guid), " + - "@Version, @Imagepath, @Timestamp, @Timeofday, @currentweather, ST_MakePoint(@x, @y, @z), ST_MakePoint(@dirx, @diry, @dirz), @fov, @view_matrix, @proj_matrix, @width, @height ) " + - "RETURNING snapshot_id;"; + $"INSERT INTO snapshots (run_id, version, imagepath, timestamp, timeofday, currentweather, camera_pos, " + + $"camera_rot, camera_direction, camera_fov, view_matrix, proj_matrix, width, height, ui_width, ui_height, " + + $"player_pos, cam_near_clip, cam_far_clip, velocity, scene_id, camera_relative_rotation, " + + $"camera_relative_position, car_model_box, world_matrix, current_target) VALUES ( (SELECT run_id FROM runs WHERE " + + $"runguid=@guid), @Version, @Imagepath, @Timestamp, @Timeofday, @currentweather, ST_MakePoint(@x, @y, @z), " + + $"ST_MakePoint(@rotx, @roty, @rotz), ST_MakePoint(@dirx, @diry, @dirz), @fov, @view_matrix, @proj_matrix, " + + $"@width, @height, @ui_width, @ui_height, ST_MakePoint(@player_x, @player_y, @player_z), @cam_near_clip, " + + $"@cam_far_clip, ST_MakePoint(@vel_x, @vel_y, @vel_z), @scene_id, {camRelativeRotString}, " + + $"{camRelativePosString}, {carModelBoxString}, @world_matrix, {currentTarget}) RETURNING snapshot_id;"; cmd.Parameters.Add(new NpgsqlParameter("@version", data.Version)); cmd.Parameters.Add(new NpgsqlParameter("@imagepath", data.ImageName)); cmd.Parameters.Add(new NpgsqlParameter("@timestamp", data.Timestamp)); cmd.Parameters.Add(new NpgsqlParameter("@timeofday", data.LocalTime)); cmd.Parameters.Add(new NpgsqlParameter("@currentweather", data.CurrentWeather)); - cmd.Parameters.Add(new NpgsqlParameter("@x", data.Pos.X)); - cmd.Parameters.Add(new NpgsqlParameter("@y", data.Pos.Y)); - cmd.Parameters.Add(new NpgsqlParameter("@z", data.Pos.Z)); + cmd.Parameters.Add(new NpgsqlParameter("@x", data.CamPos.X)); + cmd.Parameters.Add(new NpgsqlParameter("@y", data.CamPos.Y)); + cmd.Parameters.Add(new NpgsqlParameter("@z", data.CamPos.Z)); + cmd.Parameters.Add(new NpgsqlParameter("@rotx", data.CamRot.X)); + cmd.Parameters.Add(new NpgsqlParameter("@roty", data.CamRot.Y)); + cmd.Parameters.Add(new NpgsqlParameter("@rotz", data.CamRot.Z)); cmd.Parameters.AddWithValue("@dirx", data.CamDirection.X); cmd.Parameters.AddWithValue("@diry", data.CamDirection.Y); cmd.Parameters.AddWithValue("@dirz", data.CamDirection.Z); cmd.Parameters.AddWithValue("@fov", data.CamFOV); cmd.Parameters.AddWithValue("@view_matrix", data.ViewMatrix.ToArray()); cmd.Parameters.AddWithValue("@proj_matrix", data.ProjectionMatrix.ToArray()); + cmd.Parameters.AddWithValue("@world_matrix", data.WorldMatrix.ToArray()); cmd.Parameters.AddWithValue("@width", data.ImageWidth); cmd.Parameters.AddWithValue("@height", data.ImageHeight); +// @ui_width, @ui_height, @player_pos, @cam_near_clip, @cam_far_clip + cmd.Parameters.AddWithValue("@ui_width", data.UIWidth); + cmd.Parameters.AddWithValue("@ui_height", data.UIHeight); + cmd.Parameters.AddWithValue("@player_x", data.playerPos.X); + cmd.Parameters.AddWithValue("@player_y", data.playerPos.Y); + cmd.Parameters.AddWithValue("@player_z", data.playerPos.Z); + cmd.Parameters.AddWithValue("@vel_x", data.velocity.X); + cmd.Parameters.AddWithValue("@vel_y", data.velocity.Y); + cmd.Parameters.AddWithValue("@vel_z", data.velocity.Z); + cmd.Parameters.AddWithValue("@cam_near_clip", data.CamNearClip); + cmd.Parameters.AddWithValue("@cam_far_clip", data.CamFarClip); + cmd.Parameters.AddWithValue("@scene_id", data.sceneGuid); + cmd.Parameters.Add(new NpgsqlParameter("@guid", runId)); - int snapshotid = (int)cmd.ExecuteScalar(); + int snapshotid = (int) cmd.ExecuteScalar(); cmd.Parameters.Clear(); cmd.CommandText = "INSERT INTO snapshot_weathers (snapshot_id, weather_type, snapshot_page) VALUES (@snapshot, @weather, @page);"; @@ -215,8 +256,7 @@ public static void SaveSnapshotImpl(GTAData data, Guid runId) cmd.Parameters.AddWithValue("@weather", NpgsqlDbType.Enum, Weather.Unknown); cmd.Parameters.Add("@page", NpgsqlDbType.Integer); cmd.Prepare(); - for (int i = 0; i < data.CapturedWeathers.Count; ++i) - { + for (int i = 0; i < data.CapturedWeathers.Count; ++i) { cmd.Parameters["@weather"].Value = data.CapturedWeathers[i]; cmd.Parameters["@page"].Value = i; cmd.ExecuteNonQuery(); @@ -238,17 +278,19 @@ public static void SaveSnapshotImpl(GTAData data, Guid runId) cmd.Parameters.Add("@maxx", NpgsqlDbType.Real); cmd.Parameters.Add("@maxy", NpgsqlDbType.Real); cmd.Parameters.Add("@maxz", NpgsqlDbType.Real); + cmd.Parameters.Add("@vel_x", NpgsqlDbType.Real); + cmd.Parameters.Add("@vel_y", NpgsqlDbType.Real); + cmd.Parameters.Add("@vel_z", NpgsqlDbType.Real); cmd.Parameters.AddWithValue("@class", NpgsqlDbType.Enum, DetectionClass.Unknown); cmd.Parameters.Add("@handle", NpgsqlDbType.Integer); cmd.CommandText = - "INSERT INTO detections (snapshot_id, type, pos, rot, bbox, class, handle, bbox3d) VALUES " + + "INSERT INTO detections (snapshot_id, type, pos, rot, bbox, class, handle, bbox3d, velocity) VALUES " + "(@snapshot, @type, ST_MakePoint(@x,@y,@z), ST_MakePoint(@xrot, @yrot, @zrot), @bbox, @class, @handle," + - "ST_3DMakeBox(ST_MakePoint(@minx,@miny,@minz), ST_MakePoint(@maxx, @maxy, @maxz)));"; + "ST_3DMakeBox(ST_MakePoint(@minx,@miny,@minz), ST_MakePoint(@maxx, @maxy, @maxz)), ST_MakePoint(@vel_x, @vel_y, @vel_z))"; cmd.Prepare(); - - + + foreach (var detection in data.Detections) { - cmd.Parameters["@snapshot"].Value = snapshotid; cmd.Parameters["@type"].Value = detection.Type; cmd.Parameters["@x"].Value = detection.Pos.X; @@ -258,7 +300,8 @@ public static void SaveSnapshotImpl(GTAData data, Guid runId) cmd.Parameters["@yrot"].Value = detection.Rot.Y; cmd.Parameters["@zrot"].Value = detection.Rot.Z; cmd.Parameters["@bbox"].Value = - new NpgsqlBox(detection.BBox.Max.Y, detection.BBox.Max.X, detection.BBox.Min.Y, detection.BBox.Min.X); + new NpgsqlBox(detection.BBox.Max.Y, detection.BBox.Max.X, detection.BBox.Min.Y, + detection.BBox.Min.X); cmd.Parameters["@class"].Value = detection.cls; cmd.Parameters["@handle"].Value = detection.Handle; cmd.Parameters["@minx"].Value = detection.BBox3D.Minimum.X; @@ -269,12 +312,16 @@ public static void SaveSnapshotImpl(GTAData data, Guid runId) cmd.Parameters["@maxy"].Value = detection.BBox3D.Maximum.Y; cmd.Parameters["@maxz"].Value = detection.BBox3D.Maximum.Z; + cmd.Parameters["@vel_x"].Value = detection.velocity.X; + cmd.Parameters["@vel_y"].Value = detection.velocity.Y; + cmd.Parameters["@vel_z"].Value = detection.velocity.Z; + cmd.ExecuteNonQuery(); } } + trans.Commit(); conn.Close(); } } - -} +} \ No newline at end of file diff --git a/managed/GTAVisionUtils/packages.config b/managed/GTAVisionUtils/packages.config index fdbd910..33e327c 100644 --- a/managed/GTAVisionUtils/packages.config +++ b/managed/GTAVisionUtils/packages.config @@ -12,6 +12,7 @@ + diff --git a/managed/README.md b/managed/README.md index 96fffcb..65aed2c 100644 --- a/managed/README.md +++ b/managed/README.md @@ -60,7 +60,8 @@ create table detections bbox3d box3d, rot geometry, coverage real default 0.0, - created timestamp without time zone default (now() at time zone 'utc') + created timestamp without time zone default (now() at time zone 'utc'), + velocity GEOMETRY(PointZ) ) ; @@ -107,21 +108,30 @@ create table snapshots primary key, run_id integer constraint snapshots_run_fkey - references runs - on delete cascade, + references runs, version integer, + scene_id uuid, imagepath text, timestamp timestamp with time zone, timeofday time, currentweather weather, camera_pos geometry(PointZ), + camera_rot geometry(PointZ), + camera_relative_rotation geometry(PointZ), camera_direction geometry, camera_fov real, + world_matrix double precision[], view_matrix double precision[], proj_matrix double precision[], processed boolean default false not null, width integer, - height integer + height integer, + ui_width integer, + ui_height integer, + cam_near_clip real, + cam_far_clip real, + player_pos GEOMETRY(PointZ), + velocity GEOMETRY(PointZ) ) ; @@ -240,12 +250,99 @@ create table system_graphics ; +-- +-- Name: ngv_box3dmultipoint(box3d); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION ngv_box3dmultipoint(box3d) RETURNS geometry + LANGUAGE sql + AS $_$ select ST_Multi(ST_Collect(ST_MakePoint(ST_XMin($1), ST_YMin($1), ST_ZMin($1)), ST_MakePoint(ST_XMax($1), ST_YMax($1), ST_ZMax($1)))) $_$; + + +-- +-- Name: ngv_box3dpolygon(box3d); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION ngv_box3dpolygon(box3d) RETURNS geometry + LANGUAGE sql + AS $_$ +SELECT ST_Collect(ARRAY[ + ST_MakePoint(ST_XMin($1), ST_YMin($1), ST_ZMin($1)), + ST_MakePoint(ST_XMax($1), ST_YMin($1), ST_ZMin($1)), + ST_MakePoint(ST_XMax($1), ST_YMax($1), ST_ZMin($1)), + ST_MakePoint(ST_XMin($1), ST_YMax($1), ST_ZMin($1)), + ST_MakePoint(ST_XMin($1), ST_YMin($1), ST_ZMax($1)), + ST_MakePoint(ST_XMax($1), ST_YMin($1), ST_ZMax($1)), + ST_MakePoint(ST_XMax($1), ST_YMax($1), ST_ZMax($1)), + ST_MakePoint(ST_XMin($1), ST_YMax($1), ST_ZMax($1))]) +$_$; + + +-- +-- Name: ngv_contract(box, integer, integer); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION ngv_contract(bbox box, width integer, height integer) RETURNS box + LANGUAGE sql + AS $$ + select box(point((bbox[0])[0] / width, (bbox[0])[1] / height), point((bbox[1])[0] / width, (bbox[1])[1] / height)); +$$; + + +-- +-- Name: ngv_expand(box, integer, integer); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION ngv_expand(bbox box, width integer, height integer) RETURNS box + LANGUAGE sql + AS $$ + select box(point((bbox[0])[0] * width, (bbox[0])[1] * height), point((bbox[1])[0] * width, (bbox[1])[1] * height)); +$$; + + +-- +-- Name: ngv_get_bytes(integer); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION ngv_get_bytes(id integer) RETURNS bytea + LANGUAGE sql + AS $$ +SELECT ngv_get_bytes(localpath, imagepath) FROM snapshots JOIN runs USING(run_id) where snapshot_id=id +$$; + + +-- +-- Name: ngv_get_raster(text, text); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION ngv_get_raster(archive text, image text) RETURNS raster + LANGUAGE plpgsql + AS $$ +BEGIN + RETURN ST_FromGDALRaster(ngv_get_bytes(archive, image)); +END; +$$; + +-- we often ask for all entities for single snapshot, this index makes querying like 20x faster +CREATE INDEX snapshot_index ON detections (snapshot_id); + +-- so we see nicely even postgis objects +CREATE VIEW snapshots_view AS + SELECT snapshot_id, run_id, version, scene_id, imagepath, timestamp, timeofday, currentweather, + ARRAY[st_x(camera_pos), st_y(camera_pos), st_z(camera_pos)] AS camera_pos, + ARRAY[st_x(camera_rot), st_y(camera_rot), st_z(camera_rot)] AS camera_rot, + ARRAY[st_x(camera_relative_rotation), st_y(camera_relative_rotation), st_z(camera_relative_rotation)] AS camera_relative_rotation, + ARRAY[st_x(camera_relative_position), st_y(camera_relative_position), st_z(camera_relative_position)] AS camera_relative_position, + ARRAY[st_x(camera_direction), st_y(camera_direction), st_z(camera_direction)] AS camera_direction, + camera_fov, world_matrix, view_matrix, proj_matrix, processed, width, height, ui_width, ui_height, cam_near_clip, cam_far_clip, + ARRAY[st_x(player_pos), st_y(player_pos), st_z(player_pos)] AS player_pos, + ARRAY[st_x(velocity), st_y(velocity), st_z(velocity)] AS velocity + FROM snapshots; ``` ## Copying compiled files to GTA V After you compile the GTAVisionExport, copy compiled files from the `path to GTAVisionExport/managed/GTAVisionExport/bin/Release` to `path to GTA V/scripts`. Content of `scripts` directory should be following: -- AWSSDK.dll - BitMiracle.LibTiff.NET.dll - BitMiracle.LibTiff.NET.xml - gdal_csharp.dll @@ -294,6 +391,11 @@ To verify all plugins loaded, see the `ScriptHookVDotNet2.log` and search for th If less than 10 scripts loaded, you have problem. +If you have `ScriptHookVDotNet2.dll` in the scripts directory, you need to remove it. + +If only 1 script is loaded (NativeUI), it can be solved by removing `YamlDotNet.pdb` from your scripts dir. +You should not have any .pdb files except of your own dlls (`GTAVisionExport.pdb` and `GTAVisionUtils.pdb`) + ## Usage ### Dependencies setup @@ -316,7 +418,7 @@ Turn NativeUI notifications off by pressing "X" in the game. In settings, set up these things: - In Camera - - set First Person Velicle Hood to On + - set First Person Vehicle Hood to On - In Display - set Radar to Off - set HUD to Off @@ -335,4 +437,24 @@ There is either manual or automatic way. It contains python HTTP server with buttons to control the managed plugin. It connects to the socket server inside the managed plugin. When the main script starts, you can click the "START_SESSION" button and then it creates new car and starts - driving autonomously and grabbing screenshots automatically. \ No newline at end of file + driving autonomously and grabbing screenshots automatically. + +### Other notes +Data gathering, specifically grabbing data from GPU buffers, breaks when using multiple monitors, data gathering must run only on one monitor. + +### Downgrading the GTA V Steam version +Your version of GTA V can be higher than your shvdn can manage, and in that case, this error pops up and game crashes: +Here is tutorial for it: +https://www.youtube.com/watch?v=7HWOGLtV7Ig +Link for files needed to download is: +https://mega.nz/#!Z7RVUDzb!jtWcn0sQxM7Er4pR83mDG3jFDJ49QkA_7SO9aFckawY +if the link is dead, just write me and I'll upload files somewhere and share them with you. + +Basically: +setup the update frequency in steam to updating before launch (all other options are automatic updates, which you don't want) +The only files being changed during updates are: +GTA5.exe +GTAVLauncher.exe +update/update.rpf + +So simply backup these files, just to be sure, and replace them by their older versions. diff --git a/managed/Sandbox/MainClass.cs b/managed/Sandbox/MainClass.cs new file mode 100644 index 0000000..752cc57 --- /dev/null +++ b/managed/Sandbox/MainClass.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.PerformanceData; +using System.IO; +using System.Linq; +using System.Management; +using System.Threading.Tasks; +using GTAVisionUtils; +using IniParser; +using Newtonsoft.Json; +using Npgsql; +using Npgsql.NameTranslation; +using NpgsqlTypes; + +namespace Sandbox +{ + public class WMIGraphicsInformation + { + public string deviceId; + public string AdapterCompat; + public string AdapterDACType; + public string AdapterRAM; + public int Availability; + public string Caption; + public string Description; + public DateTime DriverDate; + public string DriverVersion; + public string PnPDeviceId; + public string name; + public string VideoArch; + public string MemType; + public string VideoProcessor; + public string bpp; + public string hrez; + public string vrez; + public string num_colors; + public string cols; + public string rows; + public string refresh; + public string scanMode; + public string videoModeDesc; + + public WMIGraphicsInformation(ManagementBaseObject from) + { + deviceId = from.GetPropertyValue("DeviceID") as string; + AdapterCompat = from.GetPropertyValue("AdapterCompatibility") as string; + AdapterDACType = from.GetPropertyValue("AdapterDACType") as string; + AdapterRAM = from.GetPropertyValue("AdapterRAM") as string; + Caption = from.GetPropertyValue("Caption") as string; + DriverVersion = from.GetPropertyValue("DriverVersion") as string; + DriverDate = ManagementDateTimeConverter.ToDateTime( from.GetPropertyValue("DriverDate") as string); + VideoProcessor = from.GetPropertyValue("VideoProcessor") as string; + name = from.GetPropertyValue("Name") as string; + + } + } +// public class WMIInformation +// { +// public Guid system_uuid; +// public string vendor; +// public string dnshostname; +// public string username; +// public string systemtype; +// public UInt64 totalmem; +// public List gfxCards; +// /// +// /// gets wmi info for the current computer +// /// +// public WMIInformation() +// { +// var scope = new ManagementScope("ROOT\\CIMV2"); +// var genQuery = new ObjectQuery("SELECT * FROM Win32_ComputerSystem"); +// var result = new ManagementObjectSearcher(scope, genQuery).Get().Cast(); +// dnshostname = result.First().GetPropertyValue("DNSHostName") as string; +// username = result.First().GetPropertyValue("UserName") as string; +// systemtype = result.First().GetPropertyValue("SystemType") as string; +// totalmem = (UInt64) result.First().GetPropertyValue("TotalPhysicalMemory"); +// var prodQuery = new ObjectQuery("SELECT * FROM Win32_ComputerSystemProduct"); +// result = new ManagementObjectSearcher(scope, prodQuery).Get().Cast(); +// system_uuid = Guid.Parse( result.First().GetPropertyValue("UUID") as string); +// vendor = result.First().GetPropertyValue("Vendor") as string; +// +// var videoQuery = new ObjectQuery("SELECT * FROM Win32_VideoController"); +// result = new ManagementObjectSearcher(scope, videoQuery).Get().Cast(); +// gfxCards = new List(); +// foreach (var obj in result) +// { +// gfxCards.Add(new WMIGraphicsInformation(obj)); +// } +// +// } +// } + + public enum DetectionType + { + background, + person, + car, + bicycle + } + + public enum DetectionClass + { + Unknown = -1, + Compacts = 0, + Sedans = 1, + SUVs = 2, + Coupes = 3, + Muscle = 4, + SportsClassics = 5, + Sports = 6, + Super = 7, + Motorcycles = 8, + OffRoad = 9, + Industrial = 10, + Utility = 11, + Vans = 12, + Cycles = 13, + Boats = 14, + Helicopters = 15, + Planes = 16, + Service = 17, + Emergency = 18, + Military = 19, + Commercial = 20, + Trains = 21 + } + + public enum Weather + { + Unknown = -1, + ExtraSunny = 0, + Clear = 1, + Clouds = 2, + Smog = 3, + Foggy = 4, + Overcast = 5, + Raining = 6, + ThunderStorm = 7, + Clearing = 8, + Neutral = 9, + Snowing = 10, + Blizzard = 11, + Snowlight = 12, + Christmas = 13, + Halloween = 14, + } + + public class MainClass + { + public static void InitSQLTypes() + { + NpgsqlConnection.MapEnumGlobally("weather", new NpgsqlNullNameTranslator()); + NpgsqlConnection.MapEnumGlobally(); + NpgsqlConnection.MapEnumGlobally(pgName: "detection_class", + nameTranslator: new NpgsqlNullNameTranslator()); + } + + public static NpgsqlConnection OpenConnection() + { + var parser = new FileIniDataParser(); + var location = @"D:\Program Files\Rockstar Games\Grand Theft Auto V\scripts"; + var data = parser.ReadFile(Path.Combine(location, "GTAVision.ini")); + + //UI.Notify(ConfigurationManager.AppSettings["database_connection"]); + var str = data["Database"]["ConnectionString"]; + + var conn = new NpgsqlConnection(str); + conn.Open(); + return conn; + } + + public static void InsertEnum() + { + var conn = OpenConnection(); + var trans = conn.BeginTransaction(); + using (NpgsqlCommand cmd = new NpgsqlCommand()) + { + + cmd.Connection = conn; + cmd.Transaction = trans; + //UI.Notify(data.CurrentWeather.ToString()); + cmd.Parameters.Clear(); + cmd.CommandText = + "INSERT INTO test_enums (detection_type, weather_type, detection_class) VALUES (@type, @weather, @class);"; +// cmd.CommandText = +// "INSERT INTO test_enums (detection_type) VALUES (@type);"; + cmd.Parameters.AddWithValue("@weather", NpgsqlDbType.Enum, Weather.Foggy); +// cmd.Parameters.AddWithValue("@type", NpgsqlDbType.Enum, DetectionType.background); + cmd.Parameters.AddWithValue("@type", NpgsqlDbType.Enum, DetectionType.bicycle); + cmd.Parameters.AddWithValue("@class", NpgsqlDbType.Enum, DetectionClass.Commercial); + cmd.Prepare(); + cmd.ExecuteNonQuery(); + trans.Commit(); + conn.Close(); + } + } + + public static int InsertInstanceData(NpgsqlConnection conn) + { + +// var instanceinfo = new InstanceData(); + using (var cmd = new NpgsqlCommand()) + { + cmd.Connection = conn; + +// cmd.Parameters.AddWithValue("@host", System.Environment.MachineName); +// cmd.Parameters.AddWithValue("@iid", DBNull.Value); +// cmd.Parameters.AddWithValue("@typ", instanceinfo.type); +// cmd.Parameters.AddWithValue("@pubhost", DBNull.Value); +// cmd.Parameters.AddWithValue("@amiid", DBNull.Value); +// +// if (instanceinfo.type != "LOCALHOST") +// { +// cmd.Parameters.AddWithValue("@host", instanceinfo.hostname); +// cmd.Parameters.AddWithValue("@iid", instanceinfo.instanceid); +// cmd.Parameters.AddWithValue("@typ", instanceinfo.type); +// cmd.Parameters.AddWithValue("@pubhost", instanceinfo.publichostname); +// cmd.Parameters.AddWithValue("@amiid", instanceinfo.amiid); +// } + cmd.CommandText = + "SELECT instance_id FROM instances WHERE hostname=@host AND instancetype=@typ AND instanceid=@iid AND amiid=@amiid AND publichostname=@pubhost"; + var id = cmd.ExecuteScalar(); + if (id == null) + { + cmd.CommandText = + "INSERT INTO instances (hostname, instanceid, instancetype, publichostname, amiid) VALUES (@host, @iid, @typ, @pubhost, @amiid) " + + "RETURNING instance_id"; + return (int) cmd.ExecuteScalar(); + } + + return (int) id; + + } + } + + public static Guid InsertSystemData(NpgsqlConnection conn) + { + var systemInfo = new WMIInformation(); + using (var cmd = new NpgsqlCommand()) + { + cmd.Connection = conn; + cmd.Parameters.AddWithValue("@system_uuid", systemInfo.system_uuid); + cmd.Parameters.AddWithValue("@vendor", systemInfo.vendor); + cmd.Parameters.AddWithValue("@dnshostname", systemInfo.dnshostname); + cmd.Parameters.AddWithValue("@username", systemInfo.username); + cmd.Parameters.AddWithValue("@systemtype", systemInfo.systemtype); + cmd.Parameters.AddWithValue("@totalmem", NpgsqlDbType.Bigint, systemInfo.totalmem); +// cmd.CommandText = +// "INSERT INTO systems (system_uuid, vendor, dnshostname, username, systemtype, totalmem) VALUES " + +// "(@system_uuid, @vendor, @dnshostname, @username, @systemtype, @totalmem) ON CONFLICT DO NOTHING RETURNING system_uuid"; + cmd.CommandText = + "INSERT INTO systems (system_uuid, vendor, dnshostname, username, systemtype, totalmem) VALUES " + + "(@system_uuid, @vendor, @dnshostname, @username, @systemtype, @totalmem) ON CONFLICT(system_uuid) DO UPDATE SET system_uuid = EXCLUDED.system_uuid RETURNING system_uuid"; + return Guid.Parse(cmd.ExecuteScalar().ToString()); + } + } + + public static async void Printing(int i) + { + await Task.Run(() => PrintingImpl(i)); + } + + public static void PrintingImpl(int i) + { + System.Threading.Thread.Sleep(1000); // wait 1 second + Console.WriteLine(i); + } + + public static async void Printing(string i) + { + await Task.Run(() => PrintingImpl(i)); + } + + public static void PrintingImpl(string i) + { + System.Threading.Thread.Sleep(1000); // wait 1 second + Console.WriteLine(i); + } + + public static async void Printing(byte[] i) + { + await Task.Run(() => PrintingImpl(i)); + } + + public static void PrintingImpl(byte[] i) + { + System.Threading.Thread.Sleep(1000); // wait 1 second + Console.WriteLine(BitConverter.ToString(i)); + } + + public static void tryThreads() + { +// var i = 1; +// var i = "h"; + var i = new byte[] { 0x20, 0x20, 0x20, 0x20}; + Printing(i); + System.Threading.Thread.Sleep(500); +// i = 2; +// i = "he"; + i = new byte[] { 0x30, 0x30, 0x30, 0x30}; + Printing(i); + System.Threading.Thread.Sleep(500); +// i = 3; +// i = "hello"; + i = new byte[] { 0x40, 0x40, 0x40, 0x40}; + Printing(i); + System.Threading.Thread.Sleep(3000); + } + + public static void Main(string[] args) + { +// tryThreads(); + + string weather = "Clear"; +// string weather = "Overcast"; + var weatherEnum = Enum.Parse(typeof(Weather), weather); + Console.WriteLine(weatherEnum); +// var dateTimeFormat = @"dd-MM-yyyy--HH-mm-ss"; +// var dateTimeFormat = @"dd-MM-yyyy--HH-mm-ss-fff"; +// for (int i = 0; i < 1000; i++) +// { +// var fileName = DateTime.UtcNow.ToString(dateTimeFormat) + ".tiff"; +// Console.WriteLine(fileName); +// } +// var systemInfo = new WMIInformation(); +// Console.WriteLine(systemInfo.dnshostname); +// Console.WriteLine(systemInfo.username); +// var conn = OpenConnection(); +// conn = null; +// int instanceid = InsertInstanceData(conn); +// InsertSystemData(conn); + +// InitSQLTypes(); +// InsertEnum(); +// var str = "{\"name\": \"SET_TIME\", \"time\": \"05:20\"}"; +// dynamic parameters = JsonConvert.DeserializeObject(str); +// var time = parameters.time.Value(); +// var hoursAndMinutes = time.Split(':'); +// var hours = int.Parse(hoursAndMinutes[0]); +// var minutes = int.Parse(hoursAndMinutes[1]); +// var timeSpan = new TimeSpan(hours, minutes, 0); + + Console.WriteLine("the end"); + + } + } +} \ No newline at end of file diff --git a/managed/Sandbox/Sandbox.csproj b/managed/Sandbox/Sandbox.csproj new file mode 100644 index 0000000..514d3c5 --- /dev/null +++ b/managed/Sandbox/Sandbox.csproj @@ -0,0 +1,87 @@ + + + + + Debug + AnyCPU + {35EC1C44-BEB8-4CF7-A5D8-AD3A2A029A5C} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Exe + Properties + Sandbox + Sandbox + v4.5.2 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + ..\packages\ini-parser.2.4.0\lib\net20\INIFileParser.dll + + + + ..\packages\Microsoft.Extensions.Logging.1.1.0\lib\netstandard1.1\Microsoft.Extensions.Logging.dll + + + ..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.0\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\..\..\..\..\Program Files (x86)\SteamLibrary\steamapps\common\Grand Theft Auto V\scripts\Npgsql.dll + + + ..\packages\Npgsql.3.2.1\lib\net451\Npgsql.dll + + + + + + + ..\packages\System.Threading.Tasks.Extensions.4.3.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + + + + + {D3C3EAE5-CFDD-454A-BD26-9D6FD5D6C239} + GTAVisionUtils + + + {d3c3eae5-cfdd-454a-bd26-9d6fd5d6c239} + GTAVisionUtils + + + + + + + + \ No newline at end of file diff --git a/managed/Sandbox/sandbox.sql b/managed/Sandbox/sandbox.sql new file mode 100644 index 0000000..8a62713 --- /dev/null +++ b/managed/Sandbox/sandbox.sql @@ -0,0 +1,199 @@ +-- CREATE EXTENSION postgis; + +CREATE TYPE detection_type AS ENUM ('background', 'person', 'car', 'bicycle'); + +CREATE TYPE detection_class AS ENUM ('Unknown', 'Compacts', 'Sedans', 'SUVs', 'Coupes', 'Muscle', 'SportsClassics', 'Sports', 'Super', 'Motorcycles', 'OffRoad', 'Industrial', 'Utility', 'Vans', 'Cycles', 'Boats', 'Helicopters', 'Planes', 'Service', 'Emergency', 'Military', 'Commercial', 'Train'); + +CREATE TYPE weather AS ENUM ('Unknown', 'ExtraSunny', 'Clear', 'Clouds', 'Smog', 'Foggy', 'Overcast', 'Raining', 'ThunderStorm', 'Clearing', 'Neutral', 'Snowing', 'Blizzard', 'Snowlight', 'Christmas', 'Halloween'); + +CREATE TABLE test_enums ( + detection_type detection_type, + weather_type weather, + detection_class detection_class +); + +create table detections +( + detection_id serial not null + constraint detections_pkey + primary key, + snapshot_id integer, + type detection_type, + pos geometry(PointZ), + bbox box, + class detection_class default 'Unknown'::detection_class, + handle integer default '-1'::integer, + best_bbox box, + best_bbox_old box, + bbox3d box3d, + rot geometry, + coverage real default 0.0 +) +; + + +create table runs +( + run_id serial not null + constraint runs_pkey + primary key, + runguid uuid, + archivepath text, + localpath text, + session_id integer default 1, + instance_id integer default 0 +) +; + + +create table sessions +( + session_id serial not null + constraint sessions_pkey + primary key, + name text + constraint sessions_name_key + unique, + start timestamp with time zone, + "end" timestamp with time zone +) +; + +alter table runs + add constraint runs_session_fkey +foreign key (session_id) references sessions +on delete cascade +; + +create table snapshots +( + snapshot_id serial not null + constraint snapshots_pkey + primary key, + run_id integer + constraint snapshots_run_fkey + references runs + on delete cascade, + version integer, + imagepath text, + timestamp timestamp with time zone, + timeofday time, + currentweather weather, + camera_pos geometry(PointZ), + camera_direction geometry, + camera_fov real, + view_matrix double precision[], + proj_matrix double precision[], + processed boolean default false not null, + width integer, + height integer +) +; + + +alter table detections + add constraint detections_snapshot_fkey +foreign key (snapshot_id) references snapshots +on delete cascade +; + +create table instances +( + instance_id serial not null + constraint isntances_pkey + primary key, + hostname text, + instanceid text + constraint instanceid_uniq + unique, + instancetype text, + publichostname text, + amiid text, + constraint instance_info_uniq + unique (hostname, instanceid, instancetype, publichostname, amiid) +) +; + +alter table runs + add constraint runs_instance_fkey +foreign key (instance_id) references instances +; + +create table snapshot_weathers +( + weather_id serial not null + constraint snapshot_weathers_pkey + primary key, + snapshot_id integer + constraint snapshot_weathers_snapshot_id_fkey + references snapshots + on delete cascade, + weather_type weather, + snapshot_page integer +) +; + +create table uploads +( + id serial not null + constraint uploads_pkey + primary key, + bucket text, + key text, + uploadid text +) +; + +create table datasets +( + dataset_id serial not null + constraint datasets_pkey + primary key, + dataset_name text, + view_name text +) +; + +create table systems +( + system_uuid uuid not null + constraint systems_pkey + primary key, + vendor text, + dnshostname text, + username text, + systemtype text, + totalmem integer +) +; + +create table system_graphics +( + system_graphic_id serial not null + constraint system_graphics_pkey + primary key, + deviceid text, + adaptercompatibility text, + adapterdactype text, + adapterram integer, + availability integer, + caption text, + description text, + driverdate timestamp with time zone, + driverversion text, + pnpdeviceid text, + name text, + videoarch integer, + memtype integer, + videoprocessor text, + bpp integer, + hrez integer, + vrez integer, + num_colors integer, + cols integer, + rows integer, + refresh integer, + scanmode integer, + videomodedesc text +) +; diff --git a/native/README.md b/native/README.md index 9524453..b9b3906 100644 --- a/native/README.md +++ b/native/README.md @@ -47,6 +47,18 @@ HTH FAQ --- +Can not configure in CMake, this message shows up: +``` +CMake Error at CMakeLists.txt:3 (project): + Failed to run MSBuild command: + + MSBuild.exe + + to get the value of VCTargetsPath: +``` + +This means your visual studio MSBuild is not in your PATH variable. + Can not configure in CMake, `gdi32.lib` is missing: This is probably due to incorrect Visual Studio SDK, can be solved by installing Windows 10 SDK (10.0.15063.0) for Desktop C++ x86 and x64 in the VS Installer. diff --git a/native/src/GTAVisionNative.vcxproj b/native/src/GTAVisionNative.vcxproj new file mode 100644 index 0000000..ad35c90 --- /dev/null +++ b/native/src/GTAVisionNative.vcxproj @@ -0,0 +1,328 @@ + + + + + Debug + x64 + + + Release + x64 + + + MinSizeRel + x64 + + + RelWithDebInfo + x64 + + + + {D7A05F9F-7920-3AC9-A553-47920A761D8A} + 10.0.16299.0 + Win32Proj + x64 + GTAVisionNative + NoUpgrade + + + + DynamicLibrary + MultiByte + v141 + + + DynamicLibrary + MultiByte + v141 + + + DynamicLibrary + MultiByte + v141 + + + DynamicLibrary + MultiByte + v141 + + + + + + + + + + <_ProjectFileVersion>10.0.20506.1 + D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\Debug\ + GTAVisionNative.dir\Debug\ + GTAVisionNative + .asi + true + true + D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\Release\ + GTAVisionNative.dir\Release\ + GTAVisionNative + .asi + false + true + D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\MinSizeRel\ + GTAVisionNative.dir\MinSizeRel\ + GTAVisionNative + .asi + false + true + D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\RelWithDebInfo\ + GTAVisionNative.dir\RelWithDebInfo\ + GTAVisionNative + .asi + true + true + + + + D:\projekty\GTA-V-extractors\GTAVisionExport\eigen-eigen-f562a193118d;%(AdditionalIncludeDirectories) + Debug/ + EnableFastChecks + CompileAsCpp + ProgramDatabase + Sync + Disabled + Disabled + NotUsing + MultiThreadedDebugDLL + true + Level3 + WIN32;_WINDOWS;CMAKE_INTDIR="Debug";GTAVisionNative_EXPORTS;%(PreprocessorDefinitions) + $(IntDir) + + + WIN32;_DEBUG;_WINDOWS;CMAKE_INTDIR=\"Debug\";GTAVisionNative_EXPORTS;%(PreprocessorDefinitions) + D:\projekty\GTA-V-extractors\GTAVisionExport\eigen-eigen-f562a193118d;%(AdditionalIncludeDirectories) + + + D:\projekty\GTA-V-extractors\GTAVisionExport\eigen-eigen-f562a193118d;%(AdditionalIncludeDirectories) + $(ProjectDir)/$(IntDir) + %(Filename).h + %(Filename).tlb + %(Filename)_i.c + %(Filename)_p.c + + + ..\deps\ScriptHookV.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib + %(AdditionalLibraryDirectories) + %(AdditionalOptions) /machine:x64 + true + %(IgnoreSpecificDefaultLibraries) + D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/Debug/GTAVisionNative.lib + D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/Debug/GTAVisionNative.pdb + Console + + + false + + + + + D:\projekty\GTA-V-extractors\GTAVisionExport\eigen-eigen-f562a193118d;%(AdditionalIncludeDirectories) + Release/ + CompileAsCpp + Sync + AnySuitable + MaxSpeed + NotUsing + MultiThreadedDLL + true + Level3 + WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="Release";GTAVisionNative_EXPORTS;%(PreprocessorDefinitions) + $(IntDir) + + + + WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"Release\";GTAVisionNative_EXPORTS;%(PreprocessorDefinitions) + D:\projekty\GTA-V-extractors\GTAVisionExport\eigen-eigen-f562a193118d;%(AdditionalIncludeDirectories) + + + D:\projekty\GTA-V-extractors\GTAVisionExport\eigen-eigen-f562a193118d;%(AdditionalIncludeDirectories) + $(ProjectDir)/$(IntDir) + %(Filename).h + %(Filename).tlb + %(Filename)_i.c + %(Filename)_p.c + + + ..\deps\ScriptHookV.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib + %(AdditionalLibraryDirectories) + %(AdditionalOptions) /machine:x64 + false + %(IgnoreSpecificDefaultLibraries) + D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/Release/GTAVisionNative.lib + D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/Release/GTAVisionNative.pdb + Console + + + false + + + + + D:\projekty\GTA-V-extractors\GTAVisionExport\eigen-eigen-f562a193118d;%(AdditionalIncludeDirectories) + MinSizeRel/ + CompileAsCpp + Sync + OnlyExplicitInline + MinSpace + NotUsing + MultiThreadedDLL + true + Level3 + WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="MinSizeRel";GTAVisionNative_EXPORTS;%(PreprocessorDefinitions) + $(IntDir) + + + + WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"MinSizeRel\";GTAVisionNative_EXPORTS;%(PreprocessorDefinitions) + D:\projekty\GTA-V-extractors\GTAVisionExport\eigen-eigen-f562a193118d;%(AdditionalIncludeDirectories) + + + D:\projekty\GTA-V-extractors\GTAVisionExport\eigen-eigen-f562a193118d;%(AdditionalIncludeDirectories) + $(ProjectDir)/$(IntDir) + %(Filename).h + %(Filename).tlb + %(Filename)_i.c + %(Filename)_p.c + + + ..\deps\ScriptHookV.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib + %(AdditionalLibraryDirectories) + %(AdditionalOptions) /machine:x64 + false + %(IgnoreSpecificDefaultLibraries) + D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/MinSizeRel/GTAVisionNative.lib + D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/MinSizeRel/GTAVisionNative.pdb + Console + + + false + + + + + D:\projekty\GTA-V-extractors\GTAVisionExport\eigen-eigen-f562a193118d;%(AdditionalIncludeDirectories) + RelWithDebInfo/ + CompileAsCpp + ProgramDatabase + Sync + OnlyExplicitInline + MaxSpeed + NotUsing + MultiThreadedDLL + true + Level3 + WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR="RelWithDebInfo";GTAVisionNative_EXPORTS;%(PreprocessorDefinitions) + $(IntDir) + + + WIN32;_WINDOWS;NDEBUG;CMAKE_INTDIR=\"RelWithDebInfo\";GTAVisionNative_EXPORTS;%(PreprocessorDefinitions) + D:\projekty\GTA-V-extractors\GTAVisionExport\eigen-eigen-f562a193118d;%(AdditionalIncludeDirectories) + + + D:\projekty\GTA-V-extractors\GTAVisionExport\eigen-eigen-f562a193118d;%(AdditionalIncludeDirectories) + $(ProjectDir)/$(IntDir) + %(Filename).h + %(Filename).tlb + %(Filename)_i.c + %(Filename)_p.c + + + ..\deps\ScriptHookV.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib + %(AdditionalLibraryDirectories) + %(AdditionalOptions) /machine:x64 + true + %(IgnoreSpecificDefaultLibraries) + D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/RelWithDebInfo/GTAVisionNative.lib + D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/RelWithDebInfo/GTAVisionNative.pdb + Console + + + false + + + + + Building Custom Rule D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/CMakeLists.txt + setlocal +"C:\Program Files\CMake\bin\cmake.exe" -HD:/projekty/GTA-V-extractors/GTAVisionExport/native -BD:/projekty/GTA-V-extractors/GTAVisionExport/native --check-stamp-file D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/CMakeFiles/generate.stamp +if %errorlevel% neq 0 goto :cmEnd +:cmEnd +endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone +:cmErrorLevel +exit /b %1 +:cmDone +if %errorlevel% neq 0 goto :VCEnd + D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/CMakeLists.txt;D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\CMakeLists.txt;D:\projekty\GTA-V-extractors\GTAVisionExport\native\cmake\FindEigen3.cmake;D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\CMakeLists.txt;%(AdditionalInputs) + D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\CMakeFiles\generate.stamp + false + Building Custom Rule D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/CMakeLists.txt + setlocal +"C:\Program Files\CMake\bin\cmake.exe" -HD:/projekty/GTA-V-extractors/GTAVisionExport/native -BD:/projekty/GTA-V-extractors/GTAVisionExport/native --check-stamp-file D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/CMakeFiles/generate.stamp +if %errorlevel% neq 0 goto :cmEnd +:cmEnd +endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone +:cmErrorLevel +exit /b %1 +:cmDone +if %errorlevel% neq 0 goto :VCEnd + D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/CMakeLists.txt;D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\CMakeLists.txt;D:\projekty\GTA-V-extractors\GTAVisionExport\native\cmake\FindEigen3.cmake;D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\CMakeLists.txt;%(AdditionalInputs) + D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\CMakeFiles\generate.stamp + false + Building Custom Rule D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/CMakeLists.txt + setlocal +"C:\Program Files\CMake\bin\cmake.exe" -HD:/projekty/GTA-V-extractors/GTAVisionExport/native -BD:/projekty/GTA-V-extractors/GTAVisionExport/native --check-stamp-file D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/CMakeFiles/generate.stamp +if %errorlevel% neq 0 goto :cmEnd +:cmEnd +endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone +:cmErrorLevel +exit /b %1 +:cmDone +if %errorlevel% neq 0 goto :VCEnd + D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/CMakeLists.txt;D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\CMakeLists.txt;D:\projekty\GTA-V-extractors\GTAVisionExport\native\cmake\FindEigen3.cmake;D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\CMakeLists.txt;%(AdditionalInputs) + D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\CMakeFiles\generate.stamp + false + Building Custom Rule D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/CMakeLists.txt + setlocal +"C:\Program Files\CMake\bin\cmake.exe" -HD:/projekty/GTA-V-extractors/GTAVisionExport/native -BD:/projekty/GTA-V-extractors/GTAVisionExport/native --check-stamp-file D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/CMakeFiles/generate.stamp +if %errorlevel% neq 0 goto :cmEnd +:cmEnd +endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone +:cmErrorLevel +exit /b %1 +:cmDone +if %errorlevel% neq 0 goto :VCEnd + D:/projekty/GTA-V-extractors/GTAVisionExport/native/src/CMakeLists.txt;D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\CMakeLists.txt;D:\projekty\GTA-V-extractors\GTAVisionExport\native\cmake\FindEigen3.cmake;D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\CMakeLists.txt;%(AdditionalInputs) + D:\projekty\GTA-V-extractors\GTAVisionExport\native\src\CMakeFiles\generate.stamp + false + + + + + + + + + + + + + + + {1772903C-DA00-382E-B43A-8939865BD425} + ZERO_CHECK + + + + + + \ No newline at end of file diff --git a/native/src/GTAVisionNative.vcxproj.filters b/native/src/GTAVisionNative.vcxproj.filters new file mode 100644 index 0000000..3b19c7a --- /dev/null +++ b/native/src/GTAVisionNative.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + + + + {2B7382E6-CEB9-3073-B77E-CC34D4F475C0} + + + {5F5C3B6C-34F1-38F0-8718-BF4C7F6B0B00} + + + diff --git a/native/src/cmake_install.cmake b/native/src/cmake_install.cmake new file mode 100644 index 0000000..78b5f6e --- /dev/null +++ b/native/src/cmake_install.cmake @@ -0,0 +1,34 @@ +# Install script for directory: D:/projekty/GTA-V-extractors/GTAVisionExport/native/src + +# Set the install prefix +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "C:/Program Files/GTANativePlugin") +endif() +string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + if(BUILD_TYPE) + string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + else() + set(CMAKE_INSTALL_CONFIG_NAME "Release") + endif() + message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +endif() + +# Set the component getting installed. +if(NOT CMAKE_INSTALL_COMPONENT) + if(COMPONENT) + message(STATUS "Install component: \"${COMPONENT}\"") + set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + else() + set(CMAKE_INSTALL_COMPONENT) + endif() +endif() + +# Is this installation the result of a crosscompile? +if(NOT DEFINED CMAKE_CROSSCOMPILING) + set(CMAKE_CROSSCOMPILING "FALSE") +endif() +