Merge remote-tracking branch 'upstream/develop' into node-string-tag

This commit is contained in:
heliclei 2014-03-06 10:02:50 +08:00
Родитель 55080d713b 4fe827e46b
Коммит 08d0cde490
139 изменённых файлов: 5733 добавлений и 5224 удалений

Просмотреть файл

@ -1 +1 @@
8b81e323ab3dd59b3a8ced55fa0406d09d6fa1c4
50f1022c672a57d837362191d33d09f6bf69986b

Просмотреть файл

@ -141,7 +141,7 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/cocos/base
${CMAKE_CURRENT_SOURCE_DIR}/cocos/physics
${CMAKE_CURRENT_SOURCE_DIR}/cocos/editor-support
${CMAKE_CURRENT_SOURCE_DIR}/cocos/math/kazmath/include
${CMAKE_CURRENT_SOURCE_DIR}/cocos/math/kazmath
${CMAKE_CURRENT_SOURCE_DIR}/extensions
${CMAKE_CURRENT_SOURCE_DIR}/external
${CMAKE_CURRENT_SOURCE_DIR}/external/tinyxml2

Просмотреть файл

@ -7,11 +7,6 @@ import os, os.path
import shutil
from optparse import OptionParser
CPP_SAMPLES = ['testcpp']
LUA_SAMPLES = []
JSB_SAMPLES = []
ALL_SAMPLES = CPP_SAMPLES + LUA_SAMPLES + JSB_SAMPLES
def get_num_of_cpu():
''' The build process can be accelerated by running multiple concurrent job processes using the -j-option.
'''
@ -72,34 +67,6 @@ def select_toolchain_version():
print "Couldn't find the gcc toolchain."
exit(1)
def caculate_built_samples(args):
''' Compute the sampels to be built
'cpp' for short of all cpp tests
'lua' for short of all lua tests
'jsb' for short of all javascript tests
'''
if 'all' in args:
return ALL_SAMPLES
targets = []
if 'cpp' in args:
targets += CPP_SAMPLES
args.remove('cpp')
if 'lua' in args:
targets += LUA_SAMPLES
args.remove('lua')
if 'jsb' in args:
targets += JSB_SAMPLES
args.remove('jsb')
targets += args
# remove duplicate elements, for example
# python android-build.py cpp hellocpp
targets = set(targets)
return list(targets)
def do_build(cocos_root, ndk_root, app_android_root, ndk_build_param,sdk_root,android_platform,build_mode):
ndk_path = os.path.join(ndk_root, "ndk-build")
@ -157,33 +124,11 @@ def copy_resources(target, app_android_root):
if os.path.isdir(resources_dir):
copy_files(resources_dir, assets_dir)
# jsb samples should copy javascript files and resources(shared with cocos2d-html5)
if target in JSB_SAMPLES:
resources_dir = os.path.join(app_android_root, "../../../cocos/scripting/javascript/script")
copy_files(resources_dir, assets_dir)
if target == "testjavascript":
resources_dir = os.path.join(app_android_root, "../tests/")
copy_files(resources_dir, assets_dir)
# lua samples should copy lua script
if target in LUA_SAMPLES:
resources_dir = os.path.join(app_android_root, "../../../cocos/scripting/lua/script")
copy_files(resources_dir, assets_dir)
# TestLua shared resources with TestCpp
if target == "testlua":
resources_dir = os.path.join(app_android_root, "../../test-cpp/Resources")
copy_files(resources_dir, assets_dir)
def build_samples(target,ndk_build_param,android_platform,build_mode):
ndk_root = check_environment_variables()
sdk_root = None
select_toolchain_version()
build_targets = caculate_built_samples(target)
current_dir = os.path.dirname(os.path.realpath(__file__))
cocos_root = os.path.join(current_dir, "..")
@ -201,20 +146,10 @@ def build_samples(target,ndk_build_param,android_platform,build_mode):
elif build_mode != 'release':
build_mode = 'debug'
app_android_root = ''
for target in build_targets:
if target == 'testcpp':
app_android_root = os.path.join(cocos_root, 'tests/proj.android')
elif target == 'testlua':
app_android_root = os.path.join(cocos_root, 'tests/test-lua/proj.android')
elif target == 'testjavascript':
app_android_root = os.path.join(cocos_root, 'tests/test-javascript/proj.android')
else:
print 'unknown target: %s' % target
continue
app_android_root = os.path.join(cocos_root, 'tests/proj.android')
copy_resources(target, app_android_root)
do_build(cocos_root, ndk_root, app_android_root, ndk_build_param,sdk_root,android_platform,build_mode)
copy_resources(target, app_android_root)
do_build(cocos_root, ndk_root, app_android_root, ndk_build_param,sdk_root,android_platform,build_mode)
# -------------- main --------------
if __name__ == '__main__':
@ -223,26 +158,15 @@ if __name__ == '__main__':
usage = """
This script is mainy used for building tests built-in with cocos2d-x.
Usage: %prog [options] target
Usage: %prog [options] [testcpp]
Valid targets are: [testcpp|testlua|testjavascript]. You can combine them arbitrarily with a whitespace among two valid targets.
You can use [all|cpp|lua|jsb], to build all the tests, or all the c++ tests, or all the Lua tests, or all the JavaScript tests respectevely.
cpp = ['testcpp']
lua = ['testlua']
jsb = ['testjavascript']
all = cpp + lua + jsb // be careful with the all target, it may took a very long time to compile all the projects, do it under your own risk.
If you are new to cocos2d-x, I recommend you start with testcpp, testlua or testjavascript.
If you are new to cocos2d-x, I recommend you start with testcpp.
You can combine these targets like this:
//1. to build simplegame and assetsmanager
python android-build.py -p 10 testcpp testlua
python android-build.py -p 10
//2. to build testlua and all the jsb tests
python android-build.py -p 19 testlua jsb
Note: You should install ant to generate apk while building the andriod tests. But it is optional. You can generate apk with eclipse.
"""
@ -256,7 +180,7 @@ if __name__ == '__main__':
help='The build mode for java project,debug[default] or release. Get more information,please refer to http://developer.android.com/tools/building/building-cmdline.html')
(opts, args) = parser.parse_args()
if len(args) == 0:
if len(args) == 1 and cmp(args[0], 'testcpp') != 0:
parser.print_help()
else:
try:

Просмотреть файл

@ -1 +1 @@
8fad051dc33d390c01df304fee2a78e22785136f
e8eaf27db3b5c75d371db6c73f434cea5c0f970d

Просмотреть файл

@ -1 +1 @@
9da17496043155938cbd8973b01514f220e7192b
d70aa2f168a737e7a152028e2156e3099e01c3aa

Просмотреть файл

@ -142,19 +142,20 @@ renderer/CCRenderMaterial.cpp \
../base/CCValue.cpp \
../base/etc1.cpp \
../base/s3tc.cpp \
../math/kazmath/src/aabb.c \
../math/kazmath/src/mat3.c \
../math/kazmath/src/mat4.c \
../math/kazmath/src/neon_matrix_impl.c \
../math/kazmath/src/plane.c \
../math/kazmath/src/quaternion.c \
../math/kazmath/src/ray2.c \
../math/kazmath/src/utility.c \
../math/kazmath/src/vec2.c \
../math/kazmath/src/vec3.c \
../math/kazmath/src/vec4.c \
../math/kazmath/src/GL/mat4stack.c \
../math/kazmath/src/GL/matrix.c \
../math/kazmath/kazmath/aabb.c \
../math/kazmath/kazmath/mat3.c \
../math/kazmath/kazmath/mat4.c \
../math/kazmath/kazmath/neon_matrix_impl.c \
../math/kazmath/kazmath/plane.c \
../math/kazmath/kazmath/quaternion.c \
../math/kazmath/kazmath/ray2.c \
../math/kazmath/kazmath/ray3.c \
../math/kazmath/kazmath/utility.c \
../math/kazmath/kazmath/vec2.c \
../math/kazmath/kazmath/vec3.c \
../math/kazmath/kazmath/vec4.c \
../math/kazmath/kazmath/GL/mat4stack.c \
../math/kazmath/kazmath/GL/matrix.c \
../physics/CCPhysicsBody.cpp \
../physics/CCPhysicsContact.cpp \
../physics/CCPhysicsJoint.cpp \
@ -173,7 +174,7 @@ renderer/CCRenderMaterial.cpp \
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \
$(LOCAL_PATH)/renderer \
$(LOCAL_PATH)/../math/kazmath/include \
$(LOCAL_PATH)/../math/kazmath \
platform/android \
$(LOCAL_PATH)/../physics \
$(LOCAL_PATH)/../base \
@ -183,7 +184,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
$(LOCAL_PATH)/renderer \
$(LOCAL_PATH)/../math/kazmath/include \
$(LOCAL_PATH)/../math/kazmath \
$(LOCAL_PATH)/platform/android \
$(LOCAL_PATH)/../physics \
$(LOCAL_PATH)/../base \

Просмотреть файл

@ -88,7 +88,7 @@ extern const char* cocos2dVersion(void);
const char *Director::EVENT_PROJECTION_CHANGED = "director_projection_changed";
const char *Director::EVENT_AFTER_DRAW = "director_after_draw";
const char *Director::EVENT_AFTER_VISIT = "director_after_visit";
const char *Director::EVENT_AFTER_UPDATE = "director_after_udpate";
const char *Director::EVENT_AFTER_UPDATE = "director_after_update";
Director* Director::getInstance()
{

Просмотреть файл

@ -205,8 +205,20 @@ bool DrawNode::init()
return true;
}
void DrawNode::render()
void DrawNode::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(DrawNode::onDraw, this, transform, transformUpdated);
renderer->addCommand(&_customCommand);
}
void DrawNode::onDraw(const kmMat4 &transform, bool transformUpdated)
{
getShaderProgram()->use();
getShaderProgram()->setUniformsForBuiltins(transform);
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
if (_dirty)
{
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
@ -220,40 +232,25 @@ void DrawNode::render()
else
{
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
// vertex
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, vertices));
// color
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, colors));
// texcood
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_C4B_T2F), (GLvoid *)offsetof(V2F_C4B_T2F, texCoords));
}
glDrawArrays(GL_TRIANGLES, 0, _bufferCount);
glBindBuffer(GL_ARRAY_BUFFER, 0);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,_bufferCount);
CHECK_GL_ERROR_DEBUG();
}
void DrawNode::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(DrawNode::onDraw, this);
renderer->addCommand(&_customCommand);
}
void DrawNode::onDraw()
{
CC_NODE_DRAW_SETUP();
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
render();
}
void DrawNode::drawDot(const Point &pos, float radius, const Color4F &color)
{
unsigned int vertex_count = 2*3;

Просмотреть файл

@ -89,7 +89,7 @@ public:
*/
void setBlendFunc(const BlendFunc &blendFunc);
void onDraw();
void onDraw(const kmMat4 &transform, bool transformUpdated);
// Overrides
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
@ -100,7 +100,6 @@ protected:
virtual bool init();
void ensureCapacity(int count);
void render();
GLuint _vao;
GLuint _vbo;

Просмотреть файл

@ -102,10 +102,10 @@ static void lazy_init( void )
s_shader = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_U_COLOR);
s_shader->retain();
s_colorLocation = glGetUniformLocation( s_shader->getProgram(), "u_color");
CHECK_GL_ERROR_DEBUG();
s_pointSizeLocation = glGetUniformLocation( s_shader->getProgram(), "u_pointSize");
CHECK_GL_ERROR_DEBUG();
s_colorLocation = s_shader->getUniformLocation("u_color");
CHECK_GL_ERROR_DEBUG();
s_pointSizeLocation = s_shader->getUniformLocation("u_pointSize");
CHECK_GL_ERROR_DEBUG();
s_initialized = true;
}

Просмотреть файл

@ -61,6 +61,11 @@ void EventListenerTouchOneByOne::setSwallowTouches(bool needSwallow)
_needSwallow = needSwallow;
}
bool EventListenerTouchOneByOne::isSwallowTouches()
{
return _needSwallow;
}
EventListenerTouchOneByOne* EventListenerTouchOneByOne::create()
{
auto ret = new EventListenerTouchOneByOne();

Просмотреть файл

@ -43,6 +43,7 @@ public:
virtual ~EventListenerTouchOneByOne();
void setSwallowTouches(bool needSwallow);
bool isSwallowTouches();
/// Overrides
virtual EventListenerTouchOneByOne* clone() override;

Просмотреть файл

@ -28,11 +28,11 @@
#include "ccUTF8.h"
#include "CCDirector.h"
#define PAGE_WIDTH 1024
#define PAGE_HEIGHT 1024
NS_CC_BEGIN
const int FontAtlas::CacheTextureWidth = 1024;
const int FontAtlas::CacheTextureHeight = 1024;
FontAtlas::FontAtlas(Font &theFont) :
_font(&theFont),
_currentPageData(nullptr)
@ -44,28 +44,26 @@ _currentPageData(nullptr)
{
_currentPageLineHeight = _font->getFontMaxHeight();
_commonLineHeight = _currentPageLineHeight * 0.8f;
Texture2D * tex = new Texture2D;
auto texture = new Texture2D;
_currentPage = 0;
_currentPageOrigX = 0;
_currentPageOrigY = 0;
_letterPadding = 0;
_makeDistanceMap = fontTTf->isDistanceFieldEnabled();
if(_makeDistanceMap)
if(fontTTf->isDistanceFieldEnabled())
{
_commonLineHeight += 2 * FontFreeType::DistanceMapSpread;
_letterPadding += 2 * FontFreeType::DistanceMapSpread;
}
_currentPageDataSize = (PAGE_WIDTH * PAGE_HEIGHT * 1);
_currentPageDataSize = CacheTextureWidth * CacheTextureHeight;
if(fontTTf->getOutlineSize() > 0)
{
_currentPageDataSize *= 2;
}
_currentPageData = new unsigned char[_currentPageDataSize];
memset(_currentPageData, 0, _currentPageDataSize);
addTexture(*tex,0);
tex->release();
}
else
{
_makeDistanceMap = false;
addTexture(texture,0);
texture->release();
}
}
@ -112,29 +110,75 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
return false;
FontFreeType* fontTTf = (FontFreeType*)_font;
std::unordered_map<unsigned short, FontLetterDefinition> fontDefs;
int length = cc_wcslen(utf16String);
float offsetAdjust = _letterPadding / 2;
//find out new letter
float offsetAdjust = _letterPadding / 2;
int bitmapWidth;
int bitmapHeight;
Rect tempRect;
FontLetterDefinition tempDef;
auto contentSize = Size(CacheTextureWidth,CacheTextureHeight);
auto scaleFactor = CC_CONTENT_SCALE_FACTOR();
auto pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8;
bool existNewLetter = false;
for (int i = 0; i < length; ++i)
{
auto outIterator = _fontLetterDefinitions.find(utf16String[i]);
if (outIterator == _fontLetterDefinitions.end())
{
auto outIterator2 = fontDefs.find(utf16String[i]);
if(outIterator2 != fontDefs.end())
continue;
existNewLetter = true;
Rect tempRect;
FontLetterDefinition tempDef;
if (!fontTTf->getBBOXFotChar(utf16String[i], tempRect,tempDef.xAdvance))
auto bitmap = fontTTf->getGlyphBitmap(utf16String[i],bitmapWidth,bitmapHeight,tempRect,tempDef.xAdvance);
if (bitmap)
{
tempDef.validDefinition = false;
tempDef.validDefinition = true;
tempDef.letteCharUTF16 = utf16String[i];
tempDef.width = tempRect.size.width + _letterPadding;
tempDef.height = tempRect.size.height + _letterPadding;
tempDef.offsetX = tempRect.origin.x + offsetAdjust;
tempDef.offsetY = _commonLineHeight + tempRect.origin.y - offsetAdjust;
if (_currentPageOrigX + tempDef.width > CacheTextureWidth)
{
_currentPageOrigY += _currentPageLineHeight;
_currentPageOrigX = 0;
if(_currentPageOrigY + _currentPageLineHeight >= CacheTextureHeight)
{
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
_currentPageOrigY = 0;
delete []_currentPageData;
_currentPageData = new unsigned char[_currentPageDataSize];
if(_currentPageData == nullptr)
return false;
memset(_currentPageData, 0, _currentPageDataSize);
_currentPage++;
auto tex = new Texture2D;
addTexture(tex,_currentPage);
tex->release();
}
}
fontTTf->renderCharAt(_currentPageData,_currentPageOrigX,_currentPageOrigY,bitmap,bitmapWidth,bitmapHeight);
tempDef.U = _currentPageOrigX;
tempDef.V = _currentPageOrigY;
tempDef.textureID = _currentPage;
_currentPageOrigX += tempDef.width + 1;
// take from pixels to points
tempDef.width = tempDef.width / scaleFactor;
tempDef.height = tempDef.height / scaleFactor;
tempDef.U = tempDef.U / scaleFactor;
tempDef.V = tempDef.V / scaleFactor;
}
else{
if(tempDef.xAdvance)
tempDef.validDefinition = true;
else
tempDef.validDefinition = false;
tempDef.letteCharUTF16 = utf16String[i];
tempDef.width = 0;
tempDef.height = 0;
@ -143,84 +187,29 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
tempDef.offsetX = 0;
tempDef.offsetY = 0;
tempDef.textureID = 0;
tempDef.xAdvance = 0;
_currentPageOrigX += 1;
}
else
{
tempDef.validDefinition = true;
tempDef.letteCharUTF16 = utf16String[i];
tempDef.width = tempRect.size.width + _letterPadding;
tempDef.height = tempRect.size.height + _letterPadding;
tempDef.offsetX = tempRect.origin.x + offsetAdjust;
tempDef.offsetY = _commonLineHeight + tempRect.origin.y - offsetAdjust;
}
fontDefs[utf16String[i]] = tempDef;
_fontLetterDefinitions[tempDef.letteCharUTF16] = tempDef;
}
}
Size _pageContentSize = Size(PAGE_WIDTH,PAGE_HEIGHT);
float scaleFactor = CC_CONTENT_SCALE_FACTOR();
float glyphWidth;
Texture2D::PixelFormat pixelFormat = Texture2D::PixelFormat::A8;
for(auto it = fontDefs.begin(); it != fontDefs.end(); it++)
if(existNewLetter)
{
if(it->second.validDefinition)
{
glyphWidth = it->second.width;
if (_currentPageOrigX + glyphWidth > PAGE_WIDTH)
{
_currentPageOrigY += _currentPageLineHeight;
_currentPageOrigX = 0;
if(_currentPageOrigY + _currentPageLineHeight >= PAGE_HEIGHT)
{
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, PAGE_WIDTH, PAGE_HEIGHT, _pageContentSize );
_currentPageOrigY = 0;
delete []_currentPageData;
_currentPageData = new unsigned char[_currentPageDataSize];
if(_currentPageData == nullptr)
return false;
memset(_currentPageData, 0, _currentPageDataSize);
_currentPage++;
Texture2D* tex = new Texture2D;
addTexture(*tex,_currentPage);
tex->release();
}
}
fontTTf->renderCharAt(it->second.letteCharUTF16,_currentPageOrigX,_currentPageOrigY,_currentPageData,PAGE_WIDTH);
it->second.U = _currentPageOrigX;
it->second.V = _currentPageOrigY;
it->second.textureID = _currentPage;
// take from pixels to points
it->second.width = it->second.width / scaleFactor;
it->second.height = it->second.height / scaleFactor;
it->second.U = it->second.U / scaleFactor;
it->second.V = it->second.V / scaleFactor;
}
else
glyphWidth = 0;
_fontLetterDefinitions[it->second.letteCharUTF16] = it->second;
_currentPageOrigX += glyphWidth + 1;
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
}
if(fontDefs.size() > 0)
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, PAGE_WIDTH, PAGE_HEIGHT, _pageContentSize );
return true;
}
void FontAtlas::addTexture(Texture2D &texture, int slot)
void FontAtlas::addTexture(Texture2D *texture, int slot)
{
texture.retain();
_atlasTextures[slot] = &texture;
texture->retain();
_atlasTextures[slot] = texture;
}
Texture2D & FontAtlas::getTexture(int slot)
Texture2D* FontAtlas::getTexture(int slot)
{
return *(_atlasTextures[slot]);
return _atlasTextures[slot];
}
float FontAtlas::getCommonLineHeight() const

Просмотреть файл

@ -52,6 +52,8 @@ struct FontLetterDefinition
class CC_DLL FontAtlas : public Ref
{
public:
static const int CacheTextureWidth;
static const int CacheTextureHeight;
/**
* @js ctor
*/
@ -68,11 +70,11 @@ public:
bool prepareLetterDefinitions(unsigned short *utf16String);
inline const std::unordered_map<int, Texture2D*>& getTextures() const{ return _atlasTextures;}
void addTexture(Texture2D &texture, int slot);
void addTexture(Texture2D *texture, int slot);
float getCommonLineHeight() const;
void setCommonLineHeight(float newHeight);
Texture2D& getTexture(int slot);
Texture2D* getTexture(int slot);
const Font* getFont() const;
private:

Просмотреть файл

@ -35,17 +35,32 @@ NS_CC_BEGIN
std::unordered_map<std::string, FontAtlas *> FontAtlasCache::_atlasMap;
FontAtlas * FontAtlasCache::getFontAtlasTTF(const std::string& fontFileName, int size, GlyphCollection glyphs, const char *customGlyphs, bool useDistanceField)
{
std::string atlasName = generateFontName(fontFileName, size, glyphs, useDistanceField);
FontAtlas * FontAtlasCache::getFontAtlasTTF(const TTFConfig & config)
{
bool useDistanceField = config.distanceFieldEnabled;
if(config.outlineSize > 0)
{
useDistanceField = false;
}
int fontSize = config.fontSize;
if (useDistanceField)
{
fontSize = Label::DefultFontSize;
}
std::string atlasName = generateFontName(config.fontFilePath, fontSize, GlyphCollection::DYNAMIC, useDistanceField);
atlasName.append("_outline_");
std::stringstream ss;
ss << config.outlineSize;
atlasName.append(ss.str());
FontAtlas *tempAtlas = _atlasMap[atlasName];
if ( !tempAtlas )
{
FontFreeType *font = FontFreeType::create(fontFileName, size, glyphs, customGlyphs);
FontFreeType *font = FontFreeType::create(config.fontFilePath, fontSize, config.glyphs, config.customGlyphs,useDistanceField,config.outlineSize);
if (font)
{
font->setDistanceFieldEnabled(useDistanceField);
tempAtlas = font->createFontAtlas();
if (tempAtlas)
_atlasMap[atlasName] = tempAtlas;

Просмотреть файл

@ -37,7 +37,7 @@ NS_CC_BEGIN
class CC_DLL FontAtlasCache
{
public:
static FontAtlas * getFontAtlasTTF(const std::string& fontFileName, int size, GlyphCollection glyphs, const char *customGlyphs = 0, bool useDistanceField = false);
static FontAtlas * getFontAtlasTTF(const TTFConfig & config);
static FontAtlas * getFontAtlasFNT(const std::string& fontFileName, const Point& imageOffset = Point::ZERO);
static FontAtlas * getFontAtlasCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);

Просмотреть файл

@ -158,7 +158,7 @@ FontAtlas * FontCharMap::createFontAtlas()
}
}
tempAtlas->addTexture(*_texture,0);
tempAtlas->addTexture(_texture,0);
return tempAtlas;
}

Просмотреть файл

@ -816,7 +816,7 @@ FontAtlas * FontFNT::createFontAtlas()
return 0;
// add the texture
tempAtlas->addTexture(*tempTexture, 0);
tempAtlas->addTexture(tempTexture, 0);
// done
return tempAtlas;

Просмотреть файл

@ -30,6 +30,7 @@ THE SOFTWARE.
#include "CCFontFreeType.h"
#include "platform/CCFileUtils.h"
#include "edtaa3func.h"
#include FT_BBOX_H
NS_CC_BEGIN
@ -38,9 +39,9 @@ FT_Library FontFreeType::_FTlibrary;
bool FontFreeType::_FTInitialized = false;
const int FontFreeType::DistanceMapSpread = 3;
FontFreeType * FontFreeType::create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs)
FontFreeType * FontFreeType::create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs,bool distanceFieldEnabled /* = false */,int outline /* = 0 */)
{
FontFreeType *tempFont = new FontFreeType();
FontFreeType *tempFont = new FontFreeType(distanceFieldEnabled,outline);
if (!tempFont)
return nullptr;
@ -84,10 +85,21 @@ FT_Library FontFreeType::getFTLibrary()
return _FTlibrary;
}
FontFreeType::FontFreeType()
FontFreeType::FontFreeType(bool distanceFieldEnabled /* = false */,int outline /* = 0 */)
: _fontRef(nullptr)
,_distanceFieldEnabled(false)
,_distanceFieldEnabled(distanceFieldEnabled)
,_outlineSize(outline)
,_stroker(nullptr)
{
if (_outlineSize > 0)
{
FT_Stroker_New(FontFreeType::getFTLibrary(), &_stroker);
FT_Stroker_Set(_stroker,
(int)(_outlineSize * 64),
FT_STROKER_LINECAP_ROUND,
FT_STROKER_LINEJOIN_ROUND,
0);
}
}
bool FontFreeType::createFontObject(const std::string &fontName, int fontSize)
@ -125,6 +137,10 @@ bool FontFreeType::createFontObject(const std::string &fontName, int fontSize)
FontFreeType::~FontFreeType()
{
if (_stroker)
{
FT_Stroker_Done(_stroker);
}
if (_fontRef)
{
FT_Done_Face(_fontRef);
@ -144,41 +160,6 @@ FontAtlas * FontFreeType::createFontAtlas()
return atlas;
}
bool FontFreeType::getBBOXFotChar(unsigned short theChar, Rect &outRect, int &xAdvance) const
{
if (!_fontRef)
return false;
// get the ID to the char we need
int glyph_index = FT_Get_Char_Index(_fontRef, theChar);
if (!glyph_index)
return false;
// load glyph infos
if (_distanceFieldEnabled)
{
if (FT_Load_Glyph(_fontRef, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT))
return false;
}
else
{
if (FT_Load_Glyph(_fontRef, glyph_index, FT_LOAD_DEFAULT))
return false;
}
// store result in the passed rectangle
outRect.origin.x = _fontRef->glyph->metrics.horiBearingX >> 6;
outRect.origin.y = - (_fontRef->glyph->metrics.horiBearingY >> 6);
outRect.size.width = (_fontRef->glyph->metrics.width >> 6);
outRect.size.height = (_fontRef->glyph->metrics.height >> 6);
xAdvance = (static_cast<int>(_fontRef->glyph->metrics.horiAdvance >> 6));
return true;
}
int * FontFreeType::getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const
{
if (!text)
@ -239,27 +220,162 @@ int FontFreeType::getFontMaxHeight() const
return (static_cast<int>(_fontRef->size->metrics.height >> 6));
}
unsigned char * FontFreeType::getGlyphBitmap(unsigned short theChar, int &outWidth, int &outHeight) const
unsigned char* FontFreeType::getGlyphBitmap(unsigned short theChar, int &outWidth, int &outHeight, Rect &outRect,int &xAdvance)
{
if (!_fontRef)
return 0;
if (_distanceFieldEnabled)
bool invalidChar = true;
unsigned char * ret = nullptr;
do
{
if (FT_Load_Char(_fontRef,theChar,FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT))
return 0;
if (!_fontRef)
break;
auto glyphIndex = FT_Get_Char_Index(_fontRef, theChar);
if(!glyphIndex)
break;
if (_distanceFieldEnabled)
{
if (FT_Load_Glyph(_fontRef,glyphIndex,FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT))
break;
}
else
{
if (FT_Load_Glyph(_fontRef,glyphIndex,FT_LOAD_RENDER))
break;
}
outRect.origin.x = _fontRef->glyph->metrics.horiBearingX >> 6;
outRect.origin.y = - (_fontRef->glyph->metrics.horiBearingY >> 6);
outRect.size.width = (_fontRef->glyph->metrics.width >> 6);
outRect.size.height = (_fontRef->glyph->metrics.height >> 6);
xAdvance = (static_cast<int>(_fontRef->glyph->metrics.horiAdvance >> 6));
outWidth = _fontRef->glyph->bitmap.width;
outHeight = _fontRef->glyph->bitmap.rows;
ret = _fontRef->glyph->bitmap.buffer;
if (_outlineSize > 0)
{
auto copyBitmap = new unsigned char[outWidth * outHeight];
memcpy(copyBitmap,ret,outWidth * outHeight * sizeof(unsigned char));
int bitmapWidth;
int bitmapHeight;
FT_BBox bbox;
auto outlineBitmap = getGlyphBitmapWithOutline(theChar,bbox);
if(outlineBitmap == nullptr)
{
ret = nullptr;
delete [] copyBitmap;
break;
}
bitmapWidth = (bbox.xMax - bbox.xMin)>>6;
bitmapHeight = (bbox.yMax - bbox.yMin)>>6;
int index;
auto blendImage = new unsigned char[bitmapWidth * bitmapHeight * 2];
memset(blendImage, 0, bitmapWidth * bitmapHeight * 2);
for (int x = 0; x < bitmapWidth; ++x)
{
for (int y = 0; y < bitmapHeight; ++y)
{
index = x + ( y * bitmapWidth );
blendImage[2 * index] = outlineBitmap[index];
}
}
int maxX = outWidth + _outlineSize;
int maxY = outHeight + _outlineSize;
for (int x = _outlineSize; x < maxX; ++x)
{
for (int y = _outlineSize; y < maxY; ++y)
{
index = x + ( y * bitmapWidth );
blendImage[2 * index + 1] = copyBitmap[outWidth * (y - _outlineSize) + x - _outlineSize];
}
}
outRect.origin.x = bbox.xMin >> 6;
outRect.origin.y = - (bbox.yMax >> 6);
xAdvance += bitmapWidth - outRect.size.width;
outRect.size.width = bitmapWidth;
outRect.size.height = bitmapHeight;
outWidth = bitmapWidth;
outHeight = bitmapHeight;
delete [] outlineBitmap;
delete [] copyBitmap;
ret = blendImage;
}
invalidChar = false;
} while (0);
if (invalidChar)
{
outRect.size.width = 0;
outRect.size.height = 0;
xAdvance = 0;
return nullptr;
}
else
{
if (FT_Load_Char(_fontRef,theChar,FT_LOAD_RENDER))
return 0;
return ret;
}
outWidth = _fontRef->glyph->bitmap.width;
outHeight = _fontRef->glyph->bitmap.rows;
// return the pointer to the bitmap
return _fontRef->glyph->bitmap.buffer;
}
unsigned char * FontFreeType::getGlyphBitmapWithOutline(unsigned short theChar, FT_BBox &bbox)
{
unsigned char* ret = nullptr;
FT_UInt gindex = FT_Get_Char_Index(_fontRef, theChar);
if (FT_Load_Glyph(_fontRef, gindex, FT_LOAD_NO_BITMAP) == 0)
{
if (_fontRef->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
{
FT_Glyph glyph;
if (FT_Get_Glyph(_fontRef->glyph, &glyph) == 0)
{
FT_Glyph_StrokeBorder(&glyph, _stroker, 0, 1);
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
{
FT_Outline *outline = &reinterpret_cast<FT_OutlineGlyph>(glyph)->outline;
FT_Glyph_Get_CBox(glyph,FT_GLYPH_BBOX_GRIDFIT,&bbox);
int width = (bbox.xMax - bbox.xMin)>>6;
int rows = (bbox.yMax - bbox.yMin)>>6;
FT_Bitmap bmp;
bmp.buffer = new unsigned char[width * rows];
memset(bmp.buffer, 0, width * rows);
bmp.width = width;
bmp.rows = rows;
bmp.pitch = width;
bmp.pixel_mode = FT_PIXEL_MODE_GRAY;
bmp.num_grays = 256;
FT_Raster_Params params;
memset(&params, 0, sizeof (params));
params.source = outline;
params.target = &bmp;
params.flags = FT_RASTER_FLAG_AA;
FT_Outline_Translate(outline,-bbox.xMin,-bbox.yMin);
FT_Outline_Render(_FTlibrary, outline, &params);
ret = bmp.buffer;
}
FT_Done_Glyph(glyph);
}
}
}
return ret;
}
unsigned char * makeDistanceMap( unsigned char *img, unsigned int width, unsigned int height)
@ -343,47 +459,33 @@ unsigned char * makeDistanceMap( unsigned char *img, unsigned int width, unsigne
return out;
}
void FontFreeType::setDistanceFieldEnabled(bool distanceFieldEnabled)
void FontFreeType::renderCharAt(unsigned char *dest,int posX, int posY, unsigned char* bitmap,int bitmapWidth,int bitmapHeight)
{
_distanceFieldEnabled = distanceFieldEnabled;
}
bool FontFreeType::renderCharAt(unsigned short int charToRender, int posX, int posY, unsigned char *destMemory, int destSize)
{
unsigned char *sourceBitmap = 0;
int sourceWidth = 0;
int sourceHeight = 0;
sourceBitmap = getGlyphBitmap(charToRender, sourceWidth, sourceHeight);
if (!sourceBitmap)
return false;
int iX = posX;
int iY = posY;
if (_distanceFieldEnabled)
{
unsigned char * out = makeDistanceMap(sourceBitmap,sourceWidth,sourceHeight);
auto distanceMap = makeDistanceMap(bitmap,bitmapWidth,bitmapHeight);
int iX = posX;
int iY = posY;
bitmapWidth += 2 * DistanceMapSpread;
bitmapHeight += 2 * DistanceMapSpread;
sourceWidth += 2 * DistanceMapSpread;
sourceHeight += 2 * DistanceMapSpread;
for (int y = 0; y < sourceHeight; ++y)
for (int y = 0; y < bitmapHeight; ++y)
{
int bitmap_y = y * sourceWidth;
int bitmap_y = y * bitmapWidth;
for (int x = 0; x < sourceWidth; ++x)
for (int x = 0; x < bitmapWidth; ++x)
{
/* Dual channel 16-bit output (more complicated, but good precision and range) */
/*int index = (iX + ( iY * destSize )) * 3;
int index2 = (bitmap_y + x)*3;
destMemory[index] = out[index2];
destMemory[index + 1] = out[index2 + 1];
destMemory[index + 2] = out[index2 + 2];*/
dest[index] = out[index2];
dest[index + 1] = out[index2 + 1];
dest[index + 2] = out[index2 + 2];*/
//Single channel 8-bit output
destMemory[iX + ( iY * destSize )] = out[bitmap_y + x];
dest[iX + ( iY * FontAtlas::CacheTextureWidth )] = distanceMap[bitmap_y + x];
iX += 1;
}
@ -391,33 +493,50 @@ bool FontFreeType::renderCharAt(unsigned short int charToRender, int posX, int p
iX = posX;
iY += 1;
}
free(out);
return true;
free(distanceMap);
}
int iX = posX;
int iY = posY;
for (int y = 0; y < sourceHeight; ++y)
else if(_outlineSize > 0)
{
int bitmap_y = y * sourceWidth;
for (int x = 0; x < sourceWidth; ++x)
unsigned char tempChar;
for (int y = 0; y < bitmapHeight; ++y)
{
unsigned char cTemp = sourceBitmap[bitmap_y + x];
int bitmap_y = y * bitmapWidth;
// the final pixel
destMemory[(iX + ( iY * destSize ) )] = cTemp;
for (int x = 0; x < bitmapWidth; ++x)
{
tempChar = bitmap[(bitmap_y + x) * 2];
dest[(iX + ( iY * FontAtlas::CacheTextureWidth ) ) * 2] = tempChar;
tempChar = bitmap[(bitmap_y + x) * 2 + 1];
dest[(iX + ( iY * FontAtlas::CacheTextureWidth ) ) * 2 + 1] = tempChar;
iX += 1;
iX += 1;
}
iX = posX;
iY += 1;
}
iX = posX;
iY += 1;
delete [] bitmap;
}
else
{
for (int y = 0; y < bitmapHeight; ++y)
{
int bitmap_y = y * bitmapWidth;
//everything good
return true;
for (int x = 0; x < bitmapWidth; ++x)
{
unsigned char cTemp = bitmap[bitmap_y + x];
// the final pixel
dest[(iX + ( iY * FontAtlas::CacheTextureWidth ) )] = cTemp;
iX += 1;
}
iX = posX;
iY += 1;
}
}
}
NS_CC_END

Просмотреть файл

@ -33,6 +33,7 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_STROKER_H
NS_CC_BEGIN
@ -41,25 +42,24 @@ class CC_DLL FontFreeType : public Font
public:
static const int DistanceMapSpread;
static FontFreeType * create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs);
static FontFreeType * create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs,bool distanceFieldEnabled = false,int outline = 0);
static void shutdownFreeType();
void setDistanceFieldEnabled(bool distanceFieldEnabled);
bool isDistanceFieldEnabled() const { return _distanceFieldEnabled;}
bool renderCharAt(unsigned short int charToRender, int posX, int posY, unsigned char *destMemory, int destSize);
int getOutlineSize() const { return _outlineSize; }
void renderCharAt(unsigned char *dest,int posX, int posY, unsigned char* bitmap,int bitmapWidth,int bitmapHeight);
virtual FontAtlas * createFontAtlas() override;
virtual int * getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const override;
unsigned char * getGlyphBitmap(unsigned short theChar, int &outWidth, int &outHeight) const override;
virtual int getFontMaxHeight() const override;
unsigned char * getGlyphBitmap(unsigned short theChar, int &outWidth, int &outHeight, Rect &outRect,int &xAdvance);
bool getBBOXFotChar(unsigned short theChar, Rect &outRect,int &xAdvance) const;
virtual int getFontMaxHeight() const override;
protected:
FontFreeType();
FontFreeType(bool distanceFieldEnabled = false,int outline = 0);
virtual ~FontFreeType();
bool createFontObject(const std::string &fontName, int fontSize);
@ -69,13 +69,16 @@ private:
FT_Library getFTLibrary();
int getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar) const;
unsigned char * getGlyphBitmapWithOutline(unsigned short theChar, FT_BBox &bbox);
static FT_Library _FTlibrary;
static bool _FTInitialized;
FT_Face _fontRef;
FT_Stroker _stroker;
std::string _fontName;
Data _ttfData;
bool _distanceFieldEnabled;
int _outlineSize;
};
NS_CC_END

Просмотреть файл

@ -59,8 +59,7 @@ const char* GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR = "ShaderPositi
const char* GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_NORMAL = "ShaderLabelNormol";
const char* GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_GLOW = "ShaderLabelGlow";
const char* GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_OUTLINE = "ShaderLabelOutline";
const char* GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_SHADOW = "ShaderLabelShadow";
const char* GLProgram::SHADER_NAME_LABEL_OUTLINE = "ShaderLabelOutline";
// uniform names
@ -113,7 +112,7 @@ GLProgram::~GLProgram()
}
}
bool GLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{
_program = glCreateProgram();
CHECK_GL_ERROR_DEBUG();
@ -154,12 +153,13 @@ bool GLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray, co
return true;
}
bool GLProgram::initWithVertexShaderFilename(const char* vShaderFilename, const char* fShaderFilename)
bool GLProgram::initWithFilenames(const std::string &vShaderFilename, const std::string &fShaderFilename)
{
std::string vertexSource = FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->fullPathForFilename(vShaderFilename).c_str());
std::string fragmentSource = FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->fullPathForFilename(fShaderFilename).c_str());
auto fileUtils = FileUtils::getInstance();
std::string vertexSource = fileUtils->getStringFromFile(FileUtils::getInstance()->fullPathForFilename(vShaderFilename));
std::string fragmentSource = fileUtils->getStringFromFile(FileUtils::getInstance()->fullPathForFilename(fShaderFilename));
return initWithVertexShaderByteArray(vertexSource.c_str(), fragmentSource.c_str());
return initWithByteArrays(vertexSource.c_str(), fragmentSource.c_str());
}
std::string GLProgram::getDescription() const
@ -224,7 +224,17 @@ bool GLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* source
return (status == GL_TRUE);
}
void GLProgram::addAttribute(const char* attributeName, GLuint index)
GLint GLProgram::getAttribLocation(const char* attributeName) const
{
return glGetAttribLocation(_program, attributeName);
}
GLint GLProgram::getUniformLocation(const char* attributeName) const
{
return glGetUniformLocation(_program, attributeName);
}
void GLProgram::bindAttribLocation(const char* attributeName, GLuint index) const
{
glBindAttribLocation(_program, index, attributeName);
}

Просмотреть файл

@ -92,8 +92,7 @@ public:
static const char* SHADER_NAME_LABEL_DISTANCEFIELD_NORMAL;
static const char* SHADER_NAME_LABEL_DISTANCEFIELD_GLOW;
static const char* SHADER_NAME_LABEL_DISTANCEFIELD_OUTLINE;
static const char* SHADER_NAME_LABEL_DISTANCEFIELD_SHADOW;
static const char* SHADER_NAME_LABEL_OUTLINE;
// uniform names
static const char* UNIFORM_NAME_P_MATRIX;
@ -123,14 +122,22 @@ public:
* @js initWithString
* @lua initWithString
*/
bool initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray);
bool initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray);
/** Initializes the GLProgram with a vertex and fragment with contents of filenames
* @js init
* @lua init
*/
bool initWithVertexShaderFilename(const char* vShaderFilename, const char* fShaderFilename);
/** It will add a new attribute to the shader */
void addAttribute(const char* attributeName, GLuint index);
bool initWithFilenames(const std::string& vShaderFilename, const std::string& fShaderFilename);
/** It will add a new attribute to the shader by calling glBindAttribLocation */
void bindAttribLocation(const char* attributeName, GLuint index) const;
/** calls glGetAttribLocation */
GLint getAttribLocation(const char* attributeName) const;
/** calls glGetUniformLocation() */
GLint getUniformLocation(const char* attributeName) const;
/** links the glProgram */
bool link();
/** it will call glUseProgram() */
@ -235,6 +242,13 @@ public:
inline const GLuint getProgram() const { return _program; }
// DEPRECATED
CC_DEPRECATED_ATTRIBUTE bool initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{ return initWithByteArrays(vShaderByteArray, fShaderByteArray); }
CC_DEPRECATED_ATTRIBUTE bool initWithVertexShaderFilename(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{ return initWithFilenames(vShaderByteArray, fShaderByteArray); }
CC_DEPRECATED_ATTRIBUTE void addAttribute(const char* attributeName, GLuint index) const { return bindAttribLocation(attributeName, index); }
private:
bool updateUniformLocation(GLint location, const GLvoid* data, unsigned int bytes);
virtual std::string getDescription() const;

Просмотреть файл

@ -34,10 +34,10 @@
#include "renderer/CCRenderer.h"
#include "CCFont.h"
#define DISTANCEFIELD_ATLAS_FONTSIZE 50
NS_CC_BEGIN
const int Label::DefultFontSize = 50;
Label* Label::create()
{
Label *ret = new Label();
@ -56,11 +56,9 @@ Label* Label::createWithTTF(const TTFConfig& ttfConfig, const std::string& text,
if (!ret)
return nullptr;
if (ret->setTTFConfig(ttfConfig))
{
if(ttfConfig.distanceFieldEnabled)
ret->setFontScale(1.0f * ttfConfig.fontSize / DISTANCEFIELD_ATLAS_FONTSIZE);
ret->setMaxLineWidth(lineSize);
ret->setString(text);
ret->autorelease();
@ -203,6 +201,7 @@ Label::Label(FontAtlas *atlas, TextHAlignment alignment, bool useDistanceField,b
, _fontScale(1.0f)
, _uniformEffectColor(0)
,_currNumLines(-1)
,_fontConfig(TTFConfig(""))
{
_cascadeColorEnabled = true;
_batchNodes.push_back(this);
@ -213,7 +212,7 @@ Label::~Label()
delete [] _currentUTF16String;
delete [] _originalUTF16String;
delete [] _horizontalKernings;
if (_fontAtlas)
FontAtlasCache::releaseFontAtlas(_fontAtlas);
@ -225,25 +224,49 @@ bool Label::init()
bool ret = true;
if(_fontAtlas)
{
ret = SpriteBatchNode::initWithTexture(_fontAtlas->getTexture(0), 30);
if (_reusedLetter == nullptr)
{
_reusedLetter = Sprite::createWithTexture(&_fontAtlas->getTexture(0));
_reusedLetter = Sprite::createWithTexture(_fontAtlas->getTexture(0));
_reusedLetter->setOpacityModifyRGB(_isOpacityModifyRGB);
_reusedLetter->retain();
_reusedLetter->setAnchorPoint(Point::ANCHOR_TOP_LEFT);
_reusedLetter->setBatchNode(this);
}
ret = SpriteBatchNode::initWithTexture(&_fontAtlas->getTexture(0), 30);
}
if (_useDistanceField)
setLabelEffect(LabelEffect::NORMAL,Color3B::BLACK);
else if(_useA8Shader)
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_A8_COLOR));
else
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
_currLabelEffect = LabelEffect::NORMAL;
initProgram();
return ret;
}
void Label::initProgram()
{
switch (_currLabelEffect)
{
case cocos2d::LabelEffect::NORMAL:
case cocos2d::LabelEffect::SHADOW:
if (_useDistanceField)
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_NORMAL));
else if (_useA8Shader)
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_A8_COLOR));
else
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
break;
case cocos2d::LabelEffect::OUTLINE:
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_OUTLINE));
break;
case cocos2d::LabelEffect::GLOW:
if (_useDistanceField)
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_GLOW));
break;
default:
return;
}
_uniformEffectColor = glGetUniformLocation(_shaderProgram->getProgram(), "v_effectColor");
}
bool Label::initWithFontAtlas(FontAtlas* atlas,bool distanceFieldEnabled /* = false */, bool useA8Shader /* = false */)
{
FontAtlas *oldAtlas = _fontAtlas;
@ -287,16 +310,32 @@ bool Label::initWithFontAtlas(FontAtlas* atlas,bool distanceFieldEnabled /* = fa
bool Label::setTTFConfig(const TTFConfig& ttfConfig)
{
FontAtlas *newAtlas = nullptr;
if(ttfConfig.distanceFieldEnabled)
newAtlas = FontAtlasCache::getFontAtlasTTF(ttfConfig.fontFilePath, DISTANCEFIELD_ATLAS_FONTSIZE, ttfConfig.glyphs, ttfConfig.customGlyphs,true);
else
newAtlas = FontAtlasCache::getFontAtlasTTF(ttfConfig.fontFilePath, ttfConfig.fontSize, ttfConfig.glyphs, ttfConfig.customGlyphs,false);
FontAtlas *newAtlas = FontAtlasCache::getFontAtlasTTF(ttfConfig);
if (!newAtlas)
return false;
return initWithFontAtlas(newAtlas,ttfConfig.distanceFieldEnabled,true);
if (initWithFontAtlas(newAtlas,ttfConfig.distanceFieldEnabled,true))
{
_fontConfig = ttfConfig;
if (ttfConfig.outlineSize > 0)
{
_fontConfig.distanceFieldEnabled = false;
_useDistanceField = false;
_useA8Shader = false;
_currLabelEffect = LabelEffect::OUTLINE;
initProgram();
}
else if(ttfConfig.distanceFieldEnabled)
{
this->setFontScale(1.0f * ttfConfig.fontSize / DefultFontSize);
}
return true;
}
else
{
return false;
}
}
bool Label::setBMFontFilePath(const std::string& bmfontFilePath, const Point& imageOffset /* = Point::ZERO */)
@ -313,14 +352,14 @@ void Label::setString(const std::string& text)
{
if (!_fontAtlas || _commonLineHeight <= 0)
return ;
unsigned short* utf16String = cc_utf8_to_utf16(text.c_str());
if(!utf16String)
return ;
_originalUTF8String = text;
setCurrentString(utf16String);
setOriginalString(utf16String);
// align text
alignText();
}
@ -332,7 +371,7 @@ void Label::setAlignment(TextHAlignment alignment)
{
// store
_alignment = alignment;
if (_currentUTF16String)
{
// reset the string
@ -350,7 +389,7 @@ void Label::setMaxLineWidth(float width)
{
// store
_maxLineWidth = width;
if (_currentUTF16String)
{
// reset the string
@ -368,7 +407,7 @@ void Label::setLineBreakWithoutSpace(bool breakWithoutSpace)
{
// store
_lineBreakWithoutSpaces = breakWithoutSpace;
// need to align text again
if(_currentUTF16String)
{
@ -456,10 +495,10 @@ void Label::alignText()
LabelTextFormatter::createStringSprites(this);
if(_maxLineWidth > 0 && _contentSize.width > _maxLineWidth && LabelTextFormatter::multilineText(this) )
LabelTextFormatter::createStringSprites(this);
if(_currNumLines > 1 && _alignment != TextHAlignment::LEFT)
LabelTextFormatter::alignText(this);
int strLen = cc_wcslen(_currentUTF16String);
Rect uvRect;
Sprite* letterSprite;
@ -484,7 +523,7 @@ void Label::alignText()
}
}
}
int index;
for (int ctr = 0; ctr < strLen; ++ctr)
{
@ -507,10 +546,10 @@ bool Label::computeHorizontalKernings(unsigned short int *stringToRender)
delete [] _horizontalKernings;
_horizontalKernings = 0;
}
int letterCount = 0;
_horizontalKernings = _fontAtlas->getFont()->getHorizontalKerningForTextUTF16(stringToRender, letterCount);
if(!_horizontalKernings)
return false;
else
@ -523,13 +562,13 @@ bool Label::setOriginalString(unsigned short *stringToSet)
{
delete [] _originalUTF16String;
}
int newStringLenght = cc_wcslen(stringToSet);
_originalUTF16String = new unsigned short int [newStringLenght + 1];
memset(_originalUTF16String, 0, (newStringLenght + 1) * 2);
memcpy(_originalUTF16String, stringToSet, (newStringLenght * 2));
_originalUTF16String[newStringLenght] = 0;
return true;
}
@ -540,7 +579,7 @@ bool Label::setCurrentString(unsigned short *stringToSet)
{
delete [] _currentUTF16String;
}
_currentUTF16String = stringToSet;
computeStringNumLines();
// compute the advances
@ -551,19 +590,19 @@ void Label::resetCurrentString()
{
if ((!_currentUTF16String) && (!_originalUTF16String))
return;
// set the new string
if (_currentUTF16String)
{
delete [] _currentUTF16String;
_currentUTF16String = 0;
}
int stringLenght = cc_wcslen(_originalUTF16String);
_currentUTF16String = new unsigned short int [stringLenght + 1];
memcpy(_currentUTF16String, _originalUTF16String, stringLenght * 2);
_currentUTF16String[stringLenght] = 0;
}
void Label::updateSpriteWithLetterDefinition(const FontLetterDefinition &theDefinition, Texture2D *theTexture)
@ -603,7 +642,7 @@ bool Label::recordPlaceholderInfo(int spriteIndex)
}
_lettersInfo[spriteIndex].def.validDefinition = false;
return false;
}
@ -614,31 +653,68 @@ void Label::addChild(Node * child, int zOrder/* =0 */, int tag/* =0 */)
void Label::setLabelEffect(LabelEffect effect,const Color3B& effectColor)
{
if(_useDistanceField == false)
return;
_currLabelEffect = effect;
_effectColor = effectColor;
switch (_currLabelEffect)
switch (effect)
{
case cocos2d::LabelEffect::NORMAL:
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_NORMAL));
case cocos2d::LabelEffect::NORMAL:
disableEffect();
break;
case cocos2d::LabelEffect::OUTLINE:
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_OUTLINE));
enableOutline(Color4B(effectColor));
break;
case cocos2d::LabelEffect::SHADOW:
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_SHADOW));
enableShadow(effectColor);
break;
case cocos2d::LabelEffect::GLOW:
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_GLOW));
enableGlow(effectColor);
break;
default:
return;
break;
}
}
_uniformEffectColor = glGetUniformLocation(_shaderProgram->getProgram(), "v_effectColor");
void Label::enableGlow(const Color3B& glowColor)
{
if(_useDistanceField == false)
return;
_currLabelEffect = LabelEffect::GLOW;
_effectColor = glowColor;
initProgram();
}
void Label::enableOutline(const Color4B& outlineColor,int outlineSize /* = 1 */)
{
_outlineColor = outlineColor;
if (outlineSize > 0)
{
_currLabelEffect = LabelEffect::OUTLINE;
if (_fontConfig.outlineSize != outlineSize)
{
_fontConfig.outlineSize = outlineSize;
setTTFConfig(_fontConfig);
}
initProgram();
}
}
void Label::enableShadow(const Color3B& shadowColor /* = Color3B::BLACK */,const Size &offset /* = Size(2 ,-2)*/, float opacity /* = 0.75f */, int blurRadius /* = 0 */)
{
_shadowOpacity = opacity;
_effectColor = shadowColor;
_shadowOffset = offset;
//todo:support blur for shadow
_shadowBlurRadius = 0;
_currLabelEffect = LabelEffect::SHADOW;
}
void Label::disableEffect()
{
if (_currLabelEffect == LabelEffect::OUTLINE)
{
_fontConfig.outlineSize = 0;
setTTFConfig(_fontConfig);
}
_currLabelEffect = LabelEffect::NORMAL;
initProgram();
}
void Label::setFontScale(float fontScale)
@ -647,7 +723,7 @@ void Label::setFontScale(float fontScale)
Node::setScale(_fontScale);
}
void Label::onDraw()
void Label::onDraw(const kmMat4& transform, bool transformUpdated)
{
CC_PROFILER_START("Label - draw");
@ -657,32 +733,83 @@ void Label::onDraw()
return;
}
CC_NODE_DRAW_SETUP();
_shaderProgram->use();
GL::blendFunc( _blendFunc.src, _blendFunc.dst );
bool trans = false;
if (_useDistanceField && _currLabelEffect != LabelEffect::NORMAL)
if (_currLabelEffect == LabelEffect::OUTLINE)
{
_shaderProgram->setUniformLocationWith4f(_uniformEffectColor, _outlineColor.r/255.0f,_outlineColor.g/255.0f,_outlineColor.b/255.0f,_outlineColor.a/255.0f);
}
else if (_currLabelEffect == LabelEffect::GLOW)
{
_shaderProgram->setUniformLocationWith3f(_uniformEffectColor, _effectColor.r/255.0f,_effectColor.g/255.0f,_effectColor.b/255.0f);
}
for(const auto &child: _children)
else if(_currLabelEffect == LabelEffect::SHADOW && _shadowBlurRadius <= 0)
{
child->updateTransform();
trans = true;
drawShadowWithoutBlur();
}
GL::blendFunc( _blendFunc.src, _blendFunc.dst );
_shaderProgram->setUniformsForBuiltins(transform);
for(const auto &child: _children)
{
if(child->getTag() >= 0)
child->updateTransform();
}
for (const auto& batchNode:_batchNodes)
{
batchNode->getTextureAtlas()->drawQuads();
}
if (trans)
{
kmGLPopMatrix();
}
CC_PROFILER_STOP("Label - draw");
}
void Label::drawShadowWithoutBlur()
{
_position.x += _shadowOffset.width;
_position.y += _shadowOffset.height;
_transformDirty = _inverseDirty = true;
Color3B oldColor = _realColor;
GLubyte oldOPacity = _displayedOpacity;
_displayedOpacity = _shadowOpacity * _displayedOpacity;
setColor(_effectColor);
_modelViewTransform = transform(_parentTransform);
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
_shaderProgram->setUniformsForBuiltins(_modelViewTransform);
for(const auto &child: _children)
{
child->updateTransform();
}
for (const auto& batchNode:_batchNodes)
{
batchNode->getTextureAtlas()->drawQuads();
}
_position.x -= _shadowOffset.width;
_position.y -= _shadowOffset.height;
_transformDirty = _inverseDirty = true;
_displayedOpacity = oldOPacity;
setColor(oldColor);
_modelViewTransform = transform(_parentTransform);
kmGLLoadMatrix(&_modelViewTransform);
//kmGLPopMatrix();
}
void Label::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(Label::onDraw, this);
_customCommand.func = CC_CALLBACK_0(Label::onDraw, this, transform, transformUpdated);
renderer->addCommand(&_customCommand);
}
@ -692,34 +819,42 @@ void Label::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parent
{
return;
}
if (_currLabelEffect == LabelEffect::SHADOW && _shadowBlurRadius <= 0)
{
_parentTransform = parentTransform;
draw(renderer, _modelViewTransform, true);
}
else
{
bool dirty = parentTransformUpdated || _transformUpdated;
if(dirty)
_modelViewTransform = transform(parentTransform);
_transformUpdated = false;
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
draw(renderer, _modelViewTransform, dirty);
kmGLPopMatrix();
}
bool dirty = parentTransformUpdated || _transformUpdated;
if(dirty)
_modelViewTransform = transform(parentTransform);
_transformUpdated = false;
// IMPORTANT:
// To ease the migration to v3.0, we still support the kmGL stack,
// but it is deprecated and your code should not rely on it
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
draw(renderer, _modelViewTransform, dirty);
kmGLPopMatrix();
setOrderOfArrival(0);
}
///// PROTOCOL STUFF
Sprite * Label::getLetter(int lettetIndex)
{
if (lettetIndex < getStringLenght())
{
if(_lettersInfo[lettetIndex].def.validDefinition == false)
return nullptr;
Sprite* sp = static_cast<Sprite*>(this->getChildByTag(lettetIndex));
if (!sp)
@ -730,17 +865,17 @@ Sprite * Label::getLetter(int lettetIndex)
uvRect.origin.x = _lettersInfo[lettetIndex].def.U;
uvRect.origin.y = _lettersInfo[lettetIndex].def.V;
sp = Sprite::createWithTexture(&_fontAtlas->getTexture(_lettersInfo[lettetIndex].def.textureID),uvRect);
sp = Sprite::createWithTexture(_fontAtlas->getTexture(_lettersInfo[lettetIndex].def.textureID),uvRect);
sp->setBatchNode(this);
sp->setAnchorPoint(Point::ANCHOR_MIDDLE);
sp->setPosition(Point(_lettersInfo[lettetIndex].position.x+uvRect.size.width/2,_lettersInfo[lettetIndex].position.y-uvRect.size.height/2));
sp->setOpacity(_realOpacity);
this->addSpriteWithoutQuad(sp, lettetIndex, lettetIndex);
}
return sp;
}
return nullptr;
}
@ -758,14 +893,14 @@ int Label::getStringNumLines() const
void Label::computeStringNumLines()
{
int quantityOfLines = 1;
unsigned int stringLen = _currentUTF16String ? cc_wcslen(_currentUTF16String) : -1;
if (stringLen < 1)
{
_currNumLines = stringLen;
return;
}
// count number of lines
for (unsigned int i = 0; i < stringLen - 1; ++i)
{
@ -774,7 +909,7 @@ void Label::computeStringNumLines()
quantityOfLines++;
}
}
_currNumLines = quantityOfLines;
}
@ -800,8 +935,6 @@ bool Label::breakLineWithoutSpace() const
}
// RGBA protocol
bool Label::isOpacityModifyRGB() const
{
return _isOpacityModifyRGB;
@ -810,7 +943,7 @@ bool Label::isOpacityModifyRGB() const
void Label::setOpacityModifyRGB(bool isOpacityModifyRGB)
{
_isOpacityModifyRGB = isOpacityModifyRGB;
for(const auto& child: _children) {
child->setOpacityModifyRGB(_isOpacityModifyRGB);
}
@ -820,16 +953,19 @@ void Label::setOpacityModifyRGB(bool isOpacityModifyRGB)
void Label::setColor(const Color3B& color)
{
_reusedLetter->setColor(color);
_reusedLetter->setColor(color);
SpriteBatchNode::setColor(color);
}
void Label::updateColor()
{
V3F_C4B_T2F_Quad *quads = _textureAtlas->getQuads();
auto count = _textureAtlas->getTotalQuads();
if (nullptr == _textureAtlas)
{
return;
}
Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity );
// special opacity for premultiplied textures
if (_isOpacityModifyRGB)
{
@ -837,13 +973,23 @@ void Label::updateColor()
color4.g *= _displayedOpacity/255.0f;
color4.b *= _displayedOpacity/255.0f;
}
for (int index=0; index<count; ++index)
cocos2d::TextureAtlas* textureAtlas;
V3F_C4B_T2F_Quad *quads;
for (const auto& batchNode:_batchNodes)
{
quads[index].bl.colors = color4;
quads[index].br.colors = color4;
quads[index].tl.colors = color4;
quads[index].tr.colors = color4;
_textureAtlas->updateQuad(&quads[index], index);
textureAtlas = batchNode->getTextureAtlas();
quads = textureAtlas->getQuads();
auto count = textureAtlas->getTotalQuads();
for (int index = 0; index < count; ++index)
{
quads[index].bl.colors = color4;
quads[index].br.colors = color4;
quads[index].tl.colors = color4;
quads[index].tr.colors = color4;
textureAtlas->updateQuad(&quads[index], index);
}
}
}

Просмотреть файл

@ -57,20 +57,29 @@ typedef struct _ttfConfig
GlyphCollection glyphs;
const char *customGlyphs;
bool distanceFieldEnabled;
int outlineSize;
_ttfConfig(const char* filePath,int size = 36, const GlyphCollection& glyphCollection = GlyphCollection::NEHE,
const char *customGlyphCollection = nullptr,bool useDistanceField = false)
_ttfConfig(const char* filePath = "",int size = 36, const GlyphCollection& glyphCollection = GlyphCollection::NEHE,
const char *customGlyphCollection = nullptr,bool useDistanceField = false,int outline = 0)
:fontFilePath(filePath)
,fontSize(size)
,glyphs(glyphCollection)
,customGlyphs(customGlyphCollection)
,distanceFieldEnabled(useDistanceField)
{}
,outlineSize(outline)
{
if(outline > 0)
{
distanceFieldEnabled = false;
}
}
}TTFConfig;
class CC_DLL Label : public SpriteBatchNode, public LabelProtocol
{
public:
static const int DefultFontSize;
static Label* create();
CC_DEPRECATED_ATTRIBUTE static Label* createWithTTF(const std::string& label, const std::string& fontFilePath, int fontSize, int lineSize = 0, TextHAlignment alignment = TextHAlignment::LEFT, GlyphCollection glyphs = GlyphCollection::NEHE, const char *customGlyphs = 0, bool useDistanceField = false);
@ -82,18 +91,33 @@ public:
static Label * createWithCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
static Label * createWithCharMap(const std::string& plistFile);
bool setTTFConfig(const TTFConfig& ttfConfig);
virtual bool setTTFConfig(const TTFConfig& ttfConfig);
bool setBMFontFilePath(const std::string& bmfontFilePath, const Point& imageOffset = Point::ZERO);
virtual bool setBMFontFilePath(const std::string& bmfontFilePath, const Point& imageOffset = Point::ZERO);
bool setCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
bool setCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
bool setCharMap(const std::string& plistFile);
virtual bool setCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
virtual bool setCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
virtual bool setCharMap(const std::string& plistFile);
virtual void setString(const std::string& text) override;
//only support for TTF
void setLabelEffect(LabelEffect effect,const Color3B& effectColor);
CC_DEPRECATED_ATTRIBUTE void setLabelEffect(LabelEffect effect,const Color3B& effectColor);
/**
* Enable shadow for the label
*
* @todo support blur for shadow effect
*/
virtual void enableShadow(const Color3B& shadowColor = Color3B::BLACK,const Size &offset = Size(2,-2), float opacity = 0.75f, int blurRadius = 0);
/** only support for TTF */
virtual void enableOutline(const Color4B& outlineColor,int outlineSize = -1);
/** only support for TTF */
virtual void enableGlow(const Color3B& glowColor);
/** disable shadow/outline/glow rendering */
virtual void disableEffect();
virtual void setAlignment(TextHAlignment alignment);
CC_DEPRECATED_ATTRIBUTE void setWidth(float width) { setMaxLineWidth(width);}
@ -112,29 +136,30 @@ public:
virtual Sprite * getLetter(int lettetIndex);
// font related stuff
virtual int getCommonLineHeight() const;
int getCommonLineHeight() const;
// string related stuff
virtual int getStringNumLines() const;
virtual int getStringLenght() const;
virtual TextHAlignment getTextAlignment() const;
int getStringNumLines() const;
int getStringLenght() const;
TextHAlignment getTextAlignment() const;
// label related stuff
virtual float getMaxLineWidth() const;
virtual bool breakLineWithoutSpace() const;
CC_DEPRECATED_ATTRIBUTE float getWidth() const { return getMaxLineWidth(); }
float getMaxLineWidth() const;
bool breakLineWithoutSpace() const;
virtual const std::string& getString() const override { return _originalUTF8String; }
void addChild(Node * child, int zOrder=0, int tag=0) override;
virtual void addChild(Node * child, int zOrder=0, int tag=0) override;
virtual std::string getDescription() const override;
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual void onDraw();
virtual FontAtlas* getFontAtlas() const {return _fontAtlas;}
FontAtlas* getFontAtlas() const {return _fontAtlas;}
protected:
void onDraw(const kmMat4& transform, bool transformUpdated);
private:
struct LetterInfo
{
FontLetterDefinition def;
@ -150,19 +175,19 @@ private:
* @js NA
* @lua NA
*/
~Label();
virtual ~Label();
bool initWithFontAtlas(FontAtlas* atlas,bool distanceFieldEnabled = false, bool useA8Shader = false);
virtual bool initWithFontAtlas(FontAtlas* atlas,bool distanceFieldEnabled = false, bool useA8Shader = false);
// CCLabelTextFormat protocol implementation
virtual bool recordLetterInfo(const cocos2d::Point& point,const FontLetterDefinition& letterDef, int spriteIndex);
virtual bool recordPlaceholderInfo(int spriteIndex);
bool recordLetterInfo(const cocos2d::Point& point,const FontLetterDefinition& letterDef, int spriteIndex);
bool recordPlaceholderInfo(int spriteIndex);
void setFontScale(float fontScale);
bool init();
virtual bool init();
void alignText();
virtual void alignText();
bool computeHorizontalKernings(unsigned short int *stringToRender);
bool setCurrentString(unsigned short *stringToSet);
@ -174,6 +199,10 @@ private:
virtual void updateColor() override;
virtual void initProgram();
void drawShadowWithoutBlur();
//! used for optimization
Sprite *_reusedLetter;
Rect _reusedRect;
@ -204,6 +233,19 @@ private:
std::vector<SpriteBatchNode*> _batchNodes;
Size _shadowOffset;
float _shadowOpacity;
int _shadowBlurRadius;
Color4B _outlineColor;
TTFConfig _fontConfig;
kmMat4 _parentTransform;
private:
CC_DISALLOW_COPY_AND_ASSIGN(Label);
friend class LabelTextFormatter;
};

Просмотреть файл

@ -584,7 +584,7 @@ void LayerColor::updateColor()
void LayerColor::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(LayerColor::onDraw, this);
_customCommand.func = CC_CALLBACK_0(LayerColor::onDraw, this, transform, transformUpdated);
renderer->addCommand(&_customCommand);
for(int i = 0; i < 4; ++i)
@ -594,12 +594,12 @@ void LayerColor::draw(Renderer *renderer, const kmMat4 &transform, bool transfor
kmVec3TransformCoord(&pos, &pos, &_modelViewTransform);
_noMVPVertices[i] = Vertex3F(pos.x,pos.y,pos.z);
}
}
void LayerColor::onDraw()
void LayerColor::onDraw(const kmMat4& transform, bool transformUpdated)
{
CC_NODE_DRAW_SETUP();
getShaderProgram()->use();
getShaderProgram()->setUniformsForBuiltins(transform);
GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR );
//

Просмотреть файл

@ -266,8 +266,7 @@ public:
// Overrides
//
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual void onDraw();
virtual void setContentSize(const Size & var) override;
/** BlendFunction. Conforms to BlendProtocol protocol */
/**
@ -289,7 +288,8 @@ public:
protected:
LayerColor();
virtual ~LayerColor();
virtual bool init();
void onDraw(const kmMat4& transform, bool transformUpdated);
bool init();
bool initWithColor(const Color4B& color, GLfloat width, GLfloat height);
bool initWithColor(const Color4B& color);

Просмотреть файл

@ -325,10 +325,10 @@ void MotionStreak::reset()
_nuPoints = 0;
}
void MotionStreak::onDraw()
void MotionStreak::onDraw(const kmMat4 &transform, bool transformUpdated)
{
getShaderProgram()->use();
getShaderProgram()->setUniformsForBuiltins(_modelViewTransform);
getShaderProgram()->setUniformsForBuiltins(transform);
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX );
GL::blendFunc( _blendFunc.src, _blendFunc.dst );
@ -360,9 +360,8 @@ void MotionStreak::draw(Renderer *renderer, const kmMat4 &transform, bool transf
if(_nuPoints <= 1)
return;
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(MotionStreak::onDraw, this);
_customCommand.func = CC_CALLBACK_0(MotionStreak::onDraw, this, transform, transformUpdated);
renderer->addCommand(&_customCommand);
}
NS_CC_END

Просмотреть файл

@ -103,7 +103,7 @@ public:
protected:
//renderer callback
void onDraw();
void onDraw(const kmMat4 &transform, bool transformUpdated);
MotionStreak();
virtual ~MotionStreak();

Просмотреть файл

@ -351,7 +351,6 @@ void ParticleBatchNode::removeChild(Node* aChild, bool cleanup)
CCASSERT(_children.contains(aChild), "CCParticleBatchNode doesn't contain the sprite. Can't remove it");
ParticleSystem* child = static_cast<ParticleSystem*>(aChild);
Node::removeChild(child, cleanup);
// remove child helper
_textureAtlas->removeQuadsAtIndex(child->getAtlasIndex(), child->getTotalParticles());
@ -361,6 +360,7 @@ void ParticleBatchNode::removeChild(Node* aChild, bool cleanup)
// particle could be reused for self rendering
child->setBatchNode(nullptr);
Node::removeChild(child, cleanup);
updateAllAtlasIndexes();
}

Просмотреть файл

@ -501,10 +501,11 @@ Point ProgressTimer::boundaryTexCoord(char index)
return Point::ZERO;
}
void ProgressTimer::onDraw()
void ProgressTimer::onDraw(const kmMat4 &transform, bool transformUpdated)
{
CC_NODE_DRAW_SETUP();
getShaderProgram()->use();
getShaderProgram()->setUniformsForBuiltins(transform);
GL::blendFunc( _sprite->getBlendFunc().src, _sprite->getBlendFunc().dst );
@ -557,7 +558,7 @@ void ProgressTimer::draw(Renderer *renderer, const kmMat4 &transform, bool trans
return;
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(ProgressTimer::onDraw, this);
_customCommand.func = CC_CALLBACK_0(ProgressTimer::onDraw, this, transform, transformUpdated);
renderer->addCommand(&_customCommand);
}

Просмотреть файл

@ -131,8 +131,7 @@ protected:
/** Initializes a progress timer with the sprite as the shape the timer goes through */
bool initWithSprite(Sprite* sp);
void onDraw();
void onDraw(const kmMat4 &transform, bool transformUpdated);
Tex2F textureCoordFromAlphaPoint(Point alpha);
Vertex2F vertexFromAlphaPoint(Point alpha);

Просмотреть файл

@ -233,11 +233,7 @@ void TimerScriptHandler::trigger()
void TimerScriptHandler::cancel()
{
if (0 != _scriptHandler)
{
ScriptEngineManager::getInstance()->getScriptEngine()->removeScriptHandler(_scriptHandler);
_scriptHandler = 0;
}
}
#endif

Просмотреть файл

@ -45,8 +45,7 @@ enum {
kShaderType_PositionLengthTexureColor,
kShaderType_LabelDistanceFieldNormal,
kShaderType_LabelDistanceFieldGlow,
kShaderType_LabelDistanceFieldOutline,
kShaderType_LabelDistanceFieldShadow,
kShaderType_LabelOutline,
kShaderType_MAX,
};
@ -177,12 +176,8 @@ void ShaderCache::loadDefaultShaders()
_programs.insert( std::make_pair(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_GLOW, p) );
p = new GLProgram();
loadDefaultShader(p, kShaderType_LabelDistanceFieldOutline);
_programs.insert( std::make_pair(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_OUTLINE, p) );
p = new GLProgram();
loadDefaultShader(p, kShaderType_LabelDistanceFieldShadow);
_programs.insert( std::make_pair(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_SHADOW, p) );
loadDefaultShader(p, kShaderType_LabelOutline);
_programs.insert( std::make_pair(GLProgram::SHADER_NAME_LABEL_OUTLINE, p) );
}
void ShaderCache::reloadDefaultShaders()
@ -260,122 +255,110 @@ void ShaderCache::reloadDefaultShaders()
p->reset();
loadDefaultShader(p, kShaderType_LabelDistanceFieldGlow);
p = getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_OUTLINE);
p = getProgram(GLProgram::SHADER_NAME_LABEL_OUTLINE);
p->reset();
loadDefaultShader(p, kShaderType_LabelDistanceFieldOutline);
p = getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_SHADOW);
p->reset();
loadDefaultShader(p, kShaderType_LabelDistanceFieldShadow);
loadDefaultShader(p, kShaderType_LabelOutline);
}
void ShaderCache::loadDefaultShader(GLProgram *p, int type)
{
switch (type) {
case kShaderType_PositionTextureColor:
p->initWithVertexShaderByteArray(ccPositionTextureColor_vert, ccPositionTextureColor_frag);
p->initWithByteArrays(ccPositionTextureColor_vert, ccPositionTextureColor_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
break;
case kShaderType_PositionTextureColor_noMVP:
p->initWithVertexShaderByteArray(ccPositionTextureColor_noMVP_vert, ccPositionTextureColor_noMVP_frag);
p->initWithByteArrays(ccPositionTextureColor_noMVP_vert, ccPositionTextureColor_noMVP_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
break;
case kShaderType_PositionTextureColorAlphaTest:
p->initWithVertexShaderByteArray(ccPositionTextureColor_vert, ccPositionTextureColorAlphaTest_frag);
p->initWithByteArrays(ccPositionTextureColor_vert, ccPositionTextureColorAlphaTest_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
break;
case kShaderType_PositionColor:
p->initWithVertexShaderByteArray(ccPositionColor_vert ,ccPositionColor_frag);
p->initWithByteArrays(ccPositionColor_vert ,ccPositionColor_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
break;
case kShaderType_PositionColor_noMVP:
p->initWithVertexShaderByteArray(ccPositionTextureColor_noMVP_vert ,ccPositionColor_frag);
p->initWithByteArrays(ccPositionTextureColor_noMVP_vert ,ccPositionColor_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
break;
case kShaderType_PositionTexture:
p->initWithVertexShaderByteArray(ccPositionTexture_vert ,ccPositionTexture_frag);
p->initWithByteArrays(ccPositionTexture_vert ,ccPositionTexture_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
break;
case kShaderType_PositionTexture_uColor:
p->initWithVertexShaderByteArray(ccPositionTexture_uColor_vert, ccPositionTexture_uColor_frag);
p->initWithByteArrays(ccPositionTexture_uColor_vert, ccPositionTexture_uColor_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
break;
case kShaderType_PositionTextureA8Color:
p->initWithVertexShaderByteArray(ccPositionTextureA8Color_vert, ccPositionTextureA8Color_frag);
p->initWithByteArrays(ccPositionTextureA8Color_vert, ccPositionTextureA8Color_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
break;
case kShaderType_Position_uColor:
p->initWithVertexShaderByteArray(ccPosition_uColor_vert, ccPosition_uColor_frag);
p->initWithByteArrays(ccPosition_uColor_vert, ccPosition_uColor_frag);
p->addAttribute("aVertex", GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation("aVertex", GLProgram::VERTEX_ATTRIB_POSITION);
break;
case kShaderType_PositionLengthTexureColor:
p->initWithVertexShaderByteArray(ccPositionColorLengthTexture_vert, ccPositionColorLengthTexture_frag);
p->initWithByteArrays(ccPositionColorLengthTexture_vert, ccPositionColorLengthTexture_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
break;
case kShaderType_LabelDistanceFieldNormal:
p->initWithVertexShaderByteArray(ccLabelDistanceFieldNormal_vert, ccLabelDistanceFieldNormal_frag);
p->initWithByteArrays(ccLabelDistanceFieldNormal_vert, ccLabelDistanceFieldNormal_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
break;
case kShaderType_LabelDistanceFieldGlow:
p->initWithVertexShaderByteArray(ccLabelDistanceFieldGlow_vert, ccLabelDistanceFieldGlow_frag);
p->initWithByteArrays(ccLabelDistanceFieldGlow_vert, ccLabelDistanceFieldGlow_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
break;
case kShaderType_LabelDistanceFieldOutline:
p->initWithVertexShaderByteArray(ccLabelDistanceFieldOutline_vert, ccLabelDistanceFieldOutline_frag);
case kShaderType_LabelOutline:
p->initWithByteArrays(ccLabelOutline_vert, ccLabelOutline_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
break;
case kShaderType_LabelDistanceFieldShadow:
p->initWithVertexShaderByteArray(ccLabelDistanceFieldShadow_vert, ccLabelDistanceFieldShadow_frag);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
break;
default:

Просмотреть файл

@ -18,7 +18,7 @@ void main() \n\
//float width = fwidth(dist); \n\
//assign width for constant will lead to a little bit fuzzy,it's temporary measure.\n\
float width = 0.04; \n\
float alpha = smoothstep(0.5-width, 0.5+width, dist); \n\
float alpha = smoothstep(0.5-width, 0.5+width, dist) * v_fragmentColor.a; \n\
gl_FragColor = vec4(v_fragmentColor.rgb,alpha); \n\
} \n\
";

Просмотреть файл

@ -6,19 +6,19 @@ precision lowp float; \n\
varying vec4 v_fragmentColor; \n\
varying vec2 v_texCoord; \n\
uniform sampler2D CC_Texture0; \n\
uniform vec3 v_effectColor; \n\
uniform vec4 v_effectColor; \n\
\n\
void main() \n\
{ \n\
float dist = texture2D(CC_Texture0, v_texCoord).a; \n\
//todo:Implementation 'fwidth' for glsl 1.0 \n\
//float width = fwidth(dist); \n\
//assign width for constant will lead to a little bit fuzzy,it's temporary measure.\n\
float width = 0.04; \n\
float alpha = smoothstep(0.5-width, 0.5+width, dist); \n\
//outline \n\
float mu = smoothstep(0.545-width, 0.545+width, dist); \n\
vec3 rgb = v_effectColor*(1.0-mu) + v_fragmentColor.rgb*mu; \n\
gl_FragColor = vec4(rgb, max(alpha,mu)); \n\
} \n\
void main() \n\
{ \n\
vec4 sample = texture2D(CC_Texture0, v_texCoord); \n\
float fontAlpha = sample.a; \n\
float outlineAlpha = sample.r; \n\
if (outlineAlpha > 0.0){ \n\
vec3 color = v_fragmentColor.rgb * fontAlpha + v_effectColor.rgb * (1.0 - fontAlpha);\n\
gl_FragColor = vec4( color,max(fontAlpha,outlineAlpha)*v_fragmentColor.a); \n\
} \n\
else { \n\
discard; \n\
} \n\
} \n\
";

Просмотреть файл

@ -91,14 +91,9 @@ const GLchar * ccLabelDistanceFieldGlow_frag =
const GLchar * ccLabelDistanceFieldGlow_vert =
#include "ccShader_Label_vert.h"
const GLchar * ccLabelDistanceFieldOutline_frag =
const GLchar * ccLabelOutline_frag =
#include "ccShader_Label_frag_outline.h"
const GLchar * ccLabelDistanceFieldOutline_vert =
#include "ccShader_Label_vert.h"
const GLchar * ccLabelDistanceFieldShadow_frag =
#include "ccShader_Label_frag_shadow.h"
const GLchar * ccLabelDistanceFieldShadow_vert =
const GLchar * ccLabelOutline_vert =
#include "ccShader_Label_vert.h"
NS_CC_END

Просмотреть файл

@ -68,11 +68,8 @@ extern CC_DLL const GLchar * ccLabelDistanceFieldNormal_vert;
extern CC_DLL const GLchar * ccLabelDistanceFieldGlow_frag;
extern CC_DLL const GLchar * ccLabelDistanceFieldGlow_vert;
extern CC_DLL const GLchar * ccLabelDistanceFieldOutline_frag;
extern CC_DLL const GLchar * ccLabelDistanceFieldOutline_vert;
extern CC_DLL const GLchar * ccLabelDistanceFieldShadow_frag;
extern CC_DLL const GLchar * ccLabelDistanceFieldShadow_vert;
extern CC_DLL const GLchar * ccLabelOutline_frag;
extern CC_DLL const GLchar * ccLabelOutline_vert;
extern CC_DLL const GLchar * ccExSwitchMask_frag;

Просмотреть файл

@ -182,19 +182,42 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
<ClCompile Include="..\base\CCValue.cpp" />
<ClCompile Include="..\base\etc1.cpp" />
<ClCompile Include="..\base\s3tc.cpp" />
<ClCompile Include="..\math\kazmath\src\aabb.c" />
<ClCompile Include="..\math\kazmath\src\GL\mat4stack.c" />
<ClCompile Include="..\math\kazmath\src\GL\matrix.c" />
<ClCompile Include="..\math\kazmath\src\mat3.c" />
<ClCompile Include="..\math\kazmath\src\mat4.c" />
<ClCompile Include="..\math\kazmath\src\neon_matrix_impl.c" />
<ClCompile Include="..\math\kazmath\src\plane.c" />
<ClCompile Include="..\math\kazmath\src\quaternion.c" />
<ClCompile Include="..\math\kazmath\src\ray2.c" />
<ClCompile Include="..\math\kazmath\src\utility.c" />
<ClCompile Include="..\math\kazmath\src\vec2.c" />
<ClCompile Include="..\math\kazmath\src\vec3.c" />
<ClCompile Include="..\math\kazmath\src\vec4.c" />
<ClCompile Include="..\math\kazmath\kazmath\aabb.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\GL\mat4stack.c" />
<ClCompile Include="..\math\kazmath\kazmath\GL\matrix.c" />
<ClCompile Include="..\math\kazmath\kazmath\mat3.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\mat4.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\neon_matrix_impl.c" />
<ClCompile Include="..\math\kazmath\kazmath\plane.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\quaternion.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\ray2.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\ray3.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\utility.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\vec2.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\vec3.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\vec4.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\physics\CCPhysicsBody.cpp" />
<ClCompile Include="..\physics\CCPhysicsContact.cpp" />
<ClCompile Include="..\physics\CCPhysicsJoint.cpp" />
@ -358,20 +381,21 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
<ClInclude Include="..\base\CCVector.h" />
<ClInclude Include="..\base\etc1.h" />
<ClInclude Include="..\base\s3tc.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\aabb.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\GL\mat4stack.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\GL\matrix.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\kazmath.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\mat3.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\mat4.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\neon_matrix_impl.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\plane.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\quaternion.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\ray2.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\utility.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\vec2.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\vec3.h" />
<ClInclude Include="..\math\kazmath\include\kazmath\vec4.h" />
<ClInclude Include="..\math\kazmath\kazmath\aabb.h" />
<ClInclude Include="..\math\kazmath\kazmath\GL\mat4stack.h" />
<ClInclude Include="..\math\kazmath\kazmath\GL\matrix.h" />
<ClInclude Include="..\math\kazmath\kazmath\kazmath.h" />
<ClInclude Include="..\math\kazmath\kazmath\mat3.h" />
<ClInclude Include="..\math\kazmath\kazmath\mat4.h" />
<ClInclude Include="..\math\kazmath\kazmath\neon_matrix_impl.h" />
<ClInclude Include="..\math\kazmath\kazmath\plane.h" />
<ClInclude Include="..\math\kazmath\kazmath\quaternion.h" />
<ClInclude Include="..\math\kazmath\kazmath\ray2.h" />
<ClInclude Include="..\math\kazmath\kazmath\ray3.h" />
<ClInclude Include="..\math\kazmath\kazmath\utility.h" />
<ClInclude Include="..\math\kazmath\kazmath\vec2.h" />
<ClInclude Include="..\math\kazmath\kazmath\vec3.h" />
<ClInclude Include="..\math\kazmath\kazmath\vec4.h" />
<ClInclude Include="..\physics\CCPhysicsBody.h" />
<ClInclude Include="..\physics\CCPhysicsContact.h" />
<ClInclude Include="..\physics\CCPhysicsJoint.h" />
@ -537,4 +561,4 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

Просмотреть файл

@ -180,45 +180,6 @@
<ClCompile Include="CCTouch.cpp">
<Filter>event_dispatcher</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\GL\mat4stack.c">
<Filter>kazmath\src\GL</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\GL\matrix.c">
<Filter>kazmath\src\GL</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\aabb.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\mat3.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\mat4.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\neon_matrix_impl.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\plane.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\quaternion.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\ray2.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\utility.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\vec2.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\vec3.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\src\vec4.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="CCLayer.cpp">
<Filter>layers_scenes_transitions_nodes</Filter>
</ClCompile>
@ -598,6 +559,49 @@
<ClCompile Include="platform\CCImage.cpp">
<Filter>platform</Filter>
</ClCompile>
<ClCompile Include="CCTweenFunction.cpp" />
<ClCompile Include="..\math\kazmath\kazmath\GL\mat4stack.c">
<Filter>kazmath\src\GL</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\GL\matrix.c">
<Filter>kazmath\src\GL</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\aabb.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\mat3.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\mat4.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\neon_matrix_impl.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\plane.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\quaternion.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\ray2.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\ray3.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\utility.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\vec2.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\vec3.c">
<Filter>kazmath\src</Filter>
</ClCompile>
<ClCompile Include="..\math\kazmath\kazmath\vec4.c">
<Filter>kazmath\src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\physics\CCPhysicsBody.h">
@ -684,48 +688,6 @@
<ClInclude Include="cocos2d.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\aabb.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\kazmath.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\mat3.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\mat4.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\neon_matrix_impl.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\plane.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\quaternion.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\ray2.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\utility.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\vec2.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\vec3.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\vec4.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\GL\mat4stack.h">
<Filter>kazmath\include\kazmath\GL</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\include\kazmath\GL\matrix.h">
<Filter>kazmath\include\kazmath\GL</Filter>
</ClInclude>
<ClInclude Include="CCLayer.h">
<Filter>layers_scenes_transitions_nodes</Filter>
</ClInclude>
@ -1198,5 +1160,51 @@
<ClInclude Include="platform\desktop\CCGLView.h">
<Filter>platform\desktop</Filter>
</ClInclude>
<ClInclude Include="CCTweenFunction.h" />
<ClInclude Include="..\math\kazmath\kazmath\GL\mat4stack.h">
<Filter>kazmath\include\kazmath\GL</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\GL\matrix.h">
<Filter>kazmath\include\kazmath\GL</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\aabb.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\kazmath.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\mat3.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\mat4.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\neon_matrix_impl.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\plane.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\quaternion.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\ray2.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\ray3.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\utility.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\vec2.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\vec3.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
<ClInclude Include="..\math\kazmath\kazmath\vec4.h">
<Filter>kazmath\include\kazmath</Filter>
</ClInclude>
</ItemGroup>
</Project>
</Project>

Просмотреть файл

@ -7,7 +7,7 @@
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(EngineRoot)cocos\2d;$(EngineRoot)cocos\2d\renderer;$(EngineRoot)cocos\gui;$(EngineRoot)cocos\base;$(EngineRoot)cocos\physics;$(EngineRoot)cocos\math\kazmath\include;$(EngineRoot)cocos\2d\platform\win32;$(EngineRoot)cocos\2d\platform\desktop;$(EngineRoot)external\glfw3\include\win32;$(EngineRoot)external\win32-specific\gles\include\OGLES</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(EngineRoot)cocos\2d;$(EngineRoot)cocos\2d\renderer;$(EngineRoot)cocos\gui;$(EngineRoot)cocos\base;$(EngineRoot)cocos\physics;$(EngineRoot)cocos\math\kazmath;$(EngineRoot)cocos\2d\platform\win32;$(EngineRoot)cocos\2d\platform\desktop;$(EngineRoot)external\glfw3\include\win32;$(EngineRoot)external\win32-specific\gles\include\OGLES</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_VARIADIC_MAX=10;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>

Просмотреть файл

@ -24,7 +24,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
$(LOCAL_PATH)/../.. \
$(LOCAL_PATH)/../../../base \
$(LOCAL_PATH)/../../../math/kazmath/include \
$(LOCAL_PATH)/../../../math/kazmath \
$(LOCAL_PATH)/../../../physics
LOCAL_LDLIBS := -lGLESv1_CM \

Просмотреть файл

@ -191,7 +191,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
normal = cDir;
kmVec3Scale(&point, &cDir, nearPlane);
kmVec3Add(&point, &point, &cc);
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &point, &normal);
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &point, &normal);
}
//far
@ -201,7 +201,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
kmVec3Scale(&normal, &cDir, -1);
kmVec3Scale(&point, &cDir, farPlane);
kmVec3Add(&point, &point, &cc);
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &point, &normal);
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &point, &normal);
}
//left
@ -211,7 +211,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
normal = cRight;
kmVec3Scale(&point, &cRight, -width * 0.5);
kmVec3Add(&point, &point, &cc);
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
}
//right
@ -221,7 +221,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
kmVec3Scale(&normal, &cRight, -1);
kmVec3Scale(&point, &cRight, width * 0.5);
kmVec3Add(&point, &point, &cc);
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
}
//bottom
@ -231,7 +231,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
normal = cUp;
kmVec3Scale(&point, &cUp, -height * 0.5);
kmVec3Add(&point, &point, &cc);
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
}
//top
@ -241,7 +241,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
kmVec3Scale(&normal, &cUp, -1);
kmVec3Scale(&point, &cUp, height * 0.5);
kmVec3Add(&point, &point, &cc);
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
}
}
@ -267,14 +267,14 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
//near
{
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &nearCenter, &cDir);
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &nearCenter, &cDir);
}
//far
{
kmVec3 normal;
kmVec3Scale(&normal, &cDir, -1);
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &farCenter, &normal);
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &farCenter, &normal);
}
//left
@ -288,7 +288,7 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
kmVec3Cross(&normal, &normal, &cUp);
kmVec3Normalize(&normal, &normal);
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
}
//right
@ -302,7 +302,7 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
kmVec3Cross(&normal, &cUp, &normal);
kmVec3Normalize(&normal, &normal);
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
}
//bottom
@ -316,7 +316,7 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
kmVec3Cross(&normal, &cRight, &normal);
kmVec3Normalize(&normal, &normal);
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
}
//top
@ -330,7 +330,7 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
kmVec3Cross(&normal, &normal, &cRight);
kmVec3Normalize(&normal, &normal);
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
}
}

Просмотреть файл

@ -13,7 +13,7 @@ LOCAL_SRC_FILES := cddSimpleAudioEngine.cpp \
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include \
$(LOCAL_PATH)/../../math/kazmath/include \
$(LOCAL_PATH)/../../math/kazmath \
$(LOCAL_PATH)/../../2d \
$(LOCAL_PATH)/../../2d/platform/android \
$(LOCAL_PATH)/../../base \

Просмотреть файл

@ -381,7 +381,7 @@ void Armature::draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool t
{
if (_parentBone == nullptr && _batchNode == nullptr)
{
CC_NODE_DRAW_SETUP();
// CC_NODE_DRAW_SETUP();
}
@ -418,7 +418,7 @@ void Armature::draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool t
default:
{
node->visit(renderer, transform, transformUpdated);
CC_NODE_DRAW_SETUP();
// CC_NODE_DRAW_SETUP();
}
break;
}
@ -426,7 +426,7 @@ void Armature::draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool t
else if(Node *node = dynamic_cast<Node *>(object))
{
node->visit(renderer, transform, transformUpdated);
CC_NODE_DRAW_SETUP();
// CC_NODE_DRAW_SETUP();
}
}
}

Просмотреть файл

@ -136,7 +136,7 @@ void BatchNode::draw(Renderer *renderer, const kmMat4 &transform, bool transform
return;
}
CC_NODE_DRAW_SETUP();
// CC_NODE_DRAW_SETUP();
bool pushed = false;
for(auto object : _children)

Просмотреть файл

@ -355,8 +355,8 @@ void WidgetPropertiesReader0250::setColorPropsForWidgetFromJsonDictionary(Widget
widget->setAnchorPoint(Point(apxf, apyf));
bool flipX = DICTOOL->getBooleanValue_json(options, "flipX");
bool flipY = DICTOOL->getBooleanValue_json(options, "flipY");
widget->setFlipX(flipX);
widget->setFlipY(flipY);
widget->setFlippedX(flipX);
widget->setFlippedY(flipY);
}
void WidgetPropertiesReader0250::setPropsForButtonFromJsonDictionary(Widget*widget,const rapidjson::Value& options)
@ -1129,8 +1129,8 @@ void WidgetPropertiesReader0300::setColorPropsForWidgetFromJsonDictionary(Widget
widget->setAnchorPoint(Point(apxf, apyf));
bool flipX = DICTOOL->getBooleanValue_json(options, "flipX");
bool flipY = DICTOOL->getBooleanValue_json(options, "flipY");
widget->setFlipX(flipX);
widget->setFlipY(flipY);
widget->setFlippedX(flipX);
widget->setFlippedY(flipY);
}
void WidgetPropertiesReader0300::setPropsForButtonFromJsonDictionary(Widget*widget,const rapidjson::Value& options)

Просмотреть файл

@ -129,13 +129,14 @@ void Skeleton::draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool t
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(Skeleton::onDraw, this);
_customCommand.func = CC_CALLBACK_0(Skeleton::onDraw, this, transform, transformUpdated);
renderer->addCommand(&_customCommand);
}
void Skeleton::onDraw ()
void Skeleton::onDraw(const kmMat4 &transform, bool transformUpdated)
{
CC_NODE_DRAW_SETUP();
getShaderProgram()->use();
getShaderProgram()->setUniformsForBuiltins(transform);
GL::blendFunc(blendFunc.src, blendFunc.dst);
Color3B color = getColor();
@ -193,7 +194,7 @@ void Skeleton::onDraw ()
if(debugBones || debugSlots) {
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
kmGLLoadMatrix(&transform);
if (debugSlots) {
// Slots.

Просмотреть файл

@ -68,7 +68,7 @@ public:
virtual void update (float deltaTime) override;
virtual void draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
void onDraw();
void onDraw(const kmMat4 &transform, bool transformUpdated);
void onEnter() override;
void onExit() override;
virtual cocos2d::Rect getBoundingBox () const override;

Просмотреть файл

@ -33,7 +33,7 @@ static const int NORMAL_RENDERER_Z = (-2);
static const int PRESSED_RENDERER_Z = (-2);
static const int DISABLED_RENDERER_Z = (-2);
static const int TITLE_RENDERER_Z = (-1);
Button::Button():
_buttonNormalRenderer(nullptr),
_buttonClickedRenderer(nullptr),
@ -63,7 +63,7 @@ _normalTextureLoaded(false),
_pressedTextureLoaded(false),
_disabledTextureLoaded(false)
{
}
Button::~Button()
@ -97,7 +97,7 @@ void Button::initRenderer()
_buttonClickedRenderer = Sprite::create();
_buttonDisableRenderer = Sprite::create();
_titleRenderer = LabelTTF::create();
Node::addChild(_buttonNormalRenderer, NORMAL_RENDERER_Z, -1);
Node::addChild(_buttonClickedRenderer, PRESSED_RENDERER_Z, -1);
Node::addChild(_buttonDisableRenderer, DISABLED_RENDERER_Z, -1);
@ -152,7 +152,7 @@ void Button::setScale9Enabled(bool able)
setCapInsetsDisabledRenderer(_capInsetsDisabled);
setBright(_bright);
}
bool Button::isScale9Enabled()
{
return _scale9Enabled;
@ -331,7 +331,7 @@ void Button::setCapInsetsNormalRenderer(const Rect &capInsets)
}
static_cast<extension::Scale9Sprite*>(_buttonNormalRenderer)->setCapInsets(capInsets);
}
const Rect& Button::getCapInsetsNormalRenderer()
{
return _capInsetsNormal;
@ -346,7 +346,7 @@ void Button::setCapInsetsPressedRenderer(const Rect &capInsets)
}
static_cast<extension::Scale9Sprite*>(_buttonClickedRenderer)->setCapInsets(capInsets);
}
const Rect& Button::getCapInsetsPressedRenderer()
{
return _capInsetsPressed;
@ -361,7 +361,7 @@ void Button::setCapInsetsDisabledRenderer(const Rect &capInsets)
}
static_cast<extension::Scale9Sprite*>(_buttonDisableRenderer)->setCapInsets(capInsets);
}
const Rect& Button::getCapInsetsDisabledRenderer()
{
return _capInsetsDisabled;
@ -425,31 +425,31 @@ void Button::onPressStateChangedToDisabled()
_buttonClickedRenderer->setScale(_pressedTextureScaleXInSize, _pressedTextureScaleYInSize);
}
void Button::setFlipX(bool flipX)
void Button::setFlippedX(bool flippedX)
{
_titleRenderer->setFlippedX(flipX);
_titleRenderer->setFlippedX(flippedX);
if (_scale9Enabled)
{
return;
}
static_cast<Sprite*>(_buttonNormalRenderer)->setFlippedX(flipX);
static_cast<Sprite*>(_buttonClickedRenderer)->setFlippedX(flipX);
static_cast<Sprite*>(_buttonDisableRenderer)->setFlippedX(flipX);
static_cast<Sprite*>(_buttonNormalRenderer)->setFlippedX(flippedX);
static_cast<Sprite*>(_buttonClickedRenderer)->setFlippedX(flippedX);
static_cast<Sprite*>(_buttonDisableRenderer)->setFlippedX(flippedX);
}
void Button::setFlipY(bool flipY)
void Button::setFlippedY(bool flippedY)
{
_titleRenderer->setFlippedY(flipY);
_titleRenderer->setFlippedY(flippedY);
if (_scale9Enabled)
{
return;
}
static_cast<Sprite*>(_buttonNormalRenderer)->setFlippedY(flipY);
static_cast<Sprite*>(_buttonClickedRenderer)->setFlippedY(flipY);
static_cast<Sprite*>(_buttonDisableRenderer)->setFlippedY(flipY);
static_cast<Sprite*>(_buttonNormalRenderer)->setFlippedY(flippedY);
static_cast<Sprite*>(_buttonClickedRenderer)->setFlippedY(flippedY);
static_cast<Sprite*>(_buttonDisableRenderer)->setFlippedY(flippedY);
}
bool Button::isFlipX()
bool Button::isFlippedX()
{
if (_scale9Enabled)
{
@ -458,7 +458,7 @@ bool Button::isFlipX()
return static_cast<Sprite*>(_buttonNormalRenderer)->isFlippedX();
}
bool Button::isFlipY()
bool Button::isFlippedY()
{
if (_scale9Enabled)
{
@ -677,7 +677,7 @@ void Button::copySpecialProperties(Widget *widget)
{
Button* button = dynamic_cast<Button*>(widget);
if (button)
{
{
_prevIgnoreSize = button->_prevIgnoreSize;
setScale9Enabled(button->_scale9Enabled);
loadTextureNormal(button->_normalFileName.c_str(), button->_normalTexType);

Просмотреть файл

@ -42,17 +42,17 @@ public:
* Default constructor
*/
Button();
/**
* Default destructor
*/
virtual ~Button();
/**
* Allocates and initializes.
*/
static Button* create();
/**
* Load textures for button.
*
@ -65,7 +65,7 @@ public:
* @param texType @see UI_TEX_TYPE_LOCAL
*/
void loadTextures(const char* normal,const char* selected,const char* disabled,TextureResType texType = UI_TEX_TYPE_LOCAL);
/**
* Load normal state texture for button.
*
@ -74,7 +74,7 @@ public:
* @param texType @see UI_TEX_TYPE_LOCAL
*/
void loadTextureNormal(const char* normal, TextureResType texType = UI_TEX_TYPE_LOCAL);
/**
* Load selected state texture for button.
*
@ -83,7 +83,7 @@ public:
* @param texType @see UI_TEX_TYPE_LOCAL
*/
void loadTexturePressed(const char* selected, TextureResType texType = UI_TEX_TYPE_LOCAL);
/**
* Load dark state texture for button.
*
@ -92,7 +92,7 @@ public:
* @param texType @see UI_TEX_TYPE_LOCAL
*/
void loadTextureDisabled(const char* disabled, TextureResType texType = UI_TEX_TYPE_LOCAL);
/**
* Sets capinsets for button, if button is using scale9 renderer.
*
@ -106,67 +106,76 @@ public:
* @param capInsets capinsets for button
*/
void setCapInsetsNormalRenderer(const Rect &capInsets);
const Rect& getCapInsetsNormalRenderer();
/**
* Sets capinsets for button, if button is using scale9 renderer.
*
* @param capInsets capinsets for button
*/
void setCapInsetsPressedRenderer(const Rect &capInsets);
const Rect& getCapInsetsPressedRenderer();
/**
* Sets capinsets for button, if button is using scale9 renderer.
*
* @param capInsets capinsets for button
*/
void setCapInsetsDisabledRenderer(const Rect &capInsets);
const Rect& getCapInsetsDisabledRenderer();
//override "setAnchorPoint" of widget.
virtual void setAnchorPoint(const Point &pt) override;
/**
* Sets if button is using scale9 renderer.
*
* @param true that using scale9 renderer, false otherwise.
*/
virtual void setScale9Enabled(bool able);
bool isScale9Enabled();
//override "setFlipX" of widget.
virtual void setFlipX(bool flipX) override;
//override "setFlipY" of widget.
virtual void setFlipY(bool flipY) override;
//override "isFlipX" of widget.
virtual bool isFlipX() override;
//override "isFlipY" of widget.
virtual bool isFlipY() override;
//override "setFlippedX" of widget.
virtual void setFlippedX(bool flippedX) override;
//override "setFlippedY" of widget.
virtual void setFlippedY(bool flippedY) override;
//override "isFlippedX" of widget.
virtual bool isFlippedX() override;
//override "isFlippedY" of widget.
virtual bool isFlippedY() override;
/** @deprecated Use isFlippedX() instead */
CC_DEPRECATED_ATTRIBUTE bool isFlipX() { return isFlippedX(); };
/** @deprecated Use setFlippedX() instead */
CC_DEPRECATED_ATTRIBUTE void setFlipX(bool flipX) { setFlippedX(flipX); };
/** @deprecated Use isFlippedY() instead */
CC_DEPRECATED_ATTRIBUTE bool isFlipY() { return isFlippedY(); };
/** @deprecated Use setFlippedY() instead */
CC_DEPRECATED_ATTRIBUTE void setFlipY(bool flipY) { setFlippedY(flipY); };
/**
* Changes if button can be clicked zoom effect.
*
* @param true that can be clicked zoom effect, false otherwise.
*/
void setPressedActionEnabled(bool enabled);
//override "ignoreContentAdaptWithSize" method of widget.
virtual void ignoreContentAdaptWithSize(bool ignore) override;
//override "getContentSize" method of widget.
virtual const Size& getContentSize() const override;
//override "getVirtualRenderer" method of widget.
virtual Node* getVirtualRenderer() override;
/**
* Sets color to widget
*
@ -175,12 +184,12 @@ public:
* @param color
*/
virtual void setColor(const Color3B &color) override;
/**
* Returns the "class name" of widget.
*/
virtual std::string getDescription() const override;
void setTitleText(const std::string& text);
const std::string& getTitleText() const;
void setTitleColor(const Color3B& color);
@ -197,7 +206,7 @@ protected:
virtual void onPressStateChangedToPressed() override;
virtual void onPressStateChangedToDisabled() override;
virtual void onSizeChanged() override;
void normalTextureScaleChangedWithSize();
void pressedTextureScaleChangedWithSize();
void disabledTextureScaleChangedWithSize();

Просмотреть файл

@ -322,30 +322,30 @@ void CheckBox::addEventListenerCheckBox(Ref *target, SEL_SelectedStateEvent sele
_checkBoxEventSelector = selector;
}
void CheckBox::setFlipX(bool flipX)
void CheckBox::setFlippedX(bool flippedX)
{
_backGroundBoxRenderer->setFlippedX(flipX);
_backGroundSelectedBoxRenderer->setFlippedX(flipX);
_frontCrossRenderer->setFlippedX(flipX);
_backGroundBoxDisabledRenderer->setFlippedX(flipX);
_frontCrossDisabledRenderer->setFlippedX(flipX);
_backGroundBoxRenderer->setFlippedX(flippedX);
_backGroundSelectedBoxRenderer->setFlippedX(flippedX);
_frontCrossRenderer->setFlippedX(flippedX);
_backGroundBoxDisabledRenderer->setFlippedX(flippedX);
_frontCrossDisabledRenderer->setFlippedX(flippedX);
}
void CheckBox::setFlipY(bool flipY)
void CheckBox::setFlippedY(bool flippedY)
{
_backGroundBoxRenderer->setFlippedY(flipY);
_backGroundSelectedBoxRenderer->setFlippedY(flipY);
_frontCrossRenderer->setFlippedY(flipY);
_backGroundBoxDisabledRenderer->setFlippedY(flipY);
_frontCrossDisabledRenderer->setFlippedY(flipY);
_backGroundBoxRenderer->setFlippedY(flippedY);
_backGroundSelectedBoxRenderer->setFlippedY(flippedY);
_frontCrossRenderer->setFlippedY(flippedY);
_backGroundBoxDisabledRenderer->setFlippedY(flippedY);
_frontCrossDisabledRenderer->setFlippedY(flippedY);
}
bool CheckBox::isFlipX()
bool CheckBox::isFlippedX()
{
return _backGroundBoxRenderer->isFlippedX();
}
bool CheckBox::isFlipY()
bool CheckBox::isFlippedY()
{
return _backGroundBoxRenderer->isFlippedY();
}

Просмотреть файл

@ -51,17 +51,17 @@ public:
* Default constructor
*/
CheckBox();
/**
* Default destructor
*/
virtual ~CheckBox();
/**
* Allocates and initializes.
*/
static CheckBox* create();
/**
* Load textures for checkbox.
*
@ -76,7 +76,7 @@ public:
* @param texType @see UI_TEX_TYPE_LOCAL
*/
void loadTextures(const char* backGround,const char* backGroundSelected,const char* cross,const char* backGroundDisabled,const char* frontCrossDisabled,TextureResType texType = UI_TEX_TYPE_LOCAL);
/**
* Load backGround texture for checkbox.
*
@ -85,7 +85,7 @@ public:
* @param texType @see UI_TEX_TYPE_LOCAL
*/
void loadTextureBackGround(const char* backGround,TextureResType type = UI_TEX_TYPE_LOCAL);
/**
* Load backGroundSelected texture for checkbox.
*
@ -94,7 +94,7 @@ public:
* @param texType @see UI_TEX_TYPE_LOCAL
*/
void loadTextureBackGroundSelected(const char* backGroundSelected,TextureResType texType = UI_TEX_TYPE_LOCAL);
/**
* Load cross texture for checkbox.
*
@ -103,7 +103,7 @@ public:
* @param texType @see UI_TEX_TYPE_LOCAL
*/
void loadTextureFrontCross(const char* cross,TextureResType texType = UI_TEX_TYPE_LOCAL);
/**
* Load backGroundDisabled texture for checkbox.
*
@ -112,7 +112,7 @@ public:
* @param texType @see UI_TEX_TYPE_LOCAL
*/
void loadTextureBackGroundDisabled(const char* backGroundDisabled,TextureResType texType = UI_TEX_TYPE_LOCAL);
/**
* Load frontCrossDisabled texture for checkbox.
*
@ -121,48 +121,57 @@ public:
* @param texType @see UI_TEX_TYPE_LOCAL
*/
void loadTextureFrontCrossDisabled(const char* frontCrossDisabled,TextureResType texType = UI_TEX_TYPE_LOCAL);
/**
* Sets selcted state for checkbox.
*
* @param selected true that checkbox is selected, false otherwise.
*/
void setSelectedState(bool selected);
/**
* Gets selcted state of checkbox.
*
* @return selected true that checkbox is selected, false otherwise.
*/
bool getSelectedState();
//override "setAnchorPoint" method of widget.
virtual void setAnchorPoint(const Point &pt) override;
//add a call back function would called when checkbox is selected or unselected.
void addEventListenerCheckBox(Ref* target,SEL_SelectedStateEvent selector);
//override "setFlipX" method of widget.
virtual void setFlipX(bool flipX) override;
//override "setFlipY" method of widget.
virtual void setFlipY(bool flipY) override;
//override "isFlipX" method of widget.
virtual bool isFlipX() override;
//override "isFlipY" method of widget.
virtual bool isFlipY() override;
//override "setFlippedX" method of widget.
virtual void setFlippedX(bool flippedX) override;
//override "setFlippedY" method of widget.
virtual void setFlippedY(bool flippedY) override;
//override "isFlippedX" method of widget.
virtual bool isFlippedX() override;
//override "isFlippedY" method of widget.
virtual bool isFlippedY() override;
/** @deprecated Use isFlippedX() instead */
CC_DEPRECATED_ATTRIBUTE bool isFlipX() { return isFlippedX(); };
/** @deprecated Use setFlippedX() instead */
CC_DEPRECATED_ATTRIBUTE void setFlipX(bool flipX) { setFlippedX(flipX); };
/** @deprecated Use isFlippedY() instead */
CC_DEPRECATED_ATTRIBUTE bool isFlipY() { return isFlippedY(); };
/** @deprecated Use setFlippedY() instead */
CC_DEPRECATED_ATTRIBUTE void setFlipY(bool flipY) { setFlippedY(flipY); };
//override "onTouchEnded" method of widget.
virtual void onTouchEnded(Touch *touch, Event *unusedEvent);
//override "getContentSize" method of widget.
virtual const Size& getContentSize() const override;
//override "getVirtualRenderer" method of widget.
virtual Node* getVirtualRenderer() override;
/**
* Returns the "class name" of widget.
*/
@ -194,13 +203,13 @@ protected:
Ref* _checkBoxEventListener;
SEL_SelectedStateEvent _checkBoxEventSelector;
TextureResType _backGroundTexType;
TextureResType _backGroundSelectedTexType;
TextureResType _frontCrossTexType;
TextureResType _backGroundDisabledTexType;
TextureResType _frontCrossDisabledTexType;
std::string _backGroundFileName;
std::string _backGroundSelectedFileName;
std::string _frontCrossFileName;

Просмотреть файл

@ -127,29 +127,29 @@ void ImageView::setTextureRect(const Rect &rect)
}
}
void ImageView::setFlipX(bool flipX)
void ImageView::setFlippedX(bool flippedX)
{
if (_scale9Enabled)
{
}
else
{
STATIC_CAST_CCSPRITE->setFlippedX(flipX);
STATIC_CAST_CCSPRITE->setFlippedX(flippedX);
}
}
void ImageView::setFlipY(bool flipY)
void ImageView::setFlippedY(bool flippedY)
{
if (_scale9Enabled)
{
}
else
{
STATIC_CAST_CCSPRITE->setFlippedY(flipY);
STATIC_CAST_CCSPRITE->setFlippedY(flippedY);
}
}
bool ImageView::isFlipX()
bool ImageView::isFlippedX()
{
if (_scale9Enabled)
{
@ -161,7 +161,7 @@ bool ImageView::isFlipX()
}
}
bool ImageView::isFlipY()
bool ImageView::isFlippedY()
{
if (_scale9Enabled)
{

Просмотреть файл

@ -42,17 +42,17 @@ public:
* Default constructor
*/
ImageView();
/**
* Default destructor
*/
virtual ~ImageView();
/**
* Allocates and initializes.
*/
static ImageView* create();
/**
* Load texture for imageview.
*
@ -61,54 +61,63 @@ public:
* @param texType @see UI_TEX_TYPE_LOCAL
*/
void loadTexture(const char* fileName,TextureResType texType = UI_TEX_TYPE_LOCAL);
/**
* Updates the texture rect of the ImageView in points.
* It will call setTextureRect:rotated:untrimmedSize with rotated = NO, and utrimmedSize = rect.size.
*/
void setTextureRect(const Rect& rect);
/**
* Sets if imageview is using scale9 renderer.
*
* @param true that using scale9 renderer, false otherwise.
*/
void setScale9Enabled(bool able);
bool isScale9Enabled();
/**
* Sets capinsets for imageview, if imageview is using scale9 renderer.
*
* @param capInsets capinsets for imageview
*/
void setCapInsets(const Rect &capInsets);
const Rect& getCapInsets();
//override "setFlipX" method of widget.
virtual void setFlipX(bool flipX) override;
//override "setFlipY" method of widget.
virtual void setFlipY(bool flipY) override;
//override "isFlipX" method of widget.
virtual bool isFlipX() override;
//override "isFlipY" method of widget.
virtual bool isFlipY() override;
//override "setFlippedX" method of widget.
virtual void setFlippedX(bool flippedX) override;
//override "setFlippedY" method of widget.
virtual void setFlippedY(bool flippedY) override;
//override "isFlippedX" method of widget.
virtual bool isFlippedX() override;
//override "isFlippedY" method of widget.
virtual bool isFlippedY() override;
/** @deprecated Use isFlippedX() instead */
CC_DEPRECATED_ATTRIBUTE bool isFlipX() { return isFlippedX(); };
/** @deprecated Use setFlippedX() instead */
CC_DEPRECATED_ATTRIBUTE void setFlipX(bool flipX) { setFlippedX(flipX); };
/** @deprecated Use isFlippedY() instead */
CC_DEPRECATED_ATTRIBUTE bool isFlipY() { return isFlippedY(); };
/** @deprecated Use setFlippedY() instead */
CC_DEPRECATED_ATTRIBUTE void setFlipY(bool flipY) { setFlippedY(flipY); };
//override "setAnchorPoint" method of widget.
virtual void setAnchorPoint(const Point &pt) override;
//override "ignoreContentAdaptWithSize" method of widget.
virtual void ignoreContentAdaptWithSize(bool ignore) override;
/**
* Returns the "class name" of widget.
*/
virtual std::string getDescription() const override;
virtual const Size& getContentSize() const override;
virtual Node* getVirtualRenderer() override;
protected:

Просмотреть файл

@ -197,22 +197,22 @@ void Text::onPressStateChangedToDisabled()
}
void Text::setFlipX(bool flipX)
void Text::setFlippedX(bool flippedX)
{
_labelRenderer->setFlippedX(flipX);
_labelRenderer->setFlippedX(flippedX);
}
void Text::setFlipY(bool flipY)
void Text::setFlippedY(bool flippedY)
{
_labelRenderer->setFlippedY(flipY);
_labelRenderer->setFlippedY(flippedY);
}
bool Text::isFlipX()
bool Text::isFlippedX()
{
return _labelRenderer->isFlippedX();
}
bool Text::isFlipY()
bool Text::isFlippedY()
{
return _labelRenderer->isFlippedY();
}

Просмотреть файл

@ -42,70 +42,70 @@ public:
* Default constructor
*/
Text();
/**
* Default destructor
*/
virtual ~Text();
/**
* Allocates and initializes.
*/
static Text* create();
/**
* Changes the string value of label.
*
* @param text string value.
*/
void setText(const std::string& text);
/**
* Gets the string value of label.
*
* @return text string value.
*/
const std::string& getStringValue();
/**
* Gets the string length of label.
*
* @return string length.
*/
ssize_t getStringLength();
/**
* Sets the font size of label.
*
* @param font size.
*/
void setFontSize(int size);
int getFontSize();
/**
* Sets the font name of label.
*
* @param font name.
*/
void setFontName(const std::string& name);
const std::string& getFontName();
/**
* Sets the touch scale enabled of label.
*
* @param touch scale enabled of label.
*/
void setTouchScaleChangeEnabled(bool enabled);
/**
* Gets the touch scale enabled of label.
*
* @return touch scale enabled of label.
*/
bool isTouchScaleChangeEnabled();
/**
* Changes both X and Y scale factor of the widget.
*
@ -114,7 +114,7 @@ public:
* @param scale The scale factor for both X and Y axis.
*/
virtual void setScale(float fScale) override;
/**
* Changes the scale factor on X axis of this widget
*
@ -123,7 +123,7 @@ public:
* @param fScaleX The scale factor on X axis.
*/
virtual void setScaleX(float fScaleX) override;
/**
* Changes the scale factor on Y axis of this widget
*
@ -132,46 +132,55 @@ public:
* @param fScaleY The scale factor on Y axis.
*/
virtual void setScaleY(float fScaleY) override;
//override "setFlipX" method of widget.
virtual void setFlipX(bool flipX) override;
//override "setFlipY" method of widget.
virtual void setFlipY(bool flipY) override;
//override "isFlipX" method of widget.
virtual bool isFlipX() override;
//override "isFlipY" method of widget.
virtual bool isFlipY() override;
//override "setFlippedX" method of widget.
virtual void setFlippedX(bool flippedX) override;
//override "setFlippedY" method of widget.
virtual void setFlippedY(bool flippedY) override;
//override "isFlippedX" method of widget.
virtual bool isFlippedX() override;
//override "isFlippedY" method of widget.
virtual bool isFlippedY() override;
/** @deprecated Use isFlippedX() instead */
CC_DEPRECATED_ATTRIBUTE bool isFlipX() { return isFlippedX(); };
/** @deprecated Use setFlippedX() instead */
CC_DEPRECATED_ATTRIBUTE void setFlipX(bool flipX) { setFlippedX(flipX); };
/** @deprecated Use isFlippedY() instead */
CC_DEPRECATED_ATTRIBUTE bool isFlipY() { return isFlippedY(); };
/** @deprecated Use setFlippedY() instead */
CC_DEPRECATED_ATTRIBUTE void setFlipY(bool flipY) { setFlippedY(flipY); };
//override "setAnchorPoint" method of widget.
virtual void setAnchorPoint(const Point &pt) override;
//override "getContentSize" method of widget.
virtual const Size& getContentSize() const override;
//override "getVirtualRenderer" method of widget.
virtual Node* getVirtualRenderer() override;
/**
* Returns the "class name" of widget.
*/
virtual std::string getDescription() const override;
void setTextAreaSize(const Size &size);
const Size& getTextAreaSize();
void setTextHorizontalAlignment(TextHAlignment alignment);
TextHAlignment getTextHorizontalAlignment();
void setTextVerticalAlignment(TextVAlignment alignment);
TextVAlignment getTextVerticalAlignment();
protected:
virtual bool init() override;
virtual void initRenderer() override;

Просмотреть файл

@ -29,7 +29,7 @@ THE SOFTWARE.
NS_CC_BEGIN
namespace ui {
Widget::Widget():
_enabled(true),
_bright(true),
@ -57,7 +57,7 @@ _reorderWidgetChildDirty(true),
_hitted(false),
_touchListener(nullptr)
{
}
Widget::~Widget()
@ -107,13 +107,13 @@ void Widget::onExit()
unscheduleUpdate();
Node::onExit();
}
void Widget::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
if (_enabled)
{
Node::visit(renderer, parentTransform, parentTransformUpdated);
}
}
}
void Widget::addChild(Node *child)
@ -125,14 +125,14 @@ void Widget::addChild(Node * child, int zOrder)
{
Node::addChild(child, zOrder);
}
void Widget::addChild(Node* child, int zOrder, int tag)
{
CCASSERT(dynamic_cast<Widget*>(child) != nullptr, "Widget only supports Widgets as children");
Node::addChild(child, zOrder, tag);
_widgetChildren.pushBack(child);
}
void Widget::sortAllChildren()
{
_reorderWidgetChildDirty = _reorderChildDirty;
@ -143,11 +143,11 @@ void Widget::sortAllChildren()
_reorderWidgetChildDirty = false;
}
}
Node* Widget::getChildByTag(int aTag)
{
CCASSERT( aTag != Node::INVALID_TAG, "Invalid tag");
for (auto& child : _widgetChildren)
{
if(child && child->getTag() == aTag)
@ -160,12 +160,12 @@ Vector<Node*>& Widget::getChildren()
{
return _widgetChildren;
}
const Vector<Node*>& Widget::getChildren() const
{
return _widgetChildren;
}
ssize_t Widget::getChildrenCount() const
{
return _widgetChildren.size();
@ -175,7 +175,7 @@ Widget* Widget::getWidgetParent()
{
return dynamic_cast<Widget*>(getParent());
}
void Widget::removeFromParent()
{
removeFromParentAndCleanup(true);
@ -195,9 +195,9 @@ void Widget::removeChild(Node *child, bool cleanup)
void Widget::removeChildByTag(int tag, bool cleanup)
{
CCASSERT( tag != Node::INVALID_TAG, "Invalid tag");
Node *child = getChildByTag(tag);
if (child == nullptr)
{
CCLOG("cocos2d: removeChildByTag(tag = %d): child not found!", tag);
@ -212,7 +212,7 @@ void Widget::removeAllChildren()
{
removeAllChildrenWithCleanup(true);
}
void Widget::removeAllChildrenWithCleanup(bool cleanup)
{
for (auto& child : _widgetChildren)
@ -252,7 +252,7 @@ Widget* Widget::getChildByName(const char *name)
}
return nullptr;
}
void Widget::addNode(Node* node)
{
addNode(node, node->getLocalZOrder(), node->getTag());
@ -273,7 +273,7 @@ void Widget::addNode(Node* node, int zOrder, int tag)
Node* Widget::getNodeByTag(int tag)
{
CCAssert( tag != Node::INVALID_TAG, "Invalid tag");
for (auto& node : _nodes)
{
if(node && node->getTag() == tag)
@ -296,9 +296,9 @@ void Widget::removeNode(Node* node)
void Widget::removeNodeByTag(int tag)
{
CCAssert( tag != Node::INVALID_TAG, "Invalid tag");
Node *node = this->getNodeByTag(tag);
if (node == nullptr)
{
CCLOG("cocos2d: removeNodeByTag(tag = %d): child not found!", tag);
@ -688,22 +688,22 @@ void Widget::setBrightStyle(BrightStyle style)
void Widget::onPressStateChangedToNormal()
{
}
void Widget::onPressStateChangedToPressed()
{
}
void Widget::onPressStateChangedToDisabled()
{
}
void Widget::didNotSelectSelf()
{
}
bool Widget::onTouchBegan(Touch *touch, Event *unusedEvent)
@ -837,13 +837,13 @@ bool Widget::clippingParentAreaContainPoint(const Point &pt)
}
parent = parent->getWidgetParent();
}
if (!_affectByClipping)
{
return true;
}
if (clippingParent)
{
bool bRet = false;
@ -1020,7 +1020,7 @@ Widget* Widget::createCloneInstance()
void Widget::copyClonedWidgetChildren(Widget* model)
{
auto& modelChildren = model->getChildren();
for (auto& subWidget : modelChildren)
{
Widget* child = static_cast<Widget*>(subWidget);
@ -1030,7 +1030,7 @@ void Widget::copyClonedWidgetChildren(Widget* model)
void Widget::copySpecialProperties(Widget* model)
{
}
void Widget::copyProperties(Widget *widget)
@ -1059,8 +1059,8 @@ void Widget::copyProperties(Widget *widget)
setRotation(widget->getRotation());
setRotationX(widget->getRotationX());
setRotationY(widget->getRotationY());
setFlipX(widget->isFlipX());
setFlipY(widget->isFlipY());
setFlippedX(widget->isFlippedX());
setFlippedY(widget->isFlippedY());
setColor(widget->getColor());
setOpacity(widget->getOpacity());
setCascadeOpacityEnabled(widget->isCascadeOpacityEnabled());
@ -1083,7 +1083,7 @@ int Widget::getActionTag()
{
return _actionTag;
}
}
NS_CC_END

Просмотреть файл

@ -80,22 +80,22 @@ typedef void (Ref::*SEL_TouchEvent)(Ref*,TouchEventType);
*/
class Widget : public Node
{
public:
public:
/**
* Default constructor
*/
Widget(void);
/**
* Default destructor
*/
virtual ~Widget();
/**
* Allocates and initializes a widget.
*/
static Widget* create();
/**
* Sets whether the widget is enabled
*
@ -105,14 +105,14 @@ public:
* @param enabled true if the widget is enabled, widget may be touched and visible, false if the widget is disabled, widget cannot be touched and hidden.
*/
virtual void setEnabled(bool enabled);
/**
* Determines if the widget is enabled
*
* @return true if the widget is enabled, false if the widget is disabled.
*/
bool isEnabled() const;
/**
* Sets whether the widget is bright
*
@ -121,14 +121,14 @@ public:
* @param visible true if the widget is bright, false if the widget is dark.
*/
void setBright(bool bright);
/**
* Determines if the widget is bright
*
* @return true if the widget is bright, false if the widget is dark.
*/
bool isBright() const;
/**
* Sets whether the widget is touch enabled
*
@ -137,7 +137,7 @@ public:
* @param visible true if the widget is touch enabled, false if the widget is touch disabled.
*/
virtual void setTouchEnabled(bool enabled);
/**
* To set the bright style of widget.
*
@ -146,14 +146,14 @@ public:
* @param style BRIGHT_NORMAL the widget is normal state, BRIGHT_HIGHLIGHT the widget is height light state.
*/
void setBrightStyle(BrightStyle style);
/**
* Determines if the widget is touch enabled
*
* @return true if the widget is touch enabled, false if the widget is touch disabled.
*/
bool isTouchEnabled() const;
/**
* Determines if the widget is on focused
*
@ -169,28 +169,28 @@ public:
* @param fucosed true if the widget is on focused, false if the widget is not on focused.
*/
void setFocused(bool fucosed);
/**
* Gets the left boundary position of this widget.
*
* @return The left boundary position of this widget.
*/
float getLeftInParent();
/**
* Gets the bottom boundary position of this widget.
*
* @return The bottom boundary position of this widget.
*/
float getBottomInParent();
/**
* Gets the right boundary position of this widget.
*
* @return The right boundary position of this widget.
*/
float getRightInParent();
/**
* Gets the top boundary position of this widget.
*
@ -233,7 +233,7 @@ public:
* @return a Node object whose tag equals to the input parameter
*/
virtual Node * getChildByTag(int tag) override;
virtual void sortAllChildren() override;
/**
* Return an array of children
@ -253,14 +253,14 @@ public:
*/
virtual Vector<Node*>& getChildren() override;
virtual const Vector<Node*>& getChildren() const override;
/**
* Get the amount of children.
*
* @return The amount of children.
*/
virtual ssize_t getChildrenCount() const override;
/**
* Removes this node itself from its parent node with a cleanup.
* If the node orphan, then nothing happens.
@ -275,7 +275,7 @@ public:
* @lua removeFromParent
*/
virtual void removeFromParentAndCleanup(bool cleanup) override;
/**
* Removes a child from the container. It will also cleanup all running actions depending on the cleanup parameter.
*
@ -283,7 +283,7 @@ public:
* @param cleanup true if all running actions and callbacks on the child node will be cleanup, false otherwise.
*/
virtual void removeChild(Node* child, bool cleanup = true) override;
/**
* Removes a child from the container by tag value. It will also cleanup all running actions depending on the cleanup parameter
*
@ -305,7 +305,7 @@ public:
* @lua removeAllChildren
*/
virtual void removeAllChildrenWithCleanup(bool cleanup) override;
/**
* Gets a child from the container with its name
*
@ -314,33 +314,33 @@ public:
* @return a Widget object whose name equals to the input parameter
*/
virtual Widget* getChildByName(const char* name);
virtual void addNode(Node* node);
virtual void addNode(Node * node, int zOrder);
virtual void addNode(Node* node, int zOrder, int tag);
virtual Node * getNodeByTag(int tag);
virtual Vector<Node*>& getNodes();
virtual void removeNode(Node* node);
virtual void removeNodeByTag(int tag);
virtual void removeAllNodes();
virtual void visit(cocos2d::Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
/**
* Sets the touch event target/selector of the menu item
*/
void addTouchEventListener(Ref* target,SEL_TouchEvent selector);
//cocos2d property
/**
* Changes the position (x,y) of the widget in OpenGL coordinates
*
@ -350,7 +350,7 @@ public:
* @param position The position (x,y) of the widget in OpenGL coordinates
*/
virtual void setPosition(const Point &pos) override;
/**
* Changes the position (x,y) of the widget in OpenGL coordinates
*
@ -360,7 +360,7 @@ public:
* @param percent The percent (x,y) of the widget in OpenGL coordinates
*/
void setPositionPercent(const Point &percent);
/**
* Gets the percent (x,y) of the widget in OpenGL coordinates
*
@ -369,7 +369,7 @@ public:
* @return The percent (x,y) of the widget in OpenGL coordinates
*/
const Point& getPositionPercent();
/**
* Changes the position type of the widget
*
@ -387,14 +387,14 @@ public:
* @return type the position type of widget
*/
PositionType getPositionType() const;
/**
* Sets whether the widget should be flipped horizontally or not.
*
* @param bFlipX true if the widget should be flipped horizaontally, false otherwise.
* @param bFlippedX true if the widget should be flipped horizaontally, false otherwise.
*/
virtual void setFlipX(bool flipX){};
virtual void setFlippedX(bool flippedX){};
/**
* Returns the flag which indicates whether the widget is flipped horizontally or not.
*
@ -405,15 +405,15 @@ public:
*
* @return true if the widget is flipped horizaontally, false otherwise.
*/
virtual bool isFlipX(){return false;};
virtual bool isFlippedX(){return false;};
/**
* Sets whether the widget should be flipped vertically or not.
*
* @param bFlipY true if the widget should be flipped vertically, flase otherwise.
* @param bFlippedY true if the widget should be flipped vertically, flase otherwise.
*/
virtual void setFlipY(bool flipY){};
virtual void setFlippedY(bool flippedY){};
/**
* Return the flag which indicates whether the widget is flipped vertically or not.
*
@ -424,13 +424,22 @@ public:
*
* @return true if the widget is flipped vertically, flase otherwise.
*/
virtual bool isFlipY(){return false;};
virtual bool isFlippedY(){return false;};
/** @deprecated Use isFlippedX() instead */
CC_DEPRECATED_ATTRIBUTE bool isFlipX() { return isFlippedX(); };
/** @deprecated Use setFlippedX() instead */
CC_DEPRECATED_ATTRIBUTE void setFlipX(bool flipX) { setFlippedX(flipX); };
/** @deprecated Use isFlippedY() instead */
CC_DEPRECATED_ATTRIBUTE bool isFlipY() { return isFlippedY(); };
/** @deprecated Use setFlippedY() instead */
CC_DEPRECATED_ATTRIBUTE void setFlipY(bool flipY) { setFlippedY(flipY); };
/**
* A call back function when widget lost of focus.
*/
void didNotSelectSelf();
/*
* Checks a point if in parent's area.
*
@ -439,40 +448,40 @@ public:
* @return true if the point is in parent's area, flase otherwise.
*/
bool clippingParentAreaContainPoint(const Point &pt);
/*
* Sends the touch event to widget's parent
*/
virtual void checkChildInfo(int handleState,Widget* sender,const Point &touchPoint);
/*
* Gets the touch began point of widget when widget is selected.
*
* @return the touch began point.
*/
const Point& getTouchStartPos();
/*
* Gets the touch move point of widget when widget is selected.
*
* @return the touch move point.
*/
const Point& getTouchMovePos();
/*
* Gets the touch end point of widget when widget is selected.
*
* @return the touch end point.
*/
const Point& getTouchEndPos();
/**
* Changes the name that is used to identify the widget easily.
*
* @param A const char* that indentifies the widget.
*/
void setName(const char* name);
/**
* Returns a name that is used to identify the widget easily.
*
@ -481,7 +490,7 @@ public:
* @return A const char* that identifies the widget.
*/
const char* getName() const;
/**
* Returns a type that is widget's type
*
@ -490,21 +499,21 @@ public:
* @return A WidgetType
*/
WidgetType getWidgetType() const;
/**
* Changes the size that is widget's size
*
* @param size that is widget's size
*/
virtual void setSize(const Size &size);
/**
* Changes the percent that is widget's percent size
*
* @param percent that is widget's percent size
*/
virtual void setSizePercent(const Point &percent);
/**
* Changes the size type of widget.
*
@ -522,21 +531,21 @@ public:
* @param type that is widget's size type
*/
SizeType getSizeType() const;
/**
* Returns size of widget
*
* @return size
*/
const Size& getSize() const;
/**
* Returns size percent of widget
*
* @return size percent
*/
const Point& getSizePercent() const;
/**
* Checks a point if is in widget's space
*
@ -545,14 +554,14 @@ public:
* @return true if the point is in widget's space, flase otherwise.
*/
virtual bool hitTest(const Point &pt);
virtual bool onTouchBegan(Touch *touch, Event *unusedEvent);
virtual void onTouchMoved(Touch *touch, Event *unusedEvent);
virtual void onTouchEnded(Touch *touch, Event *unusedEvent);
virtual void onTouchCancelled(Touch *touch, Event *unusedEvent);
/**
* Sets a LayoutParameter to widget.
* Sets a LayoutParameter to widget.
*
* @see LayoutParameter
*
@ -561,7 +570,7 @@ public:
* @param type Relative or Linear
*/
void setLayoutParameter(LayoutParameter* parameter);
/**
* Gets LayoutParameter of widget.
*
@ -572,21 +581,21 @@ public:
* @return LayoutParameter
*/
LayoutParameter* getLayoutParameter(LayoutParameterType type);
/**
* Ignore the widget size
*
* @param ignore, true that widget will ignore it's size, use texture size, false otherwise. Default value is true.
*/
virtual void ignoreContentAdaptWithSize(bool ignore);
/**
* Gets the widget if is ignore it's size.
*
* @param ignore, true that widget will ignore it's size, use texture size, false otherwise. Default value is true.
*/
bool isIgnoreContentAdaptWithSize() const;
/**
* Gets world position of widget.
*
@ -602,45 +611,45 @@ public:
* @return Node pointer.
*/
virtual Node* getVirtualRenderer();
/**
* Gets the content size of widget.
*
* Content size is widget's texture size.
*/
virtual const Size& getContentSize() const;
/**
* Returns the "class name" of widget.
*/
virtual std::string getDescription() const override;
Widget* clone();
virtual void onEnter() override;
virtual void onExit() override;
void updateSizeAndPosition();
/*temp action*/
void setActionTag(int tag);
int getActionTag();
protected:
//call back function called when size changed.
virtual void onSizeChanged();
//initializes state of widget.
virtual bool init();
//initializes renderer of widget.
virtual void initRenderer();
//call back function called widget's state changed to normal.
virtual void onPressStateChangedToNormal();
//call back function called widget's state changed to selected.
virtual void onPressStateChangedToPressed();
//call back function called widget's state changed to dark.
virtual void onPressStateChangedToDisabled();
void pushDownEvent();

Просмотреть файл

@ -10,11 +10,12 @@ SET(KAZMATH_SOURCES
utility.c
aabb.c
ray2.c
ray3.c
GL/mat4stack.c
GL/matrix.c
)
ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(kazmath)
set_target_properties(kazmath
PROPERTIES

Просмотреть файл

@ -1,76 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MAT3_H_INCLUDED
#define MAT3_H_INCLUDED
#include "CCPlatformMacros.h"
#include "utility.h"
struct kmVec3;
struct kmQuaternion;
typedef struct kmMat3{
kmScalar mat[9];
} kmMat3;
#ifdef __cplusplus
extern "C" {
#endif
CC_DLL kmMat3* const kmMat3Fill(kmMat3* pOut, const kmScalar* pMat);
CC_DLL kmMat3* const kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn);
CC_DLL kmMat3* const kmMat3Identity(kmMat3* pOut);
CC_DLL kmMat3* const kmMat3Inverse(kmMat3* pOut, const kmScalar pDeterminate, const kmMat3* pM);
CC_DLL const int kmMat3IsIdentity(const kmMat3* pIn);
CC_DLL kmMat3* const kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn);
CC_DLL const kmScalar kmMat3Determinant(const kmMat3* pIn);
CC_DLL kmMat3* const kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2);
CC_DLL kmMat3* const kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor);
CC_DLL kmMat3* const kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians);
CC_DLL struct kmVec3* const kmMat3RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn);
CC_DLL kmMat3* const kmMat3Assign(kmMat3* pOut, const kmMat3* pIn);
CC_DLL const int kmMat3AreEqual(const kmMat3* pM1, const kmMat3* pM2);
CC_DLL kmMat3* const kmMat3RotationX(kmMat3* pOut, const kmScalar radians);
CC_DLL kmMat3* const kmMat3RotationY(kmMat3* pOut, const kmScalar radians);
CC_DLL kmMat3* const kmMat3RotationZ(kmMat3* pOut, const kmScalar radians);
CC_DLL kmMat3* const kmMat3Rotation(kmMat3* pOut, const kmScalar radians);
CC_DLL kmMat3* const kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y);
CC_DLL kmMat3* const kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y);
CC_DLL kmMat3* const kmMat3RotationQuaternion(kmMat3* pOut, const struct kmQuaternion* pIn);
CC_DLL kmMat3* const kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians);
CC_DLL struct kmVec3* const kmMat3RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn);
#ifdef __cplusplus
}
#endif
#endif // MAT3_H_INCLUDED

Просмотреть файл

@ -1,94 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MAT4_H_INCLUDED
#define MAT4_H_INCLUDED
#include "CCPlatformMacros.h"
#include "utility.h"
struct kmVec3;
struct kmMat3;
struct kmQuaternion;
struct kmPlane;
/*
A 4x4 matrix
| 0 4 8 12 |
mat = | 1 5 9 13 |
| 2 6 10 14 |
| 3 7 11 15 |
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef struct kmMat4 {
kmScalar mat[16];
} kmMat4;
CC_DLL kmMat4* const kmMat4Fill(kmMat4* pOut, const kmScalar* pMat);
CC_DLL kmMat4* const kmMat4Identity(kmMat4* pOut);
CC_DLL kmMat4* const kmMat4Inverse(kmMat4* pOut, const kmMat4* pM);
CC_DLL const int kmMat4IsIdentity(const kmMat4* pIn);
CC_DLL kmMat4* const kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn);
CC_DLL kmMat4* const kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2);
CC_DLL kmMat4* const kmMat4Assign(kmMat4* pOut, const kmMat4* pIn);
CC_DLL const int kmMat4AreEqual(const kmMat4* pM1, const kmMat4* pM2);
CC_DLL kmMat4* const kmMat4RotationX(kmMat4* pOut, const kmScalar radians);
CC_DLL kmMat4* const kmMat4RotationY(kmMat4* pOut, const kmScalar radians);
CC_DLL kmMat4* const kmMat4RotationZ(kmMat4* pOut, const kmScalar radians);
CC_DLL kmMat4* const kmMat4RotationPitchYawRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll);
CC_DLL kmMat4* const kmMat4RotationQuaternion(kmMat4* pOut, const struct kmQuaternion* pQ);
CC_DLL kmMat4* const kmMat4RotationTranslation(kmMat4* pOut, const struct kmMat3* rotation, const struct kmVec3* translation);
CC_DLL kmMat4* const kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
CC_DLL kmMat4* const kmMat4Translation(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
CC_DLL struct kmVec3* const kmMat4GetUpVec3(struct kmVec3* pOut, const kmMat4* pIn);
CC_DLL struct kmVec3* const kmMat4GetRightVec3(struct kmVec3* pOut, const kmMat4* pIn);
CC_DLL struct kmVec3* const kmMat4GetForwardVec3(struct kmVec3* pOut, const kmMat4* pIn);
CC_DLL kmMat4* const kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY, kmScalar aspect, kmScalar zNear, kmScalar zFar);
CC_DLL kmMat4* const kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left, kmScalar right, kmScalar bottom, kmScalar top, kmScalar nearVal, kmScalar farVal);
CC_DLL kmMat4* const kmMat4LookAt(kmMat4* pOut, const struct kmVec3* pEye, const struct kmVec3* pCenter, const struct kmVec3* pUp);
CC_DLL kmMat4* const kmMat4RotationAxisAngle(kmMat4* pOut, const struct kmVec3* axis, kmScalar radians);
CC_DLL struct kmMat3* const kmMat4ExtractRotation(struct kmMat3* pOut, const kmMat4* pIn);
CC_DLL struct kmPlane* const kmMat4ExtractPlane(struct kmPlane* pOut, const kmMat4* pIn, const kmEnum plane);
CC_DLL struct kmVec3* const kmMat4RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn);
#ifdef __cplusplus
}
#endif
#endif /* MAT4_H_INCLUDED */

Просмотреть файл

@ -0,0 +1,18 @@
#ADD_LIBRARY(Kazmath STATIC ${KAZMATH_SRCS})
#INSTALL(TARGETS Kazmath ARCHIVE DESTINATION lib)
FIND_PACKAGE(Threads REQUIRED)
ADD_LIBRARY(kazmath SHARED ${KAZMATH_SOURCES})
TARGET_LINK_LIBRARIES(kazmath ${CMAKE_THREAD_LIBS_INIT})
SET_TARGET_PROPERTIES(kazmath
PROPERTIES
VERSION 0.0.1
SOVERSION 1)
INSTALL(TARGETS kazmath DESTINATION lib)
#ADD_LIBRARY(KazmathGL STATIC ${GL_UTILS_SRCS})
#INSTALL(TARGETS KazmathGL ARCHIVE DESTINATION lib)
INSTALL(FILES ${KAZMATH_HEADERS} DESTINATION include/kazmath)
INSTALL(FILES ${GL_UTILS_HEADERS} DESTINATION include/kazmath/GL)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_modules/KAZMATHConfig.cmake DESTINATION ${CMAKE_INSTALL_PREFIX}/share/kazmath)

Просмотреть файл

@ -0,0 +1,142 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "aabb.h"
/**
Initializes the AABB around a central point. If centre is NULL then the origin
is used. Returns pBox.
*/
kmAABB* kmAABBInitialize(kmAABB* pBox, const kmVec3* centre, const kmScalar width, const kmScalar height, const kmScalar depth) {
if(!pBox) return 0;
kmVec3 origin;
kmVec3* point = centre ? (kmVec3*) centre : &origin;
kmVec3Zero(&origin);
pBox->min.x = point->x - (width / 2);
pBox->min.y = point->y - (height / 2);
pBox->min.z = point->z - (depth / 2);
pBox->max.x = point->x + (width / 2);
pBox->max.y = point->y + (height / 2);
pBox->max.z = point->z + (depth / 2);
return pBox;
}
/**
* Returns KM_TRUE if point is in the specified AABB, returns
* KM_FALSE otherwise.
*/
int kmAABBContainsPoint(const kmAABB* pBox, const kmVec3* pPoint)
{
if(pPoint->x >= pBox->min.x && pPoint->x <= pBox->max.x &&
pPoint->y >= pBox->min.y && pPoint->y <= pBox->max.y &&
pPoint->z >= pBox->min.z && pPoint->z <= pBox->max.z) {
return KM_TRUE;
}
return KM_FALSE;
}
/**
* Assigns pIn to pOut, returns pOut.
*/
kmAABB* kmAABBAssign(kmAABB* pOut, const kmAABB* pIn)
{
kmVec3Assign(&pOut->min, &pIn->min);
kmVec3Assign(&pOut->max, &pIn->max);
return pOut;
}
/**
* Scales pIn by s, stores the resulting AABB in pOut. Returns pOut
*/
kmAABB* kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s)
{
assert(0 && "Not implemented");
return pOut;
}
kmBool kmAABBIntersectsTriangle(kmAABB* box, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3) {
assert(0 && "Not implemented");
return KM_TRUE;
}
kmEnum kmAABBContainsAABB(const kmAABB* container, const kmAABB* to_check) {
kmVec3 corners[8];
kmEnum result = KM_CONTAINS_ALL;
kmBool found = KM_FALSE;
kmVec3Fill(&corners[0], to_check->min.x, to_check->min.y, to_check->min.z);
kmVec3Fill(&corners[1], to_check->max.x, to_check->min.y, to_check->min.z);
kmVec3Fill(&corners[2], to_check->max.x, to_check->max.y, to_check->min.z);
kmVec3Fill(&corners[3], to_check->min.x, to_check->max.y, to_check->min.z);
kmVec3Fill(&corners[4], to_check->min.x, to_check->min.y, to_check->max.z);
kmVec3Fill(&corners[5], to_check->max.x, to_check->min.y, to_check->max.z);
kmVec3Fill(&corners[6], to_check->max.x, to_check->max.y, to_check->max.z);
kmVec3Fill(&corners[7], to_check->min.x, to_check->max.y, to_check->max.z);
kmUchar i;
for(i = 0; i < 8; ++i) {
if(!kmAABBContainsPoint(container, &corners[i])) {
result = KM_CONTAINS_PARTIAL;
if(found) {
//If we previously found a corner that was within the container
//We know that partial is the final result
return result;
}
} else {
found = KM_TRUE;
}
}
if(!found) {
result = KM_CONTAINS_NONE;
}
return result;
}
kmScalar kmAABBDiameterX(const kmAABB* aabb) {
return fabs(aabb->max.x - aabb->min.x);
}
kmScalar kmAABBDiameterY(const kmAABB* aabb) {
return fabs(aabb->max.y - aabb->min.y);
}
kmScalar kmAABBDiameterZ(const kmAABB* aabb) {
return fabs(aabb->max.z - aabb->min.z);
}
kmVec3* kmAABBCentre(const kmAABB* aabb, kmVec3* pOut) {
kmVec3Add(pOut, &aabb->min, &aabb->max);
kmVec3Scale(pOut, pOut, 0.5);
return pOut;
}

Просмотреть файл

@ -27,6 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define KAZMATH_AABB_H_INCLUDED
#include "CCPlatformMacros.h"
#include "vec3.h"
#include "utility.h"
@ -35,7 +36,7 @@ extern "C" {
#endif
/**
* A structure that represents an axis-aligned
* A struture that represents an axis-aligned
* bounding box.
*/
typedef struct kmAABB {
@ -43,9 +44,17 @@ typedef struct kmAABB {
kmVec3 max; /** The min corner of the box */
} kmAABB;
CC_DLL const int kmAABBContainsPoint(const kmVec3* pPoint, const kmAABB* pBox);
CC_DLL kmAABB* const kmAABBAssign(kmAABB* pOut, const kmAABB* pIn);
CC_DLL kmAABB* const kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s);
CC_DLL kmAABB* kmAABBInitialize(kmAABB* pBox, const kmVec3* centre, const kmScalar width, const kmScalar height, const kmScalar depth);
CC_DLL int kmAABBContainsPoint(const kmAABB* pBox, const kmVec3* pPoint);
CC_DLL kmAABB* kmAABBAssign(kmAABB* pOut, const kmAABB* pIn);
CC_DLL kmAABB* kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s);
CC_DLL kmBool kmAABBIntersectsTriangle(kmAABB* box, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3);
CC_DLL kmEnum kmAABBContainsAABB(const kmAABB* container, const kmAABB* to_check);
CC_DLL kmScalar kmAABBDiameterX(const kmAABB* aabb);
CC_DLL kmScalar kmAABBDiameterY(const kmAABB* aabb);
CC_DLL kmScalar kmAABBDiameterZ(const kmAABB* aabb);
CC_DLL kmVec3* kmAABBCentre(const kmAABB* aabb, kmVec3* pOut);
#ifdef __cplusplus
}

Просмотреть файл

@ -28,7 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "vec2.h"
#include "vec3.h"
#include "vec4.h"
#include "mat3.h"
#include "mat4.h"
#include "utility.h"
@ -36,5 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "plane.h"
#include "aabb.h"
#include "ray2.h"
#include "ray3.h"
#endif // KAZMATH_H_INCLUDED

Просмотреть файл

@ -0,0 +1,458 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <memory.h>
#include <assert.h>
#include "utility.h"
#include "vec3.h"
#include "mat3.h"
#include "mat4.h"
#include "quaternion.h"
kmMat3* kmMat3Fill(kmMat3* pOut, const kmScalar* pMat)
{
memcpy(pOut->mat, pMat, sizeof(kmScalar) * 9);
return pOut;
}
/** Sets pOut to an identity matrix returns pOut*/
kmMat3* kmMat3Identity(kmMat3* pOut)
{
memset(pOut->mat, 0, sizeof(kmScalar) * 9);
pOut->mat[0] = pOut->mat[4] = pOut->mat[8] = 1.0f;
return pOut;
}
kmScalar kmMat3Determinant(const kmMat3* pIn)
{
kmScalar output;
/*
calculating the determinant following the rule of sarus,
| 0 3 6 | 0 3 |
m = | 1 4 7 | 1 4 |
| 2 5 8 | 2 5 |
now sum up the products of the diagonals going to the right (i.e. 0,4,8)
and substract the products of the other diagonals (i.e. 2,4,6)
*/
output = pIn->mat[0] * pIn->mat[4] * pIn->mat[8] + pIn->mat[1] * pIn->mat[5] * pIn->mat[6] + pIn->mat[2] * pIn->mat[3] * pIn->mat[7];
output -= pIn->mat[2] * pIn->mat[4] * pIn->mat[6] + pIn->mat[0] * pIn->mat[5] * pIn->mat[7] + pIn->mat[1] * pIn->mat[3] * pIn->mat[8];
return output;
}
kmMat3* kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn)
{
pOut->mat[0] = pIn->mat[4] * pIn->mat[8] - pIn->mat[5] * pIn->mat[7];
pOut->mat[1] = pIn->mat[2] * pIn->mat[7] - pIn->mat[1] * pIn->mat[8];
pOut->mat[2] = pIn->mat[1] * pIn->mat[5] - pIn->mat[2] * pIn->mat[4];
pOut->mat[3] = pIn->mat[5] * pIn->mat[6] - pIn->mat[3] * pIn->mat[8];
pOut->mat[4] = pIn->mat[0] * pIn->mat[8] - pIn->mat[2] * pIn->mat[6];
pOut->mat[5] = pIn->mat[2] * pIn->mat[3] - pIn->mat[0] * pIn->mat[5];
pOut->mat[6] = pIn->mat[3] * pIn->mat[7] - pIn->mat[4] * pIn->mat[6];
pOut->mat[7] = pIn->mat[1] * pIn->mat[6] - pIn->mat[0] * pIn->mat[7];
pOut->mat[8] = pIn->mat[0] * pIn->mat[4] - pIn->mat[1] * pIn->mat[3];
return pOut;
}
kmMat3* kmMat3Inverse(kmMat3* pOut, const kmMat3* pM)
{
kmScalar determinate = kmMat3Determinant(pM);
kmScalar detInv;
kmMat3 adjugate;
if(determinate == 0.0)
{
return NULL;
}
detInv = 1.0 / determinate;
kmMat3Adjugate(&adjugate, pM);
kmMat3ScalarMultiply(pOut, &adjugate, detInv);
return pOut;
}
/** Returns true if pIn is an identity matrix */
int kmMat3IsIdentity(const kmMat3* pIn)
{
static kmScalar identity [] = { 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f};
return (memcmp(identity, pIn->mat, sizeof(kmScalar) * 9) == 0);
}
/** Sets pOut to the transpose of pIn, returns pOut */
kmMat3* kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn)
{
kmScalar temp[9];
temp[0] = pIn->mat[0];
temp[1] = pIn->mat[3];
temp[2] = pIn->mat[6];
temp[3] = pIn->mat[1];
temp[4] = pIn->mat[4];
temp[5] = pIn->mat[7];
temp[6] = pIn->mat[2];
temp[7] = pIn->mat[5];
temp[8] = pIn->mat[8];
memcpy(&pOut->mat, temp, sizeof(kmScalar)*9);
return pOut;
}
/* Multiplies pM1 with pM2, stores the result in pOut, returns pOut */
kmMat3* kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2)
{
kmScalar mat[9];
const kmScalar *m1 = pM1->mat, *m2 = pM2->mat;
mat[0] = m1[0] * m2[0] + m1[3] * m2[1] + m1[6] * m2[2];
mat[1] = m1[1] * m2[0] + m1[4] * m2[1] + m1[7] * m2[2];
mat[2] = m1[2] * m2[0] + m1[5] * m2[1] + m1[8] * m2[2];
mat[3] = m1[0] * m2[3] + m1[3] * m2[4] + m1[6] * m2[5];
mat[4] = m1[1] * m2[3] + m1[4] * m2[4] + m1[7] * m2[5];
mat[5] = m1[2] * m2[3] + m1[5] * m2[4] + m1[8] * m2[5];
mat[6] = m1[0] * m2[6] + m1[3] * m2[7] + m1[6] * m2[8];
mat[7] = m1[1] * m2[6] + m1[4] * m2[7] + m1[7] * m2[8];
mat[8] = m1[2] * m2[6] + m1[5] * m2[7] + m1[8] * m2[8];
memcpy(pOut->mat, mat, sizeof(kmScalar)*9);
return pOut;
}
kmMat3* kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor)
{
kmScalar mat[9];
int i;
for(i = 0; i < 9; i++)
{
mat[i] = pM->mat[i] * pFactor;
}
memcpy(pOut->mat, mat, sizeof(kmScalar)*9);
return pOut;
}
/** Assigns the value of pIn to pOut */
kmMat3* kmMat3Assign(kmMat3* pOut, const kmMat3* pIn)
{
assert(pOut != pIn); //You have tried to self-assign!!
memcpy(pOut->mat, pIn->mat, sizeof(kmScalar)*9);
return pOut;
}
kmMat3* kmMat3AssignMat4(kmMat3* pOut, const kmMat4* pIn) {
pOut->mat[0] = pIn->mat[0];
pOut->mat[1] = pIn->mat[1];
pOut->mat[2] = pIn->mat[2];
pOut->mat[3] = pIn->mat[4];
pOut->mat[4] = pIn->mat[5];
pOut->mat[5] = pIn->mat[6];
pOut->mat[6] = pIn->mat[8];
pOut->mat[7] = pIn->mat[9];
pOut->mat[8] = pIn->mat[10];
return pOut;
}
/** Returns true if the 2 matrices are equal (approximately) */
int kmMat3AreEqual(const kmMat3* pMat1, const kmMat3* pMat2)
{
int i;
if (pMat1 == pMat2) {
return KM_TRUE;
}
for (i = 0; i < 9; ++i) {
if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] &&
pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) {
return KM_FALSE;
}
}
return KM_TRUE;
}
/* Rotation around the z axis so everything stays planar in XY */
kmMat3* kmMat3Rotation(kmMat3* pOut, const kmScalar radians)
{
/*
| cos(A) -sin(A) 0 |
M = | sin(A) cos(A) 0 |
| 0 0 1 |
*/
pOut->mat[0] = cosf(radians);
pOut->mat[1] = sinf(radians);
pOut->mat[2] = 0.0f;
pOut->mat[3] = -sinf(radians);
pOut->mat[4] = cosf(radians);
pOut->mat[5] = 0.0f;
pOut->mat[6] = 0.0f;
pOut->mat[7] = 0.0f;
pOut->mat[8] = 1.0f;
return pOut;
}
/** Builds a scaling matrix */
kmMat3* kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y)
{
// memset(pOut->mat, 0, sizeof(kmScalar) * 9);
kmMat3Identity(pOut);
pOut->mat[0] = x;
pOut->mat[4] = y;
return pOut;
}
kmMat3* kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y)
{
// memset(pOut->mat, 0, sizeof(kmScalar) * 9);
kmMat3Identity(pOut);
pOut->mat[6] = x;
pOut->mat[7] = y;
// pOut->mat[8] = 1.0;
return pOut;
}
kmMat3* kmMat3RotationQuaternion(kmMat3* pOut, const kmQuaternion* pIn)
{
if (!pIn || !pOut) {
return NULL;
}
// First row
pOut->mat[0] = 1.0f - 2.0f * (pIn->y * pIn->y + pIn->z * pIn->z);
pOut->mat[1] = 2.0f * (pIn->x * pIn->y - pIn->w * pIn->z);
pOut->mat[2] = 2.0f * (pIn->x * pIn->z + pIn->w * pIn->y);
// Second row
pOut->mat[3] = 2.0f * (pIn->x * pIn->y + pIn->w * pIn->z);
pOut->mat[4] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->z * pIn->z);
pOut->mat[5] = 2.0f * (pIn->y * pIn->z - pIn->w * pIn->x);
// Third row
pOut->mat[6] = 2.0f * (pIn->x * pIn->z - pIn->w * pIn->y);
pOut->mat[7] = 2.0f * (pIn->y * pIn->z + pIn->w * pIn->x);
pOut->mat[8] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->y * pIn->y);
return pOut;
}
kmMat3* kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians)
{
kmScalar rcos = cosf(radians);
kmScalar rsin = sinf(radians);
pOut->mat[0] = rcos + axis->x * axis->x * (1 - rcos);
pOut->mat[1] = axis->z * rsin + axis->y * axis->x * (1 - rcos);
pOut->mat[2] = -axis->y * rsin + axis->z * axis->x * (1 - rcos);
pOut->mat[3] = -axis->z * rsin + axis->x * axis->y * (1 - rcos);
pOut->mat[4] = rcos + axis->y * axis->y * (1 - rcos);
pOut->mat[5] = axis->x * rsin + axis->z * axis->y * (1 - rcos);
pOut->mat[6] = axis->y * rsin + axis->x * axis->z * (1 - rcos);
pOut->mat[7] = -axis->x * rsin + axis->y * axis->z * (1 - rcos);
pOut->mat[8] = rcos + axis->z * axis->z * (1 - rcos);
return pOut;
}
kmVec3* kmMat3RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn)
{
/*Surely not this easy?*/
kmQuaternion temp;
kmQuaternionRotationMatrix(&temp, pIn);
kmQuaternionToAxisAngle(&temp, pAxis, radians);
return pAxis;
}
/**
* Builds an X-axis rotation matrix and stores it in pOut, returns pOut
*/
kmMat3* kmMat3RotationX(kmMat3* pOut, const kmScalar radians)
{
/*
| 1 0 0 |
M = | 0 cos(A) -sin(A) |
| 0 sin(A) cos(A) |
*/
pOut->mat[0] = 1.0f;
pOut->mat[1] = 0.0f;
pOut->mat[2] = 0.0f;
pOut->mat[3] = 0.0f;
pOut->mat[4] = cosf(radians);
pOut->mat[5] = sinf(radians);
pOut->mat[6] = 0.0f;
pOut->mat[7] = -sinf(radians);
pOut->mat[8] = cosf(radians);
return pOut;
}
/**
* Builds a rotation matrix using the rotation around the Y-axis
* The result is stored in pOut, pOut is returned.
*/
kmMat3* kmMat3RotationY(kmMat3* pOut, const kmScalar radians)
{
/*
| cos(A) 0 sin(A) |
M = | 0 1 0 |
| -sin(A) 0 cos(A) |
*/
pOut->mat[0] = cosf(radians);
pOut->mat[1] = 0.0f;
pOut->mat[2] = -sinf(radians);
pOut->mat[3] = 0.0f;
pOut->mat[4] = 1.0f;
pOut->mat[5] = 0.0f;
pOut->mat[6] = sinf(radians);
pOut->mat[7] = 0.0f;
pOut->mat[8] = cosf(radians);
return pOut;
}
/**
* Builds a rotation matrix around the Z-axis. The resulting
* matrix is stored in pOut. pOut is returned.
*/
kmMat3* kmMat3RotationZ(kmMat3* pOut, const kmScalar radians)
{
/*
| cos(A) -sin(A) 0 |
M = | sin(A) cos(A) 0 |
| 0 0 1 |
*/
pOut->mat[0] = cosf(radians);
pOut->mat[1] =-sinf(radians);
pOut->mat[2] = 0.0f;
pOut->mat[3] = sinf(radians);
pOut->mat[4] = cosf(radians);
pOut->mat[5] = 0.0f;
pOut->mat[6] = 0.0f;
pOut->mat[7] = 0.0f;
pOut->mat[8] = 1.0f;
return pOut;
}
kmVec3* kmMat3GetUpVec3(kmVec3* pOut, const kmMat3* pIn) {
pOut->x = pIn->mat[3];
pOut->y = pIn->mat[4];
pOut->z = pIn->mat[5];
kmVec3Normalize(pOut, pOut);
return pOut;
}
kmVec3* kmMat3GetRightVec3(kmVec3* pOut, const kmMat3* pIn) {
pOut->x = pIn->mat[0];
pOut->y = pIn->mat[1];
pOut->z = pIn->mat[2];
kmVec3Normalize(pOut, pOut);
return pOut;
}
kmVec3* kmMat3GetForwardVec3(kmVec3* pOut, const kmMat3* pIn) {
pOut->x = pIn->mat[6];
pOut->y = pIn->mat[7];
pOut->z = pIn->mat[8];
kmVec3Normalize(pOut, pOut);
return pOut;
}
kmMat3* kmMat3LookAt(kmMat3* pOut, const kmVec3* pEye,
const kmVec3* pCenter, const kmVec3* pUp)
{
kmVec3 f, up, s, u;
kmVec3Subtract(&f, pCenter, pEye);
kmVec3Normalize(&f, &f);
kmVec3Assign(&up, pUp);
kmVec3Normalize(&up, &up);
kmVec3Cross(&s, &f, &up);
kmVec3Normalize(&s, &s);
kmVec3Cross(&u, &s, &f);
kmVec3Normalize(&s, &s);
pOut->mat[0] = s.x;
pOut->mat[3] = s.y;
pOut->mat[6] = s.z;
pOut->mat[1] = u.x;
pOut->mat[4] = u.y;
pOut->mat[7] = u.z;
pOut->mat[2] = -f.x;
pOut->mat[5] = -f.y;
pOut->mat[8] = -f.z;
return pOut;
}

Просмотреть файл

@ -0,0 +1,87 @@
#ifndef HEADER_8E9D0ABA3C76B989
#define HEADER_8E9D0ABA3C76B989
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MAT3_H_INCLUDED
#define MAT3_H_INCLUDED
#include "CCPlatformMacros.h"
#include "utility.h"
struct kmVec3;
struct kmQuaternion;
struct kmMat4;
typedef struct kmMat3{
kmScalar mat[9];
} kmMat3;
#ifdef __cplusplus
extern "C" {
#endif
CC_DLL kmMat3* kmMat3Fill(kmMat3* pOut, const kmScalar* pMat);
CC_DLL kmMat3* kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn);
CC_DLL kmMat3* kmMat3Identity(kmMat3* pOut);
CC_DLL kmMat3* kmMat3Inverse(kmMat3* pOut, const kmMat3* pM);
CC_DLL int kmMat3IsIdentity(const kmMat3* pIn);
CC_DLL kmMat3* kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn);
CC_DLL kmScalar kmMat3Determinant(const kmMat3* pIn);
CC_DLL kmMat3* kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2);
CC_DLL kmMat3* kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor);
CC_DLL kmMat3* kmMat3Assign(kmMat3* pOut, const kmMat3* pIn);
CC_DLL kmMat3* kmMat3AssignMat4(kmMat3* pOut, const struct kmMat4* pIn);
CC_DLL int kmMat3AreEqual(const kmMat3* pM1, const kmMat3* pM2);
CC_DLL struct kmVec3* kmMat3GetUpVec3(struct kmVec3* pOut, const kmMat3* pIn);
CC_DLL struct kmVec3* kmMat3GetRightVec3(struct kmVec3* pOut, const kmMat3* pIn);
CC_DLL struct kmVec3* kmMat3GetForwardVec3(struct kmVec3* pOut, const kmMat3* pIn);
CC_DLL kmMat3* kmMat3RotationX(kmMat3* pOut, const kmScalar radians);
CC_DLL kmMat3* kmMat3RotationY(kmMat3* pOut, const kmScalar radians);
CC_DLL kmMat3* kmMat3RotationZ(kmMat3* pOut, const kmScalar radians);
CC_DLL kmMat3* kmMat3Rotation(kmMat3* pOut, const kmScalar radians);
CC_DLL kmMat3* kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y);
CC_DLL kmMat3* kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y);
CC_DLL kmMat3* kmMat3RotationQuaternion(kmMat3* pOut, const struct kmQuaternion* pIn);
CC_DLL kmMat3* kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians);
CC_DLL struct kmVec3* kmMat3RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn);
CC_DLL kmMat3* kmMat3LookAt(kmMat3* pOut, const struct kmVec3* pEye, const struct kmVec3* pCenter, const struct kmVec3* pUp);
#ifdef __cplusplus
}
#endif
#endif // MAT3_H_INCLUDED
#endif // header guard

Просмотреть файл

@ -0,0 +1,805 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file mat4.c
*/
#include <memory.h>
#include <assert.h>
#include <stdlib.h>
#include "utility.h"
#include "vec3.h"
#include "mat4.h"
#include "mat3.h"
#include "quaternion.h"
#include "plane.h"
#include "neon_matrix_impl.h"
/**
* Fills a kmMat4 structure with the values from a 16
* element array of kmScalars
* @Params pOut - A pointer to the destination matrix
* pMat - A 16 element array of kmScalars
* @Return Returns pOut so that the call can be nested
*/
kmMat4* kmMat4Fill(kmMat4* pOut, const kmScalar* pMat)
{
memcpy(pOut->mat, pMat, sizeof(kmScalar) * 16);
return pOut;
}
/**
* Sets pOut to an identity matrix returns pOut
* @Params pOut - A pointer to the matrix to set to identity
* @Return Returns pOut so that the call can be nested
*/
kmMat4* kmMat4Identity(kmMat4* pOut)
{
memset(pOut->mat, 0, sizeof(kmScalar) * 16);
pOut->mat[0] = pOut->mat[5] = pOut->mat[10] = pOut->mat[15] = 1.0f;
return pOut;
}
/**
* Calculates the inverse of pM and stores the result in
* pOut.
* @Return Returns NULL if there is no inverse, else pOut
*/
kmMat4* kmMat4Inverse(kmMat4* pOut, const kmMat4* pM) {
kmMat4 tmp;
double det;
int i;
tmp.mat[0] = pM->mat[5] * pM->mat[10] * pM->mat[15] -
pM->mat[5] * pM->mat[11] * pM->mat[14] -
pM->mat[9] * pM->mat[6] * pM->mat[15] +
pM->mat[9] * pM->mat[7] * pM->mat[14] +
pM->mat[13] * pM->mat[6] * pM->mat[11] -
pM->mat[13] * pM->mat[7] * pM->mat[10];
tmp.mat[4] = -pM->mat[4] * pM->mat[10] * pM->mat[15] +
pM->mat[4] * pM->mat[11] * pM->mat[14] +
pM->mat[8] * pM->mat[6] * pM->mat[15] -
pM->mat[8] * pM->mat[7] * pM->mat[14] -
pM->mat[12] * pM->mat[6] * pM->mat[11] +
pM->mat[12] * pM->mat[7] * pM->mat[10];
tmp.mat[8] = pM->mat[4] * pM->mat[9] * pM->mat[15] -
pM->mat[4] * pM->mat[11] * pM->mat[13] -
pM->mat[8] * pM->mat[5] * pM->mat[15] +
pM->mat[8] * pM->mat[7] * pM->mat[13] +
pM->mat[12] * pM->mat[5] * pM->mat[11] -
pM->mat[12] * pM->mat[7] * pM->mat[9];
tmp.mat[12] = -pM->mat[4] * pM->mat[9] * pM->mat[14] +
pM->mat[4] * pM->mat[10] * pM->mat[13] +
pM->mat[8] * pM->mat[5] * pM->mat[14] -
pM->mat[8] * pM->mat[6] * pM->mat[13] -
pM->mat[12] * pM->mat[5] * pM->mat[10] +
pM->mat[12] * pM->mat[6] * pM->mat[9];
tmp.mat[1] = -pM->mat[1] * pM->mat[10] * pM->mat[15] +
pM->mat[1] * pM->mat[11] * pM->mat[14] +
pM->mat[9] * pM->mat[2] * pM->mat[15] -
pM->mat[9] * pM->mat[3] * pM->mat[14] -
pM->mat[13] * pM->mat[2] * pM->mat[11] +
pM->mat[13] * pM->mat[3] * pM->mat[10];
tmp.mat[5] = pM->mat[0] * pM->mat[10] * pM->mat[15] -
pM->mat[0] * pM->mat[11] * pM->mat[14] -
pM->mat[8] * pM->mat[2] * pM->mat[15] +
pM->mat[8] * pM->mat[3] * pM->mat[14] +
pM->mat[12] * pM->mat[2] * pM->mat[11] -
pM->mat[12] * pM->mat[3] * pM->mat[10];
tmp.mat[9] = -pM->mat[0] * pM->mat[9] * pM->mat[15] +
pM->mat[0] * pM->mat[11] * pM->mat[13] +
pM->mat[8] * pM->mat[1] * pM->mat[15] -
pM->mat[8] * pM->mat[3] * pM->mat[13] -
pM->mat[12] * pM->mat[1] * pM->mat[11] +
pM->mat[12] * pM->mat[3] * pM->mat[9];
tmp.mat[13] = pM->mat[0] * pM->mat[9] * pM->mat[14] -
pM->mat[0] * pM->mat[10] * pM->mat[13] -
pM->mat[8] * pM->mat[1] * pM->mat[14] +
pM->mat[8] * pM->mat[2] * pM->mat[13] +
pM->mat[12] * pM->mat[1] * pM->mat[10] -
pM->mat[12] * pM->mat[2] * pM->mat[9];
tmp.mat[2] = pM->mat[1] * pM->mat[6] * pM->mat[15] -
pM->mat[1] * pM->mat[7] * pM->mat[14] -
pM->mat[5] * pM->mat[2] * pM->mat[15] +
pM->mat[5] * pM->mat[3] * pM->mat[14] +
pM->mat[13] * pM->mat[2] * pM->mat[7] -
pM->mat[13] * pM->mat[3] * pM->mat[6];
tmp.mat[6] = -pM->mat[0] * pM->mat[6] * pM->mat[15] +
pM->mat[0] * pM->mat[7] * pM->mat[14] +
pM->mat[4] * pM->mat[2] * pM->mat[15] -
pM->mat[4] * pM->mat[3] * pM->mat[14] -
pM->mat[12] * pM->mat[2] * pM->mat[7] +
pM->mat[12] * pM->mat[3] * pM->mat[6];
tmp.mat[10] = pM->mat[0] * pM->mat[5] * pM->mat[15] -
pM->mat[0] * pM->mat[7] * pM->mat[13] -
pM->mat[4] * pM->mat[1] * pM->mat[15] +
pM->mat[4] * pM->mat[3] * pM->mat[13] +
pM->mat[12] * pM->mat[1] * pM->mat[7] -
pM->mat[12] * pM->mat[3] * pM->mat[5];
tmp.mat[14] = -pM->mat[0] * pM->mat[5] * pM->mat[14] +
pM->mat[0] * pM->mat[6] * pM->mat[13] +
pM->mat[4] * pM->mat[1] * pM->mat[14] -
pM->mat[4] * pM->mat[2] * pM->mat[13] -
pM->mat[12] * pM->mat[1] * pM->mat[6] +
pM->mat[12] * pM->mat[2] * pM->mat[5];
tmp.mat[3] = -pM->mat[1] * pM->mat[6] * pM->mat[11] +
pM->mat[1] * pM->mat[7] * pM->mat[10] +
pM->mat[5] * pM->mat[2] * pM->mat[11] -
pM->mat[5] * pM->mat[3] * pM->mat[10] -
pM->mat[9] * pM->mat[2] * pM->mat[7] +
pM->mat[9] * pM->mat[3] * pM->mat[6];
tmp.mat[7] = pM->mat[0] * pM->mat[6] * pM->mat[11] -
pM->mat[0] * pM->mat[7] * pM->mat[10] -
pM->mat[4] * pM->mat[2] * pM->mat[11] +
pM->mat[4] * pM->mat[3] * pM->mat[10] +
pM->mat[8] * pM->mat[2] * pM->mat[7] -
pM->mat[8] * pM->mat[3] * pM->mat[6];
tmp.mat[11] = -pM->mat[0] * pM->mat[5] * pM->mat[11] +
pM->mat[0] * pM->mat[7] * pM->mat[9] +
pM->mat[4] * pM->mat[1] * pM->mat[11] -
pM->mat[4] * pM->mat[3] * pM->mat[9] -
pM->mat[8] * pM->mat[1] * pM->mat[7] +
pM->mat[8] * pM->mat[3] * pM->mat[5];
tmp.mat[15] = pM->mat[0] * pM->mat[5] * pM->mat[10] -
pM->mat[0] * pM->mat[6] * pM->mat[9] -
pM->mat[4] * pM->mat[1] * pM->mat[10] +
pM->mat[4] * pM->mat[2] * pM->mat[9] +
pM->mat[8] * pM->mat[1] * pM->mat[6] -
pM->mat[8] * pM->mat[2] * pM->mat[5];
det = pM->mat[0] * tmp.mat[0] + pM->mat[1] * tmp.mat[4] + pM->mat[2] * tmp.mat[8] + pM->mat[3] * tmp.mat[12];
if (det == 0) {
return NULL;
}
det = 1.0 / det;
for (i = 0; i < 16; i++) {
pOut->mat[i] = tmp.mat[i] * det;
}
return pOut;
}
/**
* Returns KM_TRUE if pIn is an identity matrix
* KM_FALSE otherwise
*/
int kmMat4IsIdentity(const kmMat4* pIn)
{
static kmScalar identity [] = { 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
return (memcmp(identity, pIn->mat, sizeof(kmScalar) * 16) == 0);
}
/**
* Sets pOut to the transpose of pIn, returns pOut
*/
kmMat4* kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn)
{
int x, z;
for (z = 0; z < 4; ++z) {
for (x = 0; x < 4; ++x) {
pOut->mat[(z * 4) + x] = pIn->mat[(x * 4) + z];
}
}
return pOut;
}
/**
* Multiplies pM1 with pM2, stores the result in pOut, returns pOut
*/
kmMat4* kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2)
{
#if defined(__ARM_NEON__) && !defined(__arm64__)
// It is possible to skip the memcpy() since "out" does not overwrite p1 or p2.
// otherwise a temp must be needed.
float *mat = pOut->mat;
// Invert column-order with row-order
NEON_Matrix4Mul( &pM2->mat[0], &pM1->mat[0], &mat[0] );
#else
kmScalar mat[16];
const kmScalar *m1 = pM1->mat, *m2 = pM2->mat;
mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];
mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];
mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];
mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];
mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];
mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];
mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];
mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];
mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];
mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];
mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];
mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];
mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];
mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
memcpy(pOut->mat, mat, sizeof(kmScalar)*16);
#endif
return pOut;
}
/**
* Assigns the value of pIn to pOut
*/
kmMat4* kmMat4Assign(kmMat4* pOut, const kmMat4* pIn)
{
assert(pOut != pIn && "You have tried to self-assign!!");
memcpy(pOut->mat, pIn->mat, sizeof(kmScalar)*16);
return pOut;
}
kmMat4* kmMat4AssignMat3(kmMat4* pOut, const kmMat3* pIn) {
kmMat4Identity(pOut);
pOut->mat[0] = pIn->mat[0];
pOut->mat[1] = pIn->mat[1];
pOut->mat[2] = pIn->mat[2];
pOut->mat[3] = 0.0;
pOut->mat[4] = pIn->mat[3];
pOut->mat[5] = pIn->mat[4];
pOut->mat[6] = pIn->mat[5];
pOut->mat[7] = 0.0;
pOut->mat[8] = pIn->mat[6];
pOut->mat[9] = pIn->mat[7];
pOut->mat[10] = pIn->mat[8];
pOut->mat[11] = 0.0;
return pOut;
}
/**
* Returns KM_TRUE if the 2 matrices are equal (approximately)
*/
int kmMat4AreEqual(const kmMat4* pMat1, const kmMat4* pMat2)
{
int i = 0;
assert(pMat1 != pMat2 && "You are comparing the same thing!");
for (i = 0; i < 16; ++i)
{
if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] &&
pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) {
return KM_FALSE;
}
}
return KM_TRUE;
}
/**
* Build a rotation matrix from an axis and an angle. Result is stored in pOut.
* pOut is returned.
*/
kmMat4* kmMat4RotationAxisAngle(kmMat4* pOut, const kmVec3* axis, kmScalar radians)
{
kmQuaternion quat;
kmQuaternionRotationAxisAngle(&quat, axis, radians);
kmMat4RotationQuaternion(pOut, &quat);
return pOut;
}
/**
* Builds an X-axis rotation matrix and stores it in pOut, returns pOut
*/
kmMat4* kmMat4RotationX(kmMat4* pOut, const kmScalar radians)
{
/*
| 1 0 0 0 |
M = | 0 cos(A) -sin(A) 0 |
| 0 sin(A) cos(A) 0 |
| 0 0 0 1 |
*/
pOut->mat[0] = 1.0f;
pOut->mat[1] = 0.0f;
pOut->mat[2] = 0.0f;
pOut->mat[3] = 0.0f;
pOut->mat[4] = 0.0f;
pOut->mat[5] = cosf(radians);
pOut->mat[6] = sinf(radians);
pOut->mat[7] = 0.0f;
pOut->mat[8] = 0.0f;
pOut->mat[9] = -sinf(radians);
pOut->mat[10] = cosf(radians);
pOut->mat[11] = 0.0f;
pOut->mat[12] = 0.0f;
pOut->mat[13] = 0.0f;
pOut->mat[14] = 0.0f;
pOut->mat[15] = 1.0f;
return pOut;
}
/**
* Builds a rotation matrix using the rotation around the Y-axis
* The result is stored in pOut, pOut is returned.
*/
kmMat4* kmMat4RotationY(kmMat4* pOut, const kmScalar radians)
{
/*
| cos(A) 0 sin(A) 0 |
M = | 0 1 0 0 |
| -sin(A) 0 cos(A) 0 |
| 0 0 0 1 |
*/
pOut->mat[0] = cosf(radians);
pOut->mat[1] = 0.0f;
pOut->mat[2] = -sinf(radians);
pOut->mat[3] = 0.0f;
pOut->mat[4] = 0.0f;
pOut->mat[5] = 1.0f;
pOut->mat[6] = 0.0f;
pOut->mat[7] = 0.0f;
pOut->mat[8] = sinf(radians);
pOut->mat[9] = 0.0f;
pOut->mat[10] = cosf(radians);
pOut->mat[11] = 0.0f;
pOut->mat[12] = 0.0f;
pOut->mat[13] = 0.0f;
pOut->mat[14] = 0.0f;
pOut->mat[15] = 1.0f;
return pOut;
}
/**
* Builds a rotation matrix around the Z-axis. The resulting
* matrix is stored in pOut. pOut is returned.
*/
kmMat4* kmMat4RotationZ(kmMat4* pOut, const kmScalar radians)
{
/*
| cos(A) -sin(A) 0 0 |
M = | sin(A) cos(A) 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
*/
pOut->mat[0] = cosf(radians);
pOut->mat[1] = sinf(radians);
pOut->mat[2] = 0.0f;
pOut->mat[3] = 0.0f;
pOut->mat[4] = -sinf(radians);
pOut->mat[5] = cosf(radians);
pOut->mat[6] = 0.0f;
pOut->mat[7] = 0.0f;
pOut->mat[8] = 0.0f;
pOut->mat[9] = 0.0f;
pOut->mat[10] = 1.0f;
pOut->mat[11] = 0.0f;
pOut->mat[12] = 0.0f;
pOut->mat[13] = 0.0f;
pOut->mat[14] = 0.0f;
pOut->mat[15] = 1.0f;
return pOut;
}
/**
* Builds a rotation matrix from pitch, yaw and roll. The resulting
* matrix is stored in pOut and pOut is returned
*/
kmMat4* kmMat4RotationYawPitchRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll)
{
kmMat4 yaw_matrix;
kmMat4RotationY(&yaw_matrix, yaw);
kmMat4 pitch_matrix;
kmMat4RotationX(&pitch_matrix, pitch);
kmMat4 roll_matrix;
kmMat4RotationZ(&roll_matrix, roll);
kmMat4Multiply(pOut, &pitch_matrix, &roll_matrix);
kmMat4Multiply(pOut, &yaw_matrix, pOut);
return pOut;
}
/** Converts a quaternion to a rotation matrix,
* the result is stored in pOut, returns pOut
*/
kmMat4* kmMat4RotationQuaternion(kmMat4* pOut, const kmQuaternion* pQ)
{
double xx = pQ->x * pQ->x;
double xy = pQ->x * pQ->y;
double xz = pQ->x * pQ->z;
double xw = pQ->x * pQ->w;
double yy = pQ->y * pQ->y;
double yz = pQ->y * pQ->z;
double yw = pQ->y * pQ->w;
double zz = pQ->z * pQ->z;
double zw = pQ->z * pQ->w;
pOut->mat[0] = 1 - 2 * (yy + zz);
pOut->mat[1] = 2 * (xy + zw);
pOut->mat[2] = 2 * (xz - yw);
pOut->mat[3] = 0;
pOut->mat[4] = 2 * (xy - zw);
pOut->mat[5] = 1 - 2 * (xx + zz);
pOut->mat[6] = 2 * (yz + xw);
pOut->mat[7] = 0.0;
pOut->mat[8] = 2 * (xz + yw);
pOut->mat[9] = 2 * (yz - xw);
pOut->mat[10] = 1 - 2 * (xx + yy);
pOut->mat[11] = 0.0;
pOut->mat[12] = 0.0;
pOut->mat[13] = 0.0;
pOut->mat[14] = 0.0;
pOut->mat[15] = 1.0;
return pOut;
}
/** Builds a scaling matrix */
kmMat4* kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y,
kmScalar z)
{
memset(pOut->mat, 0, sizeof(kmScalar) * 16);
pOut->mat[0] = x;
pOut->mat[5] = y;
pOut->mat[10] = z;
pOut->mat[15] = 1.0f;
return pOut;
}
/**
* Builds a translation matrix. All other elements in the matrix
* will be set to zero except for the diagonal which is set to 1.0
*/
kmMat4* kmMat4Translation(kmMat4* pOut, const kmScalar x,
kmScalar y, const kmScalar z)
{
//FIXME: Write a test for this
memset(pOut->mat, 0, sizeof(kmScalar) * 16);
pOut->mat[0] = 1.0f;
pOut->mat[5] = 1.0f;
pOut->mat[10] = 1.0f;
pOut->mat[12] = x;
pOut->mat[13] = y;
pOut->mat[14] = z;
pOut->mat[15] = 1.0f;
return pOut;
}
/**
* Get the up vector from a matrix. pIn is the matrix you
* wish to extract the vector from. pOut is a pointer to the
* kmVec3 structure that should hold the resulting vector
*/
kmVec3* kmMat4GetUpVec3(kmVec3* pOut, const kmMat4* pIn)
{
kmVec3MultiplyMat4(pOut, &KM_VEC3_POS_Y, pIn);
kmVec3Normalize(pOut, pOut);
return pOut;
}
/** Extract the right vector from a 4x4 matrix. The result is
* stored in pOut. Returns pOut.
*/
kmVec3* kmMat4GetRightVec3(kmVec3* pOut, const kmMat4* pIn)
{
kmVec3MultiplyMat4(pOut, &KM_VEC3_POS_X, pIn);
kmVec3Normalize(pOut, pOut);
return pOut;
}
/**
* Extract the forward vector from a 4x4 matrix. The result is
* stored in pOut. Returns pOut.
*/
kmVec3* kmMat4GetForwardVec3RH(kmVec3* pOut, const kmMat4* pIn)
{
kmVec3MultiplyMat4(pOut, &KM_VEC3_NEG_Z, pIn);
kmVec3Normalize(pOut, pOut);
return pOut;
}
kmVec3* kmMat4GetForwardVec3LH(kmVec3* pOut, const kmMat4* pIn)
{
kmVec3MultiplyMat4(pOut, &KM_VEC3_POS_Z, pIn);
kmVec3Normalize(pOut, pOut);
return pOut;
}
/**
* Creates a perspective projection matrix in the
* same way as gluPerspective
*/
kmMat4* kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY,
kmScalar aspect, kmScalar zNear,
kmScalar zFar)
{
kmScalar r = kmDegreesToRadians(fovY / 2);
kmScalar deltaZ = zFar - zNear;
kmScalar s = sin(r);
kmScalar cotangent = 0;
if (deltaZ == 0 || s == 0 || aspect == 0) {
return NULL;
}
//cos(r) / sin(r) = cot(r)
cotangent = cos(r) / s;
kmMat4Identity(pOut);
pOut->mat[0] = cotangent / aspect;
pOut->mat[5] = cotangent;
pOut->mat[10] = -(zFar + zNear) / deltaZ;
pOut->mat[11] = -1;
pOut->mat[14] = -2 * zNear * zFar / deltaZ;
pOut->mat[15] = 0;
return pOut;
}
/** Creates an orthographic projection matrix like glOrtho */
kmMat4* kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left,
kmScalar right, kmScalar bottom,
kmScalar top, kmScalar nearVal,
kmScalar farVal)
{
kmScalar tx = -((right + left) / (right - left));
kmScalar ty = -((top + bottom) / (top - bottom));
kmScalar tz = -((farVal + nearVal) / (farVal - nearVal));
kmMat4Identity(pOut);
pOut->mat[0] = 2 / (right - left);
pOut->mat[5] = 2 / (top - bottom);
pOut->mat[10] = -2 / (farVal - nearVal);
pOut->mat[12] = tx;
pOut->mat[13] = ty;
pOut->mat[14] = tz;
return pOut;
}
/**
* Builds a translation matrix in the same way as gluLookAt()
* the resulting matrix is stored in pOut. pOut is returned.
*/
kmMat4* kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye,
const kmVec3* pCenter, const kmVec3* pUp)
{
kmVec3 f, up, s, u;
kmMat4 translate;
kmVec3Subtract(&f, pCenter, pEye);
kmVec3Normalize(&f, &f);
kmVec3Assign(&up, pUp);
kmVec3Normalize(&up, &up);
kmVec3Cross(&s, &f, &up);
kmVec3Normalize(&s, &s);
kmVec3Cross(&u, &s, &f);
kmVec3Normalize(&s, &s);
kmMat4Identity(pOut);
pOut->mat[0] = s.x;
pOut->mat[4] = s.y;
pOut->mat[8] = s.z;
pOut->mat[1] = u.x;
pOut->mat[5] = u.y;
pOut->mat[9] = u.z;
pOut->mat[2] = -f.x;
pOut->mat[6] = -f.y;
pOut->mat[10] = -f.z;
kmMat4Translation(&translate, -pEye->x, -pEye->y, -pEye->z);
kmMat4Multiply(pOut, pOut, &translate);
return pOut;
}
/**
* Extract a 3x3 rotation matrix from the input 4x4 transformation.
* Stores the result in pOut, returns pOut
*/
kmMat3* kmMat4ExtractRotation(kmMat3* pOut, const kmMat4* pIn)
{
pOut->mat[0] = pIn->mat[0];
pOut->mat[1] = pIn->mat[1];
pOut->mat[2] = pIn->mat[2];
pOut->mat[3] = pIn->mat[4];
pOut->mat[4] = pIn->mat[5];
pOut->mat[5] = pIn->mat[6];
pOut->mat[6] = pIn->mat[8];
pOut->mat[7] = pIn->mat[9];
pOut->mat[8] = pIn->mat[10];
return pOut;
}
/**
* Take the rotation from a 4x4 transformation matrix, and return it as an axis and an angle (in radians)
* returns the output axis.
*/
kmVec3* kmMat4RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn)
{
/*Surely not this easy?*/
kmQuaternion temp;
kmMat3 rotation;
kmMat4ExtractRotation(&rotation, pIn);
kmQuaternionRotationMatrix(&temp, &rotation);
kmQuaternionToAxisAngle(&temp, pAxis, radians);
return pAxis;
}
/** Build a 4x4 OpenGL transformation matrix using a 3x3 rotation matrix,
* and a 3d vector representing a translation. Assign the result to pOut,
* pOut is also returned.
*/
kmMat4* kmMat4RotationTranslation(kmMat4* pOut, const kmMat3* rotation, const kmVec3* translation)
{
pOut->mat[0] = rotation->mat[0];
pOut->mat[1] = rotation->mat[1];
pOut->mat[2] = rotation->mat[2];
pOut->mat[3] = 0.0f;
pOut->mat[4] = rotation->mat[3];
pOut->mat[5] = rotation->mat[4];
pOut->mat[6] = rotation->mat[5];
pOut->mat[7] = 0.0f;
pOut->mat[8] = rotation->mat[6];
pOut->mat[9] = rotation->mat[7];
pOut->mat[10] = rotation->mat[8];
pOut->mat[11] = 0.0f;
pOut->mat[12] = translation->x;
pOut->mat[13] = translation->y;
pOut->mat[14] = translation->z;
pOut->mat[15] = 1.0f;
return pOut;
}
kmPlane* kmMat4ExtractPlane(kmPlane* pOut, const kmMat4* pIn, const kmEnum plane)
{
kmScalar t = 1.0f;
switch(plane) {
case KM_PLANE_RIGHT:
pOut->a = pIn->mat[3] - pIn->mat[0];
pOut->b = pIn->mat[7] - pIn->mat[4];
pOut->c = pIn->mat[11] - pIn->mat[8];
pOut->d = pIn->mat[15] - pIn->mat[12];
break;
case KM_PLANE_LEFT:
pOut->a = pIn->mat[3] + pIn->mat[0];
pOut->b = pIn->mat[7] + pIn->mat[4];
pOut->c = pIn->mat[11] + pIn->mat[8];
pOut->d = pIn->mat[15] + pIn->mat[12];
break;
case KM_PLANE_BOTTOM:
pOut->a = pIn->mat[3] + pIn->mat[1];
pOut->b = pIn->mat[7] + pIn->mat[5];
pOut->c = pIn->mat[11] + pIn->mat[9];
pOut->d = pIn->mat[15] + pIn->mat[13];
break;
case KM_PLANE_TOP:
pOut->a = pIn->mat[3] - pIn->mat[1];
pOut->b = pIn->mat[7] - pIn->mat[5];
pOut->c = pIn->mat[11] - pIn->mat[9];
pOut->d = pIn->mat[15] - pIn->mat[13];
break;
case KM_PLANE_FAR:
pOut->a = pIn->mat[3] - pIn->mat[2];
pOut->b = pIn->mat[7] - pIn->mat[6];
pOut->c = pIn->mat[11] - pIn->mat[10];
pOut->d = pIn->mat[15] - pIn->mat[14];
break;
case KM_PLANE_NEAR:
pOut->a = pIn->mat[3] + pIn->mat[2];
pOut->b = pIn->mat[7] + pIn->mat[6];
pOut->c = pIn->mat[11] + pIn->mat[10];
pOut->d = pIn->mat[15] + pIn->mat[14];
break;
default:
assert(0 && "Invalid plane index");
}
t = sqrtf(pOut->a * pOut->a +
pOut->b * pOut->b +
pOut->c * pOut->c);
pOut->a /= t;
pOut->b /= t;
pOut->c /= t;
pOut->d /= t;
return pOut;
}

Просмотреть файл

@ -0,0 +1,98 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MAT4_H_INCLUDED
#define MAT4_H_INCLUDED
#include "CCPlatformMacros.h"
#include "utility.h"
struct kmVec3;
struct kmMat3;
struct kmQuaternion;
struct kmPlane;
/*
A 4x4 matrix
| 0 4 8 12 |
mat = | 1 5 9 13 |
| 2 6 10 14 |
| 3 7 11 15 |
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef struct kmMat4 {
kmScalar mat[16];
} kmMat4;
CC_DLL kmMat4* kmMat4Fill(kmMat4* pOut, const kmScalar* pMat);
CC_DLL kmMat4* kmMat4Identity(kmMat4* pOut);
CC_DLL kmMat4* kmMat4Inverse(kmMat4* pOut, const kmMat4* pM);
CC_DLL int kmMat4IsIdentity(const kmMat4* pIn);
CC_DLL kmMat4* kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn);
CC_DLL kmMat4* kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2);
CC_DLL kmMat4* kmMat4Assign(kmMat4* pOut, const kmMat4* pIn);
CC_DLL kmMat4* kmMat4AssignMat3(kmMat4* pOut, const struct kmMat3* pIn);
CC_DLL int kmMat4AreEqual(const kmMat4* pM1, const kmMat4* pM2);
CC_DLL kmMat4* kmMat4RotationX(kmMat4* pOut, const kmScalar radians);
CC_DLL kmMat4* kmMat4RotationY(kmMat4* pOut, const kmScalar radians);
CC_DLL kmMat4* kmMat4RotationZ(kmMat4* pOut, const kmScalar radians);
CC_DLL kmMat4* kmMat4RotationYawPitchRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll);
CC_DLL kmMat4* kmMat4RotationQuaternion(kmMat4* pOut, const struct kmQuaternion* pQ);
CC_DLL kmMat4* kmMat4RotationTranslation(kmMat4* pOut, const struct kmMat3* rotation, const struct kmVec3* translation);
CC_DLL kmMat4* kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
CC_DLL kmMat4* kmMat4Translation(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
CC_DLL struct kmVec3* kmMat4GetUpVec3(struct kmVec3* pOut, const kmMat4* pIn);
CC_DLL struct kmVec3* kmMat4GetRightVec3(struct kmVec3* pOut, const kmMat4* pIn);
CC_DLL struct kmVec3* kmMat4GetForwardVec3RH(struct kmVec3* pOut, const kmMat4* pIn);
CC_DLL struct kmVec3* kmMat4GetForwardVec3LH(struct kmVec3* pOut, const kmMat4* pIn);
CC_DLL kmMat4* kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY, kmScalar aspect, kmScalar zNear, kmScalar zFar);
CC_DLL kmMat4* kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left, kmScalar right, kmScalar bottom, kmScalar top, kmScalar nearVal, kmScalar farVal);
CC_DLL kmMat4* kmMat4LookAt(kmMat4* pOut, const struct kmVec3* pEye, const struct kmVec3* pCenter, const struct kmVec3* pUp);
CC_DLL kmMat4* kmMat4RotationAxisAngle(kmMat4* pOut, const struct kmVec3* axis, kmScalar radians);
CC_DLL struct kmMat3* kmMat4ExtractRotation(struct kmMat3* pOut, const kmMat4* pIn);
CC_DLL struct kmPlane* kmMat4ExtractPlane(struct kmPlane* pOut, const kmMat4* pIn, const kmEnum plane);
CC_DLL struct kmVec3* kmMat4RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn);
#ifdef __cplusplus
}
#endif
#endif /* MAT4_H_INCLUDED */

Просмотреть файл

@ -0,0 +1,254 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <stdlib.h>
#include "vec3.h"
#include "vec4.h"
#include "plane.h"
#include "mat4.h"
kmScalar kmPlaneDot(const kmPlane* pP, const kmVec4* pV)
{
//a*x + b*y + c*z + d*w
return (pP->a * pV->x +
pP->b * pV->y +
pP->c * pV->z +
pP->d * pV->w);
}
kmScalar kmPlaneDotCoord(const kmPlane* pP, const kmVec3* pV)
{
return (pP->a * pV->x +
pP->b * pV->y +
pP->c * pV->z + pP->d);
}
kmScalar kmPlaneDotNormal(const kmPlane* pP, const kmVec3* pV)
{
return (pP->a * pV->x +
pP->b * pV->y +
pP->c * pV->z);
}
kmPlane* kmPlaneFromNormalAndDistance(kmPlane* plane, const struct kmVec3* normal, const kmScalar dist) {
plane->a = normal->x;
plane->b = normal->y;
plane->c = normal->z;
plane->d = dist;
return plane;
}
kmPlane* kmPlaneFromPointAndNormal(kmPlane* pOut, const kmVec3* pPoint, const kmVec3* pNormal)
{
/*
Planea = Nx
Planeb = Ny
Planec = Nz
Planed = NP
*/
pOut->a = pNormal->x;
pOut->b = pNormal->y;
pOut->c = pNormal->z;
pOut->d = -kmVec3Dot(pNormal, pPoint);
return pOut;
}
/**
* Creates a plane from 3 points. The result is stored in pOut.
* pOut is returned.
*/
kmPlane* kmPlaneFromPoints(kmPlane* pOut, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3)
{
/*
v = (B A) × (C A)
n = 1|v| v
Outa = nx
Outb = ny
Outc = nz
Outd = nA
*/
kmVec3 n, v1, v2;
kmVec3Subtract(&v1, p2, p1); //Create the vectors for the 2 sides of the triangle
kmVec3Subtract(&v2, p3, p1);
kmVec3Cross(&n, &v1, &v2); //Use the cross product to get the normal
kmVec3Normalize(&n, &n); //Normalize it and assign to pOut->m_N
pOut->a = n.x;
pOut->b = n.y;
pOut->c = n.z;
pOut->d = kmVec3Dot(kmVec3Scale(&n, &n, -1.0), p1);
return pOut;
}
// Added by tlensing (http://icedcoffee-framework.org)
kmVec3* kmPlaneIntersectLine(kmVec3* pOut, const kmPlane* pP, const kmVec3* pV1, const kmVec3* pV2)
{
/*
n = (Planea, Planeb, Planec)
d = V U
Out = U d(Pd + nU)(dn) [iff dn 0]
*/
kmVec3 d; // direction from V1 to V2
kmVec3Subtract(&d, pV2, pV1); // Get the direction vector
kmVec3 n; // plane normal
n.x = pP->a;
n.y = pP->b;
n.z = pP->c;
kmVec3Normalize(&n, &n);
kmScalar nt = -(n.x * pV1->x + n.y * pV1->y + n.z * pV1->z + pP->d);
kmScalar dt = (n.x * d.x + n.y * d.y + n.z * d.z);
if (fabs(dt) < kmEpsilon) {
pOut = NULL;
return pOut; // line parallel or contained
}
kmScalar t = nt/dt;
pOut->x = pV1->x + d.x * t;
pOut->y = pV1->y + d.y * t;
pOut->z = pV1->z + d.z * t;
return pOut;
}
kmPlane* kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP)
{
kmVec3 n;
kmScalar l = 0;
if (!pP->a && !pP->b && !pP->c) {
pOut->a = pP->a;
pOut->b = pP->b;
pOut->c = pP->c;
pOut->d = pP->d;
return pOut;
}
n.x = pP->a;
n.y = pP->b;
n.z = pP->c;
l = 1.0f / kmVec3Length(&n); //Get 1/length
kmVec3Normalize(&n, &n); //Normalize the vector and assign to pOut
pOut->a = n.x;
pOut->b = n.y;
pOut->c = n.z;
pOut->d = pP->d * l; //Scale the D value and assign to pOut
return pOut;
}
kmPlane* kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s)
{
assert(0 && "Not implemented");
return NULL;
}
/**
* Returns POINT_INFRONT_OF_PLANE if pP is infront of pIn. Returns
* POINT_BEHIND_PLANE if it is behind. Returns POINT_ON_PLANE otherwise
*/
KM_POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const kmVec3* pP)
{
// This function will determine if a point is on, in front of, or behind
// the plane. First we store the dot product of the plane and the point.
kmScalar distance = pIn->a * pP->x + pIn->b * pP->y + pIn->c * pP->z + pIn->d;
// Simply put if the dot product is greater than 0 then it is infront of it.
// If it is less than 0 then it is behind it. And if it is 0 then it is on it.
if(distance > kmEpsilon) return POINT_INFRONT_OF_PLANE;
if(distance < -kmEpsilon) return POINT_BEHIND_PLANE;
return POINT_ON_PLANE;
}
kmPlane* kmPlaneExtractFromMat4(kmPlane* pOut, const struct kmMat4* pIn, kmInt row) {
int scale = (row < 0) ? -1 : 1;
row = abs(row) - 1;
pOut->a = pIn->mat[3] + scale * pIn->mat[row];
pOut->b = pIn->mat[7] + scale * pIn->mat[row + 4];
pOut->c = pIn->mat[11] + scale * pIn->mat[row + 8];
pOut->d = pIn->mat[15] + scale * pIn->mat[row + 12];
return kmPlaneNormalize(pOut, pOut);
}
kmVec3* kmPlaneGetIntersection(kmVec3* pOut, const kmPlane* p1, const kmPlane* p2, const kmPlane* p3) {
kmVec3 n1, n2, n3, cross;
kmVec3 r1, r2, r3;
double denom = 0;
kmVec3Fill(&n1, p1->a, p1->b, p1->c);
kmVec3Fill(&n2, p2->a, p2->b, p2->c);
kmVec3Fill(&n3, p3->a, p3->b, p3->c);
kmVec3Cross(&cross, &n2, &n3);
denom = kmVec3Dot(&n1, &cross);
if (kmAlmostEqual(denom, 0.0)) {
return NULL;
}
kmVec3Cross(&r1, &n2, &n3);
kmVec3Cross(&r2, &n3, &n1);
kmVec3Cross(&r3, &n1, &n2);
kmVec3Scale(&r1, &r1, -p1->d);
kmVec3Scale(&r2, &r2, p2->d);
kmVec3Scale(&r3, &r3, p3->d);
kmVec3Subtract(pOut, &r1, &r2);
kmVec3Subtract(pOut, pOut, &r3);
kmVec3Scale(pOut, pOut, 1.0 / denom);
//p = -d1 * ( n2.Cross ( n3 ) ) – d2 * ( n3.Cross ( n1 ) ) – d3 * ( n1.Cross ( n2 ) ) / denom;
return pOut;
}
kmPlane* kmPlaneFill(kmPlane* plane, kmScalar a, kmScalar b, kmScalar c, kmScalar d) {
plane->a = a;
plane->b = b;
plane->c = c;
plane->d = d;
return plane;
}

Просмотреть файл

@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define KM_PLANE_FAR 5
#include "CCPlatformMacros.h"
#include "utility.h"
struct kmVec3;
@ -41,28 +42,33 @@ struct kmVec4;
struct kmMat4;
typedef struct kmPlane {
kmScalar a, b, c, d;
kmScalar a, b, c, d;
} kmPlane;
#ifdef __cplusplus
extern "C" {
#endif
typedef enum POINT_CLASSIFICATION {
POINT_INFRONT_OF_PLANE = 0,
POINT_BEHIND_PLANE,
POINT_ON_PLANE,
} POINT_CLASSIFICATION;
typedef enum KM_POINT_CLASSIFICATION {
POINT_BEHIND_PLANE = -1,
POINT_ON_PLANE = 0,
POINT_INFRONT_OF_PLANE = 1
} KM_POINT_CLASSIFICATION;
CC_DLL const kmScalar kmPlaneDot(const kmPlane* pP, const struct kmVec4* pV);
CC_DLL const kmScalar kmPlaneDotCoord(const kmPlane* pP, const struct kmVec3* pV);
CC_DLL const kmScalar kmPlaneDotNormal(const kmPlane* pP, const struct kmVec3* pV);
CC_DLL kmPlane* const kmPlaneFromPointNormal(kmPlane* pOut, const struct kmVec3* pPoint, const struct kmVec3* pNormal);
CC_DLL kmPlane* const kmPlaneFromPoints(kmPlane* pOut, const struct kmVec3* p1, const struct kmVec3* p2, const struct kmVec3* p3);
CC_DLL kmVec3* const kmPlaneIntersectLine(struct kmVec3* pOut, const kmPlane* pP, const struct kmVec3* pV1, const struct kmVec3* pV2);
CC_DLL kmPlane* const kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP);
CC_DLL kmPlane* const kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s);
CC_DLL const POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const kmVec3* pP); /** Classifies a point against a plane */
CC_DLL kmPlane* kmPlaneFill(kmPlane* plane, float a, float b, float c, float d);
CC_DLL kmScalar kmPlaneDot(const kmPlane* pP, const struct kmVec4* pV);
CC_DLL kmScalar kmPlaneDotCoord(const kmPlane* pP, const struct kmVec3* pV);
CC_DLL kmScalar kmPlaneDotNormal(const kmPlane* pP, const struct kmVec3* pV);
CC_DLL kmPlane* kmPlaneFromNormalAndDistance(kmPlane* plane, const struct kmVec3* normal, const kmScalar dist);
CC_DLL kmPlane* kmPlaneFromPointAndNormal(kmPlane* pOut, const struct kmVec3* pPoint, const struct kmVec3* pNormal);
CC_DLL kmPlane* kmPlaneFromPoints(kmPlane* pOut, const struct kmVec3* p1, const struct kmVec3* p2, const struct kmVec3* p3);
CC_DLL struct kmVec3* kmPlaneIntersectLine(struct kmVec3* pOut, const kmPlane* pP, const struct kmVec3* pV1, const struct kmVec3* pV2);
CC_DLL kmPlane* kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP);
CC_DLL kmPlane* kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s);
CC_DLL KM_POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const struct kmVec3* pP); /** Classifys a point against a plane */
CC_DLL kmPlane* kmPlaneExtractFromMat4(kmPlane* pOut, const struct kmMat4* pIn, kmInt row);
CC_DLL struct kmVec3* kmPlaneGetIntersection(struct kmVec3* pOut, const kmPlane* p1, const kmPlane* p2, const kmPlane* p3);
#ifdef __cplusplus
}

Просмотреть файл

@ -0,0 +1,609 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <memory.h>
#include <string.h>
#include "mat4.h"
#include "utility.h"
#include "mat3.h"
#include "vec3.h"
#include "quaternion.h"
int kmQuaternionAreEqual(const kmQuaternion* p1, const kmQuaternion* p2) {
if ((p1->x < (p2->x + kmEpsilon) && p1->x > (p2->x - kmEpsilon)) &&
(p1->y < (p2->y + kmEpsilon) && p1->y > (p2->y - kmEpsilon)) &&
(p1->z < (p2->z + kmEpsilon) && p1->z > (p2->z - kmEpsilon)) &&
(p1->w < (p2->w + kmEpsilon) && p1->w > (p2->w - kmEpsilon))) {
return 1;
}
return 0;
}
kmQuaternion* kmQuaternionFill(kmQuaternion* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w) {
pOut->x = x;
pOut->y = y;
pOut->z = z;
pOut->w = w;
return pOut;
}
///< Returns the dot product of the 2 quaternions
kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2)
{
/* A dot B = B dot A = AtBt + AxBx + AyBy + AzBz */
return (q1->w * q2->w +
q1->x * q2->x +
q1->y * q2->y +
q1->z * q2->z);
}
///< Returns the exponential of the quaternion
kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn)
{
assert(0);
return pOut;
}
///< Makes the passed quaternion an identity quaternion
kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut)
{
pOut->x = 0.0;
pOut->y = 0.0;
pOut->z = 0.0;
pOut->w = 1.0;
return pOut;
}
///< Returns the inverse of the passed Quaternion
kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut,
const kmQuaternion* pIn)
{
kmScalar l = kmQuaternionLength(pIn);
if (fabs(l) < kmEpsilon)
{
pOut->x = 0.0;
pOut->y = 0.0;
pOut->z = 0.0;
pOut->w = 0.0;
return pOut;
}
pOut->x = -pIn->x;
pOut->y = -pIn->y;
pOut->z = -pIn->z;
pOut->w = pIn->w;
return pOut;
}
///< Returns true if the quaternion is an identity quaternion
int kmQuaternionIsIdentity(const kmQuaternion* pIn)
{
return (pIn->x == 0.0 && pIn->y == 0.0 && pIn->z == 0.0 &&
pIn->w == 1.0);
}
///< Returns the length of the quaternion
kmScalar kmQuaternionLength(const kmQuaternion* pIn)
{
return sqrt(kmQuaternionLengthSq(pIn));
}
///< Returns the length of the quaternion squared (prevents a sqrt)
kmScalar kmQuaternionLengthSq(const kmQuaternion* pIn)
{
return pIn->x * pIn->x + pIn->y * pIn->y + pIn->z * pIn->z + pIn->w * pIn->w;
}
///< Returns the natural logarithm
kmQuaternion* kmQuaternionLn(kmQuaternion* pOut,
const kmQuaternion* pIn)
{
/*
A unit quaternion, is defined by:
Q == (cos(theta), sin(theta) * v) where |v| = 1
The natural logarithm of Q is, ln(Q) = (0, theta * v)
*/
assert(0);
return pOut;
}
///< Multiplies 2 quaternions together
extern
kmQuaternion* kmQuaternionMultiply(kmQuaternion* pOut,
const kmQuaternion* qu1,
const kmQuaternion* qu2)
{
kmQuaternion tmp1, tmp2;
kmQuaternionAssign(&tmp1, qu1);
kmQuaternionAssign(&tmp2, qu2);
//Just aliasing
kmQuaternion* q1 = &tmp1;
kmQuaternion* q2 = &tmp2;
pOut->x = q1->w * q2->x + q1->x * q2->w + q1->y * q2->z - q1->z * q2->y;
pOut->y = q1->w * q2->y + q1->y * q2->w + q1->z * q2->x - q1->x * q2->z;
pOut->z = q1->w * q2->z + q1->z * q2->w + q1->x * q2->y - q1->y * q2->x;
pOut->w = q1->w * q2->w - q1->x * q2->x - q1->y * q2->y - q1->z * q2->z;
return pOut;
}
///< Normalizes a quaternion
kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut,
const kmQuaternion* pIn)
{
kmScalar length = kmQuaternionLength(pIn);
if (fabs(length) < kmEpsilon)
{
pOut->x = 0.0;
pOut->y = 0.0;
pOut->z = 0.0;
pOut->w = 0.0;
return pOut;
}
kmQuaternionFill(pOut,
pOut->x / length,
pOut->y / length,
pOut->z / length,
pOut->w / length
);
return pOut;
}
///< Rotates a quaternion around an axis
kmQuaternion* kmQuaternionRotationAxisAngle(kmQuaternion* pOut,
const kmVec3* pV,
kmScalar angle)
{
kmScalar rad = angle * 0.5f;
kmScalar scale = sinf(rad);
pOut->x = pV->x * scale;
pOut->y = pV->y * scale;
pOut->z = pV->z * scale;
pOut->w = cosf(rad);
kmQuaternionNormalize(pOut, pOut);
return pOut;
}
///< Creates a quaternion from a rotation matrix
kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut,
const kmMat3* pIn)
{
/*
Note: The OpenGL matrices are transposed from the description below
taken from the Matrix and Quaternion FAQ
if ( mat[0] > mat[5] && mat[0] > mat[10] ) { // Column 0:
S = sqrt( 1.0 + mat[0] - mat[5] - mat[10] ) * 2;
X = 0.25 * S;
Y = (mat[4] + mat[1] ) / S;
Z = (mat[2] + mat[8] ) / S;
W = (mat[9] - mat[6] ) / S;
} else if ( mat[5] > mat[10] ) { // Column 1:
S = sqrt( 1.0 + mat[5] - mat[0] - mat[10] ) * 2;
X = (mat[4] + mat[1] ) / S;
Y = 0.25 * S;
Z = (mat[9] + mat[6] ) / S;
W = (mat[2] - mat[8] ) / S;
} else { // Column 2:
S = sqrt( 1.0 + mat[10] - mat[0] - mat[5] ) * 2;
X = (mat[2] + mat[8] ) / S;
Y = (mat[9] + mat[6] ) / S;
Z = 0.25 * S;
W = (mat[4] - mat[1] ) / S;
}
*/
kmScalar x, y, z, w;
kmScalar *pMatrix = NULL;
kmScalar m4x4[16] = {0};
kmScalar scale = 0.0f;
kmScalar diagonal = 0.0f;
if(!pIn) {
return NULL;
}
/* 0 3 6
1 4 7
2 5 8
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15*/
m4x4[0] = pIn->mat[0];
m4x4[1] = pIn->mat[3];
m4x4[2] = pIn->mat[6];
m4x4[4] = pIn->mat[1];
m4x4[5] = pIn->mat[4];
m4x4[6] = pIn->mat[7];
m4x4[8] = pIn->mat[2];
m4x4[9] = pIn->mat[5];
m4x4[10] = pIn->mat[8];
m4x4[15] = 1;
pMatrix = &m4x4[0];
diagonal = pMatrix[0] + pMatrix[5] + pMatrix[10] + 1;
if(diagonal > kmEpsilon) {
// Calculate the scale of the diagonal
scale = (kmScalar)sqrt(diagonal ) * 2;
// Calculate the x, y, x and w of the quaternion through the respective equation
x = ( pMatrix[9] - pMatrix[6] ) / scale;
y = ( pMatrix[2] - pMatrix[8] ) / scale;
z = ( pMatrix[4] - pMatrix[1] ) / scale;
w = 0.25f * scale;
}
else
{
// If the first element of the diagonal is the greatest value
if ( pMatrix[0] > pMatrix[5] && pMatrix[0] > pMatrix[10] )
{
// Find the scale according to the first element, and double that value
scale = (kmScalar)sqrt( 1.0f + pMatrix[0] - pMatrix[5] - pMatrix[10] ) * 2.0f;
// Calculate the x, y, x and w of the quaternion through the respective equation
x = 0.25f * scale;
y = (pMatrix[4] + pMatrix[1] ) / scale;
z = (pMatrix[2] + pMatrix[8] ) / scale;
w = (pMatrix[9] - pMatrix[6] ) / scale;
}
// Else if the second element of the diagonal is the greatest value
else if (pMatrix[5] > pMatrix[10])
{
// Find the scale according to the second element, and double that value
scale = (kmScalar)sqrt( 1.0f + pMatrix[5] - pMatrix[0] - pMatrix[10] ) * 2.0f;
// Calculate the x, y, x and w of the quaternion through the respective equation
x = (pMatrix[4] + pMatrix[1] ) / scale;
y = 0.25f * scale;
z = (pMatrix[9] + pMatrix[6] ) / scale;
w = (pMatrix[2] - pMatrix[8] ) / scale;
}
// Else the third element of the diagonal is the greatest value
else
{
// Find the scale according to the third element, and double that value
scale = (kmScalar)sqrt( 1.0f + pMatrix[10] - pMatrix[0] - pMatrix[5] ) * 2.0f;
// Calculate the x, y, x and w of the quaternion through the respective equation
x = (pMatrix[2] + pMatrix[8] ) / scale;
y = (pMatrix[9] + pMatrix[6] ) / scale;
z = 0.25f * scale;
w = (pMatrix[4] - pMatrix[1] ) / scale;
}
}
pOut->x = x;
pOut->y = y;
pOut->z = z;
pOut->w = w;
return pOut;
}
///< Create a quaternion from yaw, pitch and roll
kmQuaternion* kmQuaternionRotationPitchYawRoll(kmQuaternion* pOut,
kmScalar pitch,
kmScalar yaw,
kmScalar roll)
{
assert(pitch <= 2*kmPI);
assert(yaw <= 2*kmPI);
assert(roll <= 2*kmPI);
// Finds the Sin and Cosin for each half angles.
float sY = sinf(yaw * 0.5);
float cY = cosf(yaw * 0.5);
float sZ = sinf(roll * 0.5);
float cZ = cosf(roll * 0.5);
float sX = sinf(pitch * 0.5);
float cX = cosf(pitch * 0.5);
// Formula to construct a new Quaternion based on Euler Angles.
pOut->w = cY * cZ * cX - sY * sZ * sX;
pOut->x = sY * sZ * cX + cY * cZ * sX;
pOut->y = sY * cZ * cX + cY * sZ * sX;
pOut->z = cY * sZ * cX - sY * cZ * sX;
return pOut;
}
///< Interpolate between 2 quaternions
kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut,
const kmQuaternion* q1,
const kmQuaternion* q2,
kmScalar t)
{
kmScalar dot = kmQuaternionDot(q1, q2);
const double DOT_THRESHOLD = 0.9995;
if (dot > DOT_THRESHOLD) {
kmQuaternion diff;
kmQuaternionSubtract(&diff, q2, q1);
kmQuaternionScale(&diff, &diff, t);
kmQuaternionAdd(pOut, q1, &diff);
kmQuaternionNormalize(pOut, pOut);
return pOut;
}
dot = kmClamp(dot, -1, 1);
kmScalar theta_0 = acos(dot);
kmScalar theta = theta_0 * t;
kmQuaternion tmp;
kmQuaternionScale(&tmp, q1, dot);
kmQuaternionSubtract(&tmp, q2, &tmp);
kmQuaternionNormalize(&tmp, &tmp);
kmQuaternion t1, t2;
kmQuaternionScale(&t1, q1, cos(theta));
kmQuaternionScale(&t2, &tmp, sin(theta));
kmQuaternionAdd(pOut, &t1, &t2);
return pOut;
}
///< Get the axis and angle of rotation from a quaternion
void kmQuaternionToAxisAngle(const kmQuaternion* pIn,
kmVec3* pAxis,
kmScalar* pAngle)
{
kmScalar tempAngle; // temp angle
kmScalar scale; // temp vars
tempAngle = acosf(pIn->w);
scale = sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z));
if (((scale > -kmEpsilon) && scale < kmEpsilon)
|| (scale < 2*kmPI + kmEpsilon && scale > 2*kmPI - kmEpsilon)) // angle is 0 or 360 so just simply set axis to 0,0,1 with angle 0
{
*pAngle = 0.0f;
pAxis->x = 0.0f;
pAxis->y = 0.0f;
pAxis->z = 1.0f;
}
else
{
*pAngle = tempAngle * 2.0f; // angle in radians
pAxis->x = pIn->x / scale;
pAxis->y = pIn->y / scale;
pAxis->z = pIn->z / scale;
kmVec3Normalize(pAxis, pAxis);
}
}
kmQuaternion* kmQuaternionScale(kmQuaternion* pOut,
const kmQuaternion* pIn,
kmScalar s)
{
pOut->x = pIn->x * s;
pOut->y = pIn->y * s;
pOut->z = pIn->z * s;
pOut->w = pIn->w * s;
return pOut;
}
kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn)
{
memcpy(pOut, pIn, sizeof(kmScalar) * 4);
return pOut;
}
kmQuaternion* kmQuaternionSubtract(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2) {
pOut->x = pQ1->x - pQ2->x;
pOut->y = pQ1->y - pQ2->y;
pOut->z = pQ1->z - pQ2->z;
pOut->w = pQ1->w - pQ2->w;
return pOut;
}
kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2)
{
pOut->x = pQ1->x + pQ2->x;
pOut->y = pQ1->y + pQ2->y;
pOut->z = pQ1->z + pQ2->z;
pOut->w = pQ1->w + pQ2->w;
return pOut;
}
/** Adapted from the OGRE engine!
Gets the shortest arc quaternion to rotate this vector to the destination
vector.
@remarks
If you call this with a dest vector that is close to the inverse
of this vector, we will rotate 180 degrees around the 'fallbackAxis'
(if specified, or a generated axis if not) since in this case
ANY axis of rotation is valid.
*/
kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const kmVec3* vec1, const kmVec3* vec2, const kmVec3* fallback) {
kmVec3 v1, v2;
kmScalar a;
kmVec3Assign(&v1, vec1);
kmVec3Assign(&v2, vec2);
kmVec3Normalize(&v1, &v1);
kmVec3Normalize(&v2, &v2);
a = kmVec3Dot(&v1, &v2);
if (a >= 1.0) {
kmQuaternionIdentity(pOut);
return pOut;
}
if (a < (1e-6f - 1.0f)) {
if (fabs(kmVec3LengthSq(fallback)) < kmEpsilon) {
kmQuaternionRotationAxisAngle(pOut, fallback, kmPI);
} else {
kmVec3 axis;
kmVec3 X;
X.x = 1.0;
X.y = 0.0;
X.z = 0.0;
kmVec3Cross(&axis, &X, vec1);
//If axis is zero
if (fabs(kmVec3LengthSq(&axis)) < kmEpsilon) {
kmVec3 Y;
Y.x = 0.0;
Y.y = 1.0;
Y.z = 0.0;
kmVec3Cross(&axis, &Y, vec1);
}
kmVec3Normalize(&axis, &axis);
kmQuaternionRotationAxisAngle(pOut, &axis, kmPI);
}
} else {
kmScalar s = sqrtf((1+a) * 2);
kmScalar invs = 1 / s;
kmVec3 c;
kmVec3Cross(&c, &v1, &v2);
pOut->x = c.x * invs;
pOut->y = c.y * invs;
pOut->z = c.z * invs;
pOut->w = s * 0.5f;
kmQuaternionNormalize(pOut, pOut);
}
return pOut;
}
kmVec3* kmQuaternionMultiplyVec3(kmVec3* pOut, const kmQuaternion* q, const kmVec3* v) {
kmVec3 uv, uuv, qvec;
qvec.x = q->x;
qvec.y = q->y;
qvec.z = q->z;
kmVec3Cross(&uv, &qvec, v);
kmVec3Cross(&uuv, &qvec, &uv);
kmVec3Scale(&uv, &uv, (2.0f * q->w));
kmVec3Scale(&uuv, &uuv, 2.0f);
kmVec3Add(pOut, v, &uv);
kmVec3Add(pOut, pOut, &uuv);
return pOut;
}
kmVec3* kmQuaternionGetUpVec3(kmVec3* pOut, const kmQuaternion* pIn) {
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_Y);
}
kmVec3* kmQuaternionGetRightVec3(kmVec3* pOut, const kmQuaternion* pIn) {
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_X);
}
kmVec3* kmQuaternionGetForwardVec3RH(kmVec3* pOut, const kmQuaternion* pIn) {
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_NEG_Z);
}
kmVec3* kmQuaternionGetForwardVec3LH(kmVec3* pOut, const kmQuaternion* pIn) {
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_Z);
}
kmScalar kmQuaternionGetPitch(const kmQuaternion* q) {
float result = atan2(2 * (q->y * q->z + q->w * q->x), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z);
return result;
}
kmScalar kmQuaternionGetYaw(const kmQuaternion* q) {
float result = asin(-2 * (q->x * q->z - q->w * q->y));
return result;
}
kmScalar kmQuaternionGetRoll(const kmQuaternion* q) {
float result = atan2(2 * (q->x * q->y + q->w * q->z), q->w * q->w + q->x * q->x - q->y * q->y - q->z * q->z);
return result;
}
kmQuaternion* kmQuaternionLookRotation(kmQuaternion* pOut, const kmVec3* direction, const kmVec3* up) {
kmMat3 tmp;
kmMat3LookAt(&tmp, &KM_VEC3_ZERO, direction, up);
return kmQuaternionNormalize(pOut, kmQuaternionRotationMatrix(pOut, &tmp));
/*
if(!direction->x && !direction->y && !direction->z) {
return kmQuaternionIdentity(pOut);
}
kmVec3 right;
kmVec3Cross(&right, up, direction);
pOut->w = sqrtf(1.0f + right.x + up->y + direction->z) * 0.5f;
float w4_recip = 1.0f / (4.0f * pOut->w);
pOut->x = (up->z - direction->y) * w4_recip;
pOut->y = (direction->x - right.z) * w4_recip;
pOut->z = (right.y - up->x) * w4_recip;
return kmQuaternionNormalize(pOut, pOut);*/
}

Просмотреть файл

@ -30,7 +30,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
extern "C" {
#endif
#include "CCPlatformMacros.h"
#include "utility.h"
struct kmMat4;
@ -38,15 +37,15 @@ struct kmMat3;
struct kmVec3;
typedef struct kmQuaternion {
kmScalar x;
kmScalar y;
kmScalar z;
kmScalar w;
kmScalar x;
kmScalar y;
kmScalar z;
kmScalar w;
} kmQuaternion;
CC_DLL kmQuaternion* const kmQuaternionConjugate(kmQuaternion* pOut, const kmQuaternion* pIn); ///< Returns pOut, sets pOut to the conjugate of pIn
CC_DLL const kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2); ///< Returns the dot product of the 2 quaternions
CC_DLL int kmQuaternionAreEqual(const kmQuaternion* p1, const kmQuaternion* p2);
CC_DLL kmQuaternion* kmQuaternionFill(kmQuaternion* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w);
CC_DLL kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2); ///< Returns the dot product of the 2 quaternions
CC_DLL kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn); ///< Returns the exponential of the quaternion
@ -56,8 +55,7 @@ CC_DLL kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut);
///< Returns the inverse of the passed Quaternion
CC_DLL kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut,
const kmQuaternion* pIn);
CC_DLL kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut, const kmQuaternion* pIn);
///< Returns true if the quaternion is an identity quaternion
@ -85,7 +83,7 @@ CC_DLL kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut, const kmQuaternio
///< Rotates a quaternion around an axis
CC_DLL kmQuaternion* kmQuaternionRotationAxis(kmQuaternion* pOut, const struct kmVec3* pV, kmScalar angle);
CC_DLL kmQuaternion* kmQuaternionRotationAxisAngle(kmQuaternion* pOut, const struct kmVec3* pV, kmScalar angle);
///< Creates a quaternion from a rotation matrix
@ -93,7 +91,7 @@ CC_DLL kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut, const struct
///< Create a quaternion from yaw, pitch and roll
CC_DLL kmQuaternion* kmQuaternionRotationYawPitchRoll(kmQuaternion* pOut, kmScalar yaw, kmScalar pitch, kmScalar roll);
CC_DLL kmQuaternion* kmQuaternionRotationPitchYawRoll(kmQuaternion* pOut, kmScalar pitch, kmScalar yaw, kmScalar roll);
///< Interpolate between 2 quaternions
CC_DLL kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut, const kmQuaternion* q1, const kmQuaternion* q2, kmScalar t);
@ -104,9 +102,22 @@ CC_DLL void kmQuaternionToAxisAngle(const kmQuaternion* pIn, struct kmVec3* pVec
CC_DLL kmQuaternion* kmQuaternionScale(kmQuaternion* pOut, const kmQuaternion* pIn, kmScalar s);
CC_DLL kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn);
CC_DLL kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2);
CC_DLL kmQuaternion* kmQuaternionSubtract(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2);
CC_DLL kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const struct kmVec3* vec1, const struct kmVec3* vec2, const struct kmVec3* fallback);
CC_DLL struct kmVec3* kmQuaternionMultiplyVec3(struct kmVec3* pOut, const kmQuaternion* q, const struct kmVec3* v);
CC_DLL kmVec3* kmQuaternionGetUpVec3(kmVec3* pOut, const kmQuaternion* pIn);
CC_DLL kmVec3* kmQuaternionGetRightVec3(kmVec3* pOut, const kmQuaternion* pIn);
CC_DLL kmVec3* kmQuaternionGetForwardVec3RH(kmVec3* pOut, const kmQuaternion* pIn);
CC_DLL kmVec3* kmQuaternionGetForwardVec3LH(kmVec3* pOut, const kmQuaternion* pIn);
CC_DLL kmScalar kmQuaternionGetPitch(const kmQuaternion* q);
CC_DLL kmScalar kmQuaternionGetYaw(const kmQuaternion* q);
CC_DLL kmScalar kmQuaternionGetRoll(const kmQuaternion* q);
CC_DLL kmQuaternion* kmQuaternionLookRotation(kmQuaternion* pOut, const kmVec3* direction, const kmVec3* up);
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -0,0 +1,200 @@
#include <assert.h>
#include <stdio.h>
#include "ray2.h"
void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy) {
ray->start.x = px;
ray->start.y = py;
ray->dir.x = vx;
ray->dir.y = vy;
}
kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection) {
kmScalar x1 = ray->start.x;
kmScalar y1 = ray->start.y;
kmScalar x2 = ray->start.x + ray->dir.x;
kmScalar y2 = ray->start.y + ray->dir.y;
kmScalar x3 = p1->x;
kmScalar y3 = p1->y;
kmScalar x4 = p2->x;
kmScalar y4 = p2->y;
kmScalar denom = (y4 -y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
//If denom is zero, the lines are parallel
if(denom > -kmEpsilon && denom < kmEpsilon) {
return KM_FALSE;
}
kmScalar ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
kmScalar ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
kmScalar x = x1 + ua * (x2 - x1);
kmScalar y = y1 + ua * (y2 - y1);
if((0.0 <= ua) && (ua <= 1.0) && (0.0 <= ub) && (ub <= 1.0)) {
intersection->x = x;
intersection->y = y;
return KM_TRUE;
}
return KM_FALSE;
}
void calculate_line_normal(kmVec2 p1, kmVec2 p2, kmVec2 other_point, kmVec2* normal_out) {
/*
A = (3,4)
B = (2,1)
C = (1,3)
AB = (2,1) - (3,4) = (-1,-3)
AC = (1,3) - (3,4) = (-2,-1)
N = n(AB) = (-3,1)
D = dot(N,AC) = 6 + -1 = 5
since D > 0:
N = -N = (3,-1)
*/
kmVec2 edge, other_edge;
kmVec2Subtract(&edge, &p2, &p1);
kmVec2Subtract(&other_edge, &other_point, &p1);
kmVec2Normalize(&edge, &edge);
kmVec2Normalize(&other_edge, &other_edge);
kmVec2 n;
n.x = edge.y;
n.y = -edge.x;
kmScalar d = kmVec2Dot(&n, &other_edge);
if(d > 0.0f) {
n.x = -n.x;
n.y = -n.y;
}
normal_out->x = n.x;
normal_out->y = n.y;
kmVec2Normalize(normal_out, normal_out);
}
kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out, kmScalar* distance_out) {
kmVec2 intersect;
kmVec2 final_intersect;
kmVec2 normal;
kmScalar distance = 10000.0f;
kmBool intersected = KM_FALSE;
if(kmRay2IntersectLineSegment(ray, p1, p2, &intersect)) {
kmVec2 tmp;
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
kmVec2 this_normal;
calculate_line_normal(*p1, *p2, *p3, &this_normal);
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
final_intersect.x = intersect.x;
final_intersect.y = intersect.y;
distance = this_distance;
kmVec2Assign(&normal, &this_normal);
intersected = KM_TRUE;
}
}
if(kmRay2IntersectLineSegment(ray, p2, p3, &intersect)) {
kmVec2 tmp;
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
kmVec2 this_normal;
calculate_line_normal(*p2, *p3, *p1, &this_normal);
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
final_intersect.x = intersect.x;
final_intersect.y = intersect.y;
distance = this_distance;
kmVec2Assign(&normal, &this_normal);
intersected = KM_TRUE;
}
}
if(kmRay2IntersectLineSegment(ray, p3, p1, &intersect)) {
kmVec2 tmp;
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
kmVec2 this_normal;
calculate_line_normal(*p3, *p1, *p2, &this_normal);
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
final_intersect.x = intersect.x;
final_intersect.y = intersect.y;
distance = this_distance;
kmVec2Assign(&normal, &this_normal);
intersected = KM_TRUE;
}
}
if(intersected) {
intersection->x = final_intersect.x;
intersection->y = final_intersect.y;
if(normal_out) {
normal_out->x = normal.x;
normal_out->y = normal.y;
}
if(distance) {
*distance_out = distance;
}
}
return intersected;
}
kmBool kmRay2IntersectBox(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, const kmVec2* p4,
kmVec2* intersection, kmVec2* normal_out) {
kmBool intersected = KM_FALSE;
kmVec2 intersect, final_intersect, normal;
kmScalar distance = 10000.0f;
const kmVec2* points[4];
points[0] = p1;
points[1] = p2;
points[2] = p3;
points[3] = p4;
unsigned int i = 0;
for(; i < 4; ++i) {
const kmVec2* this_point = points[i];
const kmVec2* next_point = (i == 3) ? points[0] : points[i+1];
const kmVec2* other_point = (i == 3 || i == 0) ? points[1] : points[0];
if(kmRay2IntersectLineSegment(ray, this_point, next_point, &intersect)) {
kmVec2 tmp;
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
kmVec2 this_normal;
calculate_line_normal(*this_point, *next_point, *other_point, &this_normal);
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
kmVec2Assign(&final_intersect, &intersect);
distance = this_distance;
intersected = KM_TRUE;
kmVec2Assign(&normal, &this_normal);
}
}
}
if(intersected) {
intersection->x = final_intersect.x;
intersection->y = final_intersect.y;
if(normal_out) {
normal_out->x = normal.x;
normal_out->y = normal.y;
}
}
return intersected;
}
kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection) {
assert(0 && "Not implemented");
return KM_TRUE;
}

Просмотреть файл

@ -26,7 +26,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef RAY_2_H
#define RAY_2_H
#include "CCPlatformMacros.h"
#include "utility.h"
#include "vec2.h"
@ -41,7 +40,11 @@ typedef struct kmRay2 {
CC_DLL void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy);
CC_DLL kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection);
CC_DLL kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out);
CC_DLL kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out, kmScalar* distance);
CC_DLL kmBool kmRay2IntersectBox(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, const kmVec2* p4,
CC_DLL kmVec2* intersection, kmVec2* normal_out);
CC_DLL kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection);
#ifdef __cplusplus

Просмотреть файл

@ -0,0 +1,47 @@
#include "plane.h"
#include "ray3.h"
kmRay3* kmRay3Fill(kmRay3* ray, kmScalar px, kmScalar py, kmScalar pz, kmScalar vx, kmScalar vy, kmScalar vz) {
ray->start.x = px;
ray->start.y = py;
ray->start.z = pz;
ray->dir.x = vx;
ray->dir.y = vy;
ray->dir.z = vz;
return ray;
}
kmRay3* kmRay3FromPointAndDirection(kmRay3* ray, const kmVec3* point, const kmVec3* direction) {
kmVec3Assign(&ray->start, point);
kmVec3Assign(&ray->dir, direction);
return ray;
}
kmBool kmRay3IntersectPlane(kmVec3* pOut, const kmRay3* ray, const kmPlane* plane) {
//t = - (A*org.x + B*org.y + C*org.z + D) / (A*dir.x + B*dir.y + C*dir.z )
kmScalar d = (plane->a * ray->dir.x +
plane->b * ray->dir.y +
plane->c * ray->dir.z);
if(d == 0)
{
return KM_FALSE;
}
kmScalar t = -(plane->a * ray->start.x +
plane->b * ray->start.y +
plane->c * ray->start.z + plane->d) / d;
if(t < 0)
{
return KM_FALSE;
}
kmVec3 scaled_dir;
kmVec3Scale(&scaled_dir, &ray->dir, t);
kmVec3Add(pOut, &ray->start, &scaled_dir);
return KM_TRUE;
}

Просмотреть файл

@ -0,0 +1,26 @@
#ifndef RAY3_H
#define RAY3_H
#include "utility.h"
#include "vec3.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct kmRay3 {
kmVec3 start;
kmVec3 dir;
} kmRay3;
struct kmPlane;
CC_DLL kmRay3* kmRay3Fill(kmRay3* ray, kmScalar px, kmScalar py, kmScalar pz, kmScalar vx, kmScalar vy, kmScalar vz);
CC_DLL kmRay3* kmRay3FromPointAndDirection(kmRay3* ray, const kmVec3* point, const kmVec3* direction);
CC_DLL kmBool kmRay3IntersectPlane(kmVec3* pOut, const kmRay3* ray, const struct kmPlane* plane);
#ifdef __cplusplus
}
#endif
#endif // RAY3_H

Просмотреть файл

@ -23,27 +23,27 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "kazmath/utility.h"
#include "utility.h"
/**
* Returns the square of s (e.g. s*s)
*/
kmScalar kmSQR(kmScalar s) {
return s*s;
return s*s;
}
/**
* Returns degrees as radians.
*/
kmScalar kmDegreesToRadians(kmScalar degrees) {
return degrees * kmPIOver180;
return degrees * kmPIOver180;
}
/**
* Returns radians as degrees
*/
kmScalar kmRadiansToDegrees(kmScalar radians) {
return radians * kmPIUnder180;
return radians * kmPIUnder180;
}
kmScalar kmMin(kmScalar lhs, kmScalar rhs) {
@ -57,3 +57,13 @@ kmScalar kmMax(kmScalar lhs, kmScalar rhs) {
kmBool kmAlmostEqual(kmScalar lhs, kmScalar rhs) {
return (lhs + kmEpsilon > rhs && lhs - kmEpsilon < rhs);
}
kmScalar kmClamp(kmScalar x, kmScalar min, kmScalar max)
{
return x < min ? min : (x > max ? max : x);
}
kmScalar kmLerp(kmScalar x, kmScalar y, kmScalar t )
{
return x + t * ( y - x );
}

Просмотреть файл

@ -26,21 +26,37 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef UTILITY_H_INCLUDED
#define UTILITY_H_INCLUDED
#include "CCPlatformMacros.h"
#include <math.h>
#ifndef kmScalar
#ifdef USE_DOUBLE_PRECISION
#define kmScalar double
#else
#define kmScalar float
#endif
#endif
#ifndef kmBool
#define kmBool unsigned char
#endif
#ifndef kmUchar
#define kmUchar unsigned char
#endif
#ifndef kmEnum
#define kmEnum unsigned int
#endif
#ifndef kmUint
#define kmUint unsigned int
#endif
#ifndef kmInt
#define kmInt int
#endif
#ifndef KM_FALSE
#define KM_FALSE 0
#endif
@ -49,24 +65,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define KM_TRUE 1
#endif
#define kmPI 3.141592f
#define kmPIOver180 0.017453f // PI / 180
#define kmPIUnder180 57.295779f // 180 / PI
#define kmEpsilon 1.0 / 64.0
#define kmPI 3.14159265358979323846f
#define kmPIOver180 (kmPI / 180.0f)
#define kmPIUnder180 (180.0 / kmPI)
#define kmEpsilon 0.0001
#define KM_CONTAINS_NONE 0
#define KM_CONTAINS_PARTIAL 1
#define KM_CONTAINS_ALL 2
#ifdef __cplusplus
extern "C" {
#endif
CC_DLL kmScalar kmSQR(kmScalar s);
CC_DLL kmScalar kmDegreesToRadians(kmScalar degrees);
CC_DLL kmScalar kmRadiansToDegrees(kmScalar radians);
extern kmScalar kmSQR(kmScalar s);
extern kmScalar kmDegreesToRadians(kmScalar degrees);
extern kmScalar kmRadiansToDegrees(kmScalar radians);
CC_DLL kmScalar kmMin(kmScalar lhs, kmScalar rhs);
CC_DLL kmScalar kmMax(kmScalar lhs, kmScalar rhs);
CC_DLL kmBool kmAlmostEqual(kmScalar lhs, kmScalar rhs);
extern kmScalar kmMin(kmScalar lhs, kmScalar rhs);
extern kmScalar kmMax(kmScalar lhs, kmScalar rhs);
extern kmBool kmAlmostEqual(kmScalar lhs, kmScalar rhs);
extern kmScalar kmClamp(kmScalar x, kmScalar min, kmScalar max);
extern kmScalar kmLerp(kmScalar x, kmScalar y, kmScalar factor);
#ifdef __cplusplus
}

Просмотреть файл

@ -0,0 +1,239 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <stdlib.h>
#include "mat3.h"
#include "vec2.h"
#include "utility.h"
const kmVec2 KM_VEC2_POS_Y = { 0, 1 };
const kmVec2 KM_VEC2_NEG_Y = { 0, -1 };
const kmVec2 KM_VEC2_NEG_X = { -1, 0 };
const kmVec2 KM_VEC2_POS_X = { 1, 0 };
const kmVec2 KM_VEC2_ZERO = { 0, 0 };
kmVec2* kmVec2Fill(kmVec2* pOut, kmScalar x, kmScalar y)
{
pOut->x = x;
pOut->y = y;
return pOut;
}
kmScalar kmVec2Length(const kmVec2* pIn)
{
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y));
}
kmScalar kmVec2LengthSq(const kmVec2* pIn)
{
return kmSQR(pIn->x) + kmSQR(pIn->y);
}
kmVec2* kmVec2Lerp(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2, kmScalar t) {
pOut->x = pV1->x + t * ( pV2->x - pV1->x );
pOut->y = pV1->y + t * ( pV2->y - pV1->y );
return pOut;
}
kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn)
{
if (!pIn->x && !pIn->y)
return kmVec2Assign(pOut, pIn);
kmScalar l = 1.0f / kmVec2Length(pIn);
kmVec2 v;
v.x = pIn->x * l;
v.y = pIn->y * l;
pOut->x = v.x;
pOut->y = v.y;
return pOut;
}
kmVec2* kmVec2Add(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2)
{
pOut->x = pV1->x + pV2->x;
pOut->y = pV1->y + pV2->y;
return pOut;
}
kmScalar kmVec2Dot(const kmVec2* pV1, const kmVec2* pV2)
{
return pV1->x * pV2->x + pV1->y * pV2->y;
}
kmScalar kmVec2Cross(const kmVec2* pV1, const kmVec2* pV2)
{
return pV1->x * pV2->y - pV1->y * pV2->x;
}
kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2)
{
pOut->x = pV1->x - pV2->x;
pOut->y = pV1->y - pV2->y;
return pOut;
}
kmVec2* kmVec2Mul( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ) {
pOut->x = pV1->x * pV2->x;
pOut->y = pV1->y * pV2->y;
return pOut;
}
kmVec2* kmVec2Div( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ) {
if ( pV2->x && pV2->y ){
pOut->x = pV1->x / pV2->x;
pOut->y = pV1->y / pV2->y;
}
return pOut;
}
kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM)
{
kmVec2 v;
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[3] + pM->mat[6];
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[4] + pM->mat[7];
pOut->x = v.x;
pOut->y = v.y;
return pOut;
}
kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM)
{
assert(0);
return NULL;
}
kmVec2* kmVec2Scale(kmVec2* pOut, const kmVec2* pIn, const kmScalar s)
{
pOut->x = pIn->x * s;
pOut->y = pIn->y * s;
return pOut;
}
int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2)
{
return (
(p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) &&
(p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon)
);
}
/**
* Assigns pIn to pOut. Returns pOut. If pIn and pOut are the same
* then nothing happens but pOut is still returned
*/
kmVec2* kmVec2Assign(kmVec2* pOut, const kmVec2* pIn) {
if (pOut == pIn) {
return pOut;
}
pOut->x = pIn->x;
pOut->y = pIn->y;
return pOut;
}
/**
* Rotates the point anticlockwise around a center
* by an amount of degrees.
*
* Code ported from Irrlicht: http://irrlicht.sourceforge.net/
*/
kmVec2* kmVec2RotateBy(kmVec2* pOut, const kmVec2* pIn,
const kmScalar degrees, const kmVec2* center)
{
kmScalar x, y;
const kmScalar radians = kmDegreesToRadians(degrees);
const kmScalar cs = cosf(radians), sn = sinf(radians);
pOut->x = pIn->x - center->x;
pOut->y = pIn->y - center->y;
x = pOut->x * cs - pOut->y * sn;
y = pOut->x * sn + pOut->y * cs;
pOut->x = x + center->x;
pOut->y = y + center->y;
return pOut;
}
/**
* Returns the angle in degrees between the two vectors
*/
kmScalar kmVec2DegreesBetween(const kmVec2* v1, const kmVec2* v2) {
if(kmVec2AreEqual(v1, v2)) {
return 0.0;
}
kmVec2 t1, t2;
kmVec2Normalize(&t1, v1);
kmVec2Normalize(&t2, v2);
kmScalar cross = kmVec2Cross(&t1, &t2);
kmScalar dot = kmVec2Dot(&t1, &t2);
/*
* acos is only defined for -1 to 1. Outside the range we
* get NaN even if that's just because of a floating point error
* so we clamp to the -1 - 1 range
*/
if(dot > 1.0) dot = 1.0;
if(dot < -1.0) dot = -1.0;
return kmRadiansToDegrees(atan2(cross, dot));
}
/**
* Returns the distance between the two points
*/
kmScalar kmVec2DistanceBetween(const kmVec2* v1, const kmVec2* v2) {
kmVec2 diff;
kmVec2Subtract(&diff, v2, v1);
return fabs(kmVec2Length(&diff));
}
/**
* Returns the point mid-way between two others
*/
kmVec2* kmVec2MidPointBetween(kmVec2* pOut, const kmVec2* v1, const kmVec2* v2) {
kmVec2 sum;
kmVec2Add(&sum, v1, v2);
pOut->x = sum.x / 2.0f;
pOut->y = sum.y / 2.0f;
return pOut;
}

Просмотреть файл

@ -27,13 +27,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define VEC2_H_INCLUDED
#include "CCPlatformMacros.h"
#include "utility.h"
struct kmMat3;
#ifndef kmScalar
#define kmScalar float
#endif
#pragma pack(push) /* push current alignment to stack */
#pragma pack(1) /* set alignment to 1 byte boundary */
typedef struct kmVec2 {
@ -46,17 +43,33 @@ typedef struct kmVec2 {
#ifdef __cplusplus
extern "C" {
#endif
CC_DLL kmVec2* kmVec2Fill(kmVec2* pOut, kmScalar x, kmScalar y);
CC_DLL kmScalar kmVec2Length(const kmVec2* pIn); ///< Returns the length of the vector
CC_DLL kmScalar kmVec2LengthSq(const kmVec2* pIn); ///< Returns the square of the length of the vector
CC_DLL kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn); ///< Returns the vector passed in set to unit length
CC_DLL kmVec2* kmVec2Lerp(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2, kmScalar t);
CC_DLL kmVec2* kmVec2Add(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2); ///< Adds 2 vectors and returns the result
CC_DLL kmScalar kmVec2Dot(const kmVec2* pV1, const kmVec2* pV2); /** Returns the Dot product which is the cosine of the angle between the two vectors multiplied by their lengths */
CC_DLL kmScalar kmVec2Cross(const kmVec2* pV1, const kmVec2* pV2);
CC_DLL kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2); ///< Subtracts 2 vectors and returns the result
CC_DLL kmVec2* kmVec2Mul( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ); ///< Component-wise multiplication
CC_DLL kmVec2* kmVec2Div( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ); ///< Component-wise division
CC_DLL kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV1, const struct kmMat3* pM); /** Transform the Vector */
CC_DLL kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const struct kmMat3* pM); ///<Transforms a 2D vector by a given matrix, projecting the result back into w = 1.
CC_DLL kmVec2* kmVec2Scale(kmVec2* pOut, const kmVec2* pIn, const kmScalar s); ///< Scales a vector to length s
CC_DLL int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2); ///< Returns 1 if both vectors are equal
CC_DLL int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2); ///< Returns 1 if both vectors are equal
CC_DLL kmVec2* kmVec2Assign(kmVec2* pOut, const kmVec2* pIn);
CC_DLL kmVec2* kmVec2RotateBy(kmVec2* pOut, const kmVec2* pIn, const kmScalar degrees, const kmVec2* center); ///<Rotates the point anticlockwise around a center by an amount of degrees.
CC_DLL kmScalar kmVec2DegreesBetween(const kmVec2* v1, const kmVec2* v2);
CC_DLL kmScalar kmVec2DistanceBetween(const kmVec2* v1, const kmVec2* v2);
CC_DLL kmVec2* kmVec2MidPointBetween(kmVec2* pOut, const kmVec2* v1, const kmVec2* v2);
extern const kmVec2 KM_VEC2_POS_Y;
extern const kmVec2 KM_VEC2_NEG_Y;
extern const kmVec2 KM_VEC2_NEG_X;
extern const kmVec2 KM_VEC2_POS_X;
extern const kmVec2 KM_VEC2_ZERO;
#ifdef __cplusplus
}

Просмотреть файл

@ -0,0 +1,444 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file vec3.c
*/
#include <assert.h>
#include <memory.h>
#include "utility.h"
#include "vec4.h"
#include "mat4.h"
#include "mat3.h"
#include "vec3.h"
#include "plane.h"
#include "ray3.h"
const kmVec3 KM_VEC3_POS_Z = { 0, 0, 1 };
const kmVec3 KM_VEC3_NEG_Z = { 0, 0, -1 };
const kmVec3 KM_VEC3_POS_Y = { 0, 1, 0 };
const kmVec3 KM_VEC3_NEG_Y = { 0, -1, 0 };
const kmVec3 KM_VEC3_NEG_X = { -1, 0, 0 };
const kmVec3 KM_VEC3_POS_X = { 1, 0, 0 };
const kmVec3 KM_VEC3_ZERO = { 0, 0, 0 };
/**
* Fill a kmVec3 structure using 3 floating point values
* The result is store in pOut, returns pOut
*/
kmVec3* kmVec3Fill(kmVec3* pOut, kmScalar x, kmScalar y, kmScalar z)
{
pOut->x = x;
pOut->y = y;
pOut->z = z;
return pOut;
}
/**
* Returns the length of the vector
*/
kmScalar kmVec3Length(const kmVec3* pIn)
{
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z));
}
/**
* Returns the square of the length of the vector
*/
kmScalar kmVec3LengthSq(const kmVec3* pIn)
{
return kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z);
}
/// Returns the interpolation of 2 4D vectors based on t.
kmVec3* kmVec3Lerp(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2, kmScalar t) {
pOut->x = pV1->x + t * ( pV2->x - pV1->x );
pOut->y = pV1->y + t * ( pV2->y - pV1->y );
pOut->z = pV1->z + t * ( pV2->z - pV1->z );
return pOut;
}
/**
* Returns the vector passed in set to unit length
* the result is stored in pOut.
*/
kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn)
{
if (!pIn->x && !pIn->y && !pIn->z)
return kmVec3Assign(pOut, pIn);
kmScalar l = 1.0f / kmVec3Length(pIn);
kmVec3 v;
v.x = pIn->x * l;
v.y = pIn->y * l;
v.z = pIn->z * l;
pOut->x = v.x;
pOut->y = v.y;
pOut->z = v.z;
return pOut;
}
/**
* Returns a vector perpendicular to 2 other vectors.
* The result is stored in pOut.
*/
kmVec3* kmVec3Cross(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
{
kmVec3 v;
v.x = (pV1->y * pV2->z) - (pV1->z * pV2->y);
v.y = (pV1->z * pV2->x) - (pV1->x * pV2->z);
v.z = (pV1->x * pV2->y) - (pV1->y * pV2->x);
pOut->x = v.x;
pOut->y = v.y;
pOut->z = v.z;
return pOut;
}
/**
* Returns the cosine of the angle between 2 vectors
*/
kmScalar kmVec3Dot(const kmVec3* pV1, const kmVec3* pV2)
{
return ( pV1->x * pV2->x
+ pV1->y * pV2->y
+ pV1->z * pV2->z );
}
/**
* Adds 2 vectors and returns the result. The resulting
* vector is stored in pOut.
*/
kmVec3* kmVec3Add(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
{
kmVec3 v;
v.x = pV1->x + pV2->x;
v.y = pV1->y + pV2->y;
v.z = pV1->z + pV2->z;
pOut->x = v.x;
pOut->y = v.y;
pOut->z = v.z;
return pOut;
}
/**
* Subtracts 2 vectors and returns the result. The result is stored in
* pOut.
*/
kmVec3* kmVec3Subtract(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
{
kmVec3 v;
v.x = pV1->x - pV2->x;
v.y = pV1->y - pV2->y;
v.z = pV1->z - pV2->z;
pOut->x = v.x;
pOut->y = v.y;
pOut->z = v.z;
return pOut;
}
kmVec3* kmVec3Mul( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 ) {
pOut->x = pV1->x * pV2->x;
pOut->y = pV1->y * pV2->y;
pOut->z = pV1->z * pV2->z;
return pOut;
}
kmVec3* kmVec3Div( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 ) {
if ( pV2->x && pV2->y && pV2->z ){
pOut->x = pV1->x / pV2->x;
pOut->y = pV1->y / pV2->y;
pOut->z = pV1->z / pV2->z;
}
return pOut;
}
kmVec3* kmVec3MultiplyMat3(kmVec3* pOut, const kmVec3* pV, const kmMat3* pM) {
kmVec3 v;
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[3] + pV->z * pM->mat[6];
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[4] + pV->z * pM->mat[7];
v.z = pV->x * pM->mat[2] + pV->y * pM->mat[5] + pV->z * pM->mat[8];
pOut->x = v.x;
pOut->y = v.y;
pOut->z = v.z;
return pOut;
}
/**
* Multiplies vector (x, y, z, 1) by a given matrix. The result
* is stored in pOut. pOut is returned.
*/
kmVec3* kmVec3MultiplyMat4(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM) {
kmVec3 v;
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8] + pM->mat[12];
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9] + pM->mat[13];
v.z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10] + pM->mat[14];
pOut->x = v.x;
pOut->y = v.y;
pOut->z = v.z;
return pOut;
}
kmVec3* kmVec3Transform(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
{
/*
@deprecated Should intead use kmVec3MultiplyMat4
*/
return kmVec3MultiplyMat4(pOut, pV, pM);
}
kmVec3* kmVec3InverseTransform(kmVec3* pOut, const kmVec3* pVect, const kmMat4* pM)
{
kmVec3 v1, v2;
v1.x = pVect->x - pM->mat[12];
v1.y = pVect->y - pM->mat[13];
v1.z = pVect->z - pM->mat[14];
v2.x = v1.x * pM->mat[0] + v1.y * pM->mat[1] + v1.z * pM->mat[2];
v2.y = v1.x * pM->mat[4] + v1.y * pM->mat[5] + v1.z * pM->mat[6];
v2.z = v1.x * pM->mat[8] + v1.y * pM->mat[9] + v1.z * pM->mat[10];
pOut->x = v2.x;
pOut->y = v2.y;
pOut->z = v2.z;
return pOut;
}
kmVec3* kmVec3InverseTransformNormal(kmVec3* pOut, const kmVec3* pVect, const kmMat4* pM)
{
kmVec3 v;
v.x = pVect->x * pM->mat[0] + pVect->y * pM->mat[1] + pVect->z * pM->mat[2];
v.y = pVect->x * pM->mat[4] + pVect->y * pM->mat[5] + pVect->z * pM->mat[6];
v.z = pVect->x * pM->mat[8] + pVect->y * pM->mat[9] + pVect->z * pM->mat[10];
pOut->x = v.x;
pOut->y = v.y;
pOut->z = v.z;
return pOut;
}
kmVec3* kmVec3TransformCoord(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
{
/*
a = (Vx, Vy, Vz, 1)
b = (a×M)T
Out = 1bw(bx, by, bz)
*/
kmVec4 v;
kmVec4 inV;
kmVec4Fill(&inV, pV->x, pV->y, pV->z, 1.0);
kmVec4Transform(&v, &inV,pM);
pOut->x = v.x / v.w;
pOut->y = v.y / v.w;
pOut->z = v.z / v.w;
return pOut;
}
kmVec3* kmVec3TransformNormal(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
{
/*
a = (Vx, Vy, Vz, 0)
b = (a×M)T
Out = (bx, by, bz)
*/
//Omits the translation, only scaling + rotating
kmVec3 v;
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8];
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9];
v.z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10];
pOut->x = v.x;
pOut->y = v.y;
pOut->z = v.z;
return pOut;
}
/**
* Scales a vector to length s. Does not normalize first,
* you should do that!
*/
kmVec3* kmVec3Scale(kmVec3* pOut, const kmVec3* pIn, const kmScalar s)
{
pOut->x = pIn->x * s;
pOut->y = pIn->y * s;
pOut->z = pIn->z * s;
return pOut;
}
/**
* Returns KM_TRUE if the 2 vectors are approximately equal
*/
int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2)
{
if ((p1->x < (p2->x + kmEpsilon) && p1->x > (p2->x - kmEpsilon)) &&
(p1->y < (p2->y + kmEpsilon) && p1->y > (p2->y - kmEpsilon)) &&
(p1->z < (p2->z + kmEpsilon) && p1->z > (p2->z - kmEpsilon))) {
return 1;
}
return 0;
}
/**
* Assigns pIn to pOut. Returns pOut. If pIn and pOut are the same
* then nothing happens but pOut is still returned
*/
kmVec3* kmVec3Assign(kmVec3* pOut, const kmVec3* pIn) {
if (pOut == pIn) {
return pOut;
}
pOut->x = pIn->x;
pOut->y = pIn->y;
pOut->z = pIn->z;
return pOut;
}
/**
* Sets all the elements of pOut to zero. Returns pOut.
*/
kmVec3* kmVec3Zero(kmVec3* pOut) {
pOut->x = 0.0f;
pOut->y = 0.0f;
pOut->z = 0.0f;
return pOut;
}
/**
* Get the rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector.
* Useful for orienting vector towards a point.
*
* Returns a rotation vector containing the X (pitch) and Y (raw) rotations (in degrees) that when applied to a
* +Z (e.g. 0, 0, 1) direction vector would make it point in the same direction as this vector. The Z (roll) rotation
* is always 0, since two Euler rotations are sufficient to point in any given direction.
*
* Code ported from Irrlicht: http://irrlicht.sourceforge.net/
*/
kmVec3* kmVec3GetHorizontalAngle(kmVec3* pOut, const kmVec3 *pIn) {
const kmScalar z1 = sqrt(pIn->x * pIn->x + pIn->z * pIn->z);
pOut->y = kmRadiansToDegrees(atan2(pIn->x, pIn->z));
if (pOut->y < 0)
pOut->y += 360;
if (pOut->y >= 360)
pOut->y -= 360;
pOut->x = kmRadiansToDegrees(atan2(z1, pIn->y)) - 90.0;
if (pOut->x < 0)
pOut->x += 360;
if (pOut->x >= 360)
pOut->x -= 360;
return pOut;
}
/**
* Builds a direction vector from input vector.
* Input vector is assumed to be rotation vector composed from 3 Euler angle rotations, in degrees.
* The forwards vector will be rotated by the input vector
*
* Code ported from Irrlicht: http://irrlicht.sourceforge.net/
*/
kmVec3* kmVec3RotationToDirection(kmVec3* pOut, const kmVec3* pIn, const kmVec3* forwards)
{
const kmScalar xr = kmDegreesToRadians(pIn->x);
const kmScalar yr = kmDegreesToRadians(pIn->y);
const kmScalar zr = kmDegreesToRadians(pIn->z);
const kmScalar cr = cos(xr), sr = sin(xr);
const kmScalar cp = cos(yr), sp = sin(yr);
const kmScalar cy = cos(zr), sy = sin(zr);
const kmScalar srsp = sr*sp;
const kmScalar crsp = cr*sp;
const kmScalar pseudoMatrix[] = {
(cp*cy), (cp*sy), (-sp),
(srsp*cy-cr*sy), (srsp*sy+cr*cy), (sr*cp),
(crsp*cy+sr*sy), (crsp*sy-sr*cy), (cr*cp)
};
pOut->x = forwards->x * pseudoMatrix[0] +
forwards->y * pseudoMatrix[3] +
forwards->z * pseudoMatrix[6];
pOut->y = forwards->x * pseudoMatrix[1] +
forwards->y * pseudoMatrix[4] +
forwards->z * pseudoMatrix[7];
pOut->z = forwards->x * pseudoMatrix[2] +
forwards->y * pseudoMatrix[5] +
forwards->z * pseudoMatrix[8];
return pOut;
}
kmVec3* kmVec3ProjectOnToPlane(kmVec3* pOut, const kmVec3* point, const struct kmPlane* plane) {
kmRay3 ray;
kmVec3Assign(&ray.start, point);
ray.dir.x = -plane->a;
ray.dir.y = -plane->b;
ray.dir.z = -plane->c;
kmRay3IntersectPlane(pOut, &ray, plane);
return pOut;
}

Просмотреть файл

@ -27,18 +27,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define VEC3_H_INCLUDED
#include "CCPlatformMacros.h"
#include <assert.h>
#ifndef kmScalar
#define kmScalar float
#endif
#include <assert.h>
#include "utility.h"
struct kmMat4;
struct kmMat3;
struct kmPlane;
typedef struct kmVec3 {
kmScalar x;
kmScalar y;
kmScalar z;
kmScalar x;
kmScalar y;
kmScalar z;
} kmVec3;
#ifdef __cplusplus
@ -48,20 +48,40 @@ extern "C" {
CC_DLL kmVec3* kmVec3Fill(kmVec3* pOut, kmScalar x, kmScalar y, kmScalar z);
CC_DLL kmScalar kmVec3Length(const kmVec3* pIn); /** Returns the length of the vector */
CC_DLL kmScalar kmVec3LengthSq(const kmVec3* pIn); /** Returns the square of the length of the vector */
CC_DLL kmVec3* kmVec3Lerp(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2, kmScalar t);
CC_DLL kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn); /** Returns the vector passed in set to unit length */
CC_DLL kmVec3* kmVec3Cross(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Returns a vector perpendicular to 2 other vectors */
CC_DLL kmScalar kmVec3Dot(const kmVec3* pV1, const kmVec3* pV2); /** Returns the cosine of the angle between 2 vectors */
CC_DLL kmVec3* kmVec3Add(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Adds 2 vectors and returns the result */
CC_DLL kmVec3* kmVec3Subtract(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Subtracts 2 vectors and returns the result */
CC_DLL kmVec3* kmVec3Mul( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 );
CC_DLL kmVec3* kmVec3Div( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 );
CC_DLL kmVec3* kmVec3MultiplyMat3(kmVec3 *pOut, const kmVec3 *pV, const struct kmMat3* pM);
CC_DLL kmVec3* kmVec3MultiplyMat4(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);
CC_DLL kmVec3* kmVec3Transform(kmVec3* pOut, const kmVec3* pV1, const struct kmMat4* pM); /** Transforms a vector (assuming w=1) by a given matrix */
CC_DLL kmVec3* kmVec3TransformNormal(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);/**Transforms a 3D normal by a given matrix */
CC_DLL kmVec3* kmVec3TransformCoord(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM); /**Transforms a 3D vector by a given matrix, projecting the result back into w = 1. */
CC_DLL kmVec3* kmVec3Scale(kmVec3* pOut, const kmVec3* pIn, const kmScalar s); /** Scales a vector to length s */
CC_DLL int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2);
CC_DLL int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2);
CC_DLL kmVec3* kmVec3InverseTransform(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);
CC_DLL kmVec3* kmVec3InverseTransformNormal(kmVec3* pOut, const kmVec3* pVect, const struct kmMat4* pM);
CC_DLL kmVec3* kmVec3Assign(kmVec3* pOut, const kmVec3* pIn);
CC_DLL kmVec3* kmVec3Zero(kmVec3* pOut);
CC_DLL kmVec3* kmVec3GetHorizontalAngle(kmVec3* pOut, const kmVec3 *pIn); /** Get the rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector. */
CC_DLL kmVec3* kmVec3RotationToDirection(kmVec3* pOut, const kmVec3* pIn, const kmVec3* forwards); /** Builds a direction vector from input vector. */
CC_DLL kmVec3* kmVec3ProjectOnToPlane(kmVec3* pOut, const kmVec3* point, const struct kmPlane* plane);
extern const kmVec3 KM_VEC3_NEG_Z;
extern const kmVec3 KM_VEC3_POS_Z;
extern const kmVec3 KM_VEC3_POS_Y;
extern const kmVec3 KM_VEC3_NEG_Y;
extern const kmVec3 KM_VEC3_NEG_X;
extern const kmVec3 KM_VEC3_POS_X;
extern const kmVec3 KM_VEC3_ZERO;
#ifdef __cplusplus
}

Просмотреть файл

@ -27,9 +27,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory.h>
#include <assert.h>
#include "kazmath/utility.h"
#include "kazmath/vec4.h"
#include "kazmath/mat4.h"
#include "utility.h"
#include "vec4.h"
#include "mat4.h"
kmVec4* kmVec4Fill(kmVec4* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w)
@ -45,74 +45,98 @@ kmVec4* kmVec4Fill(kmVec4* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w)
/// Adds 2 4D vectors together. The result is store in pOut, the function returns
/// pOut so that it can be nested in another function.
kmVec4* kmVec4Add(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2) {
pOut->x = pV1->x + pV2->x;
pOut->y = pV1->y + pV2->y;
pOut->z = pV1->z + pV2->z;
pOut->w = pV1->w + pV2->w;
pOut->x = pV1->x + pV2->x;
pOut->y = pV1->y + pV2->y;
pOut->z = pV1->z + pV2->z;
pOut->w = pV1->w + pV2->w;
return pOut;
return pOut;
}
/// Returns the dot product of 2 4D vectors
kmScalar kmVec4Dot(const kmVec4* pV1, const kmVec4* pV2) {
return ( pV1->x * pV2->x
+ pV1->y * pV2->y
+ pV1->z * pV2->z
+ pV1->w * pV2->w );
return ( pV1->x * pV2->x
+ pV1->y * pV2->y
+ pV1->z * pV2->z
+ pV1->w * pV2->w );
}
/// Returns the length of a 4D vector, this uses a sqrt so if the squared length will do use
/// kmVec4LengthSq
kmScalar kmVec4Length(const kmVec4* pIn) {
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w));
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w));
}
/// Returns the length of the 4D vector squared.
kmScalar kmVec4LengthSq(const kmVec4* pIn) {
return kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w);
return kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w);
}
/// Returns the interpolation of 2 4D vectors based on t. Currently not implemented!
/// Returns the interpolation of 2 4D vectors based on t.
kmVec4* kmVec4Lerp(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2, kmScalar t) {
assert(0);
pOut->x = pV1->x + t * ( pV2->x - pV1->x );
pOut->y = pV1->y + t * ( pV2->y - pV1->y );
pOut->z = pV1->z + t * ( pV2->z - pV1->z );
pOut->w = pV1->w + t * ( pV2->w - pV1->w );
return pOut;
}
/// Normalizes a 4D vector. The result is stored in pOut. pOut is returned
kmVec4* kmVec4Normalize(kmVec4* pOut, const kmVec4* pIn) {
kmScalar l = 1.0f / kmVec4Length(pIn);
if (!pIn->x && !pIn->y && !pIn->z && !pIn->w){
return kmVec4Assign(pOut, pIn);
}
pOut->x *= l;
pOut->y *= l;
pOut->z *= l;
pOut->w *= l;
kmScalar l = 1.0f / kmVec4Length(pIn);
pOut->x = pIn->x * l;
pOut->y = pIn->y * l;
pOut->z = pIn->z * l;
pOut->w = pIn->w * l;
return pOut;
return pOut;
}
/// Scales a vector to the required length. This performs a Normalize before multiplying by S.
kmVec4* kmVec4Scale(kmVec4* pOut, const kmVec4* pIn, const kmScalar s) {
kmVec4Normalize(pOut, pIn);
kmVec4Normalize(pOut, pIn);
pOut->x *= s;
pOut->y *= s;
pOut->z *= s;
pOut->w *= s;
return pOut;
pOut->x *= s;
pOut->y *= s;
pOut->z *= s;
pOut->w *= s;
return pOut;
}
/// Subtracts one 4D pV2 from pV1. The result is stored in pOut. pOut is returned
kmVec4* kmVec4Subtract(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2) {
pOut->x = pV1->x - pV2->x;
pOut->y = pV1->y - pV2->y;
pOut->z = pV1->z - pV2->z;
pOut->w = pV1->w - pV2->w;
pOut->x = pV1->x - pV2->x;
pOut->y = pV1->y - pV2->y;
pOut->z = pV1->z - pV2->z;
pOut->w = pV1->w - pV2->w;
return pOut;
}
kmVec4* kmVec4Mul( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 ) {
pOut->x = pV1->x * pV2->x;
pOut->y = pV1->y * pV2->y;
pOut->z = pV1->z * pV2->z;
pOut->w = pV1->w * pV2->w;
return pOut;
}
/// Transforms a 4D vector by a matrix, the result is stored in pOut, and pOut is returned.
kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const kmMat4* pM) {
kmVec4* kmVec4Div( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 ) {
if ( pV2->x && pV2->y && pV2->z && pV2->w){
pOut->x = pV1->x / pV2->x;
pOut->y = pV1->y / pV2->y;
pOut->z = pV1->z / pV2->z;
pOut->w = pV1->w / pV2->w;
}
return pOut;
}
/// Multiplies a 4D vector by a matrix, the result is stored in pOut, and pOut is returned.
kmVec4* kmVec4MultiplyMat4(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM) {
pOut->x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8] + pV->w * pM->mat[12];
pOut->y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9] + pV->w * pM->mat[13];
pOut->z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10] + pV->w * pM->mat[14];
@ -120,9 +144,13 @@ kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const kmMat4* pM) {
return pOut;
}
kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const kmMat4* pM) {
return kmVec4MultiplyMat4(pOut, pV, pM);
}
/// Loops through an input array transforming each vec4 by the matrix.
kmVec4* kmVec4TransformArray(kmVec4* pOut, unsigned int outStride,
const kmVec4* pV, unsigned int vStride, const kmMat4* pM, unsigned int count) {
const kmVec4* pV, unsigned int vStride, const kmMat4* pM, unsigned int count) {
unsigned int i = 0;
//Go through all of the vectors
while (i < count) {
@ -136,19 +164,19 @@ kmVec4* kmVec4TransformArray(kmVec4* pOut, unsigned int outStride,
}
int kmVec4AreEqual(const kmVec4* p1, const kmVec4* p2) {
return (
(p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) &&
(p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon) &&
(p1->z < p2->z + kmEpsilon && p1->z > p2->z - kmEpsilon) &&
(p1->w < p2->w + kmEpsilon && p1->w > p2->w - kmEpsilon)
);
return (
(p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) &&
(p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon) &&
(p1->z < p2->z + kmEpsilon && p1->z > p2->z - kmEpsilon) &&
(p1->w < p2->w + kmEpsilon && p1->w > p2->w - kmEpsilon)
);
}
kmVec4* kmVec4Assign(kmVec4* pOut, const kmVec4* pIn) {
assert(pOut != pIn);
assert(pOut != pIn);
memcpy(pOut, pIn, sizeof(float) * 4);
memcpy(pOut, pIn, sizeof(kmScalar) * 4);
return pOut;
return pOut;
}

Просмотреть файл

@ -34,11 +34,12 @@ struct kmMat4;
#pragma pack(push) /* push current alignment to stack */
#pragma pack(1) /* set alignment to 1 byte boundary */
typedef struct kmVec4 {
kmScalar x;
kmScalar y;
kmScalar z;
kmScalar w;
typedef struct kmVec4
{
kmScalar x;
kmScalar y;
kmScalar z;
kmScalar w;
} kmVec4;
#pragma pack(pop)
@ -56,10 +57,14 @@ CC_DLL kmVec4* kmVec4Lerp(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2, km
CC_DLL kmVec4* kmVec4Normalize(kmVec4* pOut, const kmVec4* pIn);
CC_DLL kmVec4* kmVec4Scale(kmVec4* pOut, const kmVec4* pIn, const kmScalar s); ///< Scales a vector to length s
CC_DLL kmVec4* kmVec4Subtract(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2);
CC_DLL kmVec4* kmVec4Mul( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 );
CC_DLL kmVec4* kmVec4Div( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 );
CC_DLL kmVec4* kmVec4MultiplyMat4(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM);
CC_DLL kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM);
CC_DLL kmVec4* kmVec4TransformArray(kmVec4* pOut, unsigned int outStride,
const kmVec4* pV, unsigned int vStride, const struct kmMat4* pM, unsigned int count);
CC_DLL int kmVec4AreEqual(const kmVec4* p1, const kmVec4* p2);
const kmVec4* pV, unsigned int vStride, const struct kmMat4* pM, unsigned int count);
CC_DLL int kmVec4AreEqual(const kmVec4* p1, const kmVec4* p2);
CC_DLL kmVec4* kmVec4Assign(kmVec4* pOut, const kmVec4* pIn);
#ifdef __cplusplus

Просмотреть файл

@ -1,14 +0,0 @@
#ADD_LIBRARY(Kazmath STATIC ${KAZMATH_SRCS})
#INSTALL(TARGETS Kazmath ARCHIVE DESTINATION lib)
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/include )
ADD_LIBRARY(kazmath STATIC ${KAZMATH_SOURCES})
INSTALL(TARGETS kazmath ARCHIVE DESTINATION lib)
#ADD_LIBRARY(KazmathGL STATIC ${GL_UTILS_SRCS})
#INSTALL(TARGETS KazmathGL ARCHIVE DESTINATION lib)
INSTALL(FILES ${KAZMATH_HEADERS} DESTINATION include/kazmath)
INSTALL(FILES ${GL_UTILS_HEADERS} DESTINATION include/kazmath/GL)

Просмотреть файл

@ -1,738 +0,0 @@
------------------------------------------------------------
revno: 111
committer: Kazade <kazade@gmail.com>
branch nick: kazmath
timestamp: Thu 2010-08-19 12:07:29 +0100
message:
Fix #620352. Fix a reference to kmMat4RotationAxisAngle
------------------------------------------------------------
revno: 110
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Wed 2010-04-21 12:55:39 +0200
message:
applied the change to the header files as well
------------------------------------------------------------
revno: 109
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Wed 2010-04-21 12:54:06 +0200
message:
fixed kmMat4RotationAxis
------------------------------------------------------------
revno: 108 [merge]
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Wed 2010-04-21 12:27:53 +0200
message:
fixed CMake in kazmathxx due to missing utility.h
------------------------------------------------------------
revno: 107
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Wed 2010-04-21 12:22:40 +0200
message:
fixed mat4 rotation axis by normalizing the axis first
------------------------------------------------------------
revno: 106
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sat 2010-01-09 16:56:04 +0000
message:
Add cmake module
------------------------------------------------------------
revno: 105
committer: Luke Benstead <luke@Hydrogen>
branch nick: kazmath
timestamp: Sat 2010-01-09 16:23:31 +0000
message:
Remove kazmodel - it really should belong in its own repo
------------------------------------------------------------
revno: 104
committer: Luke Benstead <luke@Hydrogen>
branch nick: kazmath
timestamp: Fri 2010-01-08 23:03:13 +0000
message:
Reorganize the headers so that the tests can compile in place
------------------------------------------------------------
revno: 103
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Mon 2009-08-31 11:21:42 +0200
message:
Operators now inline, constructors fixed
------------------------------------------------------------
revno: 102
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Sat 2009-08-29 11:42:59 +0200
message:
fixed some compilation errors - still how do we define operators in headers correctly??
------------------------------------------------------------
revno: 101
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Wed 2009-08-26 10:37:52 +0100
message:
Added the header defines
------------------------------------------------------------
revno: 100
committer: Luke Benstead <luke@sidney>
branch nick: kazmath
timestamp: Wed 2009-08-26 09:38:47 +0100
message:
Added a V2 for kazmathxx
------------------------------------------------------------
revno: 99
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sun 2009-08-02 08:08:26 +0100
message:
Added missing header file to one of the tests
------------------------------------------------------------
revno: 98
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Sat 2009-08-01 12:05:25 +0200
message:
No longer doing self assignment in kmMat4Inverse
------------------------------------------------------------
revno: 97
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Sat 2009-08-01 11:15:36 +0200
message:
Fixed kmMat4Inverse
------------------------------------------------------------
revno: 96
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sat 2009-08-01 09:20:33 +0100
message:
Fixed some whitespace issues in plane.c
------------------------------------------------------------
revno: 95
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sat 2009-08-01 09:17:01 +0100
message:
Rename kmAABBPointInBox to kmAABBContainsPoint
------------------------------------------------------------
revno: 94
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sat 2009-08-01 09:16:28 +0100
message:
Implement kmAABBPointInBox
------------------------------------------------------------
revno: 93
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sat 2009-08-01 09:14:00 +0100
message:
Implement kmAABBAssign
------------------------------------------------------------
revno: 92
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sat 2009-08-01 09:10:36 +0100
message:
Fixed some whitespace and added some comments
------------------------------------------------------------
revno: 91
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sat 2009-08-01 08:56:13 +0100
message:
Implemented (untested) kmMat4RotationTranslation to construct a 4x4 matrix from a 3x3 + vec3
------------------------------------------------------------
revno: 90
committer: Luke Benstead <luke@hydrogen>
branch nick: kazmath
timestamp: Sun 2009-07-05 07:55:45 +0100
message:
Added kmMat3RotationX, kmMat3RotationY and kmMat3RotationZ
------------------------------------------------------------
revno: 89
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Sat 2009-06-27 09:38:20 +0200
message:
Fixed a crash?
------------------------------------------------------------
revno: 88
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Tue 2009-04-28 09:52:57 +0100
message:
Added a test for kmMat4Transpose
------------------------------------------------------------
revno: 87
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Tue 2009-04-28 08:49:59 +0100
message:
Added a commented test for kmMat4Inverse, however kmMat4Adjugate and kmMat4Determinate need implementing
------------------------------------------------------------
revno: 86
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Tue 2009-04-28 08:46:03 +0100
message:
Fixed bug in kmQuaternionRotationMatrix
------------------------------------------------------------
revno: 85
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Tue 2009-04-28 08:41:27 +0100
message:
Added missing include to test_mat3.cpp
------------------------------------------------------------
revno: 84
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 22:59:08 +0200
message:
fixed CMakeLists.txt for the tests
------------------------------------------------------------
revno: 83
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 21:34:20 +0100
message:
Added a test for kmMat3Translation
------------------------------------------------------------
revno: 82
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 21:32:19 +0100
message:
Fixed bugs in kmMat3Scaling and kmMat3Translation, added test for kmMat3Scaling
------------------------------------------------------------
revno: 81 [merge]
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 19:04:56 +0100
message:
Merge from upstream. Fixed mismatching prototype in quaternion.c
------------------------------------------------------------
revno: 80
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 19:01:35 +0100
message:
Added a test for kmMat3AreEqual. Fixed a bug in kmMat3AreEqual
------------------------------------------------------------
revno: 79
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 18:57:28 +0100
message:
Added a test for kmMat3IsIdentity
------------------------------------------------------------
revno: 78
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 18:54:48 +0100
message:
Added a test for kmMat3Identity
------------------------------------------------------------
revno: 77
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 18:52:14 +0100
message:
Added a test for kmMat3Fill
------------------------------------------------------------
revno: 76
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 18:46:30 +0100
message:
Added some mat3 unit tests. Fixed a bug in kmMat3AreEqual
------------------------------------------------------------
revno: 75
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 11:08:43 +0100
message:
Added mat4 test stub
------------------------------------------------------------
revno: 74
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 11:06:12 +0100
message:
Enabled unit testing in cmake
------------------------------------------------------------
revno: 73
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 10:44:37 +0100
message:
Added cmakelists.txt to the tests subfolder
------------------------------------------------------------
revno: 72
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 10:37:34 +0100
message:
Added stub mat3 test file
------------------------------------------------------------
revno: 71
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Mon 2009-04-27 10:35:48 +0100
message:
Added tests folder for new boost::unit based tests
------------------------------------------------------------
revno: 70
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Sun 2009-04-26 14:25:48 +0200
message:
Fixed the new quaternion -> Matrix -> AngleAxis methods and added them to mat4
------------------------------------------------------------
revno: 69
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sun 2009-04-26 12:40:08 +0100
message:
Added kazmodel to the kazlibs repo
------------------------------------------------------------
revno: 68 [merge]
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sun 2009-04-26 12:34:27 +0100
message:
Merge from upstream
------------------------------------------------------------
revno: 67
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sun 2009-04-26 12:33:43 +0100
message:
Reorganized bzr
------------------------------------------------------------
revno: 66
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sun 2009-04-26 10:00:18 +0100
message:
Renamed kmMat3RotationAxis to kmMat3RotationAxisAngle to be more accurate
------------------------------------------------------------
revno: 65
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sun 2009-04-26 09:57:19 +0100
message:
Fixed some compilation errors
------------------------------------------------------------
revno: 64
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sun 2009-04-26 09:54:12 +0100
message:
Added untested implementation of kmMat3RotationToAxisAngle
------------------------------------------------------------
revno: 63
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sun 2009-04-26 09:49:17 +0100
message:
Added stub for kmMat3RotationToAxisAngle()
------------------------------------------------------------
revno: 62
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sun 2009-04-26 09:45:58 +0100
message:
Corrected a typo
------------------------------------------------------------
revno: 61
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sun 2009-04-26 09:44:39 +0100
message:
Fixed broken Quaternion functions
Added (untested) kmMat3RotationAxis()
------------------------------------------------------------
revno: 60
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sat 2009-04-18 08:55:29 +0100
message:
Fixed some errors in the quaternion header.
Changed kmQuaternionRotationMatrix to accept a kmMat3 instead of kmMat4
------------------------------------------------------------
revno: 59
committer: Luke Benstead <kazade@gmail.com>
branch nick: kazmath
timestamp: Sat 2009-04-18 08:42:38 +0100
message:
Added kmMat3RotationQuaternion
------------------------------------------------------------
revno: 58
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Sun 2009-04-05 11:58:29 +0200
message:
Added mat3
------------------------------------------------------------
revno: 57 [merge]
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Sun 2009-04-05 11:54:15 +0200
message:
Implemented mat4 and vec4 for kazmathxx
------------------------------------------------------------
revno: 56
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Sun 2009-04-05 11:53:07 +0200
message:
Implemented mat4 and vec4 for kazmathxx
------------------------------------------------------------
revno: 55
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Fri 2009-03-13 16:46:26 +0100
message:
added km::vec3 to kazmathxx
------------------------------------------------------------
revno: 54
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Fri 2009-03-13 16:14:51 +0100
message:
Fixed: kmVec2 is no longer transformed by kmMat4\nAdded km::vec2
------------------------------------------------------------
revno: 53
committer: Carsten Haubld <carstenhaubold@googlemail.com>
branch nick: kazmath
timestamp: Fri 2009-03-13 15:38:53 +0100
message:
Added folder for kazmathxx
------------------------------------------------------------
revno: 52 [merge]
committer: Luke Benstead <kazade@gmail.com>
branch nick: trunk
timestamp: Fri 2009-03-13 14:04:32 +0000
message:
Merge from upstream
------------------------------------------------------------
revno: 51
committer: Luke Benstead <kazade@gmail.com>
branch nick: trunk
timestamp: Fri 2009-03-13 14:00:14 +0000
message:
Fixed for C89
------------------------------------------------------------
revno: 50
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
timestamp: Tue 2008-12-30 12:45:23 +0100
message:
fixed kmGLTranslate
------------------------------------------------------------
revno: 49
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
timestamp: Tue 2008-12-30 12:15:27 +0100
message:
fixed some stack memory leaks
------------------------------------------------------------
revno: 48
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
timestamp: Tue 2008-12-30 11:01:35 +0100
message:
The GL matrix stacks now work as expected - matrix multiplication was the wrong way round
------------------------------------------------------------
revno: 47
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
timestamp: Tue 2008-12-30 10:52:28 +0100
message:
Debug output
------------------------------------------------------------
revno: 46
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
timestamp: Mon 2008-12-29 18:32:13 +0100
message:
Fixed some compiler errors
------------------------------------------------------------
revno: 45
committer: Luke <kazade@gmail.com>
timestamp: Wed 2008-11-19 08:36:47 +0000
message:
Added kmGLTranslatef, kmGLScalef and kmGLRotatef
------------------------------------------------------------
revno: 44
committer: Luke <kazade@gmail.com>
timestamp: Tue 2008-11-04 20:57:30 +0000
message:
Fixed up kazmathxx
------------------------------------------------------------
revno: 43
committer: Luke <kazade@gmail.com>
timestamp: Wed 2008-10-29 09:24:32 +0000
message:
Started implementing C++ operators in kazmathxx.h
------------------------------------------------------------
revno: 42
committer: Luke <kazade@gmail.com>
timestamp: Tue 2008-10-28 18:21:16 +0000
message:
Added kazmathxx.h for C++ usage
------------------------------------------------------------
revno: 41
committer: Luke <kazade@gmail.com>
timestamp: Tue 2008-10-28 11:00:41 +0000
message:
Added Doxygen documentation
------------------------------------------------------------
revno: 40
committer: Luke <kazade@gmail.com>
timestamp: Tue 2008-10-28 08:46:19 +0000
message:
Began documenting the kmPlane functions.
Changed some assert(0)s to include a not implemented message
------------------------------------------------------------
revno: 39
committer: Luke <kazade@gmail.com>
timestamp: Tue 2008-10-28 08:42:24 +0000
message:
- Wrote stubs for the AABB functions which raise assertions if used.
- Documented the AABB functions
- Changed the definition of kmAABBPointInBox so that it actually makes sense
------------------------------------------------------------
revno: 38
committer: Luke <kazade@gmail.com>
timestamp: Tue 2008-10-28 08:38:48 +0000
message:
- Documented utility.c
------------------------------------------------------------
revno: 37
committer: Luke <kazade@gmail.com>
timestamp: Tue 2008-10-28 08:36:30 +0000
message:
- Documented vec3.c in detail.
- Fixed up a not-implemented assertion.
- Changed existing doc strings to C style - /** */
------------------------------------------------------------
revno: 36
committer: Luke <kazade@gmail.com>
timestamp: Tue 2008-10-28 08:30:00 +0000
message:
Removed uneccessary files from git
------------------------------------------------------------
revno: 35
committer: Luke <kazade@gmail.com>
timestamp: Tue 2008-10-28 08:28:49 +0000
message:
- Documented all the functions in mat4.c
- Fixed up all asserts in mat4.c to include a message
- Tidied up the code. Mat4.c is now done.
------------------------------------------------------------
revno: 34
committer: Luke <kazade@gmail.com>
timestamp: Mon 2008-10-27 21:52:33 +0000
message:
Added potential 0.1 release binary
------------------------------------------------------------
revno: 33
committer: Luke Benstead <kazade@gmail.com>
timestamp: Mon 2008-10-27 21:46:55 +0000
message:
Changed the README to include the BSD license
------------------------------------------------------------
revno: 32
committer: Luke Benstead <kazade@gmail.com>
timestamp: Mon 2008-10-27 21:45:51 +0000
message:
Added the modified BSD license to all source files
------------------------------------------------------------
revno: 31
committer: Luke Benstead <kazade@gmail.com>
timestamp: Mon 2008-10-27 21:11:51 +0000
message:
Fixed the installation of header files in CMake
------------------------------------------------------------
revno: 30
committer: Luke <kazade@gmail.com>
timestamp: Mon 2008-10-27 21:05:51 +0000
message:
Added kazmath project files
------------------------------------------------------------
revno: 29 [merge]
committer: Luke <kazade@gmail.com>
timestamp: Mon 2008-10-27 21:03:22 +0000
message:
Merge branch 'master' of git@github.com:Kazade/kazmath
------------------------------------------------------------
revno: 28
committer: Luke <kazade@gmail.com>
timestamp: Mon 2008-10-27 21:02:04 +0000
message:
Finally got kazmath compiling on VC++, man that compiler sucks! Have MS not heard of C99?
------------------------------------------------------------
revno: 27
committer: Luke Benstead <kazade@gmail.com>
timestamp: Sun 2008-10-26 21:35:24 +0000
message:
Changed the readme slightly, we need to change the license everywhere
------------------------------------------------------------
revno: 26
committer: Luke Benstead <kazade@gmail.com>
timestamp: Sun 2008-10-26 21:21:47 +0000
message:
Implemented the stacks test, fixed the undefined references I was getting
------------------------------------------------------------
revno: 25
committer: Luke Benstead <kazade@gmail.com>
timestamp: Sun 2008-10-26 20:59:34 +0000
message:
Removed the old matrix stack stuff
------------------------------------------------------------
revno: 24
committer: Luke Benstead <kazade@gmail.com>
timestamp: Sun 2008-10-26 20:11:58 +0000
message:
Started implementing the matrix stack tests
------------------------------------------------------------
revno: 23
committer: Luke Benstead <kazade@gmail.com>
timestamp: Sun 2008-10-26 10:56:51 +0000
message:
Started new implementation of the GL matrix stack
------------------------------------------------------------
revno: 22
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
timestamp: Thu 2008-08-28 12:37:41 +0200
message:
Added kmGLRotation
------------------------------------------------------------
revno: 21
committer: Luke Benstead <luke@helium.(none)>
timestamp: Thu 2008-08-28 09:24:00 +0100
message:
We now have a working matrix stack
------------------------------------------------------------
revno: 20
committer: Luke Benstead <luke@helium.(none)>
timestamp: Wed 2008-08-27 13:34:49 +0100
message:
Fixed the stack memory constants
------------------------------------------------------------
revno: 19
committer: Luke Benstead <luke@helium.(none)>
timestamp: Wed 2008-08-27 13:33:12 +0100
message:
Added the initial gl_utils implementation for replacing the matrix functionality deprecated in OpenGL 3.0
------------------------------------------------------------
revno: 18
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
timestamp: Mon 2008-08-25 12:46:16 +0200
message:
Fixed a bug in kmMat4LookAt
------------------------------------------------------------
revno: 17 [merge]
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
timestamp: Sun 2008-08-24 22:07:49 +0200
message:
Merge branch 'master' of git@github.com:Kazade/kazmath
------------------------------------------------------------
revno: 16
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
timestamp: Sun 2008-08-24 22:06:45 +0200
message:
Added kmMat4LookAt
------------------------------------------------------------
revno: 15
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
timestamp: Wed 2008-08-20 11:18:10 +0200
message:
Added Fill methods for all Vec and Mat structs
------------------------------------------------------------
revno: 14
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
timestamp: Tue 2008-08-19 22:31:55 +0200
message:
Added UnitTests, changed bool to int and fixed some minor bugs
------------------------------------------------------------
revno: 13
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
timestamp: Sun 2008-08-17 23:19:21 +0200
message:
removed .svn entries which did not belong here
------------------------------------------------------------
revno: 12
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
timestamp: Sun 2008-08-17 23:17:07 +0200
message:
some tweaks on matrices and first test-app, PerspectiveProjection is correct !
------------------------------------------------------------
revno: 11
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
timestamp: Sun 2008-08-17 16:04:09 +0200
message:
Renamed cotangent to cotangens
------------------------------------------------------------
revno: 10
committer: Luke Benstead <kazade@gmail.com>
timestamp: Sat 2008-08-16 21:51:22 +0100
message:
Added kmMat4PerspectiveProjection and kmMat4OrthographicProjection
------------------------------------------------------------
revno: 9
committer: Luke Benstead <kazade@gmail.com>
timestamp: Thu 2008-08-14 21:15:45 +0100
message:
Added the aabb struct
------------------------------------------------------------
revno: 8
committer: Luke Benstead <kazade@gmail.com>
timestamp: Thu 2008-08-14 17:57:43 +0100
message:
Added the kmAABB structure
------------------------------------------------------------
revno: 7
committer: Luke Benstead <kazade@gmail.com>
timestamp: Thu 2008-08-14 14:32:24 +0100
message:
Fixed broken kmMat3Transpose
------------------------------------------------------------
revno: 6
committer: Luke Benstead <kazade@gmail.com>
timestamp: Thu 2008-08-14 14:21:04 +0100
message:
Fixed broken kmMat4Translation, w component was not set
------------------------------------------------------------
revno: 5
committer: Luke Benstead <kazade@gmail.com>
timestamp: Thu 2008-08-14 14:01:47 +0100
message:
Added mat3.c and mat3.h to the cmake file
------------------------------------------------------------
revno: 4
committer: Luke Benstead <kazade@gmail.com>
timestamp: Thu 2008-08-14 13:56:26 +0100
message:
Added the authors section to the readme
------------------------------------------------------------
revno: 3
committer: Luke Benstead <kazade@gmail.com>
timestamp: Thu 2008-08-14 13:55:41 +0100
message:
Updated the readme file
------------------------------------------------------------
revno: 2
committer: Luke Benstead <kazade@gmail.com>
timestamp: Thu 2008-08-14 13:53:26 +0100
message:
Added kazmath to git
------------------------------------------------------------
revno: 1
committer: Luke Benstead <kazade@gmail.com>
timestamp: Thu 2008-08-14 13:47:51 +0100
message:
First commit
------------------------------------------------------------
Use --include-merges or -n0 to see merged revisions.

Просмотреть файл

@ -1,63 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "kazmath/aabb.h"
/**
* Returns KM_TRUE if point is in the specified AABB, returns
* KM_FALSE otherwise.
*/
const int kmAABBContainsPoint(const kmVec3* pPoint, const kmAABB* pBox)
{
if(pPoint->x >= pBox->min.x && pPoint->x <= pBox->max.x &&
pPoint->y >= pBox->min.y && pPoint->y <= pBox->max.y &&
pPoint->z >= pBox->min.z && pPoint->z <= pBox->max.z) {
return KM_TRUE;
}
return KM_FALSE;
}
/**
* Assigns pIn to pOut, returns pOut.
*/
kmAABB* const kmAABBAssign(kmAABB* pOut, const kmAABB* pIn)
{
kmVec3Assign(&pOut->min, &pIn->min);
kmVec3Assign(&pOut->max, &pIn->max);
return pOut;
}
/**
* Scales pIn by s, stores the resulting AABB in pOut. Returns pOut
*/
kmAABB* const kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s)
{
assert(0 && "Not implemented");
return 0;
}

Просмотреть файл

@ -1,372 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <memory.h>
#include <assert.h>
#include "kazmath/utility.h"
#include "kazmath/vec3.h"
#include "kazmath/mat3.h"
#include "kazmath/quaternion.h"
kmMat3* const kmMat3Fill(kmMat3* pOut, const kmScalar* pMat)
{
memcpy(pOut->mat, pMat, sizeof(kmScalar) * 9);
return pOut;
}
/** Sets pOut to an identity matrix returns pOut*/
kmMat3* const kmMat3Identity(kmMat3* pOut)
{
memset(pOut->mat, 0, sizeof(float) * 9);
pOut->mat[0] = pOut->mat[4] = pOut->mat[8] = 1.0f;
return pOut;
}
const kmScalar kmMat3Determinant(const kmMat3* pIn)
{
kmScalar output;
/*
calculating the determinant following the rule of sarus,
| 0 3 6 | 0 3 |
m = | 1 4 7 | 1 4 |
| 2 5 8 | 2 5 |
now sum up the products of the diagonals going to the right (i.e. 0,4,8)
and subtract the products of the other diagonals (i.e. 2,4,6)
*/
output = pIn->mat[0] * pIn->mat[4] * pIn->mat[8] + pIn->mat[1] * pIn->mat[5] * pIn->mat[6] + pIn->mat[2] * pIn->mat[3] * pIn->mat[7];
output -= pIn->mat[2] * pIn->mat[4] * pIn->mat[6] + pIn->mat[0] * pIn->mat[5] * pIn->mat[7] + pIn->mat[1] * pIn->mat[3] * pIn->mat[8];
return output;
}
kmMat3* const kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn)
{
pOut->mat[0] = pIn->mat[4] * pIn->mat[8] - pIn->mat[5] * pIn->mat[7];
pOut->mat[1] = pIn->mat[2] * pIn->mat[7] - pIn->mat[1] * pIn->mat[8];
pOut->mat[2] = pIn->mat[1] * pIn->mat[5] - pIn->mat[2] * pIn->mat[4];
pOut->mat[3] = pIn->mat[5] * pIn->mat[6] - pIn->mat[3] * pIn->mat[8];
pOut->mat[4] = pIn->mat[0] * pIn->mat[8] - pIn->mat[2] * pIn->mat[6];
pOut->mat[5] = pIn->mat[2] * pIn->mat[3] - pIn->mat[0] * pIn->mat[5];
pOut->mat[6] = pIn->mat[3] * pIn->mat[7] - pIn->mat[4] * pIn->mat[6];
// XXX: pIn->mat[9] is invalid!
// pOut->mat[7] = pIn->mat[1] * pIn->mat[6] - pIn->mat[9] * pIn->mat[7];
pOut->mat[8] = pIn->mat[0] * pIn->mat[4] - pIn->mat[1] * pIn->mat[3];
return pOut;
}
kmMat3* const kmMat3Inverse(kmMat3* pOut, const kmScalar pDeterminate, const kmMat3* pM)
{
kmScalar detInv;
kmMat3 adjugate;
if(pDeterminate == 0.0)
{
return NULL;
}
detInv = 1.0f / pDeterminate;
kmMat3Adjugate(&adjugate, pM);
kmMat3ScalarMultiply(pOut, &adjugate, detInv);
return pOut;
}
/** Returns true if pIn is an identity matrix */
const int kmMat3IsIdentity(const kmMat3* pIn)
{
static const float identity [] = { 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f};
return (memcmp(identity, pIn->mat, sizeof(float) * 9) == 0);
}
/** Sets pOut to the transpose of pIn, returns pOut */
kmMat3* const kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn)
{
int z, x;
for (z = 0; z < 3; ++z) {
for (x = 0; x < 3; ++x) {
pOut->mat[(z * 3) + x] = pIn->mat[(x * 3) + z];
}
}
return pOut;
}
/* Multiplies pM1 with pM2, stores the result in pOut, returns pOut */
kmMat3* const kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2)
{
float mat[9];
const float *m1 = pM1->mat, *m2 = pM2->mat;
mat[0] = m1[0] * m2[0] + m1[3] * m2[1] + m1[6] * m2[2];
mat[1] = m1[1] * m2[0] + m1[4] * m2[1] + m1[7] * m2[2];
mat[2] = m1[2] * m2[0] + m1[5] * m2[1] + m1[8] * m2[2];
mat[3] = m1[0] * m2[3] + m1[3] * m2[4] + m1[6] * m2[5];
mat[4] = m1[1] * m2[3] + m1[4] * m2[4] + m1[7] * m2[5];
mat[5] = m1[2] * m2[3] + m1[5] * m2[4] + m1[8] * m2[5];
mat[6] = m1[0] * m2[6] + m1[3] * m2[7] + m1[6] * m2[8];
mat[7] = m1[1] * m2[6] + m1[4] * m2[7] + m1[7] * m2[8];
mat[8] = m1[2] * m2[6] + m1[5] * m2[7] + m1[8] * m2[8];
memcpy(pOut->mat, mat, sizeof(float)*9);
return pOut;
}
kmMat3* const kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor)
{
float mat[9];
int i;
for(i = 0; i < 9; i++)
{
mat[i] = pM->mat[i] * pFactor;
}
memcpy(pOut->mat, mat, sizeof(float)*9);
return pOut;
}
/** Assigns the value of pIn to pOut */
kmMat3* const kmMat3Assign(kmMat3* pOut, const kmMat3* pIn)
{
assert(pOut != pIn); //You have tried to self-assign!!
memcpy(pOut->mat, pIn->mat, sizeof(float)*9);
return pOut;
}
/** Returns true if the 2 matrices are equal (approximately) */
const int kmMat3AreEqual(const kmMat3* pMat1, const kmMat3* pMat2)
{
int i;
if (pMat1 == pMat2) {
return KM_TRUE;
}
for (i = 0; i < 9; ++i) {
if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] &&
pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) {
return KM_FALSE;
}
}
return KM_TRUE;
}
/* Rotation around the z axis so everything stays planar in XY */
kmMat3* const kmMat3Rotation(kmMat3* pOut, const float radians)
{
/*
| cos(A) -sin(A) 0 |
M = | sin(A) cos(A) 0 |
| 0 0 1 |
*/
pOut->mat[0] = cosf(radians);
pOut->mat[1] = sinf(radians);
pOut->mat[2] = 0.0f;
pOut->mat[3] = -sinf(radians);;
pOut->mat[4] = cosf(radians);
pOut->mat[5] = 0.0f;
pOut->mat[6] = 0.0f;
pOut->mat[7] = 0.0f;
pOut->mat[8] = 1.0f;
return pOut;
}
/** Builds a scaling matrix */
kmMat3* const kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y)
{
// memset(pOut->mat, 0, sizeof(float) * 9);
kmMat3Identity(pOut);
pOut->mat[0] = x;
pOut->mat[4] = y;
return pOut;
}
kmMat3* const kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y)
{
// memset(pOut->mat, 0, sizeof(float) * 9);
kmMat3Identity(pOut);
pOut->mat[6] = x;
pOut->mat[7] = y;
// pOut->mat[8] = 1.0;
return pOut;
}
kmMat3* const kmMat3RotationQuaternion(kmMat3* pOut, const kmQuaternion* pIn)
{
if (!pIn || !pOut) {
return NULL;
}
// First row
pOut->mat[0] = 1.0f - 2.0f * (pIn->y * pIn->y + pIn->z * pIn->z);
pOut->mat[1] = 2.0f * (pIn->x * pIn->y - pIn->w * pIn->z);
pOut->mat[2] = 2.0f * (pIn->x * pIn->z + pIn->w * pIn->y);
// Second row
pOut->mat[3] = 2.0f * (pIn->x * pIn->y + pIn->w * pIn->z);
pOut->mat[4] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->z * pIn->z);
pOut->mat[5] = 2.0f * (pIn->y * pIn->z - pIn->w * pIn->x);
// Third row
pOut->mat[6] = 2.0f * (pIn->x * pIn->z - pIn->w * pIn->y);
pOut->mat[7] = 2.0f * (pIn->y * pIn->z + pIn->w * pIn->x);
pOut->mat[8] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->y * pIn->y);
return pOut;
}
kmMat3* const kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians)
{
float rcos = cosf(radians);
float rsin = sinf(radians);
pOut->mat[0] = rcos + axis->x * axis->x * (1 - rcos);
pOut->mat[1] = axis->z * rsin + axis->y * axis->x * (1 - rcos);
pOut->mat[2] = -axis->y * rsin + axis->z * axis->x * (1 - rcos);
pOut->mat[3] = -axis->z * rsin + axis->x * axis->y * (1 - rcos);
pOut->mat[4] = rcos + axis->y * axis->y * (1 - rcos);
pOut->mat[5] = axis->x * rsin + axis->z * axis->y * (1 - rcos);
pOut->mat[6] = axis->y * rsin + axis->x * axis->z * (1 - rcos);
pOut->mat[7] = -axis->x * rsin + axis->y * axis->z * (1 - rcos);
pOut->mat[8] = rcos + axis->z * axis->z * (1 - rcos);
return pOut;
}
kmVec3* const kmMat3RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn)
{
/*Surely not this easy?*/
kmQuaternion temp;
kmQuaternionRotationMatrix(&temp, pIn);
kmQuaternionToAxisAngle(&temp, pAxis, radians);
return pAxis;
}
/**
* Builds an X-axis rotation matrix and stores it in pOut, returns pOut
*/
kmMat3* const kmMat3RotationX(kmMat3* pOut, const float radians)
{
/*
| 1 0 0 |
M = | 0 cos(A) -sin(A) |
| 0 sin(A) cos(A) |
*/
pOut->mat[0] = 1.0f;
pOut->mat[1] = 0.0f;
pOut->mat[2] = 0.0f;
pOut->mat[3] = 0.0f;
pOut->mat[4] = cosf(radians);
pOut->mat[5] = sinf(radians);
pOut->mat[6] = 0.0f;
pOut->mat[7] = -sinf(radians);
pOut->mat[8] = cosf(radians);
return pOut;
}
/**
* Builds a rotation matrix using the rotation around the Y-axis
* The result is stored in pOut, pOut is returned.
*/
kmMat3* const kmMat3RotationY(kmMat3* pOut, const float radians)
{
/*
| cos(A) 0 sin(A) |
M = | 0 1 0 |
| -sin(A) 0 cos(A) |
*/
pOut->mat[0] = cosf(radians);
pOut->mat[1] = 0.0f;
pOut->mat[2] = -sinf(radians);
pOut->mat[3] = 0.0f;
pOut->mat[4] = 1.0f;
pOut->mat[5] = 0.0f;
pOut->mat[6] = sinf(radians);
pOut->mat[7] = 0.0f;
pOut->mat[8] = cosf(radians);
return pOut;
}
/**
* Builds a rotation matrix around the Z-axis. The resulting
* matrix is stored in pOut. pOut is returned.
*/
kmMat3* const kmMat3RotationZ(kmMat3* pOut, const float radians)
{
/*
| cos(A) -sin(A) 0 |
M = | sin(A) cos(A) 0 |
| 0 0 1 |
*/
pOut->mat[0] = cosf(radians);
pOut->mat[1] =-sinf(radians);
pOut->mat[2] = 0.0f;
pOut->mat[3] = sinf(radians);;
pOut->mat[4] = cosf(radians);
pOut->mat[5] = 0.0f;
pOut->mat[6] = 0.0f;
pOut->mat[7] = 0.0f;
pOut->mat[8] = 1.0f;
return pOut;
}

Просмотреть файл

@ -1,792 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file mat4.c
*/
#include <memory.h>
#include <assert.h>
#include <stdlib.h>
#include "kazmath/utility.h"
#include "kazmath/vec3.h"
#include "kazmath/mat4.h"
#include "kazmath/mat3.h"
#include "kazmath/quaternion.h"
#include "kazmath/plane.h"
#include "kazmath/neon_matrix_impl.h"
/**
* Fills a kmMat4 structure with the values from a 16
* element array of floats
* @Params pOut - A pointer to the destination matrix
* pMat - A 16 element array of floats
* @Return Returns pOut so that the call can be nested
*/
kmMat4* const kmMat4Fill(kmMat4* pOut, const kmScalar* pMat)
{
memcpy(pOut->mat, pMat, sizeof(kmScalar) * 16);
return pOut;
}
/**
* Sets pOut to an identity matrix returns pOut
* @Params pOut - A pointer to the matrix to set to identity
* @Return Returns pOut so that the call can be nested
*/
kmMat4* const kmMat4Identity(kmMat4* pOut)
{
memset(pOut->mat, 0, sizeof(float) * 16);
pOut->mat[0] = pOut->mat[5] = pOut->mat[10] = pOut->mat[15] = 1.0f;
return pOut;
}
float get(const kmMat4 * pIn, int row, int col)
{
return pIn->mat[row + 4*col];
}
void set(kmMat4 * pIn, int row, int col, float value)
{
pIn->mat[row + 4*col] = value;
}
void swap(kmMat4 * pIn, int r1, int c1, int r2, int c2)
{
float tmp = get(pIn,r1,c1);
set(pIn,r1,c1,get(pIn,r2,c2));
set(pIn,r2,c2, tmp);
}
//Returns an upper and a lower triangular matrix which are L and R in the Gauss algorithm
int gaussj(kmMat4 *a, kmMat4 *b)
{
int i, icol = 0, irow = 0, j, k, l, ll, n = 4, m = 4;
float big, dum, pivinv;
int indxc[4] = {0};
int indxr[4] = {0};
int ipiv[4] = {0};
for (j = 0; j < n; j++) {
ipiv[j] = 0;
}
for (i = 0; i < n; i++) {
big = 0.0f;
for (j = 0; j < n; j++) {
if (ipiv[j] != 1) {
for (k = 0; k < n; k++) {
if (ipiv[k] == 0) {
if (abs(get(a,j, k)) >= big) {
big = abs(get(a,j, k));
irow = j;
icol = k;
}
}
}
}
}
++(ipiv[icol]);
if (irow != icol) {
for (l = 0; l < n; l++) {
swap(a,irow, l, icol, l);
}
for (l = 0; l < m; l++) {
swap(b,irow, l, icol, l);
}
}
indxr[i] = irow;
indxc[i] = icol;
if (get(a,icol, icol) == 0.0) {
return KM_FALSE;
}
pivinv = 1.0f / get(a,icol, icol);
set(a,icol, icol, 1.0f);
for (l = 0; l < n; l++) {
set(a,icol, l, get(a,icol, l) * pivinv);
}
for (l = 0; l < m; l++) {
set(b,icol, l, get(b,icol, l) * pivinv);
}
for (ll = 0; ll < n; ll++) {
if (ll != icol) {
dum = get(a,ll, icol);
set(a,ll, icol, 0.0f);
for (l = 0; l < n; l++) {
set(a,ll, l, get(a,ll, l) - get(a,icol, l) * dum);
}
for (l = 0; l < m; l++) {
set(b,ll, l, get(a,ll, l) - get(b,icol, l) * dum);
}
}
}
}
// This is the end of the main loop over columns of the reduction. It only remains to unscram-
// ble the solution in view of the column interchanges. We do this by interchanging pairs of
// columns in the reverse order that the permutation was built up.
for (l = n - 1; l >= 0; l--) {
if (indxr[l] != indxc[l]) {
for (k = 0; k < n; k++) {
swap(a,k, indxr[l], k, indxc[l]);
}
}
}
return KM_TRUE;
}
/**
* Calculates the inverse of pM and stores the result in
* pOut.
* @Return Returns NULL if there is no inverse, else pOut
*/
kmMat4* const kmMat4Inverse(kmMat4* pOut, const kmMat4* pM)
{
kmMat4 inv;
kmMat4 tmp;
kmMat4Assign(&inv, pM);
kmMat4Identity(&tmp);
if(gaussj(&inv, &tmp) == KM_FALSE) {
return NULL;
}
kmMat4Assign(pOut, &inv);
return pOut;
}
/**
* Returns KM_TRUE if pIn is an identity matrix
* KM_FALSE otherwise
*/
const int kmMat4IsIdentity(const kmMat4* pIn)
{
static const float identity [] = { 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
return (memcmp(identity, pIn->mat, sizeof(float) * 16) == 0);
}
/**
* Sets pOut to the transpose of pIn, returns pOut
*/
kmMat4* const kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn)
{
int x, z;
for (z = 0; z < 4; ++z) {
for (x = 0; x < 4; ++x) {
pOut->mat[(z * 4) + x] = pIn->mat[(x * 4) + z];
}
}
return pOut;
}
/**
* Multiplies pM1 with pM2, stores the result in pOut, returns pOut
*/
kmMat4* const kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2)
{
#if defined(__ARM_NEON__) && !defined(__arm64__)
// It is possible to skip the memcpy() since "out" does not overwrite p1 or p2.
// otherwise a temp must be needed.
float *mat = pOut->mat;
// Invert column-order with row-order
NEON_Matrix4Mul( &pM2->mat[0], &pM1->mat[0], &mat[0] );
#else
float mat[16];
const float *m1 = pM1->mat, *m2 = pM2->mat;
mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];
mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];
mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];
mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];
mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];
mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];
mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];
mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];
mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];
mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];
mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];
mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];
mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];
mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
memcpy(pOut->mat, mat, sizeof(pOut->mat));
#endif
return pOut;
}
/**
* Assigns the value of pIn to pOut
*/
kmMat4* const kmMat4Assign(kmMat4* pOut, const kmMat4* pIn)
{
assert(pOut != pIn && "You have tried to self-assign!!");
memcpy(pOut->mat, pIn->mat, sizeof(float)*16);
return pOut;
}
/**
* Returns KM_TRUE if the 2 matrices are equal (approximately)
*/
const int kmMat4AreEqual(const kmMat4* pMat1, const kmMat4* pMat2)
{
int i = 0;
assert(pMat1 != pMat2 && "You are comparing the same thing!");
for (i = 0; i < 16; ++i)
{
if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] &&
pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) {
return KM_FALSE;
}
}
return KM_TRUE;
}
/**
* Build a rotation matrix from an axis and an angle. Result is stored in pOut.
* pOut is returned.
*/
kmMat4* const kmMat4RotationAxisAngle(kmMat4* pOut, const kmVec3* axis, kmScalar radians)
{
float rcos = cosf(radians);
float rsin = sinf(radians);
kmVec3 normalizedAxis;
kmVec3Normalize(&normalizedAxis, axis);
pOut->mat[0] = rcos + normalizedAxis.x * normalizedAxis.x * (1 - rcos);
pOut->mat[1] = normalizedAxis.z * rsin + normalizedAxis.y * normalizedAxis.x * (1 - rcos);
pOut->mat[2] = -normalizedAxis.y * rsin + normalizedAxis.z * normalizedAxis.x * (1 - rcos);
pOut->mat[3] = 0.0f;
pOut->mat[4] = -normalizedAxis.z * rsin + normalizedAxis.x * normalizedAxis.y * (1 - rcos);
pOut->mat[5] = rcos + normalizedAxis.y * normalizedAxis.y * (1 - rcos);
pOut->mat[6] = normalizedAxis.x * rsin + normalizedAxis.z * normalizedAxis.y * (1 - rcos);
pOut->mat[7] = 0.0f;
pOut->mat[8] = normalizedAxis.y * rsin + normalizedAxis.x * normalizedAxis.z * (1 - rcos);
pOut->mat[9] = -normalizedAxis.x * rsin + normalizedAxis.y * normalizedAxis.z * (1 - rcos);
pOut->mat[10] = rcos + normalizedAxis.z * normalizedAxis.z * (1 - rcos);
pOut->mat[11] = 0.0f;
pOut->mat[12] = 0.0f;
pOut->mat[13] = 0.0f;
pOut->mat[14] = 0.0f;
pOut->mat[15] = 1.0f;
return pOut;
}
/**
* Builds an X-axis rotation matrix and stores it in pOut, returns pOut
*/
kmMat4* const kmMat4RotationX(kmMat4* pOut, const float radians)
{
/*
| 1 0 0 0 |
M = | 0 cos(A) -sin(A) 0 |
| 0 sin(A) cos(A) 0 |
| 0 0 0 1 |
*/
pOut->mat[0] = 1.0f;
pOut->mat[1] = 0.0f;
pOut->mat[2] = 0.0f;
pOut->mat[3] = 0.0f;
pOut->mat[4] = 0.0f;
pOut->mat[5] = cosf(radians);
pOut->mat[6] = sinf(radians);
pOut->mat[7] = 0.0f;
pOut->mat[8] = 0.0f;
pOut->mat[9] = -sinf(radians);
pOut->mat[10] = cosf(radians);
pOut->mat[11] = 0.0f;
pOut->mat[12] = 0.0f;
pOut->mat[13] = 0.0f;
pOut->mat[14] = 0.0f;
pOut->mat[15] = 1.0f;
return pOut;
}
/**
* Builds a rotation matrix using the rotation around the Y-axis
* The result is stored in pOut, pOut is returned.
*/
kmMat4* const kmMat4RotationY(kmMat4* pOut, const float radians)
{
/*
| cos(A) 0 sin(A) 0 |
M = | 0 1 0 0 |
| -sin(A) 0 cos(A) 0 |
| 0 0 0 1 |
*/
pOut->mat[0] = cosf(radians);
pOut->mat[1] = 0.0f;
pOut->mat[2] = -sinf(radians);
pOut->mat[3] = 0.0f;
pOut->mat[4] = 0.0f;
pOut->mat[5] = 1.0f;
pOut->mat[6] = 0.0f;
pOut->mat[7] = 0.0f;
pOut->mat[8] = sinf(radians);
pOut->mat[9] = 0.0f;
pOut->mat[10] = cosf(radians);
pOut->mat[11] = 0.0f;
pOut->mat[12] = 0.0f;
pOut->mat[13] = 0.0f;
pOut->mat[14] = 0.0f;
pOut->mat[15] = 1.0f;
return pOut;
}
/**
* Builds a rotation matrix around the Z-axis. The resulting
* matrix is stored in pOut. pOut is returned.
*/
kmMat4* const kmMat4RotationZ(kmMat4* pOut, const float radians)
{
/*
| cos(A) -sin(A) 0 0 |
M = | sin(A) cos(A) 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
*/
pOut->mat[0] = cosf(radians);
pOut->mat[1] = sinf(radians);
pOut->mat[2] = 0.0f;
pOut->mat[3] = 0.0f;
pOut->mat[4] = -sinf(radians);;
pOut->mat[5] = cosf(radians);
pOut->mat[6] = 0.0f;
pOut->mat[7] = 0.0f;
pOut->mat[8] = 0.0f;
pOut->mat[9] = 0.0f;
pOut->mat[10] = 1.0f;
pOut->mat[11] = 0.0f;
pOut->mat[12] = 0.0f;
pOut->mat[13] = 0.0f;
pOut->mat[14] = 0.0f;
pOut->mat[15] = 1.0f;
return pOut;
}
/**
* Builds a rotation matrix from pitch, yaw and roll. The resulting
* matrix is stored in pOut and pOut is returned
*/
kmMat4* const kmMat4RotationPitchYawRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll)
{
double cr = cos(pitch);
double sr = sin(pitch);
double cp = cos(yaw);
double sp = sin(yaw);
double cy = cos(roll);
double sy = sin(roll);
double srsp = sr * sp;
double crsp = cr * sp;
pOut->mat[0] = (kmScalar) cp * cy;
pOut->mat[4] = (kmScalar) cp * sy;
pOut->mat[8] = (kmScalar) - sp;
pOut->mat[1] = (kmScalar) srsp * cy - cr * sy;
pOut->mat[5] = (kmScalar) srsp * sy + cr * cy;
pOut->mat[9] = (kmScalar) sr * cp;
pOut->mat[2] = (kmScalar) crsp * cy + sr * sy;
pOut->mat[6] = (kmScalar) crsp * sy - sr * cy;
pOut->mat[10] = (kmScalar) cr * cp;
pOut->mat[3] = pOut->mat[7] = pOut->mat[11] = 0.0;
pOut->mat[15] = 1.0;
return pOut;
}
/** Converts a quaternion to a rotation matrix,
* the result is stored in pOut, returns pOut
*/
kmMat4* const kmMat4RotationQuaternion(kmMat4* pOut, const kmQuaternion* pQ)
{
pOut->mat[0] = 1.0f - 2.0f * (pQ->y * pQ->y + pQ->z * pQ->z );
pOut->mat[1] = 2.0f * (pQ->x * pQ->y + pQ->z * pQ->w);
pOut->mat[2] = 2.0f * (pQ->x * pQ->z - pQ->y * pQ->w);
pOut->mat[3] = 0.0f;
// Second row
pOut->mat[4] = 2.0f * ( pQ->x * pQ->y - pQ->z * pQ->w );
pOut->mat[5] = 1.0f - 2.0f * ( pQ->x * pQ->x + pQ->z * pQ->z );
pOut->mat[6] = 2.0f * (pQ->z * pQ->y + pQ->x * pQ->w );
pOut->mat[7] = 0.0f;
// Third row
pOut->mat[8] = 2.0f * ( pQ->x * pQ->z + pQ->y * pQ->w );
pOut->mat[9] = 2.0f * ( pQ->y * pQ->z - pQ->x * pQ->w );
pOut->mat[10] = 1.0f - 2.0f * ( pQ->x * pQ->x + pQ->y * pQ->y );
pOut->mat[11] = 0.0f;
// Fourth row
pOut->mat[12] = 0;
pOut->mat[13] = 0;
pOut->mat[14] = 0;
pOut->mat[15] = 1.0f;
return pOut;
}
/** Builds a scaling matrix */
kmMat4* const kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y,
const kmScalar z)
{
memset(pOut->mat, 0, sizeof(float) * 16);
pOut->mat[0] = x;
pOut->mat[5] = y;
pOut->mat[10] = z;
pOut->mat[15] = 1.0f;
return pOut;
}
/**
* Builds a translation matrix. All other elements in the matrix
* will be set to zero except for the diagonal which is set to 1.0
*/
kmMat4* const kmMat4Translation(kmMat4* pOut, const kmScalar x,
const kmScalar y, const kmScalar z)
{
//FIXME: Write a test for this
memset(pOut->mat, 0, sizeof(float) * 16);
pOut->mat[0] = 1.0f;
pOut->mat[5] = 1.0f;
pOut->mat[10] = 1.0f;
pOut->mat[12] = x;
pOut->mat[13] = y;
pOut->mat[14] = z;
pOut->mat[15] = 1.0f;
return pOut;
}
/**
* Get the up vector from a matrix. pIn is the matrix you
* wish to extract the vector from. pOut is a pointer to the
* kmVec3 structure that should hold the resulting vector
*/
kmVec3* const kmMat4GetUpVec3(kmVec3* pOut, const kmMat4* pIn)
{
pOut->x = pIn->mat[4];
pOut->y = pIn->mat[5];
pOut->z = pIn->mat[6];
kmVec3Normalize(pOut, pOut);
return pOut;
}
/** Extract the right vector from a 4x4 matrix. The result is
* stored in pOut. Returns pOut.
*/
kmVec3* const kmMat4GetRightVec3(kmVec3* pOut, const kmMat4* pIn)
{
pOut->x = pIn->mat[0];
pOut->y = pIn->mat[1];
pOut->z = pIn->mat[2];
kmVec3Normalize(pOut, pOut);
return pOut;
}
/**
* Extract the forward vector from a 4x4 matrix. The result is
* stored in pOut. Returns pOut.
*/
kmVec3* const kmMat4GetForwardVec3(kmVec3* pOut, const kmMat4* pIn)
{
pOut->x = pIn->mat[8];
pOut->y = pIn->mat[9];
pOut->z = pIn->mat[10];
kmVec3Normalize(pOut, pOut);
return pOut;
}
/**
* Creates a perspective projection matrix in the
* same way as gluPerspective
*/
kmMat4* const kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY,
kmScalar aspect, kmScalar zNear,
kmScalar zFar)
{
kmScalar r = kmDegreesToRadians(fovY / 2);
kmScalar deltaZ = zFar - zNear;
kmScalar s = sin(r);
kmScalar cotangent = 0;
if (deltaZ == 0 || s == 0 || aspect == 0) {
return NULL;
}
//cos(r) / sin(r) = cot(r)
cotangent = cos(r) / s;
kmMat4Identity(pOut);
pOut->mat[0] = cotangent / aspect;
pOut->mat[5] = cotangent;
pOut->mat[10] = -(zFar + zNear) / deltaZ;
pOut->mat[11] = -1;
pOut->mat[14] = -2 * zNear * zFar / deltaZ;
pOut->mat[15] = 0;
return pOut;
}
/** Creates an orthographic projection matrix like glOrtho */
kmMat4* const kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left,
kmScalar right, kmScalar bottom,
kmScalar top, kmScalar nearVal,
kmScalar farVal)
{
kmScalar tx = -((right + left) / (right - left));
kmScalar ty = -((top + bottom) / (top - bottom));
kmScalar tz = -((farVal + nearVal) / (farVal - nearVal));
kmMat4Identity(pOut);
pOut->mat[0] = 2 / (right - left);
pOut->mat[5] = 2 / (top - bottom);
pOut->mat[10] = -2 / (farVal - nearVal);
pOut->mat[12] = tx;
pOut->mat[13] = ty;
pOut->mat[14] = tz;
return pOut;
}
/**
* Builds a translation matrix in the same way as gluLookAt()
* the resulting matrix is stored in pOut. pOut is returned.
*/
kmMat4* const kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye,
const kmVec3* pCenter, const kmVec3* pUp)
{
kmVec3 f, up, s, u;
kmMat4 translate;
kmVec3Subtract(&f, pCenter, pEye);
kmVec3Normalize(&f, &f);
kmVec3Assign(&up, pUp);
kmVec3Normalize(&up, &up);
kmVec3Cross(&s, &f, &up);
kmVec3Normalize(&s, &s);
kmVec3Cross(&u, &s, &f);
kmVec3Normalize(&s, &s);
kmMat4Identity(pOut);
pOut->mat[0] = s.x;
pOut->mat[4] = s.y;
pOut->mat[8] = s.z;
pOut->mat[1] = u.x;
pOut->mat[5] = u.y;
pOut->mat[9] = u.z;
pOut->mat[2] = -f.x;
pOut->mat[6] = -f.y;
pOut->mat[10] = -f.z;
kmMat4Translation(&translate, -pEye->x, -pEye->y, -pEye->z);
kmMat4Multiply(pOut, pOut, &translate);
return pOut;
}
/**
* Extract a 3x3 rotation matrix from the input 4x4 transformation.
* Stores the result in pOut, returns pOut
*/
kmMat3* const kmMat4ExtractRotation(kmMat3* pOut, const kmMat4* pIn)
{
pOut->mat[0] = pIn->mat[0];
pOut->mat[1] = pIn->mat[1];
pOut->mat[2] = pIn->mat[2];
pOut->mat[3] = pIn->mat[4];
pOut->mat[4] = pIn->mat[5];
pOut->mat[5] = pIn->mat[6];
pOut->mat[6] = pIn->mat[8];
pOut->mat[7] = pIn->mat[9];
pOut->mat[8] = pIn->mat[10];
return pOut;
}
/**
* Take the rotation from a 4x4 transformation matrix, and return it as an axis and an angle (in radians)
* returns the output axis.
*/
kmVec3* const kmMat4RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn)
{
/*Surely not this easy?*/
kmQuaternion temp;
kmMat3 rotation;
kmMat4ExtractRotation(&rotation, pIn);
kmQuaternionRotationMatrix(&temp, &rotation);
kmQuaternionToAxisAngle(&temp, pAxis, radians);
return pAxis;
}
/** Build a 4x4 OpenGL transformation matrix using a 3x3 rotation matrix,
* and a 3d vector representing a translation. Assign the result to pOut,
* pOut is also returned.
*/
kmMat4* const kmMat4RotationTranslation(kmMat4* pOut, const kmMat3* rotation, const kmVec3* translation)
{
pOut->mat[0] = rotation->mat[0];
pOut->mat[1] = rotation->mat[1];
pOut->mat[2] = rotation->mat[2];
pOut->mat[3] = 0.0f;
pOut->mat[4] = rotation->mat[3];
pOut->mat[5] = rotation->mat[4];
pOut->mat[6] = rotation->mat[5];
pOut->mat[7] = 0.0f;
pOut->mat[8] = rotation->mat[6];
pOut->mat[9] = rotation->mat[7];
pOut->mat[10] = rotation->mat[8];
pOut->mat[11] = 0.0f;
pOut->mat[12] = translation->x;
pOut->mat[13] = translation->y;
pOut->mat[14] = translation->z;
pOut->mat[15] = 1.0f;
return pOut;
}
kmPlane* const kmMat4ExtractPlane(kmPlane* pOut, const kmMat4* pIn, const kmEnum plane)
{
float t = 1.0f;
switch(plane) {
case KM_PLANE_RIGHT:
pOut->a = pIn->mat[3] - pIn->mat[0];
pOut->b = pIn->mat[7] - pIn->mat[4];
pOut->c = pIn->mat[11] - pIn->mat[8];
pOut->d = pIn->mat[15] - pIn->mat[12];
break;
case KM_PLANE_LEFT:
pOut->a = pIn->mat[3] + pIn->mat[0];
pOut->b = pIn->mat[7] + pIn->mat[4];
pOut->c = pIn->mat[11] + pIn->mat[8];
pOut->d = pIn->mat[15] + pIn->mat[12];
break;
case KM_PLANE_BOTTOM:
pOut->a = pIn->mat[3] + pIn->mat[1];
pOut->b = pIn->mat[7] + pIn->mat[5];
pOut->c = pIn->mat[11] + pIn->mat[9];
pOut->d = pIn->mat[15] + pIn->mat[13];
break;
case KM_PLANE_TOP:
pOut->a = pIn->mat[3] - pIn->mat[1];
pOut->b = pIn->mat[7] - pIn->mat[5];
pOut->c = pIn->mat[11] - pIn->mat[9];
pOut->d = pIn->mat[15] - pIn->mat[13];
break;
case KM_PLANE_FAR:
pOut->a = pIn->mat[3] - pIn->mat[2];
pOut->b = pIn->mat[7] - pIn->mat[6];
pOut->c = pIn->mat[11] - pIn->mat[10];
pOut->d = pIn->mat[15] - pIn->mat[14];
break;
case KM_PLANE_NEAR:
pOut->a = pIn->mat[3] + pIn->mat[2];
pOut->b = pIn->mat[7] + pIn->mat[6];
pOut->c = pIn->mat[11] + pIn->mat[10];
pOut->d = pIn->mat[15] + pIn->mat[14];
break;
default:
assert(0 && "Invalid plane index");
}
t = sqrtf(pOut->a * pOut->a +
pOut->b * pOut->b +
pOut->c * pOut->c);
pOut->a /= t;
pOut->b /= t;
pOut->c /= t;
pOut->d /= t;
return pOut;
}

Просмотреть файл

@ -1,175 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <stdlib.h>
#include "kazmath/vec3.h"
#include "kazmath/vec4.h"
#include "kazmath/plane.h"
const kmScalar kmPlaneDot(const kmPlane* pP, const kmVec4* pV)
{
//a*x + b*y + c*z + d*w
return (pP->a * pV->x +
pP->b * pV->y +
pP->c * pV->z +
pP->d * pV->w);
}
const kmScalar kmPlaneDotCoord(const kmPlane* pP, const kmVec3* pV)
{
return (pP->a * pV->x +
pP->b * pV->y +
pP->c * pV->z + pP->d);
}
const kmScalar kmPlaneDotNormal(const kmPlane* pP, const kmVec3* pV)
{
return (pP->a * pV->x +
pP->b * pV->y +
pP->c * pV->z);
}
kmPlane* const kmPlaneFromPointNormal(kmPlane* pOut, const kmVec3* pPoint, const kmVec3* pNormal)
{
/*
Planea = Nx
Planeb = Ny
Planec = Nz
Planed = NP
*/
pOut->a = pNormal->x;
pOut->b = pNormal->y;
pOut->c = pNormal->z;
pOut->d = -kmVec3Dot(pNormal, pPoint);
return pOut;
}
/**
* Creates a plane from 3 points. The result is stored in pOut.
* pOut is returned.
*/
kmPlane* const kmPlaneFromPoints(kmPlane* pOut, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3)
{
/*
v = (B A) × (C A)
n = 1|v| v
Outa = nx
Outb = ny
Outc = nz
Outd = nA
*/
kmVec3 n, v1, v2;
kmVec3Subtract(&v1, p2, p1); //Create the vectors for the 2 sides of the triangle
kmVec3Subtract(&v2, p3, p1);
kmVec3Cross(&n, &v1, &v2); //Use the cross product to get the normal
kmVec3Normalize(&n, &n); //Normalize it and assign to pOut->m_N
pOut->a = n.x;
pOut->b = n.y;
pOut->c = n.z;
pOut->d = kmVec3Dot(kmVec3Scale(&n, &n, -1.0), p1);
return pOut;
}
kmVec3* const kmPlaneIntersectLine(kmVec3* pOut, const kmPlane* pP, const kmVec3* pV1, const kmVec3* pV2)
{
/*
n = (Planea, Planeb, Planec)
d = V U
Out = U d(Pd + nU)(dn) [iff dn 0]
*/
kmVec3 d;
assert(0 && "Not implemented");
kmVec3Subtract(&d, pV2, pV1); //Get the direction vector
//TODO: Continue here!
/*if (fabs(kmVec3Dot(&pP->m_N, &d)) > kmEpsilon)
{
//If we get here then the plane and line are parallel (i.e. no intersection)
pOut = nullptr; //Set to nullptr
return pOut;
} */
return NULL;
}
kmPlane* const kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP)
{
kmVec3 n;
kmScalar l = 0;
n.x = pP->a;
n.y = pP->b;
n.z = pP->c;
l = 1.0f / kmVec3Length(&n); //Get 1/length
kmVec3Normalize(&n, &n); //Normalize the vector and assign to pOut
pOut->a = n.x;
pOut->b = n.y;
pOut->c = n.z;
pOut->d = pP->d * l; //Scale the D value and assign to pOut
return pOut;
}
kmPlane* const kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s)
{
assert(0 && "Not implemented");
return NULL;
}
/**
* Returns POINT_INFRONT_OF_PLANE if pP is infront of pIn. Returns
* POINT_BEHIND_PLANE if it is behind. Returns POINT_ON_PLANE otherwise
*/
const POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const kmVec3* pP)
{
// This function will determine if a point is on, in front of, or behind
// the plane. First we store the dot product of the plane and the point.
float distance = pIn->a * pP->x + pIn->b * pP->y + pIn->c * pP->z + pIn->d;
// Simply put if the dot product is greater than 0 then it is infront of it.
// If it is less than 0 then it is behind it. And if it is 0 then it is on it.
if(distance > 0.001) return POINT_INFRONT_OF_PLANE;
if(distance < -0.001) return POINT_BEHIND_PLANE;
return POINT_ON_PLANE;
}

Просмотреть файл

@ -1,586 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <memory.h>
#include "kazmath/utility.h"
#include "kazmath/mat3.h"
#include "kazmath/vec3.h"
#include "kazmath/quaternion.h"
#ifndef NULL
#define NULL ((void *)0)
#endif
///< Returns pOut, sets pOut to the conjugate of pIn
kmQuaternion* const kmQuaternionConjugate(kmQuaternion* pOut, const kmQuaternion* pIn)
{
pOut->x = -pIn->x;
pOut->y = -pIn->y;
pOut->z = -pIn->z;
pOut->w = pIn->w;
return pOut;
}
///< Returns the dot product of the 2 quaternions
const kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2)
{
// A dot B = B dot A = AtBt + AxBx + AyBy + AzBz
return (q1->w * q2->w +
q1->x * q2->x +
q1->y * q2->y +
q1->z * q2->z);
}
///< Returns the exponential of the quaternion
kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn)
{
assert(0);
return pOut;
}
///< Makes the passed quaternion an identity quaternion
kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut)
{
pOut->x = 0.0;
pOut->y = 0.0;
pOut->z = 0.0;
pOut->w = 1.0;
return pOut;
}
///< Returns the inverse of the passed Quaternion
kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut,
const kmQuaternion* pIn)
{
kmScalar l = kmQuaternionLength(pIn);
kmQuaternion tmp;
if (fabs(l) > kmEpsilon)
{
pOut->x = 0.0;
pOut->y = 0.0;
pOut->z = 0.0;
pOut->w = 0.0;
return pOut;
}
///Get the conjugute and divide by the length
kmQuaternionScale(pOut,
kmQuaternionConjugate(&tmp, pIn), 1.0f / l);
return pOut;
}
///< Returns true if the quaternion is an identity quaternion
int kmQuaternionIsIdentity(const kmQuaternion* pIn)
{
return (pIn->x == 0.0 && pIn->y == 0.0 && pIn->z == 0.0 &&
pIn->w == 1.0);
}
///< Returns the length of the quaternion
kmScalar kmQuaternionLength(const kmQuaternion* pIn)
{
return sqrtf(kmQuaternionLengthSq(pIn));
}
///< Returns the length of the quaternion squared (prevents a sqrt)
kmScalar kmQuaternionLengthSq(const kmQuaternion* pIn)
{
return pIn->x * pIn->x + pIn->y * pIn->y +
pIn->z * pIn->z + pIn->w * pIn->w;
}
///< Returns the natural logarithm
kmQuaternion* kmQuaternionLn(kmQuaternion* pOut,
const kmQuaternion* pIn)
{
/*
A unit quaternion, is defined by:
Q == (cos(theta), sin(theta) * v) where |v| = 1
The natural logarithm of Q is, ln(Q) = (0, theta * v)
*/
assert(0);
return pOut;
}
///< Multiplies 2 quaternions together
extern
kmQuaternion* kmQuaternionMultiply(kmQuaternion* pOut,
const kmQuaternion* q1,
const kmQuaternion* q2)
{
pOut->w = q1->w * q2->w - q1->x * q2->x - q1->y * q2->y - q1->z * q2->z;
pOut->x = q1->w * q2->x + q1->x * q2->w + q1->y * q2->z - q1->z * q2->y;
pOut->y = q1->w * q2->y + q1->y * q2->w + q1->z * q2->x - q1->x * q2->z;
pOut->z = q1->w * q2->z + q1->z * q2->w + q1->x * q2->y - q1->y * q2->x;
return pOut;
}
///< Normalizes a quaternion
kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut,
const kmQuaternion* pIn)
{
kmScalar length = kmQuaternionLength(pIn);
assert(fabs(length) > kmEpsilon);
kmQuaternionScale(pOut, pIn, 1.0f / length);
return pOut;
}
///< Rotates a quaternion around an axis
kmQuaternion* kmQuaternionRotationAxis(kmQuaternion* pOut,
const kmVec3* pV,
kmScalar angle)
{
kmScalar rad = angle * 0.5f;
kmScalar scale = sinf(rad);
pOut->w = cosf(rad);
pOut->x = pV->x * scale;
pOut->y = pV->y * scale;
pOut->z = pV->z * scale;
return pOut;
}
///< Creates a quaternion from a rotation matrix
kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut,
const kmMat3* pIn)
{
/*
Note: The OpenGL matrices are transposed from the description below
taken from the Matrix and Quaternion FAQ
if ( mat[0] > mat[5] && mat[0] > mat[10] ) { // Column 0:
S = sqrt( 1.0 + mat[0] - mat[5] - mat[10] ) * 2;
X = 0.25 * S;
Y = (mat[4] + mat[1] ) / S;
Z = (mat[2] + mat[8] ) / S;
W = (mat[9] - mat[6] ) / S;
} else if ( mat[5] > mat[10] ) { // Column 1:
S = sqrt( 1.0 + mat[5] - mat[0] - mat[10] ) * 2;
X = (mat[4] + mat[1] ) / S;
Y = 0.25 * S;
Z = (mat[9] + mat[6] ) / S;
W = (mat[2] - mat[8] ) / S;
} else { // Column 2:
S = sqrt( 1.0 + mat[10] - mat[0] - mat[5] ) * 2;
X = (mat[2] + mat[8] ) / S;
Y = (mat[9] + mat[6] ) / S;
Z = 0.25 * S;
W = (mat[4] - mat[1] ) / S;
}
*/
float x, y, z, w;
float *pMatrix = NULL;
float m4x4[16] = {0};
float scale = 0.0f;
float diagonal = 0.0f;
if(!pIn) {
return NULL;
}
/* 0 3 6
1 4 7
2 5 8
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15*/
m4x4[0] = pIn->mat[0];
m4x4[1] = pIn->mat[3];
m4x4[2] = pIn->mat[6];
m4x4[4] = pIn->mat[1];
m4x4[5] = pIn->mat[4];
m4x4[6] = pIn->mat[7];
m4x4[8] = pIn->mat[2];
m4x4[9] = pIn->mat[5];
m4x4[10] = pIn->mat[8];
m4x4[15] = 1;
pMatrix = &m4x4[0];
diagonal = pMatrix[0] + pMatrix[5] + pMatrix[10] + 1;
if(diagonal > kmEpsilon) {
// Calculate the scale of the diagonal
scale = (float)sqrt(diagonal ) * 2;
// Calculate the x, y, x and w of the quaternion through the respective equation
x = ( pMatrix[9] - pMatrix[6] ) / scale;
y = ( pMatrix[2] - pMatrix[8] ) / scale;
z = ( pMatrix[4] - pMatrix[1] ) / scale;
w = 0.25f * scale;
}
else
{
// If the first element of the diagonal is the greatest value
if ( pMatrix[0] > pMatrix[5] && pMatrix[0] > pMatrix[10] )
{
// Find the scale according to the first element, and double that value
scale = (float)sqrt( 1.0f + pMatrix[0] - pMatrix[5] - pMatrix[10] ) * 2.0f;
// Calculate the x, y, x and w of the quaternion through the respective equation
x = 0.25f * scale;
y = (pMatrix[4] + pMatrix[1] ) / scale;
z = (pMatrix[2] + pMatrix[8] ) / scale;
w = (pMatrix[9] - pMatrix[6] ) / scale;
}
// Else if the second element of the diagonal is the greatest value
else if (pMatrix[5] > pMatrix[10])
{
// Find the scale according to the second element, and double that value
scale = (float)sqrt( 1.0f + pMatrix[5] - pMatrix[0] - pMatrix[10] ) * 2.0f;
// Calculate the x, y, x and w of the quaternion through the respective equation
x = (pMatrix[4] + pMatrix[1] ) / scale;
y = 0.25f * scale;
z = (pMatrix[9] + pMatrix[6] ) / scale;
w = (pMatrix[2] - pMatrix[8] ) / scale;
}
// Else the third element of the diagonal is the greatest value
else
{
// Find the scale according to the third element, and double that value
scale = (float)sqrt( 1.0f + pMatrix[10] - pMatrix[0] - pMatrix[5] ) * 2.0f;
// Calculate the x, y, x and w of the quaternion through the respective equation
x = (pMatrix[2] + pMatrix[8] ) / scale;
y = (pMatrix[9] + pMatrix[6] ) / scale;
z = 0.25f * scale;
w = (pMatrix[4] - pMatrix[1] ) / scale;
}
}
pOut->x = x;
pOut->y = y;
pOut->z = z;
pOut->w = w;
return pOut;
#if 0
kmScalar T = pIn->mat[0] + pIn->mat[5] + pIn->mat[10];
if (T > kmEpsilon) {
//If the trace is greater than zero we always use this calculation:
/* S = sqrt(T) * 2;
X = ( mat[9] - mat[6] ) / S;
Y = ( mat[2] - mat[8] ) / S;
Z = ( mat[4] - mat[1] ) / S;
W = 0.25 * S;*/
/* kmScalar s = sqrtf(T) * 2;
pOut->x = (pIn->mat[9] - pIn->mat[6]) / s;
pOut->y = (pIn->mat[8] - pIn->mat[2]) / s;
pOut->z = (pIn->mat[1] - pIn->mat[4]) / s;
pOut->w = 0.25f * s;
kmQuaternionNormalize(pOut, pOut);
return pOut;
}
//Otherwise the calculation depends on which major diagonal element has the greatest value.
if (pIn->mat[0] > pIn->mat[5] && pIn->mat[0] > pIn->mat[10]) {
kmScalar s = sqrtf(1 + pIn->mat[0] - pIn->mat[5] - pIn->mat[10]) * 2;
pOut->x = 0.25f * s;
pOut->y = (pIn->mat[1] + pIn->mat[4]) / s;
pOut->z = (pIn->mat[8] + pIn->mat[2]) / s;
pOut->w = (pIn->mat[9] - pIn->mat[6]) / s;
}
else if (pIn->mat[5] > pIn->mat[10]) {
kmScalar s = sqrtf(1 + pIn->mat[5] - pIn->mat[0] - pIn->mat[10]) * 2;
pOut->x = (pIn->mat[1] + pIn->mat[4]) / s;
pOut->y = 0.25f * s;
pOut->z = (pIn->mat[9] + pIn->mat[6]) / s;
pOut->w = (pIn->mat[8] - pIn->mat[2]) / s;
}
else {
kmScalar s = sqrt(1.0f + pIn->mat[10] - pIn->mat[0] - pIn->mat[5]) * 2.0f;
pOut->x = (pIn->mat[8] + pIn->mat[2] ) / s;
pOut->y = (pIn->mat[6] + pIn->mat[9] ) / s;
pOut->z = 0.25f * s;
pOut->w = (pIn->mat[1] - pIn->mat[4] ) / s;
}
kmQuaternionNormalize(pOut, pOut);
return pOut;*/
#endif // 0
}
///< Create a quaternion from yaw, pitch and roll
kmQuaternion* kmQuaternionRotationYawPitchRoll(kmQuaternion* pOut,
kmScalar yaw,
kmScalar pitch,
kmScalar roll)
{
kmScalar ex, ey, ez; // temp half euler angles
kmScalar cr, cp, cy, sr, sp, sy, cpcy, spsy; // temp vars in roll,pitch yaw
ex = kmDegreesToRadians(pitch) / 2.0f; // convert to rads and half them
ey = kmDegreesToRadians(yaw) / 2.0f;
ez = kmDegreesToRadians(roll) / 2.0f;
cr = cosf(ex);
cp = cosf(ey);
cy = cosf(ez);
sr = sinf(ex);
sp = sinf(ey);
sy = sinf(ez);
cpcy = cp * cy;
spsy = sp * sy;
pOut->w = cr * cpcy + sr * spsy;
pOut->x = sr * cpcy - cr * spsy;
pOut->y = cr * sp * cy + sr * cp * sy;
pOut->z = cr * cp * sy - sr * sp * cy;
kmQuaternionNormalize(pOut, pOut);
return pOut;
}
///< Interpolate between 2 quaternions
kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut,
const kmQuaternion* q1,
const kmQuaternion* q2,
kmScalar t)
{
/*float CosTheta = Q0.DotProd(Q1);
float Theta = acosf(CosTheta);
float SinTheta = sqrtf(1.0f-CosTheta*CosTheta);
float Sin_T_Theta = sinf(T*Theta)/SinTheta;
float Sin_OneMinusT_Theta = sinf((1.0f-T)*Theta)/SinTheta;
Quaternion Result = Q0*Sin_OneMinusT_Theta;
Result += (Q1*Sin_T_Theta);
return Result;*/
if (q1->x == q2->x &&
q1->y == q2->y &&
q1->z == q2->z &&
q1->w == q2->w) {
pOut->x = q1->x;
pOut->y = q1->y;
pOut->z = q1->z;
pOut->w = q1->w;
return pOut;
}
{
kmScalar ct = kmQuaternionDot(q1, q2);
kmScalar theta = acosf(ct);
kmScalar st = sqrtf(1.0 - kmSQR(ct));
kmScalar stt = sinf(t * theta) / st;
kmScalar somt = sinf((1.0 - t) * theta) / st;
kmQuaternion temp, temp2;
kmQuaternionScale(&temp, q1, somt);
kmQuaternionScale(&temp2, q2, stt);
kmQuaternionAdd(pOut, &temp, &temp2);
}
return pOut;
}
///< Get the axis and angle of rotation from a quaternion
void kmQuaternionToAxisAngle(const kmQuaternion* pIn,
kmVec3* pAxis,
kmScalar* pAngle)
{
kmScalar tempAngle; // temp angle
kmScalar scale; // temp vars
tempAngle = acosf(pIn->w);
scale = sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z));
if (((scale > -kmEpsilon) && scale < kmEpsilon)
|| (scale < 2*kmPI + kmEpsilon && scale > 2*kmPI - kmEpsilon)) // angle is 0 or 360 so just simply set axis to 0,0,1 with angle 0
{
*pAngle = 0.0f;
pAxis->x = 0.0f;
pAxis->y = 0.0f;
pAxis->z = 1.0f;
}
else
{
*pAngle = tempAngle * 2.0f; // angle in radians
pAxis->x = pIn->x / scale;
pAxis->y = pIn->y / scale;
pAxis->z = pIn->z / scale;
kmVec3Normalize(pAxis, pAxis);
}
}
kmQuaternion* kmQuaternionScale(kmQuaternion* pOut,
const kmQuaternion* pIn,
kmScalar s)
{
pOut->x = pIn->x * s;
pOut->y = pIn->y * s;
pOut->z = pIn->z * s;
pOut->w = pIn->w * s;
return pOut;
}
kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn)
{
memcpy(pOut, pIn, sizeof(float) * 4);
return pOut;
}
kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2)
{
pOut->x = pQ1->x + pQ2->x;
pOut->y = pQ1->y + pQ2->y;
pOut->z = pQ1->z + pQ2->z;
pOut->w = pQ1->w + pQ2->w;
return pOut;
}
/** Adapted from the OGRE engine!
Gets the shortest arc quaternion to rotate this vector to the destination
vector.
@remarks
If you call this with a dest vector that is close to the inverse
of this vector, we will rotate 180 degrees around the 'fallbackAxis'
(if specified, or a generated axis if not) since in this case
ANY axis of rotation is valid.
*/
kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const kmVec3* vec1, const kmVec3* vec2, const kmVec3* fallback) {
kmVec3 v1, v2;
kmScalar a;
kmVec3Assign(&v1, vec1);
kmVec3Assign(&v2, vec2);
kmVec3Normalize(&v1, &v1);
kmVec3Normalize(&v2, &v2);
a = kmVec3Dot(&v1, &v2);
if (a >= 1.0) {
kmQuaternionIdentity(pOut);
return pOut;
}
if (a < (1e-6f - 1.0f)) {
if (fabs(kmVec3LengthSq(fallback)) < kmEpsilon) {
kmQuaternionRotationAxis(pOut, fallback, kmPI);
} else {
kmVec3 axis;
kmVec3 X;
X.x = 1.0;
X.y = 0.0;
X.z = 0.0;
kmVec3Cross(&axis, &X, vec1);
//If axis is zero
if (fabs(kmVec3LengthSq(&axis)) < kmEpsilon) {
kmVec3 Y;
Y.x = 0.0;
Y.y = 1.0;
Y.z = 0.0;
kmVec3Cross(&axis, &Y, vec1);
}
kmVec3Normalize(&axis, &axis);
kmQuaternionRotationAxis(pOut, &axis, kmPI);
}
} else {
kmScalar s = sqrtf((1+a) * 2);
kmScalar invs = 1 / s;
kmVec3 c;
kmVec3Cross(&c, &v1, &v2);
pOut->x = c.x * invs;
pOut->y = c.y * invs;
pOut->z = c.z * invs;
pOut->w = s * 0.5f;
kmQuaternionNormalize(pOut, pOut);
}
return pOut;
}
kmVec3* kmQuaternionMultiplyVec3(kmVec3* pOut, const kmQuaternion* q, const kmVec3* v) {
kmVec3 uv, uuv, qvec;
qvec.x = q->x;
qvec.y = q->y;
qvec.z = q->z;
kmVec3Cross(&uv, &qvec, v);
kmVec3Cross(&uuv, &qvec, &uv);
kmVec3Scale(&uv, &uv, (2.0f * q->w));
kmVec3Scale(&uuv, &uuv, 2.0f);
kmVec3Add(pOut, v, &uv);
kmVec3Add(pOut, pOut, &uuv);
return pOut;
}

Просмотреть файл

@ -1,186 +0,0 @@
#include <assert.h>
#include <stdio.h>
#include "kazmath/ray2.h"
void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy) {
ray->start.x = px;
ray->start.y = py;
ray->dir.x = vx;
ray->dir.y = vy;
}
kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection) {
float x1 = ray->start.x;
float y1 = ray->start.y;
float x2 = ray->start.x + ray->dir.x;
float y2 = ray->start.y + ray->dir.y;
float x3 = p1->x;
float y3 = p1->y;
float x4 = p2->x;
float y4 = p2->y;
float denom = (y4 -y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
float ua, x, y;
//If denom is zero, the lines are parallel
if(denom > -kmEpsilon && denom < kmEpsilon) {
return KM_FALSE;
}
ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
// float ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
x = x1 + ua * (x2 - x1);
y = y1 + ua * (y2 - y1);
if(x < kmMin(p1->x, p2->x) - kmEpsilon ||
x > kmMax(p1->x, p2->x) + kmEpsilon ||
y < kmMin(p1->y, p2->y) - kmEpsilon ||
y > kmMax(p1->y, p2->y) + kmEpsilon) {
//Outside of line
//printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1->x, p1->y, p2->x, p2->y);
return KM_FALSE;
}
if(x < kmMin(x1, x2) - kmEpsilon ||
x > kmMax(x1, x2) + kmEpsilon ||
y < kmMin(y1, y2) - kmEpsilon ||
y > kmMax(y1, y2) + kmEpsilon) {
//printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2);
return KM_FALSE;
}
intersection->x = x;
intersection->y = y;
return KM_TRUE;
/*
kmScalar A1, B1, C1;
kmScalar A2, B2, C2;
A1 = ray->dir.y;
B1 = ray->dir.x;
C1 = A1 * ray->start.x + B1 * ray->start.y;
A2 = p2->y - p1->y;
B2 = p2->x - p1->x;
C2 = A2 * p1->x + B2 * p1->y;
double det = (A1 * B2) - (A2 * B1);
if(det == 0) {
printf("Parallel\n");
return KM_FALSE;
}
double x = (B2*C1 - B1*C2) / det;
double y = (A1*C2 - A2*C1) / det;
if(x < min(p1->x, p2->x) - kmEpsilon ||
x > max(p1->x, p2->x) + kmEpsilon ||
y < min(p1->y, p2->y) - kmEpsilon ||
y > max(p1->y, p2->y) + kmEpsilon) {
//Outside of line
printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1->x, p1->y, p2->x, p2->y);
return KM_FALSE;
}
kmScalar x1 = ray->start.x;
kmScalar x2 = ray->start.x + ray->dir.x;
kmScalar y1 = ray->start.y;
kmScalar y2 = ray->start.y + ray->dir.y;
if(x < min(x1, x2) - kmEpsilon ||
x > max(x1, x2) + kmEpsilon ||
y < min(y1, y2) - kmEpsilon ||
y > max(y1, y2) + kmEpsilon) {
printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2);
return KM_FALSE;
}
intersection->x = x;
intersection->y = y;
return KM_TRUE;*/
}
void calculate_line_normal(kmVec2 p1, kmVec2 p2, kmVec2* normal_out) {
kmVec2 tmp;
kmVec2Subtract(&tmp, &p2, &p1); //Get direction vector
normal_out->x = -tmp.y;
normal_out->y = tmp.x;
kmVec2Normalize(normal_out, normal_out);
//TODO: should check that the normal is pointing out of the triangle
}
kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out) {
kmVec2 intersect;
kmVec2 final_intersect = {0., 0.}, normal = {0., 0.}; // Silencing LLVM SA.
kmScalar distance = 10000.0f;
kmBool intersected = KM_FALSE;
if(kmRay2IntersectLineSegment(ray, p1, p2, &intersect)) {
kmVec2 tmp;
kmScalar this_distance;
intersected = KM_TRUE;
this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
if(this_distance < distance) {
final_intersect.x = intersect.x;
final_intersect.y = intersect.y;
distance = this_distance;
calculate_line_normal(*p1, *p2, &normal);
}
}
if(kmRay2IntersectLineSegment(ray, p2, p3, &intersect)) {
kmVec2 tmp;
kmScalar this_distance;
intersected = KM_TRUE;
this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
if(this_distance < distance) {
final_intersect.x = intersect.x;
final_intersect.y = intersect.y;
distance = this_distance;
calculate_line_normal(*p2, *p3, &normal);
}
}
if(kmRay2IntersectLineSegment(ray, p3, p1, &intersect)) {
kmVec2 tmp;
kmScalar this_distance;
intersected = KM_TRUE;
this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
if(this_distance < distance) {
final_intersect.x = intersect.x;
final_intersect.y = intersect.y;
//distance = this_distance;
calculate_line_normal(*p3, *p1, &normal);
}
}
if(intersected) {
intersection->x = final_intersect.x;
intersection->y = final_intersect.y;
if(normal_out) {
normal_out->x = normal.x;
normal_out->y = normal.y;
}
}
return intersected;
}
kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection) {
assert(0 && "Not implemented");
return 0;
}

Просмотреть файл

@ -1,118 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <stdlib.h>
#include "kazmath/mat3.h"
#include "kazmath/vec2.h"
#include "kazmath/utility.h"
kmVec2* kmVec2Fill(kmVec2* pOut, kmScalar x, kmScalar y)
{
pOut->x = x;
pOut->y = y;
return pOut;
}
kmScalar kmVec2Length(const kmVec2* pIn)
{
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y));
}
kmScalar kmVec2LengthSq(const kmVec2* pIn)
{
return kmSQR(pIn->x) + kmSQR(pIn->y);
}
kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn)
{
kmScalar l = 1.0f / kmVec2Length(pIn);
kmVec2 v;
v.x = pIn->x * l;
v.y = pIn->y * l;
pOut->x = v.x;
pOut->y = v.y;
return pOut;
}
kmVec2* kmVec2Add(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2)
{
pOut->x = pV1->x + pV2->x;
pOut->y = pV1->y + pV2->y;
return pOut;
}
kmScalar kmVec2Dot(const kmVec2* pV1, const kmVec2* pV2)
{
return pV1->x * pV2->x + pV1->y * pV2->y;
}
kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2)
{
pOut->x = pV1->x - pV2->x;
pOut->y = pV1->y - pV2->y;
return pOut;
}
kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM)
{
kmVec2 v;
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[3] + pM->mat[6];
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[4] + pM->mat[7];
pOut->x = v.x;
pOut->y = v.y;
return pOut;
}
kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM)
{
assert(0);
return NULL;
}
kmVec2* kmVec2Scale(kmVec2* pOut, const kmVec2* pIn, const kmScalar s)
{
pOut->x = pIn->x * s;
pOut->y = pIn->y * s;
return pOut;
}
int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2)
{
return (
(p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) &&
(p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon)
);
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше