/* Crowd Simulator Engine
** Copyright (C) 2018 - Inria Rennes - Rainbow - Julien Pettre
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
** Authors: Julien Bruneau
**
** Contact: crowd_group@inria.fr
*/
using UnityEngine;
using System.Collections;
using System.IO;
///
/// Main manager: Load the scene, create all the agents and manage users input
///
public class LoadEnv : MonoBehaviour
{
#region attributes
private string rootFolder = "Assets/Resources/CSV/"; // Folder containing trajectory files
GameObject[] avatars; // List of agents
public GameObject cam; // Scene camera
private CamRecorder cam_Rec; // Control scene recording
private CamMvt cam_Movement; // Control camera movement behavior
//private float rotSpeed = 5;
// --------------------------
// CAMERA MOVEMENT PARAMETERS
const float camTranslationSpeed = 25.0f; // Camera translation speed
const float camShiftPower = 250.0f; // Shift effect on camera speed
const float camMaxShiftPower = 1000.0f; // Maximun shift effect on camera speed
const float camRotationSpeed = 0.25f; // Rotation speed
Vector3 lastMouse = new Vector3(255, 255, 255); // Last mouse position to check its movement
float camShiftHold = 1.0f; // Control the effect of shift with holding time
#endregion
///
/// Scene and agents initialization
///
void Start()
{
// --------------------------------------------------
// SET RANDOM SEED TO HAVE SAME RESULTS AT EVERY RUNS
Random.InitState(75482);
// ---------------------------------
// INITIALIZE SCENE FROM CONFIG FILE
cam_Rec = cam.GetComponent();
cam_Movement = cam.GetComponent();
rootFolder = ConfigReader.trajectoriesDir;
// -------------
// CAMERA CONFIG
cam.transform.position = ConfigReader.camPosition;
cam.transform.rotation = Quaternion.Euler(ConfigReader.camRotation);
cam_Movement.lookAt_Id = ConfigReader.camLookAtTarget;
cam_Movement.follow_Id = ConfigReader.camFollowTarget;
cam_Movement.follow_LockX = !ConfigReader.camFollowOnX;
cam_Movement.follow_LockZ = !ConfigReader.camFollowOnY;
// -------------
// RECORD CONFIG
cam_Rec.record = ConfigReader.recording;
cam_Rec.timeToStart = ConfigReader.recordingStart;
cam_Rec.timeToStop = ConfigReader.recordingEnd;
cam_Rec.framerate = ConfigReader.recordingFramerate;
if (ConfigReader.recordingSaveDir[1] != ':')
cam_Rec.saveDir = "..\\" + ConfigReader.recordingSaveDir;
else
cam_Rec.saveDir = ConfigReader.recordingSaveDir;
// -------------
// CREATE AGENTS
DirectoryInfo dir = new DirectoryInfo(rootFolder);
FileInfo[] info = dir.GetFiles("*.csv");
if (info.Length == 0)
info = dir.GetFiles("*.txt");
GameObject temp;
FollowTrajectory tmpFollower;
int i = 0;
object testRocketMan = Resources.Load("Prefabs/RocketBox/male/prefab_light/LS_m001_light");
foreach (FileInfo f in info)
{
// ------------------------------------------------------------
// IF NO ROCKETMAN (PROPRIETARY ASSETS), USE PLASTICMAN INSTEAD
if (testRocketMan == null)
{
// -------------------
// LOAD AGENT IN UNITY
string path = "PlasticMan/plasticman";
temp = UnityEngine.Object.Instantiate(Resources.Load(path, typeof(GameObject)), new Vector3(0, 0, 0), Quaternion.Euler(0, 0, 0)) as GameObject;
temp.name = temp.name + i.ToString("D4");
temp.tag = "Player";
// -----------------
// SET AGENT'S COLOR
Color tmpColor = new Color(Random.value, Random.value, Random.value, 1);
if (ConfigReader.agentsColor!=null && ConfigReader.agentsColor.Count>0)
{
foreach (ConfigAgentColor c in ConfigReader.agentsColor)
{
if (i>c.firstAgent-1 && i();
Material tmpMaterial = new Material(Shader.Find("Legacy Shaders/Diffuse"));
tmpMaterial.color = tmpColor;
tmpRenderer.material = tmpMaterial;
}
else
{
// -------------------
// LOAD AGENT IN UNITY
string path;
int modelId;
if (i % 2 == 0)
{
path = "male/prefab_light/LS_m";
modelId = i / 2;
}else
{
path = "female/prefab_light/LS_f";
modelId = (i - 1) / 2;
}
modelId = (modelId % 20) + 1;
path = "Prefabs/RocketBox/" + path + modelId.ToString("D3") + "_light";
temp = UnityEngine.Object.Instantiate(Resources.Load(path, typeof(GameObject)), new Vector3(0, 0, 0), Quaternion.Euler(0, 0, 0)) as GameObject;
temp.name = temp.name + i.ToString("D4");
temp.tag = "Player";
// ---------------------------------------------
// SET AGENT'S COLOR WHEN SPECIFY IN CONFIG FILE
bool bColor = false;
Color tmpColor = new Color(Random.value, Random.value, Random.value, 1);
if (ConfigReader.agentsColor != null && ConfigReader.agentsColor.Count > 0)
{
foreach (ConfigAgentColor c in ConfigReader.agentsColor)
{
if (i > c.firstAgent - 1 && i < c.lastAgent + 1 && (i - c.firstAgent) % c.step == 0)
{
tmpColor = new Color(c.red, c.green, c.blue, 1);
bColor = true;
break;
}
}
}
if (bColor)
{
SkinnedMeshRenderer[] rendererList = temp.GetComponentsInChildren();
Material tmpMaterial = new Material(Shader.Find("Legacy Shaders/Diffuse"));
tmpMaterial.color = tmpColor;
Material[] mats = new Material[] { tmpMaterial, tmpMaterial, tmpMaterial };
foreach (SkinnedMeshRenderer renderer in rendererList)
{
renderer.materials = mats;
}
}
}
// ----------------------------------
// FOLLOWTRAJECTORY SCRIPT MANAGEMENT
// Setup of the CSV filename and disable the start synchro
tmpFollower = temp.GetComponent();
tmpFollower.SetCsvFilename(f.FullName);
tmpFollower._SyncLaunchWithTrajectory = false; // start the character when the simulation start not at the csv time
i++;
}
}
///
/// Manage users Input
///
void Update()
{
// -------------------
// ESCAPE => EXIT APPS
if (Input.GetKey(KeyCode.Escape) == true)
{
Application.Quit();
}
// -------------------------------
// MOUSE + RCLICK => ROTATE CAMERA
if (Input.GetMouseButton(1))
{
lastMouse = Input.mousePosition - lastMouse;
lastMouse = new Vector3(-lastMouse.y * camRotationSpeed, lastMouse.x * camRotationSpeed, 0);
lastMouse = new Vector3(cam.transform.eulerAngles.x + lastMouse.x, cam.transform.eulerAngles.y + lastMouse.y, 0);
// Block all the way up or down to prevent glitches
if (lastMouse.x > 180 && lastMouse.x < 270)
lastMouse.x = 270;
else if (lastMouse.x > 90 && lastMouse.x < 180)
lastMouse.x = 90;
cam.transform.eulerAngles = lastMouse;
}
lastMouse = Input.mousePosition;
// -----------------------------------------
// ARROWS, SHIFT, CTRL => CAMERA TRANSLATION
Vector3 p = new Vector3();
if (Input.GetKey(KeyCode.UpArrow))
{
p += new Vector3(0, 0, 1);
}
if (Input.GetKey(KeyCode.DownArrow))
{
p += new Vector3(0, 0, -1);
}
if (Input.GetKey(KeyCode.LeftArrow))
{
p += new Vector3(-1, 0, 0);
}
if (Input.GetKey(KeyCode.RightArrow))
{
p += new Vector3(1, 0, 0);
}
if (Input.GetKey(KeyCode.LeftShift))
{
camShiftHold += Time.fixedUnscaledDeltaTime;
p = p * Mathf.Max(camShiftHold * camShiftPower, camMaxShiftPower);
}
else
{
camShiftHold = Mathf.Clamp(camShiftHold * 0.5f, 1f, 1000f);
p = p * camTranslationSpeed;
}
p = p * Time.fixedUnscaledDeltaTime;
Vector3 newPosition = cam.transform.position;
if (Input.GetKey(KeyCode.LeftControl))
{ //If player wants to move on X and Z axis only
cam.transform.Translate(p);
newPosition.x = cam.transform.position.x;
newPosition.z = cam.transform.position.z;
cam.transform.position = newPosition;
}
else
{
cam.transform.Translate(p);
}
// --------------------------
// F5 => SAVE CAMERA POSITION
if (Input.GetKeyDown(KeyCode.F5))
{
ConfigReader.camPosition = cam.transform.position;
ConfigReader.camRotation = cam.transform.rotation.eulerAngles;
ConfigReader.CreateXML();
}
// ----------------------
// SPACE => PAUSE UNPAUSE
if (Input.GetKeyDown(KeyCode.Space))
{
if (Time.timeScale == 0)
Time.timeScale = 1;
else
Time.timeScale = 0;
}
}
}