diff --git a/data/human.ini b/data/human.ini
index 407e522..085af53 100644
--- a/data/human.ini
+++ b/data/human.ini
@@ -13,57 +13,202 @@
# All color values have arguments in the order of rgba.
#
# Height specifies the height of the human from toe to head in meters.
+# Human drawing "size" is relative to height and mass. Note that drawing
+# is -of course- approximative, and sometimes it needs to "cheat"
+# on one parameter to obtain better drawing (example: baby_1 mass).
+# If not set, default gender is male. If gender is female, breasts
+# are drawn on human torso.
#
+# File version number.
+Version = 1 1
+
# First entry is always the default, it may be used whenever nothing
# in particular is requested.
PresetAdd = default
- Height = 1.9
- Mass = 54.0
- ColorPaletteSelect = Standard
- ColorFace = 0.847 0.615 0.447 1.00
- ColorHair = 0.30 0.24 0.19 1.00
- ColorTorso = 0.95 0.22 0.18 1.00
- ColorHips = 0.20 0.20 0.20 1.00
- ColorLegs = 0.80 0.78 0.75 1.00
- ColorFeet = 0.30 0.30 0.30 1.00
- ColorArms = 0.20 0.20 1.00 1.00
- ColorHands = 0.847 0.615 0.447 1.00
+ Height = 1.9
+ Mass = 90.0
+ Gender = Male
+ ColorPaletteSelect = Standard
+ ColorFace = 0.847 0.615 0.447 1.0
+ ColorHair = 0.300 0.240 0.190 1.0
+ ColorTorso = 0.950 0.220 0.180 1.0
+ ColorHips = 0.200 0.200 0.200 1.0
+ ColorLegs = 0.800 0.780 0.750 1.0
+ ColorFeet = 0.300 0.300 0.300 1.0
+ ColorArms = 0.200 0.200 1.000 1.0
+ ColorHands = 0.847 0.615 0.447 1.0
-# Diver (used for drawing at end of hoist rope).
+# Diver (only for drawing at end of hoist rope).
PresetAdd = diver
- Height = 1.9
- Mass = 54.0
- ColorPaletteSelect = Standard
- ColorFace = 0.847 0.615 0.447 1.00
- ColorHair = 0.10 0.20 0.60 1.00
- ColorTorso = 0.10 0.20 0.60 1.00
- ColorHips = 0.10 0.20 0.60 1.00
- ColorLegs = 0.10 0.20 0.60 1.00
- ColorFeet = 0.10 0.20 0.60 1.00
- ColorArms = 0.10 0.20 0.60 1.00
- ColorHands = 0.847 0.615 0.447 1.00
+# Hard-coded data:
+# Height = 1.9
+# Mass = 90.0
+# Gender = Male
+ ColorPaletteSelect = Standard
+ ColorFace = 0.847 0.615 0.447 1.0
+ ColorHair = 0.100 0.200 0.600 1.0
+ ColorTorso = 0.100 0.200 0.600 1.0
+ ColorHips = 0.100 0.200 0.600 1.0
+ ColorLegs = 0.100 0.200 0.600 1.0
+ ColorFeet = 0.100 0.200 0.600 1.0
+ ColorArms = 0.100 0.200 0.600 1.0
+ ColorHands = 0.847 0.615 0.447 1.0
-# Victim intended to be on a streatcher with one assisting human.
+# For backward compatibility : victim intended to be on a stretcher with
+# one assisting human. Note that only color can be be modified and will be
+# applied to all (1 to 4) assisting humans.
PresetAdd = victim_streatcher_assisted
- Height = 1.9
- Mass = 54.0
- AssistingHumans = 1
- ColorPaletteSelect = Standard
- ColorFace = 0.847 0.615 0.447 1.00
- ColorHair = 0.30 0.24 0.19 1.00
- ColorTorso = 0.95 0.22 0.18 1.00
- ColorHips = 0.20 0.20 0.20 1.00
- ColorLegs = 0.80 0.78 0.75 1.00
- ColorFeet = 0.30 0.30 0.30 1.00
- ColorArms = 0.20 0.20 1.00 1.00
- ColorHands = 0.847 0.615 0.447 1.00
- ColorPaletteSelect = AssistingHuman
- ColorFace = 0.847 0.615 0.447 1.00
- ColorHair = 0.30 0.24 0.19 1.00
- ColorTorso = 0.21 0.95 0.20 1.00
- ColorHips = 0.70 0.70 0.70 1.00
- ColorLegs = 0.70 0.70 0.70 1.00
- ColorFeet = 0.30 0.30 0.30 1.00
- ColorArms = 0.21 0.95 0.20 1.00
- ColorHands = 0.94 0.92 0.9 1.00
+ Height = 1.9
+ Mass = 90.0
+ AssistingHumans = 1
+ ColorPaletteSelect = Standard
+ ColorFace = 0.847 0.615 0.447 1.0
+ ColorHair = 0.300 0.240 0.190 1.0
+ ColorTorso = 0.950 0.220 0.180 1.0
+ ColorHips = 0.200 0.200 0.200 1.0
+ ColorLegs = 0.800 0.780 0.750 1.0
+ ColorFeet = 0.300 0.300 0.300 1.0
+ ColorArms = 0.200 0.200 1.000 1.0
+ ColorHands = 0.847 0.615 0.447 1.0
+ ColorPaletteSelect = AssistingHuman
+ ColorFace = 0.847 0.615 0.447 1.0
+ ColorHair = 0.300 0.240 0.190 1.0
+ ColorTorso = 0.210 0.950 0.200 1.0
+ ColorHips = 0.700 0.700 0.700 1.0
+ ColorLegs = 0.700 0.700 0.700 1.0
+ ColorFeet = 0.300 0.300 0.300 1.0
+ ColorArms = 0.210 0.950 0.200 1.0
+ ColorHands = 0.940 0.920 0.900 1.0
+
+# Default assisting human.
+PresetAdd = assistant_1
+ Height = 1.9
+ Mass = 90.0
+ Gender = Male
+ ColorPaletteSelect = Standard
+ ColorFace = 0.847 0.615 0.447 1.0
+ ColorHair = 0.300 0.240 0.190 1.0
+ ColorTorso = 0.210 0.950 0.200 1.0
+ ColorHips = 0.700 0.700 0.700 1.0
+ ColorLegs = 0.700 0.700 0.700 1.0
+ ColorFeet = 0.300 0.300 0.300 1.0
+ ColorArms = 0.210 0.950 0.200 1.0
+ ColorHands = 0.940 0.920 0.900 1.0
+
+# An old black man, with hairs
+PresetAdd = man_1
+ Height = 1.75
+ Mass = 80.0
+ Gender = Male
+ ColorPaletteSelect = Standard
+ ColorFace = 0.304 0.206 0.206 1.0
+ ColorHair = 0.900 0.900 0.900 1.0
+ ColorTorso = 0.900 0.900 0.900 1.0
+ ColorHips = 0.950 0.220 0.180 1.0
+ ColorLegs = 0.950 0.220 0.180 1.0
+ ColorFeet = 0.100 0.100 0.100 1.0
+ ColorArms = 0.900 0.900 0.900 1.0
+ ColorHands = 0.304 0.206 0.206 1.0
+
+# An old white man, without hairs (ColorHair alpha value set to 0.0)
+PresetAdd = man_2
+ Height = 1.90
+ Mass = 90.0
+ Gender = Male
+ ColorPaletteSelect = Standard
+ ColorFace = 0.847 0.615 0.447 1.0
+ ColorHair = 0.900 0.900 0.900 0.0
+ ColorTorso = 0.576 0.174 0.724 1.0
+ ColorHips = 0.194 0.369 0.723 1.0
+ ColorLegs = 0.194 0.369 0.723 1.0
+ ColorFeet = 0.315 0.157 0.157 1.0
+ ColorArms = 0.576 0.174 0.724 1.0
+ ColorHands = 0.847 0.615 0.447 1.0
+
+# A 10 years old white girl
+# Note that if gender had been defined and set to Female, girl would have breast.
+PresetAdd = girl_1
+ Height = 1.33
+ Mass = 28.0
+ ColorPaletteSelect = Standard
+ ColorFace = 0.847 0.615 0.447 1.0
+ ColorHair = 0.932 0.938 0.548 1.0
+ ColorTorso = 0.900 0.900 0.900 1.0
+ ColorHips = 0.951 0.670 0.969 1.0
+ ColorLegs = 0.847 0.615 0.447 1.0
+ ColorFeet = 0.951 0.670 0.969 1.0
+ ColorArms = 0.847 0.615 0.447 1.0
+ ColorHands = 0.847 0.615 0.447 1.0
+
+# A 10 years old black boy
+PresetAdd = boy_1
+ Height = 1.33
+ Mass = 28.0
+ ColorPaletteSelect = Standard
+ ColorFace = 0.304 0.206 0.206 1.0
+ ColorHair = 0.123 0.123 0.123 1.0
+ ColorTorso = 1.000 0.554 0.000 1.0
+ ColorHips = 0.194 0.369 0.723 1.0
+ ColorLegs = 0.194 0.369 0.723 1.0
+ ColorFeet = 0.900 0.900 0.900 1.0
+ ColorArms = 1.000 0.554 0.000 1.0
+ ColorHands = 0.304 0.206 0.206 1.0
+
+# A black woman
+PresetAdd = woman_1
+ Height = 1.70
+ Mass = 60.0
+ Gender = Female
+ ColorPaletteSelect = Standard
+ ColorFace = 0.304 0.206 0.206 1.0
+ ColorHair = 0.123 0.123 0.123 1.0
+ ColorTorso = 0.900 0.900 0.900 1.0
+ ColorHips = 0.900 0.900 0.900 1.0
+ ColorLegs = 0.900 0.900 0.900 1.0
+ ColorFeet = 0.950 0.220 0.180 1.0
+ ColorArms = 0.304 0.206 0.206 1.0
+ ColorHands = 0.304 0.206 0.206 1.0
+
+# A white woman
+PresetAdd = woman_2
+ Height = 1.65
+ Mass = 56.0
+ Gender = Female
+ ColorPaletteSelect = Standard
+ ColorFace = 0.847 0.615 0.447 1.0
+ ColorHair = 0.919 0.292 0.191 1.0
+ ColorTorso = 0.335 0.198 0.210 1.0
+ ColorHips = 0.335 0.198 0.210 1.0
+ ColorLegs = 0.847 0.615 0.447 1.0
+ ColorFeet = 0.335 0.198 0.210 1.0
+ ColorArms = 0.847 0.615 0.447 1.0
+ ColorHands = 0.847 0.615 0.447 1.0
+
+# A white baby
+PresetAdd = baby_1
+ Height = 0.50
+ Mass = 7.0
+ ColorPaletteSelect = Standard
+ ColorFace = 0.980 0.820 0.733 1.0
+ ColorHair = 0.304 0.206 0.206 1.0
+ ColorTorso = 0.460 0.773 0.796 1.0
+ ColorHips = 0.460 0.773 0.796 1.0
+ ColorLegs = 0.460 0.773 0.796 1.0
+ ColorFeet = 0.980 0.820 0.733 1.0
+ ColorArms = 0.460 0.773 0.796 1.0
+ ColorHands = 0.980 0.820 0.733 1.0
+
+# A fat boy with a turquoise cap and yellow gloves
+PresetAdd = Boy_2
+ Height = 1.20
+ Mass = 60.0
+ ColorPaletteSelect = Standard
+ ColorFace = 0.992 0.859 0.706 1.0
+ ColorHair = 0.294 0.710 0.749 1.0
+ ColorTorso = 0.843 0.125 0.250 1.0
+ ColorHips = 0.843 0.125 0.250 1.0
+ ColorLegs = 0.470 0.278 0.227 1.0
+ ColorFeet = 0.192 0.188 0.208 1.0
+ ColorArms = 0.843 0.125 0.250 1.0
+ ColorHands = 0.969 0.882 0.039 1.0
diff --git a/docs/sar2ParmsBook/sar2ParmsDescription.js b/docs/sar2ParmsBook/sar2ParmsDescription.js
index 8a68f73..8645459 100644
--- a/docs/sar2ParmsBook/sar2ParmsDescription.js
+++ b/docs/sar2ParmsBook/sar2ParmsDescription.js
@@ -789,8 +789,8 @@ __Creates a human.\
__ARGUMENTS\
__type_name
\
__default default human. May be used whenever nothing in particular is requested.\
-__victim_streatcher_assisted male victim intended to be on a stretcher with 1 assisting human. Warning: this type name is deprecated.\
-__.........(other type name)......... Warning: SaR II > 2.5.0 only! See data/human.ini file for other preset human types.\
+__.......(other type name)....... See data/human.ini file for other allowed preseted names.\
+__victim_streatcher_assisted Warning: this type name is deprecated. Victim intended to be on a stretcher with 1 assisting human.\
__flags
\
__need_rescue this human needs to be rescued (player has to take him aboard).\
__sit_up human is drawn sitting 'like on a chair', feet on the floor.\
@@ -801,7 +801,7 @@ __alert human is alert (is awake) and moves his arms to draw attention.\
__aware human is aware (knows of surroundings).\
__in_water human swims (moves his arms to float).\
__on_stretcher if this flag is specified, a stretcher is drawn below the human.\
-__assisted n type_name(s) Warning: SaR II > 2.5.0 only! human is assisted (surrounded) by 'n' (1 to 4) humans. Number 'n' must be followed by 'n' human type names.\
+__assisted n type_name(s) Warning: SaR II > 2.6.0 only! human is assisted (surrounded) by 'n' (1 to 4) humans. Number 'n' must be followed by 'n' human type names.\
__CONTEXT\
__mis scn\
__EXAMPLE\
@@ -811,7 +811,7 @@ __# Human position.\
__# If human 'z' position is greater than the ground / water / object which is under him, human will 'fall' until he comes into contact.\
__translate 30000.0 41020.0 0.0\
__...\
-__# Warning: SaR II > 2.5.0 only! Human lying on a strecher, with 2 assisting humans.\
+__# Warning: SaR II > 2.6.0 only! Human lying on a strecher, with 2 assisting humans.\
__create_human boy_1 need_rescue lying on_stretcher assisted 2 assistant_1 woman_1\
__translate 20000.0 41020.0 0.0\
__...\
diff --git a/src/config.h b/src/config.h
index e6420d0..3f16ad9 100644
--- a/src/config.h
+++ b/src/config.h
@@ -653,6 +653,7 @@ to the fullest extent of the law."
*/
#define SAR_HUMAN_PRESET_NAME_STANDARD "standard"
#define SAR_HUMAN_PRESET_NAME_DIVER "diver"
+#define SAR_HUMAN_PRESET_NAME_ASSISTING_HUMAN "assistant_1"
/*
diff --git a/src/human.c b/src/human.c
index 47bd32a..058c150 100644
--- a/src/human.c
+++ b/src/human.c
@@ -16,7 +16,7 @@
#include
#include
-#include
+#include
#include "../include/string.h"
@@ -36,7 +36,7 @@ sar_human_data_struct *SARHumanPresetsInit(void *core_ptr);
void SARHumanPresetsShutdown(sar_human_data_struct *hd);
void SARHumanEntryDelete(
- sar_human_data_struct *hd, sar_human_data_entry_struct *entry
+ sar_human_data_struct *hd, sar_human_data_entry_struct *entry
);
int SARHumanCreate(
@@ -44,12 +44,14 @@ int SARHumanCreate(
sar_scene_struct *scene,
sar_object_struct ***object, int *total_objects,
sar_obj_flags_t human_flags,
+ int assisting_humans,
+ const char *assisting_human_preset_name[SAR_ASSISTING_HUMANS_MAX],
const char *name
);
void SARHumanSetObjectPreset(
- sar_human_data_struct *hd,
- sar_object_struct *obj_ptr,
- const char *name
+ sar_human_data_struct *hd,
+ sar_object_struct *obj_ptr,
+ const char *name
);
@@ -75,7 +77,7 @@ void SARHumanSetObjectPreset(
* Can return NULL on failed match or error.
*/
sar_human_data_entry_struct *SARHumanMatchEntryByName(
- sar_human_data_struct *hd, const char *name
+ sar_human_data_struct *hd, const char *name
)
{
int i;
@@ -152,7 +154,7 @@ void SARHumanPresetsShutdown(sar_human_data_struct *hd)
* resources.
*/
void SARHumanEntryDelete(
- sar_human_data_struct *hd, sar_human_data_entry_struct *entry
+ sar_human_data_struct *hd, sar_human_data_entry_struct *entry
)
{
if(entry == NULL)
@@ -174,10 +176,12 @@ void SARHumanEntryDelete(
*/
int SARHumanCreate(
sar_human_data_struct *hd,
- sar_scene_struct *scene,
- sar_object_struct ***object, int *total_objects,
+ sar_scene_struct *scene,
+ sar_object_struct ***object, int *total_objects,
sar_obj_flags_t human_flags,
- const char *name
+ int assisting_humans,
+ const char *assisting_human_preset_name[SAR_ASSISTING_HUMANS_MAX],
+ const char *name
)
{
int obj_num;
@@ -237,7 +241,14 @@ int SARHumanCreate(
human->intercepting_object_distance3d = 0.0;
/* Number of assisting humans */
- human->assisting_humans = 0;
+ human->assisting_humans = assisting_humans;
+
+ /* Assisting humans preset(s) */
+ if (human->assisting_humans)
+ {
+ for(int i = 0; i < human->assisting_humans; i++)
+ human->assisting_human_preset_name[i] = assisting_human_preset_name[i];
+ }
/* Model human object values to preset values from the human
* data presets.
@@ -259,9 +270,9 @@ int SARHumanCreate(
* then no operation will be performed.
*/
void SARHumanSetObjectPreset(
- sar_human_data_struct *hd,
- sar_object_struct *obj_ptr,
- const char *name
+ sar_human_data_struct *hd,
+ sar_object_struct *obj_ptr,
+ const char *name
)
{
sar_object_human_struct *human;
@@ -295,15 +306,23 @@ void SARHumanSetObjectPreset(
/* Weight in kg */
human->mass = entry->mass;
- /* Number of assisting humans */
- human->assisting_humans = entry->assisting_humans;
-
- /* Color palette for assisting humans */
- memcpy(
- &human->assisting_human_color[0],
- &entry->assisting_human_color[0],
- SAR_HUMAN_COLORS_MAX * sizeof(sar_color_struct)
- );
+ /* Gender */
+ if(entry->preset_entry_flags & SAR_HUMAN_FLAG_GENDER_FEMALE)
+ human->flags |= SAR_HUMAN_FLAG_GENDER_FEMALE;
+
+ /* Number of assisting humans. Do not overwrite if assisting_humans
+ * number has been defined earlier by a create_human parameter.
+ */
+ if(human->assisting_humans == 0)
+ human->assisting_humans = entry->assisting_humans;
+
+ /* Color palette for assisting humans */
+ memcpy(
+ &human->assisting_human_color[0],
+ &entry->assisting_human_color[0],
+ SAR_HUMAN_COLORS_MAX * sizeof(sar_color_struct)
+ );
+
/* Add support for other things that need to be coppied here */
diff --git a/src/human.h b/src/human.h
index 9578653..258648d 100644
--- a/src/human.h
+++ b/src/human.h
@@ -15,7 +15,7 @@
***********************************************************************/
/*
- Human Preset Data
+ Human Preset Data
*/
#ifndef HUMAN_H
@@ -24,7 +24,6 @@
#include
#include "obj.h" /* For SAR_HUMAN_COLOR_* definations */
-
/*
* Human Presets Data Entry:
*/
@@ -38,12 +37,14 @@ typedef struct {
/* Height in meters */
float height;
+ /* For gender SAR_HUMAN_FLAG_GENDER_FEMALE (see obj.h). */
+ sar_obj_flags_t preset_entry_flags;
+
/* Color palette */
sar_color_struct color[SAR_HUMAN_COLORS_MAX];
/* Number of assisting humans (0 for none) */
int assisting_humans;
-
/* Assisting human color palette */
sar_color_struct assisting_human_color[SAR_HUMAN_COLORS_MAX];
@@ -81,6 +82,8 @@ extern int SARHumanCreate(
sar_scene_struct *scene,
sar_object_struct ***object, int *total_objects,
sar_obj_flags_t human_flags,
+ int assisting_humans,
+ const char *assisting_human_preset_name[SAR_ASSISTING_HUMANS_MAX],
const char *name
);
extern void SARHumanSetObjectPreset(
diff --git a/src/humanio.c b/src/humanio.c
index 705ffec..74b5a26 100644
--- a/src/humanio.c
+++ b/src/humanio.c
@@ -19,7 +19,7 @@
#include
#include
#include
-#include
+#include
#include
#include "../include/fio.h"
@@ -55,6 +55,7 @@ int SARHumanLoadFromFile(sar_human_data_struct *hd, const char *filename);
int SARHumanLoadFromFile(sar_human_data_struct *hd, const char *filename)
{
int i;
+ int version_major, version_minor;
FILE *fp;
char *buf = NULL;
struct stat stat_buf;
@@ -78,16 +79,16 @@ int SARHumanLoadFromFile(sar_human_data_struct *hd, const char *filename)
/* Check if the file exists and get its stats */
if(stat(filename, &stat_buf))
{
- char *s = STRDUP(strerror(errno));
- if(s == NULL)
- s = STRDUP("no such file");
- *s = toupper(*s);
- fprintf(
- stderr,
- "%s: %s.\n",
- filename, s
- );
- free(s);
+ char *s = STRDUP(strerror(errno));
+ if(s == NULL)
+ s = STRDUP("no such file");
+ *s = toupper(*s);
+ fprintf(
+ stderr,
+ "%s: %s.\n",
+ filename, s
+ );
+ free(s);
return(-1);
}
#ifdef S_ISDIR
@@ -122,6 +123,13 @@ int SARHumanLoadFromFile(sar_human_data_struct *hd, const char *filename)
(_p_)->a = (float)value[3]; \
} }
+ /* Set version default values.
+ * Historically first human.ini file had no version number:
+ * this version will be named "1.0".
+ */
+ version_major = 1;
+ version_minor = 0;
+
do
{
buf = FSeekNextParm(
@@ -135,18 +143,17 @@ int SARHumanLoadFromFile(sar_human_data_struct *hd, const char *filename)
/* Begin handling parameter */
- /* Version */
+ /* File version */
if(!strcasecmp(buf, "Version"))
{
FGetValuesF(fp, value, 2);
-
- /* Ignore */
+ version_major = (int)value[0];
+ version_minor = (int)value[1];
}
/* PresetAdd */
else if(!strcasecmp(buf, "PresetAdd"))
{
char *s = FGetString(fp);
-
/* Reset context pointers */
hdp_ptr = NULL;
palette_ptr = NULL;
@@ -168,9 +175,11 @@ int SARHumanLoadFromFile(sar_human_data_struct *hd, const char *filename)
);
hdp_ptr->name = STRDUP(s);
+ /* Set gender to default value (male) for current preset. */
+ hdp_ptr->preset_entry_flags &= ~SAR_HUMAN_FLAG_GENDER_FEMALE;
+
free(s);
}
-
/* Height */
else if(!strcasecmp(buf, "Height"))
{
@@ -184,19 +193,43 @@ int SARHumanLoadFromFile(sar_human_data_struct *hd, const char *filename)
else if(!strcasecmp(buf, "Mass"))
{
FGetValuesF(fp, value, 1);
+
+ /* Mass for a 1.90m tall human was set to 54kg in original
+ * "Version 1.0" human.ini file. It was certainly an error, so
+ * let's overwrite it to 90kg.
+ */
+ if(version_major == 1 && version_minor == 0)
+ value[0] = 90;
+
if(hdp_ptr != NULL)
{
hdp_ptr->mass = (float)MAX(value[0], 0.0); /* kg */
}
}
+ /* Gender */
+ else if(!strcasecmp(buf, "Gender"))
+ {
+ /* Male is default gender.
+ * If Female, breasts will be drawn on torso.
+ */
+
+ char *s = FGetString(fp);
+ if( (s != NULL) && (hdp_ptr != NULL) )
+ {
+ if( !strcasecmp(s, "Female") || !strcasecmp(s, "female") )
+ hdp_ptr->preset_entry_flags |= SAR_HUMAN_FLAG_GENDER_FEMALE;
+ else
+ /* default */
+ hdp_ptr->preset_entry_flags &= ~SAR_HUMAN_FLAG_GENDER_FEMALE;
+ }
+ free(s);
+ }
/* AssistingHumans */
else if(!strcasecmp(buf, "AssistingHumans"))
{
FGetValuesF(fp, value, 1);
if(hdp_ptr != NULL)
- {
- hdp_ptr->assisting_humans = MAX((int)value[0], 0);
- }
+ hdp_ptr->assisting_humans = CLIP((int)value[0], 0, SAR_ASSISTING_HUMANS_MAX);
}
diff --git a/src/obj.h b/src/obj.h
index ba75e80..edb466e 100644
--- a/src/obj.h
+++ b/src/obj.h
@@ -160,7 +160,7 @@ typedef struct {
/*
* Position/Velocity:
*
- * Each member must be of type float and their order is
+ * Each member must be of type float and their order is
* important.
*
* When used as position the units are in meters, when used as
@@ -268,7 +268,7 @@ typedef enum {
SAR_CRASH_TYPE_OBSTRUCTION,
SAR_CRASH_TYPE_GROUND,
SAR_CRASH_TYPE_MOUNTAIN, /* To be more specific than
- * just ground */
+ * just ground */
SAR_CRASH_TYPE_BUILDING,
SAR_CRASH_TYPE_AIRCRAFT, /* Not used */
SAR_CRASH_TYPE_FIRE
@@ -483,7 +483,7 @@ typedef struct {
pos_cen,
pos_max;
- /* Direction, dir_min and dir_max are deltas relative to
+ /* Direction, dir_min and dir_max are deltas relative to
* dir_cen
*
* Note that some part types interprite these values differently
@@ -890,7 +890,7 @@ typedef struct {
sar_engine_state engine_state;
time_t next_engine_on; /* Time till engine starts up (in ms) */
- /* Throttle control position. In aircraft flight model this is
+ /* Throttle control position. In aircraft flight model this is
* the actual throttle control position, in helicopter flight
* model this is the speed at which the rotors are spinning.
* Range is from 0.0 to 1.0
@@ -1135,7 +1135,7 @@ typedef struct {
*/
float radius_rate;
- /* If this is true then when a smoke unit has reached its
+ /* If this is true then when a smoke unit has reached its
* maximum size its visiblity will be reset to 0.0 (thus marking
* it as "available for use")
*/
@@ -1220,12 +1220,12 @@ typedef struct {
#define SAR_OBJECT_EXPLOSION(p) ((sar_object_explosion_struct *)(p))
-/*
+/*
* Fire:
*/
typedef struct {
- /* Cylendrical size of fire in meters, this is also used to
+ /* Cylendrical size of fire in meters, this is also used to
* calculate the fire billboard
*
* Center is at the base of the fire
@@ -1234,13 +1234,13 @@ typedef struct {
height;
time_t frame_inc_int, /* Frame increment interval, in ms */
- next_frame_inc; /* Time to increment next frame, in ms */
+ next_frame_inc; /* Time to increment next frame, in ms */
int cur_frame, /* Current frame */
frame_repeats; /* Number of times animation has cycled */
/* Number of frame repeats, 0 or less to repeat forever (or
* when life span has exceeded)
- */
+ */
int total_frame_repeats;
/* Texture number on scene */
@@ -1269,7 +1269,7 @@ typedef struct {
sar_chemical_type chemical_type;
- int owner; /* Object that created this spray or -1
+ int owner; /* Object that created this spray or -1
* for none */
/* Texture number on the scene */
@@ -1461,6 +1461,7 @@ typedef struct {
/*
* Human/Actor:
*/
+#define SAR_ASSISTING_HUMANS_MAX 4
typedef enum {
SAR_HUMAN_FLAG_NEED_RESCUE = (1 << 1),
SAR_HUMAN_FLAG_SIT = (1 << 2), /* Base at tush */
@@ -1471,7 +1472,7 @@ typedef enum {
SAR_HUMAN_FLAG_ALERT = (1 << 6), /* Is awake */
SAR_HUMAN_FLAG_AWARE = (1 << 7), /* Knows of surroundings */
SAR_HUMAN_FLAG_IN_WATER = (1 << 8),
- SAR_HUMAN_FLAG_ON_STREATCHER = (1 << 9),
+ SAR_HUMAN_FLAG_ON_STRETCHER = (1 << 9),
SAR_HUMAN_FLAG_RUN = (1 << 10), /* Animate as running */
SAR_HUMAN_FLAG_RUN_TOWARDS = (1 << 11), /* Intends to run towards
* (does not imply currently
@@ -1483,8 +1484,10 @@ typedef enum {
SAR_HUMAN_FLAG_GRIPPED = (1 << 14), /* Someone/something is
* holding this (ie in
* rescue basket */
- SAR_HUMAN_FLAG_DIVER_CATCHER = (1 << 15)
+ SAR_HUMAN_FLAG_DIVER_CATCHER = (1 << 15),
+ SAR_HUMAN_FLAG_GENDER_FEMALE = (1 << 16)
} sar_human_flags;
+
typedef struct {
sar_human_flags flags;
@@ -1511,8 +1514,8 @@ typedef struct {
* -1 No intercepting
* -2 Intercept player
*
- * Works when flags SAR_HUMAN_FLAG_RUN_TOWARDS xor
- * SAR_HUMAN_FLAG_RUN_AWAY is set and intercepting_object is
+ * Works when flags SAR_HUMAN_FLAG_RUN_TOWARDS xor
+ * SAR_HUMAN_FLAG_RUN_AWAY is set and intercepting_object is
* valid and not the human object itself.
*/
int intercepting_object;
@@ -1529,8 +1532,15 @@ typedef struct {
* humans.
*/
int assisting_humans;
+
+ /* Assisting human(s) preset name. When human has assisting humans(s),
+ * preset name of each one assisting human is stored here.
+ */
+ const char *assisting_human_preset_name[SAR_ASSISTING_HUMANS_MAX];
+
sar_color_struct assisting_human_color[SAR_HUMAN_COLORS_MAX];
+
/* Messages */
char *mesg_enter; /* Entering into aircraft or vehicle */
@@ -1634,7 +1644,7 @@ typedef struct {
/* Time stamp of when this object was created in milliseconds
- * and in systime seconds (respectivly). The value in milliseconds
+ * and in systime seconds (respectivly). The value in milliseconds
* may not be accurate when timmers are reset
*/
time_t birth_time_ms,
@@ -1736,7 +1746,7 @@ typedef struct {
*/
typedef struct {
- /* Note, cloud layer moves with camera in modulous
+ /* Note, cloud layer moves with camera in modulous
* of the tiled width and height on the XY plane
*/
@@ -1932,7 +1942,7 @@ typedef struct {
* rotate any vertex relative to the camera's rotation, each
* a 3 * 3 matrix.
* Member camera_rotmatrix_count indicates the actual number
- * of matrixes set, which is equal or less than
+ * of matrixes set, which is equal or less than
* SAR_CAMERA_ROTMATRIX_MAX
*/
#define SAR_CAMERA_ROTMATRIX_MAX 5
@@ -2031,13 +2041,13 @@ typedef struct {
time_t camera_ref_title_display_until;
/* Flight dynamics model realm structure, used by the SFM
- * library as global reference while simulating all flight
+ * library as global reference while simulating all flight
* dynamics models
*/
SFMRealmStruct *realm;
-
- /* Welcome message - to be displayed at being of game */
- char *welcome_message;
+
+ /* Welcome message - to be displayed at being of game */
+ char *welcome_message;
} sar_scene_struct;
#define SAR_SCENE(p) ((sar_scene_struct *)(p))
diff --git a/src/objio.c b/src/objio.c
index 3edc4cc..a3cb161 100644
--- a/src/objio.c
+++ b/src/objio.c
@@ -1608,6 +1608,8 @@ int SARObjLoadHuman(
core_ptr->human_data,
scene, &core_ptr->object, &core_ptr->total_objects,
p_new_human->flags,
+ p_new_human->assisting_humans,
+ p_new_human->assisting_human_preset_name,
p_new_human->type_name
);
@@ -1696,7 +1698,7 @@ int SARObjLoadSmoke(
case 2: /* Dark */
tex_name = SAR_STD_TEXNAME_SMOKE_DARK;
break;
- case 3: /* Orange */
+ case 3: /* Orange */
tex_name = SAR_STD_TEXNAME_SMOKE_ORANGE;
break;
}
diff --git a/src/sardraw.c b/src/sardraw.c
index 44b5ca4..62ba7a4 100644
--- a/src/sardraw.c
+++ b/src/sardraw.c
@@ -1962,7 +1962,7 @@ static void SARDrawHoistDeployment(
SARDrawHumanIterate(
dc,
1.9f, /* Height in meters */
- 54.0f, /* Mass in kg */
+ 90.0f, /* Mass in kg */
SAR_HUMAN_FLAG_ALERT | SAR_HUMAN_FLAG_AWARE |
SAR_HUMAN_FLAG_GRIPPED | SAR_HUMAN_FLAG_DIVER_CATCHER,
hoist->diver_color,
diff --git a/src/sardrawhuman.c b/src/sardrawhuman.c
index 150f68c..877d836 100644
--- a/src/sardrawhuman.c
+++ b/src/sardrawhuman.c
@@ -79,18 +79,37 @@ void SARDrawHumanIterate(
float left_knee_to_calv_angle, right_knee_to_calv_angle;
float thigh_len = 0.3f;
- float calv_len = 0.4f;
+ float calf_len = 0.4f;
+ float foot_height = 0.08f;
+ float foot_length;
float torso_len = 0.8f;
float bisep_len = 0.3f;
float trisep_len = 0.4f;
float base_to_torso = 0.0f; /* Ground to bottom of torso
* (calculated later).
*/
- float streatcher_height = 0.8f; /* Ground to bed of streatcher. */
+ float stretcher_height = 0.8f; /* Ground to bed of stretcher. */
const sar_color_struct *c;
Boolean draw_shadow_std = False;
+ /* Body segments length depends of human total height */
+ float height_coef = height / 1.9f; // SarII standard human height is 1.9m
+ thigh_len *= height_coef;
+ calf_len *= height_coef;
+ foot_height *= height_coef;
+ foot_length = 1.90f * 0.13f * height_coef;
+ torso_len *= height_coef;
+ bisep_len *= height_coef;
+ trisep_len *= height_coef;
+
+ /* Body width and thick depends of human mass: let's consider
+ * that standard is 1.9m / 90kg => BMI is ~25.
+ */
+ float bmi = mass / (height * height);
+ float width_coef = (bmi * 0.66f) / 25;
+ float thick_coef = (bmi * 1.2f) / 25;
+
/* Macro to set the color pointed to by c. The color must be specifying
* a color on the human's body, because dc->flir will be checked and if
* it is True then the color will be brightened.
@@ -108,7 +127,7 @@ void SARDrawHumanIterate(
StateGLDisable(state, GL_LIGHTING);
StateGLDisable(state, GL_TEXTURE_2D);
V3DTextureSelect(NULL);
- StateGLShadeModel(state, opt->gl_shade_model);
+ StateGLShadeModel(state, GL_SMOOTH);
/* Calculate angles of body parts. Note that all zero radians
* indicates human is standing upright with hands to side.
@@ -127,9 +146,9 @@ void SARDrawHumanIterate(
left_knee_to_calv_angle = (float)(0.0 * PI);
right_knee_to_calv_angle = (float)(0.0 * PI);
- base_to_torso = thigh_len + calv_len;
+ base_to_torso = thigh_len + calf_len + foot_height * height_coef;
- if(flags & SAR_HUMAN_FLAG_ON_STREATCHER)
+ if(flags & SAR_HUMAN_FLAG_ON_STRETCHER)
{
/* Some translating will be done later. */
}
@@ -178,11 +197,11 @@ void SARDrawHumanIterate(
left_trisep_angle = (float)(1.75 * PI);
right_trisep_angle = (float)(1.75 * PI);
left_hip_to_thigh_angle = (float)(1.5 * PI);
- right_hip_to_thigh_angle = (float)(1.5 * PI);
+ right_hip_to_thigh_angle = (float)(1.5 * PI);
left_knee_to_calv_angle = (float)(0.5 * PI);
right_knee_to_calv_angle = (float)(0.5 * PI);
-
- base_to_torso = calv_len;
+
+ base_to_torso = calf_len + foot_height * height_coef;
}
else if(flags & SAR_HUMAN_FLAG_DIVER_CATCHER)
{
@@ -192,11 +211,11 @@ void SARDrawHumanIterate(
right_shoulder_angle = (float)(1.9 * PI);
left_bisep_angle = (float)(1.8 * PI);
right_bisep_angle = (float)(1.8 * PI);
- left_trisep_angle = (float)(1.8 * PI);
+ left_trisep_angle = (float)(1.8 * PI);
right_trisep_angle = (float)(1.8 * PI);
left_hip_to_thigh_angle = (float)(1.9 * PI);
right_hip_to_thigh_angle = (float)(1.9 * PI);
- left_knee_to_calv_angle = (float)(0.2 * PI);
+ left_knee_to_calv_angle = (float)(0.2 * PI);
right_knee_to_calv_angle = (float)(0.2 * PI);
/* If gripped it implies on end of rescue hoist rope. */
@@ -205,7 +224,7 @@ void SARDrawHumanIterate(
else if(flags & SAR_HUMAN_FLAG_IN_WATER)
base_to_torso = torso_len * -0.92f;
else
- base_to_torso = thigh_len + calv_len;
+ base_to_torso = thigh_len + calf_len + foot_height * height_coef;
}
/* Run should be checked last since lying and setting have
* precidence.
@@ -251,7 +270,7 @@ void SARDrawHumanIterate(
left_knee_to_calv_angle = (float)(0.2 * PI);
right_knee_to_calv_angle = (float)(0.2 * PI);
- base_to_torso = thigh_len + calv_len;
+ base_to_torso = thigh_len + calf_len + foot_height * height_coef;
draw_shadow_std = True;
}
@@ -273,7 +292,7 @@ void SARDrawHumanIterate(
left_bisep_angle = (float)(1.5 * PI);
right_bisep_angle = (float)(1.5 * PI);
left_trisep_angle = (float)(0.0 * PI);
- right_trisep_angle = (float)(0.0 * PI);
+ right_trisep_angle = (float)(0.0 * PI);
left_hip_to_thigh_angle = (float)(0.0 * PI);
right_hip_to_thigh_angle = (float)(0.0 * PI);
left_knee_to_calv_angle = (float)(0.0 * PI);
@@ -315,7 +334,7 @@ void SARDrawHumanIterate(
left_knee_to_calv_angle = (float)(0.0 * PI);
right_knee_to_calv_angle = (float)(0.0 * PI);
- base_to_torso = thigh_len + calv_len;
+ base_to_torso = thigh_len + calf_len + foot_height * height_coef;
}
else
{
@@ -332,7 +351,7 @@ void SARDrawHumanIterate(
left_knee_to_calv_angle = (float)(0.0 * PI);
right_knee_to_calv_angle = (float)(0.0 * PI);
- base_to_torso = thigh_len + calv_len;
+ base_to_torso = thigh_len + calf_len + foot_height * height_coef;
}
draw_shadow_std = True;
}
@@ -345,7 +364,7 @@ void SARDrawHumanIterate(
/* Draw shadow? */
if(draw_shadow_std)
{
- float theta, r = 0.5f;
+ float theta, r = 0.07f + height / 4.4f;
StateGLBoolean lighting = state->lighting;
StateGLBoolean depth_mask_flag = state->depth_mask_flag;
GLenum shade_model_mode = state->shade_model_mode;
@@ -387,15 +406,15 @@ void SARDrawHumanIterate(
StateGLShadeModel(state, shade_model_mode);
}
- /* Draw streatcher? */
- if(flags & SAR_HUMAN_FLAG_ON_STREATCHER)
+ /* Draw stretcher? */
+ if(flags & SAR_HUMAN_FLAG_ON_STRETCHER)
{
float x = 0.35f, y = 1.05f;
- float h = streatcher_height - 0.1f, hl = 0.1f;
+ float h = stretcher_height - 0.1f, hl = 0.1f;
glColor4f(0.8f, 0.8f, 0.8f, 1.0f);
- /* Bed of streatcher. */
+ /* Bed of stretcher. */
glBegin(GL_QUADS);
{
glNormal3f(0.0f, 1.0f, 0.0f);
@@ -426,7 +445,7 @@ void SARDrawHumanIterate(
glEnd();
/* Right grids. */
- glBegin(GL_LINE_LOOP);
+ glBegin(GL_LINE_LOOP);
{
glNormal3f(1.0, 0.0, 0.0);
glVertex3f(x, hl, -y);
@@ -439,7 +458,7 @@ void SARDrawHumanIterate(
glColor4f(0.1f, 0.1f, 0.1f, 1.0f);
- /* Simple square wheels. */
+ /* Simple square wheels, outside / inside. */
glBegin(GL_QUADS);
{
glNormal3f(-1.0f, 0.0f, 0.0f);
@@ -447,16 +466,28 @@ void SARDrawHumanIterate(
glVertex3f(-x, 0.0f, -(y - 0.1f));
glVertex3f(-x, hl, -(y - 0.1f));
glVertex3f(-x, hl, -y);
+
+ glNormal3f(1.0f, 0.0f, 0.0f);
+ glVertex3f(-x, 0.0f, -y);
+ glVertex3f(-x, hl, -y);
+ glVertex3f(-x, hl, -(y - 0.1f));
+ glVertex3f(-x, 0.0f, -(y - 0.1f));
}
glEnd();
- glBegin(GL_QUADS);
+ glBegin(GL_QUADS);
{
glNormal3f(-1.0f, 0.0f, 0.0f);
glVertex3f(-x, hl, y);
glVertex3f(-x, hl, (y - 0.1f));
- glVertex3f(-x, 0.0f, (y - 0.1f));
+ glVertex3f(-x, 0.0f, (y - 0.1f));
glVertex3f(-x, 0.0f, y);
+
+ glNormal3f(1.0f, 0.0f, 0.0f);
+ glVertex3f(-x, hl, y);
+ glVertex3f(-x, 0.0f, y);
+ glVertex3f(-x, 0.0f, (y - 0.1f));
+ glVertex3f(-x, hl, (y - 0.1f));
}
glEnd();
@@ -467,6 +498,12 @@ void SARDrawHumanIterate(
glVertex3f(x, hl, -y);
glVertex3f(x, hl, -(y - 0.1f));
glVertex3f(x, 0.0f, -(y - 0.1f));
+
+ glNormal3f(-1.0f, 0.0f, 0.0f);
+ glVertex3f(x, 0.0f, -y);
+ glVertex3f(x, 0.0f, -(y - 0.1f));
+ glVertex3f(x, hl, -(y - 0.1f));
+ glVertex3f(x, hl, -y);
}
glEnd();
@@ -477,6 +514,12 @@ void SARDrawHumanIterate(
glVertex3f(x, hl, (y - 0.1f));
glVertex3f(x, hl, y);
glVertex3f(x, 0.0f, y);
+
+ glNormal3f(-1.0f, 0.0f, 0.0f);
+ glVertex3f(x, 0.0f, (y - 0.1f));
+ glVertex3f(x, 0.0f, y);
+ glVertex3f(x, hl, y);
+ glVertex3f(x, hl, (y - 0.1f));
}
glEnd();
}
@@ -486,14 +529,14 @@ void SARDrawHumanIterate(
/* Torso. */
glPushMatrix();
{
- /* Check if on streatcher, if so translate up. */
- if(flags & SAR_HUMAN_FLAG_ON_STREATCHER)
+ /* Check if on stretcher, if so translate up. */
+ if(flags & SAR_HUMAN_FLAG_ON_STRETCHER)
{
/* Push on extra matrix and move up (matrix poped later). */
glPushMatrix();
glTranslatef(
0.0f,
- streatcher_height,
+ stretcher_height,
-(base_to_torso + 0.2f)
);
}
@@ -513,31 +556,144 @@ void SARDrawHumanIterate(
SET_BODY_COLOR
glBegin(GL_QUADS);
{
- SARDrawBoxBaseNS(
- 0.45f * torso_len,
- 0.25f * torso_len,
+ SARDrawBoxBaseNS(
+ 0.45f * torso_len * width_coef,
+ 0.25f * torso_len * thick_coef,
0.10f * torso_len,
True
);
}
glEnd();
-
- glTranslatef(0.0f, 0.10f * torso_len, 0.0f);
-
- /* Upper torso. */
- c = &palette[SAR_HUMAN_COLOR_TORSO];
- SET_BODY_COLOR
- glBegin(GL_QUADS);
+ if( !(flags & SAR_HUMAN_FLAG_GENDER_FEMALE) )
{
- SARDrawBoxBaseNS(
- 0.45f * torso_len,
- 0.25f * torso_len,
- 0.90f * torso_len,
- False
- );
+ /* Male upper torso (default torso). */
+ glTranslatef(0.0f, 0.10f * torso_len, 0.0f);
+
+ c = &palette[SAR_HUMAN_COLOR_TORSO];
+ SET_BODY_COLOR
+ glBegin(GL_QUADS);
+ {
+ SARDrawBoxBaseNS(
+ 0.45f * torso_len * width_coef,
+ 0.25f * torso_len * thick_coef,
+ 0.90f * torso_len,
+ False
+ );
+ }
+ glEnd();
+ }
+ else
+ {
+ /* Female upper torso. */
+ glTranslatef(0.0f, 0.10f * torso_len, 0.0f);
+
+ float half_thick = (0.25f * torso_len * thick_coef) / 2.0f;
+ float half_width = 0.45f * torso_len * width_coef / 2.0f;
+ float torso_z0 = 0.0f;
+ float torso_z4 = 0.90f * torso_len;
+ float torso_z1 = torso_z4 - 0.25f * height_coef;
+ float torso_z2 = torso_z4 - 0.19f * height_coef;
+ float torso_y2 = -half_thick - 0.08f * thick_coef;
+ float torso_z3 = torso_z4 - 0.10f * height_coef;
+
+ c = &palette[SAR_HUMAN_COLOR_TORSO];
+ SET_BODY_COLOR
+ glBegin(GL_TRIANGLES);
+ glNormal3f(0.518700, 0.173200, -0.837200);
+ glVertex3f(-half_width, torso_z3,-half_thick);
+ glNormal3f(0.754400, -0.069900, -0.652600);
+ glVertex3f(-half_width, torso_z2, torso_y2);
+ glNormal3f(0.503600, -0.157200, -0.849500);
+ glVertex3f(-half_width, torso_z1,-half_thick);
+ glEnd();
+ glBegin(GL_POLYGON);
+ glNormal3f(0.444300, 0.011200, -0.895800);
+ glVertex3f(-half_width, -torso_z0,-half_thick);
+ glNormal3f(-0.372500, 0.082900, -0.924300);
+ glVertex3f(-half_width, torso_z0, half_thick);
+ glNormal3f(-0.322800, 0.427900, -0.844200);
+ glVertex3f(-half_width, torso_z4, half_thick);
+ glNormal3f(0.381800, 0.424900, -0.820800);
+ glVertex3f(-half_width, torso_z4,-half_thick);
+ glNormal3f(0.513300, 0.187400, -0.837500);
+ glVertex3f(-half_width, torso_z3,-half_thick);
+ glNormal3f(0.497900, -0.169600, -0.850500);
+ glVertex3f(-half_width, torso_z1,-half_thick);
+ glEnd();
+ glBegin(GL_TRIANGLES);
+ glNormal3f(0.754400, -0.069900, 0.652600);
+ glVertex3f(half_width, torso_z2, torso_y2);
+ glNormal3f(0.518700, 0.173200, 0.837200);
+ glVertex3f(half_width, torso_z3,-half_thick);
+ glNormal3f(0.503600, -0.157200, 0.849500);
+ glVertex3f(half_width, torso_z1,-half_thick);
+ glEnd();
+ glBegin(GL_POLYGON);
+ glNormal3f(0.513300, 0.187300, 0.837500);
+ glVertex3f(half_width, torso_z3,-half_thick);
+ glNormal3f(0.381800, 0.424900, 0.820800);
+ glVertex3f(half_width, torso_z4,-half_thick);
+ glNormal3f(-0.322700, 0.427900, 0.844200);
+ glVertex3f(half_width, torso_z4, half_thick);
+ glNormal3f(-0.372500, 0.082900, 0.924300);
+ glVertex3f(half_width, torso_z0, half_thick);
+ glNormal3f(0.444300, 0.011200, 0.895800);
+ glVertex3f(half_width, -torso_z0,-half_thick);
+ glNormal3f(0.497900, -0.169600, 0.850500);
+ glVertex3f(half_width, torso_z1,-half_thick);
+ glEnd();
+ glBegin(GL_QUADS);
+ glNormal3f(-0.334300, 0.736800, -0.587600);
+ glVertex3f(-half_width, torso_z4, half_thick);
+ glNormal3f(-0.334300, 0.736800, 0.587600);
+ glVertex3f(half_width, torso_z4, half_thick);
+ glNormal3f(0.391200, 0.731400, 0.558500);
+ glVertex3f(half_width, torso_z4,-half_thick);
+ glNormal3f(0.391200, 0.731400, -0.558500);
+ glVertex3f(-half_width, torso_z4,-half_thick);
+ glNormal3f(0.697400, 0.439900, -0.565900);
+ glVertex3f(-half_width, torso_z4,-half_thick);
+ glNormal3f(0.697400, 0.439900, 0.565900);
+ glVertex3f(half_width, torso_z4,-half_thick);
+ glNormal3f(0.800600, 0.188700, 0.568800);
+ glVertex3f(half_width, torso_z3,-half_thick);
+ glNormal3f(0.800600, 0.188800, -0.568700);
+ glVertex3f(-half_width, torso_z3,-half_thick);
+ glNormal3f(0.737800, 0.360800, -0.570500);
+ glVertex3f(-half_width, torso_z3,-half_thick);
+ glNormal3f(0.737800, 0.360800, 0.570500);
+ glVertex3f(half_width, torso_z3,-half_thick);
+ glNormal3f(0.937200, 0.101800, 0.333500);
+ glVertex3f(half_width, torso_z2, torso_y2);
+ glNormal3f(0.937200, 0.101800, -0.333500);
+ glVertex3f(-half_width, torso_z2, torso_y2);
+ glNormal3f(0.901200, -0.275700, -0.334300);
+ glVertex3f(-half_width, torso_z2, torso_y2);
+ glNormal3f(0.901200, -0.275700, 0.334300);
+ glVertex3f(half_width, torso_z2, torso_y2);
+ glNormal3f(0.696600, -0.396100, 0.598200);
+ glVertex3f(half_width, torso_z1,-half_thick);
+ glNormal3f(0.696600, -0.396100, -0.598200);
+ glVertex3f(-half_width, torso_z1,-half_thick);
+ glNormal3f(0.791000, -0.173400, -0.586700);
+ glVertex3f(-half_width, torso_z1,-half_thick);
+ glNormal3f(0.791000, -0.173400, 0.586700);
+ glVertex3f(half_width, torso_z1,-half_thick);
+ glNormal3f(0.753300, 0.011400, 0.657600);
+ glVertex3f(half_width, -torso_z0,-half_thick);
+ glNormal3f(0.753300, 0.011400, -0.657600);
+ glVertex3f(-half_width, -torso_z0,-half_thick);
+ glNormal3f(-0.699600, 0.086600, -0.709300);
+ glVertex3f(-half_width, torso_z0, half_thick);
+ glNormal3f(-0.699600, 0.086600, 0.709300);
+ glVertex3f(half_width, torso_z0, half_thick);
+ glNormal3f(-0.652000, 0.454400, 0.606900);
+ glVertex3f(half_width, torso_z4, half_thick);
+ glNormal3f(-0.652000, 0.454400, -0.606900);
+ glVertex3f(-half_width, torso_z4, half_thick);
+ glEnd();
}
- glEnd();
}
glPopMatrix();
/* Back to base of torso. */
@@ -550,7 +706,7 @@ void SARDrawHumanIterate(
(GLfloat)-SFMRadiansToDegrees(left_hip_to_thigh_angle),
1.0f, 0.0f, 0.0f
);
- glTranslatef(-0.16f * torso_len, 0.0f, 0.0f);
+ glTranslatef(-0.16f * torso_len * width_coef, 0.0f, 0.0f);
c = &palette[SAR_HUMAN_COLOR_LEGS];
SET_BODY_COLOR
@@ -558,8 +714,8 @@ void SARDrawHumanIterate(
glBegin(GL_QUADS);
{
SARDrawBoxBaseNS(
- 0.5f * thigh_len,
- 0.5f * thigh_len,
+ 0.5f * thigh_len * width_coef,
+ 0.5f * thigh_len * thick_coef,
-thigh_len,
True
);
@@ -578,16 +734,16 @@ void SARDrawHumanIterate(
glBegin(GL_QUADS);
{
SARDrawBoxBaseNS(
- 0.3f * calv_len,
- 0.3f * calv_len,
- -calv_len,
+ 0.3f * calf_len * width_coef,
+ 0.3f * calf_len * thick_coef,
+ -calf_len,
True
);
}
glEnd();
/* Feet. */
- glTranslatef(0.0f, -calv_len, -0.05f);
+ glTranslatef(0.0f, -calf_len, -0.05f);
c = &palette[SAR_HUMAN_COLOR_FEET];
SET_BODY_COLOR
@@ -595,9 +751,9 @@ void SARDrawHumanIterate(
glBegin(GL_QUADS);
{
SARDrawBoxBaseNS(
- 0.1f,
- 0.2f,
- -0.1f,
+ 0.1f * width_coef,
+ foot_length,
+ -foot_height * height_coef,
True
);
}
@@ -614,7 +770,7 @@ void SARDrawHumanIterate(
(GLfloat)-SFMRadiansToDegrees(right_hip_to_thigh_angle),
1.0f, 0.0f, 0.0f
);
- glTranslatef(0.16f * torso_len, 0.0f, 0.0f);
+ glTranslatef(0.16f * torso_len * width_coef, 0.0f, 0.0f);
c = &palette[SAR_HUMAN_COLOR_LEGS];
SET_BODY_COLOR
@@ -622,14 +778,14 @@ void SARDrawHumanIterate(
glBegin(GL_QUADS);
{
SARDrawBoxBaseNS(
- 0.5f * thigh_len,
- 0.5f * thigh_len,
+ 0.5f * thigh_len * width_coef,
+ 0.5f * thigh_len * thick_coef,
-thigh_len,
True
- );
+ );
}
- glEnd();
-
+ glEnd();
+
/* Calv. */
glTranslatef(0.0f, -thigh_len, 0.0f);
glRotatef(
@@ -642,16 +798,16 @@ void SARDrawHumanIterate(
glBegin(GL_QUADS);
{
SARDrawBoxBaseNS(
- 0.3f * calv_len,
- 0.3f * calv_len,
- -calv_len,
+ 0.3f * calf_len * width_coef,
+ 0.3f * calf_len * thick_coef,
+ -calf_len,
True
);
}
glEnd();
/* Feet. */
- glTranslatef(0.0f, -calv_len, -0.05f);
+ glTranslatef(0.0f, -calf_len, -0.05f);
c = &palette[SAR_HUMAN_COLOR_FEET];
SET_BODY_COLOR
@@ -659,9 +815,9 @@ void SARDrawHumanIterate(
glBegin(GL_QUADS);
{
SARDrawBoxBaseNS(
- 0.1f,
- 0.2f,
- -0.1f,
+ 0.1f * width_coef,
+ foot_length,
+ -foot_height * height_coef,
True
);
}
@@ -678,7 +834,7 @@ void SARDrawHumanIterate(
{
/* Bisep and shoulder. */
glTranslatef(
- (-0.225f * torso_len) + (-0.25f * bisep_len),
+ (-0.225f * torso_len + -0.25f * bisep_len) * width_coef,
0.0f,
0.0f
);
@@ -697,8 +853,8 @@ void SARDrawHumanIterate(
glBegin(GL_QUADS);
{
SARDrawBoxBaseNS(
- 0.5f * bisep_len,
- 0.5f * bisep_len,
+ 0.5f * bisep_len * width_coef,
+ 0.5f * bisep_len * thick_coef,
-bisep_len,
True
);
@@ -715,8 +871,8 @@ void SARDrawHumanIterate(
glBegin(GL_QUADS);
{
SARDrawBoxBaseNS(
- 0.28f * trisep_len,
- 0.28f * trisep_len,
+ 0.28f * trisep_len * width_coef,
+ 0.28f * trisep_len * thick_coef,
-trisep_len,
True
);
@@ -732,7 +888,7 @@ void SARDrawHumanIterate(
glBegin(GL_QUADS);
{
- SARDrawBoxBaseNS(0.2f, 0.1f, -0.2f, True);
+ SARDrawBoxBaseNS((0.28f * trisep_len + 0.06f) * width_coef, 0.06f * thick_coef, -0.50f * trisep_len, True);
}
glEnd();
}
@@ -744,7 +900,7 @@ void SARDrawHumanIterate(
{
/* Bisep. */
glTranslatef(
- (0.225f * torso_len) + (0.25f * bisep_len),
+ (0.225f * torso_len + 0.25f * bisep_len) * width_coef,
0.0f,
0.0f
);
@@ -763,8 +919,8 @@ void SARDrawHumanIterate(
glBegin(GL_QUADS);
{
SARDrawBoxBaseNS(
- 0.5f * bisep_len,
- 0.5f * bisep_len,
+ 0.5f * bisep_len * width_coef,
+ 0.5f * bisep_len * thick_coef,
-bisep_len,
True
);
@@ -781,8 +937,8 @@ void SARDrawHumanIterate(
glBegin(GL_QUADS);
{
SARDrawBoxBaseNS(
- 0.28f * trisep_len,
- 0.28f * trisep_len,
+ 0.28f * trisep_len * width_coef,
+ 0.28f * trisep_len * thick_coef,
-trisep_len,
True
);
@@ -798,7 +954,7 @@ void SARDrawHumanIterate(
glBegin(GL_QUADS);
{
- SARDrawBoxBaseNS(0.2f, 0.1f, -0.2f, True);
+ SARDrawBoxBaseNS((0.28f * trisep_len + 0.06f) * width_coef, 0.06f * thick_coef, -0.50f * trisep_len, True);
}
glEnd();
}
@@ -806,51 +962,79 @@ void SARDrawHumanIterate(
/* Back to shoulders. */
- /* Head. */
- glTranslatef(0.0f, 0.05f * torso_len, 0.0f);
-
- c = &palette[SAR_HUMAN_COLOR_FACE];
- SET_BODY_COLOR
+ /* Head and hair. */
+ float head_height = 0.22f * height_coef;
+ head_height = (head_height >= 0.13) ? (head_height) : (0.13f);
+ float hairs_height = 0.1f * height_coef;
+ /* Do not apply whole thick coefficient to head */
+ float head_thick = 0.18f * (thick_coef / 1.5f);
- glBegin(GL_QUADS);
+ /* Check if hair color is transparent. If true, human is bald (has no head hair). */
+ if ((&palette[SAR_HUMAN_COLOR_HAIR])->a == 0.0f)
{
- SARDrawBoxBaseNS(0.18f, 0.18f, 0.25f, False);
- }
- glEnd();
+ head_height += hairs_height / 3.0f;
-
- /* Hair. */
- glPushMatrix();
- {
- glTranslatef(0.0f, 0.25f, 0.0f);
-
- c = &palette[SAR_HUMAN_COLOR_HAIR];
+ /* Head */
+ c = &palette[SAR_HUMAN_COLOR_FACE];
SET_BODY_COLOR
+ glTranslatef(0.0f, 0.05f * torso_len * height_coef, 0.0f);
glBegin(GL_QUADS);
{
- SARDrawBoxBaseNS(0.18f, 0.18f, 0.1f, False);
+ SARDrawBoxBaseNS(0.18f * width_coef, head_thick, head_height, True);
}
glEnd();
+
+ /* Dont' draw hair. */
}
- glPopMatrix();
- /* Back of head hair. */
- glPushMatrix();
+ else
{
- glTranslatef(0.0f, 0.05f, -(-0.09f - 0.03f));
+ /* Head */
+ c = &palette[SAR_HUMAN_COLOR_FACE];
+ SET_BODY_COLOR
+
+ glTranslatef(0.0f, 0.05f * torso_len * height_coef, 0.0f);
glBegin(GL_QUADS);
{
- SARDrawBoxBaseNS(0.18f, 0.06f, 0.25f, True);
+ SARDrawBoxBaseNS(0.18f * width_coef, head_thick, head_height, True);
}
glEnd();
+
+ /* Hair. */
+ glPushMatrix();
+ {
+ /* Move to head top */
+ glTranslatef(0.0f, head_height, 0.0f);
+
+ c = &palette[SAR_HUMAN_COLOR_HAIR];
+ SET_BODY_COLOR
+
+ glBegin(GL_QUADS);
+ {
+ SARDrawBoxBaseNS(0.18f * width_coef, head_thick, hairs_height, False);
+ }
+ glEnd();
+ }
+ glPopMatrix();
+
+ /* Back of head hair. */
+ glPushMatrix();
+ {
+ glTranslatef(0.0f, 0.05f * height_coef, (head_thick / 2.0f) + 0.05f / 2.0f);
+ glBegin(GL_QUADS);
+ {
+ SARDrawBoxBaseNS(0.18f * width_coef, 0.05f, head_height, True);
+ }
+ glEnd();
+ }
+ glPopMatrix();
}
- glPopMatrix();
- /* Check if on streatcher, if so we need to pop one matrix
- * level that was added for translation up on to streatcher.
+ /* Check if on stretcher, if so we need to pop one matrix
+ * level that was added for translation up on to stretcher.
*/
- if(flags & SAR_HUMAN_FLAG_ON_STREATCHER)
+ if(flags & SAR_HUMAN_FLAG_ON_STRETCHER)
{
glPopMatrix();
}
@@ -967,26 +1151,35 @@ void SARDrawHuman(
{
int i;
sar_obj_flags_t flags;
- float s = 0.8f; /* Left/right spacing. */
+ float slr = 0.8f; /* Left/right spacing. */
+ float sfr; /* Front/rear spacing, from stretcher center. */
+ const sar_human_data_entry_struct *assisting_human;
- /* Draw all assisting human objects, left and right. */
+ if(human->assisting_humans <= 2)
+ /* Shitf a bit behind stretcher center. */
+ sfr = 0.2f;
+ else
+ /* Shift to stretcher rear end. */
+ sfr = 0.9f;
+
+ /* Draw one to four assisting human objects */
for(i = 0; i < human->assisting_humans; i++)
{
glPushMatrix();
{
- /* Translate to the side and a bit behind. */
- glTranslatef(s, 0.0f, 0.2f);
+ /* Translate to assistant position. */
+ glTranslatef(slr, 0.0f, sfr);
/* Set up `filtered' human flags that will be
* passed to the human draw itteration function.
- * This is so that we don't pass all the flags,
+ * This is so that we don't pass all the flags,
* because in some situations the human may be
- * lying on a streatcher and the assisting humans
+ * lying on a stretcher and the assisting humans
* need to be running.
*/
flags = 0;
if(human->flags & SAR_HUMAN_FLAG_ALERT)
- flags |= SAR_HUMAN_FLAG_ALERT;
+ flags |= SAR_HUMAN_FLAG_ALERT;
if(human->flags & SAR_HUMAN_FLAG_AWARE)
flags |= SAR_HUMAN_FLAG_AWARE;
if(human->flags & SAR_HUMAN_FLAG_IN_WATER)
@@ -996,22 +1189,40 @@ void SARDrawHuman(
if(human->flags & SAR_HUMAN_FLAG_PUSHING)
flags |= SAR_HUMAN_FLAG_PUSHING;
- /* Draw our human object as an assisting human,
- * using the filtered human flags and the
- * assisting_human_color color palette
- */
- SARDrawHumanIterate(
- dc,
- human->height, human->mass,
- flags, human->assisting_human_color,
- human->water_ripple_tex_num,
- human->anim_pos
+ assisting_human = SARHumanMatchEntryByName(
+ dc->core_ptr->human_data, human->assisting_human_preset_name[i]
);
+ /* Human preset name not found? */
+ if(assisting_human == NULL)
+ /* Use default assisting human preset. */
+ assisting_human = SARHumanMatchEntryByName(
+ dc->core_ptr->human_data, SAR_HUMAN_PRESET_NAME_ASSISTING_HUMAN
+ );
+
+ if(assisting_human != NULL)
+ {
+ /* Propagate assisting human gender to flags. */
+ if(assisting_human->preset_entry_flags & SAR_HUMAN_FLAG_GENDER_FEMALE)
+ flags |= SAR_HUMAN_FLAG_GENDER_FEMALE;
+
+ /* Draw assisting human. */
+ SARDrawHumanIterate(
+ dc,
+ assisting_human->height, assisting_human->mass,
+ flags, assisting_human->color,
+ human->water_ripple_tex_num,
+ human->anim_pos
+ );
+ }
}
glPopMatrix();
- /* Shift spacing to other side. */
- s *= -1.0;
+ /* Shift left/right spacing to other side. */
+ slr *= -1.0;
+
+ /* When second assistant has been drawn, shift to stretcher front end. */
+ if(i == 1)
+ sfr *= -1.0;
}
}
}
diff --git a/src/sarfio.h b/src/sarfio.h
index fd0dc52..104d319 100644
--- a/src/sarfio.h
+++ b/src/sarfio.h
@@ -432,6 +432,8 @@ typedef struct {
int type;
char *type_name;
sar_obj_flags_t flags; /* Any of SAR_HUMAN_FLAG_* */
+ int assisting_humans; /* Assisting humans number. */
+ char *assisting_human_preset_name[SAR_ASSISTING_HUMANS_MAX]; /* Assisting human(s) preset name. */
} sar_parm_new_human_struct;
diff --git a/src/sarfioopen.c b/src/sarfioopen.c
index 740c0f0..3071f55 100644
--- a/src/sarfioopen.c
+++ b/src/sarfioopen.c
@@ -32,6 +32,7 @@
#include "sarfio.h"
#include "config.h"
#include "sfm.h"
+#include "human.h"
static const char *NEXT_ARG(const char *s);
static void CHOP_STR_BLANK(char *s);
@@ -1127,7 +1128,8 @@ static int SARParmLoadFromFileIterate(
*
*
*
- *
+ *
+ *
*/
/* First argument is type name */
@@ -1172,11 +1174,59 @@ static int SARParmLoadFromFileIterate(
strcasepfx(cstrptr, "inwater")
)
pv->flags |= SAR_HUMAN_FLAG_IN_WATER;
- /* On streatcher? */
- else if(strcasepfx(cstrptr, "on_streatcher") ||
- strcasepfx(cstrptr, "onstreatcher")
+ /* On stretcher? */
+ else if(strcasepfx(cstrptr, "on_stretcher") ||
+ strcasepfx(cstrptr, "onstretcher") ||
+ strcasepfx(cstrptr, "on_streatcher")||
+ strcasepfx(cstrptr, "onstreatcher")
)
- pv->flags |= SAR_HUMAN_FLAG_ON_STREATCHER;
+ pv->flags |= SAR_HUMAN_FLAG_ON_STRETCHER;
+ /* Assisted? */
+ else if(strcasepfx(cstrptr, "assisted") ||
+ strcasepfx(cstrptr, "assistants") ||
+ strcasepfx(cstrptr, "assistant")
+ )
+ {
+ cstrptr = NEXT_ARG(cstrptr);
+ if((cstrptr != NULL) ? (*cstrptr != '\0') : 0)
+ {
+ if(isdigit(cstrptr[0]))
+ /* Assisting_humans number found. */
+ {
+ pv->assisting_humans = ( ATOI(cstrptr) <= SAR_ASSISTING_HUMANS_MAX ?
+ ATOI(cstrptr) : SAR_ASSISTING_HUMANS_MAX);
+
+ if(pv->assisting_humans < 0)
+ pv->assisting_humans = 0;
+
+ /* Save name of assisting human(s) preset(s) */
+ for(int j = 0; j < pv->assisting_humans; j++)
+ {
+ cstrptr = NEXT_ARG(cstrptr);
+ if((cstrptr != NULL) ? (*cstrptr != '\0') : 0)
+ {
+ pv->assisting_human_preset_name[j] = STRDUP(cstrptr);
+ CHOP_STR_BLANK(pv->assisting_human_preset_name[j]);
+ }
+ else
+ pv->assisting_human_preset_name[j] = STRDUP(SAR_HUMAN_PRESET_NAME_ASSISTING_HUMAN);
+ }
+ }
+ else
+ /* Assisting_humans number not found. */
+ {
+ pv->assisting_humans = 0;
+ /* Allow to re-read current parameter at next loop. */
+ cstrptr--;
+ }
+ }
+ if(pv->assisting_humans == 0)
+ fprintf(
+ stderr,
+"%s: %i: Warning: Assisting humans number missing or null.\n",
+ filename, *lines_read
+ );
+ }
else
fprintf(
stderr,
diff --git a/src/sarfiosave.c b/src/sarfiosave.c
index 3f6bcf5..d2054b9 100644
--- a/src/sarfiosave.c
+++ b/src/sarfiosave.c
@@ -632,6 +632,16 @@ static int SARParmSaveToFileAnyIterate(
fprintf(fp, " aware");
if(pv->flags & SAR_HUMAN_FLAG_IN_WATER)
fprintf(fp, " in_water");
+ if(pv->flags & SAR_HUMAN_FLAG_ON_STRETCHER)
+ fprintf(fp, " on_stretcher");
+ if(pv->assisting_humans > 0)
+ {
+ /* Assisting humans number */
+ fprintf(fp, " assisted %d", pv->assisting_humans);
+ /* Assisting humans preset name(s) */
+ for(int i = 0; i < pv->assisting_humans; i++)
+ fprintf(fp, " %s", pv->assisting_human_preset_name[i]);
+ }
fputc('\n', fp);
parms_saved++;
#undef PARM_TYPE
diff --git a/src/simop.c b/src/simop.c
index aed37b4..e43ba5d 100644
--- a/src/simop.c
+++ b/src/simop.c
@@ -921,7 +921,7 @@ void SARSimSetAircraftCrashed(
/* Not in water (need to work on this) */
human->flags &= ~SAR_HUMAN_FLAG_IN_WATER;
- human->flags &= ~SAR_HUMAN_FLAG_ON_STREATCHER;
+ human->flags &= ~SAR_HUMAN_FLAG_ON_STRETCHER;
}
break;
@@ -3409,7 +3409,7 @@ void SARSimApplyGCTL(sar_core_struct *core_ptr, sar_object_struct *obj_ptr)
}
/* Is door fully opened ? */
- if (door_ptr->flags & SAR_OBJ_PART_FLAG_DOOR_OPENED)
+ if(door_ptr->flags & SAR_OBJ_PART_FLAG_DOOR_OPENED)
{
/* Was rope previously in? */
if(hoist->rope_cur < hoist->contact_z_max)
@@ -3420,8 +3420,8 @@ void SARSimApplyGCTL(sar_core_struct *core_ptr, sar_object_struct *obj_ptr)
sar_position_struct *hoist_pos = &hoist->pos,
*hoist_offset = &hoist->offset;
double tx = hoist_offset->x,
- ty = hoist_offset->y,
- tz = hoist_offset->z;
+ ty = hoist_offset->y,
+ tz = hoist_offset->z;
/* Move to initial position at hoist center */
SFMOrthoRotate2D(
diff --git a/src/simutils.c b/src/simutils.c
index 1e4bc07..f2f694e 100644
--- a/src/simutils.c
+++ b/src/simutils.c
@@ -2561,7 +2561,7 @@ int SARSimDoPickUpHuman(
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_LYING;
/* Leave SAR_HUMAN_FLAG_ALERT and SAR_HUMAN_FLAG_AWARE as is */
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_IN_WATER;
- obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_ON_STREATCHER;
+ obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_ON_STRETCHER;
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_RUN;
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_RUN_TOWARDS;
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_RUN_AWAY;
@@ -2578,7 +2578,7 @@ int SARSimDoPickUpHuman(
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_LYING;
/* Leave SAR_HUMAN_FLAG_ALERT and SAR_HUMAN_FLAG_AWARE as is */
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_IN_WATER;
- obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_ON_STREATCHER;
+ obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_ON_STRETCHER;
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_RUN;
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_RUN_TOWARDS;
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_RUN_AWAY;
@@ -2595,7 +2595,7 @@ int SARSimDoPickUpHuman(
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_LYING;
/* Leave SAR_HUMAN_FLAG_ALERT and SAR_HUMAN_FLAG_AWARE as is */
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_IN_WATER;
- obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_ON_STREATCHER;
+ obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_ON_STRETCHER;
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_RUN;
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_RUN_TOWARDS;
obj_human_ptr->flags &= ~SAR_HUMAN_FLAG_RUN_AWAY;
@@ -2854,16 +2854,13 @@ int SARSimBoardObject(
break;
}
-
- /* Begin moving source object into target object */
-
/* Increment passengers count */
*passengers = MAX(*passengers, 0) + 1;
/* Increment passengers mass if possible */
if(passengers_mass != NULL)
*passengers_mass = MAX(*passengers_mass, 0.0f) + src_mass;
-
+
/* If a mission is active then call the mission passengers enter
* notify callback
*/