这是indexloc提供的服务,不要输入任何密码
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions cpp/coord/camgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,9 @@ phys3_delta camgame_delta::to_phys3(phys_t up) {
// apply scaling factor, to get 'scaled'
// scaling factor: w/2 for x, h/2 for y
// plus the phys_per_tu fixed-point scaling factor
vec2 scaled;
scaled.x = (settings::phys_per_tile * (phys_t) x) /
(phys_t) engine_coord_data->tile_halfsize.x;
scaled.y = (settings::phys_per_tile * (phys_t) y) /
(phys_t) engine_coord_data->tile_halfsize.y;
phys_t scaled_x = phys_t{x} / phys_t{engine_coord_data->tile_halfsize.x};
phys_t scaled_y = phys_t{y} / phys_t{engine_coord_data->tile_halfsize.y};


// apply transformation matrix to 'scaled',
// to get the relative phys3 position
Expand All @@ -46,8 +44,8 @@ phys3_delta camgame_delta::to_phys3(phys_t up) {
// (se) = (+0.5 -0.5 -0.5) (scaled.y)
// (up) = (+0.0 +0.0 +1.0) ( up)
phys3_delta result;
result.ne = (scaled.x + scaled.y + up)/2;
result.se = (scaled.x - scaled.y - up)/2;
result.ne = (scaled_x + scaled_y + up) / 2;
result.se = (scaled_x - scaled_y - up) / 2;
result.up = ( up);

return result;
Expand Down
6 changes: 2 additions & 4 deletions cpp/coord/chunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ namespace coord {

tile chunk::to_tile(tile_delta pos_on_chunk) {
tile result;
result.ne = (((tile_t) ne) << settings::tiles_per_chunk_bits)
+ pos_on_chunk.ne;
result.se = (((tile_t) se) << settings::tiles_per_chunk_bits)
+ pos_on_chunk.se;
result.ne = static_cast<tile_t>(ne) * chunk::tiles_per_chunk + pos_on_chunk.ne;
result.se = static_cast<tile_t>(se) * chunk::tiles_per_chunk + pos_on_chunk.se;
return result;
}

Expand Down
2 changes: 2 additions & 0 deletions cpp/coord/chunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ struct chunk {
#include "ops/abs.h"

tile to_tile(tile_delta pos_on_chunk);

static constexpr tile_t tiles_per_chunk = 16;
};

struct chunk_delta {
Expand Down
14 changes: 3 additions & 11 deletions cpp/coord/decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include <stdint.h>

#include "fixed_point.h"

/*
* forward declarations of all coordinate structs,
* scalar type name aliases, and scaling factors
Expand All @@ -16,7 +18,7 @@ namespace openage {
namespace coord {

/* physics-based vector types */
using phys_t = int64_t;
using phys_t = FixedPoint<int64_t, 16>;

struct phys2;
struct phys2_delta;
Expand Down Expand Up @@ -62,16 +64,6 @@ struct vec2f_delta;
struct vec3f;
struct vec3f_delta;


namespace settings {
constexpr unsigned phys_t_radix_pos = 16;
constexpr phys_t phys_t_scaling_factor = (1 << phys_t_radix_pos);
constexpr phys_t phys_per_tile = phys_t_scaling_factor;
constexpr unsigned tiles_per_chunk_bits = 4; //yeah, this needs a better name.
constexpr tile_t tiles_per_chunk = (1 << tiles_per_chunk_bits);
} // namespace settings


} // namespace coord
} // namespace openage

Expand Down
286 changes: 286 additions & 0 deletions cpp/coord/fixed_point.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
// Copyright 2015-2015 the openage authors. See copying.md for legal info.

#ifndef OPENAGE_COORD_FIXED_POINT_H_
#define OPENAGE_COORD_FIXED_POINT_H_

#include <cmath>
#include <functional>

#include "../util/misc.h"

namespace openage {
namespace coord {

template<typename int_type, unsigned fractional_bits>
struct FixedPoint {

int_type data;

static const int_type one = int_type(1) << fractional_bits;

static const int_type fraction_bitmask = one - 1;


// constructors
constexpr FixedPoint() : data(0) {
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our current style says

    constexpr FixedPoint()
        :
        data{0} {}


constexpr FixedPoint(int_type n) : data(n << fractional_bits) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want those single-argument constructors to be explicit to prevent some implicit conversions.

}

constexpr FixedPoint(int n) : data(n << fractional_bits) {
}

constexpr FixedPoint(unsigned int n) : data(n << fractional_bits) {
}

// Constructing FixedPoint numbers with values like 1/2 and 1/8 won't lose precision
constexpr FixedPoint(float n) : data(static_cast<int_type>(n * one)) {
}

constexpr FixedPoint(double n) : data(static_cast<int_type>(n * one)) {
}

static FixedPoint from_raw(int_type data) {
FixedPoint result;
result.data = data;
return result;
}

constexpr FixedPoint(const FixedPoint &o) : data(o.data) {
}

FixedPoint &operator=(const FixedPoint &o) {
data = o.data;
return *this;
}


// Comparison operators
bool operator==(const FixedPoint &o) const {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want references here; FixedPoint contains just a single int-like value, which may even take less memory on the stack than a reference to it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then the compiler can optimize it away anyway as it's a const &. I'd say this is good the &-way.

return data == o.data;
}

bool operator!=(const FixedPoint &o) const {
return data != o.data;
}

bool operator<(const FixedPoint &o) const {
return data < o.data;
}

bool operator>(const FixedPoint &o) const {
return data > o.data;
}

bool operator<=(const FixedPoint &o) const {
return data <= o.data;
}

bool operator>=(const FixedPoint &o) const {
return data >= o.data;
}

// Unary operators
bool operator!() const {
return !data;
}

FixedPoint operator+() const {
return *this;
}

FixedPoint operator-() const {
FixedPoint f(*this);
f.data = -f.data;
return f;
}


// Basic operators
FixedPoint &operator+=(const FixedPoint &n) {
data += n.data;
return *this;
}

FixedPoint &operator-=(const FixedPoint &n) {
data -= n.data;
return *this;
}

FixedPoint &operator*=(const FixedPoint &n) {
*this = *this * n;
return *this;
}

FixedPoint &operator/=(const FixedPoint &n) {
*this = *this / n;
return *this;
}


// Conversions
int to_int() const {
return (data >> fractional_bits);
}

float to_float() const {
return static_cast<float>(data) / FixedPoint::one;
}

float to_double() const {
return static_cast<float>(data) / FixedPoint::one;
}

FixedPoint get_fraction() const {
return from_raw(data & fraction_bitmask);
}

int_type to_raw() const {
return data;
}

explicit operator float() const {
return to_float();
}

explicit operator double() const {
return to_double();
}

explicit operator int() const {
return to_int();
}

void swap(FixedPoint &rhs) {
std::swap(data, rhs.data);
}
};


// Binary operators
template<typename I, unsigned F>
FixedPoint<I, F> operator +(const FixedPoint<I, F> &lhs, const FixedPoint<I, F> rhs) {
return FixedPoint<I, F>::from_raw(lhs.data + rhs.data);
}

template<typename I, unsigned F>
FixedPoint<I, F> operator -(const FixedPoint<I, F> &lhs, const FixedPoint<I, F> rhs) {
return FixedPoint<I, F>::from_raw(lhs.data - rhs.data);
}

template<typename I, unsigned F>
FixedPoint<I, F> operator *(const FixedPoint<I, F> &lhs, const FixedPoint<I, F> rhs) {
auto n = lhs.data * rhs.data;
return FixedPoint<I, F>::from_raw(n >> F);
}

template<typename I, unsigned F>
FixedPoint<I, F> operator /(const FixedPoint<I, F> &lhs, const FixedPoint<I, F> rhs) {
auto n = lhs.data << F;
return FixedPoint<I, F>::from_raw(util::div(n, rhs.data));
}


// N `op` FixedPoint
template<typename I, unsigned F, typename N>
typename std::enable_if<std::is_arithmetic<N>::value, FixedPoint<I, F>>::type
operator +(const N &lhs, const FixedPoint<I, F> rhs) {
return FixedPoint<I, F>{ lhs } + rhs;
}
template<typename I, unsigned F, typename N>
typename std::enable_if<std::is_arithmetic<N>::value, FixedPoint<I, F>>::type
operator -(const N &lhs, const FixedPoint<I, F> rhs) {
return FixedPoint<I, F>{ lhs } - rhs;
}
template<typename I, unsigned F, typename N>
typename std::enable_if<std::is_arithmetic<N>::value, FixedPoint<I, F>>::type
operator *(const N &lhs, const FixedPoint<I, F> rhs) {
return FixedPoint<I, F>{ lhs } * rhs;
}
template<typename I, unsigned F, typename N>
typename std::enable_if<std::is_arithmetic<N>::value, FixedPoint<I, F>>::type
operator /(const N &lhs, const FixedPoint<I, F> rhs) {
return FixedPoint<I, F>{ lhs } / rhs;
}

// FixedPoint `op` N
template<typename I, unsigned F, typename N>
typename std::enable_if<std::is_arithmetic<N>::value, FixedPoint<I, F>>::type
operator +(const FixedPoint<I, F> lhs, const N &rhs) {
return lhs + FixedPoint<I, F>{ rhs };
}
template<typename I, unsigned F, typename N>
typename std::enable_if<std::is_arithmetic<N>::value, FixedPoint<I, F>>::type
operator -(const FixedPoint<I, F> lhs, const N &rhs) {
return lhs - FixedPoint<I, F>{ rhs };
}
template<typename I, unsigned F, typename N>
typename std::enable_if<std::is_arithmetic<N>::value, FixedPoint<I, F>>::type
operator *(const FixedPoint<I, F> lhs, const N &rhs) {
return lhs * FixedPoint<I, F>{ rhs };
}
template<typename I, unsigned F, typename N>
typename std::enable_if<std::is_arithmetic<N>::value, FixedPoint<I, F>>::type
operator /(const FixedPoint<I, F> lhs, const N &rhs) {
return lhs / FixedPoint<I, F>{ rhs };
}


// I/O operators
template<typename I, unsigned F>
std::ostream &operator <<(std::ostream &os, FixedPoint<I, F> n) {
os << n.data;
return os;
}

template<typename I, unsigned F>
std::istream &operator >>(std::istream &is, FixedPoint<I, F> n) {
is >> n.data;
return is;
}

} // namespace coord
} // namespace openage


// std function overloads
namespace std {

using openage::coord::FixedPoint;

template<typename I, unsigned F>
FixedPoint<I, F> sqrt(FixedPoint<I, F> n) {
return FixedPoint<I, F> { std::sqrt(n.to_double()) };
}

template<typename I, unsigned F>
FixedPoint<I, F> min(FixedPoint<I, F> x, FixedPoint<I, F> y) {
return FixedPoint<I, F> { std::min(x.data, y.data) };
}

template<typename I, unsigned F>
FixedPoint<I, F> max(FixedPoint<I, F> x, FixedPoint<I, F> y) {
return FixedPoint<I, F> { std::max(x.data, y.data) };
}

template<typename I, unsigned F>
FixedPoint<I, F> abs(FixedPoint<I, F> n) {
return FixedPoint<I, F> { std::abs(n.data) };
}

template<typename I, unsigned F>
FixedPoint<I, F> hypot(FixedPoint<I, F> x, FixedPoint<I, F> y) {
return FixedPoint<I, F> { std::hypot(x.to_double(), y.to_double()) };
}

template<typename I, unsigned F>
struct hash<openage::coord::FixedPoint<I, F>> {
size_t operator ()(const openage::coord::FixedPoint<I, F> &n) const {
return std::hash<I>{}(n.data);
}
};

} // namespace std

#endif
12 changes: 3 additions & 9 deletions cpp/coord/phys2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,14 @@ phys3_delta phys2_delta::to_phys3(phys_t up) const {
}

tile phys2::to_tile() const {
tile result;
result.ne = (ne >> settings::phys_t_radix_pos);
result.se = (se >> settings::phys_t_radix_pos);
return result;
return tile{ ne.to_int(), se.to_int() };
}

phys2_delta phys2::get_fraction() const {
phys2_delta result;

// define a bitmask that keeps the last n bits
decltype(result.ne) bitmask = ((1 << settings::phys_t_radix_pos) - 1);

result.ne = (ne & bitmask);
result.se = (se & bitmask);
result.ne = ne.get_fraction();
result.se = se.get_fraction();
return result;
}

Expand Down
Loading